]> err.no Git - linux-2.6/commitdiff
Merge branch 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik...
authorLinus Torvalds <torvalds@g5.osdl.org>
Mon, 7 Nov 2005 16:04:01 +0000 (08:04 -0800)
committerLinus Torvalds <torvalds@g5.osdl.org>
Mon, 7 Nov 2005 16:04:01 +0000 (08:04 -0800)
813 files changed:
Documentation/Changes
Documentation/DocBook/Makefile
Documentation/DocBook/journal-api.tmpl
Documentation/DocBook/kernel-api.tmpl
Documentation/DocBook/rapidio.tmpl [new file with mode: 0644]
Documentation/MSI-HOWTO.txt
Documentation/RCU/whatisRCU.txt
Documentation/device-mapper/snapshot.txt
Documentation/fb/vesafb.txt
Documentation/feature-removal-schedule.txt
Documentation/filesystems/dentry-locking.txt [new file with mode: 0644]
Documentation/filesystems/devfs/README
Documentation/filesystems/ramfs-rootfs-initramfs.txt [new file with mode: 0644]
Documentation/filesystems/vfs.txt
Documentation/hpet.txt
Documentation/magic-number.txt
Documentation/networking/decnet.txt
Documentation/oops-tracing.txt
Documentation/power/video.txt
Documentation/s390/driver-model.txt
Documentation/sparse.txt
Documentation/video4linux/bttv/README.freeze
Documentation/vm/hugetlbpage.txt
MAINTAINERS
arch/arm/kernel/ptrace.c
arch/arm/mach-aaec2000/clock.c
arch/arm/mach-epxa10db/mm.c
arch/arm/mach-integrator/impd1.c
arch/arm/mach-pxa/corgi_lcd.c
arch/arm26/kernel/ptrace.c
arch/cris/arch-v10/README.mm
arch/cris/arch-v10/kernel/ptrace.c
arch/cris/arch-v10/kernel/signal.c
arch/cris/arch-v32/drivers/cryptocop.c
arch/cris/arch-v32/kernel/ptrace.c
arch/cris/arch-v32/kernel/signal.c
arch/cris/mm/ioremap.c
arch/frv/kernel/ptrace.c
arch/h8300/kernel/ptrace.c
arch/i386/Kconfig
arch/i386/Kconfig.debug
arch/i386/kernel/apic.c
arch/i386/kernel/apm.c
arch/i386/kernel/cpu/common.c
arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
arch/i386/kernel/cpu/mcheck/k7.c
arch/i386/kernel/cpu/mcheck/mce.c
arch/i386/kernel/cpu/mcheck/p4.c
arch/i386/kernel/cpu/mcheck/p5.c
arch/i386/kernel/cpu/mcheck/p6.c
arch/i386/kernel/cpu/mcheck/winchip.c
arch/i386/kernel/kprobes.c
arch/i386/kernel/ldt.c
arch/i386/kernel/mca.c
arch/i386/kernel/ptrace.c
arch/i386/kernel/reboot_fixups.c
arch/i386/kernel/scx200.c
arch/i386/kernel/smpboot.c
arch/i386/oprofile/Kconfig
arch/i386/power/cpu.c
arch/ia64/Kconfig
arch/ia64/Kconfig.debug
arch/ia64/hp/sim/simserial.c
arch/ia64/kernel/kprobes.c
arch/ia64/kernel/perfmon.c
arch/ia64/kernel/setup.c
arch/ia64/oprofile/Kconfig
arch/m68k/atari/time.c
arch/m68k/kernel/ptrace.c
arch/m68knommu/Kconfig
arch/m68knommu/Makefile
arch/m68knommu/kernel/asm-offsets.c
arch/m68knommu/kernel/ptrace.c
arch/m68knommu/kernel/setup.c
arch/m68knommu/kernel/vmlinux.lds.S
arch/m68knommu/platform/520x/Makefile [new file with mode: 0644]
arch/m68knommu/platform/520x/config.c [new file with mode: 0644]
arch/m68knommu/platform/5307/Makefile
arch/m68knommu/platform/5307/head.S
arch/m68knommu/platform/5307/ints.c
arch/m68knommu/platform/5307/pit.c
arch/mips/kernel/ptrace.c
arch/parisc/kernel/ptrace.c
arch/powerpc/Kconfig
arch/powerpc/Kconfig.debug
arch/powerpc/kernel/cputable.c
arch/powerpc/kernel/ptrace.c
arch/powerpc/kernel/time.c
arch/powerpc/mm/hash_utils_64.c
arch/powerpc/mm/hugetlbpage.c
arch/powerpc/mm/ppc_mmu_32.c
arch/powerpc/mm/slb_low.S
arch/powerpc/oprofile/Kconfig
arch/powerpc/platforms/pseries/reconfig.c
arch/ppc/4xx_io/serial_sicc.c
arch/ppc/8260_io/fcc_enet.c
arch/ppc/8xx_io/cs4218_tdm.c
arch/ppc/Kconfig
arch/ppc/boot/simple/Makefile
arch/ppc/boot/simple/misc.c
arch/ppc/boot/simple/openbios.c
arch/ppc/configs/ev64360_defconfig
arch/ppc/configs/stx_gp3_defconfig
arch/ppc/kernel/Makefile
arch/ppc/kernel/head_44x.S
arch/ppc/kernel/rio.c [new file with mode: 0644]
arch/ppc/platforms/4xx/Kconfig
arch/ppc/platforms/4xx/Makefile
arch/ppc/platforms/4xx/bubinga.c
arch/ppc/platforms/4xx/bubinga.h
arch/ppc/platforms/4xx/ebony.h
arch/ppc/platforms/4xx/ppc440spe.c [new file with mode: 0644]
arch/ppc/platforms/4xx/ppc440spe.h [new file with mode: 0644]
arch/ppc/platforms/4xx/sycamore.c
arch/ppc/platforms/4xx/sycamore.h
arch/ppc/platforms/4xx/walnut.c
arch/ppc/platforms/4xx/walnut.h
arch/ppc/platforms/4xx/yucca.c [new file with mode: 0644]
arch/ppc/platforms/4xx/yucca.h [new file with mode: 0644]
arch/ppc/platforms/85xx/mpc85xx_ads_common.c
arch/ppc/platforms/85xx/stx_gp3.c
arch/ppc/platforms/ev64360.c
arch/ppc/syslib/Makefile
arch/ppc/syslib/ibm440sp_common.c
arch/ppc/syslib/ibm44x_common.c
arch/ppc/syslib/ppc405_pci.c
arch/ppc/syslib/ppc440spe_pcie.c [new file with mode: 0644]
arch/ppc/syslib/ppc440spe_pcie.h [new file with mode: 0644]
arch/ppc/syslib/ppc4xx_pic.c
arch/ppc/syslib/ppc85xx_rio.c [new file with mode: 0644]
arch/ppc/syslib/ppc85xx_rio.h [new file with mode: 0644]
arch/ppc/syslib/ppc_sys.c
arch/ppc/syslib/prom.c
arch/ppc64/boot/main.c
arch/ppc64/kernel/kprobes.c
arch/ppc64/kernel/lparcfg.c
arch/ppc64/kernel/scanlog.c
arch/ppc64/kernel/sysfs.c
arch/s390/Makefile
arch/s390/kernel/Makefile
arch/s390/kernel/entry.S
arch/s390/kernel/entry64.S
arch/s390/kernel/head.S
arch/s390/kernel/head31.S [new file with mode: 0644]
arch/s390/kernel/head64.S
arch/s390/kernel/time.c
arch/s390/kernel/traps.c
arch/s390/mm/extmem.c
arch/s390/mm/fault.c
arch/sh/Kconfig
arch/sh/Makefile
arch/sh/drivers/Makefile
arch/sh/drivers/superhyway/Makefile [new file with mode: 0644]
arch/sh/drivers/superhyway/ops-sh4-202.c [new file with mode: 0644]
arch/sh/kernel/ptrace.c
arch/sh/kernel/setup.c
arch/sh/mm/init.c
arch/sh/mm/tlb-sh3.c
arch/sh/ramdisk/Makefile [deleted file]
arch/sh/ramdisk/ld.script [deleted file]
arch/sh64/kernel/ptrace.c
arch/sh64/kernel/syscalls.S
arch/sparc64/Kconfig
arch/sparc64/Kconfig.debug
arch/sparc64/kernel/kprobes.c
arch/sparc64/kernel/us2e_cpufreq.c
arch/sparc64/kernel/us3_cpufreq.c
arch/sparc64/oprofile/Kconfig
arch/um/Kconfig
arch/um/Makefile
arch/um/Makefile-i386
arch/um/drivers/chan_user.c
arch/um/drivers/harddog_kern.c
arch/um/drivers/harddog_user.c
arch/um/drivers/net_kern.c
arch/um/drivers/net_user.c
arch/um/drivers/port_user.c
arch/um/drivers/random.c
arch/um/drivers/slip_user.c
arch/um/drivers/slirp_user.c
arch/um/drivers/xterm.c
arch/um/include/helper.h [deleted file]
arch/um/include/mem_user.h
arch/um/include/net_user.h
arch/um/include/os.h
arch/um/include/sysdep-i386/stub.h
arch/um/include/sysdep-x86_64/stub.h
arch/um/include/uml_uaccess.h
arch/um/kernel/Makefile
arch/um/kernel/ksyms.c
arch/um/kernel/mem.c
arch/um/kernel/physmem.c
arch/um/kernel/ptrace.c
arch/um/kernel/sigio_user.c
arch/um/kernel/skas/include/mmu-skas.h
arch/um/kernel/skas/include/skas.h
arch/um/kernel/skas/mem.c
arch/um/kernel/skas/mmu.c
arch/um/kernel/skas/process.c
arch/um/kernel/skas/process_kern.c
arch/um/kernel/tt/uaccess_user.c
arch/um/kernel/uaccess.c [new file with mode: 0644]
arch/um/kernel/uaccess_user.c [deleted file]
arch/um/kernel/um_arch.c
arch/um/kernel/user_util.c
arch/um/os-Linux/Makefile
arch/um/os-Linux/aio.c
arch/um/os-Linux/drivers/ethertap_user.c
arch/um/os-Linux/drivers/tuntap_user.c
arch/um/os-Linux/helper.c [moved from arch/um/kernel/helper.c with 93% similarity]
arch/um/os-Linux/main.c [moved from arch/um/kernel/main.c with 82% similarity]
arch/um/os-Linux/mem.c
arch/um/os-Linux/start_up.c
arch/um/os-Linux/uaccess.c [new file with mode: 0644]
arch/um/scripts/Makefile.rules
arch/um/sys-i386/ldt.c
arch/um/sys-x86_64/Makefile
arch/um/sys-x86_64/syscalls.c
arch/v850/kernel/ptrace.c
arch/x86_64/Kconfig
arch/x86_64/Kconfig.debug
arch/x86_64/kernel/kprobes.c
arch/x86_64/kernel/ptrace.c
arch/x86_64/kernel/smpboot.c
arch/x86_64/oprofile/Kconfig
arch/xtensa/kernel/ptrace.c
drivers/Makefile
drivers/acpi/container.c
drivers/acpi/osl.c
drivers/acpi/scan.c
drivers/acpi/video.c
drivers/base/power/sysfs.c
drivers/block/DAC960.c
drivers/block/as-iosched.c
drivers/block/cciss.c
drivers/block/ll_rw_blk.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_bcsp.c
drivers/bluetooth/hci_h4.c
drivers/bluetooth/hci_ldisc.c
drivers/bluetooth/hci_usb.c
drivers/bluetooth/hci_vhci.c
drivers/cdrom/mcdx.c
drivers/char/agp/amd64-agp.c
drivers/char/consolemap.c
drivers/char/drm/ffb_context.c
drivers/char/drm/ffb_drv.c
drivers/char/ip2/i2ellis.c
drivers/char/ipmi/ipmi_bt_sm.c
drivers/char/ipmi/ipmi_kcs_sm.c
drivers/char/ipmi/ipmi_msghandler.c
drivers/char/ipmi/ipmi_poweroff.c
drivers/char/ipmi/ipmi_si_intf.c
drivers/char/ipmi/ipmi_si_sm.h
drivers/char/ipmi/ipmi_smic_sm.c
drivers/char/ipmi/ipmi_watchdog.c
drivers/char/istallion.c
drivers/char/mxser.c
drivers/char/n_hdlc.c
drivers/char/pcmcia/synclink_cs.c
drivers/char/rocket.c
drivers/char/selection.c
drivers/char/stallion.c
drivers/char/synclink.c
drivers/char/synclinkmp.c
drivers/char/tpm/tpm_nsc.c
drivers/char/tty_io.c
drivers/char/vt_ioctl.c
drivers/connector/Kconfig
drivers/connector/Makefile
drivers/connector/cn_proc.c [new file with mode: 0644]
drivers/dio/dio.c
drivers/eisa/eisa-bus.c
drivers/fc4/fc.c
drivers/fc4/soc.c
drivers/fc4/socal.c
drivers/firmware/dell_rbu.c
drivers/firmware/edd.c
drivers/firmware/efivars.c
drivers/hwmon/hwmon.c
drivers/hwmon/max1619.c
drivers/hwmon/w83781d.c
drivers/i2c/busses/i2c-amd756-s4882.c
drivers/ide/ide-cd.c
drivers/ide/ide-disk.c
drivers/ide/ide-floppy.c
drivers/ide/ide-probe.c
drivers/ide/ide-tape.c
drivers/ide/ide-taskfile.c
drivers/ide/ide.c
drivers/ide/legacy/ide-cs.c
drivers/ide/pci/hpt366.c
drivers/ide/pci/it821x.c
drivers/ieee1394/amdtp.c
drivers/infiniband/core/agent.c
drivers/infiniband/core/mad.c
drivers/infiniband/core/packer.c
drivers/infiniband/core/sysfs.c
drivers/infiniband/core/ud_header.c
drivers/infiniband/core/verbs.c
drivers/infiniband/hw/mthca/mthca_catas.c
drivers/infiniband/hw/mthca/mthca_srq.c
drivers/input/misc/uinput.c
drivers/isdn/hardware/avm/avm_cs.c
drivers/isdn/hisax/avm_pci.c
drivers/isdn/hisax/avma1_cs.c
drivers/isdn/hisax/config.c
drivers/isdn/hisax/hfc_2bds0.c
drivers/isdn/hisax/hfc_2bs0.c
drivers/isdn/hisax/hfc_usb.c
drivers/isdn/hisax/hfc_usb.h
drivers/isdn/hisax/hscx.c
drivers/isdn/hisax/icc.c
drivers/isdn/hisax/ipacx.c
drivers/isdn/hisax/isac.c
drivers/isdn/hisax/isar.c
drivers/isdn/hisax/jade.c
drivers/isdn/hisax/netjet.c
drivers/isdn/hisax/st5481_usb.c
drivers/isdn/hisax/w6692.c
drivers/isdn/hysdn/hysdn_procconf.c
drivers/isdn/i4l/isdn_ppp.c
drivers/isdn/i4l/isdn_tty.c
drivers/isdn/icn/icn.c
drivers/isdn/isdnloop/isdnloop.c
drivers/isdn/pcbit/drv.c
drivers/isdn/sc/init.c
drivers/isdn/sc/message.c
drivers/macintosh/adbhid.c
drivers/macintosh/therm_pm72.c
drivers/md/raid5.c
drivers/md/raid6main.c
drivers/media/dvb/bt8xx/dst.c
drivers/media/dvb/frontends/cx24110.c
drivers/media/dvb/frontends/dvb_dummy_fe.c
drivers/media/dvb/frontends/l64781.c
drivers/media/dvb/frontends/lgdt330x.c
drivers/media/dvb/frontends/mt312.c
drivers/media/dvb/frontends/or51132.c
drivers/media/video/arv.c
drivers/media/video/bttv-driver.c
drivers/media/video/msp3400.c
drivers/media/video/saa7134/saa7134-tvaudio.c
drivers/media/video/v4l1-compat.c
drivers/media/video/videocodec.c
drivers/media/video/videodev.c
drivers/media/video/zoran_card.c
drivers/media/video/zoran_driver.c
drivers/message/fusion/mptlan.c
drivers/message/fusion/mptscsih.c
drivers/message/i2o/exec-osm.c
drivers/message/i2o/iop.c
drivers/mfd/mcp-core.c
drivers/mmc/wbsd.c
drivers/mtd/chips/cfi_cmdset_0001.c
drivers/mtd/chips/cfi_cmdset_0002.c
drivers/mtd/devices/blkmtd.c
drivers/mtd/inftlcore.c
drivers/mtd/inftlmount.c
drivers/mtd/maps/amd76xrom.c
drivers/mtd/maps/bast-flash.c
drivers/mtd/maps/ceiva.c
drivers/mtd/maps/ichxrom.c
drivers/mtd/maps/integrator-flash.c
drivers/mtd/maps/ipaq-flash.c
drivers/mtd/maps/iq80310.c
drivers/mtd/maps/ixp2000.c
drivers/mtd/maps/ixp4xx.c
drivers/mtd/maps/lubbock-flash.c
drivers/mtd/maps/omap-toto-flash.c
drivers/mtd/maps/sa1100-flash.c
drivers/mtd/maps/sun_uflash.c
drivers/mtd/maps/tqm8xxl.c
drivers/mtd/nand/nand_base.c
drivers/mtd/nftlcore.c
drivers/net/3c59x.c
drivers/net/fec.c
drivers/net/fec.h
drivers/parport/probe.c
drivers/parport/share.c
drivers/pci/hotplug/cpqphp_pci.c
drivers/pci/hotplug/pciehprm_nonacpi.c
drivers/pci/pci-driver.c
drivers/pcmcia/cistpl.c
drivers/pcmcia/cs.c
drivers/pnp/card.c
drivers/pnp/core.c
drivers/pnp/driver.c
drivers/pnp/isapnp/core.c
drivers/pnp/manager.c
drivers/pnp/pnpacpi/core.c
drivers/pnp/resource.c
drivers/rapidio/Kconfig [new file with mode: 0644]
drivers/rapidio/Makefile [new file with mode: 0644]
drivers/rapidio/rio-access.c [new file with mode: 0644]
drivers/rapidio/rio-driver.c [new file with mode: 0644]
drivers/rapidio/rio-scan.c [new file with mode: 0644]
drivers/rapidio/rio-sysfs.c [new file with mode: 0644]
drivers/rapidio/rio.c [new file with mode: 0644]
drivers/rapidio/rio.h [new file with mode: 0644]
drivers/rapidio/switches/Makefile [new file with mode: 0644]
drivers/rapidio/switches/tsi500.c [new file with mode: 0644]
drivers/s390/block/dasd.c
drivers/s390/block/dasd_devmap.c
drivers/s390/block/dasd_diag.c
drivers/s390/block/dasd_diag.h
drivers/s390/char/con3215.c
drivers/s390/char/keyboard.c
drivers/s390/char/raw3270.c
drivers/s390/char/tape_core.c
drivers/s390/char/vmcp.c
drivers/s390/cio/ccwgroup.c
drivers/s390/cio/cmf.c
drivers/s390/cio/device_ops.c
drivers/s390/cio/qdio.c
drivers/s390/crypto/z90main.c
drivers/s390/net/claw.c
drivers/s390/net/fsm.c
drivers/s390/net/iucv.c
drivers/s390/net/lcs.c
drivers/s390/net/qeth_eddp.c
drivers/s390/scsi/zfcp_aux.c
drivers/sbus/char/envctrl.c
drivers/scsi/3w-9xxx.c
drivers/scsi/NCR5380.c
drivers/scsi/aacraid/commsup.c
drivers/scsi/aacraid/rkt.c
drivers/scsi/aacraid/rx.c
drivers/scsi/aacraid/sa.c
drivers/scsi/advansys.c
drivers/scsi/aha1542.c
drivers/scsi/aic7xxx_old.c
drivers/scsi/arm/queue.c
drivers/scsi/atari_dma_emul.c
drivers/scsi/dc395x.c
drivers/scsi/dpt_i2o.c
drivers/scsi/eata.c
drivers/scsi/ide-scsi.c
drivers/scsi/ips.c
drivers/scsi/lpfc/lpfc_els.c
drivers/scsi/lpfc/lpfc_init.c
drivers/scsi/lpfc/lpfc_mbox.c
drivers/scsi/lpfc/lpfc_scsi.c
drivers/scsi/lpfc/lpfc_sli.c
drivers/scsi/megaraid/megaraid_mbox.c
drivers/scsi/megaraid/megaraid_mm.c
drivers/scsi/osst.c
drivers/scsi/qla2xxx/qla_init.c
drivers/scsi/raid_class.c
drivers/scsi/scsi_transport_sas.c
drivers/scsi/sg.c
drivers/scsi/st.c
drivers/scsi/sym53c8xx_2/sym_hipd.c
drivers/scsi/u14-34f.c
drivers/serial/8250.c
drivers/serial/crisv10.c
drivers/serial/mcfserial.c
drivers/sh/superhyway/superhyway-sysfs.c
drivers/sh/superhyway/superhyway.c
drivers/video/68328fb.c
drivers/video/Kconfig
drivers/video/Makefile
drivers/video/acornfb.c
drivers/video/amba-clcd.c
drivers/video/amifb.c
drivers/video/arcfb.c
drivers/video/asiliantfb.c
drivers/video/aty/ati_ids.h
drivers/video/aty/aty128fb.c
drivers/video/aty/atyfb_base.c
drivers/video/aty/radeon_base.c
drivers/video/aty/radeonfb.h
drivers/video/bw2.c
drivers/video/cfbcopyarea.c
drivers/video/cfbfillrect.c
drivers/video/cfbimgblt.c
drivers/video/cg14.c
drivers/video/cg3.c
drivers/video/cg6.c
drivers/video/chipsfb.c
drivers/video/cirrusfb.c
drivers/video/clps711xfb.c
drivers/video/console/Kconfig
drivers/video/console/Makefile
drivers/video/console/bitblit.c
drivers/video/console/fbcon.c
drivers/video/console/fbcon.h
drivers/video/console/font_rl.c [new file with mode: 0644]
drivers/video/console/fonts.c
drivers/video/console/softcursor.c [moved from drivers/video/softcursor.c with 97% similarity]
drivers/video/controlfb.c
drivers/video/cyber2000fb.c
drivers/video/cyblafb.c
drivers/video/dnfb.c
drivers/video/epson1355fb.c
drivers/video/fbmon.c
drivers/video/ffb.c
drivers/video/fm2fb.c
drivers/video/gbefb.c
drivers/video/geode/Kconfig
drivers/video/geode/gx1fb_core.c
drivers/video/hitfb.c
drivers/video/hpfb.c
drivers/video/i810/i810-i2c.c
drivers/video/i810/i810.h
drivers/video/i810/i810_main.c
drivers/video/i810/i810_regs.h
drivers/video/imsttfb.c
drivers/video/imxfb.c
drivers/video/intelfb/intelfb.h
drivers/video/intelfb/intelfbdrv.c
drivers/video/intelfb/intelfbhw.c
drivers/video/kyro/fbdev.c
drivers/video/leo.c
drivers/video/logo/Kconfig
drivers/video/macfb.c
drivers/video/matrox/matroxfb_DAC1064.c
drivers/video/matrox/matroxfb_accel.c
drivers/video/matrox/matroxfb_base.c
drivers/video/matrox/matroxfb_base.h
drivers/video/matrox/matroxfb_crtc2.c
drivers/video/maxinefb.c
drivers/video/modedb.c
drivers/video/neofb.c
drivers/video/nvidia/nv_local.h
drivers/video/nvidia/nv_of.c
drivers/video/nvidia/nv_proto.h
drivers/video/nvidia/nv_setup.c
drivers/video/nvidia/nvidia.c
drivers/video/offb.c
drivers/video/p9100.c
drivers/video/platinumfb.c
drivers/video/pm2fb.c
drivers/video/pmag-ba-fb.c
drivers/video/pmagb-b-fb.c
drivers/video/pvr2fb.c
drivers/video/pxafb.c
drivers/video/q40fb.c
drivers/video/radeonfb.c
drivers/video/s1d13xxxfb.c
drivers/video/s3c2410fb.c
drivers/video/sa1100fb.c
drivers/video/savage/savagefb.h
drivers/video/savage/savagefb_driver.c
drivers/video/sgivwfb.c
drivers/video/sis/sis_main.c
drivers/video/skeletonfb.c
drivers/video/sstfb.c
drivers/video/stifb.c
drivers/video/tcx.c
drivers/video/tdfxfb.c
drivers/video/tgafb.c
drivers/video/tridentfb.c
drivers/video/tx3912fb.c
drivers/video/valkyriefb.c
drivers/video/vesafb.c
drivers/video/vfb.c
drivers/video/vga16fb.c
drivers/video/w100fb.c
drivers/w1/w1_ds2433.c
fs/9p/error.c
fs/9p/trans_sock.c
fs/9p/v9fs.c
fs/9p/vfs_inode.c
fs/Kconfig
fs/affs/file.c
fs/affs/super.c
fs/afs/file.c
fs/afs/inode.c
fs/afs/internal.h
fs/aio.c
fs/autofs/waitq.c
fs/autofs4/inode.c
fs/autofs4/waitq.c
fs/befs/linuxvfs.c
fs/binfmt_elf.c
fs/binfmt_elf_fdpic.c
fs/buffer.c
fs/cifs/asn1.c
fs/cifs/connect.c
fs/cifs/link.c
fs/cifs/misc.c
fs/cifs/xattr.c
fs/compat_ioctl.c
fs/dcache.c
fs/devfs/base.c
fs/dquot.c
fs/exec.c
fs/ext2/acl.c
fs/file_table.c
fs/freevxfs/vxfs_extern.h
fs/freevxfs/vxfs_inode.c
fs/fs-writeback.c
fs/fuse/dev.c
fs/fuse/dir.c
fs/fuse/file.c
fs/fuse/fuse_i.h
fs/hostfs/hostfs_kern.c
fs/hpfs/dnode.c
fs/hpfs/super.c
fs/isofs/inode.c
fs/jbd/commit.c
fs/jbd/recovery.c
fs/jbd/transaction.c
fs/jffs/intrep.c
fs/jffs2/readinode.c
fs/jffs2/wbuf.c
fs/lockd/clntproc.c
fs/mbcache.c
fs/namei.c
fs/nfs/delegation.c
fs/nfs/inode.c
fs/nfs/nfs4state.c
fs/nfs/unlink.c
fs/nfsd/export.c
fs/nfsd/nfs3xdr.c
fs/nfsd/nfs4xdr.c
fs/nfsd/nfscache.c
fs/nfsd/nfsctl.c
fs/nfsd/nfssvc.c
fs/nfsd/vfs.c
fs/open.c
fs/openpromfs/inode.c
fs/partitions/ibm.c
fs/quota.c
fs/smbfs/request.c
fs/smbfs/symlink.c
fs/super.c
fs/udf/udf_sb.h
fs/ufs/super.c
fs/xattr.c
fs/xfs/linux-2.6/kmem.h
include/asm-alpha/pgtable.h
include/asm-alpha/ptrace.h
include/asm-cris/arch-v10/byteorder.h
include/asm-cris/arch-v10/checksum.h
include/asm-cris/arch-v10/delay.h
include/asm-cris/arch-v10/ide.h
include/asm-cris/arch-v10/system.h
include/asm-cris/arch-v10/thread_info.h
include/asm-cris/arch-v10/timex.h
include/asm-cris/arch-v10/uaccess.h
include/asm-cris/arch-v32/bitops.h
include/asm-cris/arch-v32/byteorder.h
include/asm-cris/arch-v32/checksum.h
include/asm-cris/arch-v32/delay.h
include/asm-cris/arch-v32/ide.h
include/asm-cris/arch-v32/io.h
include/asm-cris/arch-v32/system.h
include/asm-cris/arch-v32/thread_info.h
include/asm-cris/arch-v32/timex.h
include/asm-cris/arch-v32/uaccess.h
include/asm-cris/atomic.h
include/asm-cris/bitops.h
include/asm-cris/checksum.h
include/asm-cris/current.h
include/asm-cris/delay.h
include/asm-cris/io.h
include/asm-cris/irq.h
include/asm-cris/pgalloc.h
include/asm-cris/pgtable.h
include/asm-cris/processor.h
include/asm-cris/semaphore.h
include/asm-cris/system.h
include/asm-cris/timex.h
include/asm-cris/tlbflush.h
include/asm-cris/uaccess.h
include/asm-cris/unistd.h
include/asm-frv/pgtable.h
include/asm-generic/pgtable.h
include/asm-generic/vmlinux.lds.h
include/asm-i386/elf.h
include/asm-i386/kprobes.h
include/asm-i386/pgtable.h
include/asm-i386/processor.h
include/asm-ia64/dma-mapping.h
include/asm-ia64/kprobes.h
include/asm-ia64/pgtable.h
include/asm-ia64/ptrace.h
include/asm-m32r/pgtable.h
include/asm-m32r/ptrace.h
include/asm-m68knommu/cacheflush.h
include/asm-m68knommu/irq.h
include/asm-m68knommu/irqnode.h [new file with mode: 0644]
include/asm-mips/elf.h
include/asm-mips/pgtable.h
include/asm-parisc/pgtable.h
include/asm-powerpc/elf.h
include/asm-powerpc/kprobes.h
include/asm-ppc/ibm44x.h
include/asm-ppc/ibm4xx.h
include/asm-ppc/ibm_ocp.h
include/asm-ppc/pgtable.h
include/asm-ppc/ppcboot.h
include/asm-ppc/rio.h [new file with mode: 0644]
include/asm-ppc64/pgtable-4k.h
include/asm-ppc64/pgtable-64k.h
include/asm-ppc64/pgtable.h
include/asm-s390/bitops.h
include/asm-s390/elf.h
include/asm-s390/pgtable.h
include/asm-s390/ptrace.h
include/asm-s390/uaccess.h
include/asm-s390/vtoc.h
include/asm-sh/elf.h
include/asm-sh/mmzone.h [deleted file]
include/asm-sh/page.h
include/asm-sh/pgtable.h
include/asm-sh64/pgtable.h
include/asm-sparc/ptrace.h
include/asm-sparc64/kprobes.h
include/asm-sparc64/ptrace.h
include/asm-um/ldt-i386.h [new file with mode: 0644]
include/asm-um/ldt.h
include/asm-um/mmu_context.h
include/asm-v850/atomic.h
include/asm-v850/bitops.h
include/asm-v850/delay.h
include/asm-v850/hw_irq.h
include/asm-v850/processor.h
include/asm-v850/semaphore.h
include/asm-v850/system.h
include/asm-v850/tlbflush.h
include/asm-v850/uaccess.h
include/asm-v850/unaligned.h
include/asm-x86_64/elf.h
include/asm-x86_64/kprobes.h
include/asm-x86_64/pgtable.h
include/asm-xtensa/elf.h
include/asm-xtensa/pgtable.h
include/asm-xtensa/semaphore.h
include/linux/aio.h
include/linux/cn_proc.h [new file with mode: 0644]
include/linux/connector.h
include/linux/console_struct.h
include/linux/fb.h
include/linux/file.h
include/linux/font.h
include/linux/fs.h
include/linux/fuse.h
include/linux/ioport.h
include/linux/ipmi.h
include/linux/irq.h
include/linux/jbd.h
include/linux/kernel.h
include/linux/kernel_stat.h
include/linux/kprobes.h
include/linux/list.h
include/linux/memory.h
include/linux/mm.h
include/linux/net.h
include/linux/nfsd/nfsd.h
include/linux/nfsd/syscall.h
include/linux/nfsd/xdr3.h
include/linux/pci_ids.h
include/linux/pnp.h
include/linux/ptrace.h
include/linux/quotaops.h
include/linux/radix-tree.h
include/linux/rio.h [new file with mode: 0644]
include/linux/rio_drv.h [new file with mode: 0644]
include/linux/rio_ids.h [new file with mode: 0644]
include/linux/rio_regs.h [new file with mode: 0644]
include/linux/sem.h
include/linux/shm.h
include/linux/slab.h
include/linux/sunrpc/svc.h
include/linux/superhyway.h
include/linux/wait.h
ipc/shm.c
ipc/util.c
kernel/exit.c
kernel/fork.c
kernel/futex.c
kernel/irq/manage.c
kernel/kprobes.c
kernel/module.c
kernel/posix-cpu-timers.c
kernel/power/snapshot.c
kernel/power/swsusp.c
kernel/printk.c
kernel/ptrace.c
kernel/sched.c
kernel/softirq.c
kernel/softlockup.c
kernel/sys.c
kernel/sysctl.c
kernel/workqueue.c
lib/radix-tree.c
mm/Kconfig
mm/hugetlb.c
mm/mmap.c
mm/nommu.c
mm/page-writeback.c
mm/page_alloc.c
mm/readahead.c
mm/slab.c
mm/swap.c
mm/swap_state.c
mm/swapfile.c
mm/vmalloc.c
net/sunrpc/svc.c
scripts/kconfig/Makefile
security/keys/key.c
security/keys/keyring.c
security/selinux/ss/policydb.c
sound/oss/sequencer_syms.c

index 783ddc3ce4e821a8b8c2a04881e494ab4f503c2c..86b86399d61d7237aab919f87867bd984dddaa25 100644 (file)
@@ -139,9 +139,14 @@ You'll probably want to upgrade.
 Ksymoops
 --------
 
-If the unthinkable happens and your kernel oopses, you'll need a 2.4
-version of ksymoops to decode the report; see REPORTING-BUGS in the
-root of the Linux source for more information.
+If the unthinkable happens and your kernel oopses, you may need the
+ksymoops tool to decode it, but in most cases you don't.
+In the 2.6 kernel it is generally preferred to build the kernel with
+CONFIG_KALLSYMS so that it produces readable dumps that can be used as-is
+(this also produces better output than ksymoops).
+If for some reason your kernel is not build with CONFIG_KALLSYMS and
+you have no way to rebuild and reproduce the Oops with that option, then
+you can still decode that Oops with ksymoops.
 
 Module-Init-Tools
 -----------------
index fa3e29ad8a463855c48241fb49ebfd3fd8ba86bb..7018f5c6a447b392a8ccd316d49380ce5307e936 100644 (file)
@@ -10,7 +10,7 @@ DOCBOOKS := wanbook.xml z8530book.xml mcabook.xml videobook.xml \
            kernel-hacking.xml kernel-locking.xml deviceiobook.xml \
            procfs-guide.xml writing_usb_driver.xml \
            sis900.xml kernel-api.xml journal-api.xml lsm.xml usb.xml \
-           gadget.xml libata.xml mtdnand.xml librs.xml
+           gadget.xml libata.xml mtdnand.xml librs.xml rapidio.xml
 
 ###
 # The build process is as follows (targets):
index 341aaa4ce481a5a9af1f85d17be35e83e2b8b075..2077f9a28c191bdba263271e649f015485052926 100644 (file)
@@ -306,7 +306,7 @@ an example.
 </para>
        <sect1><title>Journal Level</title>
 !Efs/jbd/journal.c
-!Efs/jbd/recovery.c
+!Ifs/jbd/recovery.c
        </sect1>
        <sect1><title>Transasction Level</title>
 !Efs/jbd/transaction.c 
index ec474e5a25ed39db151790e83bfe6e882fc34ffa..a8316b1a3e3d45e3368a1a4b3dddb732bab65b32 100644 (file)
@@ -118,7 +118,7 @@ X!Ilib/string.c
      </sect1>
      <sect1><title>User Space Memory Access</title>
 !Iinclude/asm-i386/uaccess.h
-!Iarch/i386/lib/usercopy.c
+!Earch/i386/lib/usercopy.c
      </sect1>
      <sect1><title>More Memory Management Functions</title>
 !Iinclude/linux/rmap.h
@@ -174,7 +174,6 @@ X!Ilib/string.c
      <title>The Linux VFS</title>
      <sect1><title>The Filesystem types</title>
 !Iinclude/linux/fs.h
-!Einclude/linux/fs.h
      </sect1>
      <sect1><title>The Directory Cache</title>
 !Efs/dcache.c
@@ -266,7 +265,7 @@ X!Ekernel/module.c
   <chapter id="hardware">
      <title>Hardware Interfaces</title>
      <sect1><title>Interrupt Handling</title>
-!Ikernel/irq/manage.c
+!Ekernel/irq/manage.c
      </sect1>
 
      <sect1><title>Resources Management</title>
@@ -501,7 +500,7 @@ KAO -->
 !Edrivers/video/modedb.c
      </sect1>
      <sect1><title>Frame Buffer Macintosh Video Mode Database</title>
-!Idrivers/video/macmodes.c
+!Edrivers/video/macmodes.c
      </sect1>
      <sect1><title>Frame Buffer Fonts</title>
         <para>
diff --git a/Documentation/DocBook/rapidio.tmpl b/Documentation/DocBook/rapidio.tmpl
new file mode 100644 (file)
index 0000000..1becf27
--- /dev/null
@@ -0,0 +1,160 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
+        "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
+       <!ENTITY rapidio SYSTEM "rapidio.xml">
+       ]>
+
+<book id="RapidIO-Guide">
+ <bookinfo>
+  <title>RapidIO Subsystem Guide</title>
+
+  <authorgroup>
+   <author>
+    <firstname>Matt</firstname>
+    <surname>Porter</surname>
+    <affiliation>
+     <address>
+      <email>mporter@kernel.crashing.org</email>
+      <email>mporter@mvista.com</email>
+     </address>
+    </affiliation>
+   </author>
+  </authorgroup>
+
+  <copyright>
+   <year>2005</year>
+   <holder>MontaVista Software, Inc.</holder>
+  </copyright>
+
+  <legalnotice>
+   <para>
+     This documentation 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.
+   </para>
+
+   <para>
+     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.
+   </para>
+
+   <para>
+     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
+   </para>
+
+   <para>
+     For more details see the file COPYING in the source
+     distribution of Linux.
+   </para>
+  </legalnotice>
+ </bookinfo>
+
+<toc></toc>
+
+  <chapter id="intro">
+      <title>Introduction</title>
+  <para>
+       RapidIO is a high speed switched fabric interconnect with
+       features aimed at the embedded market.  RapidIO provides
+       support for memory-mapped I/O as well as message-based
+       transactions over the switched fabric network. RapidIO has
+       a standardized discovery mechanism not unlike the PCI bus
+       standard that allows simple detection of devices in a
+       network.
+  </para>
+  <para>
+       This documentation is provided for developers intending
+       to support RapidIO on new architectures, write new drivers,
+       or to understand the subsystem internals.
+  </para>
+  </chapter>
+
+  <chapter id="bugs">
+     <title>Known Bugs and Limitations</title>
+
+     <sect1>
+       <title>Bugs</title>
+         <para>None. ;)</para>
+     </sect1>
+     <sect1>
+       <title>Limitations</title>
+         <para>
+           <orderedlist>
+             <listitem><para>Access/management of RapidIO memory regions is not supported</para></listitem>
+             <listitem><para>Multiple host enumeration is not supported</para></listitem>
+           </orderedlist>
+        </para>
+     </sect1>
+  </chapter>
+
+  <chapter id="drivers">
+       <title>RapidIO driver interface</title>
+       <para>
+               Drivers are provided a set of calls in order
+               to interface with the subsystem to gather info
+               on devices, request/map memory region resources,
+               and manage mailboxes/doorbells.
+       </para>
+       <sect1>
+               <title>Functions</title>
+!Iinclude/linux/rio_drv.h
+!Edrivers/rapidio/rio-driver.c
+!Edrivers/rapidio/rio.c
+       </sect1>
+  </chapter>
+
+  <chapter id="internals">
+     <title>Internals</title>
+
+     <para>
+     This chapter contains the autogenerated documentation of the RapidIO
+     subsystem.
+     </para>
+
+     <sect1><title>Structures</title>
+!Iinclude/linux/rio.h
+     </sect1>
+     <sect1><title>Enumeration and Discovery</title>
+!Idrivers/rapidio/rio-scan.c
+     </sect1>
+     <sect1><title>Driver functionality</title>
+!Idrivers/rapidio/rio.c
+!Idrivers/rapidio/rio-access.c
+     </sect1>
+     <sect1><title>Device model support</title>
+!Idrivers/rapidio/rio-driver.c
+     </sect1>
+     <sect1><title>Sysfs support</title>
+!Idrivers/rapidio/rio-sysfs.c
+     </sect1>
+     <sect1><title>PPC32 support</title>
+!Iarch/ppc/kernel/rio.c
+!Earch/ppc/syslib/ppc85xx_rio.c
+!Iarch/ppc/syslib/ppc85xx_rio.c
+     </sect1>
+  </chapter>
+
+  <chapter id="credits">
+     <title>Credits</title>
+       <para>
+               The following people have contributed to the RapidIO
+               subsystem directly or indirectly:
+               <orderedlist>
+                       <listitem><para>Matt Porter<email>mporter@kernel.crashing.org</email></para></listitem>
+                       <listitem><para>Randy Vinson<email>rvinson@mvista.com</email></para></listitem>
+                       <listitem><para>Dan Malek<email>dan@embeddedalley.com</email></para></listitem>
+               </orderedlist>
+       </para>
+       <para>
+               The following people have contributed to this document:
+               <orderedlist>
+                       <listitem><para>Matt Porter<email>mporter@kernel.crashing.org</email></para></listitem>
+               </orderedlist>
+       </para>
+  </chapter>
+</book>
index 63edc5f847c45a4b1771c4e35872317ca2bbcbc7..3ec6c720b0166b4a76c576391414c795898d47b5 100644 (file)
 This guide describes the basics of Message Signaled Interrupts (MSI),
 the advantages of using MSI over traditional interrupt mechanisms,
 and how to enable your driver to use MSI or MSI-X. Also included is
-a Frequently Asked Questions.
+a Frequently Asked Questions (FAQ) section.
+
+1.1 Terminology
+
+PCI devices can be single-function or multi-function.  In either case,
+when this text talks about enabling or disabling MSI on a "device
+function," it is referring to one specific PCI device and function and
+not to all functions on a PCI device (unless the PCI device has only
+one function).
 
 2. Copyright 2003 Intel Corporation
 
 3. What is MSI/MSI-X?
 
 Message Signaled Interrupt (MSI), as described in the PCI Local Bus
-Specification Revision 2.3 or latest, is an optional feature, and a
+Specification Revision 2.3 or later, is an optional feature, and a
 required feature for PCI Express devices. MSI enables a device function
 to request service by sending an Inbound Memory Write on its PCI bus to
 the FSB as a Message Signal Interrupt transaction. Because MSI is
@@ -27,7 +35,7 @@ supported.
 
 A PCI device that supports MSI must also support pin IRQ assertion
 interrupt mechanism to provide backward compatibility for systems that
-do not support MSI. In Systems, which support MSI, the bus driver is
+do not support MSI. In systems which support MSI, the bus driver is
 responsible for initializing the message address and message data of
 the device function's MSI/MSI-X capability structure during device
 initial configuration.
@@ -61,17 +69,17 @@ over the MSI capability structure as described below.
 
         - MSI and MSI-X both support per-vector masking. Per-vector
        masking is an optional extension of MSI but a required
-       feature for MSI-X. Per-vector masking provides the kernel
-       the ability to mask/unmask MSI when servicing its software
-       interrupt service routing handler. If per-vector masking is
+       feature for MSI-X. Per-vector masking provides the kernel the
+       ability to mask/unmask a single MSI while running its
+       interrupt service routine. If per-vector masking is
        not supported, then the device driver should provide the
        hardware/software synchronization to ensure that the device
        generates MSI when the driver wants it to do so.
 
 4. Why use MSI?
 
-As a benefit the simplification of board design, MSI allows board
-designers to remove out of band interrupt routing. MSI is another
+As a benefit to the simplification of board design, MSI allows board
+designers to remove out-of-band interrupt routing. MSI is another
 step towards a legacy-free environment.
 
 Due to increasing pressure on chipset and processor packages to
@@ -87,7 +95,7 @@ support. As a result, the PCI Express technology requires MSI
 support for better interrupt performance.
 
 Using MSI enables the device functions to support two or more
-vectors, which can be configured to target different CPU's to
+vectors, which can be configured to target different CPUs to
 increase scalability.
 
 5. Configuring a driver to use MSI/MSI-X
@@ -119,13 +127,13 @@ pci_enable_msi() explicitly.
 
 int pci_enable_msi(struct pci_dev *dev)
 
-With this new API, any existing device driver, which like to have
-MSI enabled on its device function, must call this API to enable MSI
+With this new API, a device driver that wants to have MSI
+enabled on its device function must call this API to enable MSI.
 A successful call will initialize the MSI capability structure
 with ONE vector, regardless of whether a device function is
 capable of supporting multiple messages. This vector replaces the
-pre-assigned dev->irq with a new MSI vector. To avoid the conflict
-of new assigned vector with existing pre-assigned vector requires
+pre-assigned dev->irq with a new MSI vector. To avoid a conflict
+of the new assigned vector with existing pre-assigned vector requires
 a device driver to call this API before calling request_irq().
 
 5.2.2 API pci_disable_msi
@@ -137,14 +145,14 @@ when a device driver is unloading. This API restores dev->irq with
 the pre-assigned IOAPIC vector and switches a device's interrupt
 mode to PCI pin-irq assertion/INTx emulation mode.
 
-Note that a device driver should always call free_irq() on MSI vector
-it has done request_irq() on before calling this API. Failure to do
-so results a BUG_ON() and a device will be left with MSI enabled and
+Note that a device driver should always call free_irq() on the MSI vector
+that it has done request_irq() on before calling this API. Failure to do
+so results in a BUG_ON() and a device will be left with MSI enabled and
 leaks its vector.
 
 5.2.3 MSI mode vs. legacy mode diagram
 
-The below diagram shows the events, which switches the interrupt
+The below diagram shows the events which switch the interrupt
 mode on the MSI-capable device function between MSI mode and
 PIN-IRQ assertion mode.
 
@@ -155,9 +163,9 @@ PIN-IRQ assertion mode.
         ------------   pci_disable_msi  ------------------------
 
 
-Figure 1.0 MSI Mode vs. Legacy Mode
+Figure 1. MSI Mode vs. Legacy Mode
 
-In Figure 1.0, a device operates by default in legacy mode. Legacy
+In Figure 1, a device operates by default in legacy mode. Legacy
 in this context means PCI pin-irq assertion or PCI-Express INTx
 emulation. A successful MSI request (using pci_enable_msi()) switches
 a device's interrupt mode to MSI mode. A pre-assigned IOAPIC vector
@@ -166,11 +174,11 @@ assigned MSI vector will replace dev->irq.
 
 To return back to its default mode, a device driver should always call
 pci_disable_msi() to undo the effect of pci_enable_msi(). Note that a
-device driver should always call free_irq() on MSI vector it has done
-request_irq() on before calling pci_disable_msi(). Failure to do so
-results a BUG_ON() and a device will be left with MSI enabled and
+device driver should always call free_irq() on the MSI vector it has
+done request_irq() on before calling pci_disable_msi(). Failure to do
+so results in a BUG_ON() and a device will be left with MSI enabled and
 leaks its vector. Otherwise, the PCI subsystem restores a device's
-dev->irq with a pre-assigned IOAPIC vector and marks released
+dev->irq with a pre-assigned IOAPIC vector and marks the released
 MSI vector as unused.
 
 Once being marked as unused, there is no guarantee that the PCI
@@ -178,8 +186,8 @@ subsystem will reserve this MSI vector for a device. Depending on
 the availability of current PCI vector resources and the number of
 MSI/MSI-X requests from other drivers, this MSI may be re-assigned.
 
-For the case where the PCI subsystem re-assigned this MSI vector
-another driver, a request to switching back to MSI mode may result
+For the case where the PCI subsystem re-assigns this MSI vector to
+another driver, a request to switch back to MSI mode may result
 in being assigned a different MSI vector or a failure if no more
 vectors are available.
 
@@ -208,12 +216,12 @@ Unlike the function pci_enable_msi(), the function pci_enable_msix()
 does not replace the pre-assigned IOAPIC dev->irq with a new MSI
 vector because the PCI subsystem writes the 1:1 vector-to-entry mapping
 into the field vector of each element contained in a second argument.
-Note that the pre-assigned IO-APIC dev->irq is valid only if the device
-operates in PIN-IRQ assertion mode. In MSI-X mode, any attempt of
+Note that the pre-assigned IOAPIC dev->irq is valid only if the device
+operates in PIN-IRQ assertion mode. In MSI-X mode, any attempt at
 using dev->irq by the device driver to request for interrupt service
 may result unpredictabe behavior.
 
-For each MSI-X vector granted, a device driver is responsible to call
+For each MSI-X vector granted, a device driver is responsible for calling
 other functions like request_irq(), enable_irq(), etc. to enable
 this vector with its corresponding interrupt service handler. It is
 a device driver's choice to assign all vectors with the same
@@ -224,13 +232,13 @@ service handler.
 
 The PCI 3.0 specification has implementation notes that MMIO address
 space for a device's MSI-X structure should be isolated so that the
-software system can set different page for controlling accesses to
-the MSI-X structure. The implementation of MSI patch requires the PCI
+software system can set different pages for controlling accesses to the
+MSI-X structure. The implementation of MSI support requires the PCI
 subsystem, not a device driver, to maintain full control of the MSI-X
-table/MSI-X PBA and MMIO address space of the MSI-X table/MSI-X PBA.
-A device driver is prohibited from requesting the MMIO address space
-of the MSI-X table/MSI-X PBA. Otherwise, the PCI subsystem will fail
-enabling MSI-X on its hardware device when it calls the function
+table/MSI-X PBA (Pending Bit Array) and MMIO address space of the MSI-X
+table/MSI-X PBA.  A device driver is prohibited from requesting the MMIO
+address space of the MSI-X table/MSI-X PBA. Otherwise, the PCI subsystem
+will fail enabling MSI-X on its hardware device when it calls the function
 pci_enable_msix().
 
 5.3.2 Handling MSI-X allocation
@@ -274,9 +282,9 @@ For the case where fewer MSI-X vectors are allocated to a function
 than requested, the function pci_enable_msix() will return the
 maximum number of MSI-X vectors available to the caller. A device
 driver may re-send its request with fewer or equal vectors indicated
-in a return. For example, if a device driver requests 5 vectors, but
-the number of available vectors is 3 vectors, a value of 3 will be a
-return as a result of pci_enable_msix() call. A function could be
+in the return. For example, if a device driver requests 5 vectors, but
+the number of available vectors is 3 vectors, a value of 3 will be
+returned as a result of pci_enable_msix() call. A function could be
 designed for its driver to use only 3 MSI-X table entries as
 different combinations as ABC--, A-B-C, A--CB, etc. Note that this
 patch does not support multiple entries with the same vector. Such
@@ -285,49 +293,46 @@ as ABBCC, AABCC, BCCBA, etc will result as a failure by the function
 pci_enable_msix(). Below are the reasons why supporting multiple
 entries with the same vector is an undesirable solution.
 
-       - The PCI subsystem can not determine which entry, which
-         generated the message, to mask/unmask MSI while handling
+       - The PCI subsystem cannot determine the entry that
+         generated the message to mask/unmask MSI while handling
          software driver ISR. Attempting to walk through all MSI-X
          table entries (2048 max) to mask/unmask any match vector
          is an undesirable solution.
 
-       - Walk through all MSI-X table entries (2048 max) to handle
+       - Walking through all MSI-X table entries (2048 max) to handle
          SMP affinity of any match vector is an undesirable solution.
 
 5.3.4 API pci_enable_msix
 
-int pci_enable_msix(struct pci_dev *dev, u32 *entries, int nvec)
+int pci_enable_msix(struct pci_dev *dev, struct msix_entry *entries, int nvec)
 
 This API enables a device driver to request the PCI subsystem
-for enabling MSI-X messages on its hardware device. Depending on
+to enable MSI-X messages on its hardware device. Depending on
 the availability of PCI vectors resources, the PCI subsystem enables
-either all or nothing.
+either all or none of the requested vectors.
 
-Argument dev points to the device (pci_dev) structure.
+Argument 'dev' points to the device (pci_dev) structure.
 
-Argument entries is a pointer of unsigned integer type. The number of
-elements is indicated in argument nvec. The content of each element
-will be mapped to the following struct defined in /driver/pci/msi.h.
+Argument 'entries' is a pointer to an array of msix_entry structs.
+The number of entries is indicated in argument 'nvec'.
+struct msix_entry is defined in /driver/pci/msi.h:
 
 struct msix_entry {
        u16     vector; /* kernel uses to write alloc vector */
        u16     entry; /* driver uses to specify entry */
 };
 
-A device driver is responsible for initializing the field entry of
-each element with unique entry supported by MSI-X table. Otherwise,
+A device driver is responsible for initializing the field 'entry' of
+each element with unique entry supported by MSI-X table. Otherwise,
 -EINVAL will be returned as a result. A successful return of zero
-indicates the PCI subsystem completes initializing each of requested
+indicates the PCI subsystem completed initializing each of the requested
 entries of the MSI-X table with message address and message data.
 Last but not least, the PCI subsystem will write the 1:1
-vector-to-entry mapping into the field vector of each element. A
-device driver is responsible of keeping track of allocated MSI-X
+vector-to-entry mapping into the field 'vector' of each element. A
+device driver is responsible for keeping track of allocated MSI-X
 vectors in its internal data structure.
 
-Argument nvec is an integer indicating the number of messages
-requested.
-
-A return of zero indicates that the number of MSI-X vectors is
+A return of zero indicates that the number of MSI-X vectors was
 successfully allocated. A return of greater than zero indicates
 MSI-X vector shortage. Or a return of less than zero indicates
 a failure. This failure may be a result of duplicate entries
@@ -341,12 +346,12 @@ void pci_disable_msix(struct pci_dev *dev)
 This API should always be used to undo the effect of pci_enable_msix()
 when a device driver is unloading. Note that a device driver should
 always call free_irq() on all MSI-X vectors it has done request_irq()
-on before calling this API. Failure to do so results a BUG_ON() and
+on before calling this API. Failure to do so results in a BUG_ON() and
 a device will be left with MSI-X enabled and leaks its vectors.
 
 5.3.6 MSI-X mode vs. legacy mode diagram
 
-The below diagram shows the events, which switches the interrupt
+The below diagram shows the events which switch the interrupt
 mode on the MSI-X capable device function between MSI-X mode and
 PIN-IRQ assertion mode (legacy).
 
@@ -356,22 +361,22 @@ PIN-IRQ assertion mode (legacy).
        |            | ===============>     |                        |
         ------------   pci_disable_msix     ------------------------
 
-Figure 2.0 MSI-X Mode vs. Legacy Mode
+Figure 2. MSI-X Mode vs. Legacy Mode
 
-In Figure 2.0, a device operates by default in legacy mode. A
+In Figure 2, a device operates by default in legacy mode. A
 successful MSI-X request (using pci_enable_msix()) switches a
 device's interrupt mode to MSI-X mode. A pre-assigned IOAPIC vector
 stored in dev->irq will be saved by the PCI subsystem; however,
 unlike MSI mode, the PCI subsystem will not replace dev->irq with
 assigned MSI-X vector because the PCI subsystem already writes the 1:1
-vector-to-entry mapping into the field vector of each element
+vector-to-entry mapping into the field 'vector' of each element
 specified in second argument.
 
 To return back to its default mode, a device driver should always call
 pci_disable_msix() to undo the effect of pci_enable_msix(). Note that
 a device driver should always call free_irq() on all MSI-X vectors it
 has done request_irq() on before calling pci_disable_msix(). Failure
-to do so results a BUG_ON() and a device will be left with MSI-X
+to do so results in a BUG_ON() and a device will be left with MSI-X
 enabled and leaks its vectors. Otherwise, the PCI subsystem switches a
 device function's interrupt mode from MSI-X mode to legacy mode and
 marks all allocated MSI-X vectors as unused.
@@ -383,53 +388,56 @@ MSI/MSI-X requests from other drivers, these MSI-X vectors may be
 re-assigned.
 
 For the case where the PCI subsystem re-assigned these MSI-X vectors
-to other driver, a request to switching back to MSI-X mode may result
+to other drivers, a request to switch back to MSI-X mode may result
 being assigned with another set of MSI-X vectors or a failure if no
 more vectors are available.
 
-5.4 Handling function implementng both MSI and MSI-X capabilities
+5.4 Handling function implementing both MSI and MSI-X capabilities
 
 For the case where a function implements both MSI and MSI-X
 capabilities, the PCI subsystem enables a device to run either in MSI
 mode or MSI-X mode but not both. A device driver determines whether it
 wants MSI or MSI-X enabled on its hardware device. Once a device
-driver requests for MSI, for example, it is prohibited to request for
+driver requests for MSI, for example, it is prohibited from requesting
 MSI-X; in other words, a device driver is not permitted to ping-pong
 between MSI mod MSI-X mode during a run-time.
 
 5.5 Hardware requirements for MSI/MSI-X support
+
 MSI/MSI-X support requires support from both system hardware and
 individual hardware device functions.
 
 5.5.1 System hardware support
+
 Since the target of MSI address is the local APIC CPU, enabling
-MSI/MSI-X support in Linux kernel is dependent on whether existing
-system hardware supports local APIC. Users should verify their
-system whether it runs when CONFIG_X86_LOCAL_APIC=y.
+MSI/MSI-X support in the Linux kernel is dependent on whether existing
+system hardware supports local APIC. Users should verify that their
+system supports local APIC operation by testing that it runs when
+CONFIG_X86_LOCAL_APIC=y.
 
 In SMP environment, CONFIG_X86_LOCAL_APIC is automatically set;
 however, in UP environment, users must manually set
 CONFIG_X86_LOCAL_APIC. Once CONFIG_X86_LOCAL_APIC=y, setting
-CONFIG_PCI_MSI enables the VECTOR based scheme and
-the option for MSI-capable device drivers to selectively enable
-MSI/MSI-X.
+CONFIG_PCI_MSI enables the VECTOR based scheme and the option for
+MSI-capable device drivers to selectively enable MSI/MSI-X.
 
 Note that CONFIG_X86_IO_APIC setting is irrelevant because MSI/MSI-X
 vector is allocated new during runtime and MSI/MSI-X support does not
 depend on BIOS support. This key independency enables MSI/MSI-X
-support on future IOxAPIC free platform.
+support on future IOxAPIC free platforms.
 
 5.5.2 Device hardware support
+
 The hardware device function supports MSI by indicating the
 MSI/MSI-X capability structure on its PCI capability list. By
 default, this capability structure will not be initialized by
 the kernel to enable MSI during the system boot. In other words,
 the device function is running on its default pin assertion mode.
 Note that in many cases the hardware supporting MSI have bugs,
-which may result in system hang. The software driver of specific
-MSI-capable hardware is responsible for whether calling
+which may result in system hangs. The software driver of specific
+MSI-capable hardware is responsible for deciding whether to call
 pci_enable_msi or not. A return of zero indicates the kernel
-successfully initializes the MSI/MSI-X capability structure of the
+successfully initialized the MSI/MSI-X capability structure of the
 device function. The device function is now running on MSI/MSI-X mode.
 
 5.6 How to tell whether MSI/MSI-X is enabled on device function
@@ -439,10 +447,10 @@ pci_enable_msi()/pci_enable_msix() indicates to a device driver that
 its device function is initialized successfully and ready to run in
 MSI/MSI-X mode.
 
-At the user level, users can use command 'cat /proc/interrupts'
-to display the vector allocated for a device and its interrupt
-MSI/MSI-X mode ("PCI MSI"/"PCI MSIX"). Below shows below MSI mode is
-enabled on a SCSI Adaptec 39320D Ultra320.
+At the user level, users can use the command 'cat /proc/interrupts'
+to display the vectors allocated for devices and their interrupt
+MSI/MSI-X modes ("PCI-MSI"/"PCI-MSI-X"). Below shows MSI mode is
+enabled on a SCSI Adaptec 39320D Ultra320 controller.
 
            CPU0       CPU1
   0:     324639          0    IO-APIC-edge  timer
@@ -453,8 +461,8 @@ enabled on a SCSI Adaptec 39320D Ultra320.
  15:          1          0    IO-APIC-edge  ide1
 169:          0          0   IO-APIC-level  uhci-hcd
 185:          0          0   IO-APIC-level  uhci-hcd
-193:        138         10         PCI MSI  aic79xx
-201:         30          0         PCI MSI  aic79xx
+193:        138         10         PCI-MSI  aic79xx
+201:         30          0         PCI-MSI  aic79xx
 225:         30          0   IO-APIC-level  aic7xxx
 233:         30          0   IO-APIC-level  aic7xxx
 NMI:          0          0
@@ -490,8 +498,8 @@ target address set as 0xfeexxxxx, as conformed to PCI
 specification 2.3 or latest, then it should work.
 
 Q4. From the driver point of view, if the MSI is lost because
-of the errors occur during inbound memory write, then it may
-wait for ever. Is there a mechanism for it to recover?
+of errors occurring during inbound memory write, then it may
+wait forever. Is there a mechanism for it to recover?
 
 A4. Since the target of the transaction is an inbound memory
 write, all transaction termination conditions (Retry,
index 354d89c783777489408967d012ff4d4f55392adf..15da16861fa3d6bfbec2e3f192ece4a22ace5b7f 100644 (file)
@@ -772,8 +772,6 @@ RCU pointer/list traversal:
        list_for_each_entry_rcu
        list_for_each_continue_rcu      (to be deprecated in favor of new
                                         list_for_each_entry_continue_rcu)
-       hlist_for_each_rcu              (to be deprecated in favor of
-                                        hlist_for_each_entry_rcu)
        hlist_for_each_entry_rcu
 
 RCU pointer update:
index dca274ff40052e31cd3a0d6badd23003648a37a7..a5009c8300f3364a98e8982c9697f1dee789346f 100644 (file)
@@ -19,7 +19,6 @@ There are two dm targets available: snapshot and snapshot-origin.
 *) snapshot-origin <origin>
 
 which will normally have one or more snapshots based on it.
-You must create the snapshot-origin device before you can create snapshots.
 Reads will be mapped directly to the backing device. For each write, the
 original data will be saved in the <COW device> of each snapshot to keep
 its visible content unchanged, at least until the <COW device> fills up.
@@ -27,7 +26,7 @@ its visible content unchanged, at least until the <COW device> fills up.
 
 *) snapshot <origin> <COW device> <persistent?> <chunksize>
 
-A snapshot is created of the <origin> block device. Changed chunks of
+A snapshot of the <origin> block device is created. Changed chunks of
 <chunksize> sectors will be stored on the <COW device>.  Writes will
 only go to the <COW device>.  Reads will come from the <COW device> or
 from <origin> for unchanged data.  <COW device> will often be
@@ -37,6 +36,8 @@ the amount of free space and expand the <COW device> before it fills up.
 
 <persistent?> is P (Persistent) or N (Not persistent - will not survive
 after reboot).
+The difference is that for transient snapshots less metadata must be
+saved on disk - they can be kept in memory by the kernel.
 
 
 How this is used by LVM2
index 62db6758d1c1050db42b638ad4d42dc06809c68b..ee277dd204b0f575165b02f0dfc1fcb27c8d0bf8 100644 (file)
@@ -146,10 +146,10 @@ pmipal    Use the protected mode interface for palette changes.
 
 mtrr:n setup memory type range registers for the vesafb framebuffer
        where n:
-             0 - disabled (equivalent to nomtrr)
+             0 - disabled (equivalent to nomtrr) (default)
              1 - uncachable
              2 - write-back
-             3 - write-combining (default)
+             3 - write-combining
              4 - write-through
 
        If you see the following in dmesg, choose the type that matches the
index b67189a8d8d471789629ae23e4c1b6e9e2b713da..decdf9917e0ddd4d809a673ef0dc5538f741b34f 100644 (file)
@@ -69,6 +69,22 @@ Who: Grant Coady <gcoady@gmail.com>
 
 ---------------------------
 
+What:  remove EXPORT_SYMBOL(panic_timeout)
+When:  April 2006
+Files: kernel/panic.c
+Why:   No modular usage in the kernel.
+Who:   Adrian Bunk <bunk@stusta.de>
+
+---------------------------
+
+What:  remove EXPORT_SYMBOL(insert_resource)
+When:  April 2006
+Files: kernel/resource.c
+Why:   No modular usage in the kernel.
+Who:   Adrian Bunk <bunk@stusta.de>
+
+---------------------------
+
 What:  PCMCIA control ioctl (needed for pcmcia-cs [cardmgr, cardctl])
 When:  November 2005
 Files: drivers/pcmcia/: pcmcia_ioctl.c
diff --git a/Documentation/filesystems/dentry-locking.txt b/Documentation/filesystems/dentry-locking.txt
new file mode 100644 (file)
index 0000000..4c0c575
--- /dev/null
@@ -0,0 +1,173 @@
+RCU-based dcache locking model
+==============================
+
+On many workloads, the most common operation on dcache is to look up a
+dentry, given a parent dentry and the name of the child. Typically,
+for every open(), stat() etc., the dentry corresponding to the
+pathname will be looked up by walking the tree starting with the first
+component of the pathname and using that dentry along with the next
+component to look up the next level and so on. Since it is a frequent
+operation for workloads like multiuser environments and web servers,
+it is important to optimize this path.
+
+Prior to 2.5.10, dcache_lock was acquired in d_lookup and thus in
+every component during path look-up. Since 2.5.10 onwards, fast-walk
+algorithm changed this by holding the dcache_lock at the beginning and
+walking as many cached path component dentries as possible. This
+significantly decreases the number of acquisition of
+dcache_lock. However it also increases the lock hold time
+significantly and affects performance in large SMP machines. Since
+2.5.62 kernel, dcache has been using a new locking model that uses RCU
+to make dcache look-up lock-free.
+
+The current dcache locking model is not very different from the
+existing dcache locking model. Prior to 2.5.62 kernel, dcache_lock
+protected the hash chain, d_child, d_alias, d_lru lists as well as
+d_inode and several other things like mount look-up. RCU-based changes
+affect only the way the hash chain is protected. For everything else
+the dcache_lock must be taken for both traversing as well as
+updating. The hash chain updates too take the dcache_lock.  The
+significant change is the way d_lookup traverses the hash chain, it
+doesn't acquire the dcache_lock for this and rely on RCU to ensure
+that the dentry has not been *freed*.
+
+
+Dcache locking details
+======================
+
+For many multi-user workloads, open() and stat() on files are very
+frequently occurring operations. Both involve walking of path names to
+find the dentry corresponding to the concerned file. In 2.4 kernel,
+dcache_lock was held during look-up of each path component. Contention
+and cache-line bouncing of this global lock caused significant
+scalability problems. With the introduction of RCU in Linux kernel,
+this was worked around by making the look-up of path components during
+path walking lock-free.
+
+
+Safe lock-free look-up of dcache hash table
+===========================================
+
+Dcache is a complex data structure with the hash table entries also
+linked together in other lists. In 2.4 kernel, dcache_lock protected
+all the lists. We applied RCU only on hash chain walking. The rest of
+the lists are still protected by dcache_lock.  Some of the important
+changes are :
+
+1. The deletion from hash chain is done using hlist_del_rcu() macro
+   which doesn't initialize next pointer of the deleted dentry and
+   this allows us to walk safely lock-free while a deletion is
+   happening.
+
+2. Insertion of a dentry into the hash table is done using
+   hlist_add_head_rcu() which take care of ordering the writes - the
+   writes to the dentry must be visible before the dentry is
+   inserted. This works in conjunction with hlist_for_each_rcu() while
+   walking the hash chain. The only requirement is that all
+   initialization to the dentry must be done before
+   hlist_add_head_rcu() since we don't have dcache_lock protection
+   while traversing the hash chain. This isn't different from the
+   existing code.
+
+3. The dentry looked up without holding dcache_lock by cannot be
+   returned for walking if it is unhashed. It then may have a NULL
+   d_inode or other bogosity since RCU doesn't protect the other
+   fields in the dentry. We therefore use a flag DCACHE_UNHASHED to
+   indicate unhashed dentries and use this in conjunction with a
+   per-dentry lock (d_lock). Once looked up without the dcache_lock,
+   we acquire the per-dentry lock (d_lock) and check if the dentry is
+   unhashed. If so, the look-up is failed. If not, the reference count
+   of the dentry is increased and the dentry is returned.
+
+4. Once a dentry is looked up, it must be ensured during the path walk
+   for that component it doesn't go away. In pre-2.5.10 code, this was
+   done holding a reference to the dentry. dcache_rcu does the same.
+   In some sense, dcache_rcu path walking looks like the pre-2.5.10
+   version.
+
+5. All dentry hash chain updates must take the dcache_lock as well as
+   the per-dentry lock in that order. dput() does this to ensure that
+   a dentry that has just been looked up in another CPU doesn't get
+   deleted before dget() can be done on it.
+
+6. There are several ways to do reference counting of RCU protected
+   objects. One such example is in ipv4 route cache where deferred
+   freeing (using call_rcu()) is done as soon as the reference count
+   goes to zero. This cannot be done in the case of dentries because
+   tearing down of dentries require blocking (dentry_iput()) which
+   isn't supported from RCU callbacks. Instead, tearing down of
+   dentries happen synchronously in dput(), but actual freeing happens
+   later when RCU grace period is over. This allows safe lock-free
+   walking of the hash chains, but a matched dentry may have been
+   partially torn down. The checking of DCACHE_UNHASHED flag with
+   d_lock held detects such dentries and prevents them from being
+   returned from look-up.
+
+
+Maintaining POSIX rename semantics
+==================================
+
+Since look-up of dentries is lock-free, it can race against a
+concurrent rename operation. For example, during rename of file A to
+B, look-up of either A or B must succeed.  So, if look-up of B happens
+after A has been removed from the hash chain but not added to the new
+hash chain, it may fail.  Also, a comparison while the name is being
+written concurrently by a rename may result in false positive matches
+violating rename semantics.  Issues related to race with rename are
+handled as described below :
+
+1. Look-up can be done in two ways - d_lookup() which is safe from
+   simultaneous renames and __d_lookup() which is not.  If
+   __d_lookup() fails, it must be followed up by a d_lookup() to
+   correctly determine whether a dentry is in the hash table or
+   not. d_lookup() protects look-ups using a sequence lock
+   (rename_lock).
+
+2. The name associated with a dentry (d_name) may be changed if a
+   rename is allowed to happen simultaneously. To avoid memcmp() in
+   __d_lookup() go out of bounds due to a rename and false positive
+   comparison, the name comparison is done while holding the
+   per-dentry lock. This prevents concurrent renames during this
+   operation.
+
+3. Hash table walking during look-up may move to a different bucket as
+   the current dentry is moved to a different bucket due to rename.
+   But we use hlists in dcache hash table and they are
+   null-terminated.  So, even if a dentry moves to a different bucket,
+   hash chain walk will terminate. [with a list_head list, it may not
+   since termination is when the list_head in the original bucket is
+   reached].  Since we redo the d_parent check and compare name while
+   holding d_lock, lock-free look-up will not race against d_move().
+
+4. There can be a theoretical race when a dentry keeps coming back to
+   original bucket due to double moves. Due to this look-up may
+   consider that it has never moved and can end up in a infinite loop.
+   But this is not any worse that theoretical livelocks we already
+   have in the kernel.
+
+
+Important guidelines for filesystem developers related to dcache_rcu
+====================================================================
+
+1. Existing dcache interfaces (pre-2.5.62) exported to filesystem
+   don't change. Only dcache internal implementation changes. However
+   filesystems *must not* delete from the dentry hash chains directly
+   using the list macros like allowed earlier. They must use dcache
+   APIs like d_drop() or __d_drop() depending on the situation.
+
+2. d_flags is now protected by a per-dentry lock (d_lock). All access
+   to d_flags must be protected by it.
+
+3. For a hashed dentry, checking of d_count needs to be protected by
+   d_lock.
+
+
+Papers and other documentation on dcache locking
+================================================
+
+1. Scaling dcache with RCU (http://linuxjournal.com/article.php?sid=7124).
+
+2. http://lse.sourceforge.net/locking/dcache/dcache.html
+
+
+
index 54366ecc241fee30aaf1a77ec91b15c310b766a3..aabfba24bc2edc214adfb90d5f28bda9de7ccad1 100644 (file)
@@ -1812,11 +1812,6 @@ it may overflow the messages buffer, but try to get as much of it as
 you can
 
 
-if you get an Oops, run ksymoops to decode it so that the
-names of the offending functions are provided. A non-decoded Oops is
-pretty useless
-
-
 send a copy of your devfsd configuration file(s)
 
 send the bug report to me first.
diff --git a/Documentation/filesystems/ramfs-rootfs-initramfs.txt b/Documentation/filesystems/ramfs-rootfs-initramfs.txt
new file mode 100644 (file)
index 0000000..b3404a0
--- /dev/null
@@ -0,0 +1,195 @@
+ramfs, rootfs and initramfs
+October 17, 2005
+Rob Landley <rob@landley.net>
+=============================
+
+What is ramfs?
+--------------
+
+Ramfs is a very simple filesystem that exports Linux's disk caching
+mechanisms (the page cache and dentry cache) as a dynamically resizable
+ram-based filesystem.
+
+Normally all files are cached in memory by Linux.  Pages of data read from
+backing store (usually the block device the filesystem is mounted on) are kept
+around in case it's needed again, but marked as clean (freeable) in case the
+Virtual Memory system needs the memory for something else.  Similarly, data
+written to files is marked clean as soon as it has been written to backing
+store, but kept around for caching purposes until the VM reallocates the
+memory.  A similar mechanism (the dentry cache) greatly speeds up access to
+directories.
+
+With ramfs, there is no backing store.  Files written into ramfs allocate
+dentries and page cache as usual, but there's nowhere to write them to.
+This means the pages are never marked clean, so they can't be freed by the
+VM when it's looking to recycle memory.
+
+The amount of code required to implement ramfs is tiny, because all the
+work is done by the existing Linux caching infrastructure.  Basically,
+you're mounting the disk cache as a filesystem.  Because of this, ramfs is not
+an optional component removable via menuconfig, since there would be negligible
+space savings.
+
+ramfs and ramdisk:
+------------------
+
+The older "ram disk" mechanism created a synthetic block device out of
+an area of ram and used it as backing store for a filesystem.  This block
+device was of fixed size, so the filesystem mounted on it was of fixed
+size.  Using a ram disk also required unnecessarily copying memory from the
+fake block device into the page cache (and copying changes back out), as well
+as creating and destroying dentries.  Plus it needed a filesystem driver
+(such as ext2) to format and interpret this data.
+
+Compared to ramfs, this wastes memory (and memory bus bandwidth), creates
+unnecessary work for the CPU, and pollutes the CPU caches.  (There are tricks
+to avoid this copying by playing with the page tables, but they're unpleasantly
+complicated and turn out to be about as expensive as the copying anyway.)
+More to the point, all the work ramfs is doing has to happen _anyway_,
+since all file access goes through the page and dentry caches.  The ram
+disk is simply unnecessary, ramfs is internally much simpler.
+
+Another reason ramdisks are semi-obsolete is that the introduction of
+loopback devices offered a more flexible and convenient way to create
+synthetic block devices, now from files instead of from chunks of memory.
+See losetup (8) for details.
+
+ramfs and tmpfs:
+----------------
+
+One downside of ramfs is you can keep writing data into it until you fill
+up all memory, and the VM can't free it because the VM thinks that files
+should get written to backing store (rather than swap space), but ramfs hasn't
+got any backing store.  Because of this, only root (or a trusted user) should
+be allowed write access to a ramfs mount.
+
+A ramfs derivative called tmpfs was created to add size limits, and the ability
+to write the data to swap space.  Normal users can be allowed write access to
+tmpfs mounts.  See Documentation/filesystems/tmpfs.txt for more information.
+
+What is rootfs?
+---------------
+
+Rootfs is a special instance of ramfs, which is always present in 2.6 systems.
+(It's used internally as the starting and stopping point for searches of the
+kernel's doubly-linked list of mount points.)
+
+Most systems just mount another filesystem over it and ignore it.  The
+amount of space an empty instance of ramfs takes up is tiny.
+
+What is initramfs?
+------------------
+
+All 2.6 Linux kernels contain a gzipped "cpio" format archive, which is
+extracted into rootfs when the kernel boots up.  After extracting, the kernel
+checks to see if rootfs contains a file "init", and if so it executes it as PID
+1.  If found, this init process is responsible for bringing the system the
+rest of the way up, including locating and mounting the real root device (if
+any).  If rootfs does not contain an init program after the embedded cpio
+archive is extracted into it, the kernel will fall through to the older code
+to locate and mount a root partition, then exec some variant of /sbin/init
+out of that.
+
+All this differs from the old initrd in several ways:
+
+  - The old initrd was a separate file, while the initramfs archive is linked
+    into the linux kernel image.  (The directory linux-*/usr is devoted to
+    generating this archive during the build.)
+
+  - The old initrd file was a gzipped filesystem image (in some file format,
+    such as ext2, that had to be built into the kernel), while the new
+    initramfs archive is a gzipped cpio archive (like tar only simpler,
+    see cpio(1) and Documentation/early-userspace/buffer-format.txt).
+
+  - The program run by the old initrd (which was called /initrd, not /init) did
+    some setup and then returned to the kernel, while the init program from
+    initramfs is not expected to return to the kernel.  (If /init needs to hand
+    off control it can overmount / with a new root device and exec another init
+    program.  See the switch_root utility, below.)
+
+  - When switching another root device, initrd would pivot_root and then
+    umount the ramdisk.  But initramfs is rootfs: you can neither pivot_root
+    rootfs, nor unmount it.  Instead delete everything out of rootfs to
+    free up the space (find -xdev / -exec rm '{}' ';'), overmount rootfs
+    with the new root (cd /newmount; mount --move . /; chroot .), attach
+    stdin/stdout/stderr to the new /dev/console, and exec the new init.
+
+    Since this is a remarkably persnickity process (and involves deleting
+    commands before you can run them), the klibc package introduced a helper
+    program (utils/run_init.c) to do all this for you.  Most other packages
+    (such as busybox) have named this command "switch_root".
+
+Populating initramfs:
+---------------------
+
+The 2.6 kernel build process always creates a gzipped cpio format initramfs
+archive and links it into the resulting kernel binary.  By default, this
+archive is empty (consuming 134 bytes on x86).  The config option
+CONFIG_INITRAMFS_SOURCE (for some reason buried under devices->block devices
+in menuconfig, and living in usr/Kconfig) can be used to specify a source for
+the initramfs archive, which will automatically be incorporated into the
+resulting binary.  This option can point to an existing gzipped cpio archive, a
+directory containing files to be archived, or a text file specification such
+as the following example:
+
+  dir /dev 755 0 0
+  nod /dev/console 644 0 0 c 5 1
+  nod /dev/loop0 644 0 0 b 7 0
+  dir /bin 755 1000 1000
+  slink /bin/sh busybox 777 0 0
+  file /bin/busybox initramfs/busybox 755 0 0
+  dir /proc 755 0 0
+  dir /sys 755 0 0
+  dir /mnt 755 0 0
+  file /init initramfs/init.sh 755 0 0
+
+One advantage of the text file is that root access is not required to
+set permissions or create device nodes in the new archive.  (Note that those
+two example "file" entries expect to find files named "init.sh" and "busybox" in
+a directory called "initramfs", under the linux-2.6.* directory.  See
+Documentation/early-userspace/README for more details.)
+
+If you don't already understand what shared libraries, devices, and paths
+you need to get a minimal root filesystem up and running, here are some
+references:
+http://www.tldp.org/HOWTO/Bootdisk-HOWTO/
+http://www.tldp.org/HOWTO/From-PowerUp-To-Bash-Prompt-HOWTO.html
+http://www.linuxfromscratch.org/lfs/view/stable/
+
+The "klibc" package (http://www.kernel.org/pub/linux/libs/klibc) is
+designed to be a tiny C library to statically link early userspace
+code against, along with some related utilities.  It is BSD licensed.
+
+I use uClibc (http://www.uclibc.org) and busybox (http://www.busybox.net)
+myself.  These are LGPL and GPL, respectively.
+
+In theory you could use glibc, but that's not well suited for small embedded
+uses like this.  (A "hello world" program statically linked against glibc is
+over 400k.  With uClibc it's 7k.  Also note that glibc dlopens libnss to do
+name lookups, even when otherwise statically linked.)
+
+Future directions:
+------------------
+
+Today (2.6.14), initramfs is always compiled in, but not always used.  The
+kernel falls back to legacy boot code that is reached only if initramfs does
+not contain an /init program.  The fallback is legacy code, there to ensure a
+smooth transition and allowing early boot functionality to gradually move to
+"early userspace" (I.E. initramfs).
+
+The move to early userspace is necessary because finding and mounting the real
+root device is complex.  Root partitions can span multiple devices (raid or
+separate journal).  They can be out on the network (requiring dhcp, setting a
+specific mac address, logging into a server, etc).  They can live on removable
+media, with dynamically allocated major/minor numbers and persistent naming
+issues requiring a full udev implementation to sort out.  They can be
+compressed, encrypted, copy-on-write, loopback mounted, strangely partitioned,
+and so on.
+
+This kind of complexity (which inevitably includes policy) is rightly handled
+in userspace.  Both klibc and busybox/uClibc are working on simple initramfs
+packages to drop into a kernel build, and when standard solutions are ready
+and widely deployed, the kernel's legacy early boot code will become obsolete
+and a candidate for the feature removal schedule.
+
+But that's a while off yet.
index f042c12e0ed2d24683e1b83ddfd130b561ad0e1b..ee4c0a8b8db7a663169fd97c57ce472a1a790398 100644 (file)
@@ -3,7 +3,7 @@
 
        Original author: Richard Gooch <rgooch@atnf.csiro.au>
 
-                 Last updated on August 25, 2005
+                 Last updated on October 28, 2005
 
   Copyright (C) 1999 Richard Gooch
   Copyright (C) 2005 Pekka Enberg
   This file is released under the GPLv2.
 
 
-What is it?
-===========
+Introduction
+============
 
-The Virtual File System (otherwise known as the Virtual Filesystem
-Switch) is the software layer in the kernel that provides the
-filesystem interface to userspace programs. It also provides an
-abstraction within the kernel which allows different filesystem
-implementations to coexist.
+The Virtual File System (also known as the Virtual Filesystem Switch)
+is the software layer in the kernel that provides the filesystem
+interface to userspace programs. It also provides an abstraction
+within the kernel which allows different filesystem implementations to
+coexist.
 
+VFS system calls open(2), stat(2), read(2), write(2), chmod(2) and so
+on are called from a process context. Filesystem locking is described
+in the document Documentation/filesystems/Locking.
 
-A Quick Look At How It Works
-============================
 
-In this section I'll briefly describe how things work, before
-launching into the details. I'll start with describing what happens
-when user programs open and manipulate files, and then look from the
-other view which is how a filesystem is supported and subsequently
-mounted.
-
-
-Opening a File
---------------
-
-The VFS implements the open(2), stat(2), chmod(2) and similar system
-calls. The pathname argument is used by the VFS to search through the
-directory entry cache (dentry cache or "dcache"). This provides a very
-fast look-up mechanism to translate a pathname (filename) into a
-specific dentry.
-
-An individual dentry usually has a pointer to an inode. Inodes are the
-things that live on disc drives, and can be regular files (you know:
-those things that you write data into), directories, FIFOs and other
-beasts. Dentries live in RAM and are never saved to disc: they exist
-only for performance. Inodes live on disc and are copied into memory
-when required. Later any changes are written back to disc. The inode
-that lives in RAM is a VFS inode, and it is this which the dentry
-points to. A single inode can be pointed to by multiple dentries
-(think about hardlinks).
-
-The dcache is meant to be a view into your entire filespace. Unlike
-Linus, most of us losers can't fit enough dentries into RAM to cover
-all of our filespace, so the dcache has bits missing. In order to
-resolve your pathname into a dentry, the VFS may have to resort to
-creating dentries along the way, and then loading the inode. This is
-done by looking up the inode.
-
-To look up an inode (usually read from disc) requires that the VFS
-calls the lookup() method of the parent directory inode. This method
-is installed by the specific filesystem implementation that the inode
-lives in. There will be more on this later.
+Directory Entry Cache (dcache)
+------------------------------
 
-Once the VFS has the required dentry (and hence the inode), we can do
-all those boring things like open(2) the file, or stat(2) it to peek
-at the inode data. The stat(2) operation is fairly simple: once the
-VFS has the dentry, it peeks at the inode data and passes some of it
-back to userspace.
+The VFS implements the open(2), stat(2), chmod(2), and similar system
+calls. The pathname argument that is passed to them is used by the VFS
+to search through the directory entry cache (also known as the dentry
+cache or dcache). This provides a very fast look-up mechanism to
+translate a pathname (filename) into a specific dentry. Dentries live
+in RAM and are never saved to disc: they exist only for performance.
+
+The dentry cache is meant to be a view into your entire filespace. As
+most computers cannot fit all dentries in the RAM at the same time,
+some bits of the cache are missing. In order to resolve your pathname
+into a dentry, the VFS may have to resort to creating dentries along
+the way, and then loading the inode. This is done by looking up the
+inode.
+
+
+The Inode Object
+----------------
+
+An individual dentry usually has a pointer to an inode. Inodes are
+filesystem objects such as regular files, directories, FIFOs and other
+beasts.  They live either on the disc (for block device filesystems)
+or in the memory (for pseudo filesystems). Inodes that live on the
+disc are copied into the memory when required and changes to the inode
+are written back to disc. A single inode can be pointed to by multiple
+dentries (hard links, for example, do this).
+
+To look up an inode requires that the VFS calls the lookup() method of
+the parent directory inode. This method is installed by the specific
+filesystem implementation that the inode lives in. Once the VFS has
+the required dentry (and hence the inode), we can do all those boring
+things like open(2) the file, or stat(2) it to peek at the inode
+data. The stat(2) operation is fairly simple: once the VFS has the
+dentry, it peeks at the inode data and passes some of it back to
+userspace.
+
+
+The File Object
+---------------
 
 Opening a file requires another operation: allocation of a file
 structure (this is the kernel-side implementation of file
@@ -74,51 +73,39 @@ descriptors). The freshly allocated file structure is initialized with
 a pointer to the dentry and a set of file operation member functions.
 These are taken from the inode data. The open() file method is then
 called so the specific filesystem implementation can do it's work. You
-can see that this is another switch performed by the VFS.
-
-The file structure is placed into the file descriptor table for the
-process.
+can see that this is another switch performed by the VFS. The file
+structure is placed into the file descriptor table for the process.
 
 Reading, writing and closing files (and other assorted VFS operations)
 is done by using the userspace file descriptor to grab the appropriate
-file structure, and then calling the required file structure method
-function to do whatever is required.
-
-For as long as the file is open, it keeps the dentry "open" (in use),
-which in turn means that the VFS inode is still in use.
-
-All VFS system calls (i.e. open(2), stat(2), read(2), write(2),
-chmod(2) and so on) are called from a process context. You should
-assume that these calls are made without any kernel locks being
-held. This means that the processes may be executing the same piece of
-filesystem or driver code at the same time, on different
-processors. You should ensure that access to shared resources is
-protected by appropriate locks.
+file structure, and then calling the required file structure method to
+do whatever is required. For as long as the file is open, it keeps the
+dentry in use, which in turn means that the VFS inode is still in use.
 
 
 Registering and Mounting a Filesystem
--------------------------------------
+=====================================
 
-If you want to support a new kind of filesystem in the kernel, all you
-need to do is call register_filesystem(). You pass a structure
-describing the filesystem implementation (struct file_system_type)
-which is then added to an internal table of supported filesystems. You
-can do:
+To register and unregister a filesystem, use the following API
+functions:
 
-% cat /proc/filesystems
+   #include <linux/fs.h>
 
-to see what filesystems are currently available on your system.
+   extern int register_filesystem(struct file_system_type *);
+   extern int unregister_filesystem(struct file_system_type *);
 
-When a request is made to mount a block device onto a directory in
-your filespace the VFS will call the appropriate method for the
-specific filesystem. The dentry for the mount point will then be
-updated to point to the root inode for the new filesystem.
+The passed struct file_system_type describes your filesystem. When a
+request is made to mount a device onto a directory in your filespace,
+the VFS will call the appropriate get_sb() method for the specific
+filesystem. The dentry for the mount point will then be updated to
+point to the root inode for the new filesystem.
 
-It's now time to look at things in more detail.
+You can see all filesystems that are registered to the kernel in the
+file /proc/filesystems.
 
 
 struct file_system_type
-=======================
+-----------------------
 
 This describes the filesystem. As of kernel 2.6.13, the following
 members are defined:
@@ -197,8 +184,14 @@ A fill_super() method implementation has the following arguments:
   int silent: whether or not to be silent on error
 
 
+The Superblock Object
+=====================
+
+A superblock object represents a mounted filesystem.
+
+
 struct super_operations
-=======================
+-----------------------
 
 This describes how the VFS can manipulate the superblock of your
 filesystem. As of kernel 2.6.13, the following members are defined:
@@ -286,9 +279,9 @@ or bottom half).
        a superblock. The second parameter indicates whether the method
        should wait until the write out has been completed. Optional.
 
-  write_super_lockfs: called when VFS is locking a filesystem and forcing
-       it into a consistent state.  This function is currently used by the
-       Logical Volume Manager (LVM).
+  write_super_lockfs: called when VFS is locking a filesystem and
+       forcing it into a consistent state.  This method is currently
+       used by the Logical Volume Manager (LVM).
 
   unlockfs: called when VFS is unlocking a filesystem and making it writable
        again.
@@ -317,8 +310,14 @@ field. This is a pointer to a "struct inode_operations" which
 describes the methods that can be performed on individual inodes.
 
 
+The Inode Object
+================
+
+An inode object represents an object within the filesystem.
+
+
 struct inode_operations
-=======================
+-----------------------
 
 This describes how the VFS can manipulate an inode in your
 filesystem. As of kernel 2.6.13, the following members are defined:
@@ -394,51 +393,62 @@ otherwise noted.
        will probably need to call d_instantiate() just as you would
        in the create() method
 
+  rename: called by the rename(2) system call to rename the object to
+       have the parent and name given by the second inode and dentry.
+
   readlink: called by the readlink(2) system call. Only required if
        you want to support reading symbolic links
 
   follow_link: called by the VFS to follow a symbolic link to the
        inode it points to.  Only required if you want to support
-       symbolic links.  This function returns a void pointer cookie
+       symbolic links.  This method returns a void pointer cookie
        that is passed to put_link().
 
   put_link: called by the VFS to release resources allocated by
-       follow_link().  The cookie returned by follow_link() is passed to
-       to this function as the last parameter.  It is used by filesystems
-       such as NFS where page cache is not stable (i.e. page that was
-       installed when the symbolic link walk started might not be in the
-       page cache at the end of the walk).
-
-  truncate: called by the VFS to change the size of a file.  The i_size
-       field of the inode is set to the desired size by the VFS before
-       this function is called.  This function is called by the truncate(2)
-       system call and related functionality.
+       follow_link().  The cookie returned by follow_link() is passed
+       to to this method as the last parameter.  It is used by
+       filesystems such as NFS where page cache is not stable
+       (i.e. page that was installed when the symbolic link walk
+       started might not be in the page cache at the end of the
+       walk).
+
+  truncate: called by the VFS to change the size of a file.  The
+       i_size field of the inode is set to the desired size by the
+       VFS before this method is called.  This method is called by
+       the truncate(2) system call and related functionality.
 
   permission: called by the VFS to check for access rights on a POSIX-like
        filesystem.
 
-  setattr: called by the VFS to set attributes for a file.  This function is
-       called by chmod(2) and related system calls.
+  setattr: called by the VFS to set attributes for a file. This method
+       is called by chmod(2) and related system calls.
 
-  getattr: called by the VFS to get attributes of a file.  This function is
-       called by stat(2) and related system calls.
+  getattr: called by the VFS to get attributes of a file. This method
+       is called by stat(2) and related system calls.
 
   setxattr: called by the VFS to set an extended attribute for a file.
-       Extended attribute is a name:value pair associated with an inode. This
-       function is called by setxattr(2) system call.
+       Extended attribute is a name:value pair associated with an
+       inode. This method is called by setxattr(2) system call.
+
+  getxattr: called by the VFS to retrieve the value of an extended
+       attribute name. This method is called by getxattr(2) function
+       call.
 
-  getxattr: called by the VFS to retrieve the value of an extended attribute
-       name.  This function is called by getxattr(2) function call.
+  listxattr: called by the VFS to list all extended attributes for a
+       given file. This method is called by listxattr(2) system call.
 
-  listxattr: called by the VFS to list all extended attributes for a given
-       file.  This function is called by listxattr(2) system call.
+  removexattr: called by the VFS to remove an extended attribute from
+       a file. This method is called by removexattr(2) system call.
 
-  removexattr: called by the VFS to remove an extended attribute from a file.
-       This function is called by removexattr(2) system call.
+
+The Address Space Object
+========================
+
+The address space object is used to identify pages in the page cache.
 
 
 struct address_space_operations
-===============================
+-------------------------------
 
 This describes how the VFS can manipulate mapping of a file to page cache in
 your filesystem. As of kernel 2.6.13, the following members are defined:
@@ -502,8 +512,14 @@ struct address_space_operations {
        it.  An example implementation can be found in fs/ext2/xip.c.
 
 
+The File Object
+===============
+
+A file object represents a file opened by a process.
+
+
 struct file_operations
-======================
+----------------------
 
 This describes how the VFS can manipulate an open file. As of kernel
 2.6.13, the following members are defined:
@@ -661,7 +677,7 @@ of child dentries. Child dentries are basically like files in a
 directory.
 
 
-Directory Entry Cache APIs
+Directory Entry Cache API
 --------------------------
 
 There are a number of functions defined which permit a filesystem to
@@ -705,178 +721,24 @@ manipulate dentries:
        and the dentry is returned. The caller must use d_put()
        to free the dentry when it finishes using it.
 
+For further information on dentry locking, please refer to the document
+Documentation/filesystems/dentry-locking.txt.
 
-RCU-based dcache locking model
-------------------------------
 
-On many workloads, the most common operation on dcache is
-to look up a dentry, given a parent dentry and the name
-of the child. Typically, for every open(), stat() etc.,
-the dentry corresponding to the pathname will be looked
-up by walking the tree starting with the first component
-of the pathname and using that dentry along with the next
-component to look up the next level and so on. Since it
-is a frequent operation for workloads like multiuser
-environments and web servers, it is important to optimize
-this path.
-
-Prior to 2.5.10, dcache_lock was acquired in d_lookup and thus
-in every component during path look-up. Since 2.5.10 onwards,
-fast-walk algorithm changed this by holding the dcache_lock
-at the beginning and walking as many cached path component
-dentries as possible. This significantly decreases the number
-of acquisition of dcache_lock. However it also increases the
-lock hold time significantly and affects performance in large
-SMP machines. Since 2.5.62 kernel, dcache has been using
-a new locking model that uses RCU to make dcache look-up
-lock-free.
-
-The current dcache locking model is not very different from the existing
-dcache locking model. Prior to 2.5.62 kernel, dcache_lock
-protected the hash chain, d_child, d_alias, d_lru lists as well
-as d_inode and several other things like mount look-up. RCU-based
-changes affect only the way the hash chain is protected. For everything
-else the dcache_lock must be taken for both traversing as well as
-updating. The hash chain updates too take the dcache_lock.
-The significant change is the way d_lookup traverses the hash chain,
-it doesn't acquire the dcache_lock for this and rely on RCU to
-ensure that the dentry has not been *freed*.
-
-
-Dcache locking details
-----------------------
+Resources
+=========
+
+(Note some of these resources are not up-to-date with the latest kernel
+ version.)
+
+Creating Linux virtual filesystems. 2002
+    <http://lwn.net/Articles/13325/>
+
+The Linux Virtual File-system Layer by Neil Brown. 1999
+    <http://www.cse.unsw.edu.au/~neilb/oss/linux-commentary/vfs.html>
+
+A tour of the Linux VFS by Michael K. Johnson. 1996
+    <http://www.tldp.org/LDP/khg/HyperNews/get/fs/vfstour.html>
 
-For many multi-user workloads, open() and stat() on files are
-very frequently occurring operations. Both involve walking
-of path names to find the dentry corresponding to the
-concerned file. In 2.4 kernel, dcache_lock was held
-during look-up of each path component. Contention and
-cache-line bouncing of this global lock caused significant
-scalability problems. With the introduction of RCU
-in Linux kernel, this was worked around by making
-the look-up of path components during path walking lock-free.
-
-
-Safe lock-free look-up of dcache hash table
-===========================================
-
-Dcache is a complex data structure with the hash table entries
-also linked together in other lists. In 2.4 kernel, dcache_lock
-protected all the lists. We applied RCU only on hash chain
-walking. The rest of the lists are still protected by dcache_lock.
-Some of the important changes are :
-
-1. The deletion from hash chain is done using hlist_del_rcu() macro which
-   doesn't initialize next pointer of the deleted dentry and this
-   allows us to walk safely lock-free while a deletion is happening.
-
-2. Insertion of a dentry into the hash table is done using
-   hlist_add_head_rcu() which take care of ordering the writes -
-   the writes to the dentry must be visible before the dentry
-   is inserted. This works in conjunction with hlist_for_each_rcu()
-   while walking the hash chain. The only requirement is that
-   all initialization to the dentry must be done before hlist_add_head_rcu()
-   since we don't have dcache_lock protection while traversing
-   the hash chain. This isn't different from the existing code.
-
-3. The dentry looked up without holding dcache_lock by cannot be
-   returned for walking if it is unhashed. It then may have a NULL
-   d_inode or other bogosity since RCU doesn't protect the other
-   fields in the dentry. We therefore use a flag DCACHE_UNHASHED to
-   indicate unhashed  dentries and use this in conjunction with a
-   per-dentry lock (d_lock). Once looked up without the dcache_lock,
-   we acquire the per-dentry lock (d_lock) and check if the
-   dentry is unhashed. If so, the look-up is failed. If not, the
-   reference count of the dentry is increased and the dentry is returned.
-
-4. Once a dentry is looked up, it must be ensured during the path
-   walk for that component it doesn't go away. In pre-2.5.10 code,
-   this was done holding a reference to the dentry. dcache_rcu does
-   the same.  In some sense, dcache_rcu path walking looks like
-   the pre-2.5.10 version.
-
-5. All dentry hash chain updates must take the dcache_lock as well as
-   the per-dentry lock in that order. dput() does this to ensure
-   that a dentry that has just been looked up in another CPU
-   doesn't get deleted before dget() can be done on it.
-
-6. There are several ways to do reference counting of RCU protected
-   objects. One such example is in ipv4 route cache where
-   deferred freeing (using call_rcu()) is done as soon as
-   the reference count goes to zero. This cannot be done in
-   the case of dentries because tearing down of dentries
-   require blocking (dentry_iput()) which isn't supported from
-   RCU callbacks. Instead, tearing down of dentries happen
-   synchronously in dput(), but actual freeing happens later
-   when RCU grace period is over. This allows safe lock-free
-   walking of the hash chains, but a matched dentry may have
-   been partially torn down. The checking of DCACHE_UNHASHED
-   flag with d_lock held detects such dentries and prevents
-   them from being returned from look-up.
-
-
-Maintaining POSIX rename semantics
-==================================
-
-Since look-up of dentries is lock-free, it can race against
-a concurrent rename operation. For example, during rename
-of file A to B, look-up of either A or B must succeed.
-So, if look-up of B happens after A has been removed from the
-hash chain but not added to the new hash chain, it may fail.
-Also, a comparison while the name is being written concurrently
-by a rename may result in false positive matches violating
-rename semantics.  Issues related to race with rename are
-handled as described below :
-
-1. Look-up can be done in two ways - d_lookup() which is safe
-   from simultaneous renames and __d_lookup() which is not.
-   If __d_lookup() fails, it must be followed up by a d_lookup()
-   to correctly determine whether a dentry is in the hash table
-   or not. d_lookup() protects look-ups using a sequence
-   lock (rename_lock).
-
-2. The name associated with a dentry (d_name) may be changed if
-   a rename is allowed to happen simultaneously. To avoid memcmp()
-   in __d_lookup() go out of bounds due to a rename and false
-   positive comparison, the name comparison is done while holding the
-   per-dentry lock. This prevents concurrent renames during this
-   operation.
-
-3. Hash table walking during look-up may move to a different bucket as
-   the current dentry is moved to a different bucket due to rename.
-   But we use hlists in dcache hash table and they are null-terminated.
-   So, even if a dentry moves to a different bucket, hash chain
-   walk will terminate. [with a list_head list, it may not since
-   termination is when the list_head in the original bucket is reached].
-   Since we redo the d_parent check and compare name while holding
-   d_lock, lock-free look-up will not race against d_move().
-
-4. There can be a theoretical race when a dentry keeps coming back
-   to original bucket due to double moves. Due to this look-up may
-   consider that it has never moved and can end up in a infinite loop.
-   But this is not any worse that theoretical livelocks we already
-   have in the kernel.
-
-
-Important guidelines for filesystem developers related to dcache_rcu
-====================================================================
-
-1. Existing dcache interfaces (pre-2.5.62) exported to filesystem
-   don't change. Only dcache internal implementation changes. However
-   filesystems *must not* delete from the dentry hash chains directly
-   using the list macros like allowed earlier. They must use dcache
-   APIs like d_drop() or __d_drop() depending on the situation.
-
-2. d_flags is now protected by a per-dentry lock (d_lock). All
-   access to d_flags must be protected by it.
-
-3. For a hashed dentry, checking of d_count needs to be protected
-   by d_lock.
-
-
-Papers and other documentation on dcache locking
-================================================
-
-1. Scaling dcache with RCU (http://linuxjournal.com/article.php?sid=7124).
-
-2. http://lse.sourceforge.net/locking/dcache/dcache.html
+A small trail through the Linux kernel by Andries Brouwer. 2001
+    <http://www.win.tue.nl/~aeb/linux/vfs/trail.html>
index 4e7cc8d3359b9a839ed941d5dbad01598869c306..e52457581f47ef0e6274f756a9f70ab8fcb61961 100644 (file)
@@ -1,18 +1,21 @@
                High Precision Event Timer Driver for Linux
 
-The High Precision Event Timer (HPET) hardware is the future replacement for the 8254 and Real
-Time Clock (RTC) periodic timer functionality.  Each HPET can have up two 32 timers.  It is possible
-to configure the first two timers as legacy replacements for 8254 and RTC periodic.  A specification
-done by INTEL and Microsoft can be found at http://www.intel.com/labs/platcomp/hpet/hpetspec.htm.
-
-The driver supports detection of HPET driver allocation and initialization of the HPET before the
-driver module_init routine is called.  This enables platform code which uses timer 0 or 1 as the
-main timer to intercept HPET initialization.  An example of this initialization can be found in
+The High Precision Event Timer (HPET) hardware is the future replacement
+for the 8254 and Real Time Clock (RTC) periodic timer functionality.
+Each HPET can have up two 32 timers.  It is possible to configure the
+first two timers as legacy replacements for 8254 and RTC periodic timers.
+A specification done by Intel and Microsoft can be found at
+<http://www.intel.com/hardwaredesign/hpetspec.htm>.
+
+The driver supports detection of HPET driver allocation and initialization
+of the HPET before the driver module_init routine is called.  This enables
+platform code which uses timer 0 or 1 as the main timer to intercept HPET
+initialization.  An example of this initialization can be found in
 arch/i386/kernel/time_hpet.c.
 
-The driver provides two APIs which are very similar to the API found in the rtc.c driver.
-There is a user space API and a kernel space API.  An example user space program is provided
-below.
+The driver provides two APIs which are very similar to the API found in
+the rtc.c driver.  There is a user space API and a kernel space API.
+An example user space program is provided below.
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -290,9 +293,8 @@ The kernel API has three interfaces exported from the driver:
        hpet_unregister(struct hpet_task *tp)
        hpet_control(struct hpet_task *tp, unsigned int cmd, unsigned long arg)
 
-The kernel module using this interface fills in the ht_func and ht_data members of the
-hpet_task structure before calling hpet_register.  hpet_control simply vectors to the hpet_ioctl
-routine and has the same commands and respective arguments as the user API.  hpet_unregister
+The kernel module using this interface fills in the ht_func and ht_data
+members of the hpet_task structure before calling hpet_register.
+hpet_control simply vectors to the hpet_ioctl routine and has the same
+commands and respective arguments as the user API.  hpet_unregister
 is used to terminate usage of the HPET timer reserved by hpet_register.
-
-
index bd8eefa175872b7aaf85df4439870b43fba2892f..af67faccf4de991f75ef5bcc387095dceaa21926 100644 (file)
@@ -120,7 +120,7 @@ ISDN_NET_MAGIC        0x49344C02  isdn_net_local_s  drivers/isdn/i4l/isdn_net_li
 SAVEKMSG_MAGIC2       0x4B4D5347  savekmsg          arch/*/amiga/config.c
 STLI_BOARDMAGIC       0x4bc6c825  stlibrd           include/linux/istallion.h
 CS_STATE_MAGIC        0x4c4f4749  cs_state          sound/oss/cs46xx.c
-SLAB_C_MAGIC          0x4f17a36d  kmem_cache_s      mm/slab.c
+SLAB_C_MAGIC          0x4f17a36d  kmem_cache        mm/slab.c
 COW_MAGIC             0x4f4f4f4d  cow_header_v1     arch/um/drivers/ubd_user.c
 I810_CARD_MAGIC       0x5072696E  i810_card         sound/oss/i810_audio.c
 TRIDENT_CARD_MAGIC    0x5072696E  trident_card      sound/oss/trident.c
index c6bd25f5d61d4153c9590d7cb590b2b352aad006..e6c39c5831f5f4059ebfbeefb597991221185543 100644 (file)
@@ -176,8 +176,6 @@ information (_most_ of which _is_ _essential_) includes:
  - Which client caused the problem ?
  - How much data was being transferred ?
  - Was the network congested ?
- - If there was a kernel panic, please run the output through ksymoops
-   before sending it to me, otherwise its _useless_.
  - How can the problem be reproduced ?
  - Can you use tcpdump to get a trace ? (N.B. Most (all?) versions of 
    tcpdump don't understand how to dump DECnet properly, so including
index 66eaaab7773d551691181070daead961fca33df2..c563842ed8057e1ee960ff0faa75d87c6b797a56 100644 (file)
@@ -1,6 +1,6 @@
 NOTE: ksymoops is useless on 2.6.  Please use the Oops in its original format
 (from dmesg, etc).  Ignore any references in this or other docs to "decoding
-the Oops" or "running it through ksymoops".  If you post an Oops fron 2.6 that
+the Oops" or "running it through ksymoops".  If you post an Oops from 2.6 that
 has been run through ksymoops, people will just tell you to repost it.
 
 Quick Summary
index 526d6dd267ea8e38f319c30de9f6accf2967327f..912bed87c758457b2f42b6decb1964326efce3de 100644 (file)
@@ -11,9 +11,9 @@ boot video card. (Kernel usually does not even contain video card
 driver -- vesafb and vgacon are widely used).
 
 This is not problem for swsusp, because during swsusp resume, BIOS is
-run normally so video card is normally initialized. S3 has absolutely
-no chance of working with SMP/HT. Be sure it to turn it off before
-testing (swsusp should work ok, OTOH).
+run normally so video card is normally initialized. It should not be
+problem for S1 standby, because hardware should retain its state over
+that.
 
 There are a few types of systems where video works after S3 resume:
 
@@ -64,7 +64,7 @@ your video card (good luck getting docs :-(). Maybe suspending from X
 (proper X, knowing your hardware, not XF68_FBcon) might have better
 chance of working.
 
-Table of known working systems:
+Table of known working notebooks:
 
 Model                           hack (or "how to do it")
 ------------------------------------------------------------------------------
@@ -73,7 +73,7 @@ Acer TM 242FX                 vbetool (6)
 Acer TM C110                   video_post (8)
 Acer TM C300                    vga=normal (only suspend on console, not in X), vbetool (6) or video_post (8)
 Acer TM 4052LCi                        s3_bios (2)
-Acer TM 636Lci                 s3_bios vga=normal (2)
+Acer TM 636Lci                 s3_bios,s3_mode (4)
 Acer TM 650 (Radeon M7)                vga=normal plus boot-radeon (5) gets text console back
 Acer TM 660                    ??? (*)
 Acer TM 800                    vga=normal, X patches, see webpage (5) or vbetool (6)
@@ -137,6 +137,13 @@ Toshiba Satellite P10-554       s3_bios,s3_mode (4)(****)
 Toshiba M30                     (2) xor X with nvidia driver using internal AGP
 Uniwill 244IIO                 ??? (*)
 
+Known working desktop systems
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Mainboard          Graphics card                 hack (or "how to do it")
+------------------------------------------------------------------------------
+Asus A7V8X         nVidia RIVA TNT2 model 64     s3_bios,s3_mode (4)
+
 
 (*) from http://www.ubuntulinux.org/wiki/HoaryPMResults, not sure
     which options to use. If you know, please tell me.
index 19461958e2bd98a24260866329eb2e26b5188dbd..df09758bf3fe1619df2b57118b5bb60a12c754a8 100644 (file)
@@ -8,11 +8,10 @@ All devices which can be addressed by means of ccws are called 'CCW devices' -
 even if they aren't actually driven by ccws.
 
 All ccw devices are accessed via a subchannel, this is reflected in the 
-structures under root/:
+structures under devices/:
 
-root/
-     - sys
-     - legacy
+devices/
+     - system/
      - css0/
            - 0.0.0000/0.0.0815/
           - 0.0.0001/0.0.4711/
@@ -36,7 +35,7 @@ availability: Can be 'good' or 'boxed'; 'no path' or 'no device' for
 
 online:     An interface to set the device online and offline.
            In the special case of the device being disconnected (see the
-           notify function under 1.2), piping 0 to online will focibly delete
+           notify function under 1.2), piping 0 to online will forcibly delete
            the device.
 
 The device drivers can add entries to export per-device data and interfaces.
@@ -222,7 +221,7 @@ and are called 'chp0.<chpid>'. They have no driver and do not belong to any bus.
 Please note, that unlike /proc/chpids in 2.4, the channel path objects reflect
 only the logical state and not the physical state, since we cannot track the
 latter consistently due to lacking machine support (we don't need to be aware
-of anyway).
+of it anyway).
 
 status - Can be 'online' or 'offline'.
         Piping 'on' or 'off' sets the chpid logically online/offline.
@@ -235,12 +234,16 @@ status - Can be 'online' or 'offline'.
 3. System devices
 -----------------
 
-Note: cpus may yet be added here.
-
 3.1 xpram 
 ---------
 
-xpram shows up under sys/ as 'xpram'.
+xpram shows up under devices/system/ as 'xpram'.
+
+3.2 cpus
+--------
+
+For each cpu, a directory is created under devices/system/cpu/. Each cpu has an
+attribute 'online' which can be 0 or 1.
 
 
 4. Other devices
index 1829009db771042038f3e302a8c35dbcb07c1d14..3f1c5464b1c9f1206dd497e891e1bd6e691d15fb 100644 (file)
@@ -41,9 +41,9 @@ sure that bitwise types don't get mixed up (little-endian vs big-endian
 vs cpu-endian vs whatever), and there the constant "0" really _is_
 special.
 
-Modify top-level Makefile to say
+Use
 
-CHECK           = sparse -Wbitwise
+       make C=[12] CF=-Wbitwise
 
 or you don't get any checking at all.
 
index 51f8d4379a9475b3034e00d68f92df50974ad4bc..4259dccc8287fdd421693bf0d08879175fa64386 100644 (file)
@@ -27,9 +27,9 @@ information out of a register+stack dump printed by the kernel on
 protection faults (so-called "kernel oops").
 
 If you run into some kind of deadlock, you can try to dump a call trace
-for each process using sysrq-t (see Documentation/sysrq.txt).  ksymoops
-will translate these dumps into kernel symbols too.  This way it is
-possible to figure where *exactly* some process in "D" state is stuck.
+for each process using sysrq-t (see Documentation/sysrq.txt).
+This way it is possible to figure where *exactly* some process in "D"
+state is stuck.
 
 I've seen reports that bttv 0.7.x crashes whereas 0.8.x works rock solid
 for some people.  Thus probably a small buglet left somewhere in bttv
index 1b9bcd1fe98b3867d60a50241bbee7ab84099608..1ad9af1ca4d0b1f2c58b49009c139a69c6124f2d 100644 (file)
@@ -13,12 +13,13 @@ This optimization is more critical now as bigger and bigger physical memories
 Users can use the huge page support in Linux kernel by either using the mmap
 system call or standard SYSv shared memory system calls (shmget, shmat).
 
-First the Linux kernel needs to be built with CONFIG_HUGETLB_PAGE (present
-under Processor types and feature)  and CONFIG_HUGETLBFS (present under file
-system option on config menu) config options.
+First the Linux kernel needs to be built with the CONFIG_HUGETLBFS
+(present under "File systems") and CONFIG_HUGETLB_PAGE (selected
+automatically when CONFIG_HUGETLBFS is selected) configuration
+options.
 
 The kernel built with hugepage support should show the number of configured
-hugepages in the system by running the "cat /proc/meminfo" command.  
+hugepages in the system by running the "cat /proc/meminfo" command.
 
 /proc/meminfo also provides information about the total number of hugetlb
 pages configured in the kernel.  It also displays information about the
@@ -38,19 +39,19 @@ in the kernel.
 
 /proc/sys/vm/nr_hugepages indicates the current number of configured hugetlb
 pages in the kernel.  Super user can dynamically request more (or free some
-pre-configured) hugepages. 
-The allocation( or deallocation) of hugetlb pages is posible only if there are
+pre-configured) hugepages.
+The allocation (or deallocation) of hugetlb pages is possible only if there are
 enough physically contiguous free pages in system (freeing of hugepages is
-possible only if there are enough hugetlb pages free that can be transfered 
+possible only if there are enough hugetlb pages free that can be transfered
 back to regular memory pool).
 
 Pages that are used as hugetlb pages are reserved inside the kernel and can
-not be used for other purposes. 
+not be used for other purposes.
 
 Once the kernel with Hugetlb page support is built and running, a user can
 use either the mmap system call or shared memory system calls to start using
 the huge pages.  It is required that the system administrator preallocate
-enough memory for huge page purposes.  
+enough memory for huge page purposes.
 
 Use the following command to dynamically allocate/deallocate hugepages:
 
@@ -80,9 +81,9 @@ memory (huge pages) allowed for that filesystem (/mnt/huge). The size is
 rounded down to HPAGE_SIZE.  The option nr_inode sets the maximum number of
 inodes that /mnt/huge can use.  If the size or nr_inode options are not
 provided on command line then no limits are set.  For size and nr_inodes
-options, you can use [G|g]/[M|m]/[K|k] to represent giga/mega/kilo. For 
-example, size=2K has the same meaning as size=2048. An example is given at 
-the end of this document. 
+options, you can use [G|g]/[M|m]/[K|k] to represent giga/mega/kilo. For
+example, size=2K has the same meaning as size=2048. An example is given at
+the end of this document.
 
 read and write system calls are not supported on files that reside on hugetlb
 file systems.
index d57c491212b1bf8184272b2c172c18c51c0c09d4..3ccbfa96eeecf6181990e89071eb3b8ccdb963e7 100644 (file)
@@ -1077,6 +1077,26 @@ P:       Jaroslav Kysela
 M:     perex@suse.cz
 S:     Maintained
 
+HPET:  High Precision Event Timers driver (hpet.c)
+P:     Clemens Ladisch
+M:     clemens@ladisch.de
+S:     Maintained
+
+HPET:  i386
+P:     Venkatesh Pallipadi (Venki)
+M:     venkatesh.pallipadi@intel.com
+S:     Maintained
+
+HPET:  x86_64
+P:     Andi Kleen and Vojtech Pavlik
+M:     ak@muc.de and vojtech@suse.cz
+S:     Maintained
+
+HPET:  ACPI hpet.c
+P:     Bob Picco
+M:     bob.picco@hp.com
+S:     Maintained
+
 HPFS FILESYSTEM
 P:     Mikulas Patocka
 M:     mikulas@artax.karlin.mff.cuni.cz
@@ -2051,6 +2071,12 @@ P:       Matt Mackall
 M:     mpm@selenic.com
 S:     Maintained
 
+RAPIDIO SUBSYSTEM
+P:     Matt Porter
+M:     mporter@kernel.crashing.org
+L:     linux-kernel@vger.kernel.org
+S:     Maintained
+
 REAL TIME CLOCK DRIVER
 P:     Paul Gortmaker
 M:     p_gortmaker@yahoo.com
index 9bd8609a2926d29f12913c28705f9175d6e2a420..9a340e790da52a9b801857c2da22226f89c91d66 100644 (file)
@@ -648,7 +648,7 @@ static int ptrace_setwmmxregs(struct task_struct *tsk, void __user *ufp)
 
 #endif
 
-static int do_ptrace(int request, struct task_struct *child, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
 {
        unsigned long tmp;
        int ret;
@@ -782,53 +782,6 @@ static int do_ptrace(int request, struct task_struct *child, long addr, long dat
        return ret;
 }
 
-asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
-{
-       struct task_struct *child;
-       int ret;
-
-       lock_kernel();
-       ret = -EPERM;
-       if (request == PTRACE_TRACEME) {
-               /* are we already being traced? */
-               if (current->ptrace & PT_PTRACED)
-                       goto out;
-               ret = security_ptrace(current->parent, current);
-               if (ret)
-                       goto out;
-               /* set the ptrace bit in the process flags. */
-               current->ptrace |= PT_PTRACED;
-               ret = 0;
-               goto out;
-       }
-       ret = -ESRCH;
-       read_lock(&tasklist_lock);
-       child = find_task_by_pid(pid);
-       if (child)
-               get_task_struct(child);
-       read_unlock(&tasklist_lock);
-       if (!child)
-               goto out;
-
-       ret = -EPERM;
-       if (pid == 1)           /* you may not mess with init */
-               goto out_tsk;
-
-       if (request == PTRACE_ATTACH) {
-               ret = ptrace_attach(child);
-               goto out_tsk;
-       }
-       ret = ptrace_check_attach(child, request == PTRACE_KILL);
-       if (ret == 0)
-               ret = do_ptrace(request, child, addr, data);
-
-out_tsk:
-       put_task_struct(child);
-out:
-       unlock_kernel();
-       return ret;
-}
-
 asmlinkage void syscall_trace(int why, struct pt_regs *regs)
 {
        unsigned long ip;
index 99e019169ddadbbd61c74c757909da93bcc8f351..0340ddc4824ea3e7e8f0ebb733d71c3385c9bb7b 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/list.h>
 #include <linux/errno.h>
 #include <linux/err.h>
+#include <linux/string.h>
 
 #include <asm/semaphore.h>
 #include <asm/hardware/clock.h>
index e8832d0910ee52117673bb66b3a51aefbd0515fa..cfd0d2182d44c46be13f55df034a596e2197ea29 100644 (file)
@@ -25,6 +25,7 @@
 #include <asm/hardware.h>
 #include <asm/io.h>
 #include <asm/sizes.h>
+#include <asm/page.h>
  
 #include <asm/mach/map.h>
 
index a1b153d1626cf182b6fa952c31daedfc6bb8528a..a4bafee77a06d0389269981a370a01192033096a 100644 (file)
@@ -420,8 +420,7 @@ static int impd1_probe(struct lm_device *dev)
  free_impd1:
        if (impd1 && impd1->base)
                iounmap(impd1->base);
-       if (impd1)
-               kfree(impd1);
+       kfree(impd1);
  release_lm:
        release_mem_region(dev->resource.start, SZ_4K);
        return ret;
index 54162ba954142d615bb47832128e288c90ba023f..698eb06545c43c3ee5461fe5133139046af84a7a 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
 #include <linux/module.h>
+#include <linux/string.h>
 #include <asm/arch/akita.h>
 #include <asm/arch/corgi.h>
 #include <asm/arch/hardware.h>
index cf7e977d18c850eb4aba0bd3a2975cf48e85d525..4e6b7356a7221a29c20faa79299ba118bd9cfebe 100644 (file)
@@ -546,7 +546,7 @@ static int ptrace_setfpregs(struct task_struct *tsk, void *ufp)
                              sizeof(struct user_fp)) ? -EFAULT : 0;
 }
 
-static int do_ptrace(int request, struct task_struct *child, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
 {
        unsigned long tmp;
        int ret;
@@ -665,53 +665,6 @@ static int do_ptrace(int request, struct task_struct *child, long addr, long dat
        return ret;
 }
 
-asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
-{
-       struct task_struct *child;
-       int ret;
-
-       lock_kernel();
-       ret = -EPERM;
-       if (request == PTRACE_TRACEME) {
-               /* are we already being traced? */
-               if (current->ptrace & PT_PTRACED)
-                       goto out;
-               ret = security_ptrace(current->parent, current);
-               if (ret)
-                       goto out;
-               /* set the ptrace bit in the process flags. */
-               current->ptrace |= PT_PTRACED;
-               ret = 0;
-               goto out;
-       }
-       ret = -ESRCH;
-       read_lock(&tasklist_lock);
-       child = find_task_by_pid(pid);
-       if (child)
-               get_task_struct(child);
-       read_unlock(&tasklist_lock);
-       if (!child)
-               goto out;
-
-       ret = -EPERM;
-       if (pid == 1)           /* you may not mess with init */
-               goto out_tsk;
-
-       if (request == PTRACE_ATTACH) {
-               ret = ptrace_attach(child);
-               goto out_tsk;
-       }
-       ret = ptrace_check_attach(child, request == PTRACE_KILL);
-       if (ret == 0)
-               ret = do_ptrace(request, child, addr, data);
-
-out_tsk:
-       put_task_struct(child);
-out:
-       unlock_kernel();
-       return ret;
-}
-
 asmlinkage void syscall_trace(int why, struct pt_regs *regs)
 {
        unsigned long ip;
index 6f08903f3139f866888cdde72d4b11aabf942aa6..517d1f027fe879efc310e49aae97732bd7c7f564 100644 (file)
@@ -177,7 +177,7 @@ The example address is 0xd004000c; in binary this is:
 Given the top-level Page Directory, the offset in that directory is calculated
 using the upper 8 bits:
 
-extern inline pgd_t * pgd_offset(struct mm_struct * mm, unsigned long address)
+static inline pgd_t * pgd_offset(struct mm_struct * mm, unsigned long address)
 {
        return mm->pgd + (address >> PGDIR_SHIFT);
 }
@@ -190,14 +190,14 @@ The pgd_t from our example will therefore be the 208'th (0xd0) entry in mm->pgd.
 
 Since the Middle Directory does not exist, it is a unity mapping:
 
-extern inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address)
+static inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address)
 {
        return (pmd_t *) dir;
 }
 
 The Page Table provides the final lookup by using bits 13 to 23 as index:
 
-extern inline pte_t * pte_offset(pmd_t * dir, unsigned long address)
+static inline pte_t * pte_offset(pmd_t * dir, unsigned long address)
 {
        return (pte_t *) pmd_page(*dir) + ((address >> PAGE_SHIFT) &
                                           (PTRS_PER_PTE - 1));
index 130dd214e41d9e4d8f287afa8bb37e4d454dfa54..6cbd34a27b906cdce1805b710eedca1cd6cfa566 100644 (file)
@@ -76,55 +76,11 @@ ptrace_disable(struct task_struct *child)
  * (in user space) where the result of the ptrace call is written (instead of
  * being returned).
  */
-asmlinkage int 
-sys_ptrace(long request, long pid, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
 {
-       struct task_struct *child;
        int ret;
        unsigned long __user *datap = (unsigned long __user *)data;
 
-       lock_kernel();
-       ret = -EPERM;
-       
-       if (request == PTRACE_TRACEME) {
-               /* are we already being traced? */
-               if (current->ptrace & PT_PTRACED)
-                       goto out;
-               ret = security_ptrace(current->parent, current);
-               if (ret)
-                       goto out;
-               /* set the ptrace bit in the process flags. */
-               current->ptrace |= PT_PTRACED;
-               ret = 0;
-               goto out;
-       }
-       
-       ret = -ESRCH;
-       read_lock(&tasklist_lock);
-       child = find_task_by_pid(pid);
-       
-       if (child)
-               get_task_struct(child);
-       
-       read_unlock(&tasklist_lock);
-       
-       if (!child)
-               goto out;
-       
-       ret = -EPERM;
-       
-       if (pid == 1)           /* Leave the init process alone! */
-               goto out_tsk;
-       
-       if (request == PTRACE_ATTACH) {
-               ret = ptrace_attach(child);
-               goto out_tsk;
-       }
-       
-       ret = ptrace_check_attach(child, request == PTRACE_KILL);
-       if (ret < 0)
-               goto out_tsk;
-
        switch (request) {
                /* Read word at location address. */ 
                case PTRACE_PEEKTEXT:
@@ -289,10 +245,7 @@ sys_ptrace(long request, long pid, long addr, long data)
                        ret = ptrace_request(child, request, addr, data);
                        break;
        }
-out_tsk:
-       put_task_struct(child);
-out:
-       unlock_kernel();
+
        return ret;
 }
 
index 693771961f859f788c4eec80bbea21df85ecf1e7..19bcad05716f7880506983cec1f580d88bb689cb 100644 (file)
@@ -476,7 +476,7 @@ give_sigsegv:
  * OK, we're invoking a handler
  */    
 
-extern inline void
+static inline void
 handle_signal(int canrestart, unsigned long sig,
              siginfo_t *info, struct k_sigaction *ka,
               sigset_t *oldset, struct pt_regs * regs)
index ca72076c630a9efee555ab7894983f70633d0357..501fa52d8d3a1974285b1d8c1d0e9e73444f9f37 100644 (file)
@@ -277,7 +277,7 @@ struct file_operations cryptocop_fops = {
 static void free_cdesc(struct cryptocop_dma_desc *cdesc)
 {
        DEBUG(printk("free_cdesc: cdesc 0x%p, from_pool=%d\n", cdesc, cdesc->from_pool));
-       if (cdesc->free_buf) kfree(cdesc->free_buf);
+       kfree(cdesc->free_buf);
 
        if (cdesc->from_pool) {
                unsigned long int flags;
@@ -2950,15 +2950,15 @@ static int cryptocop_ioctl_process(struct inode *inode, struct file *filp, unsig
                put_page(outpages[i]);
        }
 
-       if (digest_result) kfree(digest_result);
-       if (inpages) kfree(inpages);
-       if (outpages) kfree(outpages);
+       kfree(digest_result);
+       kfree(inpages);
+       kfree(outpages);
        if (cop){
-               if (cop->tfrm_op.indata) kfree(cop->tfrm_op.indata);
-               if (cop->tfrm_op.outdata) kfree(cop->tfrm_op.outdata);
+               kfree(cop->tfrm_op.indata);
+               kfree(cop->tfrm_op.outdata);
                kfree(cop);
        }
-       if (jc) kfree(jc);
+       kfree(jc);
 
        DEBUG(print_lock_status());
 
index 208489da2a87fe0ee7ad1843ae69b28439539d4c..5528b83a622b62e666f2e4241967353724f47f7e 100644 (file)
@@ -99,55 +99,11 @@ ptrace_disable(struct task_struct *child)
 }
 
 
-asmlinkage int
-sys_ptrace(long request, long pid, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
 {
-       struct task_struct *child;
        int ret;
        unsigned long __user *datap = (unsigned long __user *)data;
 
-       lock_kernel();
-       ret = -EPERM;
-
-       if (request == PTRACE_TRACEME) {
-               /* are we already being traced? */
-               if (current->ptrace & PT_PTRACED)
-                       goto out;
-               ret = security_ptrace(current->parent, current);
-               if (ret)
-                       goto out;
-               /* set the ptrace bit in the process flags. */
-               current->ptrace |= PT_PTRACED;
-               ret = 0;
-               goto out;
-       }
-
-       ret = -ESRCH;
-       read_lock(&tasklist_lock);
-       child = find_task_by_pid(pid);
-
-       if (child)
-               get_task_struct(child);
-
-       read_unlock(&tasklist_lock);
-
-       if (!child)
-               goto out;
-
-       ret = -EPERM;
-
-       if (pid == 1)           /* Leave the init process alone! */
-               goto out_tsk;
-
-       if (request == PTRACE_ATTACH) {
-               ret = ptrace_attach(child);
-               goto out_tsk;
-       }
-
-       ret = ptrace_check_attach(child, request == PTRACE_KILL);
-       if (ret < 0)
-               goto out_tsk;
-
        switch (request) {
                /* Read word at location address. */
                case PTRACE_PEEKTEXT:
@@ -347,10 +303,7 @@ sys_ptrace(long request, long pid, long addr, long data)
                        ret = ptrace_request(child, request, addr, data);
                        break;
        }
-out_tsk:
-       put_task_struct(child);
-out:
-       unlock_kernel();
+
        return ret;
 }
 
index 0a3614dab88701b2827e26ce5858c94bf824852e..99e59b3eacf8fd5cd4616108873be9afbc460401 100644 (file)
@@ -513,7 +513,7 @@ give_sigsegv:
 }
 
 /* Invoke a singal handler to, well, handle the signal. */
-extern inline void
+static inline void
 handle_signal(int canrestart, unsigned long sig,
              siginfo_t *info, struct k_sigaction *ka,
               sigset_t *oldset, struct pt_regs * regs)
index a92ac9877582f29acea28be385ebccfc9ed01ca5..1780df3ed9e590997529aadcbd9d3a1c7f134abd 100644 (file)
@@ -16,7 +16,7 @@
 #include <asm/tlbflush.h>
 #include <asm/arch/memmap.h>
 
-extern inline void remap_area_pte(pte_t * pte, unsigned long address, unsigned long size,
+static inline void remap_area_pte(pte_t * pte, unsigned long address, unsigned long size,
        unsigned long phys_addr, pgprot_t prot)
 {
        unsigned long end;
index cb335a14a315ae3d18ac319939754725f4b89b67..f953484e7d596eced5666356750f6ef72f2239f6 100644 (file)
@@ -106,48 +106,11 @@ void ptrace_enable(struct task_struct *child)
        child->thread.frame0->__status |= REG__STATUS_STEP;
 }
 
-asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
 {
-       struct task_struct *child;
        unsigned long tmp;
        int ret;
 
-       lock_kernel();
-       ret = -EPERM;
-       if (request == PTRACE_TRACEME) {
-               /* are we already being traced? */
-               if (current->ptrace & PT_PTRACED)
-                       goto out;
-               ret = security_ptrace(current->parent, current);
-               if (ret)
-                       goto out;
-               /* set the ptrace bit in the process flags. */
-               current->ptrace |= PT_PTRACED;
-               ret = 0;
-               goto out;
-       }
-       ret = -ESRCH;
-       read_lock(&tasklist_lock);
-       child = find_task_by_pid(pid);
-       if (child)
-               get_task_struct(child);
-       read_unlock(&tasklist_lock);
-       if (!child)
-               goto out;
-
-       ret = -EPERM;
-       if (pid == 1)           /* you may not mess with init */
-               goto out_tsk;
-
-       if (request == PTRACE_ATTACH) {
-               ret = ptrace_attach(child);
-               goto out_tsk;
-       }
-
-       ret = ptrace_check_attach(child, request == PTRACE_KILL);
-       if (ret < 0)
-               goto out_tsk;
-
        switch (request) {
                /* when I and D space are separate, these will need to be fixed. */
        case PTRACE_PEEKTEXT: /* read word at location addr. */
@@ -351,10 +314,6 @@ asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
                ret = -EIO;
                break;
        }
-out_tsk:
-       put_task_struct(child);
-out:
-       unlock_kernel();
        return ret;
 }
 
index a569fe4aa2842c34271174a0dfedecc232ff986e..0ff6f79b0fedcf240fc56af0e1f8c679fb9db716 100644 (file)
@@ -57,43 +57,10 @@ void ptrace_disable(struct task_struct *child)
        h8300_disable_trace(child);
 }
 
-asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
 {
-       struct task_struct *child;
        int ret;
 
-       lock_kernel();
-       ret = -EPERM;
-       if (request == PTRACE_TRACEME) {
-               /* are we already being traced? */
-               if (current->ptrace & PT_PTRACED)
-                       goto out;
-               /* set the ptrace bit in the process flags. */
-               current->ptrace |= PT_PTRACED;
-               ret = 0;
-               goto out;
-       }
-       ret = -ESRCH;
-       read_lock(&tasklist_lock);
-       child = find_task_by_pid(pid);
-       if (child)
-               get_task_struct(child);
-       read_unlock(&tasklist_lock);
-       if (!child)
-               goto out;
-
-       ret = -EPERM;
-       if (pid == 1)           /* you may not mess with init */
-               goto out_tsk;
-
-       if (request == PTRACE_ATTACH) {
-               ret = ptrace_attach(child);
-               goto out_tsk;
-       }
-       ret = ptrace_check_attach(child, request == PTRACE_KILL);
-       if (ret < 0)
-               goto out_tsk;
-
        switch (request) {
                case PTRACE_PEEKTEXT: /* read word at location addr. */ 
                case PTRACE_PEEKDATA: {
@@ -251,10 +218,6 @@ asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
                        ret = -EIO;
                        break;
        }
-out_tsk:
-       put_task_struct(child);
-out:
-       unlock_kernel();
        return ret;
 }
 
index bac0da731ee3ae98065d5771148648ad1df53940..dbf90ad6eac363a082deae5141c7fcac7a385279 100644 (file)
@@ -997,8 +997,21 @@ source "drivers/Kconfig"
 
 source "fs/Kconfig"
 
+menu "Instrumentation Support"
+       depends on EXPERIMENTAL
+
 source "arch/i386/oprofile/Kconfig"
 
+config KPROBES
+       bool "Kprobes (EXPERIMENTAL)"
+       help
+         Kprobes allows you to trap at almost any kernel address and
+         execute a callback function.  register_kprobe() establishes
+         a probepoint and specifies the callback.  Kprobes is useful
+         for kernel debugging, non-intrusive instrumentation and testing.
+         If in doubt, say "N".
+endmenu
+
 source "arch/i386/Kconfig.debug"
 
 source "security/Kconfig"
index 5228c40a6fb21f6c7e34745ec537ca94c9781e7d..c48b424dd6401de05d5c8d3ecbbf661e15f0a78f 100644 (file)
@@ -22,16 +22,6 @@ config DEBUG_STACKOVERFLOW
          This option will cause messages to be printed if free stack space
          drops below a certain limit.
 
-config KPROBES
-       bool "Kprobes"
-       depends on DEBUG_KERNEL
-       help
-         Kprobes allows you to trap at almost any kernel address and
-         execute a callback function.  register_kprobe() establishes
-         a probepoint and specifies the callback.  Kprobes is useful
-         for kernel debugging, non-intrusive instrumentation and testing.
-         If in doubt, say "N".
-
 config DEBUG_STACK_USAGE
        bool "Stack utilization instrumentation"
        depends on DEBUG_KERNEL
index 7c724ffa08bb9617e4a1834fb20e5924565e281f..496a2c9909fe71d6c502e00683239183f08e72cc 100644 (file)
@@ -559,14 +559,20 @@ void __devinit setup_local_APIC(void)
  * If Linux enabled the LAPIC against the BIOS default
  * disable it down before re-entering the BIOS on shutdown.
  * Otherwise the BIOS may get confused and not power-off.
+ * Additionally clear all LVT entries before disable_local_APIC
+ * for the case where Linux didn't enable the LAPIC.
  */
 void lapic_shutdown(void)
 {
-       if (!cpu_has_apic || !enabled_via_apicbase)
+       if (!cpu_has_apic)
                return;
 
        local_irq_disable();
-       disable_local_APIC();
+       clear_local_APIC();
+
+       if (enabled_via_apicbase)
+               disable_local_APIC();
+
        local_irq_enable();
 }
 
index d2ef0c2aa93e462df516ec6e78c8473bed7c56b7..86e80c551478894c468b4225f72d00a4c772bcfc 100644 (file)
@@ -447,8 +447,7 @@ static char *       apm_event_name[] = {
        "system standby resume",
        "capabilities change"
 };
-#define NR_APM_EVENT_NAME      \
-               (sizeof(apm_event_name) / sizeof(apm_event_name[0]))
+#define NR_APM_EVENT_NAME ARRAY_SIZE(apm_event_name)
 
 typedef struct lookup_t {
        int     key;
@@ -479,7 +478,7 @@ static const lookup_t error_table[] = {
        { APM_NO_ERROR,         "BIOS did not set a return code" },
        { APM_NOT_PRESENT,      "No APM present" }
 };
-#define ERROR_COUNT    (sizeof(error_table)/sizeof(lookup_t))
+#define ERROR_COUNT    ARRAY_SIZE(error_table)
 
 /**
  *     apm_error       -       display an APM error
index 74145a33cb0fd9cc4b69d9e07717e65adac35f74..c145fb30002ed6894d37ffa03b33227166337243 100644 (file)
@@ -30,8 +30,6 @@ static int disable_x86_serial_nr __devinitdata = 1;
 
 struct cpu_dev * cpu_devs[X86_VENDOR_NUM] = {};
 
-extern void mcheck_init(struct cpuinfo_x86 *c);
-
 extern int disable_pse;
 
 static void default_init(struct cpuinfo_x86 * c)
@@ -429,9 +427,8 @@ void __devinit identify_cpu(struct cpuinfo_x86 *c)
        }
 
        /* Init Machine Check Exception if available. */
-#ifdef CONFIG_X86_MCE
        mcheck_init(c);
-#endif
+
        if (c == &boot_cpu_data)
                sysenter_setup();
        enable_sep_cpu();
index 1465974256c9a57300427cc3ca851c890f79684f..0ea010a7afb15bb8d95d0c62afeb77bed13aaaf5 100644 (file)
@@ -67,7 +67,7 @@ static const struct cpu_id cpu_ids[] = {
        [CPU_MP4HT_D0]  = {15,  3, 4 },
        [CPU_MP4HT_E0]  = {15,  4, 1 },
 };
-#define N_IDS  (sizeof(cpu_ids)/sizeof(cpu_ids[0]))
+#define N_IDS  ARRAY_SIZE(cpu_ids)
 
 struct cpu_model
 {
index 7c6b9c73522fe3fe5ca4ece85654226c56d86963..fc5d5215e23deb24fd871c07c26494abfbfad42d 100644 (file)
@@ -68,7 +68,7 @@ static fastcall void k7_machine_check(struct pt_regs * regs, long error_code)
 
 
 /* AMD K7 machine check is Intel like */
-void __devinit amd_mcheck_init(struct cpuinfo_x86 *c)
+void amd_mcheck_init(struct cpuinfo_x86 *c)
 {
        u32 l, h;
        int i;
index 2cf25d2ba0f11ee1b4120841e30f5cd9cabe5b98..6170af3c271aee39554172a0cd9eb9ce99452113 100644 (file)
@@ -16,7 +16,7 @@
 
 #include "mce.h"
 
-int mce_disabled __devinitdata = 0;
+int mce_disabled = 0;
 int nr_mce_banks;
 
 EXPORT_SYMBOL_GPL(nr_mce_banks);       /* non-fatal.o */
@@ -31,7 +31,7 @@ static fastcall void unexpected_machine_check(struct pt_regs * regs, long error_
 void fastcall (*machine_check_vector)(struct pt_regs *, long error_code) = unexpected_machine_check;
 
 /* This has to be run for each processor */
-void __devinit mcheck_init(struct cpuinfo_x86 *c)
+void mcheck_init(struct cpuinfo_x86 *c)
 {
        if (mce_disabled==1)
                return;
index 1d1e885f500ae9592d007844aec7000e06ff3017..fd2c459a31ef7f70a6433ba04378059b1db29f8c 100644 (file)
@@ -77,7 +77,7 @@ fastcall void smp_thermal_interrupt(struct pt_regs *regs)
 }
 
 /* P4/Xeon Thermal regulation detect and init */
-static void __devinit intel_init_thermal(struct cpuinfo_x86 *c)
+static void intel_init_thermal(struct cpuinfo_x86 *c)
 {
        u32 l, h;
        unsigned int cpu = smp_processor_id();
@@ -231,7 +231,7 @@ static fastcall void intel_machine_check(struct pt_regs * regs, long error_code)
 }
 
 
-void __devinit intel_p4_mcheck_init(struct cpuinfo_x86 *c)
+void intel_p4_mcheck_init(struct cpuinfo_x86 *c)
 {
        u32 l, h;
        int i;
index 3a2e24baddc78ee63ab546d9fc78760c2880310d..94bc43d950cf1eb2c1e3db71940ab60e231cac2b 100644 (file)
@@ -28,7 +28,7 @@ static fastcall void pentium_machine_check(struct pt_regs * regs, long error_cod
 }
 
 /* Set up machine check reporting for processors with Intel style MCE */
-void __devinit intel_p5_mcheck_init(struct cpuinfo_x86 *c)
+void intel_p5_mcheck_init(struct cpuinfo_x86 *c)
 {
        u32 l, h;
        
index 979b18bc95c192aa4fe2740245d4923319124927..deeae42ce199b80584e752609217978a7eb19b27 100644 (file)
@@ -79,7 +79,7 @@ static fastcall void intel_machine_check(struct pt_regs * regs, long error_code)
 }
 
 /* Set up machine check reporting for processors with Intel style MCE */
-void __devinit intel_p6_mcheck_init(struct cpuinfo_x86 *c)
+void intel_p6_mcheck_init(struct cpuinfo_x86 *c)
 {
        u32 l, h;
        int i;
index 5b9d2dd411d3a9e469a7c2806bb4e0f41a221889..9e424b6c293d3fea2727a814d02cc79b729cacfc 100644 (file)
@@ -22,7 +22,7 @@ static fastcall void winchip_machine_check(struct pt_regs * regs, long error_cod
 }
 
 /* Set up machine check reporting on the Winchip C6 series */
-void __devinit winchip_mcheck_init(struct cpuinfo_x86 *c)
+void winchip_mcheck_init(struct cpuinfo_x86 *c)
 {
        u32 lo, hi;
        machine_check_vector = winchip_machine_check;
index 6345b430b105fd913c1fdca36768910e2f7fd580..32b0c24ab9a6dcca721414a7027635aa06d2c828 100644 (file)
 #include <linux/config.h>
 #include <linux/kprobes.h>
 #include <linux/ptrace.h>
-#include <linux/spinlock.h>
 #include <linux/preempt.h>
 #include <asm/cacheflush.h>
 #include <asm/kdebug.h>
 #include <asm/desc.h>
 
-static struct kprobe *current_kprobe;
-static unsigned long kprobe_status, kprobe_old_eflags, kprobe_saved_eflags;
-static struct kprobe *kprobe_prev;
-static unsigned long kprobe_status_prev, kprobe_old_eflags_prev, kprobe_saved_eflags_prev;
-static struct pt_regs jprobe_saved_regs;
-static long *jprobe_saved_esp;
-/* copy of the kernel stack at the probe fire time */
-static kprobe_opcode_t jprobes_stack[MAX_STACK_SIZE];
 void jprobe_return_end(void);
 
+DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
+DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
+
 /*
  * returns non-zero if opcode modifies the interrupt flag.
  */
@@ -91,29 +85,30 @@ void __kprobes arch_remove_kprobe(struct kprobe *p)
 {
 }
 
-static inline void save_previous_kprobe(void)
+static inline void save_previous_kprobe(struct kprobe_ctlblk *kcb)
 {
-       kprobe_prev = current_kprobe;
-       kprobe_status_prev = kprobe_status;
-       kprobe_old_eflags_prev = kprobe_old_eflags;
-       kprobe_saved_eflags_prev = kprobe_saved_eflags;
+       kcb->prev_kprobe.kp = kprobe_running();
+       kcb->prev_kprobe.status = kcb->kprobe_status;
+       kcb->prev_kprobe.old_eflags = kcb->kprobe_old_eflags;
+       kcb->prev_kprobe.saved_eflags = kcb->kprobe_saved_eflags;
 }
 
-static inline void restore_previous_kprobe(void)
+static inline void restore_previous_kprobe(struct kprobe_ctlblk *kcb)
 {
-       current_kprobe = kprobe_prev;
-       kprobe_status = kprobe_status_prev;
-       kprobe_old_eflags = kprobe_old_eflags_prev;
-       kprobe_saved_eflags = kprobe_saved_eflags_prev;
+       __get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp;
+       kcb->kprobe_status = kcb->prev_kprobe.status;
+       kcb->kprobe_old_eflags = kcb->prev_kprobe.old_eflags;
+       kcb->kprobe_saved_eflags = kcb->prev_kprobe.saved_eflags;
 }
 
-static inline void set_current_kprobe(struct kprobe *p, struct pt_regs *regs)
+static inline void set_current_kprobe(struct kprobe *p, struct pt_regs *regs,
+                               struct kprobe_ctlblk *kcb)
 {
-       current_kprobe = p;
-       kprobe_saved_eflags = kprobe_old_eflags
+       __get_cpu_var(current_kprobe) = p;
+       kcb->kprobe_saved_eflags = kcb->kprobe_old_eflags
                = (regs->eflags & (TF_MASK | IF_MASK));
        if (is_IF_modifier(p->opcode))
-               kprobe_saved_eflags &= ~IF_MASK;
+               kcb->kprobe_saved_eflags &= ~IF_MASK;
 }
 
 static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
@@ -127,6 +122,7 @@ static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
                regs->eip = (unsigned long)&p->ainsn.insn;
 }
 
+/* Called with kretprobe_lock held */
 void __kprobes arch_prepare_kretprobe(struct kretprobe *rp,
                                      struct pt_regs *regs)
 {
@@ -157,9 +153,15 @@ static int __kprobes kprobe_handler(struct pt_regs *regs)
        int ret = 0;
        kprobe_opcode_t *addr = NULL;
        unsigned long *lp;
+       struct kprobe_ctlblk *kcb;
 
-       /* We're in an interrupt, but this is clear and BUG()-safe. */
+       /*
+        * We don't want to be preempted for the entire
+        * duration of kprobe processing
+        */
        preempt_disable();
+       kcb = get_kprobe_ctlblk();
+
        /* Check if the application is using LDT entry for its code segment and
         * calculate the address by reading the base address from the LDT entry.
         */
@@ -173,15 +175,12 @@ static int __kprobes kprobe_handler(struct pt_regs *regs)
        }
        /* Check we're not actually recursing */
        if (kprobe_running()) {
-               /* We *are* holding lock here, so this is safe.
-                  Disarm the probe we just hit, and ignore it. */
                p = get_kprobe(addr);
                if (p) {
-                       if (kprobe_status == KPROBE_HIT_SS &&
+                       if (kcb->kprobe_status == KPROBE_HIT_SS &&
                                *p->ainsn.insn == BREAKPOINT_INSTRUCTION) {
                                regs->eflags &= ~TF_MASK;
-                               regs->eflags |= kprobe_saved_eflags;
-                               unlock_kprobes();
+                               regs->eflags |= kcb->kprobe_saved_eflags;
                                goto no_kprobe;
                        }
                        /* We have reentered the kprobe_handler(), since
@@ -190,26 +189,23 @@ static int __kprobes kprobe_handler(struct pt_regs *regs)
                         * just single step on the instruction of the new probe
                         * without calling any user handlers.
                         */
-                       save_previous_kprobe();
-                       set_current_kprobe(p, regs);
+                       save_previous_kprobe(kcb);
+                       set_current_kprobe(p, regs, kcb);
                        p->nmissed++;
                        prepare_singlestep(p, regs);
-                       kprobe_status = KPROBE_REENTER;
+                       kcb->kprobe_status = KPROBE_REENTER;
                        return 1;
                } else {
-                       p = current_kprobe;
+                       p = __get_cpu_var(current_kprobe);
                        if (p->break_handler && p->break_handler(p, regs)) {
                                goto ss_probe;
                        }
                }
-               /* If it's not ours, can't be delete race, (we hold lock). */
                goto no_kprobe;
        }
 
-       lock_kprobes();
        p = get_kprobe(addr);
        if (!p) {
-               unlock_kprobes();
                if (regs->eflags & VM_MASK) {
                        /* We are in virtual-8086 mode. Return 0 */
                        goto no_kprobe;
@@ -232,8 +228,8 @@ static int __kprobes kprobe_handler(struct pt_regs *regs)
                goto no_kprobe;
        }
 
-       kprobe_status = KPROBE_HIT_ACTIVE;
-       set_current_kprobe(p, regs);
+       set_current_kprobe(p, regs, kcb);
+       kcb->kprobe_status = KPROBE_HIT_ACTIVE;
 
        if (p->pre_handler && p->pre_handler(p, regs))
                /* handler has already set things up, so skip ss setup */
@@ -241,7 +237,7 @@ static int __kprobes kprobe_handler(struct pt_regs *regs)
 
 ss_probe:
        prepare_singlestep(p, regs);
-       kprobe_status = KPROBE_HIT_SS;
+       kcb->kprobe_status = KPROBE_HIT_SS;
        return 1;
 
 no_kprobe:
@@ -269,9 +265,10 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
         struct kretprobe_instance *ri = NULL;
         struct hlist_head *head;
         struct hlist_node *node, *tmp;
-       unsigned long orig_ret_address = 0;
+       unsigned long flags, orig_ret_address = 0;
        unsigned long trampoline_address =(unsigned long)&kretprobe_trampoline;
 
+       spin_lock_irqsave(&kretprobe_lock, flags);
         head = kretprobe_inst_table_head(current);
 
        /*
@@ -310,14 +307,15 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
        BUG_ON(!orig_ret_address || (orig_ret_address == trampoline_address));
        regs->eip = orig_ret_address;
 
-       unlock_kprobes();
+       reset_current_kprobe();
+       spin_unlock_irqrestore(&kretprobe_lock, flags);
        preempt_enable_no_resched();
 
-        /*
-         * By returning a non-zero value, we are telling
-         * kprobe_handler() that we have handled unlocking
-         * and re-enabling preemption.
-         */
+       /*
+        * By returning a non-zero value, we are telling
+        * kprobe_handler() that we don't want the post_handler
+        * to run (and have re-enabled preemption)
+        */
         return 1;
 }
 
@@ -343,7 +341,8 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
  * that is atop the stack is the address following the copied instruction.
  * We need to make it the address following the original instruction.
  */
-static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs)
+static void __kprobes resume_execution(struct kprobe *p,
+               struct pt_regs *regs, struct kprobe_ctlblk *kcb)
 {
        unsigned long *tos = (unsigned long *)&regs->esp;
        unsigned long next_eip = 0;
@@ -353,7 +352,7 @@ static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs)
        switch (p->ainsn.insn[0]) {
        case 0x9c:              /* pushfl */
                *tos &= ~(TF_MASK | IF_MASK);
-               *tos |= kprobe_old_eflags;
+               *tos |= kcb->kprobe_old_eflags;
                break;
        case 0xc3:              /* ret/lret */
        case 0xcb:
@@ -394,27 +393,30 @@ static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs)
 
 /*
  * Interrupts are disabled on entry as trap1 is an interrupt gate and they
- * remain disabled thoroughout this function.  And we hold kprobe lock.
+ * remain disabled thoroughout this function.
  */
 static inline int post_kprobe_handler(struct pt_regs *regs)
 {
-       if (!kprobe_running())
+       struct kprobe *cur = kprobe_running();
+       struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+
+       if (!cur)
                return 0;
 
-       if ((kprobe_status != KPROBE_REENTER) && current_kprobe->post_handler) {
-               kprobe_status = KPROBE_HIT_SSDONE;
-               current_kprobe->post_handler(current_kprobe, regs, 0);
+       if ((kcb->kprobe_status != KPROBE_REENTER) && cur->post_handler) {
+               kcb->kprobe_status = KPROBE_HIT_SSDONE;
+               cur->post_handler(cur, regs, 0);
        }
 
-       resume_execution(current_kprobe, regs);
-       regs->eflags |= kprobe_saved_eflags;
+       resume_execution(cur, regs, kcb);
+       regs->eflags |= kcb->kprobe_saved_eflags;
 
        /*Restore back the original saved kprobes variables and continue. */
-       if (kprobe_status == KPROBE_REENTER) {
-               restore_previous_kprobe();
+       if (kcb->kprobe_status == KPROBE_REENTER) {
+               restore_previous_kprobe(kcb);
                goto out;
        }
-       unlock_kprobes();
+       reset_current_kprobe();
 out:
        preempt_enable_no_resched();
 
@@ -429,18 +431,19 @@ out:
        return 1;
 }
 
-/* Interrupts disabled, kprobe_lock held. */
 static inline int kprobe_fault_handler(struct pt_regs *regs, int trapnr)
 {
-       if (current_kprobe->fault_handler
-           && current_kprobe->fault_handler(current_kprobe, regs, trapnr))
+       struct kprobe *cur = kprobe_running();
+       struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+
+       if (cur->fault_handler && cur->fault_handler(cur, regs, trapnr))
                return 1;
 
-       if (kprobe_status & KPROBE_HIT_SS) {
-               resume_execution(current_kprobe, regs);
-               regs->eflags |= kprobe_old_eflags;
+       if (kcb->kprobe_status & KPROBE_HIT_SS) {
+               resume_execution(cur, regs, kcb);
+               regs->eflags |= kcb->kprobe_old_eflags;
 
-               unlock_kprobes();
+               reset_current_kprobe();
                preempt_enable_no_resched();
        }
        return 0;
@@ -453,39 +456,41 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
                                       unsigned long val, void *data)
 {
        struct die_args *args = (struct die_args *)data;
+       int ret = NOTIFY_DONE;
+
        switch (val) {
        case DIE_INT3:
                if (kprobe_handler(args->regs))
-                       return NOTIFY_STOP;
+                       ret = NOTIFY_STOP;
                break;
        case DIE_DEBUG:
                if (post_kprobe_handler(args->regs))
-                       return NOTIFY_STOP;
+                       ret = NOTIFY_STOP;
                break;
        case DIE_GPF:
-               if (kprobe_running() &&
-                   kprobe_fault_handler(args->regs, args->trapnr))
-                       return NOTIFY_STOP;
-               break;
        case DIE_PAGE_FAULT:
+               /* kprobe_running() needs smp_processor_id() */
+               preempt_disable();
                if (kprobe_running() &&
                    kprobe_fault_handler(args->regs, args->trapnr))
-                       return NOTIFY_STOP;
+                       ret = NOTIFY_STOP;
+               preempt_enable();
                break;
        default:
                break;
        }
-       return NOTIFY_DONE;
+       return ret;
 }
 
 int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
 {
        struct jprobe *jp = container_of(p, struct jprobe, kp);
        unsigned long addr;
+       struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
 
-       jprobe_saved_regs = *regs;
-       jprobe_saved_esp = &regs->esp;
-       addr = (unsigned long)jprobe_saved_esp;
+       kcb->jprobe_saved_regs = *regs;
+       kcb->jprobe_saved_esp = &regs->esp;
+       addr = (unsigned long)(kcb->jprobe_saved_esp);
 
        /*
         * TBD: As Linus pointed out, gcc assumes that the callee
@@ -494,7 +499,8 @@ int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
         * we also save and restore enough stack bytes to cover
         * the argument area.
         */
-       memcpy(jprobes_stack, (kprobe_opcode_t *) addr, MIN_STACK_SIZE(addr));
+       memcpy(kcb->jprobes_stack, (kprobe_opcode_t *)addr,
+                       MIN_STACK_SIZE(addr));
        regs->eflags &= ~IF_MASK;
        regs->eip = (unsigned long)(jp->entry);
        return 1;
@@ -502,36 +508,40 @@ int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
 
 void __kprobes jprobe_return(void)
 {
-       preempt_enable_no_resched();
+       struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+
        asm volatile ("       xchgl   %%ebx,%%esp     \n"
                      "       int3                      \n"
                      "       .globl jprobe_return_end  \n"
                      "       jprobe_return_end:        \n"
                      "       nop                       \n"::"b"
-                     (jprobe_saved_esp):"memory");
+                     (kcb->jprobe_saved_esp):"memory");
 }
 
 int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
 {
+       struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
        u8 *addr = (u8 *) (regs->eip - 1);
-       unsigned long stack_addr = (unsigned long)jprobe_saved_esp;
+       unsigned long stack_addr = (unsigned long)(kcb->jprobe_saved_esp);
        struct jprobe *jp = container_of(p, struct jprobe, kp);
 
        if ((addr > (u8 *) jprobe_return) && (addr < (u8 *) jprobe_return_end)) {
-               if (&regs->esp != jprobe_saved_esp) {
+               if (&regs->esp != kcb->jprobe_saved_esp) {
                        struct pt_regs *saved_regs =
-                           container_of(jprobe_saved_esp, struct pt_regs, esp);
+                           container_of(kcb->jprobe_saved_esp,
+                                           struct pt_regs, esp);
                        printk("current esp %p does not match saved esp %p\n",
-                              &regs->esp, jprobe_saved_esp);
+                              &regs->esp, kcb->jprobe_saved_esp);
                        printk("Saved registers for jprobe %p\n", jp);
                        show_registers(saved_regs);
                        printk("Current registers\n");
                        show_registers(regs);
                        BUG();
                }
-               *regs = jprobe_saved_regs;
-               memcpy((kprobe_opcode_t *) stack_addr, jprobes_stack,
+               *regs = kcb->jprobe_saved_regs;
+               memcpy((kprobe_opcode_t *) stack_addr, kcb->jprobes_stack,
                       MIN_STACK_SIZE(stack_addr));
+               preempt_enable_no_resched();
                return 1;
        }
        return 0;
index fe1ffa55587d483668d0f19adda973df7ea57190..983f95707e1169f75c761bdfd7c43e87479f7c67 100644 (file)
@@ -18,6 +18,7 @@
 #include <asm/system.h>
 #include <asm/ldt.h>
 #include <asm/desc.h>
+#include <asm/mmu_context.h>
 
 #ifdef CONFIG_SMP /* avoids "defined but not used" warnig */
 static void flush_ldt(void *null)
index 8600faeea29ddb186b1bb5b271ddf8c767ebc3da..558bb207720f1ecf13f2fe624037e9bf6b307a56 100644 (file)
@@ -132,7 +132,7 @@ static struct resource mca_standard_resources[] = {
        { .start = 0x100, .end = 0x107, .name = "POS (MCA)" }
 };
 
-#define MCA_STANDARD_RESOURCES (sizeof(mca_standard_resources)/sizeof(struct resource))
+#define MCA_STANDARD_RESOURCES ARRAY_SIZE(mca_standard_resources)
 
 /**
  *     mca_read_and_store_pos - read the POS registers into a memory buffer
index efd11f09c99663208a14e918d69fe2a607b666fe..5ffbb4b7ad059a038b7273de448b8e5f97ac5c20 100644 (file)
@@ -354,49 +354,12 @@ ptrace_set_thread_area(struct task_struct *child,
        return 0;
 }
 
-asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
 {
-       struct task_struct *child;
        struct user * dummy = NULL;
        int i, ret;
        unsigned long __user *datap = (unsigned long __user *)data;
 
-       lock_kernel();
-       ret = -EPERM;
-       if (request == PTRACE_TRACEME) {
-               /* are we already being traced? */
-               if (current->ptrace & PT_PTRACED)
-                       goto out;
-               ret = security_ptrace(current->parent, current);
-               if (ret)
-                       goto out;
-               /* set the ptrace bit in the process flags. */
-               current->ptrace |= PT_PTRACED;
-               ret = 0;
-               goto out;
-       }
-       ret = -ESRCH;
-       read_lock(&tasklist_lock);
-       child = find_task_by_pid(pid);
-       if (child)
-               get_task_struct(child);
-       read_unlock(&tasklist_lock);
-       if (!child)
-               goto out;
-
-       ret = -EPERM;
-       if (pid == 1)           /* you may not mess with init */
-               goto out_tsk;
-
-       if (request == PTRACE_ATTACH) {
-               ret = ptrace_attach(child);
-               goto out_tsk;
-       }
-
-       ret = ptrace_check_attach(child, request == PTRACE_KILL);
-       if (ret < 0)
-               goto out_tsk;
-
        switch (request) {
        /* when I and D space are separate, these will need to be fixed. */
        case PTRACE_PEEKTEXT: /* read word at location addr. */ 
@@ -663,10 +626,7 @@ asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
                ret = ptrace_request(child, request, addr, data);
                break;
        }
-out_tsk:
-       put_task_struct(child);
-out:
-       unlock_kernel();
+ out_tsk:
        return ret;
 }
 
index c9b87330aeeacfb49009faa725f51c1343d3a308..10e21a4773dd4e822a82d461c4d1ee17f3f7164d 100644 (file)
@@ -10,6 +10,7 @@
 
 #include <asm/delay.h>
 #include <linux/pci.h>
+#include <linux/reboot_fixups.h>
 
 static void cs5530a_warm_reset(struct pci_dev *dev)
 {
@@ -42,7 +43,7 @@ void mach_reboot_fixups(void)
        struct pci_dev *dev;
        int i;
 
-       for (i=0; i < (sizeof(fixups_table)/sizeof(fixups_table[0])); i++) {
+       for (i=0; i < ARRAY_SIZE(fixups_table); i++) {
                cur = &(fixups_table[i]);
                dev = pci_get_device(cur->vendor, cur->device, NULL);
                if (!dev)
index 69e203a0d330ea8de05182f38bb53e5681fabfcb..9c968ae67c43dd1d4c008db3f37c8bc64a9f802d 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/pci.h>
 
 #include <linux/scx200.h>
+#include <linux/scx200_gpio.h>
 
 /* Verify that the configuration block really is there */
 #define scx200_cb_probe(base) (inw((base) + SCx200_CBA) == (base))
index 01b618e73ecd14ba6f9dedea08a718865715d266..47ec76794d02ac11bdcef2416bff7796a9099572 100644 (file)
@@ -68,11 +68,9 @@ EXPORT_SYMBOL(smp_num_siblings);
 
 /* Package ID of each logical CPU */
 int phys_proc_id[NR_CPUS] __read_mostly = {[0 ... NR_CPUS-1] = BAD_APICID};
-EXPORT_SYMBOL(phys_proc_id);
 
 /* Core ID of each logical CPU */
 int cpu_core_id[NR_CPUS] __read_mostly = {[0 ... NR_CPUS-1] = BAD_APICID};
-EXPORT_SYMBOL(cpu_core_id);
 
 cpumask_t cpu_sibling_map[NR_CPUS] __read_mostly;
 EXPORT_SYMBOL(cpu_sibling_map);
@@ -612,7 +610,7 @@ static inline void __inquire_remote_apic(int apicid)
 
        printk("Inquiring remote APIC #%d...\n", apicid);
 
-       for (i = 0; i < sizeof(regs) / sizeof(*regs); i++) {
+       for (i = 0; i < ARRAY_SIZE(regs); i++) {
                printk("... APIC #%d %s: ", apicid, names[i]);
 
                /*
index 5ade19801b97a598829b4b1dff817a6cc59a028e..d8a84088471a1c011868aae0b44558d15c9f1c0b 100644 (file)
@@ -1,7 +1,3 @@
-
-menu "Profiling support"
-       depends on EXPERIMENTAL
-
 config PROFILING
        bool "Profiling support (EXPERIMENTAL)"
        help
@@ -19,5 +15,3 @@ config OPROFILE
 
          If unsure, say N.
 
-endmenu
-
index 1f1572692e0b7eeaa9c318a5051c98f4d8de2402..50a0bef8c85f691bc135167e595dc5b6521a8ec0 100644 (file)
@@ -118,6 +118,7 @@ void __restore_processor_state(struct saved_context *ctxt)
        fix_processor_context();
        do_fpu_end();
        mtrr_ap_init();
+       mcheck_init(&boot_cpu_data);
 }
 
 void restore_processor_state(void)
index 3b4248cff9a7d1218182dcf7d380eda86b3b426d..9f2093c1f44b0ed9507633c5f8c8bd0ad696437d 100644 (file)
@@ -426,8 +426,21 @@ config GENERIC_PENDING_IRQ
 
 source "arch/ia64/hp/sim/Kconfig"
 
+menu "Instrumentation Support"
+        depends on EXPERIMENTAL
+
 source "arch/ia64/oprofile/Kconfig"
 
+config KPROBES
+       bool "Kprobes (EXPERIMENTAL)"
+       help
+         Kprobes allows you to trap at almost any kernel address and
+         execute a callback function.  register_kprobe() establishes
+         a probepoint and specifies the callback.  Kprobes is useful
+         for kernel debugging, non-intrusive instrumentation and testing.
+         If in doubt, say "N".
+endmenu
+
 source "arch/ia64/Kconfig.debug"
 
 source "security/Kconfig"
index fda67ac993d7e958b5747514594e73ce9cd9bf94..de9d507ba0fd466d8b466f54d1143a46d20caaa0 100644 (file)
@@ -2,17 +2,6 @@ menu "Kernel hacking"
 
 source "lib/Kconfig.debug"
 
-config KPROBES
-        bool "Kprobes"
-        depends on DEBUG_KERNEL
-        help
-          Kprobes allows you to trap at almost any kernel address and
-          execute a callback function.  register_kprobe() establishes
-          a probepoint and specifies the callback.  Kprobes is useful
-          for kernel debugging, non-intrusive instrumentation and testing.
-          If in doubt, say "N".
-
-
 choice
        prompt "Physical memory granularity"
        default IA64_GRANULE_64MB
index b42ec37be51c317911e1037d85718a9b95fdc045..19ee635eeb707566daa0e3b8d5eafd895490a2a9 100644 (file)
@@ -642,10 +642,8 @@ static void rs_close(struct tty_struct *tty, struct file * filp)
        info->event = 0;
        info->tty = 0;
        if (info->blocked_open) {
-               if (info->close_delay) {
-                       current->state = TASK_INTERRUPTIBLE;
-                       schedule_timeout(info->close_delay);
-               }
+               if (info->close_delay)
+                       schedule_timeout_interruptible(info->close_delay);
                wake_up_interruptible(&info->open_wait);
        }
        info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
index 471086b808a4b942781aa19abe940fb08dc8533b..96736a119c911e22fcbab6d6e7aabb1529a04a9a 100644 (file)
@@ -26,7 +26,6 @@
 #include <linux/config.h>
 #include <linux/kprobes.h>
 #include <linux/ptrace.h>
-#include <linux/spinlock.h>
 #include <linux/string.h>
 #include <linux/slab.h>
 #include <linux/preempt.h>
 
 extern void jprobe_inst_return(void);
 
-/* kprobe_status settings */
-#define KPROBE_HIT_ACTIVE      0x00000001
-#define KPROBE_HIT_SS          0x00000002
-
-static struct kprobe *current_kprobe, *kprobe_prev;
-static unsigned long kprobe_status, kprobe_status_prev;
-static struct pt_regs jprobe_saved_regs;
+DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
+DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
 
 enum instruction_type {A, I, M, F, B, L, X, u};
 static enum instruction_type bundle_encoding[32][3] = {
@@ -313,21 +307,22 @@ static int __kprobes valid_kprobe_addr(int template, int slot,
        return 0;
 }
 
-static inline void save_previous_kprobe(void)
+static inline void save_previous_kprobe(struct kprobe_ctlblk *kcb)
 {
-       kprobe_prev = current_kprobe;
-       kprobe_status_prev = kprobe_status;
+       kcb->prev_kprobe.kp = kprobe_running();
+       kcb->prev_kprobe.status = kcb->kprobe_status;
 }
 
-static inline void restore_previous_kprobe(void)
+static inline void restore_previous_kprobe(struct kprobe_ctlblk *kcb)
 {
-       current_kprobe = kprobe_prev;
-       kprobe_status = kprobe_status_prev;
+       __get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp;
+       kcb->kprobe_status = kcb->prev_kprobe.status;
 }
 
-static inline void set_current_kprobe(struct kprobe *p)
+static inline void set_current_kprobe(struct kprobe *p,
+                       struct kprobe_ctlblk *kcb)
 {
-       current_kprobe = p;
+       __get_cpu_var(current_kprobe) = p;
 }
 
 static void kretprobe_trampoline(void)
@@ -347,10 +342,11 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
        struct kretprobe_instance *ri = NULL;
        struct hlist_head *head;
        struct hlist_node *node, *tmp;
-       unsigned long orig_ret_address = 0;
+       unsigned long flags, orig_ret_address = 0;
        unsigned long trampoline_address =
                ((struct fnptr *)kretprobe_trampoline)->ip;
 
+       spin_lock_irqsave(&kretprobe_lock, flags);
         head = kretprobe_inst_table_head(current);
 
        /*
@@ -389,17 +385,19 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
        BUG_ON(!orig_ret_address || (orig_ret_address == trampoline_address));
        regs->cr_iip = orig_ret_address;
 
-       unlock_kprobes();
+       reset_current_kprobe();
+       spin_unlock_irqrestore(&kretprobe_lock, flags);
        preempt_enable_no_resched();
 
-        /*
-         * By returning a non-zero value, we are telling
-         * kprobe_handler() that we have handled unlocking
-         * and re-enabling preemption.
-         */
+       /*
+        * By returning a non-zero value, we are telling
+        * kprobe_handler() that we don't want the post_handler
+        * to run (and have re-enabled preemption)
+        */
         return 1;
 }
 
+/* Called with kretprobe_lock held */
 void __kprobes arch_prepare_kretprobe(struct kretprobe *rp,
                                      struct pt_regs *regs)
 {
@@ -606,17 +604,22 @@ static int __kprobes pre_kprobes_handler(struct die_args *args)
        int ret = 0;
        struct pt_regs *regs = args->regs;
        kprobe_opcode_t *addr = (kprobe_opcode_t *)instruction_pointer(regs);
+       struct kprobe_ctlblk *kcb;
 
+       /*
+        * We don't want to be preempted for the entire
+        * duration of kprobe processing
+        */
        preempt_disable();
+       kcb = get_kprobe_ctlblk();
 
        /* Handle recursion cases */
        if (kprobe_running()) {
                p = get_kprobe(addr);
                if (p) {
-                       if ( (kprobe_status == KPROBE_HIT_SS) &&
+                       if ((kcb->kprobe_status == KPROBE_HIT_SS) &&
                             (p->ainsn.inst_flag == INST_FLAG_BREAK_INST)) {
                                ia64_psr(regs)->ss = 0;
-                               unlock_kprobes();
                                goto no_kprobe;
                        }
                        /* We have reentered the pre_kprobe_handler(), since
@@ -625,17 +628,17 @@ static int __kprobes pre_kprobes_handler(struct die_args *args)
                         * just single step on the instruction of the new probe
                         * without calling any user handlers.
                         */
-                       save_previous_kprobe();
-                       set_current_kprobe(p);
+                       save_previous_kprobe(kcb);
+                       set_current_kprobe(p, kcb);
                        p->nmissed++;
                        prepare_ss(p, regs);
-                       kprobe_status = KPROBE_REENTER;
+                       kcb->kprobe_status = KPROBE_REENTER;
                        return 1;
                } else if (args->err == __IA64_BREAK_JPROBE) {
                        /*
                         * jprobe instrumented function just completed
                         */
-                       p = current_kprobe;
+                       p = __get_cpu_var(current_kprobe);
                        if (p->break_handler && p->break_handler(p, regs)) {
                                goto ss_probe;
                        }
@@ -645,10 +648,8 @@ static int __kprobes pre_kprobes_handler(struct die_args *args)
                }
        }
 
-       lock_kprobes();
        p = get_kprobe(addr);
        if (!p) {
-               unlock_kprobes();
                if (!is_ia64_break_inst(regs)) {
                        /*
                         * The breakpoint instruction was removed right
@@ -665,8 +666,8 @@ static int __kprobes pre_kprobes_handler(struct die_args *args)
                goto no_kprobe;
        }
 
-       kprobe_status = KPROBE_HIT_ACTIVE;
-       set_current_kprobe(p);
+       set_current_kprobe(p, kcb);
+       kcb->kprobe_status = KPROBE_HIT_ACTIVE;
 
        if (p->pre_handler && p->pre_handler(p, regs))
                /*
@@ -678,7 +679,7 @@ static int __kprobes pre_kprobes_handler(struct die_args *args)
 
 ss_probe:
        prepare_ss(p, regs);
-       kprobe_status = KPROBE_HIT_SS;
+       kcb->kprobe_status = KPROBE_HIT_SS;
        return 1;
 
 no_kprobe:
@@ -688,23 +689,25 @@ no_kprobe:
 
 static int __kprobes post_kprobes_handler(struct pt_regs *regs)
 {
-       if (!kprobe_running())
+       struct kprobe *cur = kprobe_running();
+       struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+
+       if (!cur)
                return 0;
 
-       if ((kprobe_status != KPROBE_REENTER) && current_kprobe->post_handler) {
-               kprobe_status = KPROBE_HIT_SSDONE;
-               current_kprobe->post_handler(current_kprobe, regs, 0);
+       if ((kcb->kprobe_status != KPROBE_REENTER) && cur->post_handler) {
+               kcb->kprobe_status = KPROBE_HIT_SSDONE;
+               cur->post_handler(cur, regs, 0);
        }
 
-       resume_execution(current_kprobe, regs);
+       resume_execution(cur, regs);
 
        /*Restore back the original saved kprobes variables and continue. */
-       if (kprobe_status == KPROBE_REENTER) {
-               restore_previous_kprobe();
+       if (kcb->kprobe_status == KPROBE_REENTER) {
+               restore_previous_kprobe(kcb);
                goto out;
        }
-
-       unlock_kprobes();
+       reset_current_kprobe();
 
 out:
        preempt_enable_no_resched();
@@ -713,16 +716,15 @@ out:
 
 static int __kprobes kprobes_fault_handler(struct pt_regs *regs, int trapnr)
 {
-       if (!kprobe_running())
-               return 0;
+       struct kprobe *cur = kprobe_running();
+       struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
 
-       if (current_kprobe->fault_handler &&
-           current_kprobe->fault_handler(current_kprobe, regs, trapnr))
+       if (cur->fault_handler && cur->fault_handler(cur, regs, trapnr))
                return 1;
 
-       if (kprobe_status & KPROBE_HIT_SS) {
-               resume_execution(current_kprobe, regs);
-               unlock_kprobes();
+       if (kcb->kprobe_status & KPROBE_HIT_SS) {
+               resume_execution(cur, regs);
+               reset_current_kprobe();
                preempt_enable_no_resched();
        }
 
@@ -733,31 +735,38 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
                                       unsigned long val, void *data)
 {
        struct die_args *args = (struct die_args *)data;
+       int ret = NOTIFY_DONE;
+
        switch(val) {
        case DIE_BREAK:
                if (pre_kprobes_handler(args))
-                       return NOTIFY_STOP;
+                       ret = NOTIFY_STOP;
                break;
        case DIE_SS:
                if (post_kprobes_handler(args->regs))
-                       return NOTIFY_STOP;
+                       ret = NOTIFY_STOP;
                break;
        case DIE_PAGE_FAULT:
-               if (kprobes_fault_handler(args->regs, args->trapnr))
-                       return NOTIFY_STOP;
+               /* kprobe_running() needs smp_processor_id() */
+               preempt_disable();
+               if (kprobe_running() &&
+                       kprobes_fault_handler(args->regs, args->trapnr))
+                       ret = NOTIFY_STOP;
+               preempt_enable();
        default:
                break;
        }
-       return NOTIFY_DONE;
+       return ret;
 }
 
 int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
 {
        struct jprobe *jp = container_of(p, struct jprobe, kp);
        unsigned long addr = ((struct fnptr *)(jp->entry))->ip;
+       struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
 
        /* save architectural state */
-       jprobe_saved_regs = *regs;
+       kcb->jprobe_saved_regs = *regs;
 
        /* after rfi, execute the jprobe instrumented function */
        regs->cr_iip = addr & ~0xFULL;
@@ -775,7 +784,10 @@ int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
 
 int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
 {
-       *regs = jprobe_saved_regs;
+       struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+
+       *regs = kcb->jprobe_saved_regs;
+       preempt_enable_no_resched();
        return 1;
 }
 
index f7dfc107cb7bd6040eca8f4e7aa46b7531c4a443..410d4804fa6e0cb4086e6fb6af75760337a60d23 100644 (file)
@@ -4940,7 +4940,7 @@ abort_locked:
        if (call_made && PFM_CMD_RW_ARG(cmd) && copy_to_user(arg, args_k, base_sz*count)) ret = -EFAULT;
 
 error_args:
-       if (args_k) kfree(args_k);
+       kfree(args_k);
 
        DPRINT(("cmd=%s ret=%ld\n", PFM_CMD_NAME(cmd), ret));
 
index fc56ca2da35899e0bd5b5b42dfe2e4c399d1fc8d..3af6de36a4822e72c537a12f4a8ef6fe6f950ef7 100644 (file)
@@ -92,6 +92,13 @@ extern void efi_initialize_iomem_resources(struct resource *,
 extern char _text[], _end[], _etext[];
 
 unsigned long ia64_max_cacheline_size;
+
+int dma_get_cache_alignment(void)
+{
+        return ia64_max_cacheline_size;
+}
+EXPORT_SYMBOL(dma_get_cache_alignment);
+
 unsigned long ia64_iobase;     /* virtual address for I/O accesses */
 EXPORT_SYMBOL(ia64_iobase);
 struct io_space io_space[MAX_IO_SPACES];
index 56e6f614b04a58592203d5fc3a12f69319da485a..97271ab484dc8406a181fe36f717ff2b5e3ba417 100644 (file)
@@ -1,7 +1,3 @@
-
-menu "Profiling support"
-       depends on EXPERIMENTAL
-
 config PROFILING
        bool "Profiling support (EXPERIMENTAL)"
        help
@@ -22,5 +18,3 @@ config OPROFILE
 
          If unsure, say N.
 
-endmenu
-
index 6df7fb60dfea5af07a03950b62dc3d200c77a600..e79bbc94216dab99289925ba8208181952eb4369 100644 (file)
@@ -212,10 +212,8 @@ 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 ) {
-        current->state = TASK_INTERRUPTIBLE;
-        schedule_timeout(HWCLK_POLL_INTERVAL);
-    }
+    while( RTC_READ(RTC_FREQ_SELECT) & RTC_UIP )
+        schedule_timeout_interruptible(HWCLK_POLL_INTERVAL);
 
     local_irq_save(flags);
     RTC_WRITE( RTC_CONTROL, ctrl | RTC_SET );
index f7f1d2e5b90bcec403526c14c1f183fc74d3fe4e..7e54422685cfc1ed8737d29bac74124b3a4f8cdd 100644 (file)
@@ -121,48 +121,11 @@ void ptrace_disable(struct task_struct *child)
        child->thread.work.syscall_trace = 0;
 }
 
-asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
 {
-       struct task_struct *child;
        unsigned long tmp;
        int i, ret = 0;
 
-       lock_kernel();
-       if (request == PTRACE_TRACEME) {
-               /* are we already being traced? */
-               if (current->ptrace & PT_PTRACED) {
-                       ret = -EPERM;
-                       goto out;
-               }
-               /* set the ptrace bit in the process flags. */
-               current->ptrace |= PT_PTRACED;
-               goto out;
-       }
-       read_lock(&tasklist_lock);
-       child = find_task_by_pid(pid);
-       if (child)
-               get_task_struct(child);
-       read_unlock(&tasklist_lock);
-       if (unlikely(!child)) {
-               ret = -ESRCH;
-               goto out;
-       }
-
-       /* you may not mess with init */
-       if (unlikely(pid == 1)) {
-               ret = -EPERM;
-               goto out_tsk;
-       }
-
-       if (request == PTRACE_ATTACH) {
-               ret = ptrace_attach(child);
-               goto out_tsk;
-       }
-
-       ret = ptrace_check_attach(child, request == PTRACE_KILL);
-       if (ret)
-               goto out_tsk;
-
        switch (request) {
        /* when I and D space are separate, these will need to be fixed. */
        case PTRACE_PEEKTEXT:   /* read word at location addr. */
@@ -317,14 +280,10 @@ asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
                ret = ptrace_request(child, request, addr, data);
                break;
        }
-out_tsk:
-       put_task_struct(child);
-out:
-       unlock_kernel();
+
        return ret;
 out_eio:
-       ret = -EIO;
-       goto out_tsk;
+       return -EIO;
 }
 
 asmlinkage void syscall_trace(void)
index 8520df9cee6dd8c6cd9464b9d28bd23ee2292c83..b96498120fe9aed0c3dc9565c89e9b93c92bb8d2 100644 (file)
@@ -71,6 +71,11 @@ config M5206e
        help
          Motorola ColdFire 5206e processor support.
 
+config M520x
+       bool "MCF520x"
+       help
+          Freescale Coldfire 5207/5208 processor support.
+
 config M523x
        bool "MCF523x"
        help
@@ -120,7 +125,7 @@ config M527x
 
 config COLDFIRE
        bool
-       depends on (M5206 || M5206e || M523x || M5249 || M527x || M5272 || M528x || M5307 || M5407)
+       depends on (M5206 || M5206e || M520x || M523x || M5249 || M527x || M5272 || M528x || M5307 || M5407)
        default y
 
 choice
@@ -322,6 +327,12 @@ config ELITE
        help
          Support for the Motorola M5206eLITE board.
 
+config M5208EVB
+       bool "Freescale M5208EVB board support"
+       depends on M520x
+       help
+         Support for the Freescale Coldfire M5208EVB.
+
 config M5235EVB
        bool "Freescale M5235EVB support"
        depends on M523x
@@ -465,10 +476,10 @@ config ARNEWSH
        default y
        depends on (ARN5206 || ARN5307)
 
-config MOTOROLA
+config FREESCALE
        bool
        default y
-       depends on (M5206eC3 || M5235EVB || M5249C3 || M5271EVB || M5272C3 || M5275EVB || M5282EVB || M5307C3 || M5407C3)
+       depends on (M5206eC3 || M5208EVB || M5235EVB || M5249C3 || M5271EVB || M5272C3 || M5275EVB || M5282EVB || M5307C3 || M5407C3)
 
 config HW_FEITH
        bool
index b8fdf191b8f6b3e95d05830f13dc33e7b06c1425..b6b5c14e55fd1dbc89baf0de69477d6749ddca09 100644 (file)
@@ -14,6 +14,7 @@ platform-$(CONFIG_M68VZ328)   := 68VZ328
 platform-$(CONFIG_M68360)      := 68360
 platform-$(CONFIG_M5206)       := 5206
 platform-$(CONFIG_M5206e)      := 5206e
+platform-$(CONFIG_M520x)       := 520x
 platform-$(CONFIG_M523x)       := 523x
 platform-$(CONFIG_M5249)       := 5249
 platform-$(CONFIG_M527x)       := 527x
@@ -29,7 +30,7 @@ board-$(CONFIG_UCDIMM)                := ucdimm
 board-$(CONFIG_UCQUICC)                := uCquicc
 board-$(CONFIG_DRAGEN2)                := de2
 board-$(CONFIG_ARNEWSH)                := ARNEWSH
-board-$(CONFIG_MOTOROLA)       := MOTOROLA
+board-$(CONFIG_FREESCALE)      := FREESCALE
 board-$(CONFIG_M5235EVB)       := M5235EVB
 board-$(CONFIG_M5271EVB)       := M5271EVB
 board-$(CONFIG_M5275EVB)       := M5275EVB
@@ -41,6 +42,7 @@ board-$(CONFIG_SECUREEDGEMP3) := MP3
 board-$(CONFIG_CLEOPATRA)      := CLEOPATRA
 board-$(CONFIG_senTec)         := senTec
 board-$(CONFIG_SNEHA)          := SNEHA
+board-$(CONFIG_M5208EVB)       := M5208EVB
 board-$(CONFIG_MOD5272)                := MOD5272
 BOARD := $(board-y)
 
@@ -56,6 +58,7 @@ MODEL := $(model-y)
 #
 cpuclass-$(CONFIG_M5206)       := 5307
 cpuclass-$(CONFIG_M5206e)      := 5307
+cpuclass-$(CONFIG_M520x)       := 5307
 cpuclass-$(CONFIG_M523x)       := 5307
 cpuclass-$(CONFIG_M5249)       := 5307
 cpuclass-$(CONFIG_M527x)       := 5307
@@ -80,6 +83,7 @@ export PLATFORM BOARD MODEL CPUCLASS
 #
 cflags-$(CONFIG_M5206)         := -m5200 -Wa,-S -Wa,-m5200
 cflags-$(CONFIG_M5206e)                := -m5200 -Wa,-S -Wa,-m5200
+cflags-$(CONFIG_M520x)         := -m5307 -Wa,-S -Wa,-m5307
 cflags-$(CONFIG_M523x)         := -m5307 -Wa,-S -Wa,-m5307
 cflags-$(CONFIG_M5249)         := -m5200 -Wa,-S -Wa,-m5200
 cflags-$(CONFIG_M527x)         := -m5307 -Wa,-S -Wa,-m5307
@@ -95,7 +99,6 @@ cflags-$(CONFIG_M68360)               := -m68332
 AFLAGS += $(cflags-y)
 
 CFLAGS += $(cflags-y)
-CFLAGS += -fno-builtin
 CFLAGS += -O1 -g
 CFLAGS += -D__linux__
 CFLAGS += -DUTS_SYSNAME=\"uClinux\"
index cd3ffe12653e1577e3a31068a9f64eecb9db45a4..b988c7bdc6e4d6fd78656b68b1e41fdea1131da0 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/hardirq.h>
 #include <asm/bootinfo.h>
 #include <asm/irq.h>
+#include <asm/irqnode.h>
 #include <asm/thread_info.h>
 
 #define DEFINE(sym, val) \
index 621d7b91ccfe5147833dc47f1de8e8c6de79c1b7..262ab8c72e5f31bb6e43151b5aa8568241e49647 100644 (file)
@@ -101,43 +101,10 @@ void ptrace_disable(struct task_struct *child)
        put_reg(child, PT_SR, tmp);
 }
 
-asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
+long arch_ptrace(truct task_struct *child, long request, long addr, long data)
 {
-       struct task_struct *child;
        int ret;
 
-       lock_kernel();
-       ret = -EPERM;
-       if (request == PTRACE_TRACEME) {
-               /* are we already being traced? */
-               if (current->ptrace & PT_PTRACED)
-                       goto out;
-               /* set the ptrace bit in the process flags. */
-               current->ptrace |= PT_PTRACED;
-               ret = 0;
-               goto out;
-       }
-       ret = -ESRCH;
-       read_lock(&tasklist_lock);
-       child = find_task_by_pid(pid);
-       if (child)
-               get_task_struct(child);
-       read_unlock(&tasklist_lock);
-       if (!child)
-               goto out;
-
-       ret = -EPERM;
-       if (pid == 1)           /* you may not mess with init */
-               goto out_tsk;
-
-       if (request == PTRACE_ATTACH) {
-               ret = ptrace_attach(child);
-               goto out_tsk;
-       }
-       ret = ptrace_check_attach(child, request == PTRACE_KILL);
-       if (ret < 0)
-               goto out_tsk;
-
        switch (request) {
                /* when I and D space are separate, these will need to be fixed. */
                case PTRACE_PEEKTEXT: /* read word at location addr. */ 
@@ -357,10 +324,6 @@ asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
                        ret = -EIO;
                        break;
        }
-out_tsk:
-       put_task_struct(child);
-out:
-       unlock_kernel();
        return ret;
 }
 
index a220345e9746d063ba2997ab3dc0544651b676e2..abb80fa2b9408a1f9d898ef0fde2d07a2dee968b 100644 (file)
@@ -107,6 +107,9 @@ void (*mach_power_off)( void ) = NULL;
 #if defined(CONFIG_M5206e)
        #define CPU "COLDFIRE(m5206e)"
 #endif
+#if defined(CONFIG_M520x)
+       #define CPU "COLDFIRE(m520x)"
+#endif
 #if defined(CONFIG_M523x)
        #define CPU "COLDFIRE(m523x)"
 #endif
@@ -132,7 +135,7 @@ void (*mach_power_off)( void ) = NULL;
        #define CPU "COLDFIRE(m5407)"
 #endif
 #ifndef CPU
-       #define CPU "UNKOWN"
+       #define CPU "UNKNOWN"
 #endif
 
 /* (es) */
index 47f06787190dfb14491db3cb2c06376471acd6e1..0eab92ca4b97a8bf4a419b10759a580cec5e7070 100644 (file)
 #define        RAM_LENGTH      0x3e0000
 #endif
 
+/*
+ *     The Freescale 5208EVB board has 32MB of RAM.
+ */
+#if defined(CONFIG_M5208EVB)
+#define        RAM_START       0x40020000
+#define        RAM_LENGTH      0x01e00000
+#endif
+
 /*
  *     The senTec COBRA5272 board has nearly the same memory layout as 
  *     the M5272C3. We assume 16MiB ram.
@@ -275,6 +283,7 @@ SECTIONS {
                *(__ksymtab_strings)
 
                /* Built-in module parameters */
+               . = ALIGN(4) ;
                __start___param = .;
                *(__param)
                __stop___param = .;
diff --git a/arch/m68knommu/platform/520x/Makefile b/arch/m68knommu/platform/520x/Makefile
new file mode 100644 (file)
index 0000000..e861b05
--- /dev/null
@@ -0,0 +1,19 @@
+#
+# Makefile for the M5208 specific file.
+#
+
+#
+# If you want to play with the HW breakpoints then you will
+# need to add define this,  which will give you a stack backtrace
+# on the console port whenever a DBG interrupt occurs.  You have to
+# set up you HW breakpoints to trigger a DBG interrupt:
+#
+# EXTRA_CFLAGS += -DTRAP_DBG_INTERRUPT
+# EXTRA_AFLAGS += -DTRAP_DBG_INTERRUPT
+#
+
+ifdef CONFIG_FULLDEBUG
+AFLAGS += -DDEBUGGER_COMPATIBLE_CACHE=1
+endif
+
+obj-y := config.o
diff --git a/arch/m68knommu/platform/520x/config.c b/arch/m68knommu/platform/520x/config.c
new file mode 100644 (file)
index 0000000..71dea2e
--- /dev/null
@@ -0,0 +1,65 @@
+/***************************************************************************/
+
+/*
+ *  linux/arch/m68knommu/platform/520x/config.c
+ *
+ *  Copyright (C) 2005,      Freescale (www.freescale.com)
+ *  Copyright (C) 2005,      Intec Automation (mike@steroidmicros.com)
+ *  Copyright (C) 1999-2003, Greg Ungerer (gerg@snapgear.com)
+ *  Copyright (C) 2001-2003, SnapGear Inc. (www.snapgear.com)
+ */
+
+/***************************************************************************/
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/param.h>
+#include <asm/machdep.h>
+#include <asm/dma.h>
+
+/***************************************************************************/
+
+/*
+ *     DMA channel base address table.
+ */
+unsigned int dma_base_addr[MAX_M68K_DMA_CHANNELS];
+unsigned int dma_device_address[MAX_M68K_DMA_CHANNELS];
+
+/***************************************************************************/
+
+void coldfire_pit_tick(void);
+void coldfire_pit_init(irqreturn_t (*handler)(int, void *, struct pt_regs *));
+unsigned long coldfire_pit_offset(void);
+void coldfire_trap_init(void);
+void coldfire_reset(void);
+
+/***************************************************************************/
+
+/*
+ *  Program the vector to be an auto-vectored.
+ */
+
+void mcf_autovector(unsigned int vec)
+{
+    /* Everything is auto-vectored on the 520x devices */
+}
+
+/***************************************************************************/
+
+void config_BSP(char *commandp, int size)
+{
+#ifdef CONFIG_BOOTPARAM
+    strncpy(commandp, CONFIG_BOOTPARAM_STRING, size);
+    commandp[size-1] = 0;
+#else
+    memset(commandp, 0, size);
+#endif
+
+    mach_sched_init = coldfire_pit_init;
+    mach_tick = coldfire_pit_tick;
+    mach_gettimeoffset = coldfire_pit_offset;
+    mach_trap_init = coldfire_trap_init;
+    mach_reset = coldfire_reset;
+}
+
+/***************************************************************************/
index 6fe5a2b8fb08476298ad4ac4171b309f72845f6f..8d1619dc1ea60a965ef16f4224d18b302e0f4cda 100644 (file)
@@ -19,6 +19,7 @@ endif
 obj-$(CONFIG_COLDFIRE) += entry.o vectors.o ints.o
 obj-$(CONFIG_M5206)    += timers.o
 obj-$(CONFIG_M5206e)   += timers.o
+obj-$(CONFIG_M520x)    += pit.o
 obj-$(CONFIG_M523x)    += pit.o
 obj-$(CONFIG_M5249)    += timers.o
 obj-$(CONFIG_M527x)     += pit.o
index 7f4ba837901f6dfa74dd7e4cb2c64ee8f25f2316..c30c462b99b13830149e30d9dbc389448a8b3da6 100644 (file)
 #define MEM_BASE       0x02000000
 #define VBR_BASE       0x20000000      /* vectors in SRAM */
 #endif
+#if defined(CONFIG_M5208EVB)
+#define MEM_BASE       0x40000000
+#endif
 
 #ifndef MEM_BASE
 #define        MEM_BASE        0x00000000      /* memory base at address 0 */
index 0117754d44f33143fd6978546388871d52a65919..a134fb2f056672bc144898ace95f787d3be2a754 100644 (file)
@@ -26,6 +26,7 @@
 
 #include <asm/system.h>
 #include <asm/irq.h>
+#include <asm/irqnode.h>
 #include <asm/traps.h>
 #include <asm/page.h>
 #include <asm/machdep.h>
index a9b2c2e7e28085632e4bfd6215d636e3d76cc314..323f2677e49db2390aec84497059f454b76a6242 100644 (file)
@@ -3,7 +3,7 @@
 /*
  *     pit.c -- Motorola ColdFire PIT timer. Currently this type of
  *              hardware timer only exists in the Motorola ColdFire
- *              5270/5271 and 5282 CPUs.
+ *              5270/5271, 5282 and other CPUs.
  *
  *     Copyright (C) 1999-2004, Greg Ungerer (gerg@snapgear.com)
  *     Copyright (C) 2001-2004, SnapGear Inc. (www.snapgear.com)
@@ -47,10 +47,10 @@ void coldfire_pit_init(irqreturn_t (*handler)(int, void *, struct pt_regs *))
 
        icrp = (volatile unsigned char *) (MCF_IPSBAR + MCFICM_INTC0 +
                MCFINTC_ICR0 + MCFINT_PIT1);
-       *icrp = 0x2b; /* PIT1 with level 5, priority 3 */
+       *icrp = ICR_INTRCONF;
 
-       imrp = (volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRH);
-       *imrp &= ~(1 << (MCFINT_PIT1 - 32));
+       imrp = (volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 + MCFPIT_IMR);
+       *imrp &= ~MCFPIT_IMR_IBIT;
 
        /* Set up PIT timer 1 as poll clock */
        tp = (volatile struct mcfpit *) (MCF_IPSBAR + MCFPIT_BASE1);
@@ -70,7 +70,7 @@ unsigned long coldfire_pit_offset(void)
        unsigned long pmr, pcntr, offset;
 
        tp = (volatile struct mcfpit *) (MCF_IPSBAR + MCFPIT_BASE1);
-       ipr = (volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IPRH);
+       ipr = (volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 + MCFPIT_IMR);
 
        pmr = *(&tp->pmr);
        pcntr = *(&tp->pcntr);
@@ -80,7 +80,7 @@ unsigned long coldfire_pit_offset(void)
         * timer interupt is pending, then add on a ticks worth of time.
         */
        offset = ((pmr - pcntr) * (1000000 / HZ)) / pmr;
-       if ((offset < (1000000 / HZ / 2)) && (*ipr & (1 << (MCFINT_PIT1 - 32))))
+       if ((offset < (1000000 / HZ / 2)) && (*ipr & MCFPIT_IMR_IBIT))
                offset += 1000000 / HZ;
        return offset;  
 }
index f1b0f3e1f95b4c1ebd0dcfd23cafaffb9824dc97..510da5fda567e55317e333f179a60eeb35bd039b 100644 (file)
@@ -174,51 +174,10 @@ int ptrace_setfpregs (struct task_struct *child, __u32 __user *data)
        return 0;
 }
 
-asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
 {
-       struct task_struct *child;
        int ret;
 
-#if 0
-       printk("ptrace(r=%d,pid=%d,addr=%08lx,data=%08lx)\n",
-              (int) request, (int) pid, (unsigned long) addr,
-              (unsigned long) data);
-#endif
-       lock_kernel();
-       ret = -EPERM;
-       if (request == PTRACE_TRACEME) {
-               /* are we already being traced? */
-               if (current->ptrace & PT_PTRACED)
-                       goto out;
-               if ((ret = security_ptrace(current->parent, current)))
-                       goto out;
-               /* set the ptrace bit in the process flags. */
-               current->ptrace |= PT_PTRACED;
-               ret = 0;
-               goto out;
-       }
-       ret = -ESRCH;
-       read_lock(&tasklist_lock);
-       child = find_task_by_pid(pid);
-       if (child)
-               get_task_struct(child);
-       read_unlock(&tasklist_lock);
-       if (!child)
-               goto out;
-
-       ret = -EPERM;
-       if (pid == 1)           /* you may not mess with init */
-               goto out_tsk;
-
-       if (request == PTRACE_ATTACH) {
-               ret = ptrace_attach(child);
-               goto out_tsk;
-       }
-
-       ret = ptrace_check_attach(child, request == PTRACE_KILL);
-       if (ret < 0)
-               goto out_tsk;
-
        switch (request) {
        /* when I and D space are separate, these will need to be fixed. */
        case PTRACE_PEEKTEXT: /* read word at location addr. */
@@ -319,7 +278,7 @@ asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
                        if (!cpu_has_dsp) {
                                tmp = 0;
                                ret = -EIO;
-                               goto out_tsk;
+                               goto out;
                        }
                        if (child->thread.dsp.used_dsp) {
                                dregs = __get_dsp_regs(child);
@@ -333,14 +292,14 @@ asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
                        if (!cpu_has_dsp) {
                                tmp = 0;
                                ret = -EIO;
-                               goto out_tsk;
+                               goto out;
                        }
                        tmp = child->thread.dsp.dspcontrol;
                        break;
                default:
                        tmp = 0;
                        ret = -EIO;
-                       goto out_tsk;
+                       goto out;
                }
                ret = put_user(tmp, (unsigned long __user *) data);
                break;
@@ -495,11 +454,7 @@ asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
                ret = ptrace_request(child, request, addr, data);
                break;
        }
-
-out_tsk:
-       put_task_struct(child);
-out:
-       unlock_kernel();
+ out:
        return ret;
 }
 
index 18130c3748f3e4a46c6632c93e6c5b449abd19aa..b6fe202a620d5b4b013029a71e4e8cf75edd1ad4 100644 (file)
@@ -78,52 +78,13 @@ void ptrace_disable(struct task_struct *child)
        pa_psw(child)->l = 0;
 }
 
-long sys_ptrace(long request, long pid, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
 {
-       struct task_struct *child;
        long ret;
 #ifdef DEBUG_PTRACE
        long oaddr=addr, odata=data;
 #endif
 
-       lock_kernel();
-       ret = -EPERM;
-       if (request == PTRACE_TRACEME) {
-               /* are we already being traced? */
-               if (current->ptrace & PT_PTRACED)
-                       goto out;
-
-               ret = security_ptrace(current->parent, current);
-               if (ret) 
-                       goto out;
-
-               /* set the ptrace bit in the process flags. */
-               current->ptrace |= PT_PTRACED;
-               ret = 0;
-               goto out;
-       }
-
-       ret = -ESRCH;
-       read_lock(&tasklist_lock);
-       child = find_task_by_pid(pid);
-       if (child)
-               get_task_struct(child);
-       read_unlock(&tasklist_lock);
-       if (!child)
-               goto out;
-       ret = -EPERM;
-       if (pid == 1)           /* no messing around with init! */
-               goto out_tsk;
-
-       if (request == PTRACE_ATTACH) {
-               ret = ptrace_attach(child);
-               goto out_tsk;
-       }
-
-       ret = ptrace_check_attach(child, request == PTRACE_KILL);
-       if (ret < 0)
-               goto out_tsk;
-
        switch (request) {
        case PTRACE_PEEKTEXT: /* read word at location addr. */ 
        case PTRACE_PEEKDATA: {
@@ -383,11 +344,11 @@ long sys_ptrace(long request, long pid, long addr, long data)
 
        case PTRACE_GETEVENTMSG:
                 ret = put_user(child->ptrace_message, (unsigned int __user *) data);
-               goto out_tsk;
+               goto out;
 
        default:
                ret = ptrace_request(child, request, addr, data);
-               goto out_tsk;
+               goto out;
        }
 
 out_wake_notrap:
@@ -396,10 +357,7 @@ out_wake:
        wake_up_process(child);
        ret = 0;
 out_tsk:
-       put_task_struct(child);
-out:
-       unlock_kernel();
-       DBG("sys_ptrace(%ld, %d, %lx, %lx) returning %ld\n",
+       DBG("arch_ptrace(%ld, %d, %lx, %lx) returning %ld\n",
                request, pid, oaddr, odata, ret);
        return ret;
 }
index ca7acb0c79f0cc79ab989680a853d83403e2a990..6ffae2d2b3fa655ad46dcde5cfac90996cde7bc0 100644 (file)
@@ -605,6 +605,7 @@ config NODES_SPAN_OTHER_NODES
 
 config PPC_64K_PAGES
        bool "64k page size"
+       depends on PPC64
        help
          This option changes the kernel logical page size to 64k. On machines
           without processor support for 64k pages, the kernel will simulate
@@ -916,8 +917,21 @@ source "arch/powerpc/platforms/iseries/Kconfig"
 
 source "lib/Kconfig"
 
+menu "Instrumentation Support"
+        depends on EXPERIMENTAL
+
 source "arch/powerpc/oprofile/Kconfig"
 
+config KPROBES
+       bool "Kprobes (EXPERIMENTAL)"
+       help
+         Kprobes allows you to trap at almost any kernel address and
+         execute a callback function.  register_kprobe() establishes
+         a probepoint and specifies the callback.  Kprobes is useful
+         for kernel debugging, non-intrusive instrumentation and testing.
+         If in doubt, say "N".
+endmenu
+
 source "arch/powerpc/Kconfig.debug"
 
 source "security/Kconfig"
index 0baf64ec80d022b9f7f00549014cbb0f9af26365..30a30bf559eaa161d4678c4faad74a3e286616e5 100644 (file)
@@ -9,16 +9,6 @@ config DEBUG_STACKOVERFLOW
          This option will cause messages to be printed if free stack space
          drops below a certain limit.
 
-config KPROBES
-       bool "Kprobes"
-       depends on DEBUG_KERNEL && PPC64
-       help
-         Kprobes allows you to trap at almost any kernel address and
-         execute a callback function.  register_kprobe() establishes
-         a probepoint and specifies the callback.  Kprobes is useful
-         for kernel debugging, non-intrusive instrumentation and testing.
-         If in doubt, say "N".
-
 config DEBUG_STACK_USAGE
        bool "Stack utilization instrumentation"
        depends on DEBUG_KERNEL && PPC64
index 33c63bcf69f8e1670736f0dca9452c91a1774e03..cc4e9eb1c13f98041ca53467659c0f3b024cee28 100644 (file)
@@ -929,6 +929,16 @@ struct cpu_spec    cpu_specs[] = {
                .icache_bsize           = 32,
                .dcache_bsize           = 32,
        },
+       { /* 440SPe Rev. A */
+               .pvr_mask               = 0xff000fff,
+               .pvr_value              = 0x53000890,
+               .cpu_name               = "440SPe Rev. A",
+               .cpu_features           = CPU_FTR_SPLIT_ID_CACHE |
+                       CPU_FTR_USE_TB,
+               .cpu_user_features      = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
+               .icache_bsize           = 32,
+               .dcache_bsize           = 32,
+       },
 #endif /* CONFIG_44x */
 #ifdef CONFIG_FSL_BOOKE
        {       /* e200z5 */
index 568ea335d61626bfabb10d5421fada42f3c1d62e..3d2abd95c7aea05b23cfb8e9cc8db69ffd9e9838 100644 (file)
@@ -248,46 +248,10 @@ void ptrace_disable(struct task_struct *child)
        clear_single_step(child);
 }
 
-long sys_ptrace(long request, long pid, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
 {
-       struct task_struct *child;
        int ret = -EPERM;
 
-       lock_kernel();
-       if (request == PTRACE_TRACEME) {
-               /* are we already being traced? */
-               if (current->ptrace & PT_PTRACED)
-                       goto out;
-               ret = security_ptrace(current->parent, current);
-               if (ret)
-                       goto out;
-               /* set the ptrace bit in the process flags. */
-               current->ptrace |= PT_PTRACED;
-               ret = 0;
-               goto out;
-       }
-       ret = -ESRCH;
-       read_lock(&tasklist_lock);
-       child = find_task_by_pid(pid);
-       if (child)
-               get_task_struct(child);
-       read_unlock(&tasklist_lock);
-       if (!child)
-               goto out;
-
-       ret = -EPERM;
-       if (pid == 1)           /* you may not mess with init */
-               goto out_tsk;
-
-       if (request == PTRACE_ATTACH) {
-               ret = ptrace_attach(child);
-               goto out_tsk;
-       }
-
-       ret = ptrace_check_attach(child, request == PTRACE_KILL);
-       if (ret < 0)
-               goto out_tsk;
-
        switch (request) {
        /* when I and D space are separate, these will need to be fixed. */
        case PTRACE_PEEKTEXT: /* read word at location addr. */
@@ -540,10 +504,7 @@ long sys_ptrace(long request, long pid, long addr, long data)
                ret = ptrace_request(child, request, addr, data);
                break;
        }
-out_tsk:
-       put_task_struct(child);
-out:
-       unlock_kernel();
+
        return ret;
 }
 
index 6996a593dcb39b91422fa205f2af8057c2109165..b1c89bc4bf90bc5c32dca68dc52b0c1d08399b08 100644 (file)
@@ -69,6 +69,7 @@
 #include <asm/iseries/it_lp_queue.h>
 #include <asm/iseries/hv_call_xm.h>
 #endif
+#include <asm/smp.h>
 
 /* keep track of when we need to update the rtc */
 time_t last_rtc_update;
index b2f3dbca695223fc988c1be9cc778243481eb221..f15dfb92dec052d51f6c9212a8323ea2cf517945 100644 (file)
@@ -329,12 +329,14 @@ static void __init htab_init_page_sizes(void)
         */
        if (mmu_psize_defs[MMU_PAGE_16M].shift)
                mmu_huge_psize = MMU_PAGE_16M;
+       /* With 4k/4level pagetables, we can't (for now) cope with a
+        * huge page size < PMD_SIZE */
        else if (mmu_psize_defs[MMU_PAGE_1M].shift)
                mmu_huge_psize = MMU_PAGE_1M;
 
        /* Calculate HPAGE_SHIFT and sanity check it */
-       if (mmu_psize_defs[mmu_huge_psize].shift > 16 &&
-           mmu_psize_defs[mmu_huge_psize].shift < 28)
+       if (mmu_psize_defs[mmu_huge_psize].shift > MIN_HUGEPTE_SHIFT &&
+           mmu_psize_defs[mmu_huge_psize].shift < SID_SHIFT)
                HPAGE_SHIFT = mmu_psize_defs[mmu_huge_psize].shift;
        else
                HPAGE_SHIFT = 0; /* No huge pages dude ! */
index 0073a04047e48b6a7b8144ee1538142925d7bdb3..426c269e552eec77bbee18cb086f900716cffb4a 100644 (file)
@@ -212,6 +212,12 @@ static int prepare_high_area_for_htlb(struct mm_struct *mm, unsigned long area)
 
        BUG_ON(area >= NUM_HIGH_AREAS);
 
+       /* Hack, so that each addresses is controlled by exactly one
+        * of the high or low area bitmaps, the first high area starts
+        * at 4GB, not 0 */
+       if (start == 0)
+               start = 0x100000000UL;
+
        /* Check no VMAs are in the region */
        vma = find_vma(mm, start);
        if (vma && (vma->vm_start < end))
index d137abd241ff09dc0c7c520794c13b1c24016269..ed7fcfe5fd370882d2264bd3e86ed04b9cbc74aa 100644 (file)
@@ -188,9 +188,9 @@ void hash_preload(struct mm_struct *mm, unsigned long ea,
 
        if (Hash == 0)
                return;
-       pmd = pmd_offset(pgd_offset(vma->vm_mm, address), address);
+       pmd = pmd_offset(pgd_offset(mm, ea), ea);
        if (!pmd_none(*pmd))
-               add_hash_page(vma->vm_mm->context, address, pmd_val(*pmd));
+               add_hash_page(mm->context, ea, pmd_val(*pmd));
 }
 
 /*
index 3e18241b6f35218b65619762f63fc1867052aa83..950ffc5848c7950e1d449615aa61fb5782dde2cc 100644 (file)
@@ -80,12 +80,17 @@ _GLOBAL(slb_miss_kernel_load_virtual)
 BEGIN_FTR_SECTION
        b       1f
 END_FTR_SECTION_IFCLR(CPU_FTR_16M_PAGE)
+       cmpldi  r10,16
+
+       lhz     r9,PACALOWHTLBAREAS(r13)
+       mr      r11,r10
+       blt     5f
+
        lhz     r9,PACAHIGHHTLBAREAS(r13)
        srdi    r11,r10,(HTLB_AREA_SHIFT-SID_SHIFT)
-       srd     r9,r9,r11
-       lhz     r11,PACALOWHTLBAREAS(r13)
-       srd     r11,r11,r10
-       or.     r9,r9,r11
+
+5:     srd     r9,r9,r11
+       andi.   r9,r9,1
        beq     1f
 _GLOBAL(slb_miss_user_load_huge)
        li      r11,0
index 19d37730b664a03cc441886740dc517fd7349c2c..eb2dece76a540626fc3fe6c0f90e4330f9c84a59 100644 (file)
@@ -1,7 +1,3 @@
-
-menu "Profiling support"
-       depends on EXPERIMENTAL
-
 config PROFILING
        bool "Profiling support (EXPERIMENTAL)"
        help
@@ -19,5 +15,3 @@ config OPROFILE
 
          If unsure, say N.
 
-endmenu
-
index 58c61219d08e0765646450c30cba107936db01ab..d7d400339458d2e5e159bd67633bc919e8b8eed6 100644 (file)
@@ -286,10 +286,8 @@ static struct property *new_property(const char *name, const int length,
        return new;
 
 cleanup:
-       if (new->name)
-               kfree(new->name);
-       if (new->value)
-               kfree(new->value);
+       kfree(new->name);
+       kfree(new->value);
        kfree(new);
        return NULL;
 }
index e95c48d57571d7a3af2d6f91acab38de6d231d44..84d96b857e4af93fdf6055f59ad177f1d6047ae9 100644 (file)
@@ -1145,8 +1145,8 @@ static int set_serial_info(struct SICC_info *info,
     info->flags = ((state->flags & ~ASYNC_INTERNAL_FLAGS) |
                (info->flags & ASYNC_INTERNAL_FLAGS));
     state->custom_divisor = new_serial.custom_divisor;
-    state->close_delay = new_serial.close_delay * HZ / 100;
-    state->closing_wait = new_serial.closing_wait * HZ / 100;
+    state->close_delay = msecs_to_jiffies(10 * new_serial.close_delay);
+    state->closing_wait = msecs_to_jiffies(10 * new_serial.closing_wait);
     info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
     port->fifosize = new_serial.xmit_fifo_size;
 
@@ -1465,10 +1465,8 @@ static void siccuart_close(struct tty_struct *tty, struct file *filp)
     info->event = 0;
     info->tty = NULL;
     if (info->blocked_open) {
-        if (info->state->close_delay) {
-            set_current_state(TASK_INTERRUPTIBLE);
-            schedule_timeout(info->state->close_delay);
-        }
+        if (info->state->close_delay)
+            schedule_timeout_interruptible(info->state->close_delay);
         wake_up_interruptible(&info->open_wait);
     }
     info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
@@ -1496,7 +1494,7 @@ static void siccuart_wait_until_sent(struct tty_struct *tty, int timeout)
      * Note: we have to use pretty tight timings here to satisfy
      * the NIST-PCTS.
      */
-    char_time = (info->timeout - HZ/50) / info->port->fifosize;
+    char_time = (info->timeout - msecs_to_jiffies(20)) / info->port->fifosize;
     char_time = char_time / 5;
     if (char_time == 0)
         char_time = 1;
@@ -1521,8 +1519,7 @@ static void siccuart_wait_until_sent(struct tty_struct *tty, int timeout)
            tty->index, jiffies,
            expire, char_time);
     while ((readb(info->port->uart_base + BL_SICC_LSR) & _LSR_TX_ALL) != _LSR_TX_ALL) {
-        set_current_state(TASK_INTERRUPTIBLE);
-        schedule_timeout(char_time);
+        schedule_timeout_interruptible(char_time);
         if (signal_pending(current))
             break;
         if (timeout && time_after(jiffies, expire))
@@ -1773,7 +1770,7 @@ int __init siccuart_init(void)
     for (i = 0; i < SERIAL_SICC_NR; i++) {
         struct SICC_state *state = sicc_state + i;
         state->line     = i;
-        state->close_delay  = 5 * HZ / 10;
+        state->close_delay  = msecs_to_jiffies(500);
         state->closing_wait = 30 * HZ;
        spin_lock_init(&state->sicc_lock);
     }
index 2086c6ad11475f167438a2b18166429c1e647488..4edeede9ccfdbc4c2636cf5b83b672ee182629e0 100644 (file)
@@ -1309,8 +1309,7 @@ static void mii_dm9161_wait(uint mii_reg, struct net_device *dev)
 
        /* Davicom takes a bit to come up after a reset,
         * so wait here for a bit */
-       set_current_state(TASK_UNINTERRUPTIBLE);
-       schedule_timeout(timeout);
+       schedule_timeout_uninterruptible(timeout);
 }
 
 static phy_info_t phy_info_dm9161 = {
index 532caa388dc258b9a90407d96a0a978c71854f9b..49eb2a7e65c0711a8ee2585b0ec2221210796c5a 100644 (file)
@@ -1013,8 +1013,7 @@ static void CS_IrqCleanup(void)
        */
        cpm_free_handler(CPMVEC_SMC2);
 
-       if (beep_buf)
-               kfree(beep_buf);
+       kfree(beep_buf);
        kd_mksound = orig_mksound;
 }
 #endif /* MODULE */
index 114b90fdea240cab6d7cf7eeeb1b8adea51a7823..8fa51b0a32d2d5390450d6478117ec1e7410a804 100644 (file)
@@ -746,6 +746,16 @@ config MPC834x
        bool
        default y if MPC834x_SYS
 
+config CPM1
+       bool
+       depends on 8xx
+       default y
+       help
+         The CPM1 (Communications Processor Module) is a coprocessor on
+         embedded CPUs made by Motorola.  Selecting this option means that
+         you wish to build a kernel for a machine with a CPM1 coprocessor
+         on it (8xx, 827x, 8560).
+
 config CPM2
        bool
        depends on 8260 || MPC8560 || MPC8555
@@ -1247,6 +1257,14 @@ source "drivers/pci/Kconfig"
 
 source "drivers/pcmcia/Kconfig"
 
+config RAPIDIO
+       bool "RapidIO support" if MPC8540 || MPC8560
+       help
+         If you say Y here, the kernel will include drivers and
+         infrastructure code to support RapidIO interconnect devices.
+
+source "drivers/rapidio/Kconfig"
+
 endmenu
 
 menu "Advanced setup"
index b7bd8f61a4adaab4afb1fd4a5bda99693bfcbc55..82df88b01bbe5a7e4c9c6679328674e5f418628e 100644 (file)
@@ -67,6 +67,12 @@ zimageinitrd-$(CONFIG_BAMBOO)                := zImage.initrd-TREE
   entrypoint-$(CONFIG_BAMBOO)          := 0x01000000
      extra.o-$(CONFIG_BAMBOO)          := pibs.o
 
+      zimage-$(CONFIG_BUBINGA)         := zImage-TREE
+zimageinitrd-$(CONFIG_BUBINGA)         := zImage.initrd-TREE
+         end-$(CONFIG_BUBINGA)         := bubinga
+  entrypoint-$(CONFIG_BUBINGA)         := 0x01000000
+     extra.o-$(CONFIG_BUBINGA)         := openbios.o
+
       zimage-$(CONFIG_EBONY)           := zImage-TREE
 zimageinitrd-$(CONFIG_EBONY)           := zImage.initrd-TREE
          end-$(CONFIG_EBONY)           := ebony
@@ -79,12 +85,30 @@ zimageinitrd-$(CONFIG_LUAN)         := zImage.initrd-TREE
   entrypoint-$(CONFIG_LUAN)            := 0x01000000
      extra.o-$(CONFIG_LUAN)            := pibs.o
 
+      zimage-$(CONFIG_YUCCA)           := zImage-TREE
+zimageinitrd-$(CONFIG_YUCCA)           := zImage.initrd-TREE
+         end-$(CONFIG_YUCCA)           := yucca
+  entrypoint-$(CONFIG_YUCCA)           := 0x01000000
+     extra.o-$(CONFIG_YUCCA)           := pibs.o
+
       zimage-$(CONFIG_OCOTEA)          := zImage-TREE
 zimageinitrd-$(CONFIG_OCOTEA)          := zImage.initrd-TREE
          end-$(CONFIG_OCOTEA)          := ocotea
   entrypoint-$(CONFIG_OCOTEA)          := 0x01000000
      extra.o-$(CONFIG_OCOTEA)          := pibs.o
 
+      zimage-$(CONFIG_SYCAMORE)                := zImage-TREE
+zimageinitrd-$(CONFIG_SYCAMORE)                := zImage.initrd-TREE
+         end-$(CONFIG_SYCAMORE)                := sycamore
+  entrypoint-$(CONFIG_SYCAMORE)                := 0x01000000
+     extra.o-$(CONFIG_SYCAMORE)                := openbios.o
+
+      zimage-$(CONFIG_WALNUT)          := zImage-TREE
+zimageinitrd-$(CONFIG_WALNUT)          := zImage.initrd-TREE
+         end-$(CONFIG_WALNUT)          := walnut
+  entrypoint-$(CONFIG_WALNUT)          := 0x01000000
+     extra.o-$(CONFIG_WALNUT)          := openbios.o
+
      extra.o-$(CONFIG_EV64260)         := misc-ev64260.o
          end-$(CONFIG_EV64260)         := ev64260
    cacheflag-$(CONFIG_EV64260)         := -include $(clear_L2_L3)
@@ -162,7 +186,8 @@ OBJCOPY_ARGS                        := -O elf32-powerpc
 
 # head.o and relocate.o must be at the start.
 boot-y                         := head.o relocate.o $(extra.o-y) $(misc-y)
-boot-$(CONFIG_40x)             += embed_config.o
+boot-$(CONFIG_REDWOOD_5)       += embed_config.o
+boot-$(CONFIG_REDWOOD_6)       += embed_config.o
 boot-$(CONFIG_8xx)             += embed_config.o
 boot-$(CONFIG_8260)            += embed_config.o
 boot-$(CONFIG_BSEIP)           += iic.o
index e02de5b467a45ff9e278f59350bdbdd1c020d5b0..f415d6c62362ca84acece2c98ee6d99154fac9f2 100644 (file)
@@ -23,7 +23,7 @@
 #include <asm/page.h>
 #include <asm/mmu.h>
 #include <asm/bootinfo.h>
-#ifdef CONFIG_44x
+#ifdef CONFIG_4xx
 #include <asm/ibm4xx.h>
 #endif
 #include <asm/reg.h>
@@ -88,6 +88,14 @@ get_mem_size(void)
        return 0;
 }
 
+#if defined(CONFIG_40x)
+#define PPC4xx_EMAC0_MR0       EMAC0_BASE
+#endif
+
+#if defined(CONFIG_44x) && defined(PPC44x_EMAC0_MR0)
+#define PPC4xx_EMAC0_MR0       PPC44x_EMAC0_MR0
+#endif
+
 struct bi_record *
 decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum)
 {
@@ -103,13 +111,13 @@ decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum)
        com_port = serial_init(0, NULL);
 #endif
 
-#if defined(CONFIG_44x) && defined(PPC44x_EMAC0_MR0)
+#if defined(PPC4xx_EMAC0_MR0)
        /* Reset MAL */
        mtdcr(DCRN_MALCR(DCRN_MAL_BASE), MALCR_MMSR);
        /* Wait for reset */
        while (mfdcr(DCRN_MALCR(DCRN_MAL_BASE)) & MALCR_MMSR) {};
        /* Reset EMAC */
-       *(volatile unsigned long *)PPC44x_EMAC0_MR0 = 0x20000000;
+       *(volatile unsigned long *)PPC4xx_EMAC0_MR0 = 0x20000000;
        __asm__ __volatile__("eieio");
 #endif
 
@@ -164,7 +172,9 @@ decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum)
                puts(" "); puthex((unsigned long)(&__ramdisk_end));puts("\n");
        }
 
+#ifndef CONFIG_40x /* don't overwrite the 40x image located at 0x00400000! */
        avail_ram = (char *)0x00400000;
+#endif
        end_avail = (char *)0x00800000;
        puts("avail ram:     "); puthex((unsigned long)avail_ram); puts(" ");
        puthex((unsigned long)end_avail); puts("\n");
index c732b6d70cfbe91b039bee39c93d63537b1874b3..81f11d8b30a7ad80a426e348dc86715311bd70f3 100644 (file)
@@ -1,19 +1,43 @@
 /*
  * arch/ppc/boot/simple/openbios.c
  *
- * 2005 (c) SYSGO AG - g.jaeger@sysgo.com
+ * Copyright (c) 2005 DENX Software Engineering
+ * Stefan Roese <sr@denx.de>
+ *
+ * Based on original work by
+ *      2005 (c) SYSGO AG - g.jaeger@sysgo.com
+ *
  * This file is licensed under the terms of the GNU General Public
  * License version 2.  This program is licensed "as is" without
  * any warranty of any kind, whether express or implied.
  *
- * Derived from arch/ppc/boot/simple/pibs.c (from MontaVista)
  */
 
 #include <linux/types.h>
 #include <linux/config.h>
 #include <linux/string.h>
 #include <asm/ppcboot.h>
-#include <platforms/4xx/ebony.h>
+#include <asm/ibm4xx.h>
+#include <asm/reg.h>
+#ifdef CONFIG_40x
+#include <asm/io.h>
+#endif
+
+#if defined(CONFIG_BUBINGA)
+#define BOARD_INFO_VECTOR       0xFFF80B50 /* openbios 1.19 moved this vector down  - armin */
+#else
+#define BOARD_INFO_VECTOR      0xFFFE0B50
+#endif
+
+#ifdef CONFIG_40x
+/* Supply a default Ethernet address for those eval boards that don't
+ * ship with one.  This is an address from the MBX board I have, so
+ * it is unlikely you will find it on your network.
+ */
+static ushort  def_enet_addr[] = { 0x0800, 0x3e26, 0x1559 };
+
+extern unsigned long timebase_period_ns;
+#endif /* CONFIG_40x */
 
 extern unsigned long decompress_kernel(unsigned long load_addr, int num_words,
                                       unsigned long cksum);
@@ -23,15 +47,85 @@ extern unsigned long decompress_kernel(unsigned long load_addr, int num_words,
 bd_t hold_resid_buf __attribute__ ((__section__ (".data.boot")));
 bd_t *hold_residual = &hold_resid_buf;
 
+typedef struct openbios_board_info {
+        unsigned char    bi_s_version[4];       /* Version of this structure */
+        unsigned char    bi_r_version[30];      /* Version of the IBM ROM */
+        unsigned int     bi_memsize;            /* DRAM installed, in bytes */
+#ifdef CONFIG_405EP
+        unsigned char    bi_enetaddr[2][6];     /* Local Ethernet MAC address */
+#else /* CONFIG_405EP */
+        unsigned char    bi_enetaddr[6];        /* Local Ethernet MAC address */
+#endif /* CONFIG_405EP */
+        unsigned char    bi_pci_enetaddr[6];    /* PCI Ethernet MAC address */
+        unsigned int     bi_intfreq;            /* Processor speed, in Hz */
+        unsigned int     bi_busfreq;            /* PLB Bus speed, in Hz */
+        unsigned int     bi_pci_busfreq;        /* PCI Bus speed, in Hz */
+#ifdef CONFIG_405EP
+        unsigned int     bi_opb_busfreq;        /* OPB Bus speed, in Hz */
+        unsigned int     bi_pllouta_freq;       /* PLL OUTA speed, in Hz */
+#endif /* CONFIG_405EP */
+} openbios_bd_t;
+
 void *
 load_kernel(unsigned long load_addr, int num_words, unsigned long cksum,
                void *ign1, void *ign2)
 {
-       decompress_kernel(load_addr, num_words, cksum);
+#ifdef CONFIG_40x
+       openbios_bd_t *openbios_bd = NULL;
+       openbios_bd_t *(*get_board_info)(void) =
+               (openbios_bd_t *(*)(void))(*(unsigned long *)BOARD_INFO_VECTOR);
+
+       /*
+        * On 40x platforms we not only need the MAC-addresses, but also the
+        * clocks and memsize. Now try to get all values using the OpenBIOS
+        * "get_board_info()" callback.
+        */
+       if ((openbios_bd = get_board_info()) != NULL) {
+               /*
+                * Copy bd_info from OpenBIOS struct into U-Boot struct
+                * used by kernel
+                */
+               hold_residual->bi_memsize = openbios_bd->bi_memsize;
+               hold_residual->bi_intfreq = openbios_bd->bi_intfreq;
+               hold_residual->bi_busfreq = openbios_bd->bi_busfreq;
+               hold_residual->bi_pci_busfreq = openbios_bd->bi_pci_busfreq;
+               memcpy(hold_residual->bi_pci_enetaddr, openbios_bd->bi_pci_enetaddr, 6);
+#ifdef CONFIG_405EP
+               memcpy(hold_residual->bi_enetaddr, openbios_bd->bi_enetaddr[0], 6);
+               memcpy(hold_residual->bi_enet1addr, openbios_bd->bi_enetaddr[1], 6);
+               hold_residual->bi_opbfreq = openbios_bd->bi_opb_busfreq;
+               hold_residual->bi_procfreq = openbios_bd->bi_pllouta_freq;
+#else /* CONFIG_405EP */
+               memcpy(hold_residual->bi_enetaddr, openbios_bd->bi_enetaddr, 6);
+#endif /* CONFIG_405EP */
+       } else {
+               /* Hmmm...better try to stuff some defaults.
+                */
+               hold_residual->bi_memsize = 16 * 1024 * 1024;
+               hold_residual->bi_intfreq = 200000000;
+               hold_residual->bi_busfreq = 100000000;
+               hold_residual->bi_pci_busfreq = 66666666;
+
+               /*
+                * Only supply one mac-address in this fallback
+                */
+               memcpy(hold_residual->bi_enetaddr, (void *)def_enet_addr, 6);
+#ifdef CONFIG_405EP
+               hold_residual->bi_opbfreq = 50000000;
+               hold_residual->bi_procfreq = 200000000;
+#endif /* CONFIG_405EP */
+       }
 
+       timebase_period_ns = 1000000000 / hold_residual->bi_intfreq;
+#endif /* CONFIG_40x */
+
+#ifdef CONFIG_440GP
        /* simply copy the MAC addresses */
-       memcpy(hold_residual->bi_enetaddr,  (char *)EBONY_OPENBIOS_MAC_BASE, 6);
-       memcpy(hold_residual->bi_enet1addr, (char *)(EBONY_OPENBIOS_MAC_BASE+EBONY_OPENBIOS_MAC_OFFSET), 6);
+       memcpy(hold_residual->bi_enetaddr,  (char *)OPENBIOS_MAC_BASE, 6);
+       memcpy(hold_residual->bi_enet1addr, (char *)(OPENBIOS_MAC_BASE+OPENBIOS_MAC_OFFSET), 6);
+#endif /* CONFIG_440GP */
+
+       decompress_kernel(load_addr, num_words, cksum);
 
        return (void *)hold_residual;
 }
index de9bbb791db98f3abac6706fd938f7b3a17d25ae..d471e578dcb58b0664acdf2765531da42c8b8a4b 100644 (file)
@@ -1,17 +1,17 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.13-rc5
-# Fri Aug  5 15:18:23 2005
+# Linux kernel version: 2.6.14
+# Fri Oct 28 19:15:34 2005
 #
 CONFIG_MMU=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_HAVE_DEC_LOCK=y
 CONFIG_PPC=y
 CONFIG_PPC32=y
 CONFIG_GENERIC_NVRAM=y
 CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
 
 #
 # Code maturity level options
@@ -26,6 +26,7 @@ CONFIG_INIT_ENV_ARG_LIMIT=32
 # General setup
 #
 CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 CONFIG_POSIX_MQUEUE=y
@@ -35,6 +36,7 @@ CONFIG_SYSCTL=y
 CONFIG_HOTPLUG=y
 CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
+CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_EMBEDDED is not set
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
@@ -74,7 +76,7 @@ CONFIG_TAU=y
 # CONFIG_TAU_AVERAGE is not set
 # CONFIG_KEXEC is not set
 # CONFIG_CPU_FREQ is not set
-# CONFIG_PM is not set
+# CONFIG_WANT_EARLY_SERIAL is not set
 CONFIG_PPC_STD_MMU=y
 CONFIG_NOT_COHERENT_CACHE=y
 
@@ -86,22 +88,18 @@ CONFIG_NOT_COHERENT_CACHE=y
 # CONFIG_KATANA is not set
 # CONFIG_WILLOW is not set
 # CONFIG_CPCI690 is not set
-# CONFIG_PCORE is not set
 # CONFIG_POWERPMC250 is not set
 # CONFIG_CHESTNUT is not set
 # CONFIG_SPRUCE is not set
 # CONFIG_HDPU is not set
 # CONFIG_EV64260 is not set
 # CONFIG_LOPEC is not set
-# CONFIG_MCPN765 is not set
 # CONFIG_MVME5100 is not set
 # CONFIG_PPLUS is not set
 # CONFIG_PRPMC750 is not set
 # CONFIG_PRPMC800 is not set
 # CONFIG_SANDPOINT is not set
 # CONFIG_RADSTONE_PPC7D is not set
-# CONFIG_ADIR is not set
-# CONFIG_K2 is not set
 # CONFIG_PAL4 is not set
 # CONFIG_GEMINI is not set
 # CONFIG_EST8260 is not set
@@ -138,10 +136,13 @@ CONFIG_FLATMEM_MANUAL=y
 # CONFIG_SPARSEMEM_MANUAL is not set
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
 CONFIG_BINFMT_ELF=y
 CONFIG_BINFMT_MISC=y
 CONFIG_CMDLINE_BOOL=y
 CONFIG_CMDLINE="console=ttyMM0,115200 root=/dev/mtdblock1 rw rootfstype=jffs2"
+# CONFIG_PM is not set
+# CONFIG_SOFTWARE_SUSPEND is not set
 CONFIG_SECCOMP=y
 CONFIG_ISA_DMA_API=y
 
@@ -152,7 +153,6 @@ CONFIG_GENERIC_ISA_DMA=y
 CONFIG_PCI=y
 CONFIG_PCI_DOMAINS=y
 # CONFIG_PCI_LEGACY_PROC is not set
-# CONFIG_PCI_NAMES is not set
 
 #
 # PCCARD (PCMCIA/CardBus) support
@@ -206,13 +206,18 @@ CONFIG_SYN_COOKIES=y
 # CONFIG_INET_ESP is not set
 # CONFIG_INET_IPCOMP is not set
 # CONFIG_INET_TUNNEL is not set
-CONFIG_IP_TCPDIAG=y
-# CONFIG_IP_TCPDIAG_IPV6 is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
 CONFIG_TCP_CONG_BIC=y
 # CONFIG_IPV6 is not set
 # CONFIG_NETFILTER is not set
 
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
 #
 # SCTP Configuration (EXPERIMENTAL)
 #
@@ -239,6 +244,7 @@ CONFIG_TCP_CONG_BIC=y
 # CONFIG_HAMRADIO is not set
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
 
 #
 # Device Drivers
@@ -251,6 +257,11 @@ CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_FW_LOADER is not set
 
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
 #
 # Memory Technology Devices (MTD)
 #
@@ -358,7 +369,6 @@ CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=32768
 CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_LBD is not set
 # CONFIG_CDROM_PKTCDVD is not set
 
@@ -379,6 +389,7 @@ CONFIG_IOSCHED_CFQ=y
 #
 # SCSI device support
 #
+# CONFIG_RAID_ATTRS is not set
 # CONFIG_SCSI is not set
 
 #
@@ -419,6 +430,10 @@ CONFIG_NETDEVICES=y
 #
 # CONFIG_ARCNET is not set
 
+#
+# PHY device support
+#
+
 #
 # Ethernet (10 or 100Mbit)
 #
@@ -434,6 +449,7 @@ CONFIG_NETDEVICES=y
 # 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_SK98LIN is not set
 # CONFIG_TIGON3 is not set
@@ -446,6 +462,7 @@ CONFIG_MV643XX_ETH_0=y
 #
 # Ethernet (10000 Mbit)
 #
+# CONFIG_CHELSIO_T1 is not set
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
 
@@ -547,7 +564,20 @@ CONFIG_LEGACY_PTY_COUNT=256
 #
 # Watchdog Cards
 #
-# CONFIG_WATCHDOG is not set
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+CONFIG_MV64X60_WDT=y
+
+#
+# PCI-based Watchdog Cards
+#
+# CONFIG_PCIPCWATCHDOG is not set
+# CONFIG_WDTPCI is not set
 # CONFIG_NVRAM is not set
 CONFIG_GEN_RTC=y
 # CONFIG_GEN_RTC_X is not set
@@ -571,7 +601,6 @@ CONFIG_GEN_RTC=y
 # I2C support
 #
 # CONFIG_I2C is not set
-# CONFIG_I2C_SENSOR is not set
 
 #
 # Dallas's 1-wire bus
@@ -582,12 +611,17 @@ CONFIG_GEN_RTC=y
 # Hardware Monitoring support
 #
 CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
 # CONFIG_HWMON_DEBUG_CHIP is not set
 
 #
 # Misc devices
 #
 
+#
+# Multimedia Capabilities Port drivers
+#
+
 #
 # Multimedia devices
 #
@@ -651,10 +685,6 @@ CONFIG_EXT2_FS=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
-
-#
-# XFS support
-#
 # CONFIG_XFS_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
@@ -663,6 +693,7 @@ CONFIG_INOTIFY=y
 CONFIG_DNOTIFY=y
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
 
 #
 # CD-ROM/DVD Filesystems
@@ -683,11 +714,10 @@ CONFIG_DNOTIFY=y
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
 CONFIG_SYSFS=y
-# CONFIG_DEVPTS_FS_XATTR is not set
 CONFIG_TMPFS=y
-# CONFIG_TMPFS_XATTR is not set
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
+# CONFIG_RELAYFS_FS is not set
 
 #
 # Miscellaneous filesystems
@@ -735,6 +765,7 @@ CONFIG_SUNRPC=y
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
 
 #
 # Partition Types
@@ -751,6 +782,7 @@ CONFIG_MSDOS_PARTITION=y
 # Library routines
 #
 # CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
 CONFIG_CRC32=y
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
@@ -767,6 +799,7 @@ CONFIG_ZLIB_DEFLATE=y
 # CONFIG_PRINTK_TIME is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_SERIAL_TEXT_DEBUG is not set
 
 #
 # Security options
index 66dae8367659f7df98e962d547352e92a9de3d8e..3fedc43e44ad110f3060ffe2e0b4a9e966489dd7 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc2
-# Wed Jan 26 14:32:58 2005
+# Linux kernel version: 2.6.12-rc4
+# Tue May 24 18:11:04 2005
 #
 CONFIG_MMU=y
 CONFIG_GENERIC_HARDIRQS=y
@@ -11,6 +11,7 @@ CONFIG_HAVE_DEC_LOCK=y
 CONFIG_PPC=y
 CONFIG_PPC32=y
 CONFIG_GENERIC_NVRAM=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
 
 #
 # Code maturity level options
@@ -18,6 +19,7 @@ CONFIG_GENERIC_NVRAM=y
 CONFIG_EXPERIMENTAL=y
 CONFIG_CLEAN_COMPILE=y
 CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 #
 # General setup
@@ -29,7 +31,6 @@ CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
 # CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
 CONFIG_HOTPLUG=y
 CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
@@ -37,6 +38,9 @@ CONFIG_EMBEDDED=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -46,6 +50,7 @@ CONFIG_CC_ALIGN_LABELS=0
 CONFIG_CC_ALIGN_LOOPS=0
 CONFIG_CC_ALIGN_JUMPS=0
 # CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
 
 #
 # Loadable module support
@@ -69,9 +74,11 @@ CONFIG_KMOD=y
 CONFIG_E500=y
 CONFIG_BOOKE=y
 CONFIG_FSL_BOOKE=y
+# CONFIG_PHYS_64BIT is not set
 # CONFIG_SPE is not set
 CONFIG_MATH_EMULATION=y
 # CONFIG_CPU_FREQ is not set
+# CONFIG_PM is not set
 CONFIG_85xx=y
 CONFIG_PPC_INDIRECT_PCI_BE=y
 
@@ -96,6 +103,7 @@ CONFIG_HIGHMEM=y
 CONFIG_BINFMT_ELF=y
 CONFIG_BINFMT_MISC=m
 # CONFIG_CMDLINE_BOOL is not set
+CONFIG_ISA_DMA_API=y
 
 #
 # Bus options
@@ -104,15 +112,15 @@ CONFIG_PCI=y
 CONFIG_PCI_DOMAINS=y
 # CONFIG_PCI_LEGACY_PROC is not set
 # CONFIG_PCI_NAMES is not set
+# CONFIG_PCI_DEBUG is not set
 
 #
 # PCCARD (PCMCIA/CardBus) support
 #
 # CONFIG_PCCARD is not set
-
-#
-# PC-card bridges
-#
+CONFIG_RAPIDIO=y
+CONFIG_RAPIDIO_8_BIT_TRANSPORT=y
+CONFIG_RAPIDIO_DISC_TIMEOUT=30
 
 #
 # Advanced setup
@@ -152,7 +160,7 @@ CONFIG_PARPORT=m
 CONFIG_PARPORT_PC=m
 # CONFIG_PARPORT_PC_FIFO is not set
 # CONFIG_PARPORT_PC_SUPERIO is not set
-# CONFIG_PARPORT_OTHER is not set
+# CONFIG_PARPORT_GSC is not set
 # CONFIG_PARPORT_1284 is not set
 
 #
@@ -264,7 +272,6 @@ CONFIG_SCSI_CONSTANTS=y
 # CONFIG_SCSI_BUSLOGIC is not set
 # CONFIG_SCSI_DMX3191D is not set
 # CONFIG_SCSI_EATA is not set
-# CONFIG_SCSI_EATA_PIO is not set
 # CONFIG_SCSI_FUTURE_DOMAIN is not set
 # CONFIG_SCSI_GDTH is not set
 # CONFIG_SCSI_IPS is not set
@@ -274,7 +281,6 @@ CONFIG_SCSI_CONSTANTS=y
 # CONFIG_SCSI_IMM is not set
 # CONFIG_SCSI_SYM53C8XX_2 is not set
 # CONFIG_SCSI_IPR is not set
-# CONFIG_SCSI_QLOGIC_ISP is not set
 # CONFIG_SCSI_QLOGIC_FC is not set
 # CONFIG_SCSI_QLOGIC_1280 is not set
 CONFIG_SCSI_QLA2XXX=m
@@ -283,6 +289,7 @@ CONFIG_SCSI_QLA2XXX=m
 # CONFIG_SCSI_QLA2300 is not set
 # CONFIG_SCSI_QLA2322 is not set
 # CONFIG_SCSI_QLA6312 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
@@ -322,7 +329,6 @@ CONFIG_NET=y
 #
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
-# CONFIG_NETLINK_DEV is not set
 CONFIG_UNIX=y
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
@@ -431,7 +437,7 @@ CONFIG_IP_NF_NAT_FTP=m
 #
 # Network testing
 #
-# CONFIG_NET_PKTGEN is not set
+CONFIG_NET_PKTGEN=y
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
 # CONFIG_HAMRADIO is not set
@@ -499,6 +505,7 @@ CONFIG_GFAR_NAPI=y
 # Wan interfaces
 #
 # CONFIG_WAN is not set
+CONFIG_RIONET=y
 # CONFIG_FDDI is not set
 # CONFIG_HIPPI is not set
 # CONFIG_PLIP is not set
@@ -535,20 +542,6 @@ CONFIG_INPUT_JOYDEV=m
 CONFIG_INPUT_EVDEV=m
 # CONFIG_INPUT_EVBUG is not set
 
-#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-CONFIG_SERIO_I8042=y
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_PARKBD is not set
-# CONFIG_SERIO_PCIPS2 is not set
-CONFIG_SERIO_LIBPS2=y
-# CONFIG_SERIO_RAW is not set
-
 #
 # Input Device Drivers
 #
@@ -566,6 +559,19 @@ CONFIG_MOUSE_PS2=y
 # 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 is not set
+# CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+CONFIG_SOUND_GAMEPORT=y
+
 #
 # Character devices
 #
@@ -590,6 +596,7 @@ CONFIG_SERIAL_CPM_SCC2=y
 # CONFIG_SERIAL_CPM_SCC4 is not set
 # CONFIG_SERIAL_CPM_SMC1 is not set
 # CONFIG_SERIAL_CPM_SMC2 is not set
+# CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
@@ -625,6 +632,11 @@ CONFIG_DRM=m
 # CONFIG_DRM_SIS is not set
 # CONFIG_RAW_DRIVER is not set
 
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
 #
 # I2C support
 #
@@ -648,12 +660,12 @@ CONFIG_I2C_ALGOBIT=m
 # 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_ISA is not set
 # CONFIG_I2C_MPC is not set
 # CONFIG_I2C_NFORCE2 is not set
 # CONFIG_I2C_PARPORT is not set
 # CONFIG_I2C_PARPORT_LIGHT is not set
-# CONFIG_I2C_PIIX4 is not set
 # CONFIG_I2C_PROSAVAGE is not set
 # CONFIG_I2C_SAVAGE4 is not set
 # CONFIG_SCx200_ACB is not set
@@ -677,7 +689,9 @@ CONFIG_I2C_ALGOBIT=m
 # CONFIG_SENSORS_ASB100 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_FSCHER is not set
+# CONFIG_SENSORS_FSCPOS is not set
 # CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
 # CONFIG_SENSORS_IT87 is not set
 # CONFIG_SENSORS_LM63 is not set
 # CONFIG_SENSORS_LM75 is not set
@@ -688,9 +702,11 @@ CONFIG_I2C_ALGOBIT=m
 # CONFIG_SENSORS_LM85 is not set
 # CONFIG_SENSORS_LM87 is not set
 # CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
 # CONFIG_SENSORS_MAX1619 is not set
 # CONFIG_SENSORS_PC87360 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_SIS5595 is not set
 # CONFIG_SENSORS_SMSC47M1 is not set
 # CONFIG_SENSORS_VIA686A is not set
 # CONFIG_SENSORS_W83781D is not set
@@ -700,10 +716,12 @@ CONFIG_I2C_ALGOBIT=m
 #
 # Other I2C Chip support
 #
+# CONFIG_SENSORS_DS1337 is not set
 # CONFIG_SENSORS_EEPROM is not set
 # CONFIG_SENSORS_PCF8574 is not set
 # CONFIG_SENSORS_PCF8591 is not set
 # CONFIG_SENSORS_RTC8564 is not set
+# CONFIG_SENSORS_M41T00 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
@@ -732,7 +750,6 @@ CONFIG_I2C_ALGOBIT=m
 # Graphics support
 #
 # CONFIG_FB is not set
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Sound
@@ -752,13 +769,9 @@ CONFIG_SOUND=m
 #
 # USB support
 #
-# CONFIG_USB is not set
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
-
-#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
-#
+# CONFIG_USB is not set
 
 #
 # USB Gadget Support
@@ -789,6 +802,10 @@ CONFIG_JBD_DEBUG=y
 CONFIG_FS_MBCACHE=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
+
+#
+# XFS support
+#
 # CONFIG_XFS_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
@@ -859,7 +876,6 @@ CONFIG_NFS_V3=y
 CONFIG_ROOT_NFS=y
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
-# CONFIG_EXPORTFS is not set
 CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -942,8 +958,10 @@ CONFIG_ZLIB_INFLATE=m
 #
 # Kernel hacking
 #
+# CONFIG_PRINTK_TIME is not set
 CONFIG_DEBUG_KERNEL=y
 # CONFIG_MAGIC_SYSRQ is not set
+CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_DEBUG_SLAB is not set
 # CONFIG_DEBUG_SPINLOCK is not set
index c610ca933a252b125babeb5aa3e93b60dd8c675b..76a55a438f2383cc2c72294b078356c88078b9f9 100644 (file)
@@ -22,6 +22,7 @@ obj-$(CONFIG_POWER4)          += cpu_setup_power4.o
 obj-$(CONFIG_MODULES)          += module.o ppc_ksyms.o
 obj-$(CONFIG_NOT_COHERENT_CACHE)       += dma-mapping.o
 obj-$(CONFIG_PCI)              += pci.o
+obj-$(CONFIG_RAPIDIO)          += rio.o
 obj-$(CONFIG_KGDB)             += ppc-stub.o
 obj-$(CONFIG_SMP)              += smp.o smp-tbsync.o
 obj-$(CONFIG_TAU)              += temp.o
index 8b49679fad549f7810a597f34857576d98d82bca..677c571aa276385427153d099451de14db4488ee 100644 (file)
@@ -190,8 +190,8 @@ skpinv:     addi    r4,r4,1                         /* Increment */
 
        /* xlat fields */
        lis     r4,UART0_PHYS_IO_BASE@h         /* RPN depends on SoC */
-#ifndef CONFIG_440EP
-       ori     r4,r4,0x0001            /* ERPN is 1 for second 4GB page */
+#ifdef UART0_PHYS_ERPN
+       ori     r4,r4,UART0_PHYS_ERPN           /* Add ERPN if above 4GB */
 #endif
 
        /* attrib fields */
diff --git a/arch/ppc/kernel/rio.c b/arch/ppc/kernel/rio.c
new file mode 100644 (file)
index 0000000..29487fe
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * RapidIO PPC32 support
+ *
+ * Copyright 2005 MontaVista Software, Inc.
+ * Matt Porter <mporter@kernel.crashing.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.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/rio.h>
+
+#include <asm/rio.h>
+
+/**
+ * platform_rio_init - Do platform specific RIO init
+ *
+ * Any platform specific initialization of RapdIO
+ * hardware is done here as well as registration
+ * of any active master ports in the system.
+ */
+void __attribute__ ((weak))
+    platform_rio_init(void)
+{
+       printk(KERN_WARNING "RIO: No platform_rio_init() present\n");
+}
+
+/**
+ * ppc_rio_init - Do PPC32 RIO init
+ *
+ * Calls platform-specific RIO init code and then calls
+ * rio_init_mports() to initialize any master ports that
+ * have been registered with the RIO subsystem.
+ */
+static int __init ppc_rio_init(void)
+{
+       printk(KERN_INFO "RIO: RapidIO init\n");
+
+       /* Platform specific initialization */
+       platform_rio_init();
+
+       /* Enumerate all registered ports */
+       rio_init_mports();
+
+       return 0;
+}
+
+subsys_initcall(ppc_rio_init);
index 76f4476cab44b7803b7a481fb9785a2d78b73027..d8837911bbc6a473d90ae22d3c1c04f38dc90e3c 100644 (file)
@@ -82,6 +82,12 @@ config LUAN
        help
          This option enables support for the IBM PPC440SP evaluation board.
 
+config YUCCA
+       bool "Yucca"
+       select WANT_EARLY_SERIAL
+       help
+         This option enables support for the AMCC PPC440SPe evaluation board.
+
 config OCOTEA
        bool "Ocotea"
        select WANT_EARLY_SERIAL
@@ -124,9 +130,14 @@ config 440SP
        depends on LUAN
        default y
 
+config 440SPE
+       bool
+       depends on YUCCA
+       default y
+
 config 440
        bool
-       depends on 440GP || 440SP || 440EP
+       depends on 440GP || 440SP || 440SPE || 440EP
        default y
 
 config 440A
@@ -158,7 +169,7 @@ config BOOKE
 
 config IBM_OCP
        bool
-       depends on ASH || BAMBOO || BUBINGA || CPCI405 || EBONY || EP405 || LUAN || OCOTEA || REDWOOD_5 || REDWOOD_6 || SYCAMORE || WALNUT
+       depends on ASH || BAMBOO || BUBINGA || CPCI405 || EBONY || EP405 || LUAN || YUCCA || OCOTEA || REDWOOD_5 || REDWOOD_6 || SYCAMORE || WALNUT
        default y
 
 config XILINX_OCP
@@ -168,7 +179,7 @@ config XILINX_OCP
 
 config IBM_EMAC4
        bool
-       depends on 440GX || 440SP
+       depends on 440GX || 440SP || 440SPE
        default y
 
 config BIOS_FIXUP
@@ -214,7 +225,7 @@ config EMBEDDEDBOOT
 
 config IBM_OPENBIOS
        bool
-       depends on ASH || BUBINGA || REDWOOD_5 || REDWOOD_6 || SYCAMORE || WALNUT
+       depends on ASH || REDWOOD_5 || REDWOOD_6
        default y
 
 config PPC4xx_DMA
index 1dd6d7fd6a9a8b08b25203af8b12a82b48968fa9..c9bb6117095477144a43f26487a338536e0f683a 100644 (file)
@@ -7,6 +7,7 @@ obj-$(CONFIG_EBONY)             += ebony.o
 obj-$(CONFIG_EP405)            += ep405.o
 obj-$(CONFIG_BUBINGA)          += bubinga.o
 obj-$(CONFIG_LUAN)             += luan.o
+obj-$(CONFIG_YUCCA)            += yucca.o
 obj-$(CONFIG_OCOTEA)           += ocotea.o
 obj-$(CONFIG_REDWOOD_5)                += redwood5.o
 obj-$(CONFIG_REDWOOD_6)                += redwood6.o
@@ -22,6 +23,7 @@ obj-$(CONFIG_440EP)           += ibm440ep.o
 obj-$(CONFIG_440GP)            += ibm440gp.o
 obj-$(CONFIG_440GX)            += ibm440gx.o
 obj-$(CONFIG_440SP)            += ibm440sp.o
+obj-$(CONFIG_440SPE)           += ppc440spe.o
 obj-$(CONFIG_405EP)            += ibm405ep.o
 obj-$(CONFIG_405GPR)           += ibm405gpr.o
 obj-$(CONFIG_VIRTEX_II_PRO)    += virtex-ii_pro.o
index 3678abf863139475d42da06b08b2784d92930c42..8110f55668c5508979919f5c2b060edb0d0d1b67 100644 (file)
@@ -89,7 +89,7 @@ bubinga_early_serial_map(void)
           * by 16.
           */
        uart_div = (mfdcr(DCRN_CPC0_UCR_BASE) & DCRN_CPC0_UCR_U0DIV);
-       uart_clock = __res.bi_pllouta_freq / uart_div;
+       uart_clock = __res.bi_procfreq / uart_div;
 
        /* Setup serial port access */
        memset(&port, 0, sizeof(port));
index b1df856f8e22520834527efb6eef77fc21ed494e..b5380cfaf5c0cae05aea52094746d1e568654332 100644 (file)
@@ -1,52 +1,34 @@
 /*
- * Support for IBM PPC 405EP evaluation board (Bubinga).
+ * arch/ppc/platforms/4xx/bubinga.h
  *
- * Author: SAW (IBM), derived from walnut.h.
- *         Maintained by MontaVista Software <source@mvista.com>
+ * Bubinga board definitions
+ *
+ * Copyright (c) 2005 DENX Software Engineering
+ * Stefan Roese <sr@denx.de>
+ *
+ * Based on original work by
+ *     SAW (IBM)
+ *     2003 (c) MontaVista Softare 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.
  *
- * 2003 (c) MontaVista Softare Inc.  This file is licensed under the
- * terms of the GNU General Public License version 2. This program is
- * licensed "as is" without any warranty of any kind, whether express
- * or implied.
  */
 
 #ifdef __KERNEL__
 #ifndef __BUBINGA_H__
 #define __BUBINGA_H__
 
-/* 405EP */
+#include <linux/config.h>
 #include <platforms/4xx/ibm405ep.h>
-
-#ifndef __ASSEMBLY__
-/*
- * Data structure defining board information maintained by the boot
- * ROM on IBM's evaluation board. An effort has been made to
- * keep the field names consistent with the 8xx 'bd_t' board info
- * structures.
- */
-
-typedef struct board_info {
-        unsigned char    bi_s_version[4];       /* Version of this structure */
-        unsigned char    bi_r_version[30];      /* Version of the IBM ROM */
-        unsigned int     bi_memsize;            /* DRAM installed, in bytes */
-        unsigned char    bi_enetaddr[2][6];     /* Local Ethernet MAC address */        unsigned char    bi_pci_enetaddr[6];    /* PCI Ethernet MAC address */
-        unsigned int     bi_intfreq;            /* Processor speed, in Hz */
-        unsigned int     bi_busfreq;            /* PLB Bus speed, in Hz */
-        unsigned int     bi_pci_busfreq;        /* PCI Bus speed, in Hz */
-        unsigned int     bi_opb_busfreq;        /* OPB Bus speed, in Hz */
-        unsigned int     bi_pllouta_freq;       /* PLL OUTA speed, in Hz */
-} bd_t;
-
-/* Some 4xx parts use a different timebase frequency from the internal clock.
-*/
-#define bi_tbfreq bi_intfreq
-
+#include <asm/ppcboot.h>
 
 /* Memory map for the Bubinga board.
  * Generic 4xx plus RTC.
  */
 
-extern void *bubinga_rtc_base;
 #define BUBINGA_RTC_PADDR      ((uint)0xf0000000)
 #define BUBINGA_RTC_VADDR      BUBINGA_RTC_PADDR
 #define BUBINGA_RTC_SIZE       ((uint)8*1024)
@@ -58,12 +40,18 @@ extern void *bubinga_rtc_base;
  * for typical configurations at various CPU speeds.
  * The base baud is calculated as (FWDA / EXT UART DIV / 16)
  */
-#define BASE_BAUD       0
+#define BASE_BAUD              0
 
-#define BUBINGA_FPGA_BASE      0xF0300000
+/* Flash */
+#define PPC40x_FPGA_BASE       0xF0300000
+#define PPC40x_FPGA_REG_OFFS   1       /* offset to flash map reg */
+#define PPC40x_FLASH_ONBD_N(x) (x & 0x02)
+#define PPC40x_FLASH_SRAM_SEL(x) (x & 0x01)
+#define PPC40x_FLASH_LOW       0xFFF00000
+#define PPC40x_FLASH_HIGH      0xFFF80000
+#define PPC40x_FLASH_SIZE      0x80000
 
-#define PPC4xx_MACHINE_NAME     "IBM Bubinga"
+#define PPC4xx_MACHINE_NAME    "IBM Bubinga"
 
-#endif /* !__ASSEMBLY__ */
 #endif /* __BUBINGA_H__ */
 #endif /* __KERNEL__ */
index d08faa46a0aef5b9e5e49a1761145ddaec9e175a..b91ad4272dfe2b299b253eba92bcef4c38728a8b 100644 (file)
@@ -24,8 +24,8 @@
 #define PPC44x_EMAC0_MR0       0xE0000800
 
 /* Where to find the MAC info */
-#define EBONY_OPENBIOS_MAC_BASE   0xfffffe0c
-#define EBONY_OPENBIOS_MAC_OFFSET 0x0c
+#define OPENBIOS_MAC_BASE      0xfffffe0c
+#define OPENBIOS_MAC_OFFSET    0x0c
 
 /* Default clock rates for Rev. B and Rev. C silicon */
 #define EBONY_440GP_RB_SYSCLK  33000000
diff --git a/arch/ppc/platforms/4xx/ppc440spe.c b/arch/ppc/platforms/4xx/ppc440spe.c
new file mode 100644 (file)
index 0000000..6139a0b
--- /dev/null
@@ -0,0 +1,148 @@
+/*
+ * arch/ppc/platforms/4xx/ppc440spe.c
+ *
+ * PPC440SPe I/O descriptions
+ *
+ * Roland Dreier <rolandd@cisco.com>
+ * Copyright (c) 2005 Cisco Systems.  All rights reserved.
+ *
+ * Matt Porter <mporter@kernel.crashing.org>
+ * Copyright 2002-2005 MontaVista Software Inc.
+ *
+ * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
+ * Copyright (c) 2003, 2004 Zultys Technologies
+ *
+ * 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/init.h>
+#include <linux/module.h>
+#include <platforms/4xx/ppc440spe.h>
+#include <asm/ocp.h>
+#include <asm/ppc4xx_pic.h>
+
+static struct ocp_func_emac_data ppc440spe_emac0_def = {
+       .rgmii_idx      = -1,           /* No RGMII */
+       .rgmii_mux      = -1,           /* No RGMII */
+       .zmii_idx       = -1,           /* No ZMII */
+       .zmii_mux       = -1,           /* No ZMII */
+       .mal_idx        = 0,            /* MAL device index */
+       .mal_rx_chan    = 0,            /* MAL rx channel number */
+       .mal_tx_chan    = 0,            /* MAL tx channel number */
+       .wol_irq        = 61,           /* WOL interrupt number */
+       .mdio_idx       = -1,           /* No shared MDIO */
+       .tah_idx        = -1,           /* No TAH */
+};
+OCP_SYSFS_EMAC_DATA()
+
+static struct ocp_func_mal_data ppc440spe_mal0_def = {
+       .num_tx_chans   = 1,            /* Number of TX channels */
+       .num_rx_chans   = 1,            /* Number of RX channels */
+       .txeob_irq      = 38,           /* TX End Of Buffer IRQ  */
+       .rxeob_irq      = 39,           /* RX End Of Buffer IRQ  */
+       .txde_irq       = 34,           /* TX Descriptor Error IRQ */
+       .rxde_irq       = 35,           /* RX Descriptor Error IRQ */
+       .serr_irq       = 33,           /* MAL System Error IRQ    */
+       .dcr_base       = DCRN_MAL_BASE /* MAL0_CFG DCR number */
+};
+OCP_SYSFS_MAL_DATA()
+
+static struct ocp_func_iic_data ppc440spe_iic0_def = {
+       .fast_mode      = 0,            /* Use standad mode (100Khz) */
+};
+
+static struct ocp_func_iic_data ppc440spe_iic1_def = {
+       .fast_mode      = 0,            /* Use standad mode (100Khz) */
+};
+OCP_SYSFS_IIC_DATA()
+
+struct ocp_def core_ocp[] = {
+       { .vendor       = OCP_VENDOR_IBM,
+         .function     = OCP_FUNC_16550,
+         .index        = 0,
+         .paddr        = PPC440SPE_UART0_ADDR,
+         .irq          = UART0_INT,
+         .pm           = IBM_CPM_UART0,
+       },
+       { .vendor       = OCP_VENDOR_IBM,
+         .function     = OCP_FUNC_16550,
+         .index        = 1,
+         .paddr        = PPC440SPE_UART1_ADDR,
+         .irq          = UART1_INT,
+         .pm           = IBM_CPM_UART1,
+       },
+       { .vendor       = OCP_VENDOR_IBM,
+         .function     = OCP_FUNC_16550,
+         .index        = 2,
+         .paddr        = PPC440SPE_UART2_ADDR,
+         .irq          = UART2_INT,
+         .pm           = IBM_CPM_UART2,
+       },
+       { .vendor       = OCP_VENDOR_IBM,
+         .function     = OCP_FUNC_IIC,
+         .index        = 0,
+         .paddr        = 0x00000004f0000400ULL,
+         .irq          = 2,
+         .pm           = IBM_CPM_IIC0,
+         .additions    = &ppc440spe_iic0_def,
+         .show         = &ocp_show_iic_data
+       },
+       { .vendor       = OCP_VENDOR_IBM,
+         .function     = OCP_FUNC_IIC,
+         .index        = 1,
+         .paddr        = 0x00000004f0000500ULL,
+         .irq          = 3,
+         .pm           = IBM_CPM_IIC1,
+         .additions    = &ppc440spe_iic1_def,
+         .show         = &ocp_show_iic_data
+       },
+       { .vendor       = OCP_VENDOR_IBM,
+         .function     = OCP_FUNC_GPIO,
+         .index        = 0,
+         .paddr        = 0x00000004f0000700ULL,
+         .irq          = OCP_IRQ_NA,
+         .pm           = IBM_CPM_GPIO0,
+       },
+       { .vendor       = OCP_VENDOR_IBM,
+         .function     = OCP_FUNC_MAL,
+         .paddr        = OCP_PADDR_NA,
+         .irq          = OCP_IRQ_NA,
+         .pm           = OCP_CPM_NA,
+         .additions    = &ppc440spe_mal0_def,
+         .show         = &ocp_show_mal_data,
+       },
+       { .vendor       = OCP_VENDOR_IBM,
+         .function     = OCP_FUNC_EMAC,
+         .index        = 0,
+         .paddr        = 0x00000004f0000800ULL,
+         .irq          = 60,
+         .pm           = OCP_CPM_NA,
+         .additions    = &ppc440spe_emac0_def,
+         .show         = &ocp_show_emac_data,
+       },
+       { .vendor       = OCP_VENDOR_INVALID
+       }
+};
+
+/* Polarity and triggering settings for internal interrupt sources */
+struct ppc4xx_uic_settings ppc4xx_core_uic_cfg[] __initdata = {
+       { .polarity     = 0xffffffff,
+         .triggering   = 0x010f0004,
+         .ext_irq_mask = 0x00000000,
+       },
+       { .polarity     = 0xffffffff,
+         .triggering   = 0x001f8040,
+         .ext_irq_mask = 0x00007c30,   /* IRQ6 - IRQ7, IRQ8 - IRQ12 */
+       },
+       { .polarity     = 0xffffffff,
+         .triggering   = 0x00000000,
+         .ext_irq_mask = 0x000000fc,   /* IRQ0 - IRQ5 */
+       },
+       { .polarity     = 0xffffffff,
+         .triggering   = 0x00000000,
+         .ext_irq_mask = 0x00000000,
+       },
+};
diff --git a/arch/ppc/platforms/4xx/ppc440spe.h b/arch/ppc/platforms/4xx/ppc440spe.h
new file mode 100644 (file)
index 0000000..2216846
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * arch/ppc/platforms/4xx/ibm440spe.h
+ *
+ * PPC440SPe definitions
+ *
+ * Roland Dreier <rolandd@cisco.com>
+ * Copyright (c) 2005 Cisco Systems.  All rights reserved.
+ *
+ * Matt Porter <mporter@kernel.crashing.org>
+ * Copyright 2004-2005 MontaVista Software, 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.
+ */
+
+#ifdef __KERNEL__
+#ifndef __PPC_PLATFORMS_PPC440SPE_H
+#define __PPC_PLATFORMS_PPC440SPE_H
+
+#include <linux/config.h>
+
+#include <asm/ibm44x.h>
+
+/* UART */
+#define PPC440SPE_UART0_ADDR   0x00000004f0000200ULL
+#define PPC440SPE_UART1_ADDR   0x00000004f0000300ULL
+#define PPC440SPE_UART2_ADDR   0x00000004f0000600ULL
+#define UART0_INT              0
+#define UART1_INT              1
+#define UART2_INT              37
+
+/* Clock and Power Management */
+#define IBM_CPM_IIC0           0x80000000      /* IIC interface */
+#define IBM_CPM_IIC1           0x40000000      /* IIC interface */
+#define IBM_CPM_PCI            0x20000000      /* PCI bridge */
+#define IBM_CPM_CPU                0x02000000  /* processor core */
+#define IBM_CPM_DMA                0x01000000  /* DMA controller */
+#define IBM_CPM_BGO                0x00800000  /* PLB to OPB bus arbiter */
+#define IBM_CPM_BGI                0x00400000  /* OPB to PLB bridge */
+#define IBM_CPM_EBC                0x00200000  /* External Bux Controller */
+#define IBM_CPM_EBM                0x00100000  /* Ext Bus Master Interface */
+#define IBM_CPM_DMC                0x00080000  /* SDRAM peripheral controller */
+#define IBM_CPM_PLB                0x00040000  /* PLB bus arbiter */
+#define IBM_CPM_SRAM           0x00020000      /* SRAM memory controller */
+#define IBM_CPM_PPM                0x00002000  /* PLB Performance Monitor */
+#define IBM_CPM_UIC1           0x00001000      /* Universal Interrupt Controller */
+#define IBM_CPM_GPIO0          0x00000800      /* General Purpose IO (??) */
+#define IBM_CPM_GPT                0x00000400  /* General Purpose Timers  */
+#define IBM_CPM_UART0          0x00000200      /* serial port 0 */
+#define IBM_CPM_UART1          0x00000100      /* serial port 1 */
+#define IBM_CPM_UART2          0x00000100      /* serial port 1 */
+#define IBM_CPM_UIC0           0x00000080      /* Universal Interrupt Controller */
+#define IBM_CPM_TMRCLK         0x00000040      /* CPU timers */
+#define IBM_CPM_EMAC0                  0x00000020      /* EMAC 0     */
+
+#define DFLT_IBM4xx_PM         ~(IBM_CPM_UIC | IBM_CPM_UIC1 | IBM_CPM_CPU \
+                               | IBM_CPM_EBC | IBM_CPM_SRAM | IBM_CPM_BGO \
+                               | IBM_CPM_EBM | IBM_CPM_PLB | IBM_CPM_OPB \
+                               | IBM_CPM_TMRCLK | IBM_CPM_DMA | IBM_CPM_PCI \
+                               | IBM_CPM_TAHOE0 | IBM_CPM_TAHOE1 \
+                               | IBM_CPM_EMAC0 | IBM_CPM_EMAC1 \
+                               | IBM_CPM_EMAC2 | IBM_CPM_EMAC3 )
+#endif /* __PPC_PLATFORMS_PPC440SP_H */
+#endif /* __KERNEL__ */
index d8019eec47045156786eff4f43da9833f885ce5b..281b4a2ffb968ce55a46e2b4d9fc19ba9e9fb51b 100644 (file)
@@ -88,9 +88,6 @@ ppc405_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
 void __init
 sycamore_setup_arch(void)
 {
-#define SYCAMORE_PS2_BASE      0xF0100000
-#define SYCAMORE_FPGA_BASE     0xF0300000
-
        void *fpga_brdc;
        unsigned char fpga_brdc_data;
        void *fpga_enable;
@@ -100,7 +97,7 @@ sycamore_setup_arch(void)
 
        ppc4xx_setup_arch();
 
-       ibm_ocp_set_emac(0, 1);
+       ibm_ocp_set_emac(0, 0);
 
        kb_data = ioremap(SYCAMORE_PS2_BASE, 8);
        if (!kb_data) {
@@ -111,7 +108,7 @@ sycamore_setup_arch(void)
 
        kb_cs = kb_data + 1;
 
-       fpga_status = ioremap(SYCAMORE_FPGA_BASE, 8);
+       fpga_status = ioremap(PPC40x_FPGA_BASE, 8);
        if (!fpga_status) {
                printk(KERN_CRIT
                       "sycamore_setup_arch() fpga_status ioremap failed\n");
index 3e7b4e2c8c570668d56a66d58af836534fa1d62f..1cd6c824fd62efcde04c5de5bb5f8eb6e7be1f3b 100644 (file)
@@ -1,67 +1,52 @@
 /*
  * arch/ppc/platforms/4xx/sycamore.h
  *
- * Macros, definitions, and data structures specific to the IBM PowerPC
- * 405GPr "Sycamore" evaluation board.
+ * Sycamore board definitions
  *
- * Author: Armin Kuster <akuster@mvista.com>
+ * Copyright (c) 2005 DENX Software Engineering
+ * Stefan Roese <sr@denx.de>
+ *
+ * Based on original work by
+ *     Armin Kuster <akuster@mvista.com>
+ *     2000 (c) MontaVista, Software, 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.
  *
- * 2000 (c) MontaVista, Software, Inc.  This file is licensed under
- * the terms of the GNU General Public License version 2.  This program
- * is licensed "as is" without any warranty of any kind, whether express
- * or implied.
  */
 
 #ifdef __KERNEL__
 #ifndef __ASM_SYCAMORE_H__
 #define __ASM_SYCAMORE_H__
 
+#include <linux/config.h>
 #include <platforms/4xx/ibm405gpr.h>
+#include <asm/ppcboot.h>
 
-#ifndef __ASSEMBLY__
-/*
- * Data structure defining board information maintained by the boot
- * ROM on IBM's "Sycamore" evaluation board. An effort has been made to
- * keep the field names consistent with the 8xx 'bd_t' board info
- * structures.
- */
-
-typedef struct board_info {
-       unsigned char    bi_s_version[4];       /* Version of this structure */
-       unsigned char    bi_r_version[30];      /* Version of the IBM ROM */
-       unsigned int     bi_memsize;            /* DRAM installed, in bytes */
-       unsigned char    bi_enetaddr[6];        /* Local Ethernet MAC address */
-       unsigned char    bi_pci_enetaddr[6];    /* PCI Ethernet MAC address */
-       unsigned int     bi_intfreq;            /* Processor speed, in Hz */
-       unsigned int     bi_busfreq;            /* PLB Bus speed, in Hz */
-       unsigned int     bi_pci_busfreq;        /* PCI Bus speed, in Hz */
-} bd_t;
-
-/* Some 4xx parts use a different timebase frequency from the internal clock.
-*/
-#define bi_tbfreq bi_intfreq
-
-
-/* Memory map for the IBM "Sycamore" 405GP evaluation board.
+/* Memory map for the IBM "Sycamore" 405GPr evaluation board.
  * Generic 4xx plus RTC.
  */
 
-extern void *sycamore_rtc_base;
 #define SYCAMORE_RTC_PADDR     ((uint)0xf0000000)
 #define SYCAMORE_RTC_VADDR     SYCAMORE_RTC_PADDR
-#define SYCAMORE_RTC_SIZE              ((uint)8*1024)
+#define SYCAMORE_RTC_SIZE      ((uint)8*1024)
 
-#ifdef CONFIG_PPC405GP_INTERNAL_CLOCK
-#define BASE_BAUD              201600
-#else
 #define BASE_BAUD              691200
-#endif
 
-#define SYCAMORE_PS2_BASE              0xF0100000
-#define SYCAMORE_FPGA_BASE     0xF0300000
+#define SYCAMORE_PS2_BASE      0xF0100000
+
+/* Flash */
+#define PPC40x_FPGA_BASE       0xF0300000
+#define PPC40x_FPGA_REG_OFFS   5       /* offset to flash map reg */
+#define PPC40x_FLASH_ONBD_N(x) (x & 0x02)
+#define PPC40x_FLASH_SRAM_SEL(x) (x & 0x01)
+#define PPC40x_FLASH_LOW       0xFFF00000
+#define PPC40x_FLASH_HIGH      0xFFF80000
+#define PPC40x_FLASH_SIZE      0x80000
 
 #define PPC4xx_MACHINE_NAME    "IBM Sycamore"
 
-#endif /* !__ASSEMBLY__ */
 #endif /* __ASM_SYCAMORE_H__ */
 #endif /* __KERNEL__ */
index a33eda4b7489a46eab90e7b89efec6746ab5abb8..74cb33182d9fac8baf42f6c2a1b5e096c67ffd6e 100644 (file)
@@ -90,7 +90,7 @@ walnut_setup_arch(void)
 
        kb_cs = kb_data + 1;
 
-       fpga_status = ioremap(WALNUT_FPGA_BASE, 8);
+       fpga_status = ioremap(PPC40x_FPGA_BASE, 8);
        if (!fpga_status) {
                printk(KERN_CRIT
                       "walnut_setup_arch() fpga_status ioremap failed\n");
index 04cfbf3696b91ddfb49e6ac196d42db7f76c5c4b..dcf2691698c029b9350993130f7dc58f07a1a432 100644 (file)
@@ -1,72 +1,55 @@
 /*
  * arch/ppc/platforms/4xx/walnut.h
  *
- * Macros, definitions, and data structures specific to the IBM PowerPC
- * 405GP "Walnut" evaluation board.
+ * Walnut board definitions
  *
- * Authors: Grant Erickson <grant@lcse.umn.edu>, Frank Rowand
- * <frank_rowand@mvista.com>, Debbie Chu <debbie_chu@mvista.com> or
- * source@mvista.com
+ * Copyright (c) 2005 DENX Software Engineering
+ * Stefan Roese <sr@denx.de>
  *
- * Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
+ * Based on original work by
+ *     Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
+ *     Frank Rowand <frank_rowand@mvista.com>
+ *     Debbie Chu <debbie_chu@mvista.com>
+ *     2000 (c) MontaVista, Software, 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.
  *
- * 2000 (c) MontaVista, Software, Inc.  This file is licensed under
- * the terms of the GNU General Public License version 2.  This program
- * is licensed "as is" without any warranty of any kind, whether express
- * or implied.
  */
 
 #ifdef __KERNEL__
 #ifndef __ASM_WALNUT_H__
 #define __ASM_WALNUT_H__
 
-/* We have a 405GP core */
+#include <linux/config.h>
 #include <platforms/4xx/ibm405gp.h>
-
-#ifndef __ASSEMBLY__
-/*
- * Data structure defining board information maintained by the boot
- * ROM on IBM's "Walnut" evaluation board. An effort has been made to
- * keep the field names consistent with the 8xx 'bd_t' board info
- * structures.
- */
-
-typedef struct board_info {
-       unsigned char    bi_s_version[4];       /* Version of this structure */
-       unsigned char    bi_r_version[30];      /* Version of the IBM ROM */
-       unsigned int     bi_memsize;            /* DRAM installed, in bytes */
-       unsigned char    bi_enetaddr[6];        /* Local Ethernet MAC address */
-       unsigned char    bi_pci_enetaddr[6];    /* PCI Ethernet MAC address */
-       unsigned int     bi_intfreq;            /* Processor speed, in Hz */
-       unsigned int     bi_busfreq;            /* PLB Bus speed, in Hz */
-       unsigned int     bi_pci_busfreq;        /* PCI Bus speed, in Hz */
-} bd_t;
-
-/* Some 4xx parts use a different timebase frequency from the internal clock.
-*/
-#define bi_tbfreq bi_intfreq
-
+#include <asm/ppcboot.h>
 
 /* Memory map for the IBM "Walnut" 405GP evaluation board.
  * Generic 4xx plus RTC.
  */
 
-extern void *walnut_rtc_base;
 #define WALNUT_RTC_PADDR       ((uint)0xf0000000)
 #define WALNUT_RTC_VADDR       WALNUT_RTC_PADDR
 #define WALNUT_RTC_SIZE                ((uint)8*1024)
 
-#ifdef CONFIG_PPC405GP_INTERNAL_CLOCK
-#define BASE_BAUD              201600
-#else
 #define BASE_BAUD              691200
-#endif
 
 #define WALNUT_PS2_BASE                0xF0100000
-#define WALNUT_FPGA_BASE       0xF0300000
+
+/* Flash */
+#define PPC40x_FPGA_BASE       0xF0300000
+#define PPC40x_FPGA_REG_OFFS   5       /* offset to flash map reg */
+#define PPC40x_FLASH_ONBD_N(x) (x & 0x02)
+#define PPC40x_FLASH_SRAM_SEL(x) (x & 0x01)
+#define PPC40x_FLASH_LOW       0xFFF00000
+#define PPC40x_FLASH_HIGH      0xFFF80000
+#define PPC40x_FLASH_SIZE      0x80000
+#define WALNUT_FPGA_BASE       PPC40x_FPGA_BASE
 
 #define PPC4xx_MACHINE_NAME    "IBM Walnut"
 
-#endif /* !__ASSEMBLY__ */
 #endif /* __ASM_WALNUT_H__ */
 #endif /* __KERNEL__ */
diff --git a/arch/ppc/platforms/4xx/yucca.c b/arch/ppc/platforms/4xx/yucca.c
new file mode 100644 (file)
index 0000000..e60f4bd
--- /dev/null
@@ -0,0 +1,395 @@
+/*
+ * arch/ppc/platforms/4xx/yucca.c
+ *
+ * Yucca board specific routines
+ *
+ * Roland Dreier <rolandd@cisco.com> (based on luan.c by Matt Porter)
+ *
+ * Copyright 2004-2005 MontaVista Software Inc.
+ * Copyright (c) 2005 Cisco Systems.  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.
+ */
+
+#include <linux/config.h>
+#include <linux/stddef.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/reboot.h>
+#include <linux/pci.h>
+#include <linux/kdev_t.h>
+#include <linux/types.h>
+#include <linux/major.h>
+#include <linux/blkdev.h>
+#include <linux/console.h>
+#include <linux/delay.h>
+#include <linux/ide.h>
+#include <linux/initrd.h>
+#include <linux/seq_file.h>
+#include <linux/root_dev.h>
+#include <linux/tty.h>
+#include <linux/serial.h>
+#include <linux/serial_core.h>
+
+#include <asm/system.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/dma.h>
+#include <asm/io.h>
+#include <asm/machdep.h>
+#include <asm/ocp.h>
+#include <asm/pci-bridge.h>
+#include <asm/time.h>
+#include <asm/todc.h>
+#include <asm/bootinfo.h>
+#include <asm/ppc4xx_pic.h>
+#include <asm/ppcboot.h>
+
+#include <syslib/ibm44x_common.h>
+#include <syslib/ibm440gx_common.h>
+#include <syslib/ibm440sp_common.h>
+#include <syslib/ppc440spe_pcie.h>
+
+extern bd_t __res;
+
+static struct ibm44x_clocks clocks __initdata;
+
+static void __init
+yucca_calibrate_decr(void)
+{
+       unsigned int freq;
+
+       if (mfspr(SPRN_CCR1) & CCR1_TCS)
+               freq = YUCCA_TMR_CLK;
+       else
+               freq = clocks.cpu;
+
+       ibm44x_calibrate_decr(freq);
+}
+
+static int
+yucca_show_cpuinfo(struct seq_file *m)
+{
+       seq_printf(m, "vendor\t\t: AMCC\n");
+       seq_printf(m, "machine\t\t: PPC440SPe EVB (Yucca)\n");
+
+       return 0;
+}
+
+static enum {
+       HOSE_UNKNOWN,
+       HOSE_PCIX,
+       HOSE_PCIE0,
+       HOSE_PCIE1,
+       HOSE_PCIE2
+} hose_type[4];
+
+static inline int
+yucca_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
+{
+       struct pci_controller *hose = pci_bus_to_hose(dev->bus->number);
+
+       if (hose_type[hose->index] == HOSE_PCIX) {
+               static char pci_irq_table[][4] =
+               /*
+                *      PCI IDSEL/INTPIN->INTLINE
+                *        A   B   C   D
+                */
+               {
+                       { 81, -1, -1, -1 },     /* IDSEL 1 - PCIX0 Slot 0 */
+               };
+               const long min_idsel = 1, max_idsel = 1, irqs_per_slot = 4;
+               return PCI_IRQ_TABLE_LOOKUP;
+       } else if (hose_type[hose->index] == HOSE_PCIE0) {
+               static char pci_irq_table[][4] =
+               /*
+                *      PCI IDSEL/INTPIN->INTLINE
+                *        A   B   C   D
+                */
+               {
+                       { 96, 97, 98, 99 },
+               };
+               const long min_idsel = 1, max_idsel = 1, irqs_per_slot = 4;
+               return PCI_IRQ_TABLE_LOOKUP;
+       } else if (hose_type[hose->index] == HOSE_PCIE1) {
+               static char pci_irq_table[][4] =
+               /*
+                *      PCI IDSEL/INTPIN->INTLINE
+                *        A   B   C   D
+                */
+               {
+                       { 100, 101, 102, 103 },
+               };
+               const long min_idsel = 1, max_idsel = 1, irqs_per_slot = 4;
+               return PCI_IRQ_TABLE_LOOKUP;
+       } else if (hose_type[hose->index] == HOSE_PCIE2) {
+               static char pci_irq_table[][4] =
+               /*
+                *      PCI IDSEL/INTPIN->INTLINE
+                *        A   B   C   D
+                */
+               {
+                       { 104, 105, 106, 107 },
+               };
+               const long min_idsel = 1, max_idsel = 1, irqs_per_slot = 4;
+               return PCI_IRQ_TABLE_LOOKUP;
+       }
+       return -1;
+}
+
+static void __init yucca_set_emacdata(void)
+{
+       struct ocp_def *def;
+       struct ocp_func_emac_data *emacdata;
+
+       /* Set phy_map, phy_mode, and mac_addr for the EMAC */
+       def = ocp_get_one_device(OCP_VENDOR_IBM, OCP_FUNC_EMAC, 0);
+       emacdata = def->additions;
+       emacdata->phy_map = 0x00000001; /* Skip 0x00 */
+       emacdata->phy_mode = PHY_MODE_GMII;
+       memcpy(emacdata->mac_addr, __res.bi_enetaddr, 6);
+}
+
+static int __init yucca_pcie_card_present(int port)
+{
+   void __iomem *pcie_fpga_base;
+   u16 reg;
+
+   pcie_fpga_base = ioremap64(YUCCA_FPGA_REG_BASE, YUCCA_FPGA_REG_SIZE);
+   reg = in_be16(pcie_fpga_base + FPGA_REG1C);
+   iounmap(pcie_fpga_base);
+
+   switch(port) {
+   case 0: return !(reg & FPGA_REG1C_PE0_PRSNT);
+   case 1: return !(reg & FPGA_REG1C_PE1_PRSNT);
+   case 2: return !(reg & FPGA_REG1C_PE2_PRSNT);
+   default: return 0;
+   }
+}
+
+/*
+ * For the given slot, set rootpoint mode, send power to the slot,
+ * turn on the green LED and turn off the yellow LED, enable the clock
+ * and turn off reset.
+ */
+static void __init yucca_setup_pcie_fpga_rootpoint(int port)
+{
+       void __iomem *pcie_reg_fpga_base;
+       u16 power, clock, green_led, yellow_led, reset_off, rootpoint, endpoint;
+
+       pcie_reg_fpga_base = ioremap64(YUCCA_FPGA_REG_BASE, YUCCA_FPGA_REG_SIZE);
+
+       switch(port) {
+       case 0:
+               rootpoint   = FPGA_REG1C_PE0_ROOTPOINT;
+               endpoint    = 0;
+               power       = FPGA_REG1A_PE0_PWRON;
+               green_led   = FPGA_REG1A_PE0_GLED;
+               clock       = FPGA_REG1A_PE0_REFCLK_ENABLE;
+               yellow_led  = FPGA_REG1A_PE0_YLED;
+               reset_off   = FPGA_REG1C_PE0_PERST;
+               break;
+       case 1:
+               rootpoint   = 0;
+               endpoint    = FPGA_REG1C_PE1_ENDPOINT;
+               power       = FPGA_REG1A_PE1_PWRON;
+               green_led   = FPGA_REG1A_PE1_GLED;
+               clock       = FPGA_REG1A_PE1_REFCLK_ENABLE;
+               yellow_led  = FPGA_REG1A_PE1_YLED;
+               reset_off   = FPGA_REG1C_PE1_PERST;
+               break;
+       case 2:
+               rootpoint   = 0;
+               endpoint    = FPGA_REG1C_PE2_ENDPOINT;
+               power       = FPGA_REG1A_PE2_PWRON;
+               green_led   = FPGA_REG1A_PE2_GLED;
+               clock       = FPGA_REG1A_PE2_REFCLK_ENABLE;
+               yellow_led  = FPGA_REG1A_PE2_YLED;
+               reset_off   = FPGA_REG1C_PE2_PERST;
+               break;
+
+       default:
+               return;
+       }
+
+       out_be16(pcie_reg_fpga_base + FPGA_REG1A,
+                ~(power | clock | green_led) &
+                (yellow_led | in_be16(pcie_reg_fpga_base + FPGA_REG1A)));
+       out_be16(pcie_reg_fpga_base + FPGA_REG1C,
+                ~(endpoint | reset_off) &
+                (rootpoint | in_be16(pcie_reg_fpga_base + FPGA_REG1C)));
+
+       /*
+        * Leave device in reset for a while after powering on the
+        * slot to give it a chance to initialize.
+        */
+       mdelay(250);
+
+       out_be16(pcie_reg_fpga_base + FPGA_REG1C,
+                reset_off | in_be16(pcie_reg_fpga_base + FPGA_REG1C));
+
+       iounmap(pcie_reg_fpga_base);
+}
+
+static void __init
+yucca_setup_hoses(void)
+{
+       struct pci_controller *hose;
+       char name[20];
+       int i;
+
+       if (0 && ppc440spe_init_pcie()) {
+               printk(KERN_WARNING "PPC440SPe PCI Express initialization failed\n");
+               return;
+       }
+
+       for (i = 0; i <= 2; ++i) {
+               if (!yucca_pcie_card_present(i))
+                       continue;
+
+               printk(KERN_INFO "PCIE%d: card present\n", i);
+               yucca_setup_pcie_fpga_rootpoint(i);
+               if (ppc440spe_init_pcie_rootport(i)) {
+                       printk(KERN_WARNING "PCIE%d: initialization failed\n", i);
+                       continue;
+               }
+
+               hose = pcibios_alloc_controller();
+               if (!hose)
+                       return;
+
+               sprintf(name, "PCIE%d host bridge", i);
+               pci_init_resource(&hose->io_resource,
+                                 YUCCA_PCIX_LOWER_IO,
+                                 YUCCA_PCIX_UPPER_IO,
+                                 IORESOURCE_IO,
+                                 name);
+
+               hose->mem_space.start = YUCCA_PCIE_LOWER_MEM +
+                       i * YUCCA_PCIE_MEM_SIZE;
+               hose->mem_space.end   = hose->mem_space.start +
+                       YUCCA_PCIE_MEM_SIZE - 1;
+
+               pci_init_resource(&hose->mem_resources[0],
+                                 hose->mem_space.start,
+                                 hose->mem_space.end,
+                                 IORESOURCE_MEM,
+                                 name);
+
+               hose->first_busno = 0;
+               hose->last_busno  = 15;
+               hose_type[hose->index] = HOSE_PCIE0 + i;
+
+               ppc440spe_setup_pcie(hose, i);
+               hose->last_busno = pciauto_bus_scan(hose, hose->first_busno);
+       }
+
+       ppc_md.pci_swizzle = common_swizzle;
+       ppc_md.pci_map_irq = yucca_map_irq;
+}
+
+TODC_ALLOC();
+
+static void __init
+yucca_early_serial_map(void)
+{
+       struct uart_port port;
+
+       /* Setup ioremapped serial port access */
+       memset(&port, 0, sizeof(port));
+       port.membase = ioremap64(PPC440SPE_UART0_ADDR, 8);
+       port.irq = UART0_INT;
+       port.uartclk = clocks.uart0;
+       port.regshift = 0;
+       port.iotype = SERIAL_IO_MEM;
+       port.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST;
+       port.line = 0;
+
+       if (early_serial_setup(&port) != 0) {
+               printk("Early serial init of port 0 failed\n");
+       }
+
+       port.membase = ioremap64(PPC440SPE_UART1_ADDR, 8);
+       port.irq = UART1_INT;
+       port.uartclk = clocks.uart1;
+       port.line = 1;
+
+       if (early_serial_setup(&port) != 0) {
+               printk("Early serial init of port 1 failed\n");
+       }
+
+       port.membase = ioremap64(PPC440SPE_UART2_ADDR, 8);
+       port.irq = UART2_INT;
+       port.uartclk = BASE_BAUD;
+       port.line = 2;
+
+       if (early_serial_setup(&port) != 0) {
+               printk("Early serial init of port 2 failed\n");
+       }
+}
+
+static void __init
+yucca_setup_arch(void)
+{
+       yucca_set_emacdata();
+
+#if !defined(CONFIG_BDI_SWITCH)
+       /*
+        * The Abatron BDI JTAG debugger does not tolerate others
+        * mucking with the debug registers.
+        */
+       mtspr(SPRN_DBCR0, (DBCR0_TDE | DBCR0_IDM));
+#endif
+
+       /*
+        * Determine various clocks.
+        * To be completely correct we should get SysClk
+        * from FPGA, because it can be changed by on-board switches
+        * --ebs
+        */
+       /* 440GX and 440SPe clocking is the same - rd */
+       ibm440gx_get_clocks(&clocks, 33333333, 6 * 1843200);
+       ocp_sys_info.opb_bus_freq = clocks.opb;
+
+       /* init to some ~sane value until calibrate_delay() runs */
+       loops_per_jiffy = 50000000/HZ;
+
+       /* Setup PCIXn host bridges */
+       yucca_setup_hoses();
+
+#ifdef CONFIG_BLK_DEV_INITRD
+       if (initrd_start)
+               ROOT_DEV = Root_RAM0;
+       else
+#endif
+#ifdef CONFIG_ROOT_NFS
+               ROOT_DEV = Root_NFS;
+#else
+               ROOT_DEV = Root_HDA1;
+#endif
+
+       yucca_early_serial_map();
+
+       /* Identify the system */
+       printk("Yucca port (Roland Dreier <rolandd@cisco.com>)\n");
+}
+
+void __init platform_init(unsigned long r3, unsigned long r4,
+               unsigned long r5, unsigned long r6, unsigned long r7)
+{
+       ibm44x_platform_init(r3, r4, r5, r6, r7);
+
+       ppc_md.setup_arch = yucca_setup_arch;
+       ppc_md.show_cpuinfo = yucca_show_cpuinfo;
+       ppc_md.find_end_of_memory = ibm440sp_find_end_of_memory;
+       ppc_md.get_irq = NULL;          /* Set in ppc4xx_pic_init() */
+
+       ppc_md.calibrate_decr = yucca_calibrate_decr;
+#ifdef CONFIG_KGDB
+       ppc_md.early_serial_map = yucca_early_serial_map;
+#endif
+}
diff --git a/arch/ppc/platforms/4xx/yucca.h b/arch/ppc/platforms/4xx/yucca.h
new file mode 100644 (file)
index 0000000..01a4afe
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ * arch/ppc/platforms/4xx/yucca.h
+ *
+ * Yucca board definitions
+ *
+ * Roland Dreier <rolandd@cisco.com> (based on luan.h by Matt Porter)
+ *
+ * Copyright 2004-2005 MontaVista Software Inc.
+ * Copyright (c) 2005 Cisco Systems.  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.
+ *
+ */
+
+#ifdef __KERNEL__
+#ifndef __ASM_YUCCA_H__
+#define __ASM_YUCCA_H__
+
+#include <linux/config.h>
+#include <platforms/4xx/ppc440spe.h>
+
+/* F/W TLB mapping used in bootloader glue to reset EMAC */
+#define PPC44x_EMAC0_MR0       0xa0000800
+
+/* Location of MAC addresses in PIBS image */
+#define PIBS_FLASH_BASE                0xffe00000
+#define PIBS_MAC_BASE          (PIBS_FLASH_BASE+0x1b0400)
+
+/* External timer clock frequency */
+#define YUCCA_TMR_CLK          25000000
+
+/*
+ * FPGA registers
+ */
+#define YUCCA_FPGA_REG_BASE                    0x00000004e2000000ULL
+#define YUCCA_FPGA_REG_SIZE                    0x24
+
+#define FPGA_REG1A                             0x1a
+
+#define FPGA_REG1A_PE0_GLED                    0x8000
+#define FPGA_REG1A_PE1_GLED                    0x4000
+#define FPGA_REG1A_PE2_GLED                    0x2000
+#define FPGA_REG1A_PE0_YLED                    0x1000
+#define FPGA_REG1A_PE1_YLED                    0x0800
+#define FPGA_REG1A_PE2_YLED                    0x0400
+#define FPGA_REG1A_PE0_PWRON                   0x0200
+#define FPGA_REG1A_PE1_PWRON                   0x0100
+#define FPGA_REG1A_PE2_PWRON                   0x0080
+#define FPGA_REG1A_PE0_REFCLK_ENABLE           0x0040
+#define FPGA_REG1A_PE1_REFCLK_ENABLE           0x0020
+#define FPGA_REG1A_PE2_REFCLK_ENABLE           0x0010
+#define FPGA_REG1A_PE_SPREAD0                  0x0008
+#define FPGA_REG1A_PE_SPREAD1                  0x0004
+#define FPGA_REG1A_PE_SELSOURCE_0              0x0002
+#define FPGA_REG1A_PE_SELSOURCE_1              0x0001
+
+#define FPGA_REG1C                             0x1c
+
+#define FPGA_REG1C_PE0_ROOTPOINT               0x8000
+#define FPGA_REG1C_PE1_ENDPOINT                        0x4000
+#define FPGA_REG1C_PE2_ENDPOINT                        0x2000
+#define FPGA_REG1C_PE0_PRSNT                   0x1000
+#define FPGA_REG1C_PE1_PRSNT                   0x0800
+#define FPGA_REG1C_PE2_PRSNT                   0x0400
+#define FPGA_REG1C_PE0_WAKE                    0x0080
+#define FPGA_REG1C_PE1_WAKE                    0x0040
+#define FPGA_REG1C_PE2_WAKE                    0x0020
+#define FPGA_REG1C_PE0_PERST                   0x0010
+#define FPGA_REG1C_PE1_PERST                   0x0008
+#define FPGA_REG1C_PE2_PERST                   0x0004
+
+/*
+ * Serial port defines
+ */
+#define RS_TABLE_SIZE  3
+
+/* PIBS defined UART mappings, used before early_serial_setup */
+#define UART0_IO_BASE  0xa0000200
+#define UART1_IO_BASE  0xa0000300
+#define UART2_IO_BASE  0xa0000600
+
+#define BASE_BAUD      11059200
+#define STD_UART_OP(num)                                       \
+       { 0, BASE_BAUD, 0, UART##num##_INT,                     \
+               (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST),        \
+               iomem_base: (void*)UART##num##_IO_BASE,         \
+               io_type: SERIAL_IO_MEM},
+
+#define SERIAL_PORT_DFNS       \
+       STD_UART_OP(0)          \
+       STD_UART_OP(1)          \
+       STD_UART_OP(2)
+
+/* PCI support */
+#define YUCCA_PCIX_LOWER_IO    0x00000000
+#define YUCCA_PCIX_UPPER_IO    0x0000ffff
+#define YUCCA_PCIX_LOWER_MEM   0x80000000
+#define YUCCA_PCIX_UPPER_MEM   0x8fffffff
+#define YUCCA_PCIE_LOWER_MEM   0x90000000
+#define YUCCA_PCIE_MEM_SIZE    0x10000000
+
+#define YUCCA_PCIX_MEM_SIZE    0x10000000
+#define YUCCA_PCIX_MEM_OFFSET  0x00000000
+#define YUCCA_PCIE_MEM_SIZE    0x10000000
+#define YUCCA_PCIE_MEM_OFFSET  0x00000000
+
+#endif                         /* __ASM_YUCCA_H__ */
+#endif                         /* __KERNEL__ */
index bd3ac0136756bc260c31cec5f0686826d055adcd..16ad092d8a06396a4ffed0f44037c5dce99a44ec 100644 (file)
@@ -45,6 +45,8 @@
 
 #include <mm/mmu_decl.h>
 
+#include <syslib/ppc85xx_rio.h>
+
 #include <platforms/85xx/mpc85xx_ads_common.h>
 
 #ifndef CONFIG_PCI
@@ -189,3 +191,11 @@ mpc85xx_exclude_device(u_char bus, u_char devfn)
 }
 
 #endif /* CONFIG_PCI */
+
+#ifdef CONFIG_RAPIDIO
+void platform_rio_init(void)
+{
+       /* 512MB RIO LAW at 0xc0000000 */
+       mpc85xx_rio_setup(0xc0000000, 0x20000000);
+}
+#endif /* CONFIG_RAPIDIO */
index 1e1b85f8193a480a12030e7e84f6c07ff9fdbabb..15ce9d070634eb26793e2800365674d5ddc84cb7 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/module.h>
 #include <linux/fsl_devices.h>
 #include <linux/interrupt.h>
+#include <linux/rio.h>
 
 #include <asm/system.h>
 #include <asm/pgtable.h>
@@ -57,6 +58,7 @@
 
 #include <syslib/cpm2_pic.h>
 #include <syslib/ppc85xx_common.h>
+#include <syslib/ppc85xx_rio.h>
 
 
 unsigned char __res[sizeof(bd_t)];
@@ -273,6 +275,18 @@ int mpc85xx_exclude_device(u_char bus, u_char devfn)
 }
 #endif /* CONFIG_PCI */
 
+#ifdef CONFIG_RAPIDIO
+void
+platform_rio_init(void)
+{
+       /*
+        * The STx firmware configures the RapidIO Local Access Window
+        * at 0xc0000000 with a size of 512MB.
+        */
+       mpc85xx_rio_setup(0xc0000000, 0x20000000);
+}
+#endif /* CONFIG_RAPIDIO */
+
 void __init
 platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
              unsigned long r6, unsigned long r7)
index b1324564456e80e28c220c113a4608022d9ace2e..b9d844f88c2bc8088ebbab314a8498e860e93238 100644 (file)
@@ -52,6 +52,8 @@ static u32            ev64360_bus_frequency;
 
 unsigned char  __res[sizeof(bd_t)];
 
+TODC_ALLOC();
+
 static int __init
 ev64360_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
 {
@@ -182,6 +184,9 @@ ev64360_setup_peripherals(void)
                 EV64360_RTC_WINDOW_BASE, EV64360_RTC_WINDOW_SIZE, 0);
        bh.ci->enable_window_32bit(&bh, MV64x60_CPU2DEV_1_WIN);
 
+       TODC_INIT(TODC_TYPE_DS1501, 0, 0,
+               ioremap(EV64360_RTC_WINDOW_BASE, EV64360_RTC_WINDOW_SIZE), 8);
+
        mv64x60_set_32bit_window(&bh, MV64x60_CPU2SRAM_WIN,
                 EV64360_INTERNAL_SRAM_BASE, MV64360_SRAM_SIZE, 0);
        bh.ci->enable_window_32bit(&bh, MV64x60_CPU2SRAM_WIN);
@@ -496,6 +501,13 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
        ppc_md.power_off = ev64360_power_off;
        ppc_md.halt = ev64360_halt;
        ppc_md.find_end_of_memory = ev64360_find_end_of_memory;
+       ppc_md.init = NULL;
+
+       ppc_md.time_init = todc_time_init;
+       ppc_md.set_rtc_time = todc_set_rtc_time;
+       ppc_md.get_rtc_time = todc_get_rtc_time;
+       ppc_md.nvram_read_val = todc_direct_read_val;
+       ppc_md.nvram_write_val = todc_direct_write_val;
        ppc_md.calibrate_decr = ev64360_calibrate_decr;
 
 #if defined(CONFIG_SERIAL_TEXT_DEBUG) && defined(CONFIG_SERIAL_MPSC_CONSOLE)
index b4ef15b45c4ab8306e0e0118a36e6b6a5146ac60..5bd33baac24322d85208114089af1b8edcbc7bec 100644 (file)
@@ -15,6 +15,7 @@ obj-$(CONFIG_440EP)           += ibm440gx_common.o
 obj-$(CONFIG_440GP)            += ibm440gp_common.o
 obj-$(CONFIG_440GX)            += ibm440gx_common.o
 obj-$(CONFIG_440SP)            += ibm440gx_common.o ibm440sp_common.o
+obj-$(CONFIG_440SPE)           += ibm440gx_common.o ibm440sp_common.o ppc440spe_pcie.o
 ifeq ($(CONFIG_4xx),y)
 ifeq ($(CONFIG_VIRTEX_II_PRO),y)
 obj-$(CONFIG_40x)              += xilinx_pic.o
@@ -32,6 +33,7 @@ obj-$(CONFIG_PPC4xx_DMA)      += ppc4xx_dma.o
 obj-$(CONFIG_PPC4xx_EDMA)      += ppc4xx_sgdma.o
 ifeq ($(CONFIG_40x),y)
 obj-$(CONFIG_PCI)              += pci_auto.o ppc405_pci.o
+obj-$(CONFIG_RAPIDIO)          += ppc85xx_rio.o
 endif
 endif
 obj-$(CONFIG_8xx)              += m8xx_setup.o ppc8xx_pic.o $(wdt-mpc8xx-y) \
@@ -46,12 +48,14 @@ obj-$(CONFIG_BAMBOO)                += pci_auto.o todc_time.o
 obj-$(CONFIG_CPCI690)          += todc_time.o pci_auto.o
 obj-$(CONFIG_EBONY)            += pci_auto.o todc_time.o
 obj-$(CONFIG_EV64260)          += todc_time.o pci_auto.o
+obj-$(CONFIG_EV64360)          += todc_time.o
 obj-$(CONFIG_CHESTNUT)         += mv64360_pic.o pci_auto.o
 obj-$(CONFIG_GEMINI)           += open_pic.o
 obj-$(CONFIG_GT64260)          += gt64260_pic.o
 obj-$(CONFIG_LOPEC)            += pci_auto.o todc_time.o
 obj-$(CONFIG_HDPU)             += pci_auto.o
 obj-$(CONFIG_LUAN)             += pci_auto.o todc_time.o
+obj-$(CONFIG_YUCCA)            += pci_auto.o todc_time.o
 obj-$(CONFIG_KATANA)           += pci_auto.o
 obj-$(CONFIG_MV64360)          += mv64360_pic.o
 obj-$(CONFIG_MV64X60)          += mv64x60.o mv64x60_win.o
index 417d4cff77a0d5a3e4acaecb74fa8b28ee0dbf8f..cdafda127d81f1a5615e133f110e53513542671f 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * arch/ppc/syslib/ibm440sp_common.c
  *
- * PPC440SP system library
+ * PPC440SP/PPC440SPe system library
  *
  * Matt Porter <mporter@kernel.crashing.org>
  * Copyright 2002-2005 MontaVista Software Inc.
@@ -35,7 +35,7 @@ unsigned long __init ibm440sp_find_end_of_memory(void)
        u32 mem_size = 0;
 
        /* Read two bank sizes and sum */
-       for (i=0; i<2; i++)
+       for (i=0; i< MQ0_NUM_BANKS; i++)
                switch (mfdcr(DCRN_MQ0_BS0BAS + i) & MQ0_CONFIG_SIZE_MASK) {
                        case MQ0_CONFIG_SIZE_8M:
                                mem_size += PPC44x_MEM_SIZE_8M;
index 5152c8e41340cca5f0a4437dd4fdb6c697b9677f..71db11d2215840016704ff8768418e655358f3b2 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/types.h>
 #include <linux/serial.h>
 #include <linux/module.h>
+#include <linux/initrd.h>
 
 #include <asm/ibm44x.h>
 #include <asm/mmu.h>
@@ -214,9 +215,20 @@ void __init ibm44x_platform_init(unsigned long r3, unsigned long r4, unsigned lo
 /* Called from machine_check_exception */
 void platform_machine_check(struct pt_regs *regs)
 {
+#if defined(CONFIG_440SP) || defined(CONFIG_440SPE)
+       printk("PLB0: BEAR=0x%08x%08x ACR=  0x%08x BESR= 0x%08x%08x\n",
+              mfdcr(DCRN_PLB0_BEARH), mfdcr(DCRN_PLB0_BEARL),
+              mfdcr(DCRN_PLB0_ACR), mfdcr(DCRN_PLB0_BESRH),
+              mfdcr(DCRN_PLB0_BESRL));
+       printk("PLB1: BEAR=0x%08x%08x ACR=  0x%08x BESR= 0x%08x%08x\n",
+              mfdcr(DCRN_PLB1_BEARH), mfdcr(DCRN_PLB1_BEARL),
+              mfdcr(DCRN_PLB1_ACR), mfdcr(DCRN_PLB1_BESRH),
+              mfdcr(DCRN_PLB1_BESRL));
+#else
        printk("PLB0: BEAR=0x%08x%08x ACR=  0x%08x BESR= 0x%08x\n",
                mfdcr(DCRN_PLB0_BEARH), mfdcr(DCRN_PLB0_BEARL),
                mfdcr(DCRN_PLB0_ACR),  mfdcr(DCRN_PLB0_BESR));
+#endif
        printk("POB0: BEAR=0x%08x%08x BESR0=0x%08x BESR1=0x%08x\n",
                mfdcr(DCRN_POB0_BEARH), mfdcr(DCRN_POB0_BEARL),
                mfdcr(DCRN_POB0_BESR0), mfdcr(DCRN_POB0_BESR1));
index 81c83bf98df49fb10a20e953b422464eb42d7ce4..d6d838b16dacf65542fcfb532ef5fb3cd58ed009 100644 (file)
@@ -89,13 +89,6 @@ ppc4xx_find_bridges(void)
        isa_mem_base = 0;
        pci_dram_offset = 0;
 
-#if  (PSR_PCI_ARBIT_EN > 1)
-       /* Check if running in slave mode */
-       if ((mfdcr(DCRN_CHPSR) & PSR_PCI_ARBIT_EN) == 0) {
-               printk("Running as PCI slave, kernel PCI disabled !\n");
-               return;
-       }
-#endif
        /* Setup PCI32 hose */
        hose_a = pcibios_alloc_controller();
        if (!hose_a)
diff --git a/arch/ppc/syslib/ppc440spe_pcie.c b/arch/ppc/syslib/ppc440spe_pcie.c
new file mode 100644 (file)
index 0000000..1509fc1
--- /dev/null
@@ -0,0 +1,442 @@
+/*
+ * Copyright (c) 2005 Cisco Systems.  All rights reserved.
+ * Roland Dreier <rolandd@cisco.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/config.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+
+#include <asm/reg.h>
+#include <asm/io.h>
+#include <asm/ibm44x.h>
+
+#include "ppc440spe_pcie.h"
+
+static int
+pcie_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
+                    int len, u32 *val)
+{
+       struct pci_controller *hose = bus->sysdata;
+
+       if (PCI_SLOT(devfn) != 1)
+               return PCIBIOS_DEVICE_NOT_FOUND;
+
+       offset += devfn << 12;
+
+       /*
+        * 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(hose->cfg_data + offset);
+               break;
+       case 2:
+               *val = in_le16(hose->cfg_data + offset);
+               break;
+       default:
+               *val = in_le32(hose->cfg_data + offset);
+               break;
+       }
+
+       if (0) printk("%s: read %x(%d) @ %x\n", __func__, *val, len, offset);
+
+       return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+pcie_write_config(struct pci_bus *bus, unsigned int devfn, int offset,
+                     int len, u32 val)
+{
+       struct pci_controller *hose = bus->sysdata;
+
+       if (PCI_SLOT(devfn) != 1)
+               return PCIBIOS_DEVICE_NOT_FOUND;
+
+       offset += devfn << 12;
+
+       switch (len) {
+       case 1:
+               out_8(hose->cfg_data + offset, val);
+               break;
+       case 2:
+               out_le16(hose->cfg_data + offset, val);
+               break;
+       default:
+               out_le32(hose->cfg_data + offset, val);
+               break;
+       }
+       return PCIBIOS_SUCCESSFUL;
+}
+
+static struct pci_ops pcie_pci_ops =
+{
+       .read  = pcie_read_config,
+       .write = pcie_write_config
+};
+
+enum {
+       PTYPE_ENDPOINT          = 0x0,
+       PTYPE_LEGACY_ENDPOINT   = 0x1,
+       PTYPE_ROOT_PORT         = 0x4,
+
+       LNKW_X1                 = 0x1,
+       LNKW_X4                 = 0x4,
+       LNKW_X8                 = 0x8
+};
+
+static void check_error(void)
+{
+       u32 valPE0, valPE1, valPE2;
+
+       /* SDR0_PEGPLLLCT1 reset */
+       if (!(valPE0 = SDR_READ(PESDR0_PLLLCT1) & 0x01000000)) {
+               printk(KERN_INFO "PCIE: SDR0_PEGPLLLCT1 reset error 0x%8x\n", valPE0);
+       }
+
+       valPE0 = SDR_READ(PESDR0_RCSSET);
+       valPE1 = SDR_READ(PESDR1_RCSSET);
+       valPE2 = SDR_READ(PESDR2_RCSSET);
+
+       /* SDR0_PExRCSSET rstgu */
+       if ( !(valPE0 & 0x01000000) ||
+            !(valPE1 & 0x01000000) ||
+            !(valPE2 & 0x01000000)) {
+               printk(KERN_INFO "PCIE:  SDR0_PExRCSSET rstgu error\n");
+       }
+
+       /* SDR0_PExRCSSET rstdl */
+       if ( !(valPE0 & 0x00010000) ||
+            !(valPE1 & 0x00010000) ||
+            !(valPE2 & 0x00010000)) {
+               printk(KERN_INFO "PCIE:  SDR0_PExRCSSET rstdl error\n");
+       }
+
+       /* SDR0_PExRCSSET rstpyn */
+       if ( (valPE0 & 0x00001000) ||
+            (valPE1 & 0x00001000) ||
+            (valPE2 & 0x00001000)) {
+               printk(KERN_INFO "PCIE:  SDR0_PExRCSSET rstpyn error\n");
+       }
+
+       /* SDR0_PExRCSSET hldplb */
+       if ( (valPE0 & 0x10000000) ||
+            (valPE1 & 0x10000000) ||
+            (valPE2 & 0x10000000)) {
+               printk(KERN_INFO "PCIE:  SDR0_PExRCSSET hldplb error\n");
+       }
+
+       /* SDR0_PExRCSSET rdy */
+       if ( (valPE0 & 0x00100000) ||
+            (valPE1 & 0x00100000) ||
+            (valPE2 & 0x00100000)) {
+               printk(KERN_INFO "PCIE:  SDR0_PExRCSSET rdy error\n");
+       }
+
+       /* SDR0_PExRCSSET shutdown */
+       if ( (valPE0 & 0x00000100) ||
+            (valPE1 & 0x00000100) ||
+            (valPE2 & 0x00000100)) {
+               printk(KERN_INFO "PCIE:  SDR0_PExRCSSET shutdown error\n");
+       }
+}
+
+/*
+ * Initialize PCI Express core as described in User Manual section 27.12.1
+ */
+int ppc440spe_init_pcie(void)
+{
+       /* Set PLL clock receiver to LVPECL */
+       SDR_WRITE(PESDR0_PLLLCT1, SDR_READ(PESDR0_PLLLCT1) | 1 << 28);
+
+       check_error();
+
+       printk(KERN_INFO "PCIE initialization OK\n");
+
+       if (!(SDR_READ(PESDR0_PLLLCT2) & 0x10000))
+               printk(KERN_INFO "PESDR_PLLCT2 resistance calibration failed (0x%08x)\n",
+                      SDR_READ(PESDR0_PLLLCT2));
+
+       /* De-assert reset of PCIe PLL, wait for lock */
+       SDR_WRITE(PESDR0_PLLLCT1, SDR_READ(PESDR0_PLLLCT1) & ~(1 << 24));
+       udelay(3);
+
+       return 0;
+}
+
+int ppc440spe_init_pcie_rootport(int port)
+{
+       static int core_init;
+       void __iomem *utl_base;
+       u32 val = 0;
+       int i;
+
+       if (!core_init) {
+               ++core_init;
+               i = ppc440spe_init_pcie();
+               if (i)
+                       return i;
+       }
+
+       /*
+        * Initialize various parts of the PCI Express core for our port:
+        *
+        * - Set as a root port and enable max width
+        *   (PXIE0 -> X8, PCIE1 and PCIE2 -> X4).
+        * - Set up UTL configuration.
+        * - Increase SERDES drive strength to levels suggested by AMCC.
+        * - De-assert RSTPYN, RSTDL and RSTGU.
+        */
+       switch (port) {
+       case 0:
+               SDR_WRITE(PESDR0_DLPSET, PTYPE_ROOT_PORT << 20 | LNKW_X8 << 12);
+
+               SDR_WRITE(PESDR0_UTLSET1, 0x21222222);
+               SDR_WRITE(PESDR0_UTLSET2, 0x11000000);
+
+               SDR_WRITE(PESDR0_HSSL0SET1, 0x35000000);
+               SDR_WRITE(PESDR0_HSSL1SET1, 0x35000000);
+               SDR_WRITE(PESDR0_HSSL2SET1, 0x35000000);
+               SDR_WRITE(PESDR0_HSSL3SET1, 0x35000000);
+               SDR_WRITE(PESDR0_HSSL4SET1, 0x35000000);
+               SDR_WRITE(PESDR0_HSSL5SET1, 0x35000000);
+               SDR_WRITE(PESDR0_HSSL6SET1, 0x35000000);
+               SDR_WRITE(PESDR0_HSSL7SET1, 0x35000000);
+
+               SDR_WRITE(PESDR0_RCSSET,
+                         (SDR_READ(PESDR0_RCSSET) & ~(1 << 24 | 1 << 16)) | 1 << 12);
+               break;
+
+       case 1:
+               SDR_WRITE(PESDR1_DLPSET, PTYPE_ROOT_PORT << 20 | LNKW_X4 << 12);
+
+               SDR_WRITE(PESDR1_UTLSET1, 0x21222222);
+               SDR_WRITE(PESDR1_UTLSET2, 0x11000000);
+
+               SDR_WRITE(PESDR1_HSSL0SET1, 0x35000000);
+               SDR_WRITE(PESDR1_HSSL1SET1, 0x35000000);
+               SDR_WRITE(PESDR1_HSSL2SET1, 0x35000000);
+               SDR_WRITE(PESDR1_HSSL3SET1, 0x35000000);
+
+               SDR_WRITE(PESDR1_RCSSET,
+                         (SDR_READ(PESDR1_RCSSET) & ~(1 << 24 | 1 << 16)) | 1 << 12);
+               break;
+
+       case 2:
+               SDR_WRITE(PESDR2_DLPSET, PTYPE_ROOT_PORT << 20 | LNKW_X4 << 12);
+
+               SDR_WRITE(PESDR2_UTLSET1, 0x21222222);
+               SDR_WRITE(PESDR2_UTLSET2, 0x11000000);
+
+               SDR_WRITE(PESDR2_HSSL0SET1, 0x35000000);
+               SDR_WRITE(PESDR2_HSSL1SET1, 0x35000000);
+               SDR_WRITE(PESDR2_HSSL2SET1, 0x35000000);
+               SDR_WRITE(PESDR2_HSSL3SET1, 0x35000000);
+
+               SDR_WRITE(PESDR2_RCSSET,
+                         (SDR_READ(PESDR2_RCSSET) & ~(1 << 24 | 1 << 16)) | 1 << 12);
+               break;
+       }
+
+       mdelay(1000);
+
+       switch (port) {
+       case 0: val = SDR_READ(PESDR0_RCSSTS); break;
+       case 1: val = SDR_READ(PESDR1_RCSSTS); break;
+       case 2: val = SDR_READ(PESDR2_RCSSTS); break;
+       }
+
+       if (!(val & (1 << 20)))
+               printk(KERN_INFO "PCIE%d: PGRST inactive\n", port);
+       else
+               printk(KERN_WARNING "PGRST for PCIE%d failed %08x\n", port, val);
+
+       switch (port) {
+       case 0: printk(KERN_INFO "PCIE0: LOOP %08x\n", SDR_READ(PESDR0_LOOP)); break;
+       case 1: printk(KERN_INFO "PCIE1: LOOP %08x\n", SDR_READ(PESDR1_LOOP)); break;
+       case 2: printk(KERN_INFO "PCIE2: LOOP %08x\n", SDR_READ(PESDR2_LOOP)); break;
+       }
+
+       /*
+        * Map UTL registers at 0xc_1000_0n00
+        */
+       switch (port) {
+       case 0:
+               mtdcr(DCRN_PEGPL_REGBAH(PCIE0), 0x0000000c);
+               mtdcr(DCRN_PEGPL_REGBAL(PCIE0), 0x10000000);
+               mtdcr(DCRN_PEGPL_REGMSK(PCIE0), 0x00007001);
+               mtdcr(DCRN_PEGPL_SPECIAL(PCIE0), 0x68782800);
+               break;
+
+       case 1:
+               mtdcr(DCRN_PEGPL_REGBAH(PCIE1), 0x0000000c);
+               mtdcr(DCRN_PEGPL_REGBAL(PCIE1), 0x10001000);
+               mtdcr(DCRN_PEGPL_REGMSK(PCIE1), 0x00007001);
+               mtdcr(DCRN_PEGPL_SPECIAL(PCIE1), 0x68782800);
+               break;
+
+       case 2:
+               mtdcr(DCRN_PEGPL_REGBAH(PCIE2), 0x0000000c);
+               mtdcr(DCRN_PEGPL_REGBAL(PCIE2), 0x10002000);
+               mtdcr(DCRN_PEGPL_REGMSK(PCIE2), 0x00007001);
+               mtdcr(DCRN_PEGPL_SPECIAL(PCIE2), 0x68782800);
+       }
+
+       utl_base = ioremap64(0xc10000000ull + 0x1000 * port, 0x100);
+
+       /*
+        * Set buffer allocations and then assert VRB and TXE.
+        */
+       out_be32(utl_base + PEUTL_OUTTR,   0x08000000);
+       out_be32(utl_base + PEUTL_INTR,    0x02000000);
+       out_be32(utl_base + PEUTL_OPDBSZ,  0x10000000);
+       out_be32(utl_base + PEUTL_PBBSZ,   0x53000000);
+       out_be32(utl_base + PEUTL_IPHBSZ,  0x08000000);
+       out_be32(utl_base + PEUTL_IPDBSZ,  0x10000000);
+       out_be32(utl_base + PEUTL_RCIRQEN, 0x00f00000);
+       out_be32(utl_base + PEUTL_PCTL,    0x80800066);
+
+       iounmap(utl_base);
+
+       /*
+        * We map PCI Express configuration access into the 512MB regions
+        *     PCIE0: 0xc_4000_0000
+        *     PCIE1: 0xc_8000_0000
+        *     PCIE2: 0xc_c000_0000
+        */
+       switch (port) {
+       case 0:
+               mtdcr(DCRN_PEGPL_CFGBAH(PCIE0), 0x0000000c);
+               mtdcr(DCRN_PEGPL_CFGBAL(PCIE0), 0x40000000);
+               mtdcr(DCRN_PEGPL_CFGMSK(PCIE0), 0xe0000001); /* 512MB region, valid */
+               break;
+
+       case 1:
+               mtdcr(DCRN_PEGPL_CFGBAH(PCIE1), 0x0000000c);
+               mtdcr(DCRN_PEGPL_CFGBAL(PCIE1), 0x80000000);
+               mtdcr(DCRN_PEGPL_CFGMSK(PCIE1), 0xe0000001); /* 512MB region, valid */
+               break;
+
+       case 2:
+               mtdcr(DCRN_PEGPL_CFGBAH(PCIE2), 0x0000000c);
+               mtdcr(DCRN_PEGPL_CFGBAL(PCIE2), 0xc0000000);
+               mtdcr(DCRN_PEGPL_CFGMSK(PCIE2), 0xe0000001); /* 512MB region, valid */
+               break;
+       }
+
+       /*
+        * Check for VC0 active and assert RDY.
+        */
+       switch (port) {
+       case 0:
+               if (!(SDR_READ(PESDR0_RCSSTS) & (1 << 16)))
+                       printk(KERN_WARNING "PCIE0: VC0 not active\n");
+               SDR_WRITE(PESDR0_RCSSET, SDR_READ(PESDR0_RCSSET) | 1 << 20);
+               break;
+       case 1:
+               if (!(SDR_READ(PESDR1_RCSSTS) & (1 << 16)))
+                       printk(KERN_WARNING "PCIE0: VC0 not active\n");
+               SDR_WRITE(PESDR1_RCSSET, SDR_READ(PESDR1_RCSSET) | 1 << 20);
+               break;
+       case 2:
+               if (!(SDR_READ(PESDR2_RCSSTS) & (1 << 16)))
+                       printk(KERN_WARNING "PCIE0: VC0 not active\n");
+               SDR_WRITE(PESDR2_RCSSET, SDR_READ(PESDR2_RCSSET) | 1 << 20);
+               break;
+       }
+
+#if 0
+       /* Dump all config regs */
+       for (i = 0x300; i <= 0x320; ++i)
+               printk("[%04x] 0x%08x\n", i, SDR_READ(i));
+       for (i = 0x340; i <= 0x353; ++i)
+               printk("[%04x] 0x%08x\n", i, SDR_READ(i));
+       for (i = 0x370; i <= 0x383; ++i)
+               printk("[%04x] 0x%08x\n", i, SDR_READ(i));
+       for (i = 0x3a0; i <= 0x3a2; ++i)
+               printk("[%04x] 0x%08x\n", i, SDR_READ(i));
+       for (i = 0x3c0; i <= 0x3c3; ++i)
+               printk("[%04x] 0x%08x\n", i, SDR_READ(i));
+#endif
+
+       mdelay(100);
+
+       return 0;
+}
+
+void ppc440spe_setup_pcie(struct pci_controller *hose, int port)
+{
+       void __iomem *mbase;
+
+       /*
+        * Map 16MB, which is enough for 4 bits of bus #
+        */
+       hose->cfg_data = ioremap64(0xc40000000ull + port * 0x40000000,
+                                  1 << 24);
+       hose->ops = &pcie_pci_ops;
+
+       /*
+        * Set bus numbers on our root port
+        */
+       mbase = ioremap64(0xc50000000ull + port * 0x40000000, 4096);
+       out_8(mbase + PCI_PRIMARY_BUS, 0);
+       out_8(mbase + PCI_SECONDARY_BUS, 0);
+
+       /*
+        * Set up outbound translation to hose->mem_space from PLB
+        * addresses at an offset of 0xd_0000_0000.  We set the low
+        * bits of the mask to 11 to turn off splitting into 8
+        * subregions and to enable the outbound translation.
+        */
+       out_le32(mbase + PECFG_POM0LAH, 0);
+       out_le32(mbase + PECFG_POM0LAL, hose->mem_space.start);
+
+       switch (port) {
+       case 0:
+               mtdcr(DCRN_PEGPL_OMR1BAH(PCIE0),  0x0000000d);
+               mtdcr(DCRN_PEGPL_OMR1BAL(PCIE0),  hose->mem_space.start);
+               mtdcr(DCRN_PEGPL_OMR1MSKH(PCIE0), 0x7fffffff);
+               mtdcr(DCRN_PEGPL_OMR1MSKL(PCIE0),
+                     ~(hose->mem_space.end - hose->mem_space.start) | 3);
+               break;
+       case 1:
+               mtdcr(DCRN_PEGPL_OMR1BAH(PCIE1),  0x0000000d);
+               mtdcr(DCRN_PEGPL_OMR1BAL(PCIE1),  hose->mem_space.start);
+               mtdcr(DCRN_PEGPL_OMR1MSKH(PCIE1), 0x7fffffff);
+               mtdcr(DCRN_PEGPL_OMR1MSKL(PCIE1),
+                     ~(hose->mem_space.end - hose->mem_space.start) | 3);
+
+               break;
+       case 2:
+               mtdcr(DCRN_PEGPL_OMR1BAH(PCIE2),  0x0000000d);
+               mtdcr(DCRN_PEGPL_OMR1BAL(PCIE2),  hose->mem_space.start);
+               mtdcr(DCRN_PEGPL_OMR1MSKH(PCIE2), 0x7fffffff);
+               mtdcr(DCRN_PEGPL_OMR1MSKL(PCIE2),
+                     ~(hose->mem_space.end - hose->mem_space.start) | 3);
+               break;
+       }
+
+       /* Set up 16GB inbound memory window at 0 */
+       out_le32(mbase + PCI_BASE_ADDRESS_0, 0);
+       out_le32(mbase + PCI_BASE_ADDRESS_1, 0);
+       out_le32(mbase + PECFG_BAR0HMPA, 0x7fffffc);
+       out_le32(mbase + PECFG_BAR0LMPA, 0);
+       out_le32(mbase + PECFG_PIM0LAL, 0);
+       out_le32(mbase + PECFG_PIM0LAH, 0);
+       out_le32(mbase + PECFG_PIMEN, 0x1);
+
+       /* Enable I/O, Mem, and Busmaster cycles */
+       out_le16(mbase + PCI_COMMAND,
+                in_le16(mbase + PCI_COMMAND) |
+                PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
+
+       iounmap(mbase);
+}
diff --git a/arch/ppc/syslib/ppc440spe_pcie.h b/arch/ppc/syslib/ppc440spe_pcie.h
new file mode 100644 (file)
index 0000000..55b765a
--- /dev/null
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 2005 Cisco Systems.  All rights reserved.
+ * Roland Dreier <rolandd@cisco.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 __PPC_SYSLIB_PPC440SPE_PCIE_H
+#define __PPC_SYSLIB_PPC440SPE_PCIE_H
+
+#define DCRN_SDR0_CFGADDR      0x00e
+#define DCRN_SDR0_CFGDATA      0x00f
+
+#define DCRN_PCIE0_BASE                0x100
+#define DCRN_PCIE1_BASE                0x120
+#define DCRN_PCIE2_BASE                0x140
+#define PCIE0                  DCRN_PCIE0_BASE
+#define PCIE1                  DCRN_PCIE1_BASE
+#define PCIE2                  DCRN_PCIE2_BASE
+
+#define DCRN_PEGPL_CFGBAH(base)                (base + 0x00)
+#define DCRN_PEGPL_CFGBAL(base)                (base + 0x01)
+#define DCRN_PEGPL_CFGMSK(base)                (base + 0x02)
+#define DCRN_PEGPL_MSGBAH(base)                (base + 0x03)
+#define DCRN_PEGPL_MSGBAL(base)                (base + 0x04)
+#define DCRN_PEGPL_MSGMSK(base)                (base + 0x05)
+#define DCRN_PEGPL_OMR1BAH(base)       (base + 0x06)
+#define DCRN_PEGPL_OMR1BAL(base)       (base + 0x07)
+#define DCRN_PEGPL_OMR1MSKH(base)      (base + 0x08)
+#define DCRN_PEGPL_OMR1MSKL(base)      (base + 0x09)
+#define DCRN_PEGPL_REGBAH(base)                (base + 0x12)
+#define DCRN_PEGPL_REGBAL(base)                (base + 0x13)
+#define DCRN_PEGPL_REGMSK(base)                (base + 0x14)
+#define DCRN_PEGPL_SPECIAL(base)       (base + 0x15)
+
+/*
+ * System DCRs (SDRs)
+ */
+#define PESDR0_PLLLCT1         0x03a0
+#define PESDR0_PLLLCT2         0x03a1
+#define PESDR0_PLLLCT3         0x03a2
+
+#define PESDR0_UTLSET1         0x0300
+#define PESDR0_UTLSET2         0x0301
+#define PESDR0_DLPSET          0x0302
+#define PESDR0_LOOP            0x0303
+#define PESDR0_RCSSET          0x0304
+#define PESDR0_RCSSTS          0x0305
+#define PESDR0_HSSL0SET1       0x0306
+#define PESDR0_HSSL0SET2       0x0307
+#define PESDR0_HSSL0STS                0x0308
+#define PESDR0_HSSL1SET1       0x0309
+#define PESDR0_HSSL1SET2       0x030a
+#define PESDR0_HSSL1STS                0x030b
+#define PESDR0_HSSL2SET1       0x030c
+#define PESDR0_HSSL2SET2       0x030d
+#define PESDR0_HSSL2STS                0x030e
+#define PESDR0_HSSL3SET1       0x030f
+#define PESDR0_HSSL3SET2       0x0310
+#define PESDR0_HSSL3STS                0x0311
+#define PESDR0_HSSL4SET1       0x0312
+#define PESDR0_HSSL4SET2       0x0313
+#define PESDR0_HSSL4STS                0x0314
+#define PESDR0_HSSL5SET1       0x0315
+#define PESDR0_HSSL5SET2       0x0316
+#define PESDR0_HSSL5STS                0x0317
+#define PESDR0_HSSL6SET1       0x0318
+#define PESDR0_HSSL6SET2       0x0319
+#define PESDR0_HSSL6STS                0x031a
+#define PESDR0_HSSL7SET1       0x031b
+#define PESDR0_HSSL7SET2       0x031c
+#define PESDR0_HSSL7STS                0x031d
+#define PESDR0_HSSCTLSET       0x031e
+#define PESDR0_LANE_ABCD       0x031f
+#define PESDR0_LANE_EFGH       0x0320
+
+#define PESDR1_UTLSET1         0x0340
+#define PESDR1_UTLSET2         0x0341
+#define PESDR1_DLPSET          0x0342
+#define PESDR1_LOOP            0x0343
+#define PESDR1_RCSSET          0x0344
+#define PESDR1_RCSSTS          0x0345
+#define PESDR1_HSSL0SET1       0x0346
+#define PESDR1_HSSL0SET2       0x0347
+#define PESDR1_HSSL0STS                0x0348
+#define PESDR1_HSSL1SET1       0x0349
+#define PESDR1_HSSL1SET2       0x034a
+#define PESDR1_HSSL1STS                0x034b
+#define PESDR1_HSSL2SET1       0x034c
+#define PESDR1_HSSL2SET2       0x034d
+#define PESDR1_HSSL2STS                0x034e
+#define PESDR1_HSSL3SET1       0x034f
+#define PESDR1_HSSL3SET2       0x0350
+#define PESDR1_HSSL3STS                0x0351
+#define PESDR1_HSSCTLSET       0x0352
+#define PESDR1_LANE_ABCD       0x0353
+
+#define PESDR2_UTLSET1         0x0370
+#define PESDR2_UTLSET2         0x0371
+#define PESDR2_DLPSET          0x0372
+#define PESDR2_LOOP            0x0373
+#define PESDR2_RCSSET          0x0374
+#define PESDR2_RCSSTS          0x0375
+#define PESDR2_HSSL0SET1       0x0376
+#define PESDR2_HSSL0SET2       0x0377
+#define PESDR2_HSSL0STS                0x0378
+#define PESDR2_HSSL1SET1       0x0379
+#define PESDR2_HSSL1SET2       0x037a
+#define PESDR2_HSSL1STS                0x037b
+#define PESDR2_HSSL2SET1       0x037c
+#define PESDR2_HSSL2SET2       0x037d
+#define PESDR2_HSSL2STS                0x037e
+#define PESDR2_HSSL3SET1       0x037f
+#define PESDR2_HSSL3SET2       0x0380
+#define PESDR2_HSSL3STS                0x0381
+#define PESDR2_HSSCTLSET       0x0382
+#define PESDR2_LANE_ABCD       0x0383
+
+/*
+ * UTL register offsets
+ */
+#define PEUTL_PBBSZ            0x20
+#define PEUTL_OPDBSZ           0x68
+#define PEUTL_IPHBSZ           0x70
+#define PEUTL_IPDBSZ           0x78
+#define PEUTL_OUTTR            0x90
+#define PEUTL_INTR             0x98
+#define PEUTL_PCTL             0xa0
+#define PEUTL_RCIRQEN          0xb8
+
+/*
+ * Config space register offsets
+ */
+#define PECFG_BAR0LMPA         0x210
+#define PECFG_BAR0HMPA         0x214
+#define PECFG_PIMEN            0x33c
+#define PECFG_PIM0LAL          0x340
+#define PECFG_PIM0LAH          0x344
+#define PECFG_POM0LAL          0x380
+#define PECFG_POM0LAH          0x384
+
+int ppc440spe_init_pcie(void);
+int ppc440spe_init_pcie_rootport(int port);
+void ppc440spe_setup_pcie(struct pci_controller *hose, int port);
+
+#endif /* __PPC_SYSLIB_PPC440SPE_PCIE_H */
index 0b435633a0d174da0991570bf73cacc6406108c0..aa4165144ec27481c61ea55b286d5c51557e34a0 100644 (file)
@@ -38,6 +38,7 @@ extern unsigned char ppc4xx_uic_ext_irq_cfg[] __attribute__ ((weak));
 #define IRQ_MASK_UICx(irq)             (1 << (31 - ((irq) & 0x1f)))
 #define IRQ_MASK_UIC1(irq)             IRQ_MASK_UICx(irq)
 #define IRQ_MASK_UIC2(irq)             IRQ_MASK_UICx(irq)
+#define IRQ_MASK_UIC3(irq)             IRQ_MASK_UICx(irq)
 
 #define UIC_HANDLERS(n)                                                        \
 static void ppc4xx_uic##n##_enable(unsigned int irq)                   \
@@ -88,7 +89,38 @@ static void ppc4xx_uic##n##_end(unsigned int irq)                    \
        .end            = ppc4xx_uic##n##_end,                          \
 }                                                                      \
 
-#if NR_UICS == 3
+#if NR_UICS == 4
+#define ACK_UIC0_PARENT
+#define ACK_UIC1_PARENT        mtdcr(DCRN_UIC_SR(UIC0), UIC0_UIC1NC);
+#define ACK_UIC2_PARENT        mtdcr(DCRN_UIC_SR(UIC0), UIC0_UIC2NC);
+#define ACK_UIC3_PARENT        mtdcr(DCRN_UIC_SR(UIC0), UIC0_UIC3NC);
+UIC_HANDLERS(0);
+UIC_HANDLERS(1);
+UIC_HANDLERS(2);
+UIC_HANDLERS(3);
+
+static int ppc4xx_pic_get_irq(struct pt_regs *regs)
+{
+       u32 uic0 = mfdcr(DCRN_UIC_MSR(UIC0));
+       if (uic0 & UIC0_UIC1NC)
+               return 64 - ffs(mfdcr(DCRN_UIC_MSR(UIC1)));
+       else if (uic0 & UIC0_UIC2NC)
+               return 96 - ffs(mfdcr(DCRN_UIC_MSR(UIC2)));
+       else if (uic0 & UIC0_UIC3NC)
+               return 128 - ffs(mfdcr(DCRN_UIC_MSR(UIC3)));
+       else
+               return uic0 ? 32 - ffs(uic0) : -1;
+}
+
+static void __init ppc4xx_pic_impl_init(void)
+{
+       /* Enable cascade interrupts in UIC0 */
+       ppc_cached_irq_mask[0] |= UIC0_UIC1NC | UIC0_UIC2NC | UIC0_UIC3NC;
+       mtdcr(DCRN_UIC_SR(UIC0), UIC0_UIC1NC | UIC0_UIC2NC | UIC0_UIC3NC);
+       mtdcr(DCRN_UIC_ER(UIC0), ppc_cached_irq_mask[0]);
+}
+
+#elif NR_UICS == 3
 #define ACK_UIC0_PARENT        mtdcr(DCRN_UIC_SR(UICB), UICB_UIC0NC);
 #define ACK_UIC1_PARENT        mtdcr(DCRN_UIC_SR(UICB), UICB_UIC1NC);
 #define ACK_UIC2_PARENT        mtdcr(DCRN_UIC_SR(UICB), UICB_UIC2NC);
@@ -170,6 +202,9 @@ static struct ppc4xx_uic_impl {
        { .decl = DECLARE_UIC(1), .base = UIC1 },
 #if NR_UICS > 2
        { .decl = DECLARE_UIC(2), .base = UIC2 },
+#if NR_UICS > 3
+       { .decl = DECLARE_UIC(3), .base = UIC3 },
+#endif
 #endif
 #endif
 };
diff --git a/arch/ppc/syslib/ppc85xx_rio.c b/arch/ppc/syslib/ppc85xx_rio.c
new file mode 100644 (file)
index 0000000..297f3b5
--- /dev/null
@@ -0,0 +1,938 @@
+/*
+ * MPC85xx RapidIO support
+ *
+ * Copyright 2005 MontaVista Software, Inc.
+ * Matt Porter <mporter@kernel.crashing.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.
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/dma-mapping.h>
+#include <linux/interrupt.h>
+#include <linux/rio.h>
+#include <linux/rio_drv.h>
+
+#include <asm/io.h>
+
+#define RIO_REGS_BASE          (CCSRBAR + 0xc0000)
+#define RIO_ATMU_REGS_OFFSET   0x10c00
+#define RIO_MSG_REGS_OFFSET    0x11000
+#define RIO_MAINT_WIN_SIZE     0x400000
+#define RIO_DBELL_WIN_SIZE     0x1000
+
+#define RIO_MSG_OMR_MUI                0x00000002
+#define RIO_MSG_OSR_TE         0x00000080
+#define RIO_MSG_OSR_QOI                0x00000020
+#define RIO_MSG_OSR_QFI                0x00000010
+#define RIO_MSG_OSR_MUB                0x00000004
+#define RIO_MSG_OSR_EOMI       0x00000002
+#define RIO_MSG_OSR_QEI                0x00000001
+
+#define RIO_MSG_IMR_MI         0x00000002
+#define RIO_MSG_ISR_TE         0x00000080
+#define RIO_MSG_ISR_QFI                0x00000010
+#define RIO_MSG_ISR_DIQI       0x00000001
+
+#define RIO_MSG_DESC_SIZE      32
+#define RIO_MSG_BUFFER_SIZE    4096
+#define RIO_MIN_TX_RING_SIZE   2
+#define RIO_MAX_TX_RING_SIZE   2048
+#define RIO_MIN_RX_RING_SIZE   2
+#define RIO_MAX_RX_RING_SIZE   2048
+
+#define DOORBELL_DMR_DI                0x00000002
+#define DOORBELL_DSR_TE                0x00000080
+#define DOORBELL_DSR_QFI       0x00000010
+#define DOORBELL_DSR_DIQI      0x00000001
+#define DOORBELL_TID_OFFSET    0x03
+#define DOORBELL_SID_OFFSET    0x05
+#define DOORBELL_INFO_OFFSET   0x06
+
+#define DOORBELL_MESSAGE_SIZE  0x08
+#define DBELL_SID(x)           (*(u8 *)(x + DOORBELL_SID_OFFSET))
+#define DBELL_TID(x)           (*(u8 *)(x + DOORBELL_TID_OFFSET))
+#define DBELL_INF(x)           (*(u16 *)(x + DOORBELL_INFO_OFFSET))
+
+#define is_power_of_2(x)       (((x) & ((x) - 1)) == 0)
+
+struct rio_atmu_regs {
+       u32 rowtar;
+       u32 pad1;
+       u32 rowbar;
+       u32 pad2;
+       u32 rowar;
+       u32 pad3[3];
+};
+
+struct rio_msg_regs {
+       u32 omr;
+       u32 osr;
+       u32 pad1;
+       u32 odqdpar;
+       u32 pad2;
+       u32 osar;
+       u32 odpr;
+       u32 odatr;
+       u32 odcr;
+       u32 pad3;
+       u32 odqepar;
+       u32 pad4[13];
+       u32 imr;
+       u32 isr;
+       u32 pad5;
+       u32 ifqdpar;
+       u32 pad6;
+       u32 ifqepar;
+       u32 pad7[250];
+       u32 dmr;
+       u32 dsr;
+       u32 pad8;
+       u32 dqdpar;
+       u32 pad9;
+       u32 dqepar;
+       u32 pad10[26];
+       u32 pwmr;
+       u32 pwsr;
+       u32 pad11;
+       u32 pwqbar;
+};
+
+struct rio_tx_desc {
+       u32 res1;
+       u32 saddr;
+       u32 dport;
+       u32 dattr;
+       u32 res2;
+       u32 res3;
+       u32 dwcnt;
+       u32 res4;
+};
+
+static u32 regs_win;
+static struct rio_atmu_regs *atmu_regs;
+static struct rio_atmu_regs *maint_atmu_regs;
+static struct rio_atmu_regs *dbell_atmu_regs;
+static u32 dbell_win;
+static u32 maint_win;
+static struct rio_msg_regs *msg_regs;
+
+static struct rio_dbell_ring {
+       void *virt;
+       dma_addr_t phys;
+} dbell_ring;
+
+static struct rio_msg_tx_ring {
+       void *virt;
+       dma_addr_t phys;
+       void *virt_buffer[RIO_MAX_TX_RING_SIZE];
+       dma_addr_t phys_buffer[RIO_MAX_TX_RING_SIZE];
+       int tx_slot;
+       int size;
+       void *dev_id;
+} msg_tx_ring;
+
+static struct rio_msg_rx_ring {
+       void *virt;
+       dma_addr_t phys;
+       void *virt_buffer[RIO_MAX_RX_RING_SIZE];
+       int rx_slot;
+       int size;
+       void *dev_id;
+} msg_rx_ring;
+
+/**
+ * mpc85xx_rio_doorbell_send - Send a MPC85xx doorbell message
+ * @index: ID of RapidIO interface
+ * @destid: Destination ID of target device
+ * @data: 16-bit info field of RapidIO doorbell message
+ *
+ * Sends a MPC85xx doorbell message. Returns %0 on success or
+ * %-EINVAL on failure.
+ */
+static int mpc85xx_rio_doorbell_send(int index, u16 destid, u16 data)
+{
+       pr_debug("mpc85xx_doorbell_send: index %d destid %4.4x data %4.4x\n",
+                index, destid, data);
+       out_be32((void *)&dbell_atmu_regs->rowtar, destid << 22);
+       out_be16((void *)(dbell_win), data);
+
+       return 0;
+}
+
+/**
+ * mpc85xx_local_config_read - Generate a MPC85xx local config space read
+ * @index: ID of RapdiIO interface
+ * @offset: Offset into configuration space
+ * @len: Length (in bytes) of the maintenance transaction
+ * @data: Value to be read into
+ *
+ * Generates a MPC85xx local configuration space read. Returns %0 on
+ * success or %-EINVAL on failure.
+ */
+static int mpc85xx_local_config_read(int index, u32 offset, int len, u32 * data)
+{
+       pr_debug("mpc85xx_local_config_read: index %d offset %8.8x\n", index,
+                offset);
+       *data = in_be32((void *)(regs_win + offset));
+
+       return 0;
+}
+
+/**
+ * mpc85xx_local_config_write - Generate a MPC85xx local config space write
+ * @index: ID of RapdiIO interface
+ * @offset: Offset into configuration space
+ * @len: Length (in bytes) of the maintenance transaction
+ * @data: Value to be written
+ *
+ * Generates a MPC85xx local configuration space write. Returns %0 on
+ * success or %-EINVAL on failure.
+ */
+static int mpc85xx_local_config_write(int index, u32 offset, int len, u32 data)
+{
+       pr_debug
+           ("mpc85xx_local_config_write: index %d offset %8.8x data %8.8x\n",
+            index, offset, data);
+       out_be32((void *)(regs_win + offset), data);
+
+       return 0;
+}
+
+/**
+ * mpc85xx_rio_config_read - Generate a MPC85xx read maintenance transaction
+ * @index: ID of RapdiIO interface
+ * @destid: Destination ID of transaction
+ * @hopcount: Number of hops to target device
+ * @offset: Offset into configuration space
+ * @len: Length (in bytes) of the maintenance transaction
+ * @val: Location to be read into
+ *
+ * Generates a MPC85xx read maintenance transaction. Returns %0 on
+ * success or %-EINVAL on failure.
+ */
+static int
+mpc85xx_rio_config_read(int index, u16 destid, u8 hopcount, u32 offset, int len,
+                       u32 * val)
+{
+       u8 *data;
+
+       pr_debug
+           ("mpc85xx_rio_config_read: index %d destid %d hopcount %d offset %8.8x len %d\n",
+            index, destid, hopcount, offset, len);
+       out_be32((void *)&maint_atmu_regs->rowtar,
+                (destid << 22) | (hopcount << 12) | ((offset & ~0x3) >> 9));
+
+       data = (u8 *) maint_win + offset;
+       switch (len) {
+       case 1:
+               *val = in_8((u8 *) data);
+               break;
+       case 2:
+               *val = in_be16((u16 *) data);
+               break;
+       default:
+               *val = in_be32((u32 *) data);
+               break;
+       }
+
+       return 0;
+}
+
+/**
+ * mpc85xx_rio_config_write - Generate a MPC85xx write maintenance transaction
+ * @index: ID of RapdiIO interface
+ * @destid: Destination ID of transaction
+ * @hopcount: Number of hops to target device
+ * @offset: Offset into configuration space
+ * @len: Length (in bytes) of the maintenance transaction
+ * @val: Value to be written
+ *
+ * Generates an MPC85xx write maintenance transaction. Returns %0 on
+ * success or %-EINVAL on failure.
+ */
+static int
+mpc85xx_rio_config_write(int index, u16 destid, u8 hopcount, u32 offset,
+                        int len, u32 val)
+{
+       u8 *data;
+       pr_debug
+           ("mpc85xx_rio_config_write: index %d destid %d hopcount %d offset %8.8x len %d val %8.8x\n",
+            index, destid, hopcount, offset, len, val);
+       out_be32((void *)&maint_atmu_regs->rowtar,
+                (destid << 22) | (hopcount << 12) | ((offset & ~0x3) >> 9));
+
+       data = (u8 *) maint_win + offset;
+       switch (len) {
+       case 1:
+               out_8((u8 *) data, val);
+               break;
+       case 2:
+               out_be16((u16 *) data, val);
+               break;
+       default:
+               out_be32((u32 *) data, val);
+               break;
+       }
+
+       return 0;
+}
+
+/**
+ * rio_hw_add_outb_message - Add message to the MPC85xx outbound message queue
+ * @mport: Master port with outbound message queue
+ * @rdev: Target of outbound message
+ * @mbox: Outbound mailbox
+ * @buffer: Message to add to outbound queue
+ * @len: Length of message
+ *
+ * Adds the @buffer message to the MPC85xx outbound message queue. Returns
+ * %0 on success or %-EINVAL on failure.
+ */
+int
+rio_hw_add_outb_message(struct rio_mport *mport, struct rio_dev *rdev, int mbox,
+                       void *buffer, size_t len)
+{
+       u32 omr;
+       struct rio_tx_desc *desc =
+           (struct rio_tx_desc *)msg_tx_ring.virt + msg_tx_ring.tx_slot;
+       int ret = 0;
+
+       pr_debug
+           ("RIO: rio_hw_add_outb_message(): destid %4.4x mbox %d buffer %8.8x len %8.8x\n",
+            rdev->destid, mbox, (int)buffer, len);
+
+       if ((len < 8) || (len > RIO_MAX_MSG_SIZE)) {
+               ret = -EINVAL;
+               goto out;
+       }
+
+       /* Copy and clear rest of buffer */
+       memcpy(msg_tx_ring.virt_buffer[msg_tx_ring.tx_slot], buffer, len);
+       if (len < (RIO_MAX_MSG_SIZE - 4))
+               memset((void *)((u32) msg_tx_ring.
+                               virt_buffer[msg_tx_ring.tx_slot] + len), 0,
+                      RIO_MAX_MSG_SIZE - len);
+
+       /* Set mbox field for message */
+       desc->dport = mbox & 0x3;
+
+       /* Enable EOMI interrupt, set priority, and set destid */
+       desc->dattr = 0x28000000 | (rdev->destid << 2);
+
+       /* Set transfer size aligned to next power of 2 (in double words) */
+       desc->dwcnt = is_power_of_2(len) ? len : 1 << get_bitmask_order(len);
+
+       /* Set snooping and source buffer address */
+       desc->saddr = 0x00000004 | msg_tx_ring.phys_buffer[msg_tx_ring.tx_slot];
+
+       /* Increment enqueue pointer */
+       omr = in_be32((void *)&msg_regs->omr);
+       out_be32((void *)&msg_regs->omr, omr | RIO_MSG_OMR_MUI);
+
+       /* Go to next descriptor */
+       if (++msg_tx_ring.tx_slot == msg_tx_ring.size)
+               msg_tx_ring.tx_slot = 0;
+
+      out:
+       return ret;
+}
+
+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)
+{
+       int osr;
+       struct rio_mport *port = (struct rio_mport *)dev_instance;
+
+       osr = in_be32((void *)&msg_regs->osr);
+
+       if (osr & RIO_MSG_OSR_TE) {
+               pr_info("RIO: outbound message transmission error\n");
+               out_be32((void *)&msg_regs->osr, RIO_MSG_OSR_TE);
+               goto out;
+       }
+
+       if (osr & RIO_MSG_OSR_QOI) {
+               pr_info("RIO: outbound message queue overflow\n");
+               out_be32((void *)&msg_regs->osr, RIO_MSG_OSR_QOI);
+               goto out;
+       }
+
+       if (osr & RIO_MSG_OSR_EOMI) {
+               u32 dqp = in_be32((void *)&msg_regs->odqdpar);
+               int slot = (dqp - msg_tx_ring.phys) >> 5;
+               port->outb_msg[0].mcback(port, msg_tx_ring.dev_id, -1, slot);
+
+               /* Ack the end-of-message interrupt */
+               out_be32((void *)&msg_regs->osr, RIO_MSG_OSR_EOMI);
+       }
+
+      out:
+       return IRQ_HANDLED;
+}
+
+/**
+ * rio_open_outb_mbox - Initialize MPC85xx outbound mailbox
+ * @mport: Master port implementing the outbound message unit
+ * @dev_id: Device specific pointer to pass on event
+ * @mbox: Mailbox to open
+ * @entries: Number of entries in the outbound mailbox ring
+ *
+ * Initializes buffer ring, request the outbound message interrupt,
+ * and enables the outbound message unit. Returns %0 on success and
+ * %-EINVAL or %-ENOMEM on failure.
+ */
+int rio_open_outb_mbox(struct rio_mport *mport, void *dev_id, int mbox, int entries)
+{
+       int i, j, rc = 0;
+
+       if ((entries < RIO_MIN_TX_RING_SIZE) ||
+           (entries > RIO_MAX_TX_RING_SIZE) || (!is_power_of_2(entries))) {
+               rc = -EINVAL;
+               goto out;
+       }
+
+       /* Initialize shadow copy ring */
+       msg_tx_ring.dev_id = dev_id;
+       msg_tx_ring.size = entries;
+
+       for (i = 0; i < msg_tx_ring.size; i++) {
+               if (!
+                   (msg_tx_ring.virt_buffer[i] =
+                    dma_alloc_coherent(NULL, RIO_MSG_BUFFER_SIZE,
+                                       &msg_tx_ring.phys_buffer[i],
+                                       GFP_KERNEL))) {
+                       rc = -ENOMEM;
+                       for (j = 0; j < msg_tx_ring.size; j++)
+                               if (msg_tx_ring.virt_buffer[j])
+                                       dma_free_coherent(NULL,
+                                                         RIO_MSG_BUFFER_SIZE,
+                                                         msg_tx_ring.
+                                                         virt_buffer[j],
+                                                         msg_tx_ring.
+                                                         phys_buffer[j]);
+                       goto out;
+               }
+       }
+
+       /* Initialize outbound message descriptor ring */
+       if (!(msg_tx_ring.virt = dma_alloc_coherent(NULL,
+                                                   msg_tx_ring.size *
+                                                   RIO_MSG_DESC_SIZE,
+                                                   &msg_tx_ring.phys,
+                                                   GFP_KERNEL))) {
+               rc = -ENOMEM;
+               goto out_dma;
+       }
+       memset(msg_tx_ring.virt, 0, msg_tx_ring.size * RIO_MSG_DESC_SIZE);
+       msg_tx_ring.tx_slot = 0;
+
+       /* Point dequeue/enqueue pointers at first entry in ring */
+       out_be32((void *)&msg_regs->odqdpar, msg_tx_ring.phys);
+       out_be32((void *)&msg_regs->odqepar, msg_tx_ring.phys);
+
+       /* Configure for snooping */
+       out_be32((void *)&msg_regs->osar, 0x00000004);
+
+       /* Clear interrupt status */
+       out_be32((void *)&msg_regs->osr, 0x000000b3);
+
+       /* Hook up outbound message handler */
+       if ((rc =
+            request_irq(MPC85xx_IRQ_RIO_TX, mpc85xx_rio_tx_handler, 0,
+                        "msg_tx", (void *)mport)) < 0)
+               goto out_irq;
+
+       /*
+        * Configure outbound message unit
+        *      Snooping
+        *      Interrupts (all enabled, except QEIE)
+        *      Chaining mode
+        *      Disable
+        */
+       out_be32((void *)&msg_regs->omr, 0x00100220);
+
+       /* Set number of entries */
+       out_be32((void *)&msg_regs->omr,
+                in_be32((void *)&msg_regs->omr) |
+                ((get_bitmask_order(entries) - 2) << 12));
+
+       /* Now enable the unit */
+       out_be32((void *)&msg_regs->omr, in_be32((void *)&msg_regs->omr) | 0x1);
+
+      out:
+       return rc;
+
+      out_irq:
+       dma_free_coherent(NULL, msg_tx_ring.size * RIO_MSG_DESC_SIZE,
+                         msg_tx_ring.virt, msg_tx_ring.phys);
+
+      out_dma:
+       for (i = 0; i < msg_tx_ring.size; i++)
+               dma_free_coherent(NULL, RIO_MSG_BUFFER_SIZE,
+                                 msg_tx_ring.virt_buffer[i],
+                                 msg_tx_ring.phys_buffer[i]);
+
+       return rc;
+}
+
+/**
+ * rio_close_outb_mbox - Shut down MPC85xx outbound mailbox
+ * @mport: Master port implementing the outbound message unit
+ * @mbox: Mailbox to close
+ *
+ * Disables the outbound message unit, free all buffers, and
+ * frees the outbound message interrupt.
+ */
+void rio_close_outb_mbox(struct rio_mport *mport, int mbox)
+{
+       /* Disable inbound message unit */
+       out_be32((void *)&msg_regs->omr, 0);
+
+       /* Free ring */
+       dma_free_coherent(NULL, msg_tx_ring.size * RIO_MSG_DESC_SIZE,
+                         msg_tx_ring.virt, msg_tx_ring.phys);
+
+       /* Free interrupt */
+       free_irq(MPC85xx_IRQ_RIO_TX, (void *)mport);
+}
+
+/**
+ * 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)
+{
+       int isr;
+       struct rio_mport *port = (struct rio_mport *)dev_instance;
+
+       isr = in_be32((void *)&msg_regs->isr);
+
+       if (isr & RIO_MSG_ISR_TE) {
+               pr_info("RIO: inbound message reception error\n");
+               out_be32((void *)&msg_regs->isr, RIO_MSG_ISR_TE);
+               goto out;
+       }
+
+       /* XXX Need to check/dispatch until queue empty */
+       if (isr & RIO_MSG_ISR_DIQI) {
+               /*
+                * We implement *only* mailbox 0, but can receive messages
+                * for any mailbox/letter to that mailbox destination. So,
+                * make the callback with an unknown/invalid mailbox number
+                * argument.
+                */
+               port->inb_msg[0].mcback(port, msg_rx_ring.dev_id, -1, -1);
+
+               /* Ack the queueing interrupt */
+               out_be32((void *)&msg_regs->isr, RIO_MSG_ISR_DIQI);
+       }
+
+      out:
+       return IRQ_HANDLED;
+}
+
+/**
+ * rio_open_inb_mbox - Initialize MPC85xx inbound mailbox
+ * @mport: Master port implementing the inbound message unit
+ * @dev_id: Device specific pointer to pass on event
+ * @mbox: Mailbox to open
+ * @entries: Number of entries in the inbound mailbox ring
+ *
+ * Initializes buffer ring, request the inbound message interrupt,
+ * and enables the inbound message unit. Returns %0 on success
+ * and %-EINVAL or %-ENOMEM on failure.
+ */
+int rio_open_inb_mbox(struct rio_mport *mport, void *dev_id, int mbox, int entries)
+{
+       int i, rc = 0;
+
+       if ((entries < RIO_MIN_RX_RING_SIZE) ||
+           (entries > RIO_MAX_RX_RING_SIZE) || (!is_power_of_2(entries))) {
+               rc = -EINVAL;
+               goto out;
+       }
+
+       /* Initialize client buffer ring */
+       msg_rx_ring.dev_id = dev_id;
+       msg_rx_ring.size = entries;
+       msg_rx_ring.rx_slot = 0;
+       for (i = 0; i < msg_rx_ring.size; i++)
+               msg_rx_ring.virt_buffer[i] = NULL;
+
+       /* Initialize inbound message ring */
+       if (!(msg_rx_ring.virt = dma_alloc_coherent(NULL,
+                                                   msg_rx_ring.size *
+                                                   RIO_MAX_MSG_SIZE,
+                                                   &msg_rx_ring.phys,
+                                                   GFP_KERNEL))) {
+               rc = -ENOMEM;
+               goto out;
+       }
+
+       /* Point dequeue/enqueue pointers at first entry in ring */
+       out_be32((void *)&msg_regs->ifqdpar, (u32) msg_rx_ring.phys);
+       out_be32((void *)&msg_regs->ifqepar, (u32) msg_rx_ring.phys);
+
+       /* Clear interrupt status */
+       out_be32((void *)&msg_regs->isr, 0x00000091);
+
+       /* Hook up inbound message handler */
+       if ((rc =
+            request_irq(MPC85xx_IRQ_RIO_RX, mpc85xx_rio_rx_handler, 0,
+                        "msg_rx", (void *)mport)) < 0) {
+               dma_free_coherent(NULL, RIO_MSG_BUFFER_SIZE,
+                                 msg_tx_ring.virt_buffer[i],
+                                 msg_tx_ring.phys_buffer[i]);
+               goto out;
+       }
+
+       /*
+        * Configure inbound message unit:
+        *      Snooping
+        *      4KB max message size
+        *      Unmask all interrupt sources
+        *      Disable
+        */
+       out_be32((void *)&msg_regs->imr, 0x001b0060);
+
+       /* Set number of queue entries */
+       out_be32((void *)&msg_regs->imr,
+                in_be32((void *)&msg_regs->imr) |
+                ((get_bitmask_order(entries) - 2) << 12));
+
+       /* Now enable the unit */
+       out_be32((void *)&msg_regs->imr, in_be32((void *)&msg_regs->imr) | 0x1);
+
+      out:
+       return rc;
+}
+
+/**
+ * rio_close_inb_mbox - Shut down MPC85xx inbound mailbox
+ * @mport: Master port implementing the inbound message unit
+ * @mbox: Mailbox to close
+ *
+ * Disables the inbound message unit, free all buffers, and
+ * frees the inbound message interrupt.
+ */
+void rio_close_inb_mbox(struct rio_mport *mport, int mbox)
+{
+       /* Disable inbound message unit */
+       out_be32((void *)&msg_regs->imr, 0);
+
+       /* Free ring */
+       dma_free_coherent(NULL, msg_rx_ring.size * RIO_MAX_MSG_SIZE,
+                         msg_rx_ring.virt, msg_rx_ring.phys);
+
+       /* Free interrupt */
+       free_irq(MPC85xx_IRQ_RIO_RX, (void *)mport);
+}
+
+/**
+ * rio_hw_add_inb_buffer - Add buffer to the MPC85xx inbound message queue
+ * @mport: Master port implementing the inbound message unit
+ * @mbox: Inbound mailbox number
+ * @buf: Buffer to add to inbound queue
+ *
+ * Adds the @buf buffer to the MPC85xx inbound message queue. Returns
+ * %0 on success or %-EINVAL on failure.
+ */
+int rio_hw_add_inb_buffer(struct rio_mport *mport, int mbox, void *buf)
+{
+       int rc = 0;
+
+       pr_debug("RIO: rio_hw_add_inb_buffer(), msg_rx_ring.rx_slot %d\n",
+                msg_rx_ring.rx_slot);
+
+       if (msg_rx_ring.virt_buffer[msg_rx_ring.rx_slot]) {
+               printk(KERN_ERR
+                      "RIO: error adding inbound buffer %d, buffer exists\n",
+                      msg_rx_ring.rx_slot);
+               rc = -EINVAL;
+               goto out;
+       }
+
+       msg_rx_ring.virt_buffer[msg_rx_ring.rx_slot] = buf;
+       if (++msg_rx_ring.rx_slot == msg_rx_ring.size)
+               msg_rx_ring.rx_slot = 0;
+
+      out:
+       return rc;
+}
+
+EXPORT_SYMBOL_GPL(rio_hw_add_inb_buffer);
+
+/**
+ * rio_hw_get_inb_message - Fetch inbound message from the MPC85xx message unit
+ * @mport: Master port implementing the inbound message unit
+ * @mbox: Inbound mailbox number
+ *
+ * Gets the next available inbound message from the inbound message queue.
+ * A pointer to the message is returned on success or NULL on failure.
+ */
+void *rio_hw_get_inb_message(struct rio_mport *mport, int mbox)
+{
+       u32 imr;
+       u32 phys_buf, virt_buf;
+       void *buf = NULL;
+       int buf_idx;
+
+       phys_buf = in_be32((void *)&msg_regs->ifqdpar);
+
+       /* If no more messages, then bail out */
+       if (phys_buf == in_be32((void *)&msg_regs->ifqepar))
+               goto out2;
+
+       virt_buf = (u32) msg_rx_ring.virt + (phys_buf - msg_rx_ring.phys);
+       buf_idx = (phys_buf - msg_rx_ring.phys) / RIO_MAX_MSG_SIZE;
+       buf = msg_rx_ring.virt_buffer[buf_idx];
+
+       if (!buf) {
+               printk(KERN_ERR
+                      "RIO: inbound message copy failed, no buffers\n");
+               goto out1;
+       }
+
+       /* Copy max message size, caller is expected to allocate that big */
+       memcpy(buf, (void *)virt_buf, RIO_MAX_MSG_SIZE);
+
+       /* Clear the available buffer */
+       msg_rx_ring.virt_buffer[buf_idx] = NULL;
+
+      out1:
+       imr = in_be32((void *)&msg_regs->imr);
+       out_be32((void *)&msg_regs->imr, imr | RIO_MSG_IMR_MI);
+
+      out2:
+       return buf;
+}
+
+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)
+{
+       int dsr;
+       struct rio_mport *port = (struct rio_mport *)dev_instance;
+
+       dsr = in_be32((void *)&msg_regs->dsr);
+
+       if (dsr & DOORBELL_DSR_TE) {
+               pr_info("RIO: doorbell reception error\n");
+               out_be32((void *)&msg_regs->dsr, DOORBELL_DSR_TE);
+               goto out;
+       }
+
+       if (dsr & DOORBELL_DSR_QFI) {
+               pr_info("RIO: doorbell queue full\n");
+               out_be32((void *)&msg_regs->dsr, DOORBELL_DSR_QFI);
+               goto out;
+       }
+
+       /* XXX Need to check/dispatch until queue empty */
+       if (dsr & DOORBELL_DSR_DIQI) {
+               u32 dmsg =
+                   (u32) dbell_ring.virt +
+                   (in_be32((void *)&msg_regs->dqdpar) & 0xfff);
+               u32 dmr;
+               struct rio_dbell *dbell;
+               int found = 0;
+
+               pr_debug
+                   ("RIO: processing doorbell, sid %2.2x tid %2.2x info %4.4x\n",
+                    DBELL_SID(dmsg), DBELL_TID(dmsg), DBELL_INF(dmsg));
+
+               list_for_each_entry(dbell, &port->dbells, node) {
+                       if ((dbell->res->start <= DBELL_INF(dmsg)) &&
+                           (dbell->res->end >= DBELL_INF(dmsg))) {
+                               found = 1;
+                               break;
+                       }
+               }
+               if (found) {
+                       dbell->dinb(port, dbell->dev_id, DBELL_SID(dmsg), DBELL_TID(dmsg),
+                                   DBELL_INF(dmsg));
+               } else {
+                       pr_debug
+                           ("RIO: spurious doorbell, sid %2.2x tid %2.2x info %4.4x\n",
+                            DBELL_SID(dmsg), DBELL_TID(dmsg), DBELL_INF(dmsg));
+               }
+               dmr = in_be32((void *)&msg_regs->dmr);
+               out_be32((void *)&msg_regs->dmr, dmr | DOORBELL_DMR_DI);
+               out_be32((void *)&msg_regs->dsr, DOORBELL_DSR_DIQI);
+       }
+
+      out:
+       return IRQ_HANDLED;
+}
+
+/**
+ * mpc85xx_rio_doorbell_init - MPC85xx doorbell interface init
+ * @mport: Master port implementing the inbound doorbell unit
+ *
+ * Initializes doorbell unit hardware and inbound DMA buffer
+ * ring. Called from mpc85xx_rio_setup(). Returns %0 on success
+ * or %-ENOMEM on failure.
+ */
+static int mpc85xx_rio_doorbell_init(struct rio_mport *mport)
+{
+       int rc = 0;
+
+       /* Map outbound doorbell window immediately after maintenance window */
+       if (!(dbell_win =
+             (u32) ioremap(mport->iores.start + RIO_MAINT_WIN_SIZE,
+                           RIO_DBELL_WIN_SIZE))) {
+               printk(KERN_ERR
+                      "RIO: unable to map outbound doorbell window\n");
+               rc = -ENOMEM;
+               goto out;
+       }
+
+       /* Initialize inbound doorbells */
+       if (!(dbell_ring.virt = dma_alloc_coherent(NULL,
+                                                  512 * DOORBELL_MESSAGE_SIZE,
+                                                  &dbell_ring.phys,
+                                                  GFP_KERNEL))) {
+               printk(KERN_ERR "RIO: unable allocate inbound doorbell ring\n");
+               rc = -ENOMEM;
+               iounmap((void *)dbell_win);
+               goto out;
+       }
+
+       /* Point dequeue/enqueue pointers at first entry in ring */
+       out_be32((void *)&msg_regs->dqdpar, (u32) dbell_ring.phys);
+       out_be32((void *)&msg_regs->dqepar, (u32) dbell_ring.phys);
+
+       /* Clear interrupt status */
+       out_be32((void *)&msg_regs->dsr, 0x00000091);
+
+       /* Hook up doorbell handler */
+       if ((rc =
+            request_irq(MPC85xx_IRQ_RIO_BELL, mpc85xx_rio_dbell_handler, 0,
+                        "dbell_rx", (void *)mport) < 0)) {
+               iounmap((void *)dbell_win);
+               dma_free_coherent(NULL, 512 * DOORBELL_MESSAGE_SIZE,
+                                 dbell_ring.virt, dbell_ring.phys);
+               printk(KERN_ERR
+                      "MPC85xx RIO: unable to request inbound doorbell irq");
+               goto out;
+       }
+
+       /* Configure doorbells for snooping, 512 entries, and enable */
+       out_be32((void *)&msg_regs->dmr, 0x00108161);
+
+      out:
+       return rc;
+}
+
+static char *cmdline = NULL;
+
+static int mpc85xx_rio_get_hdid(int index)
+{
+       /* XXX Need to parse multiple entries in some format */
+       if (!cmdline)
+               return -1;
+
+       return simple_strtol(cmdline, NULL, 0);
+}
+
+static int mpc85xx_rio_get_cmdline(char *s)
+{
+       if (!s)
+               return 0;
+
+       cmdline = s;
+       return 1;
+}
+
+__setup("riohdid=", mpc85xx_rio_get_cmdline);
+
+/**
+ * mpc85xx_rio_setup - Setup MPC85xx RapidIO interface
+ * @law_start: Starting physical address of RapidIO LAW
+ * @law_size: Size of RapidIO LAW
+ *
+ * Initializes MPC85xx RapidIO hardware interface, configures
+ * master port with system-specific info, and registers the
+ * master port with the RapidIO subsystem.
+ */
+void mpc85xx_rio_setup(int law_start, int law_size)
+{
+       struct rio_ops *ops;
+       struct rio_mport *port;
+
+       ops = kmalloc(sizeof(struct rio_ops), GFP_KERNEL);
+       ops->lcread = mpc85xx_local_config_read;
+       ops->lcwrite = mpc85xx_local_config_write;
+       ops->cread = mpc85xx_rio_config_read;
+       ops->cwrite = mpc85xx_rio_config_write;
+       ops->dsend = mpc85xx_rio_doorbell_send;
+
+       port = kmalloc(sizeof(struct rio_mport), GFP_KERNEL);
+       port->id = 0;
+       port->index = 0;
+       INIT_LIST_HEAD(&port->dbells);
+       port->iores.start = law_start;
+       port->iores.end = law_start + law_size;
+       port->iores.flags = IORESOURCE_MEM;
+
+       rio_init_dbell_res(&port->riores[RIO_DOORBELL_RESOURCE], 0, 0xffff);
+       rio_init_mbox_res(&port->riores[RIO_INB_MBOX_RESOURCE], 0, 0);
+       rio_init_mbox_res(&port->riores[RIO_OUTB_MBOX_RESOURCE], 0, 0);
+       strcpy(port->name, "RIO0 mport");
+
+       port->ops = ops;
+       port->host_deviceid = mpc85xx_rio_get_hdid(port->id);
+
+       rio_register_mport(port);
+
+       regs_win = (u32) ioremap(RIO_REGS_BASE, 0x20000);
+       atmu_regs = (struct rio_atmu_regs *)(regs_win + RIO_ATMU_REGS_OFFSET);
+       maint_atmu_regs = atmu_regs + 1;
+       dbell_atmu_regs = atmu_regs + 2;
+       msg_regs = (struct rio_msg_regs *)(regs_win + RIO_MSG_REGS_OFFSET);
+
+       /* Configure maintenance transaction window */
+       out_be32((void *)&maint_atmu_regs->rowbar, 0x000c0000);
+       out_be32((void *)&maint_atmu_regs->rowar, 0x80077015);
+
+       maint_win = (u32) ioremap(law_start, RIO_MAINT_WIN_SIZE);
+
+       /* Configure outbound doorbell window */
+       out_be32((void *)&dbell_atmu_regs->rowbar, 0x000c0400);
+       out_be32((void *)&dbell_atmu_regs->rowar, 0x8004200b);
+       mpc85xx_rio_doorbell_init(port);
+}
diff --git a/arch/ppc/syslib/ppc85xx_rio.h b/arch/ppc/syslib/ppc85xx_rio.h
new file mode 100644 (file)
index 0000000..c0827a2
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * MPC85xx RapidIO definitions
+ *
+ * Copyright 2005 MontaVista Software, Inc.
+ * Matt Porter <mporter@kernel.crashing.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.
+ */
+
+#ifndef __PPC_SYSLIB_PPC85XX_RIO_H
+#define __PPC_SYSLIB_PPC85XX_RIO_H
+
+#include <linux/config.h>
+#include <linux/init.h>
+
+extern void mpc85xx_rio_setup(int law_start, int law_size);
+
+#endif                         /* __PPC_SYSLIB_PPC85XX_RIO_H */
index 62ee86e80711da6e70862d2f49bd7dafc2fe4caf..603f0119081602e866d83324acf09f7c7a93808d 100644 (file)
@@ -14,6 +14,7 @@
  * option) any later version.
  */
 
+#include <linux/string.h>
 #include <asm/ppc_sys.h>
 
 int (*ppc_sys_device_fixup) (struct platform_device * pdev);
index 278da6ee62ea22f2c3bfa330562460d9c9e9e107..1b9aa0d6a924f5259446c9bbf9a09ac58c0cbfe4 100644 (file)
@@ -1335,10 +1335,8 @@ release_OF_resource(struct device_node* node, int index)
        if (!res)
                return -ENODEV;
 
-       if (res->name) {
-               kfree(res->name);
-               res->name = NULL;
-       }
+       kfree(res->name);
+       res->name = NULL;
        release_resource(res);
        kfree(res);
 
index c1dc876bccab04d424ec7e0b9527c81b0f203462..e0dde24a72cebda62a135314b8c819230b4fd09a 100644 (file)
@@ -203,8 +203,15 @@ void start(unsigned long a1, unsigned long a2, void *promptr, void *sp)
                if (elf64ph->p_type == PT_LOAD && elf64ph->p_offset != 0)
                        break;
        }
-       vmlinux.size = (unsigned long)elf64ph->p_filesz;
-       vmlinux.memsize = (unsigned long)elf64ph->p_memsz;
+       vmlinux.size = (unsigned long)elf64ph->p_filesz +
+               (unsigned long)elf64ph->p_offset;
+       /* We need to claim the memsize plus the file offset since gzip
+        * will expand the header (file offset), then the kernel, then
+        * possible rubbish we don't care about. But the kernel bss must
+        * be claimed (it will be zero'd by the kernel itself)
+        */
+       vmlinux.memsize = (unsigned long)elf64ph->p_memsz +
+               (unsigned long)elf64ph->p_offset;
        printf("Allocating 0x%lx bytes for kernel ...\n\r", vmlinux.memsize);
        vmlinux.addr = try_claim(vmlinux.memsize);
        if (vmlinux.addr == 0) {
index ed876a5178ae6bedf663488915c0dc27cdd0ff83..511af54e6230ca13eeba65dd7765dcb9f7c8947c 100644 (file)
 #include <linux/config.h>
 #include <linux/kprobes.h>
 #include <linux/ptrace.h>
-#include <linux/spinlock.h>
 #include <linux/preempt.h>
 #include <asm/cacheflush.h>
 #include <asm/kdebug.h>
 #include <asm/sstep.h>
 
 static DECLARE_MUTEX(kprobe_mutex);
-
-static struct kprobe *current_kprobe;
-static unsigned long kprobe_status, kprobe_saved_msr;
-static struct kprobe *kprobe_prev;
-static unsigned long kprobe_status_prev, kprobe_saved_msr_prev;
-static struct pt_regs jprobe_saved_regs;
+DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
+DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
 
 int __kprobes arch_prepare_kprobe(struct kprobe *p)
 {
@@ -108,20 +103,28 @@ static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
                regs->nip = (unsigned long)p->ainsn.insn;
 }
 
-static inline void save_previous_kprobe(void)
+static inline void save_previous_kprobe(struct kprobe_ctlblk *kcb)
+{
+       kcb->prev_kprobe.kp = kprobe_running();
+       kcb->prev_kprobe.status = kcb->kprobe_status;
+       kcb->prev_kprobe.saved_msr = kcb->kprobe_saved_msr;
+}
+
+static inline void restore_previous_kprobe(struct kprobe_ctlblk *kcb)
 {
-       kprobe_prev = current_kprobe;
-       kprobe_status_prev = kprobe_status;
-       kprobe_saved_msr_prev = kprobe_saved_msr;
+       __get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp;
+       kcb->kprobe_status = kcb->prev_kprobe.status;
+       kcb->kprobe_saved_msr = kcb->prev_kprobe.saved_msr;
 }
 
-static inline void restore_previous_kprobe(void)
+static inline void set_current_kprobe(struct kprobe *p, struct pt_regs *regs,
+                               struct kprobe_ctlblk *kcb)
 {
-       current_kprobe = kprobe_prev;
-       kprobe_status = kprobe_status_prev;
-       kprobe_saved_msr = kprobe_saved_msr_prev;
+       __get_cpu_var(current_kprobe) = p;
+       kcb->kprobe_saved_msr = regs->msr;
 }
 
+/* Called with kretprobe_lock held */
 void __kprobes arch_prepare_kretprobe(struct kretprobe *rp,
                                      struct pt_regs *regs)
 {
@@ -145,19 +148,24 @@ static inline int kprobe_handler(struct pt_regs *regs)
        struct kprobe *p;
        int ret = 0;
        unsigned int *addr = (unsigned int *)regs->nip;
+       struct kprobe_ctlblk *kcb;
+
+       /*
+        * We don't want to be preempted for the entire
+        * duration of kprobe processing
+        */
+       preempt_disable();
+       kcb = get_kprobe_ctlblk();
 
        /* Check we're not actually recursing */
        if (kprobe_running()) {
-               /* We *are* holding lock here, so this is safe.
-                  Disarm the probe we just hit, and ignore it. */
                p = get_kprobe(addr);
                if (p) {
                        kprobe_opcode_t insn = *p->ainsn.insn;
-                       if (kprobe_status == KPROBE_HIT_SS &&
+                       if (kcb->kprobe_status == KPROBE_HIT_SS &&
                                        is_trap(insn)) {
                                regs->msr &= ~MSR_SE;
-                               regs->msr |= kprobe_saved_msr;
-                               unlock_kprobes();
+                               regs->msr |= kcb->kprobe_saved_msr;
                                goto no_kprobe;
                        }
                        /* We have reentered the kprobe_handler(), since
@@ -166,27 +174,24 @@ static inline int kprobe_handler(struct pt_regs *regs)
                         * just single step on the instruction of the new probe
                         * without calling any user handlers.
                         */
-                       save_previous_kprobe();
-                       current_kprobe = p;
-                       kprobe_saved_msr = regs->msr;
+                       save_previous_kprobe(kcb);
+                       set_current_kprobe(p, regs, kcb);
+                       kcb->kprobe_saved_msr = regs->msr;
                        p->nmissed++;
                        prepare_singlestep(p, regs);
-                       kprobe_status = KPROBE_REENTER;
+                       kcb->kprobe_status = KPROBE_REENTER;
                        return 1;
                } else {
-                       p = current_kprobe;
+                       p = __get_cpu_var(current_kprobe);
                        if (p->break_handler && p->break_handler(p, regs)) {
                                goto ss_probe;
                        }
                }
-               /* If it's not ours, can't be delete race, (we hold lock). */
                goto no_kprobe;
        }
 
-       lock_kprobes();
        p = get_kprobe(addr);
        if (!p) {
-               unlock_kprobes();
                if (*addr != BREAKPOINT_INSTRUCTION) {
                        /*
                         * PowerPC has multiple variants of the "trap"
@@ -209,24 +214,19 @@ static inline int kprobe_handler(struct pt_regs *regs)
                goto no_kprobe;
        }
 
-       kprobe_status = KPROBE_HIT_ACTIVE;
-       current_kprobe = p;
-       kprobe_saved_msr = regs->msr;
+       kcb->kprobe_status = KPROBE_HIT_ACTIVE;
+       set_current_kprobe(p, regs, kcb);
        if (p->pre_handler && p->pre_handler(p, regs))
                /* handler has already set things up, so skip ss setup */
                return 1;
 
 ss_probe:
        prepare_singlestep(p, regs);
-       kprobe_status = KPROBE_HIT_SS;
-       /*
-        * This preempt_disable() matches the preempt_enable_no_resched()
-        * in post_kprobe_handler().
-        */
-       preempt_disable();
+       kcb->kprobe_status = KPROBE_HIT_SS;
        return 1;
 
 no_kprobe:
+       preempt_enable_no_resched();
        return ret;
 }
 
@@ -251,9 +251,10 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
         struct kretprobe_instance *ri = NULL;
         struct hlist_head *head;
         struct hlist_node *node, *tmp;
-       unsigned long orig_ret_address = 0;
+       unsigned long flags, orig_ret_address = 0;
        unsigned long trampoline_address =(unsigned long)&kretprobe_trampoline;
 
+       spin_lock_irqsave(&kretprobe_lock, flags);
         head = kretprobe_inst_table_head(current);
 
        /*
@@ -292,12 +293,14 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
        BUG_ON(!orig_ret_address || (orig_ret_address == trampoline_address));
        regs->nip = orig_ret_address;
 
-       unlock_kprobes();
+       reset_current_kprobe();
+       spin_unlock_irqrestore(&kretprobe_lock, flags);
+       preempt_enable_no_resched();
 
         /*
          * By returning a non-zero value, we are telling
-         * kprobe_handler() that we have handled unlocking
-         * and re-enabling preemption.
+         * kprobe_handler() that we don't want the post_handler
+         * to run (and have re-enabled preemption)
          */
         return 1;
 }
@@ -323,23 +326,26 @@ static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs)
 
 static inline int post_kprobe_handler(struct pt_regs *regs)
 {
-       if (!kprobe_running())
+       struct kprobe *cur = kprobe_running();
+       struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+
+       if (!cur)
                return 0;
 
-       if ((kprobe_status != KPROBE_REENTER) && current_kprobe->post_handler) {
-               kprobe_status = KPROBE_HIT_SSDONE;
-               current_kprobe->post_handler(current_kprobe, regs, 0);
+       if ((kcb->kprobe_status != KPROBE_REENTER) && cur->post_handler) {
+               kcb->kprobe_status = KPROBE_HIT_SSDONE;
+               cur->post_handler(cur, regs, 0);
        }
 
-       resume_execution(current_kprobe, regs);
-       regs->msr |= kprobe_saved_msr;
+       resume_execution(cur, regs);
+       regs->msr |= kcb->kprobe_saved_msr;
 
        /*Restore back the original saved kprobes variables and continue. */
-       if (kprobe_status == KPROBE_REENTER) {
-               restore_previous_kprobe();
+       if (kcb->kprobe_status == KPROBE_REENTER) {
+               restore_previous_kprobe(kcb);
                goto out;
        }
-       unlock_kprobes();
+       reset_current_kprobe();
 out:
        preempt_enable_no_resched();
 
@@ -354,19 +360,20 @@ out:
        return 1;
 }
 
-/* Interrupts disabled, kprobe_lock held. */
 static inline int kprobe_fault_handler(struct pt_regs *regs, int trapnr)
 {
-       if (current_kprobe->fault_handler
-           && current_kprobe->fault_handler(current_kprobe, regs, trapnr))
+       struct kprobe *cur = kprobe_running();
+       struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+
+       if (cur->fault_handler && cur->fault_handler(cur, regs, trapnr))
                return 1;
 
-       if (kprobe_status & KPROBE_HIT_SS) {
-               resume_execution(current_kprobe, regs);
+       if (kcb->kprobe_status & KPROBE_HIT_SS) {
+               resume_execution(cur, regs);
                regs->msr &= ~MSR_SE;
-               regs->msr |= kprobe_saved_msr;
+               regs->msr |= kcb->kprobe_saved_msr;
 
-               unlock_kprobes();
+               reset_current_kprobe();
                preempt_enable_no_resched();
        }
        return 0;
@@ -381,11 +388,6 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
        struct die_args *args = (struct die_args *)data;
        int ret = NOTIFY_DONE;
 
-       /*
-        * Interrupts are not disabled here.  We need to disable
-        * preemption, because kprobe_running() uses smp_processor_id().
-        */
-       preempt_disable();
        switch (val) {
        case DIE_BPT:
                if (kprobe_handler(args->regs))
@@ -396,22 +398,25 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
                        ret = NOTIFY_STOP;
                break;
        case DIE_PAGE_FAULT:
+               /* kprobe_running() needs smp_processor_id() */
+               preempt_disable();
                if (kprobe_running() &&
                    kprobe_fault_handler(args->regs, args->trapnr))
                        ret = NOTIFY_STOP;
+               preempt_enable();
                break;
        default:
                break;
        }
-       preempt_enable_no_resched();
        return ret;
 }
 
 int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
 {
        struct jprobe *jp = container_of(p, struct jprobe, kp);
+       struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
 
-       memcpy(&jprobe_saved_regs, regs, sizeof(struct pt_regs));
+       memcpy(&kcb->jprobe_saved_regs, regs, sizeof(struct pt_regs));
 
        /* setup return addr to the jprobe handler routine */
        regs->nip = (unsigned long)(((func_descr_t *)jp->entry)->entry);
@@ -431,12 +436,15 @@ void __kprobes jprobe_return_end(void)
 
 int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
 {
+       struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+
        /*
         * FIXME - we should ideally be validating that we got here 'cos
         * of the "trap" in jprobe_return() above, before restoring the
         * saved regs...
         */
-       memcpy(regs, &jprobe_saved_regs, sizeof(struct pt_regs));
+       memcpy(regs, &kcb->jprobe_saved_regs, sizeof(struct pt_regs));
+       preempt_enable_no_resched();
        return 1;
 }
 
index e86155770bbc5ff761352dfc556b7c146295e77d..3e7b2f28ec8302a4b9025a5cdde84296b9c30e7e 100644 (file)
@@ -599,9 +599,7 @@ int __init lparcfg_init(void)
 void __exit lparcfg_cleanup(void)
 {
        if (proc_ppc64_lparcfg) {
-               if (proc_ppc64_lparcfg->data) {
-                       kfree(proc_ppc64_lparcfg->data);
-               }
+               kfree(proc_ppc64_lparcfg->data);
                remove_proc_entry("lparcfg", proc_ppc64_lparcfg->parent);
        }
 }
index 215bf8900304ea8aa135434feeb26b33b53c6c41..2edc947f7c44b2a9908f43ad098633018dc38bf6 100644 (file)
@@ -225,8 +225,7 @@ int __init scanlog_init(void)
 void __exit scanlog_cleanup(void)
 {
        if (proc_ppc64_scan_log_dump) {
-               if (proc_ppc64_scan_log_dump->data)
-                       kfree(proc_ppc64_scan_log_dump->data);
+               kfree(proc_ppc64_scan_log_dump->data);
                remove_proc_entry("scan-log-dump", proc_ppc64_scan_log_dump->parent);
        }
 }
index 6654b350979cfd3a868c029677fff0239d9972ed..e99ec62c2c52abba20b1e4f36da62e70f4d925bc 100644 (file)
@@ -20,6 +20,7 @@
 #include <asm/paca.h>
 #include <asm/lppaca.h>
 #include <asm/machdep.h>
+#include <asm/smp.h>
 
 static DEFINE_PER_CPU(struct cpu, cpu_devices);
 
index 98db30481d97eb211d1e767ca9701767e323dc09..73a09a6ee6c8227f96192a3ef821575d3514c471 100644 (file)
@@ -76,9 +76,7 @@ AFLAGS                += $(aflags-y)
 OBJCOPYFLAGS   := -O binary
 LDFLAGS_vmlinux := -e start
 
-head-$(CONFIG_ARCH_S390_31)    += arch/$(ARCH)/kernel/head.o
-head-$(CONFIG_ARCH_S390X)      += arch/$(ARCH)/kernel/head64.o
-head-y                         += arch/$(ARCH)/kernel/init_task.o
+head-y         := arch/$(ARCH)/kernel/head.o arch/$(ARCH)/kernel/init_task.o
 
 core-y         += arch/$(ARCH)/mm/ arch/$(ARCH)/kernel/ arch/$(ARCH)/crypto/ \
                   arch/$(ARCH)/appldata/
index 8584dd8232181a5cec925779ad799688dbccfc82..7434c32bc6312720a47af11f822a0348f4ad3e4e 100644 (file)
@@ -8,9 +8,7 @@ obj-y   :=  bitmap.o traps.o time.o process.o \
             setup.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o \
             semaphore.o s390_ext.o debug.o profile.o irq.o reipl_diag.o
 
-extra-$(CONFIG_ARCH_S390_31)   += head.o 
-extra-$(CONFIG_ARCH_S390X)     += head64.o 
-extra-y                                += init_task.o vmlinux.lds
+extra-y                                += head.o init_task.o vmlinux.lds
 
 obj-$(CONFIG_MODULES)          += s390_ksyms.o module.o
 obj-$(CONFIG_SMP)              += smp.o
index 9b30f4cf32c4736806791f0904231705f1fc9353..27b07730b7b8d172f4330aaea690f53e82152628 100644 (file)
@@ -288,7 +288,7 @@ sysc_sigpending:
        bo      BASED(sysc_restart)
        tm      __TI_flags+3(%r9),_TIF_SINGLE_STEP
        bo      BASED(sysc_singlestep)
-       b       BASED(sysc_leave)      # out of here, do NOT recheck
+       b       BASED(sysc_work_loop)
 
 #
 # _TIF_RESTART_SVC is set, set up registers and restart svc
@@ -645,7 +645,7 @@ io_sigpending:
         l       %r1,BASED(.Ldo_signal)
        basr    %r14,%r1               # call do_signal
         stnsm   __SF_EMPTY(%r15),0xfc  # disable I/O and ext. interrupts
-       b       BASED(io_leave)        # out of here, do NOT recheck
+       b       BASED(io_work_loop)
 
 /*
  * External interrupt handler routine
index 7b9b4a2ba1d7c3ee58c6b16aba372c278d52addb..4eb71ffcf484d16e985b73c821e836e040fb5e1d 100644 (file)
@@ -283,7 +283,7 @@ sysc_sigpending:
        jo      sysc_restart
        tm      __TI_flags+7(%r9),_TIF_SINGLE_STEP
        jo      sysc_singlestep
-       j       sysc_leave        # out of here, do NOT recheck
+       j       sysc_work_loop
 
 #
 # _TIF_RESTART_SVC is set, set up registers and restart svc
@@ -684,7 +684,7 @@ io_sigpending:
        slgr    %r3,%r3                 # clear *oldset
        brasl   %r14,do_signal          # call do_signal
        stnsm   __SF_EMPTY(%r15),0xfc   # disable I/O and ext. interrupts
-       j       sysc_leave              # out of here, do NOT recheck
+       j       io_work_loop
 
 /*
  * External interrupt handler routine
index 039354d72348eae678124fe62a9dc30dff2ac53f..d31a97c89f684813a5e02777ee6d1c05d7b21633 100644 (file)
@@ -1,11 +1,12 @@
 /*
  *  arch/s390/kernel/head.S
  *
- *  S390 version
- *    Copyright (C) 1999,2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
- *    Author(s): Hartmut Penner (hp@de.ibm.com),
- *               Martin Schwidefsky (schwidefsky@de.ibm.com),
- *               Rob van der Heij (rvdhei@iae.nl)
+ * (C) Copyright IBM Corp. 1999, 2005
+ *
+ *    Author(s): Hartmut Penner <hp@de.ibm.com>
+ *              Martin Schwidefsky <schwidefsky@de.ibm.com>
+ *              Rob van der Heij <rvdhei@iae.nl>
+ *              Heiko Carstens <heiko.carstens@de.ibm.com>
  *
  * There are 5 different IPL methods
  *  1) load the image directly into ram at address 0 and do an PSW restart
  *  5) direct call of start by the SALIPL loader
  *  We use the cpuid to distinguish between VM and native ipl
  *  params for kernel are pushed to 0x10400 (see setup.h)
-
-    Changes: 
-    Okt 25 2000 <rvdheij@iae.nl>
-       added code to skip HDR and EOF to allow SL tape IPL (5 retries)
-       changed first CCW from rewind to backspace block
-
+ *
  */
 
 #include <linux/config.h>
 #include <asm/thread_info.h>
 #include <asm/page.h>
 
+#ifdef CONFIG_ARCH_S390X
+#define ARCH_OFFSET    4
+#else
+#define ARCH_OFFSET    0
+#endif
+
 #ifndef CONFIG_IPL
         .org   0
         .long  0x00080000,0x80000000+startup   # Just a restart PSW
         ssch  0(%r3)                           # load chunk of 1600 bytes
         bnz   .Llderr
 .Lwait4irq:
-        mvc   __LC_IO_NEW_PSW(8),.Lnewpsw      # set up IO interrupt psw
+        mvc   0x78(8),.Lnewpsw                 # set up IO interrupt psw
         lpsw  .Lwaitpsw              
 .Lioint:
         c     %r1,0xb8                         # compare subchannel number
@@ -265,13 +267,13 @@ iplstart:
         la    %r2,IPL_BS                       # load start address
         bas   %r14,.Lloader                    # load rest of ipl image
         l     %r12,.Lparm                      # pointer to parameter area
-        st    %r1,IPL_DEVICE-PARMAREA(%r12)    # store ipl device number
+        st    %r1,IPL_DEVICE+ARCH_OFFSET-PARMAREA(%r12) # save ipl device number
 
 #
 # load parameter file from ipl device
 #
 .Lagain1:
-       l     %r2,INITRD_START-PARMAREA(%r12)  # use ramdisk location as temp
+       l     %r2,INITRD_START+ARCH_OFFSET-PARMAREA(%r12) # ramdisk loc. is temp
         bas   %r14,.Lloader                    # load parameter file
         ltr   %r2,%r2                          # got anything ?
         bz    .Lnopf
@@ -279,7 +281,7 @@ iplstart:
        bnh   .Lnotrunc
        la    %r2,895
 .Lnotrunc:
-       l     %r4,INITRD_START-PARMAREA(%r12)
+       l     %r4,INITRD_START+ARCH_OFFSET-PARMAREA(%r12)
        clc   0(3,%r4),.L_hdr                  # if it is HDRx
        bz    .Lagain1                         # skip dataset header
        clc   0(3,%r4),.L_eof                  # if it is EOFx
@@ -322,14 +324,14 @@ iplstart:
 # load ramdisk from ipl device
 #      
 .Lagain2:
-       l     %r2,INITRD_START-PARMAREA(%r12)  # load adr. of ramdisk
+       l     %r2,INITRD_START+ARCH_OFFSET-PARMAREA(%r12) # addr of ramdisk
         bas   %r14,.Lloader                    # load ramdisk
-       st    %r2,INITRD_SIZE-PARMAREA(%r12)   # store size of ramdisk
+       st    %r2,INITRD_SIZE+ARCH_OFFSET-PARMAREA(%r12) # store size of ramdisk
         ltr   %r2,%r2
         bnz   .Lrdcont
-        st    %r2,INITRD_START-PARMAREA(%r12)  # no ramdisk found, null it
+        st    %r2,INITRD_START+ARCH_OFFSET-PARMAREA(%r12) # no ramdisk found
 .Lrdcont:
-       l     %r2,INITRD_START-PARMAREA(%r12)
+       l     %r2,INITRD_START+ARCH_OFFSET-PARMAREA(%r12)
 
        clc   0(3,%r2),.L_hdr                  # skip HDRx and EOFx 
        bz    .Lagain2
@@ -432,10 +434,10 @@ start:
        la    %r3,1(%r3)
 .done:
         l     %r1,.memsize
-       st    %r3,0(%r1)
+       st    %r3,ARCH_OFFSET(%r1)
        slr   %r0,%r0
-       st    %r0,INITRD_SIZE-PARMAREA(%r11)
-       st    %r0,INITRD_START-PARMAREA(%r11)
+       st    %r0,INITRD_SIZE+ARCH_OFFSET-PARMAREA(%r11)
+       st    %r0,INITRD_START+ARCH_OFFSET-PARMAREA(%r11)
        j     startup                   # continue with startup
 .tbl:  .long _ebcasc                   # translate table
 .cmd:  .long COMMAND_LINE              # address of command line buffer
@@ -478,304 +480,23 @@ start:
        .byte 0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7 
        .byte 0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff
 
-#
-# startup-code at 0x10000, running in real mode
-# this is called either by the ipl loader or directly by PSW restart
-# or linload or SALIPL
-#
-        .org  0x10000
-startup:basr  %r13,0                     # get base
-.LPG1: l     %r1, .Lget_ipl_device_addr-.LPG1(%r13)
-       basr  %r14, %r1
-       lctl  %c0,%c15,.Lctl-.LPG1(%r13) # load control registers
-       la    %r12,_pstart-.LPG1(%r13)   # pointer to parameter area
-                                        # move IPL device to lowcore
-        mvc   __LC_IPLDEV(4),IPL_DEVICE-PARMAREA(%r12)
-       
-#
-# clear bss memory
-#
-        l     %r2,.Lbss_bgn-.LPG1(%r13) # start of bss
-        l     %r3,.Lbss_end-.LPG1(%r13) # end of bss
-        sr    %r3,%r2                   # length of bss
-        sr    %r4,%r4                   #
-        sr    %r5,%r5                   # set src,length and pad to zero
-        sr    %r0,%r0                   #
-        mvcle %r2,%r4,0                 # clear mem
-        jo    .-4                       # branch back, if not finish
-
-       l     %r2,.Lrcp-.LPG1(%r13)     # Read SCP forced command word
-.Lservicecall:
-       stosm .Lpmask-.LPG1(%r13),0x01  # authorize ext interrupts
-
-       stctl %r0, %r0,.Lcr-.LPG1(%r13) # get cr0
-       la    %r1,0x200                 # set bit 22
-       o     %r1,.Lcr-.LPG1(%r13)      # or old cr0 with r1
-       st    %r1,.Lcr-.LPG1(%r13)
-       lctl  %r0, %r0,.Lcr-.LPG1(%r13) # load modified cr0
-
-       mvc   __LC_EXT_NEW_PSW(8),.Lpcext-.LPG1(%r13) # set postcall psw
-       la    %r1, .Lsclph-.LPG1(%r13)
-       a     %r1,__LC_EXT_NEW_PSW+4    # set handler
-       st    %r1,__LC_EXT_NEW_PSW+4
-
-       la    %r4,_pstart-.LPG1(%r13)   # %r4 is our index for sccb stuff
-       la    %r1, .Lsccb-PARMAREA(%r4) # our sccb
-       .insn rre,0xb2200000,%r2,%r1    # service call
-       ipm   %r1
-       srl   %r1,28                    # get cc code
-       xr    %r3, %r3
-       chi   %r1,3
-       be    .Lfchunk-.LPG1(%r13)      # leave
-       chi   %r1,2
-       be    .Lservicecall-.LPG1(%r13)
-       lpsw  .Lwaitsclp-.LPG1(%r13)
-.Lsclph:
-       lh    %r1,.Lsccbr-PARMAREA(%r4)
-       chi   %r1,0x10                  # 0x0010 is the sucess code
-       je    .Lprocsccb                # let's process the sccb
-       chi   %r1,0x1f0
-       bne   .Lfchunk-.LPG1(%r13)      # unhandled error code
-       c     %r2, .Lrcp-.LPG1(%r13)    # Did we try Read SCP forced
-       bne   .Lfchunk-.LPG1(%r13)      # if no, give up
-       l     %r2, .Lrcp2-.LPG1(%r13)   # try with Read SCP
-       b     .Lservicecall-.LPG1(%r13)
-.Lprocsccb:
-       lhi   %r1,0
-       icm   %r1,3,.Lscpincr1-PARMAREA(%r4) # use this one if != 0
-       jnz   .Lscnd
-       lhi   %r1,0x800                 # otherwise report 2GB
-.Lscnd:
-       lhi   %r3,0x800                 # limit reported memory size to 2GB
-       cr    %r1,%r3
-       jl    .Lno2gb
-       lr    %r1,%r3
-.Lno2gb:
-       xr    %r3,%r3                   # same logic
-       ic    %r3,.Lscpa1-PARMAREA(%r4)
-       chi   %r3,0x00
-       jne   .Lcompmem
-       l     %r3,.Lscpa2-PARMAREA(%r13)
-.Lcompmem:
-       mr    %r2,%r1                   # mem in MB on 128-bit
-       l     %r1,.Lonemb-.LPG1(%r13)
-       mr    %r2,%r1                   # mem size in bytes in %r3
-       b     .Lfchunk-.LPG1(%r13)
-
-       .align 4
-.Lget_ipl_device_addr:
-       .long .Lget_ipl_device
-.Lpmask:
-       .byte 0
-.align 8
-.Lpcext:.long  0x00080000,0x80000000
-.Lcr:
-       .long 0x00                      # place holder for cr0
-.Lwaitsclp:
-       .long 0x020A0000
-       .long .Lsclph
-.Lrcp:
-       .int 0x00120001                 # Read SCP forced code
-.Lrcp2:
-       .int 0x00020001                 # Read SCP code
-.Lonemb:
-       .int 0x100000
-.Lfchunk:
-
-#
-# find memory chunks.
-#
-       lr    %r9,%r3                    # end of mem
-       mvc   __LC_PGM_NEW_PSW(8),.Lpcmem-.LPG1(%r13)
-       la    %r1,1                      # test in increments of 128KB
-       sll   %r1,17
-       l     %r3,.Lmchunk-.LPG1(%r13)   # get pointer to memory_chunk array
-       slr   %r4,%r4                    # set start of chunk to zero
-       slr   %r5,%r5                    # set end of chunk to zero
-       slr   %r6,%r6                    # set access code to zero
-       la    %r10, MEMORY_CHUNKS        # number of chunks
-.Lloop:
-       tprot 0(%r5),0                   # test protection of first byte
-       ipm   %r7
-       srl   %r7,28
-       clr   %r6,%r7                    # compare cc with last access code
-       be    .Lsame-.LPG1(%r13)
-       b     .Lchkmem-.LPG1(%r13)
-.Lsame:
-       ar    %r5,%r1                    # add 128KB to end of chunk
-       bno   .Lloop-.LPG1(%r13)         # r1 < 0x80000000 -> loop
-.Lchkmem:                               # > 2GB or tprot got a program check
-       clr   %r4,%r5                    # chunk size > 0?
-       be    .Lchkloop-.LPG1(%r13)
-       st    %r4,0(%r3)                 # store start address of chunk
-       lr    %r0,%r5
-       slr   %r0,%r4
-       st    %r0,4(%r3)                 # store size of chunk
-       st    %r6,8(%r3)                 # store type of chunk
-       la    %r3,12(%r3)
-       l     %r4,.Lmemsize-.LPG1(%r13)  # address of variable memory_size
-       st    %r5,0(%r4)                 # store last end to memory size
-       ahi   %r10,-1                    # update chunk number
-.Lchkloop:
-       lr    %r6,%r7                    # set access code to last cc
-       # we got an exception or we're starting a new
-       # chunk , we must check if we should
-       # still try to find valid memory (if we detected
-       # the amount of available storage), and if we
-       # have chunks left
-       xr    %r0,%r0
-       clr   %r0,%r9                    # did we detect memory?
-       je    .Ldonemem                  # if not, leave
-       chi   %r10,0                     # do we have chunks left?
-       je    .Ldonemem
-       alr   %r5,%r1                    # add 128KB to end of chunk
-       lr    %r4,%r5                    # potential new chunk
-       clr    %r5,%r9                   # should we go on?
-       jl     .Lloop
-.Ldonemem:             
-        l      %r12,.Lmflags-.LPG1(%r13) # get address of machine_flags
-#
-# find out if we are running under VM
-#
-        stidp  __LC_CPUID               # store cpuid
-       tm     __LC_CPUID,0xff          # running under VM ?
-       bno    .Lnovm-.LPG1(%r13)
-        oi     3(%r12),1                # set VM flag
-.Lnovm:
-        lh     %r0,__LC_CPUID+4         # get cpu version
-        chi    %r0,0x7490               # running on a P/390 ?
-        bne    .Lnop390-.LPG1(%r13)
-        oi     3(%r12),4                # set P/390 flag
-.Lnop390:
-
-#
-# find out if we have an IEEE fpu
-#
-        mvc    __LC_PGM_NEW_PSW(8),.Lpcfpu-.LPG1(%r13)
-       efpc   %r0,0                    # test IEEE extract fpc instruction
-        oi     3(%r12),2                # set IEEE fpu flag
-.Lchkfpu:
-
-#
-# find out if we have the CSP instruction
-#
-       mvc    __LC_PGM_NEW_PSW(8),.Lpccsp-.LPG1(%r13)
-       la     %r0,0
-       lr     %r1,%r0
-       la     %r2,4
-       csp    %r0,%r2                   # Test CSP instruction
-       oi     3(%r12),8                 # set CSP flag
-.Lchkcsp:
-
-#
-# find out if we have the MVPG instruction
-#
-       mvc    __LC_PGM_NEW_PSW(8),.Lpcmvpg-.LPG1(%r13)
-       sr     %r0,%r0
-       la     %r1,0
-       la     %r2,0
-       mvpg   %r1,%r2                   # Test CSP instruction
-       oi     3(%r12),16                # set MVPG flag
-.Lchkmvpg:
-
-#
-# find out if we have the IDTE instruction
-#
-       mvc     __LC_PGM_NEW_PSW(8),.Lpcidte-.LPG1(%r13)
-       .long   0xb2b10000              # store facility list
-       tm      0xc8,0x08               # check bit for clearing-by-ASCE
-       bno     .Lchkidte-.LPG1(%r13)
-       lhi     %r1,2094
-       lhi     %r2,0
-       .long   0xb98e2001
-       oi      3(%r12),0x80            # set IDTE flag
-.Lchkidte:
-
-        lpsw  .Lentry-.LPG1(13)         # jump to _stext in primary-space,
-                                        # virtual and never return ...
-        .align 8
-.Lentry:.long  0x00080000,0x80000000 + _stext
-.Lctl:  .long  0x04b50002               # cr0: various things
-        .long  0                        # cr1: primary space segment table
-        .long  .Lduct                   # cr2: dispatchable unit control table
-        .long  0                        # cr3: instruction authorization
-        .long  0                        # cr4: instruction authorization
-        .long  0xffffffff               # cr5: primary-aste origin
-        .long  0                        # cr6:  I/O interrupts
-        .long  0                        # cr7:  secondary space segment table
-        .long  0                        # cr8:  access registers translation
-        .long  0                        # cr9:  tracing off
-        .long  0                        # cr10: tracing off
-        .long  0                        # cr11: tracing off
-        .long  0                        # cr12: tracing off
-        .long  0                        # cr13: home space segment table
-        .long  0xc0000000               # cr14: machine check handling off
-        .long  0                        # cr15: linkage stack operations
-.Lpcmem:.long  0x00080000,0x80000000 + .Lchkmem
-.Lpcfpu:.long  0x00080000,0x80000000 + .Lchkfpu
-.Lpccsp:.long  0x00080000,0x80000000 + .Lchkcsp
-.Lpcmvpg:.long 0x00080000,0x80000000 + .Lchkmvpg
-.Lpcidte:.long 0x00080000,0x80000000 + .Lchkidte
-.Lmemsize:.long memory_size
-.Lmchunk:.long memory_chunk
-.Lmflags:.long machine_flags
-.Lbss_bgn:  .long  __bss_start
-.Lbss_end:  .long  _end
-
-       .org PARMAREA-64
-.Lduct:        .long 0,0,0,0,0,0,0,0
-       .long 0,0,0,0,0,0,0,0
-
-#
-# params at 10400 (setup.h)
-#
-       .org   PARMAREA
-       .global _pstart
-_pstart:       
-        .long  0,0                      # IPL_DEVICE
-        .long  0,RAMDISK_ORIGIN         # INITRD_START
-        .long  0,RAMDISK_SIZE           # INITRD_SIZE
-
-        .org   COMMAND_LINE
-       .byte  "root=/dev/ram0 ro"
-        .byte  0
-       .org   0x11000
-.Lsccb:
-       .hword 0x1000                   # length, one page
-       .byte 0x00,0x00,0x00
-       .byte 0x80                      # variable response bit set
-.Lsccbr:
-       .hword 0x00                     # response code
-.Lscpincr1:
-       .hword 0x00
-.Lscpa1:
-       .byte 0x00
-       .fill 89,1,0
-.Lscpa2:
-       .int 0x00
-.Lscpincr2:
-       .quad 0x00
-       .fill 3984,1,0
-       .org 0x12000
-       .global _pend
-_pend: 
-
+.macro GET_IPL_DEVICE
 .Lget_ipl_device:
        basr  %r12,0
-.LPG2: l     %r1,0xb8                  # get sid
+.LGID: l     %r1,0xb8                  # get sid
        sll   %r1,15                    # test if subchannel is enabled
        srl   %r1,31
        ltr   %r1,%r1
        bz    0(%r14)                   # subchannel disabled
        l     %r1,0xb8
-       la    %r5,.Lipl_schib-.LPG2(%r12)
+       la    %r5,.Lipl_schib-.LGID(%r12)
        stsch 0(%r5)                    # get schib of subchannel
        bnz   0(%r14)                   # schib not available
        tm    5(%r5),0x01               # devno valid?
        bno   0(%r14)
-       la    %r6,ipl_parameter_flags-.LPG2(%r12)
+       la    %r6,ipl_parameter_flags-.LGID(%r12)
        oi    3(%r6),0x01               # set flag
-       la    %r2,ipl_devno-.LPG2(%r12)
+       la    %r2,ipl_devno-.LGID(%r12)
        mvc   0(2,%r2),6(%r5)           # store devno
        tm    4(%r5),0x80               # qdio capable device?
        bno   0(%r14)
@@ -816,46 +537,10 @@ ipl_parameter_flags:
        .globl ipl_devno
 ipl_devno:
        .word 0
+.endm
 
-#ifdef CONFIG_SHARED_KERNEL
-       .org   0x100000
+#ifdef CONFIG_ARCH_S390X
+#include "head64.S"
+#else
+#include "head31.S"
 #endif
-
-#
-# startup-code, running in virtual mode
-#
-        .globl _stext
-_stext:        basr  %r13,0                    # get base
-.LPG3:
-#
-# Setup stack
-#
-        l     %r15,.Linittu-.LPG3(%r13)
-       mvc   __LC_CURRENT(4),__TI_task(%r15)
-        ahi   %r15,1<<(PAGE_SHIFT+THREAD_ORDER) # init_task_union + THREAD_SIZE
-        st    %r15,__LC_KERNEL_STACK    # set end of kernel stack
-        ahi   %r15,-96
-        xc    __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) # clear backchain
-
-# check control registers
-        stctl  %c0,%c15,0(%r15)
-       oi     2(%r15),0x40             # enable sigp emergency signal
-       oi     0(%r15),0x10             # switch on low address protection
-        lctl   %c0,%c15,0(%r15)
-
-#
-        lam    0,15,.Laregs-.LPG3(%r13) # load access regs needed by uaccess
-        l      %r14,.Lstart-.LPG3(%r13)
-        basr   %r14,%r14                # call start_kernel
-#
-# We returned from start_kernel ?!? PANIK
-#
-        basr  %r13,0
-       lpsw  .Ldw-.(%r13)           # load disabled wait psw
-#
-            .align 8
-.Ldw:      .long  0x000a0000,0x00000000
-.Linittu:   .long  init_thread_union
-.Lstart:    .long  start_kernel
-.Laregs:    .long  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
-
diff --git a/arch/s390/kernel/head31.S b/arch/s390/kernel/head31.S
new file mode 100644 (file)
index 0000000..2d3b089
--- /dev/null
@@ -0,0 +1,336 @@
+/*
+ * arch/s390/kernel/head31.S
+ *
+ * (C) Copyright IBM Corp. 2005
+ *
+ *   Author(s):        Hartmut Penner <hp@de.ibm.com>
+ *             Martin Schwidefsky <schwidefsky@de.ibm.com>
+ *             Rob van der Heij <rvdhei@iae.nl>
+ *             Heiko Carstens <heiko.carstens@de.ibm.com>
+ *
+ */
+
+#
+# startup-code at 0x10000, running in absolute addressing mode
+# this is called either by the ipl loader or directly by PSW restart
+# or linload or SALIPL
+#
+       .org    0x10000
+startup:basr   %r13,0                   # get base
+.LPG1: l       %r1, .Lget_ipl_device_addr-.LPG1(%r13)
+       basr    %r14, %r1
+       lctl    %c0,%c15,.Lctl-.LPG1(%r13) # load control registers
+       la      %r12,_pstart-.LPG1(%r13) # pointer to parameter area
+                                        # move IPL device to lowcore
+       mvc     __LC_IPLDEV(4),IPL_DEVICE-PARMAREA(%r12)
+
+#
+# clear bss memory
+#
+       l       %r2,.Lbss_bgn-.LPG1(%r13) # start of bss
+       l       %r3,.Lbss_end-.LPG1(%r13) # end of bss
+       sr      %r3,%r2                 # length of bss
+       sr      %r4,%r4
+       sr      %r5,%r5                 # set src,length and pad to zero
+       sr      %r0,%r0
+       mvcle   %r2,%r4,0               # clear mem
+       jo      .-4                     # branch back, if not finish
+
+       l       %r2,.Lrcp-.LPG1(%r13)   # Read SCP forced command word
+.Lservicecall:
+       stosm   .Lpmask-.LPG1(%r13),0x01        # authorize ext interrupts
+
+       stctl   %r0, %r0,.Lcr-.LPG1(%r13)       # get cr0
+       la      %r1,0x200               # set bit 22
+       o       %r1,.Lcr-.LPG1(%r13)    # or old cr0 with r1
+       st      %r1,.Lcr-.LPG1(%r13)
+       lctl    %r0, %r0,.Lcr-.LPG1(%r13)       # load modified cr0
+
+       mvc     __LC_EXT_NEW_PSW(8),.Lpcext-.LPG1(%r13) # set postcall psw
+       la      %r1, .Lsclph-.LPG1(%r13)
+       a       %r1,__LC_EXT_NEW_PSW+4  # set handler
+       st      %r1,__LC_EXT_NEW_PSW+4
+
+       la      %r4,_pstart-.LPG1(%r13) # %r4 is our index for sccb stuff
+       la      %r1, .Lsccb-PARMAREA(%r4)       # our sccb
+       .insn   rre,0xb2200000,%r2,%r1  # service call
+       ipm     %r1
+       srl     %r1,28                  # get cc code
+       xr      %r3, %r3
+       chi     %r1,3
+       be      .Lfchunk-.LPG1(%r13)    # leave
+       chi     %r1,2
+       be      .Lservicecall-.LPG1(%r13)
+       lpsw    .Lwaitsclp-.LPG1(%r13)
+.Lsclph:
+       lh      %r1,.Lsccbr-PARMAREA(%r4)
+       chi     %r1,0x10                # 0x0010 is the sucess code
+       je      .Lprocsccb              # let's process the sccb
+       chi     %r1,0x1f0
+       bne     .Lfchunk-.LPG1(%r13)    # unhandled error code
+       c       %r2, .Lrcp-.LPG1(%r13)  # Did we try Read SCP forced
+       bne     .Lfchunk-.LPG1(%r13)    # if no, give up
+       l       %r2, .Lrcp2-.LPG1(%r13) # try with Read SCP
+       b       .Lservicecall-.LPG1(%r13)
+.Lprocsccb:
+       lhi     %r1,0
+       icm     %r1,3,.Lscpincr1-PARMAREA(%r4) # use this one if != 0
+       jnz     .Lscnd
+       lhi     %r1,0x800               # otherwise report 2GB
+.Lscnd:
+       lhi     %r3,0x800               # limit reported memory size to 2GB
+       cr      %r1,%r3
+       jl      .Lno2gb
+       lr      %r1,%r3
+.Lno2gb:
+       xr      %r3,%r3                 # same logic
+       ic      %r3,.Lscpa1-PARMAREA(%r4)
+       chi     %r3,0x00
+       jne     .Lcompmem
+       l       %r3,.Lscpa2-PARMAREA(%r13)
+.Lcompmem:
+       mr      %r2,%r1                 # mem in MB on 128-bit
+       l       %r1,.Lonemb-.LPG1(%r13)
+       mr      %r2,%r1                 # mem size in bytes in %r3
+       b       .Lfchunk-.LPG1(%r13)
+
+       .align 4
+.Lget_ipl_device_addr:
+       .long   .Lget_ipl_device
+.Lpmask:
+       .byte   0
+.align 8
+.Lpcext:.long  0x00080000,0x80000000
+.Lcr:
+       .long   0x00                    # place holder for cr0
+.Lwaitsclp:
+       .long 0x010a0000,0x80000000 + .Lsclph
+.Lrcp:
+       .int    0x00120001              # Read SCP forced code
+.Lrcp2:
+       .int    0x00020001              # Read SCP code
+.Lonemb:
+       .int    0x100000
+.Lfchunk:
+
+#
+# find memory chunks.
+#
+       lr      %r9,%r3                 # end of mem
+       mvc     __LC_PGM_NEW_PSW(8),.Lpcmem-.LPG1(%r13)
+       la      %r1,1                   # test in increments of 128KB
+       sll     %r1,17
+       l       %r3,.Lmchunk-.LPG1(%r13) # get pointer to memory_chunk array
+       slr     %r4,%r4                 # set start of chunk to zero
+       slr     %r5,%r5                 # set end of chunk to zero
+       slr     %r6,%r6                 # set access code to zero
+       la      %r10, MEMORY_CHUNKS     # number of chunks
+.Lloop:
+       tprot   0(%r5),0                # test protection of first byte
+       ipm     %r7
+       srl     %r7,28
+       clr     %r6,%r7                 # compare cc with last access code
+       be      .Lsame-.LPG1(%r13)
+       b       .Lchkmem-.LPG1(%r13)
+.Lsame:
+       ar      %r5,%r1                 # add 128KB to end of chunk
+       bno     .Lloop-.LPG1(%r13)      # r1 < 0x80000000 -> loop
+.Lchkmem:                              # > 2GB or tprot got a program check
+       clr     %r4,%r5                 # chunk size > 0?
+       be      .Lchkloop-.LPG1(%r13)
+       st      %r4,0(%r3)              # store start address of chunk
+       lr      %r0,%r5
+       slr     %r0,%r4
+       st      %r0,4(%r3)              # store size of chunk
+       st      %r6,8(%r3)              # store type of chunk
+       la      %r3,12(%r3)
+       l       %r4,.Lmemsize-.LPG1(%r13)        # address of variable memory_size
+       st      %r5,0(%r4)              # store last end to memory size
+       ahi     %r10,-1                 # update chunk number
+.Lchkloop:
+       lr      %r6,%r7                 # set access code to last cc
+       # we got an exception or we're starting a new
+       # chunk , we must check if we should
+       # still try to find valid memory (if we detected
+       # the amount of available storage), and if we
+       # have chunks left
+       xr      %r0,%r0
+       clr     %r0,%r9                 # did we detect memory?
+       je      .Ldonemem               # if not, leave
+       chi     %r10,0                  # do we have chunks left?
+       je      .Ldonemem
+       alr     %r5,%r1                 # add 128KB to end of chunk
+       lr      %r4,%r5                 # potential new chunk
+       clr     %r5,%r9                 # should we go on?
+       jl      .Lloop
+.Ldonemem:
+       l       %r12,.Lmflags-.LPG1(%r13) # get address of machine_flags
+#
+# find out if we are running under VM
+#
+       stidp   __LC_CPUID              # store cpuid
+       tm      __LC_CPUID,0xff         # running under VM ?
+       bno     .Lnovm-.LPG1(%r13)
+       oi      3(%r12),1               # set VM flag
+.Lnovm:
+       lh      %r0,__LC_CPUID+4        # get cpu version
+       chi     %r0,0x7490              # running on a P/390 ?
+       bne     .Lnop390-.LPG1(%r13)
+       oi      3(%r12),4               # set P/390 flag
+.Lnop390:
+
+#
+# find out if we have an IEEE fpu
+#
+       mvc     __LC_PGM_NEW_PSW(8),.Lpcfpu-.LPG1(%r13)
+       efpc    %r0,0                   # test IEEE extract fpc instruction
+       oi      3(%r12),2               # set IEEE fpu flag
+.Lchkfpu:
+
+#
+# find out if we have the CSP instruction
+#
+       mvc      __LC_PGM_NEW_PSW(8),.Lpccsp-.LPG1(%r13)
+       la       %r0,0
+       lr      %r1,%r0
+       la      %r2,4
+       csp     %r0,%r2                 # Test CSP instruction
+       oi      3(%r12),8               # set CSP flag
+.Lchkcsp:
+
+#
+# find out if we have the MVPG instruction
+#
+       mvc     __LC_PGM_NEW_PSW(8),.Lpcmvpg-.LPG1(%r13)
+       sr      %r0,%r0
+       la      %r1,0
+       la      %r2,0
+       mvpg    %r1,%r2                 # Test CSP instruction
+       oi      3(%r12),16              # set MVPG flag
+.Lchkmvpg:
+
+#
+# find out if we have the IDTE instruction
+#
+       mvc     __LC_PGM_NEW_PSW(8),.Lpcidte-.LPG1(%r13)
+       .long   0xb2b10000              # store facility list
+       tm      0xc8,0x08               # check bit for clearing-by-ASCE
+       bno     .Lchkidte-.LPG1(%r13)
+       lhi     %r1,2094
+       lhi     %r2,0
+       .long   0xb98e2001
+       oi      3(%r12),0x80            # set IDTE flag
+.Lchkidte:
+
+       lpsw  .Lentry-.LPG1(13)         # jump to _stext in primary-space,
+                                       # virtual and never return ...
+       .align  8
+.Lentry:.long  0x00080000,0x80000000 + _stext
+.Lctl: .long   0x04b50002              # cr0: various things
+       .long   0                       # cr1: primary space segment table
+       .long   .Lduct                  # cr2: dispatchable unit control table
+       .long   0                       # cr3: instruction authorization
+       .long   0                       # cr4: instruction authorization
+       .long   0xffffffff              # cr5: primary-aste origin
+       .long   0                       # cr6:  I/O interrupts
+       .long   0                       # cr7:  secondary space segment table
+       .long   0                       # cr8:  access registers translation
+       .long   0                       # cr9:  tracing off
+       .long   0                       # cr10: tracing off
+       .long   0                       # cr11: tracing off
+       .long   0                       # cr12: tracing off
+       .long   0                       # cr13: home space segment table
+       .long   0xc0000000              # cr14: machine check handling off
+       .long   0                       # cr15: linkage stack operations
+.Lpcmem:.long  0x00080000,0x80000000 + .Lchkmem
+.Lpcfpu:.long  0x00080000,0x80000000 + .Lchkfpu
+.Lpccsp:.long  0x00080000,0x80000000 + .Lchkcsp
+.Lpcmvpg:.long 0x00080000,0x80000000 + .Lchkmvpg
+.Lpcidte:.long 0x00080000,0x80000000 + .Lchkidte
+.Lmemsize:.long memory_size
+.Lmchunk:.long memory_chunk
+.Lmflags:.long machine_flags
+.Lbss_bgn:  .long __bss_start
+.Lbss_end:  .long _end
+
+       .org    PARMAREA-64
+.Lduct:        .long   0,0,0,0,0,0,0,0
+       .long   0,0,0,0,0,0,0,0
+
+#
+# params at 10400 (setup.h)
+#
+       .org    PARMAREA
+       .global _pstart
+_pstart:
+       .long   0,0                     # IPL_DEVICE
+       .long   0,RAMDISK_ORIGIN        # INITRD_START
+       .long   0,RAMDISK_SIZE          # INITRD_SIZE
+
+       .org    COMMAND_LINE
+       .byte   "root=/dev/ram0 ro"
+       .byte   0
+       .org    0x11000
+.Lsccb:
+       .hword  0x1000                  # length, one page
+       .byte   0x00,0x00,0x00
+       .byte   0x80                    # variable response bit set
+.Lsccbr:
+       .hword  0x00                    # response code
+.Lscpincr1:
+       .hword  0x00
+.Lscpa1:
+       .byte   0x00
+       .fill   89,1,0
+.Lscpa2:
+       .int    0x00
+.Lscpincr2:
+       .quad   0x00
+       .fill   3984,1,0
+       .org    0x12000
+       .global _pend
+_pend:
+
+       GET_IPL_DEVICE
+
+#ifdef CONFIG_SHARED_KERNEL
+       .org    0x100000
+#endif
+
+#
+# startup-code, running in virtual mode
+#
+       .globl  _stext
+_stext:        basr    %r13,0                  # get base
+.LPG3:
+#
+# Setup stack
+#
+       l       %r15,.Linittu-.LPG3(%r13)
+       mvc     __LC_CURRENT(4),__TI_task(%r15)
+       ahi     %r15,1<<(PAGE_SHIFT+THREAD_ORDER) # init_task_union+THREAD_SIZE
+       st      %r15,__LC_KERNEL_STACK  # set end of kernel stack
+       ahi     %r15,-96
+       xc      __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) # clear backchain
+
+# check control registers
+       stctl   %c0,%c15,0(%r15)
+       oi      2(%r15),0x40            # enable sigp emergency signal
+       oi      0(%r15),0x10            # switch on low address protection
+       lctl    %c0,%c15,0(%r15)
+
+#
+       lam     0,15,.Laregs-.LPG3(%r13) # load access regs needed by uaccess
+       l       %r14,.Lstart-.LPG3(%r13)
+       basr    %r14,%r14               # call start_kernel
+#
+# We returned from start_kernel ?!? PANIK
+#
+       basr    %r13,0
+       lpsw    .Ldw-.(%r13)            # load disabled wait psw
+#
+       .align  8
+.Ldw:  .long   0x000a0000,0x00000000
+.Linittu:.long init_thread_union
+.Lstart:.long  start_kernel
+.Laregs:.long  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
index 193aafa72f54a200158d6320728b0ca0b3037654..f08c06f45d5ceea01fcb70ab3051037af13fcf70 100644 (file)
 /*
- *  arch/s390/kernel/head.S
+ * arch/s390/kernel/head64.S
  *
- *  S390 version
- *    Copyright (C) 1999,2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
- *    Author(s): Hartmut Penner (hp@de.ibm.com),
- *               Martin Schwidefsky (schwidefsky@de.ibm.com),
- *               Rob van der Heij (rvdhei@iae.nl)
+ * (C) Copyright IBM Corp. 1999,2005
+ *
+ *   Author(s):        Hartmut Penner <hp@de.ibm.com>
+ *             Martin Schwidefsky <schwidefsky@de.ibm.com>
+ *             Rob van der Heij <rvdhei@iae.nl>
+ *             Heiko Carstens <heiko.carstens@de.ibm.com>
  *
- * There are 5 different IPL methods
- *  1) load the image directly into ram at address 0 and do an PSW restart
- *  2) linload will load the image from address 0x10000 to memory 0x10000
- *     and start the code thru LPSW 0x0008000080010000 (VM only, deprecated)
- *  3) generate the tape ipl header, store the generated image on a tape
- *     and ipl from it
- *     In case of SL tape you need to IPL 5 times to get past VOL1 etc
- *  4) generate the vm reader ipl header, move the generated image to the
- *     VM reader (use option NOH!) and do a ipl from reader (VM only)
- *  5) direct call of start by the SALIPL loader
- *  We use the cpuid to distinguish between VM and native ipl
- *  params for kernel are pushed to 0x10400 (see setup.h)
-
-    Changes: 
-    Okt 25 2000 <rvdheij@iae.nl>
-       added code to skip HDR and EOF to allow SL tape IPL (5 retries)
-       changed first CCW from rewind to backspace block
-
  */
 
-#include <linux/config.h>
-#include <asm/setup.h>
-#include <asm/lowcore.h>
-#include <asm/asm-offsets.h>
-#include <asm/thread_info.h>
-#include <asm/page.h>
-
-#ifndef CONFIG_IPL
-        .org   0
-        .long  0x00080000,0x80000000+startup   # Just a restart PSW
-#else
-#ifdef CONFIG_IPL_TAPE
-#define IPL_BS 1024
-        .org   0
-        .long  0x00080000,0x80000000+iplstart  # The first 24 bytes are loaded
-        .long  0x27000000,0x60000001           # by ipl to addresses 0-23.
-        .long  0x02000000,0x20000000+IPL_BS    # (a PSW and two CCWs).
-        .long  0x00000000,0x00000000           # external old psw
-        .long  0x00000000,0x00000000           # svc old psw
-        .long  0x00000000,0x00000000           # program check old psw
-        .long  0x00000000,0x00000000           # machine check old psw
-        .long  0x00000000,0x00000000           # io old psw
-        .long  0x00000000,0x00000000
-        .long  0x00000000,0x00000000
-        .long  0x00000000,0x00000000
-        .long  0x000a0000,0x00000058           # external new psw
-        .long  0x000a0000,0x00000060           # svc new psw
-        .long  0x000a0000,0x00000068           # program check new psw
-        .long  0x000a0000,0x00000070           # machine check new psw
-        .long  0x00080000,0x80000000+.Lioint   # io new psw
-
-        .org   0x100
-#
-# subroutine for loading from tape
-# Paramters:   
-#  R1 = device number
-#  R2 = load address
-.Lloader:      
-        st    %r14,.Lldret
-        la    %r3,.Lorbread                    # r3 = address of orb 
-       la    %r5,.Lirb                        # r5 = address of irb
-        st    %r2,.Lccwread+4                  # initialize CCW data addresses
-        lctl  %c6,%c6,.Lcr6               
-        slr   %r2,%r2
-.Lldlp:
-        la    %r6,3                            # 3 retries
-.Lssch:
-        ssch  0(%r3)                           # load chunk of IPL_BS bytes
-        bnz   .Llderr
-.Lw4end:
-        bas   %r14,.Lwait4io
-        tm    8(%r5),0x82                      # do we have a problem ?
-        bnz   .Lrecov
-        slr   %r7,%r7
-        icm   %r7,3,10(%r5)                    # get residual count
-        lcr   %r7,%r7
-        la    %r7,IPL_BS(%r7)                  # IPL_BS-residual=#bytes read
-        ar    %r2,%r7                          # add to total size
-        tm    8(%r5),0x01                      # found a tape mark ?
-        bnz   .Ldone
-        l     %r0,.Lccwread+4                  # update CCW data addresses
-        ar    %r0,%r7
-        st    %r0,.Lccwread+4                
-        b     .Lldlp
-.Ldone:
-        l     %r14,.Lldret
-        br    %r14                             # r2 contains the total size
-.Lrecov:
-        bas   %r14,.Lsense                     # do the sensing
-        bct   %r6,.Lssch                       # dec. retry count & branch
-        b     .Llderr
-#
-# Sense subroutine
-#
-.Lsense:
-        st    %r14,.Lsnsret
-        la    %r7,.Lorbsense              
-        ssch  0(%r7)                           # start sense command
-        bnz   .Llderr
-        bas   %r14,.Lwait4io
-        l     %r14,.Lsnsret
-        tm    8(%r5),0x82                      # do we have a problem ?
-        bnz   .Llderr
-        br    %r14
-#
-# Wait for interrupt subroutine
-#
-.Lwait4io:
-        lpsw  .Lwaitpsw                 
-.Lioint:
-        c     %r1,0xb8                         # compare subchannel number
-        bne   .Lwait4io
-        tsch  0(%r5)
-        slr   %r0,%r0
-        tm    8(%r5),0x82                      # do we have a problem ?
-        bnz   .Lwtexit
-        tm    8(%r5),0x04                      # got device end ?
-        bz    .Lwait4io
-.Lwtexit:
-        br    %r14
-.Llderr:
-        lpsw  .Lcrash              
-
-        .align 8
-.Lorbread:
-       .long  0x00000000,0x0080ff00,.Lccwread
-        .align 8
-.Lorbsense:
-        .long  0x00000000,0x0080ff00,.Lccwsense
-        .align 8
-.Lccwread:
-        .long  0x02200000+IPL_BS,0x00000000
-.Lccwsense:
-        .long  0x04200001,0x00000000
-.Lwaitpsw:
-       .long  0x020a0000,0x80000000+.Lioint
-
-.Lirb: .long  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
-.Lcr6:  .long  0xff000000
-        .align 8
-.Lcrash:.long  0x000a0000,0x00000000
-.Lldret:.long  0
-.Lsnsret: .long 0
-#endif  /* CONFIG_IPL_TAPE */
-
-#ifdef CONFIG_IPL_VM
-#define IPL_BS 0x730
-        .org   0
-        .long  0x00080000,0x80000000+iplstart  # The first 24 bytes are loaded
-        .long  0x02000018,0x60000050           # by ipl to addresses 0-23.
-        .long  0x02000068,0x60000050           # (a PSW and two CCWs).
-        .fill  80-24,1,0x40                    # bytes 24-79 are discarded !!
-        .long  0x020000f0,0x60000050           # The next 160 byte are loaded
-        .long  0x02000140,0x60000050           # to addresses 0x18-0xb7
-        .long  0x02000190,0x60000050           # They form the continuation
-        .long  0x020001e0,0x60000050           # of the CCW program started
-        .long  0x02000230,0x60000050           # by ipl and load the range
-        .long  0x02000280,0x60000050           # 0x0f0-0x730 from the image
-        .long  0x020002d0,0x60000050           # to the range 0x0f0-0x730
-        .long  0x02000320,0x60000050           # in memory. At the end of
-        .long  0x02000370,0x60000050           # the channel program the PSW
-        .long  0x020003c0,0x60000050           # at location 0 is loaded.
-        .long  0x02000410,0x60000050           # Initial processing starts
-        .long  0x02000460,0x60000050           # at 0xf0 = iplstart.
-        .long  0x020004b0,0x60000050
-        .long  0x02000500,0x60000050
-        .long  0x02000550,0x60000050
-        .long  0x020005a0,0x60000050
-        .long  0x020005f0,0x60000050
-        .long  0x02000640,0x60000050
-        .long  0x02000690,0x60000050
-        .long  0x020006e0,0x20000050
-
-        .org   0xf0
-#
-# subroutine for loading cards from the reader
-#
-.Lloader:      
-       la    %r3,.Lorb                        # r2 = address of orb into r2
-       la    %r5,.Lirb                        # r4 = address of irb
-        la    %r6,.Lccws              
-        la    %r7,20
-.Linit:
-        st    %r2,4(%r6)                       # initialize CCW data addresses
-        la    %r2,0x50(%r2)
-        la    %r6,8(%r6)
-        bct   7,.Linit
-
-        lctl  %c6,%c6,.Lcr6                    # set IO subclass mask
-       slr   %r2,%r2
-.Lldlp:
-        ssch  0(%r3)                           # load chunk of 1600 bytes
-        bnz   .Llderr
-.Lwait4irq:
-        mvc   0x78(8),.Lnewpsw                 # set up IO interrupt psw
-        lpsw  .Lwaitpsw              
-.Lioint:
-        c     %r1,0xb8                         # compare subchannel number
-       bne   .Lwait4irq
-       tsch  0(%r5)
-
-       slr   %r0,%r0
-       ic    %r0,8(%r5)                       # get device status
-       chi   %r0,8                            # channel end ?
-       be    .Lcont
-       chi   %r0,12                           # channel end + device end ?
-       be    .Lcont
-
-        l     %r0,4(%r5)
-        s     %r0,8(%r3)                       # r0/8 = number of ccws executed
-        mhi   %r0,10                           # *10 = number of bytes in ccws
-        lh    %r3,10(%r5)                      # get residual count
-        sr    %r0,%r3                          # #ccws*80-residual=#bytes read
-       ar    %r2,%r0
-       
-        br    %r14                             # r2 contains the total size
-
-.Lcont:
-       ahi   %r2,0x640                        # add 0x640 to total size
-        la    %r6,.Lccws             
-        la    %r7,20
-.Lincr:
-        l     %r0,4(%r6)                       # update CCW data addresses
-        ahi   %r0,0x640
-        st    %r0,4(%r6)
-        ahi   %r6,8
-        bct   7,.Lincr
-
-        b     .Lldlp
-.Llderr:
-        lpsw  .Lcrash              
-
-        .align 8
-.Lorb: .long  0x00000000,0x0080ff00,.Lccws
-.Lirb: .long  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
-.Lcr6:  .long  0xff000000
-.Lloadp:.long  0,0
-        .align 8
-.Lcrash:.long  0x000a0000,0x00000000
-.Lnewpsw:
-        .long  0x00080000,0x80000000+.Lioint
-.Lwaitpsw:
-        .long  0x020a0000,0x80000000+.Lioint
-
-        .align 8
-.Lccws: .rept  19
-        .long  0x02600050,0x00000000
-        .endr
-        .long  0x02200050,0x00000000
-#endif  /* CONFIG_IPL_VM */
-
-iplstart:
-        lh    %r1,0xb8                         # test if subchannel number
-        bct   %r1,.Lnoload                     #  is valid
-       l     %r1,0xb8                         # load ipl subchannel number
-        la    %r2,IPL_BS                       # load start address
-        bas   %r14,.Lloader                    # load rest of ipl image
-        larl  %r12,_pstart                     # pointer to parameter area
-        st    %r1,IPL_DEVICE+4-PARMAREA(%r12)  # store ipl device number
-
-#
-# load parameter file from ipl device
 #
-.Lagain1:
-       l     %r2,INITRD_START+4-PARMAREA(%r12)# use ramdisk location as temp
-        bas   %r14,.Lloader                    # load parameter file
-        ltr   %r2,%r2                          # got anything ?
-        bz    .Lnopf
-       chi   %r2,895
-       bnh   .Lnotrunc
-       la    %r2,895
-.Lnotrunc:
-       l     %r4,INITRD_START+4-PARMAREA(%r12)
-       clc   0(3,%r4),.L_hdr                  # if it is HDRx
-       bz    .Lagain1                         # skip dataset header
-       clc   0(3,%r4),.L_eof                  # if it is EOFx
-       bz    .Lagain1                         # skip dateset trailer
-        la    %r5,0(%r4,%r2)
-        lr    %r3,%r2
-.Lidebc:
-        tm    0(%r5),0x80                      # high order bit set ?
-        bo    .Ldocv                           #  yes -> convert from EBCDIC
-        ahi   %r5,-1
-        bct   %r3,.Lidebc
-        b     .Lnocv
-.Ldocv:
-        l     %r3,.Lcvtab
-        tr    0(256,%r4),0(%r3)                # convert parameters to ascii
-        tr    256(256,%r4),0(%r3)
-        tr    512(256,%r4),0(%r3)
-        tr    768(122,%r4),0(%r3)
-.Lnocv: la    %r3,COMMAND_LINE-PARMAREA(%r12)  # load adr. of command line
-       mvc   0(256,%r3),0(%r4)
-       mvc   256(256,%r3),256(%r4)
-       mvc   512(256,%r3),512(%r4)
-       mvc   768(122,%r3),768(%r4)
-        slr   %r0,%r0
-        b     .Lcntlp
-.Ldelspc:
-        ic    %r0,0(%r2,%r3)
-        chi   %r0,0x20                         # is it a space ?
-        be    .Lcntlp
-        ahi   %r2,1
-        b     .Leolp
-.Lcntlp:
-        brct  %r2,.Ldelspc
-.Leolp:
-        slr   %r0,%r0
-        stc   %r0,0(%r2,%r3)                   # terminate buffer
-.Lnopf:
-
-#
-# load ramdisk from ipl device
-#
-.Lagain2:
-       l     %r2,INITRD_START+4-PARMAREA(%r12)# load adr. of ramdisk
-        bas   %r14,.Lloader                    # load ramdisk
-       st    %r2,INITRD_SIZE+4-PARMAREA(%r12) # store size of ramdisk
-        ltr   %r2,%r2
-        bnz   .Lrdcont
-        st    %r2,INITRD_START+4-PARMAREA(%r12)# no ramdisk found, null it
-.Lrdcont:
-       l     %r2,INITRD_START+4-PARMAREA(%r12)
-       clc   0(3,%r2),.L_hdr                  # skip HDRx and EOFx 
-       bz    .Lagain2
-       clc   0(3,%r2),.L_eof
-       bz    .Lagain2
-
-#ifdef CONFIG_IPL_VM
-#
-# reset files in VM reader
-#
-        stidp __LC_CPUID                       # store cpuid
-       tm    __LC_CPUID,0xff                  # running VM ?
-       bno   .Lnoreset
-        la    %r2,.Lreset              
-        lhi   %r3,26
-       diag  %r2,%r3,8
-       la    %r5,.Lirb
-       stsch 0(%r5)                           # check if irq is pending
-       tm    30(%r5),0x0f                     # by verifying if any of the
-       bnz   .Lwaitforirq                     # activity or status control
-       tm    31(%r5),0xff                     # bits is set in the schib
-       bz    .Lnoreset
-.Lwaitforirq:
-       mvc   0x78(8),.Lrdrnewpsw              # set up IO interrupt psw
-.Lwaitrdrirq:
-       lpsw  .Lrdrwaitpsw
-.Lrdrint:
-       c     %r1,0xb8                         # compare subchannel number
-       bne   .Lwaitrdrirq
-       la    %r5,.Lirb
-       tsch  0(%r5)
-.Lnoreset:
-       b     .Lnoload
-
-       .align 8
-.Lrdrnewpsw:
-       .long  0x00080000,0x80000000+.Lrdrint
-.Lrdrwaitpsw:
-       .long  0x020a0000,0x80000000+.Lrdrint
-#endif
-
-#
-# everything loaded, go for it
-#
-.Lnoload:
-        l     %r1,.Lstartup
-        br    %r1
-
-.Lstartup: .long startup
-.Lcvtab:.long  _ebcasc                         # ebcdic to ascii table
-.Lreset:.byte  0xc3,0xc8,0xc1,0xd5,0xc7,0xc5,0x40,0xd9,0xc4,0xd9,0x40
-        .byte  0xc1,0xd3,0xd3,0x40,0xd2,0xc5,0xc5,0xd7,0x40,0xd5,0xd6
-        .byte  0xc8,0xd6,0xd3,0xc4             # "change rdr all keep nohold"
-.L_eof: .long  0xc5d6c600       /* C'EOF' */
-.L_hdr: .long  0xc8c4d900       /* C'HDR' */
-#endif  /* CONFIG_IPL */
-
-#
-# SALIPL loader support. Based on a patch by Rob van der Heij.
-# This entry point is called directly from the SALIPL loader and
-# doesn't need a builtin ipl record.
-#
-        .org  0x800
-       .globl start
-start:
-       stm   %r0,%r15,0x07b0           # store registers
-       basr  %r12,%r0
-.base:
-       l     %r11,.parm
-       l     %r8,.cmd                  # pointer to command buffer
-
-       ltr   %r9,%r9                   # do we have SALIPL parameters?
-       bp    .sk8x8
-
-       mvc   0(64,%r8),0x00b0          # copy saved registers
-       xc    64(240-64,%r8),0(%r8)     # remainder of buffer
-       tr    0(64,%r8),.lowcase        
-       b     .gotr
-.sk8x8:
-       mvc   0(240,%r8),0(%r9)         # copy iplparms into buffer
-.gotr:
-       l     %r10,.tbl                 # EBCDIC to ASCII table
-       tr    0(240,%r8),0(%r10)
-       stidp __LC_CPUID                # Are we running on VM maybe
-       cli   __LC_CPUID,0xff
-       bnz   .test
-       .long 0x83300060                # diag 3,0,x'0060' - storage size
-       b     .done
-.test:
-       mvc   0x68(8),.pgmnw            # set up pgm check handler
-       l     %r2,.fourmeg
-       lr    %r3,%r2
-       bctr  %r3,%r0                   # 4M-1
-.loop:  iske  %r0,%r3
-       ar    %r3,%r2
-.pgmx:
-       sr    %r3,%r2
-       la    %r3,1(%r3)
-.done:
-       l     %r1,.memsize
-       st    %r3,4(%r1)
-       slr   %r0,%r0
-       st    %r0,INITRD_SIZE+4-PARMAREA(%r11)
-       st    %r0,INITRD_START+4-PARMAREA(%r11)
-       j     startup                   # continue with startup
-.tbl:  .long _ebcasc                   # translate table
-.cmd:  .long COMMAND_LINE              # address of command line buffer
-.parm: .long PARMAREA
-.fourmeg: .long 0x00400000             # 4M
-.pgmnw:        .long 0x00080000,.pgmx
-.memsize: .long memory_size
-.lowcase:
-       .byte 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07 
-       .byte 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f
-       .byte 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17 
-       .byte 0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f
-       .byte 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27 
-       .byte 0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f
-       .byte 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37 
-       .byte 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f
-       .byte 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47 
-       .byte 0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f
-       .byte 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57 
-       .byte 0x58,0x59,0x5a,0x5b,0x5c,0x5d,0x5e,0x5f
-       .byte 0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67 
-       .byte 0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f
-       .byte 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77 
-       .byte 0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7f
-
-       .byte 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87 
-       .byte 0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f
-       .byte 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97 
-       .byte 0x98,0x99,0x9a,0x9b,0x9c,0x9d,0x9e,0x9f
-       .byte 0xa0,0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7 
-       .byte 0xa8,0xa9,0xaa,0xab,0xac,0xad,0xae,0xaf
-       .byte 0xb0,0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7 
-       .byte 0xb8,0xb9,0xba,0xbb,0xbc,0xbd,0xbe,0xbf
-       .byte 0xc0,0x81,0x82,0x83,0x84,0x85,0x86,0x87   # .abcdefg 
-       .byte 0x88,0x89,0xca,0xcb,0xcc,0xcd,0xce,0xcf   # hi
-       .byte 0xd0,0x91,0x92,0x93,0x94,0x95,0x96,0x97   # .jklmnop
-       .byte 0x98,0x99,0xda,0xdb,0xdc,0xdd,0xde,0xdf   # qr
-       .byte 0xe0,0xe1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7   # ..stuvwx
-       .byte 0xa8,0xa9,0xea,0xeb,0xec,0xed,0xee,0xef   # yz
-       .byte 0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7 
-       .byte 0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff
-
-#
-# startup-code at 0x10000, running in real mode
+# startup-code at 0x10000, running in absolute addressing mode
 # this is called either by the ipl loader or directly by PSW restart
 # or linload or SALIPL
 #
@@ -530,7 +65,7 @@ startup:basr  %r13,0                     # get base
        be    .Lfchunk-.LPG1(%r13)      # leave
        chi   %r1,2
        be    .Lservicecall-.LPG1(%r13)
-       lpsw  .Lwaitsclp-.LPG1(%r13)
+       lpswe .Lwaitsclp-.LPG1(%r13)
 .Lsclph:
        lh    %r1,.Lsccbr-PARMAREA(%r4)
        chi   %r1,0x10                  # 0x0010 is the sucess code
@@ -567,8 +102,7 @@ startup:basr  %r13,0                     # get base
 .Lcr:
        .quad 0x00  # place holder for cr0
 .Lwaitsclp:
-       .long 0x020A0000
-       .quad .Lsclph
+       .quad  0x0102000180000000,.Lsclph
 .Lrcp:
        .int 0x00120001 # Read SCP forced code
 .Lrcp2:
@@ -751,62 +285,7 @@ _pstart:
        .global _pend
 _pend: 
 
-.Lget_ipl_device:
-       basr  %r12,0
-.LPG2: l     %r1,0xb8                  # get sid
-       sll   %r1,15                    # test if subchannel is enabled
-       srl   %r1,31
-       ltr   %r1,%r1
-       bz    0(%r14)                   # subchannel disabled
-       l     %r1,0xb8
-       la    %r5,.Lipl_schib-.LPG2(%r12)
-       stsch 0(%r5)                    # get schib of subchannel
-       bnz   0(%r14)                   # schib not available
-       tm    5(%r5),0x01               # devno valid?
-       bno   0(%r14)
-       la    %r6,ipl_parameter_flags-.LPG2(%r12)
-       oi    3(%r6),0x01               # set flag
-       la    %r2,ipl_devno-.LPG2(%r12)
-       mvc   0(2,%r2),6(%r5)           # store devno
-       tm    4(%r5),0x80               # qdio capable device?
-       bno   0(%r14)
-       oi    3(%r6),0x02               # set flag
-
-       # copy ipl parameters
-
-       lhi   %r0,4096
-       l     %r2,20(%r0)               # get address of parameter list
-       lhi   %r3,IPL_PARMBLOCK_ORIGIN
-       st    %r3,20(%r0)
-       lhi   %r4,1
-       cr    %r2,%r3                   # start parameters < destination ?
-       jl    0f
-       lhi   %r1,1                     # copy direction is upwards
-       j     1f
-0:     lhi   %r1,-1                    # copy direction is downwards
-       ar    %r2,%r0
-       ar    %r3,%r0
-       ar    %r2,%r1
-       ar    %r3,%r1
-1:     mvc   0(1,%r3),0(%r2)           # finally copy ipl parameters
-       ar    %r3,%r1
-       ar    %r2,%r1
-       sr    %r0,%r4
-       jne   1b
-       b     0(%r14)
-
-       .align 4
-.Lipl_schib:
-       .rept 13
-       .long 0
-       .endr
-
-       .globl ipl_parameter_flags
-ipl_parameter_flags:
-       .long 0
-       .globl ipl_devno
-ipl_devno:
-       .word 0
+       GET_IPL_DEVICE
 
 #ifdef CONFIG_SHARED_KERNEL
        .org   0x100000
index 9a1d95894f3df95e8201f210894ab88dcf651e07..c36353e8c1404b22ae5dfbd8f0b0bd8f1a8214b8 100644 (file)
@@ -237,6 +237,8 @@ int sysctl_hz_timer = 1;
  */
 static inline void stop_hz_timer(void)
 {
+       unsigned long flags;
+       unsigned long seq, next;
        __u64 timer, todval;
 
        if (sysctl_hz_timer != 0)
@@ -257,7 +259,11 @@ static inline void stop_hz_timer(void)
         * This cpu is going really idle. Set up the clock comparator
         * for the next event.
         */
-       timer = (__u64) (next_timer_interrupt() - jiffies) + jiffies_64;
+       next = next_timer_interrupt();
+       do {
+               seq = read_seqbegin_irqsave(&xtime_lock, flags);
+               timer = (__u64)(next - jiffies) + jiffies_64;
+       } while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
        todval = -1ULL;
        /* Be careful about overflows. */
        if (timer < (-1ULL / CLK_TICKS_PER_JIFFY)) {
index 6b8703ec2ae66edf93f527a44d4ecaf2af108f42..c5bd36fae56b29294db4953a5375441a5e047720 100644 (file)
@@ -57,7 +57,6 @@ int sysctl_userprocess_debug = 0;
 
 extern pgm_check_handler_t do_protection_exception;
 extern pgm_check_handler_t do_dat_exception;
-extern pgm_check_handler_t do_pseudo_page_fault;
 #ifdef CONFIG_PFAULT
 extern int pfault_init(void);
 extern void pfault_fini(void);
@@ -676,20 +675,6 @@ asmlinkage void kernel_stack_overflow(struct pt_regs * regs)
        panic("Corrupt kernel stack, can't continue.");
 }
 
-#ifndef CONFIG_ARCH_S390X
-static int
-pagex_reboot_event(struct notifier_block *this, unsigned long event, void *ptr)
-{
-       if (MACHINE_IS_VM)
-               cpcmd("SET PAGEX OFF", NULL, 0, NULL);
-       return NOTIFY_DONE;
-}
-
-static struct notifier_block pagex_reboot_notifier = {
-       .notifier_call = &pagex_reboot_event,
-};
-#endif
-
 /* init is done in lowcore.S and head.S */
 
 void __init trap_init(void)
@@ -717,9 +702,7 @@ void __init trap_init(void)
         pgm_check_table[0x11] = &do_dat_exception;
         pgm_check_table[0x12] = &translation_exception;
         pgm_check_table[0x13] = &special_op_exception;
-#ifndef CONFIG_ARCH_S390X
-       pgm_check_table[0x14] = &do_pseudo_page_fault;
-#else /* CONFIG_ARCH_S390X */
+#ifdef CONFIG_ARCH_S390X
         pgm_check_table[0x38] = &do_dat_exception;
        pgm_check_table[0x39] = &do_dat_exception;
        pgm_check_table[0x3A] = &do_dat_exception;
@@ -731,12 +714,10 @@ void __init trap_init(void)
        pgm_check_table[0x40] = &do_monitor_call;
 
        if (MACHINE_IS_VM) {
+#ifdef CONFIG_PFAULT
                /*
-                * First try to get pfault pseudo page faults going.
-                * If this isn't available turn on pagex page faults.
+                * Try to get pfault pseudo page faults going.
                 */
-#ifdef CONFIG_PFAULT
-               /* request the 0x2603 external interrupt */
                if (register_early_external_interrupt(0x2603, pfault_interrupt,
                                                      &ext_int_pfault) != 0)
                        panic("Couldn't request external interrupt 0x2603");
@@ -747,10 +728,6 @@ void __init trap_init(void)
                /* Tough luck, no pfault. */
                unregister_early_external_interrupt(0x2603, pfault_interrupt,
                                                    &ext_int_pfault);
-#endif
-#ifndef CONFIG_ARCH_S390X
-               register_reboot_notifier(&pagex_reboot_notifier);
-               cpcmd("SET PAGEX ON", NULL, 0, NULL);
 #endif
        }
 }
index c5348108ca3ce23e8da4a6681c32330ebad73122..506a33b51e4f789317a3a854fb7eef9221aa7827 100644 (file)
@@ -234,8 +234,8 @@ query_segment_type (struct dcss_segment *seg)
        rc = 0;
 
  out_free:
-       if (qin) kfree(qin);
-       if (qout) kfree(qout);
+       kfree(qin);
+       kfree(qout);
        return rc;
 }
 
@@ -394,7 +394,7 @@ __segment_load (char *name, int do_nonshared, unsigned long *addr, unsigned long
                                segtype_string[seg->vm_segtype]);
        goto out;
  out_free:
-       kfree (seg);
+       kfree(seg);
  out:
        return rc;
 }
@@ -505,7 +505,7 @@ segment_modify_shared (char *name, int do_nonshared)
        list_del(&seg->list);
        dcss_diag(DCSS_PURGESEG, seg->dcss_name,
                  &dummy, &dummy);
-       kfree (seg);
+       kfree(seg);
  out_unlock:
        spin_unlock(&dcss_lock);
        return rc;
index 856a971759b1a2d0776c347914d1dc3015885659..64e32da777541b69f053d18ec7a3508b0ea40c0b 100644 (file)
@@ -352,115 +352,6 @@ void do_dat_exception(struct pt_regs *regs, unsigned long error_code)
        do_exception(regs, error_code & 0xff, 0);
 }
 
-#ifndef CONFIG_ARCH_S390X
-
-typedef struct _pseudo_wait_t {
-       struct _pseudo_wait_t *next;
-       wait_queue_head_t queue;
-       unsigned long address;
-       int resolved;
-} pseudo_wait_t;
-
-static pseudo_wait_t *pseudo_lock_queue = NULL;
-static spinlock_t pseudo_wait_spinlock; /* spinlock to protect lock queue */
-
-/*
- * This routine handles 'pagex' pseudo page faults.
- */
-asmlinkage void
-do_pseudo_page_fault(struct pt_regs *regs, unsigned long error_code)
-{
-        pseudo_wait_t wait_struct;
-        pseudo_wait_t *ptr, *last, *next;
-        unsigned long address;
-
-        /*
-         * get the failing address
-         * more specific the segment and page table portion of
-         * the address
-         */
-        address = S390_lowcore.trans_exc_code & 0xfffff000;
-
-        if (address & 0x80000000) {
-                /* high bit set -> a page has been swapped in by VM */
-                address &= 0x7fffffff;
-                spin_lock(&pseudo_wait_spinlock);
-                last = NULL;
-                ptr = pseudo_lock_queue;
-                while (ptr != NULL) {
-                        next = ptr->next;
-                        if (address == ptr->address) {
-                                /*
-                                 * This is one of the processes waiting
-                                 * for the page. Unchain from the queue.
-                                 * There can be more than one process
-                                 * waiting for the same page. VM presents
-                                 * an initial and a completion interrupt for
-                                 * every process that tries to access a 
-                                 * page swapped out by VM. 
-                                 */
-                                if (last == NULL)
-                                        pseudo_lock_queue = next;
-                                else
-                                        last->next = next;
-                                /* now wake up the process */
-                                ptr->resolved = 1;
-                                wake_up(&ptr->queue);
-                        } else
-                                last = ptr;
-                        ptr = next;
-                }
-                spin_unlock(&pseudo_wait_spinlock);
-        } else {
-                /* Pseudo page faults in kernel mode is a bad idea */
-                if (!(regs->psw.mask & PSW_MASK_PSTATE)) {
-                        /*
-                        * VM presents pseudo page faults if the interrupted
-                        * state was not disabled for interrupts. So we can
-                        * get pseudo page fault interrupts while running
-                        * in kernel mode. We simply access the page here
-                        * while we are running disabled. VM will then swap
-                        * in the page synchronously.
-                         */
-                         if (check_user_space(regs, error_code) == 0)
-                                 /* dereference a virtual kernel address */
-                                 __asm__ __volatile__ (
-                                         "  ic 0,0(%0)"
-                                         : : "a" (address) : "0");
-                         else
-                                 /* dereference a virtual user address */
-                                 __asm__ __volatile__ (
-                                         "  la   2,0(%0)\n"
-                                         "  sacf 512\n"
-                                         "  ic   2,0(2)\n"
-                                        "0:sacf 0\n"
-                                        ".section __ex_table,\"a\"\n"
-                                        "  .align 4\n"
-                                        "  .long  0b,0b\n"
-                                        ".previous"
-                                         : : "a" (address) : "2" );
-
-                        return;
-                }
-               /* initialize and add element to pseudo_lock_queue */
-                init_waitqueue_head (&wait_struct.queue);
-                wait_struct.address = address;
-                wait_struct.resolved = 0;
-                spin_lock(&pseudo_wait_spinlock);
-                wait_struct.next = pseudo_lock_queue;
-                pseudo_lock_queue = &wait_struct;
-                spin_unlock(&pseudo_wait_spinlock);
-               /*
-                * The instruction that caused the program check will
-                * be repeated. Don't signal single step via SIGTRAP.
-                */
-               clear_tsk_thread_flag(current, TIF_SINGLE_STEP);
-                /* go to sleep */
-                wait_event(wait_struct.queue, wait_struct.resolved);
-        }
-}
-#endif /* CONFIG_ARCH_S390X */
-
 #ifdef CONFIG_PFAULT 
 /*
  * 'pfault' pseudo page faults routines.
@@ -508,7 +399,7 @@ int pfault_init(void)
                "   .quad  0b,1b\n"
 #endif /* CONFIG_ARCH_S390X */
                ".previous"
-                : "=d" (rc) : "a" (&refbk) : "cc" );
+                : "=d" (rc) : "a" (&refbk), "m" (refbk) : "cc" );
         __ctl_set_bit(0, 9);
         return rc;
 }
@@ -532,7 +423,7 @@ void pfault_fini(void)
                "   .quad  0b,0b\n"
 #endif /* CONFIG_ARCH_S390X */
                ".previous"
-               : : "a" (&refbk) : "cc" );
+               : : "a" (&refbk), "m" (refbk) : "cc" );
 }
 
 asmlinkage void
index 3e804c736e640eb9340128cf2adb18435a2ee61c..64f5ae0ff96d1474c3f4052848ced900c78d5a1f 100644 (file)
@@ -490,16 +490,6 @@ config CPU_SUBTYPE_ST40
        depends on CPU_SUBTYPE_ST40STB1 || CPU_SUBTYPE_ST40GX1
        default y
 
-config ARCH_DISCONTIGMEM_ENABLE
-       bool
-       depends on SH_HP690
-       default y
-       help
-         Say Y to upport efficient handling of discontiguous physical memory,
-         for architectures which are either NUMA (Non-Uniform Memory Access)
-         or have huge holes in the physical address space for other reasons.
-         See <file:Documentation/vm/numa> for more.
-
 source "mm/Kconfig"
 
 config ZERO_PAGE_OFFSET
@@ -770,24 +760,6 @@ source "fs/Kconfig.binfmt"
 
 endmenu
 
-menu "SH initrd options"
-       depends on BLK_DEV_INITRD
-
-config EMBEDDED_RAMDISK
-       bool "Embed root filesystem ramdisk into the kernel"
-
-config EMBEDDED_RAMDISK_IMAGE
-       string "Filename of gziped ramdisk image"
-       depends on EMBEDDED_RAMDISK
-       default "ramdisk.gz"
-       help
-         This is the filename of the ramdisk image to be built into the
-         kernel.  Relative pathnames are relative to arch/sh/ramdisk/.
-         The ramdisk image is not part of the kernel distribution; you must
-         provide one yourself.
-
-endmenu
-
 source "net/Kconfig"
 
 source "drivers/Kconfig"
index 4a3049080b4190cc61518d2625195e95d1737f65..67192d6b00d8ec550c853e1fdc9b7010e1ea02e3 100644 (file)
@@ -60,14 +60,6 @@ LIBGCC := $(shell $(CC) $(CFLAGS) -print-libgcc-file-name)
 
 core-y                         += arch/sh/kernel/ arch/sh/mm/
 
-#
-# ramdisk/initrd support
-# You need a compressed ramdisk image, named
-# CONFIG_EMBEDDED_RAMDISK_IMAGE. Relative pathnames
-# are relative to arch/sh/ramdisk/.
-#
-core-$(CONFIG_EMBEDDED_RAMDISK)        += arch/sh/ramdisk/
-
 # Boards
 machdir-$(CONFIG_SH_SOLUTION_ENGINE)           := se/770x
 machdir-$(CONFIG_SH_7751_SOLUTION_ENGINE)      := se/7751
index bd6726cde398b307ff19d9a435ec64f386892254..338c3729d2705095a338743e2cb6b5528275dbd2 100644 (file)
@@ -2,6 +2,7 @@
 # Makefile for the Linux SuperH-specific device drivers.
 #
 
-obj-$(CONFIG_PCI)      += pci/
-obj-$(CONFIG_SH_DMA)   += dma/
+obj-$(CONFIG_PCI)              += pci/
+obj-$(CONFIG_SH_DMA)           += dma/
+obj-$(CONFIG_SUPERHYWAY)       += superhyway/
 
diff --git a/arch/sh/drivers/superhyway/Makefile b/arch/sh/drivers/superhyway/Makefile
new file mode 100644 (file)
index 0000000..5b8e0c7
--- /dev/null
@@ -0,0 +1,6 @@
+#
+# Makefile for the SuperHyway specific kernel interface routines under Linux.
+#
+
+obj-$(CONFIG_CPU_SUBTYPE_SH4_202)      += ops-sh4-202.o
+
diff --git a/arch/sh/drivers/superhyway/ops-sh4-202.c b/arch/sh/drivers/superhyway/ops-sh4-202.c
new file mode 100644 (file)
index 0000000..a55c98a
--- /dev/null
@@ -0,0 +1,171 @@
+/*
+ * arch/sh/drivers/superhyway/ops-sh4-202.c
+ *
+ * SuperHyway bus support for SH4-202
+ *
+ * Copyright (C) 2005  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/kernel.h>
+#include <linux/init.h>
+#include <linux/superhyway.h>
+#include <linux/string.h>
+#include <asm/addrspace.h>
+#include <asm/io.h>
+
+#define PHYS_EMI_CBLOCK                P4SEGADDR(0x1ec00000)
+#define PHYS_EMI_DBLOCK                P4SEGADDR(0x08000000)
+#define PHYS_FEMI_CBLOCK       P4SEGADDR(0x1f800000)
+#define PHYS_FEMI_DBLOCK       P4SEGADDR(0x00000000)
+
+#define PHYS_EPBR_BLOCK                P4SEGADDR(0x1de00000)
+#define PHYS_DMAC_BLOCK                P4SEGADDR(0x1fa00000)
+#define PHYS_PBR_BLOCK         P4SEGADDR(0x1fc00000)
+
+static struct resource emi_resources[] = {
+       [0] = {
+               .start  = PHYS_EMI_CBLOCK,
+               .end    = PHYS_EMI_CBLOCK + 0x00300000 - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = PHYS_EMI_DBLOCK,
+               .end    = PHYS_EMI_DBLOCK + 0x08000000 - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+};
+
+static struct superhyway_device emi_device = {
+       .name           = "emi",
+       .num_resources  = ARRAY_SIZE(emi_resources),
+       .resource       = emi_resources,
+};
+
+static struct resource femi_resources[] = {
+       [0] = {
+               .start  = PHYS_FEMI_CBLOCK,
+               .end    = PHYS_FEMI_CBLOCK + 0x00100000 - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = PHYS_FEMI_DBLOCK,
+               .end    = PHYS_FEMI_DBLOCK + 0x08000000 - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+};
+
+static struct superhyway_device femi_device = {
+       .name           = "femi",
+       .num_resources  = ARRAY_SIZE(femi_resources),
+       .resource       = femi_resources,
+};
+
+static struct resource epbr_resources[] = {
+       [0] = {
+               .start  = P4SEGADDR(0x1e7ffff8),
+               .end    = P4SEGADDR(0x1e7ffff8 + (sizeof(u32) * 2) - 1),
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = PHYS_EPBR_BLOCK,
+               .end    = PHYS_EPBR_BLOCK + 0x00a00000 - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+};
+
+static struct superhyway_device epbr_device = {
+       .name           = "epbr",
+       .num_resources  = ARRAY_SIZE(epbr_resources),
+       .resource       = epbr_resources,
+};
+
+static struct resource dmac_resource = {
+       .start  = PHYS_DMAC_BLOCK,
+       .end    = PHYS_DMAC_BLOCK + 0x00100000 - 1,
+       .flags  = IORESOURCE_MEM,
+};
+
+static struct superhyway_device dmac_device = {
+       .name           = "dmac",
+       .num_resources  = 1,
+       .resource       = &dmac_resource,
+};
+
+static struct resource pbr_resources[] = {
+       [0] = {
+               .start  = P4SEGADDR(0x1ffffff8),
+               .end    = P4SEGADDR(0x1ffffff8 + (sizeof(u32) * 2) - 1),
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = PHYS_PBR_BLOCK,
+               .end    = PHYS_PBR_BLOCK + 0x00400000 - (sizeof(u32) * 2) - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+};
+
+static struct superhyway_device pbr_device = {
+       .name           = "pbr",
+       .num_resources  = ARRAY_SIZE(pbr_resources),
+       .resource       = pbr_resources,
+};
+
+static struct superhyway_device *sh4202_devices[] __initdata = {
+       &emi_device, &femi_device, &epbr_device, &dmac_device, &pbr_device,
+};
+
+static int sh4202_read_vcr(unsigned long base, struct superhyway_vcr_info *vcr)
+{
+       u32 vcrh, vcrl;
+       u64 tmp;
+
+       /*
+        * XXX: Even though the SH4-202 Evaluation Device documentation
+        * indicates that VCRL is mapped first with VCRH at a + 0x04
+        * offset, the opposite seems to be true.
+        *
+        * Some modules (PBR and ePBR for instance) also appear to have
+        * VCRL/VCRH flipped in the documentation, but on the SH4-202
+        * itself it appears that these are all consistently mapped with
+        * VCRH preceeding VCRL.
+        *
+        * Do not trust the documentation, for it is evil.
+        */
+       vcrh = ctrl_inl(base);
+       vcrl = ctrl_inl(base + sizeof(u32));
+
+       tmp = ((u64)vcrh << 32) | vcrl;
+       memcpy(vcr, &tmp, sizeof(u64));
+
+       return 0;
+}
+
+static int sh4202_write_vcr(unsigned long base, struct superhyway_vcr_info vcr)
+{
+       u64 tmp = *(u64 *)&vcr;
+
+       ctrl_outl((tmp >> 32) & 0xffffffff, base);
+       ctrl_outl(tmp & 0xffffffff, base + sizeof(u32));
+
+       return 0;
+}
+
+static struct superhyway_ops sh4202_superhyway_ops = {
+       .read_vcr       = sh4202_read_vcr,
+       .write_vcr      = sh4202_write_vcr,
+};
+
+struct superhyway_bus superhyway_channels[] = {
+       { &sh4202_superhyway_ops, },
+       { 0, },
+};
+
+int __init superhyway_scan_bus(struct superhyway_bus *bus)
+{
+       return superhyway_add_devices(bus, sh4202_devices,
+                                     ARRAY_SIZE(sh4202_devices));
+}
+
index 1fbe5a428e31fe54c017a58bff0d5b82efaea24e..1a8be06519ecf4c5de4fc7bcd5ed8dc56bad069b 100644 (file)
@@ -80,48 +80,11 @@ void ptrace_disable(struct task_struct *child)
        /* nothing to do.. */
 }
 
-asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
 {
-       struct task_struct *child;
        struct user * dummy = NULL;
        int ret;
 
-       lock_kernel();
-       ret = -EPERM;
-       if (request == PTRACE_TRACEME) {
-               /* are we already being traced? */
-               if (current->ptrace & PT_PTRACED)
-                       goto out;
-               ret = security_ptrace(current->parent, current);
-               if (ret)
-                       goto out;
-               /* set the ptrace bit in the process flags. */
-               current->ptrace |= PT_PTRACED;
-               ret = 0;
-               goto out;
-       }
-       ret = -ESRCH;
-       read_lock(&tasklist_lock);
-       child = find_task_by_pid(pid);
-       if (child)
-               get_task_struct(child);
-       read_unlock(&tasklist_lock);
-       if (!child)
-               goto out;
-
-       ret = -EPERM;
-       if (pid == 1)           /* you may not mess with init */
-               goto out_tsk;
-
-       if (request == PTRACE_ATTACH) {
-               ret = ptrace_attach(child);
-               goto out_tsk;
-       }
-
-       ret = ptrace_check_attach(child, request == PTRACE_KILL);
-       if (ret < 0)
-               goto out_tsk;
-
        switch (request) {
        /* when I and D space are separate, these will need to be fixed. */
        case PTRACE_PEEKTEXT: /* read word at location addr. */ 
@@ -289,10 +252,7 @@ asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
                ret = ptrace_request(child, request, addr, data);
                break;
        }
-out_tsk:
-       put_task_struct(child);
-out:
-       unlock_kernel();
+
        return ret;
 }
 
index 25b9d9ebe858b83163f00b83666a839124379b01..036050b377cdd6458ae1cf1858bfb445a4aad4aa 100644 (file)
@@ -83,9 +83,9 @@ static struct sh_machine_vector* __init get_mv_byname(const char* name);
 /* ... */
 #define COMMAND_LINE ((char *) (PARAM+0x100))
 
-#define RAMDISK_IMAGE_START_MASK       0x07FF
+#define RAMDISK_IMAGE_START_MASK       0x07FF
 #define RAMDISK_PROMPT_FLAG            0x8000
-#define RAMDISK_LOAD_FLAG              0x4000  
+#define RAMDISK_LOAD_FLAG              0x4000
 
 static char command_line[COMMAND_LINE_SIZE] = { 0, };
 
@@ -284,18 +284,6 @@ void __init setup_arch(char **cmdline_p)
 #define PFN_DOWN(x)    ((x) >> PAGE_SHIFT)
 #define PFN_PHYS(x)    ((x) << PAGE_SHIFT)
 
-#ifdef CONFIG_DISCONTIGMEM
-       NODE_DATA(0)->bdata = &discontig_node_bdata[0];
-       NODE_DATA(1)->bdata = &discontig_node_bdata[1];
-
-       bootmap_size = init_bootmem_node(NODE_DATA(1), 
-                                        PFN_UP(__MEMORY_START_2ND),
-                                        PFN_UP(__MEMORY_START_2ND),
-                                        PFN_DOWN(__MEMORY_START_2ND+__MEMORY_SIZE_2ND));
-       free_bootmem_node(NODE_DATA(1), __MEMORY_START_2ND, __MEMORY_SIZE_2ND);
-       reserve_bootmem_node(NODE_DATA(1), __MEMORY_START_2ND, bootmap_size);
-#endif
-
        /*
         * Find the highest page frame number we have available
         */
@@ -306,10 +294,10 @@ void __init setup_arch(char **cmdline_p)
         */
        max_low_pfn = max_pfn;
 
-       /*
+       /*
         * Partially used pages are not usable - thus
         * we are rounding upwards:
-        */
+        */
        start_pfn = PFN_UP(__pa(_end));
 
        /*
@@ -360,12 +348,12 @@ void __init setup_arch(char **cmdline_p)
        reserve_bootmem_node(NODE_DATA(0), __MEMORY_START, PAGE_SIZE);
 
 #ifdef CONFIG_BLK_DEV_INITRD
-       ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
-       if (&__rd_start != &__rd_end) {
+       ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
+       if (&__rd_start != &__rd_end) {
                LOADER_TYPE = 1;
                INITRD_START = PHYSADDR((unsigned long)&__rd_start) - __MEMORY_START;
                INITRD_SIZE = (unsigned long)&__rd_end - (unsigned long)&__rd_start;
-       }
+       }
 
        if (LOADER_TYPE && INITRD_START) {
                if (INITRD_START + INITRD_SIZE <= (max_low_pfn << PAGE_SHIFT)) {
index 4e9c854845a4461155b5fd040de85dcdf4c19784..e342565f75fbc464684faf8e54f28e05134475ea 100644 (file)
@@ -51,11 +51,6 @@ unsigned long mmu_context_cache = NO_CONTEXT;
 #define MAX_LOW_PFN    (NODE_DATA(0)->bdata->node_low_pfn)
 #endif
 
-#ifdef CONFIG_DISCONTIGMEM
-pg_data_t discontig_page_data[MAX_NUMNODES];
-bootmem_data_t discontig_node_bdata[MAX_NUMNODES];
-#endif
-
 void (*copy_page)(void *from, void *to);
 void (*clear_page)(void *to);
 
@@ -216,15 +211,6 @@ void __init paging_init(void)
 #endif
        NODE_DATA(0)->node_mem_map = NULL;
        free_area_init_node(0, NODE_DATA(0), zones_size, __MEMORY_START >> PAGE_SHIFT, 0);
-
-#ifdef CONFIG_DISCONTIGMEM
-       /*
-        * And for discontig, do some more fixups on the zone sizes..
-        */
-       zones_size[ZONE_DMA] = __MEMORY_SIZE_2ND >> PAGE_SHIFT;
-       zones_size[ZONE_NORMAL] = 0;
-       free_area_init_node(1, NODE_DATA(1), zones_size, __MEMORY_START_2ND >> PAGE_SHIFT, 0);
-#endif
 }
 
 void __init mem_init(void)
@@ -248,7 +234,7 @@ void __init mem_init(void)
        memset(empty_zero_page, 0, PAGE_SIZE);
        __flush_wback_region(empty_zero_page, PAGE_SIZE);
 
-       /* 
+       /*
         * Setup wrappers for copy/clear_page(), these will get overridden
         * later in the boot process if a better method is available.
         */
@@ -257,9 +243,6 @@ void __init mem_init(void)
 
        /* this will put all low memory onto the freelists */
        totalram_pages += free_all_bootmem_node(NODE_DATA(0));
-#ifdef CONFIG_DISCONTIGMEM
-       totalram_pages += free_all_bootmem_node(NODE_DATA(1));
-#endif
        reservedpages = 0;
        for (tmp = 0; tmp < num_physpages; tmp++)
                /*
@@ -286,7 +269,7 @@ void __init mem_init(void)
 void free_initmem(void)
 {
        unsigned long addr;
-       
+
        addr = (unsigned long)(&__init_begin);
        for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) {
                ClearPageReserved(virt_to_page(addr));
index 7a0d5c10bf20908dfad7a58fb8f96300f1f61f2e..46b09e26e0825fa411a593fdd4f5755e01d4f77a 100644 (file)
@@ -40,12 +40,17 @@ void update_mmu_cache(struct vm_area_struct * vma,
                return;
 
 #if defined(CONFIG_SH7705_CACHE_32KB)
-       struct page *page;
-       page = pte_page(pte);
-       if (VALID_PAGE(page) && !test_bit(PG_mapped, &page->flags)) {
-               unsigned long phys = pte_val(pte) & PTE_PHYS_MASK;
-               __flush_wback_region((void *)P1SEGADDR(phys), PAGE_SIZE);
-               __set_bit(PG_mapped, &page->flags);
+       {
+               struct page *page = pte_page(pte);
+               unsigned long pfn = pte_pfn(pte);
+
+               if (pfn_valid(pfn) && !test_bit(PG_mapped, &page->flags)) {
+                       unsigned long phys = pte_val(pte) & PTE_PHYS_MASK;
+
+                       __flush_wback_region((void *)P1SEGADDR(phys),
+                                            PAGE_SIZE);
+                       __set_bit(PG_mapped, &page->flags);
+               }
        }
 #endif
 
@@ -80,7 +85,7 @@ void __flush_tlb_page(unsigned long asid, unsigned long page)
         */
        addr = MMU_TLB_ADDRESS_ARRAY | (page & 0x1F000);
        data = (page & 0xfffe0000) | asid; /* VALID bit is off */
-       
+
        if ((cpu_data->flags & CPU_HAS_MMU_PAGE_ASSOC)) {
                addr |= MMU_PAGE_ASSOC_BIT;
                ways = 1;       /* we already know the way .. */
diff --git a/arch/sh/ramdisk/Makefile b/arch/sh/ramdisk/Makefile
deleted file mode 100644 (file)
index 99e1c68..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-#
-# Makefile for a ramdisk image
-#
-
-obj-y += ramdisk.o
-
-
-O_FORMAT = $(shell $(OBJDUMP) -i | head -n 2 | grep elf32)
-img := $(subst ",,$(CONFIG_EMBEDDED_RAMDISK_IMAGE))
-# add $(src) when $(img) is relative
-img := $(subst $(src)//,/,$(src)/$(img))
-
-quiet_cmd_ramdisk = LD      $@
-define cmd_ramdisk
-       $(LD) -T $(srctree)/$(src)/ld.script -b binary --oformat $(O_FORMAT) \
-               -o $@ $(img)
-endef
-
-$(obj)/ramdisk.o: $(img) $(srctree)/$(src)/ld.script
-       $(call cmd,ramdisk)
diff --git a/arch/sh/ramdisk/ld.script b/arch/sh/ramdisk/ld.script
deleted file mode 100644 (file)
index 94beee2..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-OUTPUT_ARCH(sh)
-SECTIONS
-{
-  .initrd :
-  {
-       *(.data)
-  }
-}
-
index 71f2eec00b99d3f6004457a2be1fec1347ee651d..cd22e94713165ce9e9335936a78852d68d522658 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/ptrace.h>
 #include <linux/user.h>
 #include <linux/signal.h>
+#include <linux/syscalls.h>
 
 #include <asm/io.h>
 #include <asm/uaccess.h>
@@ -121,61 +122,11 @@ put_fpu_long(struct task_struct *task, unsigned long addr, unsigned long data)
        return 0;
 }
 
-asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
+
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
 {
-       struct task_struct *child;
-       extern void poke_real_address_q(unsigned long long addr, unsigned long long data);
-#define WPC_DBRMODE 0x0d104008
-       static int first_call = 1;
        int ret;
 
-       lock_kernel();
-
-       if (first_call) {
-               /* Set WPC.DBRMODE to 0.  This makes all debug events get
-                * delivered through RESVEC, i.e. into the handlers in entry.S.
-                * (If the kernel was downloaded using a remote gdb, WPC.DBRMODE
-                * would normally be left set to 1, which makes debug events get
-                * delivered through DBRVEC, i.e. into the remote gdb's
-                * handlers.  This prevents ptrace getting them, and confuses
-                * the remote gdb.) */
-               printk("DBRMODE set to 0 to permit native debugging\n");
-               poke_real_address_q(WPC_DBRMODE, 0);
-               first_call = 0;
-       }
-
-       ret = -EPERM;
-       if (request == PTRACE_TRACEME) {
-               /* are we already being traced? */
-               if (current->ptrace & PT_PTRACED)
-                       goto out;
-               /* set the ptrace bit in the process flags. */
-               current->ptrace |= PT_PTRACED;
-               ret = 0;
-               goto out;
-       }
-       ret = -ESRCH;
-       read_lock(&tasklist_lock);
-       child = find_task_by_pid(pid);
-       if (child)
-               get_task_struct(child);
-       read_unlock(&tasklist_lock);
-       if (!child)
-               goto out;
-
-       ret = -EPERM;
-       if (pid == 1)           /* you may not mess with init */
-               goto out_tsk;
-
-       if (request == PTRACE_ATTACH) {
-               ret = ptrace_attach(child);
-                       goto out_tsk;
-               }
-
-       ret = ptrace_check_attach(child, request == PTRACE_KILL);
-       if (ret < 0)
-               goto out_tsk;
-
        switch (request) {
        /* when I and D space are separate, these will need to be fixed. */
        case PTRACE_PEEKTEXT: /* read word at location addr. */
@@ -313,13 +264,33 @@ asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
                ret = ptrace_request(child, request, addr, data);
                break;
        }
-out_tsk:
-       put_task_struct(child);
-out:
-       unlock_kernel();
        return ret;
 }
 
+asmlinkage int sh64_ptrace(long request, long pid, long addr, long data)
+{
+       extern void poke_real_address_q(unsigned long long addr, unsigned long long data);
+#define WPC_DBRMODE 0x0d104008
+       static int first_call = 1;
+
+       lock_kernel();
+       if (first_call) {
+               /* Set WPC.DBRMODE to 0.  This makes all debug events get
+                * delivered through RESVEC, i.e. into the handlers in entry.S.
+                * (If the kernel was downloaded using a remote gdb, WPC.DBRMODE
+                * would normally be left set to 1, which makes debug events get
+                * delivered through DBRVEC, i.e. into the remote gdb's
+                * handlers.  This prevents ptrace getting them, and confuses
+                * the remote gdb.) */
+               printk("DBRMODE set to 0 to permit native debugging\n");
+               poke_real_address_q(WPC_DBRMODE, 0);
+               first_call = 0;
+       }
+       unlock_kernel();
+
+       return sys_ptrace(request, pid, addr, data);
+}
+
 asmlinkage void syscall_trace(void)
 {
        struct task_struct *tsk = current;
index a3d037805f1cf7e7d418e328cca61555e79479dd..c0079d54c85044d9ccdf19696b88fa091a5b109c 100644 (file)
@@ -46,7 +46,7 @@ sys_call_table:
        .long sys_setuid16
        .long sys_getuid16
        .long sys_stime                 /* 25 */
-       .long sys_ptrace
+       .long sh64_ptrace
        .long sys_alarm
        .long sys_fstat
        .long sys_pause
index 1e9d8638a28a249823d31f53c7d629d392240088..3fded69b19228ca4a81013149b638d97b554143d 100644 (file)
@@ -377,8 +377,21 @@ source "drivers/fc4/Kconfig"
 
 source "fs/Kconfig"
 
+menu "Instrumentation Support"
+        depends on EXPERIMENTAL
+
 source "arch/sparc64/oprofile/Kconfig"
 
+config KPROBES
+       bool "Kprobes (EXPERIMENTAL)"
+       help
+         Kprobes allows you to trap at almost any kernel address and
+         execute a callback function.  register_kprobe() establishes
+         a probepoint and specifies the callback.  Kprobes is useful
+         for kernel debugging, non-intrusive instrumentation and testing.
+         If in doubt, say "N".
+endmenu
+
 source "arch/sparc64/Kconfig.debug"
 
 source "security/Kconfig"
index fa06ea04837b9525da90580e0c4db0a3d9f3a952..3e31be494e54ab7902d4df0639ce0bdab8ffe559 100644 (file)
@@ -11,16 +11,6 @@ config DEBUG_STACK_USAGE
 
          This option will slow down process creation somewhat.
 
-config KPROBES
-       bool "Kprobes"
-       depends on DEBUG_KERNEL
-       help
-         Kprobes allows you to trap at almost any kernel address and
-         execute a callback function.  register_kprobe() establishes
-         a probepoint and specifies the callback.  Kprobes is useful
-         for kernel debugging, non-intrusive instrumentation and testing.
-         If in doubt, say "N".
-
 config DEBUG_DCFLUSH
        bool "D-cache flush debugging"
        depends on DEBUG_KERNEL
index 0d66d07c8c6eead89fa6e5799ec6ba5fcf57873f..96bd09b098f431876c87778594983f0bf514f85d 100644 (file)
@@ -38,6 +38,9 @@
  * - Mark that we are no longer actively in a kprobe.
  */
 
+DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
+DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
+
 int __kprobes arch_prepare_kprobe(struct kprobe *p)
 {
        return 0;
@@ -66,46 +69,39 @@ void __kprobes arch_remove_kprobe(struct kprobe *p)
 {
 }
 
-static struct kprobe *current_kprobe;
-static unsigned long current_kprobe_orig_tnpc;
-static unsigned long current_kprobe_orig_tstate_pil;
-static unsigned int kprobe_status;
-static struct kprobe *kprobe_prev;
-static unsigned long kprobe_orig_tnpc_prev;
-static unsigned long kprobe_orig_tstate_pil_prev;
-static unsigned int kprobe_status_prev;
-
-static inline void save_previous_kprobe(void)
+static inline void save_previous_kprobe(struct kprobe_ctlblk *kcb)
 {
-       kprobe_status_prev = kprobe_status;
-       kprobe_orig_tnpc_prev = current_kprobe_orig_tnpc;
-       kprobe_orig_tstate_pil_prev = current_kprobe_orig_tstate_pil;
-       kprobe_prev = current_kprobe;
+       kcb->prev_kprobe.kp = kprobe_running();
+       kcb->prev_kprobe.status = kcb->kprobe_status;
+       kcb->prev_kprobe.orig_tnpc = kcb->kprobe_orig_tnpc;
+       kcb->prev_kprobe.orig_tstate_pil = kcb->kprobe_orig_tstate_pil;
 }
 
-static inline void restore_previous_kprobe(void)
+static inline void restore_previous_kprobe(struct kprobe_ctlblk *kcb)
 {
-       kprobe_status = kprobe_status_prev;
-       current_kprobe_orig_tnpc = kprobe_orig_tnpc_prev;
-       current_kprobe_orig_tstate_pil = kprobe_orig_tstate_pil_prev;
-       current_kprobe = kprobe_prev;
+       __get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp;
+       kcb->kprobe_status = kcb->prev_kprobe.status;
+       kcb->kprobe_orig_tnpc = kcb->prev_kprobe.orig_tnpc;
+       kcb->kprobe_orig_tstate_pil = kcb->prev_kprobe.orig_tstate_pil;
 }
 
-static inline void set_current_kprobe(struct kprobe *p, struct pt_regs *regs)
+static inline void set_current_kprobe(struct kprobe *p, struct pt_regs *regs,
+                               struct kprobe_ctlblk *kcb)
 {
-       current_kprobe_orig_tnpc = regs->tnpc;
-       current_kprobe_orig_tstate_pil = (regs->tstate & TSTATE_PIL);
-       current_kprobe = p;
+       __get_cpu_var(current_kprobe) = p;
+       kcb->kprobe_orig_tnpc = regs->tnpc;
+       kcb->kprobe_orig_tstate_pil = (regs->tstate & TSTATE_PIL);
 }
 
-static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
+static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs,
+                       struct kprobe_ctlblk *kcb)
 {
        regs->tstate |= TSTATE_PIL;
 
        /*single step inline, if it a breakpoint instruction*/
        if (p->opcode == BREAKPOINT_INSTRUCTION) {
                regs->tpc = (unsigned long) p->addr;
-               regs->tnpc = current_kprobe_orig_tnpc;
+               regs->tnpc = kcb->kprobe_orig_tnpc;
        } else {
                regs->tpc = (unsigned long) &p->ainsn.insn[0];
                regs->tnpc = (unsigned long) &p->ainsn.insn[1];
@@ -117,19 +113,21 @@ static int __kprobes kprobe_handler(struct pt_regs *regs)
        struct kprobe *p;
        void *addr = (void *) regs->tpc;
        int ret = 0;
+       struct kprobe_ctlblk *kcb;
 
+       /*
+        * We don't want to be preempted for the entire
+        * duration of kprobe processing
+        */
        preempt_disable();
+       kcb = get_kprobe_ctlblk();
 
        if (kprobe_running()) {
-               /* We *are* holding lock here, so this is safe.
-                * Disarm the probe we just hit, and ignore it.
-                */
                p = get_kprobe(addr);
                if (p) {
-                       if (kprobe_status == KPROBE_HIT_SS) {
+                       if (kcb->kprobe_status == KPROBE_HIT_SS) {
                                regs->tstate = ((regs->tstate & ~TSTATE_PIL) |
-                                       current_kprobe_orig_tstate_pil);
-                               unlock_kprobes();
+                                       kcb->kprobe_orig_tstate_pil);
                                goto no_kprobe;
                        }
                        /* We have reentered the kprobe_handler(), since
@@ -138,25 +136,22 @@ static int __kprobes kprobe_handler(struct pt_regs *regs)
                         * just single step on the instruction of the new probe
                         * without calling any user handlers.
                         */
-                       save_previous_kprobe();
-                       set_current_kprobe(p, regs);
+                       save_previous_kprobe(kcb);
+                       set_current_kprobe(p, regs, kcb);
                        p->nmissed++;
-                       kprobe_status = KPROBE_REENTER;
-                       prepare_singlestep(p, regs);
+                       kcb->kprobe_status = KPROBE_REENTER;
+                       prepare_singlestep(p, regs, kcb);
                        return 1;
                } else {
-                       p = current_kprobe;
+                       p = __get_cpu_var(current_kprobe);
                        if (p->break_handler && p->break_handler(p, regs))
                                goto ss_probe;
                }
-               /* If it's not ours, can't be delete race, (we hold lock). */
                goto no_kprobe;
        }
 
-       lock_kprobes();
        p = get_kprobe(addr);
        if (!p) {
-               unlock_kprobes();
                if (*(u32 *)addr != BREAKPOINT_INSTRUCTION) {
                        /*
                         * The breakpoint instruction was removed right
@@ -171,14 +166,14 @@ static int __kprobes kprobe_handler(struct pt_regs *regs)
                goto no_kprobe;
        }
 
-       set_current_kprobe(p, regs);
-       kprobe_status = KPROBE_HIT_ACTIVE;
+       set_current_kprobe(p, regs, kcb);
+       kcb->kprobe_status = KPROBE_HIT_ACTIVE;
        if (p->pre_handler && p->pre_handler(p, regs))
                return 1;
 
 ss_probe:
-       prepare_singlestep(p, regs);
-       kprobe_status = KPROBE_HIT_SS;
+       prepare_singlestep(p, regs, kcb);
+       kcb->kprobe_status = KPROBE_HIT_SS;
        return 1;
 
 no_kprobe:
@@ -260,11 +255,12 @@ static void __kprobes retpc_fixup(struct pt_regs *regs, u32 insn,
  * This function prepares to return from the post-single-step
  * breakpoint trap.
  */
-static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs)
+static void __kprobes resume_execution(struct kprobe *p,
+               struct pt_regs *regs, struct kprobe_ctlblk *kcb)
 {
        u32 insn = p->ainsn.insn[0];
 
-       regs->tpc = current_kprobe_orig_tnpc;
+       regs->tpc = kcb->kprobe_orig_tnpc;
        regs->tnpc = relbranch_fixup(insn,
                                     (unsigned long) p->addr,
                                     (unsigned long) &p->ainsn.insn[0],
@@ -272,44 +268,48 @@ static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs)
        retpc_fixup(regs, insn, (unsigned long) p->addr);
 
        regs->tstate = ((regs->tstate & ~TSTATE_PIL) |
-                       current_kprobe_orig_tstate_pil);
+                       kcb->kprobe_orig_tstate_pil);
 }
 
 static inline int post_kprobe_handler(struct pt_regs *regs)
 {
-       if (!kprobe_running())
+       struct kprobe *cur = kprobe_running();
+       struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+
+       if (!cur)
                return 0;
 
-       if ((kprobe_status != KPROBE_REENTER) && current_kprobe->post_handler) {
-               kprobe_status = KPROBE_HIT_SSDONE;
-               current_kprobe->post_handler(current_kprobe, regs, 0);
+       if ((kcb->kprobe_status != KPROBE_REENTER) && cur->post_handler) {
+               kcb->kprobe_status = KPROBE_HIT_SSDONE;
+               cur->post_handler(cur, regs, 0);
        }
 
-       resume_execution(current_kprobe, regs);
+       resume_execution(cur, regs, kcb);
 
        /*Restore back the original saved kprobes variables and continue. */
-       if (kprobe_status == KPROBE_REENTER) {
-               restore_previous_kprobe();
+       if (kcb->kprobe_status == KPROBE_REENTER) {
+               restore_previous_kprobe(kcb);
                goto out;
        }
-       unlock_kprobes();
+       reset_current_kprobe();
 out:
        preempt_enable_no_resched();
 
        return 1;
 }
 
-/* Interrupts disabled, kprobe_lock held. */
 static inline int kprobe_fault_handler(struct pt_regs *regs, int trapnr)
 {
-       if (current_kprobe->fault_handler
-           && current_kprobe->fault_handler(current_kprobe, regs, trapnr))
+       struct kprobe *cur = kprobe_running();
+       struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+
+       if (cur->fault_handler && cur->fault_handler(cur, regs, trapnr))
                return 1;
 
-       if (kprobe_status & KPROBE_HIT_SS) {
-               resume_execution(current_kprobe, regs);
+       if (kcb->kprobe_status & KPROBE_HIT_SS) {
+               resume_execution(cur, regs, kcb);
 
-               unlock_kprobes();
+               reset_current_kprobe();
                preempt_enable_no_resched();
        }
        return 0;
@@ -322,29 +322,30 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
                                       unsigned long val, void *data)
 {
        struct die_args *args = (struct die_args *)data;
+       int ret = NOTIFY_DONE;
+
        switch (val) {
        case DIE_DEBUG:
                if (kprobe_handler(args->regs))
-                       return NOTIFY_STOP;
+                       ret = NOTIFY_STOP;
                break;
        case DIE_DEBUG_2:
                if (post_kprobe_handler(args->regs))
-                       return NOTIFY_STOP;
+                       ret = NOTIFY_STOP;
                break;
        case DIE_GPF:
-               if (kprobe_running() &&
-                   kprobe_fault_handler(args->regs, args->trapnr))
-                       return NOTIFY_STOP;
-               break;
        case DIE_PAGE_FAULT:
+               /* kprobe_running() needs smp_processor_id() */
+               preempt_disable();
                if (kprobe_running() &&
                    kprobe_fault_handler(args->regs, args->trapnr))
-                       return NOTIFY_STOP;
+                       ret = NOTIFY_STOP;
+               preempt_enable();
                break;
        default:
                break;
        }
-       return NOTIFY_DONE;
+       return ret;
 }
 
 asmlinkage void __kprobes kprobe_trap(unsigned long trap_level,
@@ -368,24 +369,21 @@ asmlinkage void __kprobes kprobe_trap(unsigned long trap_level,
 }
 
 /* Jprobes support.  */
-static struct pt_regs jprobe_saved_regs;
-static struct pt_regs *jprobe_saved_regs_location;
-static struct sparc_stackf jprobe_saved_stack;
-
 int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
 {
        struct jprobe *jp = container_of(p, struct jprobe, kp);
+       struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
 
-       jprobe_saved_regs_location = regs;
-       memcpy(&jprobe_saved_regs, regs, sizeof(*regs));
+       kcb->jprobe_saved_regs_location = regs;
+       memcpy(&(kcb->jprobe_saved_regs), regs, sizeof(*regs));
 
        /* Save a whole stack frame, this gets arguments
         * pushed onto the stack after using up all the
         * arg registers.
         */
-       memcpy(&jprobe_saved_stack,
+       memcpy(&(kcb->jprobe_saved_stack),
               (char *) (regs->u_regs[UREG_FP] + STACK_BIAS),
-              sizeof(jprobe_saved_stack));
+              sizeof(kcb->jprobe_saved_stack));
 
        regs->tpc  = (unsigned long) jp->entry;
        regs->tnpc = ((unsigned long) jp->entry) + 0x4UL;
@@ -396,7 +394,6 @@ int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
 
 void __kprobes jprobe_return(void)
 {
-       preempt_enable_no_resched();
        __asm__ __volatile__(
                ".globl jprobe_return_trap_instruction\n"
 "jprobe_return_trap_instruction:\n\t"
@@ -410,14 +407,15 @@ extern void __show_regs(struct pt_regs * regs);
 int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
 {
        u32 *addr = (u32 *) regs->tpc;
+       struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
 
        if (addr == (u32 *) jprobe_return_trap_instruction) {
-               if (jprobe_saved_regs_location != regs) {
+               if (kcb->jprobe_saved_regs_location != regs) {
                        printk("JPROBE: Current regs (%p) does not match "
                               "saved regs (%p).\n",
-                              regs, jprobe_saved_regs_location);
+                              regs, kcb->jprobe_saved_regs_location);
                        printk("JPROBE: Saved registers\n");
-                       __show_regs(jprobe_saved_regs_location);
+                       __show_regs(kcb->jprobe_saved_regs_location);
                        printk("JPROBE: Current registers\n");
                        __show_regs(regs);
                        BUG();
@@ -426,12 +424,13 @@ int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
                 * first so that UREG_FP is the original one for
                 * the stack frame restore.
                 */
-               memcpy(regs, &jprobe_saved_regs, sizeof(*regs));
+               memcpy(regs, &(kcb->jprobe_saved_regs), sizeof(*regs));
 
                memcpy((char *) (regs->u_regs[UREG_FP] + STACK_BIAS),
-                      &jprobe_saved_stack,
-                      sizeof(jprobe_saved_stack));
+                      &(kcb->jprobe_saved_stack),
+                      sizeof(kcb->jprobe_saved_stack));
 
+               preempt_enable_no_resched();
                return 1;
        }
        return 0;
index 686e526bec04c91ffe1e7c145537b1a74680fb20..b35dc8dc995a066810c5c4dac01658c4ab9f8944 100644 (file)
@@ -388,10 +388,8 @@ err_out:
                        kfree(driver);
                        cpufreq_us2e_driver = NULL;
                }
-               if (us2e_freq_table) {
-                       kfree(us2e_freq_table);
-                       us2e_freq_table = NULL;
-               }
+               kfree(us2e_freq_table);
+               us2e_freq_table = NULL;
                return ret;
        }
 
@@ -402,7 +400,6 @@ static void __exit us2e_freq_exit(void)
 {
        if (cpufreq_us2e_driver) {
                cpufreq_unregister_driver(cpufreq_us2e_driver);
-
                kfree(cpufreq_us2e_driver);
                cpufreq_us2e_driver = NULL;
                kfree(us2e_freq_table);
index 0340041f614352a5cd22ddae1a946c8b1cf53e0f..6d1f9a3c464f55ed63c158527ea6d88502606b7d 100644 (file)
@@ -249,10 +249,8 @@ err_out:
                        kfree(driver);
                        cpufreq_us3_driver = NULL;
                }
-               if (us3_freq_table) {
-                       kfree(us3_freq_table);
-                       us3_freq_table = NULL;
-               }
+               kfree(us3_freq_table);
+               us3_freq_table = NULL;
                return ret;
        }
 
@@ -263,7 +261,6 @@ static void __exit us3_freq_exit(void)
 {
        if (cpufreq_us3_driver) {
                cpufreq_unregister_driver(cpufreq_us3_driver);
-
                kfree(cpufreq_us3_driver);
                cpufreq_us3_driver = NULL;
                kfree(us3_freq_table);
index 5ade19801b97a598829b4b1dff817a6cc59a028e..d8a84088471a1c011868aae0b44558d15c9f1c0b 100644 (file)
@@ -1,7 +1,3 @@
-
-menu "Profiling support"
-       depends on EXPERIMENTAL
-
 config PROFILING
        bool "Profiling support (EXPERIMENTAL)"
        help
@@ -19,5 +15,3 @@ config OPROFILE
 
          If unsure, say N.
 
-endmenu
-
index cd06ed7d842d93d54f18886efcf512d5471c009d..3b5f47c469073df1ca4b0bac35bc06dff2aaaeaf 100644 (file)
@@ -65,6 +65,30 @@ config STATIC_LINK
        chroot, and you disable CONFIG_MODE_TT, you probably want to say Y
        here.
 
+config HOST_2G_2G
+       bool "2G/2G host address space split"
+       default n
+       depends on MODE_TT
+       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'.
+
+config KERNEL_HALF_GIGS
+       int "Kernel address space size (in .5G units)"
+       default "1"
+       depends on MODE_TT
+       help
+        This determines the amount of address space that UML will allocate for
+        its own, measured in half Gigabyte units.  The default is 1.
+        Change this only if you need to boot UML with an unusually large amount
+        of physical memory.
+
 config MODE_SKAS
        bool "Separate Kernel Address Space support"
        default y
@@ -182,19 +206,6 @@ config MAGIC_SYSRQ
        The keys are documented in <file:Documentation/sysrq.txt>. Don't say Y
        unless you really know what this hack does.
 
-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'.
-
 config SMP
        bool "Symmetric multi-processing support (EXPERIMENTAL)"
        default n
@@ -241,15 +252,6 @@ config NEST_LEVEL
         set to the host's CONFIG_NEST_LEVEL + CONFIG_KERNEL_HALF_GIGS.
         Only change this if you are running nested UMLs.
 
-config KERNEL_HALF_GIGS
-       int "Kernel address space size (in .5G units)"
-       default "1"
-       help
-        This determines the amount of address space that UML will allocate for
-        its own, measured in half Gigabyte units.  The default is 1.
-        Change this only if you need to boot UML with an unusually large amount
-        of physical memory.
-
 config HIGHMEM
        bool "Highmem support"
        depends on !64BIT
index e1ffad2246053651339c07281a5aa003aa60c3d9..e55d32e903bc1a4095a3f44123f2fb22ccd40abc 100644 (file)
@@ -60,7 +60,7 @@ AFLAGS += $(ARCH_INCLUDE)
 
 USER_CFLAGS := $(patsubst -I%,,$(CFLAGS))
 USER_CFLAGS := $(patsubst -D__KERNEL__,,$(USER_CFLAGS)) $(ARCH_INCLUDE) \
-       $(MODE_INCLUDE)
+       $(MODE_INCLUDE) -D_FILE_OFFSET_BITS=64
 
 # -Derrno=kernel_errno - This turns all kernel references to errno into
 # kernel_errno to separate them from the libc errno.  This allows -fno-common
index aef7c50f8e1365a6478de2d84471bab6213e1547..1f7dcb064aee65602eac0d5fbb18cc77aad6754e 100644 (file)
@@ -17,8 +17,6 @@ ifeq ("$(origin SUBARCH)", "command line")
 ifneq ("$(shell uname -m | sed -e s/i.86/i386/)", "$(SUBARCH)")
 CFLAGS                 += $(call cc-option,-m32)
 USER_CFLAGS            += $(call cc-option,-m32)
-HOSTCFLAGS             += $(call cc-option,-m32)
-HOSTLDFLAGS            += $(call cc-option,-m32)
 AFLAGS                 += $(call cc-option,-m32)
 LINK-y                 += $(call cc-option,-m32)
 UML_OBJCOPYFLAGS       += -F $(ELF_FORMAT)
index de3bce71aeb3e8f3b3d283da35a77949a6444022..1c55d580248993c9ef1dd7249ccf8bb8e548c745 100644 (file)
@@ -16,7 +16,6 @@
 #include "user_util.h"
 #include "chan_user.h"
 #include "user.h"
-#include "helper.h"
 #include "os.h"
 #include "choose-mode.h"
 #include "mode.h"
index 147ec19f6bb9dc98c2dd026c25bd49cf9cc1a959..49acb2badf3229437c7a0149bc3da5be8d7d2109 100644 (file)
@@ -46,7 +46,6 @@
 #include <linux/smp_lock.h>
 #include <linux/init.h>
 #include <asm/uaccess.h>
-#include "helper.h"
 #include "mconsole.h"
 
 MODULE_LICENSE("GPL");
index d934181b8d4c67238b3fa10a5941952884743e1b..def013b5a3c7a5ec373dae711829b4ae10f76349 100644 (file)
@@ -8,7 +8,6 @@
 #include <errno.h>
 #include "user_util.h"
 #include "user.h"
-#include "helper.h"
 #include "mconsole.h"
 #include "os.h"
 #include "choose-mode.h"
index 721e2601a75da2e8b8fbcbb94dc1797831bc0e7c..fe865d9a37212d690d859dc4dc2209cb4d584a36 100644 (file)
@@ -96,7 +96,6 @@ irqreturn_t uml_net_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 static int uml_net_open(struct net_device *dev)
 {
        struct uml_net_private *lp = dev->priv;
-       char addr[sizeof("255.255.255.255\0")];
        int err;
 
        spin_lock(&lp->lock);
@@ -107,7 +106,7 @@ static int uml_net_open(struct net_device *dev)
        }
 
        if(!lp->have_mac){
-               dev_ip_addr(dev, addr, &lp->mac[2]);
+               dev_ip_addr(dev, &lp->mac[2]);
                set_ether_mac(dev, lp->mac);
        }
 
@@ -664,8 +663,6 @@ static int uml_inetaddr_event(struct notifier_block *this, unsigned long event,
                              void *ptr)
 {
        struct in_ifaddr *ifa = ptr;
-       u32 addr = ifa->ifa_address;
-       u32 netmask = ifa->ifa_mask;
        struct net_device *dev = ifa->ifa_dev->dev;
        struct uml_net_private *lp;
        void (*proc)(unsigned char *, unsigned char *, void *);
@@ -685,14 +682,8 @@ static int uml_inetaddr_event(struct notifier_block *this, unsigned long event,
                break;
        }
        if(proc != NULL){
-               addr_buf[0] = addr & 0xff;
-               addr_buf[1] = (addr >> 8) & 0xff;
-               addr_buf[2] = (addr >> 16) & 0xff;
-               addr_buf[3] = addr >> 24;
-               netmask_buf[0] = netmask & 0xff;
-               netmask_buf[1] = (netmask >> 8) & 0xff;
-               netmask_buf[2] = (netmask >> 16) & 0xff;
-               netmask_buf[3] = netmask >> 24;
+               memcpy(addr_buf, &ifa->ifa_address, sizeof(addr_buf));
+               memcpy(netmask_buf, &ifa->ifa_mask, sizeof(netmask_buf));
                (*proc)(addr_buf, netmask_buf, &lp->user);
        }
        return(NOTIFY_DONE);
@@ -774,27 +765,18 @@ int setup_etheraddr(char *str, unsigned char *addr)
        return(1);
 }
 
-void dev_ip_addr(void *d, char *buf, char *bin_buf)
+void dev_ip_addr(void *d, unsigned char *bin_buf)
 {
        struct net_device *dev = d;
        struct in_device *ip = dev->ip_ptr;
        struct in_ifaddr *in;
-       u32 addr;
 
        if((ip == NULL) || ((in = ip->ifa_list) == NULL)){
                printk(KERN_WARNING "dev_ip_addr - device not assigned an "
                       "IP address\n");
                return;
        }
-       addr = in->ifa_address;
-       sprintf(buf, "%d.%d.%d.%d", addr & 0xff, (addr >> 8) & 0xff, 
-               (addr >> 16) & 0xff, addr >> 24);
-       if(bin_buf){
-               bin_buf[0] = addr & 0xff;
-               bin_buf[1] = (addr >> 8) & 0xff;
-               bin_buf[2] = (addr >> 16) & 0xff;
-               bin_buf[3] = addr >> 24;
-       }
+       memcpy(bin_buf, &in->ifa_address, sizeof(in->ifa_address));
 }
 
 void set_ether_mac(void *d, unsigned char *addr)
@@ -829,14 +811,8 @@ void iter_addresses(void *d, void (*cb)(unsigned char *, unsigned char *,
        if(ip == NULL) return;
        in = ip->ifa_list;
        while(in != NULL){
-               address[0] = in->ifa_address & 0xff;
-               address[1] = (in->ifa_address >> 8) & 0xff;
-               address[2] = (in->ifa_address >> 16) & 0xff;
-               address[3] = in->ifa_address >> 24;
-               netmask[0] = in->ifa_mask & 0xff;
-               netmask[1] = (in->ifa_mask >> 8) & 0xff;
-               netmask[2] = (in->ifa_mask >> 16) & 0xff;
-               netmask[3] = in->ifa_mask >> 24;
+               memcpy(address, &in->ifa_address, sizeof(address));
+               memcpy(netmask, &in->ifa_mask, sizeof(netmask));
                (*cb)(address, netmask, arg);
                in = in->ifa_next;
        }
index 3730d4f1271368e43ee147303973b8490ab153ea..098fa65981aba6404eb9422137466d39d5ffc38b 100644 (file)
@@ -16,7 +16,6 @@
 #include "user_util.h"
 #include "kern_util.h"
 #include "net_user.h"
-#include "helper.h"
 #include "os.h"
 
 int tap_open_common(void *dev, char *gate_addr)
index 14dd2002d2da6946bd61ac133198f112338cff31..ed4a1a6c5d83fa03fb515f69a2fc30340f596301 100644 (file)
@@ -18,7 +18,6 @@
 #include "user.h"
 #include "chan_user.h"
 #include "port.h"
-#include "helper.h"
 #include "os.h"
 
 struct port_chan {
index f9e22198e011c911c7c2f1d36a1b8da742c2325e..ba471f5864a6d7d6815f3847a36aa78b4ed1a5e3 100644 (file)
@@ -58,10 +58,8 @@ static ssize_t rng_dev_read (struct file *filp, char __user *buf, size_t size,
                         if (filp->f_flags & O_NONBLOCK)
                                 return ret ? : -EAGAIN;
 
-                        if(need_resched()){
-                                current->state = TASK_INTERRUPTIBLE;
-                                schedule_timeout(1);
-                        }
+                        if(need_resched())
+                                schedule_timeout_interruptible(1);
                 }
                 else return n;
                if (signal_pending (current))
index 71af444e591f8bff7b097ac57dc85376529fb677..89fbec185cc16ec10d2d8df49410cf8bb32080a1 100644 (file)
@@ -14,7 +14,6 @@
 #include "net_user.h"
 #include "slip.h"
 #include "slip_common.h"
-#include "helper.h"
 #include "os.h"
 
 void slip_user_init(void *data, void *dev)
index 8d91f663d82c684267567f2489f8059b738590e8..b94c66114bc85d7a56fe4d9f6d29d4d31a633c13 100644 (file)
@@ -13,7 +13,6 @@
 #include "net_user.h"
 #include "slirp.h"
 #include "slip_common.h"
-#include "helper.h"
 #include "os.h"
 
 void slirp_user_init(void *data, void *dev)
index 90e0e5ff451e1cc2f21909ff90b6a40575172baa..b530f1a6540d506a556e38c90dc3afec63f2f7f6 100644 (file)
@@ -14,7 +14,6 @@
 #include <sys/socket.h>
 #include "kern_util.h"
 #include "chan_user.h"
-#include "helper.h"
 #include "user_util.h"
 #include "user.h"
 #include "os.h"
diff --git a/arch/um/include/helper.h b/arch/um/include/helper.h
deleted file mode 100644 (file)
index 162ac31..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-/* 
- * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
-
-#ifndef __HELPER_H__
-#define __HELPER_H__
-
-extern int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv,
-                     unsigned long *stack_out);
-extern int run_helper_thread(int (*proc)(void *), void *arg, 
-                            unsigned int flags, unsigned long *stack_out,
-                            int stack_order);
-extern int helper_wait(int pid);
-
-#endif
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
index 9fef4123a65a72af9baada02ecd1cb775d571d8b..a1064c5823bfe92c8e5c83c71592e37ceacd5e69 100644 (file)
@@ -57,7 +57,7 @@ extern int init_maps(unsigned long physmem, unsigned long iomem,
                     unsigned long highmem);
 extern unsigned long get_vm(unsigned long len);
 extern void setup_physmem(unsigned long start, unsigned long usable,
-                         unsigned long len, unsigned long highmem);
+                         unsigned long len, unsigned long long highmem);
 extern void add_iomem(char *name, int fd, unsigned long size);
 extern unsigned long phys_offset(unsigned long phys);
 extern void unmap_physmem(void);
index 89885a77a771f203edbbf39d6fadd6742e54e2e2..800c403920bc707780135d0227c32d9b3d8cc96b 100644 (file)
@@ -25,7 +25,7 @@ struct net_user_info {
 };
 
 extern void ether_user_init(void *data, void *dev);
-extern void dev_ip_addr(void *d, char *buf, char *bin_buf);
+extern void dev_ip_addr(void *d, unsigned char *bin_buf);
 extern void set_ether_mac(void *d, unsigned char *addr);
 extern void iter_addresses(void *d, void (*cb)(unsigned char *, 
                                               unsigned char *, void *), 
index 2e58e304b8be6ce3dc867ba2418432735fc07058..2cccfa5b8ab5f53cc5f340800b1486bf3b582925 100644 (file)
@@ -167,7 +167,7 @@ extern int can_do_skas(void);
 #endif
 
 /* mem.c */
-extern int create_mem_file(unsigned long len);
+extern int create_mem_file(unsigned long long len);
 
 /* process.c */
 extern unsigned long os_process_pc(int pid);
@@ -199,6 +199,20 @@ extern void forward_pending_sigio(int target);
 extern int start_fork_tramp(void *arg, unsigned long temp_stack,
                            int clone_flags, int (*tramp)(void *));
 
+/* uaccess.c */
+extern unsigned long __do_user_copy(void *to, const void *from, int n,
+                                   void **fault_addr, void **fault_catcher,
+                                   void (*op)(void *to, const void *from,
+                                              int n), int *faulted_out);
+
+/* helper.c */
+extern int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv,
+                     unsigned long *stack_out);
+extern int run_helper_thread(int (*proc)(void *), void *arg,
+                            unsigned int flags, unsigned long *stack_out,
+                            int stack_order);
+extern int helper_wait(int pid);
+
 #endif
 
 /*
index d3699fe1c6133b001e9b09c50e904f3fc5b944d5..a49ceb199ee57e2c5150f93373dc994fe7d00f30 100644 (file)
@@ -16,45 +16,69 @@ extern void stub_clone_handler(void);
 #define STUB_MMAP_NR __NR_mmap2
 #define MMAP_OFFSET(o) ((o) >> PAGE_SHIFT)
 
+static inline long stub_syscall1(long syscall, long arg1)
+{
+       long ret;
+
+       __asm__ volatile ("int $0x80" : "=a" (ret) : "0" (syscall), "b" (arg1));
+
+       return ret;
+}
+
 static inline long stub_syscall2(long syscall, long arg1, long arg2)
 {
        long ret;
 
-       __asm__("movl %0, %%ecx; " : : "g" (arg2) : "%ecx");
-       __asm__("movl %0, %%ebx; " : : "g" (arg1) : "%ebx");
-       __asm__("movl %0, %%eax; " : : "g" (syscall) : "%eax");
-       __asm__("int $0x80;" : : : "%eax");
-       __asm__ __volatile__("movl %%eax, %0; " : "=g" (ret) :);
-       return(ret);
+       __asm__ volatile ("int $0x80" : "=a" (ret) : "0" (syscall), "b" (arg1),
+                       "c" (arg2));
+
+       return ret;
 }
 
 static inline long stub_syscall3(long syscall, long arg1, long arg2, long arg3)
 {
-       __asm__("movl %0, %%edx; " : : "g" (arg3) : "%edx");
-       return(stub_syscall2(syscall, arg1, arg2));
+       long ret;
+
+       __asm__ volatile ("int $0x80" : "=a" (ret) : "0" (syscall), "b" (arg1),
+                       "c" (arg2), "d" (arg3));
+
+       return ret;
 }
 
 static inline long stub_syscall4(long syscall, long arg1, long arg2, long arg3,
                                 long arg4)
 {
-       __asm__("movl %0, %%esi; " : : "g" (arg4) : "%esi");
-       return(stub_syscall3(syscall, arg1, arg2, arg3));
+       long ret;
+
+       __asm__ volatile ("int $0x80" : "=a" (ret) : "0" (syscall), "b" (arg1),
+                       "c" (arg2), "d" (arg3), "S" (arg4));
+
+       return ret;
+}
+
+static inline long stub_syscall5(long syscall, long arg1, long arg2, long arg3,
+                                long arg4, long arg5)
+{
+       long ret;
+
+       __asm__ volatile ("int $0x80" : "=a" (ret) : "0" (syscall), "b" (arg1),
+                       "c" (arg2), "d" (arg3), "S" (arg4), "D" (arg5));
+
+       return ret;
 }
 
 static inline long stub_syscall6(long syscall, long arg1, long arg2, long arg3,
                                 long arg4, long arg5, long arg6)
 {
        long ret;
-       __asm__("movl %0, %%eax; " : : "g" (syscall) : "%eax");
-       __asm__("movl %0, %%ebx; " : : "g" (arg1) : "%ebx");
-       __asm__("movl %0, %%ecx; " : : "g" (arg2) : "%ecx");
-       __asm__("movl %0, %%edx; " : : "g" (arg3) : "%edx");
-       __asm__("movl %0, %%esi; " : : "g" (arg4) : "%esi");
-       __asm__("movl %0, %%edi; " : : "g" (arg5) : "%edi");
-       __asm__ __volatile__("pushl %%ebp ; movl %1, %%ebp; "
-               "int $0x80; popl %%ebp ; "
-               "movl %%eax, %0; " : "=g" (ret) : "g" (arg6) : "%eax");
-       return(ret);
+
+       __asm__ volatile ("push %%ebp ; movl %%eax,%%ebp ; movl %1,%%eax ; "
+                       "int $0x80 ; pop %%ebp"
+                       : "=a" (ret)
+                       : "g" (syscall), "b" (arg1), "c" (arg2), "d" (arg3),
+                         "S" (arg4), "D" (arg5), "0" (arg6));
+
+       return ret;
 }
 
 static inline void trap_myself(void)
index f599058d8263a95d8fb27ab335e66a7e35b833a6..2bd6e7a972866c0d8130101a3a78679af0b91f13 100644 (file)
@@ -17,37 +17,72 @@ extern void stub_clone_handler(void);
 #define STUB_MMAP_NR __NR_mmap
 #define MMAP_OFFSET(o) (o)
 
+#define __syscall_clobber "r11","rcx","memory"
+#define __syscall "syscall"
+
 static inline long stub_syscall2(long syscall, long arg1, long arg2)
 {
        long ret;
 
-       __asm__("movq %0, %%rsi; " : : "g" (arg2) : "%rsi");
-       __asm__("movq %0, %%rdi; " : : "g" (arg1) : "%rdi");
-       __asm__("movq %0, %%rax; " : : "g" (syscall) : "%rax");
-       __asm__("syscall;" : : : "%rax", "%r11", "%rcx");
-       __asm__ __volatile__("movq %%rax, %0; " : "=g" (ret) :);
-       return(ret);
+       __asm__ volatile (__syscall
+               : "=a" (ret)
+               : "0" (syscall), "D" (arg1), "S" (arg2) : __syscall_clobber );
+
+       return ret;
 }
 
 static inline long stub_syscall3(long syscall, long arg1, long arg2, long arg3)
 {
-       __asm__("movq %0, %%rdx; " : : "g" (arg3) : "%rdx");
-       return(stub_syscall2(syscall, arg1, arg2));
+       long ret;
+
+       __asm__ volatile (__syscall
+               : "=a" (ret)
+               : "0" (syscall), "D" (arg1), "S" (arg2), "d" (arg3)
+               : __syscall_clobber );
+
+       return ret;
 }
 
 static inline long stub_syscall4(long syscall, long arg1, long arg2, long arg3,
                                 long arg4)
 {
-       __asm__("movq %0, %%r10; " : : "g" (arg4) : "%r10");
-       return(stub_syscall3(syscall, arg1, arg2, arg3));
+       long ret;
+
+       __asm__ volatile ("movq %5,%%r10 ; " __syscall
+               : "=a" (ret)
+               : "0" (syscall), "D" (arg1), "S" (arg2), "d" (arg3),
+                 "g" (arg4)
+               : __syscall_clobber, "r10" );
+
+       return ret;
+}
+
+static inline long stub_syscall5(long syscall, long arg1, long arg2, long arg3,
+                                long arg4, long arg5)
+{
+       long ret;
+
+       __asm__ volatile ("movq %5,%%r10 ; movq %6,%%r8 ; " __syscall
+               : "=a" (ret)
+               : "0" (syscall), "D" (arg1), "S" (arg2), "d" (arg3),
+                 "g" (arg4), "g" (arg5)
+               : __syscall_clobber, "r10", "r8" );
+
+       return ret;
 }
 
 static inline long stub_syscall6(long syscall, long arg1, long arg2, long arg3,
                                 long arg4, long arg5, long arg6)
 {
-       __asm__("movq %0, %%r9; " : : "g" (arg6) : "%r9");
-       __asm__("movq %0, %%r8; " : : "g" (arg5) : "%r8");
-       return(stub_syscall4(syscall, arg1, arg2, arg3, arg4));
+       long ret;
+
+       __asm__ volatile ("movq %5,%%r10 ; movq %6,%%r8 ; "
+               "movq %7, %%r9; " __syscall : "=a" (ret)
+               : "0" (syscall), "D" (arg1), "S" (arg2), "d" (arg3),
+                 "g" (arg4), "g" (arg5), "g" (arg6)
+               : __syscall_clobber, "r10", "r8", "r9" );
+
+       return ret;
 }
 
 static inline void trap_myself(void)
index f77eb64284538574e6e9f831d8679ab374950bdc..c0df11d06f5e791adaa27546b8d8270c7aac885e 100644 (file)
@@ -8,10 +8,6 @@
 
 extern int __do_copy_to_user(void *to, const void *from, int n,
                             void **fault_addr, void **fault_catcher);
-extern unsigned long __do_user_copy(void *to, const void *from, int n,
-                                   void **fault_addr, void **fault_catcher,
-                                   void (*op)(void *to, const void *from,
-                                              int n), int *faulted_out);
 void __do_copy(void *to, const void *from, int n);
 
 #endif
index 1a0001b3850caf86c00ef2c61f0258ed67666c5c..3de9d21e36bf042156b8b6c61cd8831c8885abea 100644 (file)
@@ -7,10 +7,10 @@ extra-y := vmlinux.lds
 clean-files :=
 
 obj-y = config.o exec_kern.o exitcode.o \
-       helper.o init_task.o irq.o irq_user.o ksyms.o main.o mem.o physmem.o \
+       init_task.o irq.o irq_user.o ksyms.o mem.o physmem.o \
        process_kern.o ptrace.o reboot.o resource.o sigio_user.o sigio_kern.o \
        signal_kern.o signal_user.o smp.o syscall_kern.o sysrq.o time.o \
-       time_kern.o tlb.o trap_kern.o trap_user.o uaccess_user.o um_arch.o \
+       time_kern.o tlb.o trap_kern.o trap_user.o uaccess.o um_arch.o \
        umid.o user_util.o
 
 obj-$(CONFIG_BLK_DEV_INITRD) += initrd.o
@@ -24,8 +24,7 @@ obj-$(CONFIG_MODE_SKAS) += skas/
 
 user-objs-$(CONFIG_TTY_LOG) += tty_log.o
 
-USER_OBJS := $(user-objs-y) config.o helper.o main.o time.o tty_log.o umid.o \
-       user_util.o
+USER_OBJS := $(user-objs-y) config.o time.o tty_log.o umid.o user_util.o
 
 include arch/um/scripts/Makefile.rules
 
index a97a72e516aa6f6c6b7b4e6e0e4814b6e24f3a69..7713e7a6f476fcdf910a99565be74ccdb01828f5 100644 (file)
@@ -20,7 +20,6 @@
 #include "user_util.h"
 #include "mem_user.h"
 #include "os.h"
-#include "helper.h"
 
 EXPORT_SYMBOL(stop);
 EXPORT_SYMBOL(uml_physmem);
index 462cc9d65386a60bcfc57969158c0fc1263f85c8..fa4f915be5c59e15fb5c393e12f40e0a0f77f24e 100644 (file)
@@ -234,8 +234,8 @@ void paging_init(void)
        empty_bad_page = (unsigned long *) alloc_bootmem_low_pages(PAGE_SIZE);
        for(i=0;i<sizeof(zones_size)/sizeof(zones_size[0]);i++) 
                zones_size[i] = 0;
-       zones_size[0] = (end_iomem >> PAGE_SHIFT) - (uml_physmem >> PAGE_SHIFT);
-       zones_size[2] = highmem >> PAGE_SHIFT;
+       zones_size[ZONE_DMA] = (end_iomem >> PAGE_SHIFT) - (uml_physmem >> PAGE_SHIFT);
+       zones_size[ZONE_HIGHMEM] = highmem >> PAGE_SHIFT;
        free_area_init(zones_size);
 
        /*
index ea670fcc8af5b3c52b020afe31fbd09f02df97cd..f3b583a878a6c9a4504e68f4bbce985251101fe6 100644 (file)
@@ -246,7 +246,7 @@ int is_remapped(void *virt)
 /* Changed during early boot */
 unsigned long high_physmem;
 
-extern unsigned long physmem_size;
+extern unsigned long long physmem_size;
 
 int init_maps(unsigned long physmem, unsigned long iomem, unsigned long highmem)
 {
@@ -321,7 +321,7 @@ void map_memory(unsigned long virt, unsigned long phys, unsigned long len,
 extern int __syscall_stub_start, __binary_start;
 
 void setup_physmem(unsigned long start, unsigned long reserve_end,
-                  unsigned long len, unsigned long highmem)
+                  unsigned long len, unsigned long long highmem)
 {
        unsigned long reserve = reserve_end - start;
        int pfn = PFN_UP(__pa(reserve_end));
index 71af4d5038994014f12e5030dd3187bcbaae9450..98e09395c093c1d75be57ab82ed3b46c084e533f 100644 (file)
@@ -43,53 +43,10 @@ void ptrace_disable(struct task_struct *child)
 extern int peek_user(struct task_struct * child, long addr, long data);
 extern int poke_user(struct task_struct * child, long addr, long data);
 
-long sys_ptrace(long request, long pid, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
 {
-       struct task_struct *child;
        int i, ret;
 
-       lock_kernel();
-       ret = -EPERM;
-       if (request == PTRACE_TRACEME) {
-               /* are we already being traced? */
-               if (current->ptrace & PT_PTRACED)
-                       goto out;
-
-               ret = security_ptrace(current->parent, current);
-               if (ret)
-                       goto out;
-
-               /* set the ptrace bit in the process flags. */
-               current->ptrace |= PT_PTRACED;
-               ret = 0;
-               goto out;
-       }
-       ret = -ESRCH;
-       read_lock(&tasklist_lock);
-       child = find_task_by_pid(pid);
-       if (child)
-               get_task_struct(child);
-       read_unlock(&tasklist_lock);
-       if (!child)
-               goto out;
-
-       ret = -EPERM;
-       if (pid == 1)           /* you may not mess with init */
-               goto out_tsk;
-
-       if (request == PTRACE_ATTACH) {
-               ret = ptrace_attach(child);
-               goto out_tsk;
-       }
-
-#ifdef SUBACH_PTRACE_SPECIAL
-        SUBARCH_PTRACE_SPECIAL(child,request,addr,data);
-#endif
-
-       ret = ptrace_check_attach(child, request == PTRACE_KILL);
-       if (ret < 0)
-               goto out_tsk;
-
        switch (request) {
                /* when I and D space are separate, these will need to be fixed. */
        case PTRACE_PEEKTEXT: /* read word at location addr. */ 
@@ -282,10 +239,7 @@ long sys_ptrace(long request, long pid, long addr, long data)
                ret = ptrace_request(child, request, addr, data);
                break;
        }
- out_tsk:
-       put_task_struct(child);
- out:
-       unlock_kernel();
+
        return ret;
 }
 
index a52751108aa125c3299926efdb8d8aad53496a72..48b1f644b9a624a66ce16c782c832d84c4c2a074 100644 (file)
@@ -18,7 +18,6 @@
 #include "kern_util.h"
 #include "user_util.h"
 #include "sigio.h"
-#include "helper.h"
 #include "os.h"
 
 /* Changed during early boot */
@@ -225,7 +224,7 @@ static int need_poll(int n)
                next_poll.used = n;
                return(0);
        }
-       if(next_poll.poll != NULL) kfree(next_poll.poll);
+       kfree(next_poll.poll);
        next_poll.poll = um_kmalloc_atomic(n * sizeof(struct pollfd));
        if(next_poll.poll == NULL){
                printk("need_poll : failed to allocate new pollfds\n");
index 09536f81ee42f6e527154d5085fa4f73865da114..44110c521e498bb2d86033d3dea5e71584346804 100644 (file)
@@ -8,6 +8,7 @@
 
 #include "linux/config.h"
 #include "mm_id.h"
+#include "asm/ldt.h"
 
 struct mmu_context_skas {
        struct mm_id id;
@@ -15,6 +16,7 @@ struct mmu_context_skas {
 #ifdef CONFIG_3_LEVEL_PGTABLES
         unsigned long last_pmd;
 #endif
+       uml_ldt_t ldt;
 };
 
 extern void switch_mm_skas(struct mm_id * mm_idp);
index 060934740f9f94e65ed1b4dafd2587b9836766ff..daa2f85b684c7dd14845b6d1a63560abad1de67c 100644 (file)
@@ -10,7 +10,8 @@
 #include "sysdep/ptrace.h"
 
 extern int userspace_pid[];
-extern int proc_mm, ptrace_faultinfo;
+extern int proc_mm, ptrace_faultinfo, ptrace_ldt;
+extern int skas_needs_stub;
 
 extern void switch_threads(void *me, void *next);
 extern void thread_wait(void *sw, void *fb);
index 147466d7ff4f1b90e6273f3b4f99e68f1ffb7c9f..88ab96c609cecec84b1e960a512dc7a10035d8a7 100644 (file)
@@ -20,7 +20,7 @@ unsigned long set_task_sizes_skas(int arg, unsigned long *host_size_out,
        *task_size_out = CONFIG_HOST_TASK_SIZE;
 #else
        *host_size_out = top;
-       if (proc_mm && ptrace_faultinfo)
+       if (!skas_needs_stub)
                *task_size_out = top;
        else *task_size_out = CONFIG_STUB_START & PGDIR_MASK;
 #endif
index 9e5e39cea821f8fe772c54b9363e7731cb22fc9a..677871f1b37c65d2379cd4b4b3f58e2fc9aec067 100644 (file)
@@ -15,6 +15,7 @@
 #include "asm/mmu.h"
 #include "asm/pgalloc.h"
 #include "asm/pgtable.h"
+#include "asm/ldt.h"
 #include "os.h"
 #include "skas.h"
 
@@ -74,13 +75,12 @@ static int init_stub_pte(struct mm_struct *mm, unsigned long proc,
 
 int init_new_context_skas(struct task_struct *task, struct mm_struct *mm)
 {
-       struct mm_struct *cur_mm = current->mm;
-       struct mm_id *cur_mm_id = &cur_mm->context.skas.id;
-       struct mm_id *mm_id = &mm->context.skas.id;
+       struct mmu_context_skas *from_mm = NULL;
+       struct mmu_context_skas *to_mm = &mm->context.skas;
        unsigned long stack = 0;
-       int from, ret = -ENOMEM;
+       int from_fd, ret = -ENOMEM;
 
-       if(!proc_mm || !ptrace_faultinfo){
+       if(skas_needs_stub){
                stack = get_zeroed_page(GFP_KERNEL);
                if(stack == 0)
                        goto out;
@@ -102,33 +102,43 @@ int init_new_context_skas(struct task_struct *task, struct mm_struct *mm)
 
                mm->nr_ptes--;
        }
-       mm_id->stack = stack;
+
+       to_mm->id.stack = stack;
+       if(current->mm != NULL && current->mm != &init_mm)
+               from_mm = &current->mm->context.skas;
 
        if(proc_mm){
-               if((cur_mm != NULL) && (cur_mm != &init_mm))
-                       from = cur_mm_id->u.mm_fd;
-               else from = -1;
+               if(from_mm)
+                       from_fd = from_mm->id.u.mm_fd;
+               else from_fd = -1;
 
-               ret = new_mm(from, stack);
+               ret = new_mm(from_fd, stack);
                if(ret < 0){
                        printk("init_new_context_skas - new_mm failed, "
                               "errno = %d\n", ret);
                        goto out_free;
                }
-               mm_id->u.mm_fd = ret;
+               to_mm->id.u.mm_fd = ret;
        }
        else {
-               if((cur_mm != NULL) && (cur_mm != &init_mm))
-                       mm_id->u.pid = copy_context_skas0(stack,
-                                                         cur_mm_id->u.pid);
-               else mm_id->u.pid = start_userspace(stack);
+               if(from_mm)
+                       to_mm->id.u.pid = copy_context_skas0(stack,
+                                                            from_mm->id.u.pid);
+               else to_mm->id.u.pid = start_userspace(stack);
+       }
+
+       ret = init_new_ldt(to_mm, from_mm);
+       if(ret < 0){
+               printk("init_new_context_skas - init_ldt"
+                      " failed, errno = %d\n", ret);
+               goto out_free;
        }
 
        return 0;
 
  out_free:
-       if(mm_id->stack != 0)
-               free_page(mm_id->stack);
+       if(to_mm->id.stack != 0)
+               free_page(to_mm->id.stack);
  out:
        return ret;
 }
index 5cd0e992978969c8d076b3fd9ce4fd0fe9d3a4c1..599d679bd4fcb3bfdebff8355d69e8d5b7a13274 100644 (file)
@@ -69,6 +69,17 @@ void wait_stub_done(int pid, int sig, char * fname)
 
         if((n < 0) || !WIFSTOPPED(status) ||
            (WSTOPSIG(status) != SIGUSR1 && WSTOPSIG(status) != SIGTRAP)){
+               unsigned long regs[FRAME_SIZE];
+               if(ptrace(PTRACE_GETREGS, pid, 0, regs) < 0)
+                       printk("Failed to get registers from stub, "
+                              "errno = %d\n", errno);
+               else {
+                       int i;
+
+                       printk("Stub registers -\n");
+                       for(i = 0; i < FRAME_SIZE; i++)
+                               printk("\t%d - %lx\n", i, regs[i]);
+               }
                 panic("%s : failed to wait for SIGUSR1/SIGTRAP, "
                       "pid = %d, n = %d, errno = %d, status = 0x%x\n",
                       fname, pid, n, errno, status);
@@ -370,9 +381,9 @@ int copy_context_skas0(unsigned long new_stack, int pid)
 }
 
 /*
- * This is used only, if proc_mm is available, while PTRACE_FAULTINFO
- * isn't. Opening /proc/mm creates a new mm_context, which lacks the stub-pages
- * Thus, we map them using /proc/mm-fd
+ * This is used only, if stub pages are needed, while proc_mm is
+ * availabl. Opening /proc/mm creates a new mm_context, which lacks
+ * the stub-pages. Thus, we map them using /proc/mm-fd
  */
 void map_stub_pages(int fd, unsigned long code,
                    unsigned long data, unsigned long stack)
index efe92e8aa2a9e37ffba7974d1dd6ee842928e131..9c990253966c596af858b1dbd176084012cd48d2 100644 (file)
@@ -145,7 +145,7 @@ int new_mm(int from, unsigned long stack)
                               "err = %d\n", -n);
        }
 
-       if(!ptrace_faultinfo)
+       if(skas_needs_stub)
                map_stub_pages(fd, CONFIG_STUB_CODE, CONFIG_STUB_DATA, stack);
 
        return(fd);
index 8c220f054b611a3349114e69eb8fe8cb188e39ab..6c92bbccb49c30658295c9ea226258ce62c3b5af 100644 (file)
@@ -10,6 +10,7 @@
 #include "uml_uaccess.h"
 #include "task.h"
 #include "kern_util.h"
+#include "os.h"
 
 int __do_copy_from_user(void *to, const void *from, int n,
                        void **fault_addr, void **fault_catcher)
diff --git a/arch/um/kernel/uaccess.c b/arch/um/kernel/uaccess.c
new file mode 100644 (file)
index 0000000..054e3de
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2001 Chris Emerson (cemerson@chiark.greenend.org.uk)
+ * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
+ * Licensed under the GPL
+ */
+
+/* These are here rather than tt/uaccess.c because skas mode needs them in
+ * order to do SIGBUS recovery when a tmpfs mount runs out of room.
+ */
+
+#include <linux/string.h>
+#include "os.h"
+
+void __do_copy(void *to, const void *from, int n)
+{
+       memcpy(to, from, n);
+}
+
+
+int __do_copy_to_user(void *to, const void *from, int n,
+                     void **fault_addr, void **fault_catcher)
+{
+       unsigned long fault;
+       int faulted;
+
+       fault = __do_user_copy(to, from, n, fault_addr, fault_catcher,
+                              __do_copy, &faulted);
+       if(!faulted) return(0);
+       else return(n - (fault - (unsigned long) to));
+}
diff --git a/arch/um/kernel/uaccess_user.c b/arch/um/kernel/uaccess_user.c
deleted file mode 100644 (file)
index d035257..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-/* 
- * Copyright (C) 2001 Chris Emerson (cemerson@chiark.greenend.org.uk)
- * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
-
-#include <setjmp.h>
-#include <string.h>
-
-/* These are here rather than tt/uaccess.c because skas mode needs them in
- * order to do SIGBUS recovery when a tmpfs mount runs out of room.
- */
-
-unsigned long __do_user_copy(void *to, const void *from, int n,
-                            void **fault_addr, void **fault_catcher,
-                            void (*op)(void *to, const void *from,
-                                       int n), int *faulted_out)
-{
-       unsigned long *faddrp = (unsigned long *) fault_addr, ret;
-
-       sigjmp_buf jbuf;
-       *fault_catcher = &jbuf;
-       if(sigsetjmp(jbuf, 1) == 0){
-               (*op)(to, from, n);
-               ret = 0;
-               *faulted_out = 0;
-       } 
-       else {
-               ret = *faddrp;
-               *faulted_out = 1;
-       }
-       *fault_addr = NULL;
-       *fault_catcher = NULL;
-       return ret;
-}
-
-void __do_copy(void *to, const void *from, int n)
-{
-       memcpy(to, from, n);
-}      
-
-
-int __do_copy_to_user(void *to, const void *from, int n,
-                     void **fault_addr, void **fault_catcher)
-{
-       unsigned long fault;
-       int faulted;
-
-       fault = __do_user_copy(to, from, n, fault_addr, fault_catcher,
-                              __do_copy, &faulted);
-       if(!faulted) return(0);
-       else return(n - (fault - (unsigned long) to));
-}
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
index 93dc782dc1cc8f5d790b2151694c4caf757238d0..142a9493912b29955140df360e86a721a2c355a1 100644 (file)
@@ -137,7 +137,7 @@ static char *argv1_end = NULL;
 
 /* Set in early boot */
 static int have_root __initdata = 0;
-long physmem_size = 32 * 1024 * 1024;
+long long physmem_size = 32 * 1024 * 1024;
 
 void set_cmdline(char *cmd)
 {
@@ -402,7 +402,7 @@ int linux_main(int argc, char **argv)
 #ifndef CONFIG_HIGHMEM
                highmem = 0;
                printf("CONFIG_HIGHMEM not enabled - physical memory shrunk "
-                      "to %ld bytes\n", physmem_size);
+                      "to %lu bytes\n", physmem_size);
 #endif
        }
 
@@ -414,8 +414,8 @@ int linux_main(int argc, char **argv)
 
        setup_physmem(uml_physmem, uml_reserved, physmem_size, highmem);
        if(init_maps(physmem_size, iomem_size, highmem)){
-               printf("Failed to allocate mem_map for %ld bytes of physical "
-                      "memory and %ld bytes of highmem\n", physmem_size,
+               printf("Failed to allocate mem_map for %lu bytes of physical "
+                      "memory and %lu bytes of highmem\n", physmem_size,
                       highmem);
                exit(1);
        }
@@ -426,7 +426,7 @@ int linux_main(int argc, char **argv)
        end_vm = start_vm + virtmem_size;
 
        if(virtmem_size < physmem_size)
-               printf("Kernel virtual memory size shrunk to %ld bytes\n",
+               printf("Kernel virtual memory size shrunk to %lu bytes\n",
                       virtmem_size);
 
        uml_postsetup();
index 41d17c71511c51cf01077d51d2c6637863892c59..4c231161f25717b2bcbfad0c31598a87488beab0 100644 (file)
@@ -27,7 +27,6 @@
 #include "user.h"
 #include "mem_user.h"
 #include "init.h"
-#include "helper.h"
 #include "ptrace_user.h"
 #include "uml-config.h"
 
index d15ec2af6a224cda56b45d66cd8bf048c1c04d90..b83ac8e21c354eb6f7a27b21599569c31157143b 100644 (file)
@@ -3,11 +3,12 @@
 # Licensed under the GPL
 #
 
-obj-y = aio.o elf_aux.o file.o mem.o process.o signal.o start_up.o time.o \
-       tt.o tty.o user_syms.o drivers/ sys-$(SUBARCH)/
+obj-y = aio.o elf_aux.o file.o helper.o main.o mem.o process.o signal.o \
+       start_up.o time.o tt.o tty.o uaccess.o user_syms.o drivers/ \
+       sys-$(SUBARCH)/
 
-USER_OBJS := aio.o elf_aux.o file.o mem.o process.o signal.o start_up.o \
-       time.o tt.o tty.o
+USER_OBJS := aio.o elf_aux.o file.o helper.o main.o mem.o process.o signal.o \
+       start_up.o time.o tt.o tty.o uaccess.o
 
 elf_aux.o: $(ARCH_DIR)/kernel-offsets.h
 CFLAGS_elf_aux.o += -I$(objtree)/arch/um
index 41cfb09442013325f7511949f8d6171e2bbac487..ffa759addd3c657e7292c07482d49d6dbc24bc38 100644 (file)
@@ -10,7 +10,6 @@
 #include <sched.h>
 #include <sys/syscall.h>
 #include "os.h"
-#include "helper.h"
 #include "aio.h"
 #include "init.h"
 #include "user.h"
index cd4d6544da715eef01010a61ea46ff127651f9af..901b85e8a1c65c4df84ae87018b3d55cefd45698 100644 (file)
@@ -19,7 +19,6 @@
 #include "user_util.h"
 #include "net_user.h"
 #include "etap.h"
-#include "helper.h"
 #include "os.h"
 
 #define MAX_PACKET ETH_MAX_PACKET
index 4ba9b17adf13cac85f62dfc224218bbeb9b354d7..52945338b64d503ea13c0d20ad4d45ba607e53f5 100644 (file)
@@ -20,7 +20,6 @@
 #include "kern_util.h"
 #include "user_util.h"
 #include "user.h"
-#include "helper.h"
 #include "os.h"
 
 #define MAX_PACKET ETH_MAX_PACKET
similarity index 93%
rename from arch/um/kernel/helper.c
rename to arch/um/os-Linux/helper.c
index 33fb0bd3b11a13af3f0db7ddf272af3aa4f3e871..36cc8475bcdacc76aba1d932a7d2a41eff6392d8 100644 (file)
@@ -1,4 +1,4 @@
-/* 
+/*
  * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
  * Licensed under the GPL
  */
@@ -13,7 +13,6 @@
 #include "user.h"
 #include "kern_util.h"
 #include "user_util.h"
-#include "helper.h"
 #include "os.h"
 
 struct helper_data {
@@ -46,7 +45,7 @@ static int helper_child(void *arg)
        errval = errno;
        printk("execvp of '%s' failed - errno = %d\n", argv[0], errno);
        os_write_file(data->fd, &errval, sizeof(errval));
-       os_kill_process(os_getpid(), 0);
+       kill(os_getpid(), SIGKILL);
        return(0);
 }
 
@@ -90,7 +89,7 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv,
                goto out_close;
        }
 
-       os_close_file(fds[1]);
+       close(fds[1]);
        fds[1] = -1;
 
        /*Read the errno value from the child.*/
@@ -98,7 +97,8 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv,
        if(n < 0){
                printk("run_helper : read on pipe failed, ret = %d\n", -n);
                ret = n;
-               os_kill_process(pid, 1);
+               kill(pid, SIGKILL);
+               CATCH_EINTR(waitpid(pid, NULL, 0));
        }
        else if(n != 0){
                CATCH_EINTR(n = waitpid(pid, NULL, 0));
@@ -109,8 +109,8 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv,
 
 out_close:
        if (fds[1] != -1)
-               os_close_file(fds[1]);
-       os_close_file(fds[0]);
+               close(fds[1]);
+       close(fds[0]);
 out_free:
        if(stack_out == NULL)
                free_stack(stack, 0);
@@ -118,7 +118,7 @@ out_free:
        return(ret);
 }
 
-int run_helper_thread(int (*proc)(void *), void *arg, unsigned int flags, 
+int run_helper_thread(int (*proc)(void *), void *arg, unsigned int flags,
                      unsigned long *stack_out, int stack_order)
 {
        unsigned long stack, sp;
@@ -131,7 +131,7 @@ int run_helper_thread(int (*proc)(void *), void *arg, unsigned int flags,
        pid = clone(proc, (void *) sp, flags | SIGCHLD, arg);
        if(pid < 0){
                err = -errno;
-               printk("run_helper_thread : clone failed, errno = %d\n", 
+               printk("run_helper_thread : clone failed, errno = %d\n",
                       errno);
                return err;
        }
similarity index 82%
rename from arch/um/kernel/main.c
rename to arch/um/os-Linux/main.c
index d31027f0fe392e9753fbe04e9ef106f719a2b5d4..23da27d22569da2308b373f0edd42a2b5757c710 100644 (file)
@@ -157,25 +157,25 @@ int main(int argc, char **argv, char **envp)
         */
        change_sig(SIGPROF, 0);
 
-        /* This signal stuff used to be in the reboot case.  However,
-         * sometimes a SIGVTALRM can come in when we're halting (reproducably
-         * when writing out gcov information, presumably because that takes
-         * some time) and cause a segfault.
-         */
-
-        /* stop timers and set SIG*ALRM to be ignored */
-        disable_timer();
-
-        /* disable SIGIO for the fds and set SIGIO to be ignored */
-        err = deactivate_all_fds();
-        if(err)
-                printf("deactivate_all_fds failed, errno = %d\n", -err);
-
-        /* Let any pending signals fire now.  This ensures
-         * that they won't be delivered after the exec, when
-         * they are definitely not expected.
-         */
-        unblock_signals();
+       /* This signal stuff used to be in the reboot case.  However,
+        * sometimes a SIGVTALRM can come in when we're halting (reproducably
+        * when writing out gcov information, presumably because that takes
+        * some time) and cause a segfault.
+        */
+
+       /* stop timers and set SIG*ALRM to be ignored */
+       disable_timer();
+
+       /* disable SIGIO for the fds and set SIGIO to be ignored */
+       err = deactivate_all_fds();
+       if(err)
+               printf("deactivate_all_fds failed, errno = %d\n", -err);
+
+       /* Let any pending signals fire now.  This ensures
+        * that they won't be delivered after the exec, when
+        * they are definitely not expected.
+        */
+       unblock_signals();
 
        /* Reboot */
        if(ret){
@@ -257,14 +257,3 @@ void __wrap_free(void *ptr)
        }
        else __real_free(ptr);
 }
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
index 8e71edaaf80b1f53b2a66afe2ec208df375c15c1..9d7d69a523bb551f069898bed0f2f2be7c4ef247 100644 (file)
@@ -88,7 +88,7 @@ int make_tempfile(const char *template, char **out_tempname, int do_unlink)
  * This proc is used in start_up.c
  * So it isn't 'static'.
  */
-int create_tmp_file(unsigned long len)
+int create_tmp_file(unsigned long long len)
 {
        int fd, err;
        char zero;
@@ -121,7 +121,7 @@ int create_tmp_file(unsigned long len)
        return(fd);
 }
 
-static int create_anon_file(unsigned long len)
+static int create_anon_file(unsigned long long len)
 {
        void *addr;
        int fd;
@@ -144,7 +144,7 @@ static int create_anon_file(unsigned long len)
 
 extern int have_devanon;
 
-int create_mem_file(unsigned long len)
+int create_mem_file(unsigned long long len)
 {
        int err, fd;
 
index b99ab414542fcb6700b39285fe28aeb5f881c33b..37517d49c4aea948054a70a17ec36c8f6b255b57 100644 (file)
@@ -135,7 +135,9 @@ static int stop_ptraced_child(int pid, void *stack, int exitcode,
 }
 
 int ptrace_faultinfo = 1;
+int ptrace_ldt = 1;
 int proc_mm = 1;
+int skas_needs_stub = 0;
 
 static int __init skas0_cmd_param(char *str, int* add)
 {
@@ -294,7 +296,7 @@ static void __init check_ptrace(void)
        check_sysemu();
 }
 
-extern int create_tmp_file(unsigned long len);
+extern int create_tmp_file(unsigned long long len);
 
 static void check_tmpexec(void)
 {
@@ -352,14 +354,26 @@ __uml_setup("noptracefaultinfo", noptracefaultinfo_cmd_param,
 "    it. To support PTRACE_FAULTINFO, the host needs to be patched\n"
 "    using the current skas3 patch.\n\n");
 
+static int __init noptraceldt_cmd_param(char *str, int* add)
+{
+       ptrace_ldt = 0;
+       return 0;
+}
+
+__uml_setup("noptraceldt", noptraceldt_cmd_param,
+"noptraceldt\n"
+"    Turns off usage of PTRACE_LDT, even if host supports it.\n"
+"    To support PTRACE_LDT, the host needs to be patched using\n"
+"    the current skas3 patch.\n\n");
+
 #ifdef UML_CONFIG_MODE_SKAS
-static inline void check_skas3_ptrace_support(void)
+static inline void check_skas3_ptrace_faultinfo(void)
 {
        struct ptrace_faultinfo fi;
        void *stack;
        int pid, n;
 
-       printf("Checking for the skas3 patch in the host...");
+       printf("  - PTRACE_FAULTINFO...");
        pid = start_ptraced_child(&stack);
 
        n = ptrace(PTRACE_FAULTINFO, pid, 0, &fi);
@@ -381,9 +395,49 @@ static inline void check_skas3_ptrace_support(void)
        stop_ptraced_child(pid, stack, 1, 1);
 }
 
-int can_do_skas(void)
+static inline void check_skas3_ptrace_ldt(void)
+{
+#ifdef PTRACE_LDT
+       void *stack;
+       int pid, n;
+       unsigned char ldtbuf[40];
+       struct ptrace_ldt ldt_op = (struct ptrace_ldt) {
+               .func = 2, /* read default ldt */
+               .ptr = ldtbuf,
+               .bytecount = sizeof(ldtbuf)};
+
+       printf("  - PTRACE_LDT...");
+       pid = start_ptraced_child(&stack);
+
+       n = ptrace(PTRACE_LDT, pid, 0, (unsigned long) &ldt_op);
+       if (n < 0) {
+               if(errno == EIO)
+                       printf("not found\n");
+               else {
+                       perror("not found");
+               }
+               ptrace_ldt = 0;
+       }
+       else {
+               if(ptrace_ldt)
+                       printf("found\n");
+               else
+                       printf("found, but use is disabled\n");
+       }
+
+       stop_ptraced_child(pid, stack, 1, 1);
+#else
+       /* PTRACE_LDT might be disabled via cmdline option.
+        * We want to override this, else we might use the stub
+        * without real need
+        */
+       ptrace_ldt = 1;
+#endif
+}
+
+static inline void check_skas3_proc_mm(void)
 {
-       printf("Checking for /proc/mm...");
+       printf("  - /proc/mm...");
        if (os_access("/proc/mm", OS_ACC_W_OK) < 0) {
                proc_mm = 0;
                printf("not found\n");
@@ -394,8 +448,19 @@ int can_do_skas(void)
                else
                        printf("found\n");
        }
+}
+
+int can_do_skas(void)
+{
+       printf("Checking for the skas3 patch in the host:\n");
+
+       check_skas3_proc_mm();
+       check_skas3_ptrace_faultinfo();
+       check_skas3_ptrace_ldt();
+
+       if(!proc_mm || !ptrace_faultinfo || !ptrace_ldt)
+               skas_needs_stub = 1;
 
-       check_skas3_ptrace_support();
        return 1;
 }
 #else
diff --git a/arch/um/os-Linux/uaccess.c b/arch/um/os-Linux/uaccess.c
new file mode 100644 (file)
index 0000000..38d7101
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2001 Chris Emerson (cemerson@chiark.greenend.org.uk)
+ * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
+ * Licensed under the GPL
+ */
+
+#include <setjmp.h>
+#include <string.h>
+
+unsigned long __do_user_copy(void *to, const void *from, int n,
+                            void **fault_addr, void **fault_catcher,
+                            void (*op)(void *to, const void *from,
+                                       int n), int *faulted_out)
+{
+       unsigned long *faddrp = (unsigned long *) fault_addr, ret;
+
+       sigjmp_buf jbuf;
+       *fault_catcher = &jbuf;
+       if(sigsetjmp(jbuf, 1) == 0){
+               (*op)(to, from, n);
+               ret = 0;
+               *faulted_out = 0;
+       }
+       else {
+               ret = *faddrp;
+               *faulted_out = 1;
+       }
+       *fault_addr = NULL;
+       *fault_catcher = NULL;
+       return ret;
+}
+
index 651d9d88b6564dd0c901aa451a5a6e1b2cbad5bb..b3fbf125709b83d5a1bf7814fab538455aa95f26 100644 (file)
@@ -26,8 +26,13 @@ define unprofile
        $(patsubst -pg,,$(patsubst -fprofile-arcs -ftest-coverage,,$(1)))
 endef
 
+# cmd_make_link checks to see if the $(foo-dir) variable starts with a /.  If
+# so, it's considered to be a path relative to $(srcdir) rather than
+# $(srcdir)/arch/$(SUBARCH).  This is because x86_64 wants to get ldt.c from
+# arch/um/sys-i386 rather than arch/i386 like the other borrowed files.  So,
+# it sets $(ldt.c-dir) to /arch/um/sys-i386.
 quiet_cmd_make_link = SYMLINK $@
-cmd_make_link       = ln -sf $(srctree)/arch/$(SUBARCH)/$($(notdir $@)-dir)/$(notdir $@) $@
+cmd_make_link       = rm -f $@; ln -sf $(srctree)$(if $(filter-out /%,$($(notdir $@)-dir)),/arch/$(SUBARCH))/$($(notdir $@)-dir)/$(notdir $@) $@
 
 # this needs to be before the foreach, because targets does not accept
 # complete paths like $(obj)/$(f). To make sure this works, use a := assignment
index 36b5c2c13289fd900e96f48d87c667f552b49721..6360f1c958d048db6fc46272f7671b5e5f21d0e6 100644 (file)
@@ -3,53 +3,26 @@
  * Licensed under the GPL
  */
 
+#include "linux/stddef.h"
 #include "linux/config.h"
 #include "linux/sched.h"
 #include "linux/slab.h"
 #include "linux/types.h"
+#include "linux/errno.h"
 #include "asm/uaccess.h"
-#include "asm/ptrace.h"
 #include "asm/smp.h"
 #include "asm/ldt.h"
+#include "asm/unistd.h"
 #include "choose-mode.h"
 #include "kern.h"
 #include "mode_kern.h"
 
-#ifdef CONFIG_MODE_TT
-
 extern int modify_ldt(int func, void *ptr, unsigned long bytecount);
 
-static int do_modify_ldt_tt(int func, void *ptr, unsigned long bytecount)
-{
-       return modify_ldt(func, ptr, bytecount);
-}
-
-#endif
-
-#ifdef CONFIG_MODE_SKAS
-
-#include "skas.h"
-#include "skas_ptrace.h"
-
-static int do_modify_ldt_skas(int func, void *ptr, unsigned long bytecount)
-{
-       struct ptrace_ldt ldt;
-       u32 cpu;
-       int res;
-
-       ldt = ((struct ptrace_ldt) { .func      = func,
-                                    .ptr       = ptr,
-                                    .bytecount = bytecount });
-
-       cpu = get_cpu();
-       res = ptrace(PTRACE_LDT, userspace_pid[cpu], 0, (unsigned long) &ldt);
-       put_cpu();
-
-       return res;
-}
-#endif
+#ifdef CONFIG_MODE_TT
 
-int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount)
+static long do_modify_ldt_tt(int func, void __user *ptr,
+                             unsigned long bytecount)
 {
        struct user_desc info;
        int res = 0;
@@ -89,8 +62,7 @@ int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount)
                goto out;
        }
 
-       res = CHOOSE_MODE_PROC(do_modify_ldt_tt, do_modify_ldt_skas, func,
-                               p, bytecount);
+       res = modify_ldt(func, p, bytecount);
        if(res < 0)
                goto out;
 
@@ -108,3 +80,467 @@ out:
        kfree(buf);
        return res;
 }
+
+#endif
+
+#ifdef CONFIG_MODE_SKAS
+
+#include "skas.h"
+#include "skas_ptrace.h"
+#include "asm/mmu_context.h"
+
+long write_ldt_entry(struct mm_id * mm_idp, int func, struct user_desc * desc,
+                    void **addr, int done)
+{
+       long res;
+
+       if(proc_mm){
+               /* This is a special handling for the case, that the mm to
+                * modify isn't current->active_mm.
+                * If this is called directly by modify_ldt,
+                *     (current->active_mm->context.skas.u == mm_idp)
+                * will be true. So no call to switch_mm_skas(mm_idp) is done.
+                * If this is called in case of init_new_ldt or PTRACE_LDT,
+                * mm_idp won't belong to current->active_mm, but child->mm.
+                * So we need to switch child's mm into our userspace, then
+                * later switch back.
+                *
+                * Note: I'm unshure: should interrupts be disabled here?
+                */
+               if(!current->active_mm || current->active_mm == &init_mm ||
+                  mm_idp != &current->active_mm->context.skas.id)
+                       switch_mm_skas(mm_idp);
+       }
+
+       if(ptrace_ldt) {
+               struct ptrace_ldt ldt_op = (struct ptrace_ldt) {
+                       .func = func,
+                       .ptr = desc,
+                       .bytecount = sizeof(*desc)};
+               u32 cpu;
+               int pid;
+
+               if(!proc_mm)
+                       pid = mm_idp->u.pid;
+               else {
+                       cpu = get_cpu();
+                       pid = userspace_pid[cpu];
+               }
+
+               res = ptrace(PTRACE_LDT, pid, 0, (unsigned long) &ldt_op);
+               if(res)
+                       res = errno;
+
+               if(proc_mm)
+                       put_cpu();
+       }
+       else {
+               void *stub_addr;
+               res = syscall_stub_data(mm_idp, (unsigned long *)desc,
+                                       (sizeof(*desc) + sizeof(long) - 1) &
+                                           ~(sizeof(long) - 1),
+                                       addr, &stub_addr);
+               if(!res){
+                       unsigned long args[] = { func,
+                                                (unsigned long)stub_addr,
+                                                sizeof(*desc),
+                                                0, 0, 0 };
+                       res = run_syscall_stub(mm_idp, __NR_modify_ldt, args,
+                                              0, addr, done);
+               }
+       }
+
+       if(proc_mm){
+               /* This is the second part of special handling, that makes
+                * PTRACE_LDT possible to implement.
+                */
+               if(current->active_mm && current->active_mm != &init_mm &&
+                  mm_idp != &current->active_mm->context.skas.id)
+                       switch_mm_skas(&current->active_mm->context.skas.id);
+       }
+
+       return res;
+}
+
+static long read_ldt_from_host(void __user * ptr, unsigned long bytecount)
+{
+       int res, n;
+       struct ptrace_ldt ptrace_ldt = (struct ptrace_ldt) {
+                       .func = 0,
+                       .bytecount = bytecount,
+                       .ptr = (void *)kmalloc(bytecount, GFP_KERNEL)};
+       u32 cpu;
+
+       if(ptrace_ldt.ptr == NULL)
+               return -ENOMEM;
+
+       /* This is called from sys_modify_ldt only, so userspace_pid gives
+        * us the right number
+        */
+
+       cpu = get_cpu();
+       res = ptrace(PTRACE_LDT, userspace_pid[cpu], 0,
+                    (unsigned long) &ptrace_ldt);
+       put_cpu();
+       if(res < 0)
+               goto out;
+
+       n = copy_to_user(ptr, ptrace_ldt.ptr, res);
+       if(n != 0)
+               res = -EFAULT;
+
+  out:
+       kfree(ptrace_ldt.ptr);
+
+       return res;
+}
+
+/*
+ * In skas mode, we hold our own ldt data in UML.
+ * Thus, the code implementing sys_modify_ldt_skas
+ * is very similar to (and mostly stolen from) sys_modify_ldt
+ * for arch/i386/kernel/ldt.c
+ * The routines copied and modified in part are:
+ * - read_ldt
+ * - read_default_ldt
+ * - write_ldt
+ * - sys_modify_ldt_skas
+ */
+
+static int read_ldt(void __user * ptr, unsigned long bytecount)
+{
+       int i, err = 0;
+       unsigned long size;
+       uml_ldt_t * ldt = &current->mm->context.skas.ldt;
+
+       if(!ldt->entry_count)
+               goto out;
+       if(bytecount > LDT_ENTRY_SIZE*LDT_ENTRIES)
+               bytecount = LDT_ENTRY_SIZE*LDT_ENTRIES;
+       err = bytecount;
+
+       if(ptrace_ldt){
+               return read_ldt_from_host(ptr, bytecount);
+       }
+
+       down(&ldt->semaphore);
+       if(ldt->entry_count <= LDT_DIRECT_ENTRIES){
+               size = LDT_ENTRY_SIZE*LDT_DIRECT_ENTRIES;
+               if(size > bytecount)
+                       size = bytecount;
+               if(copy_to_user(ptr, ldt->entries, size))
+                       err = -EFAULT;
+               bytecount -= size;
+               ptr += size;
+       }
+       else {
+               for(i=0; i<ldt->entry_count/LDT_ENTRIES_PER_PAGE && bytecount;
+                        i++){
+                       size = PAGE_SIZE;
+                       if(size > bytecount)
+                               size = bytecount;
+                       if(copy_to_user(ptr, ldt->pages[i], size)){
+                               err = -EFAULT;
+                               break;
+                       }
+                       bytecount -= size;
+                       ptr += size;
+               }
+       }
+       up(&ldt->semaphore);
+
+       if(bytecount == 0 || err == -EFAULT)
+               goto out;
+
+       if(clear_user(ptr, bytecount))
+               err = -EFAULT;
+
+out:
+       return err;
+}
+
+static int read_default_ldt(void __user * ptr, unsigned long bytecount)
+{
+       int err;
+
+       if(bytecount > 5*LDT_ENTRY_SIZE)
+               bytecount = 5*LDT_ENTRY_SIZE;
+
+       err = bytecount;
+       /* UML doesn't support lcall7 and lcall27.
+        * So, we don't really have a default ldt, but emulate
+        * an empty ldt of common host default ldt size.
+        */
+       if(clear_user(ptr, bytecount))
+               err = -EFAULT;
+
+       return err;
+}
+
+static int write_ldt(void __user * ptr, unsigned long bytecount, int func)
+{
+       uml_ldt_t * ldt = &current->mm->context.skas.ldt;
+       struct mm_id * mm_idp = &current->mm->context.skas.id;
+       int i, err;
+       struct user_desc ldt_info;
+       struct ldt_entry entry0, *ldt_p;
+       void *addr = NULL;
+
+       err = -EINVAL;
+       if(bytecount != sizeof(ldt_info))
+               goto out;
+       err = -EFAULT;
+       if(copy_from_user(&ldt_info, ptr, sizeof(ldt_info)))
+               goto out;
+
+       err = -EINVAL;
+       if(ldt_info.entry_number >= LDT_ENTRIES)
+               goto out;
+       if(ldt_info.contents == 3){
+               if (func == 1)
+                       goto out;
+               if (ldt_info.seg_not_present == 0)
+                       goto out;
+       }
+
+        if(!ptrace_ldt)
+                down(&ldt->semaphore);
+
+       err = write_ldt_entry(mm_idp, func, &ldt_info, &addr, 1);
+       if(err)
+               goto out_unlock;
+        else if(ptrace_ldt) {
+       /* With PTRACE_LDT available, this is used as a flag only */
+                ldt->entry_count = 1;
+                goto out;
+        }
+
+       if(ldt_info.entry_number >= ldt->entry_count &&
+          ldt_info.entry_number >= LDT_DIRECT_ENTRIES){
+               for(i=ldt->entry_count/LDT_ENTRIES_PER_PAGE;
+                   i*LDT_ENTRIES_PER_PAGE <= ldt_info.entry_number;
+                   i++){
+                       if(i == 0)
+                               memcpy(&entry0, ldt->entries, sizeof(entry0));
+                       ldt->pages[i] = (struct ldt_entry *)
+                                       __get_free_page(GFP_KERNEL|__GFP_ZERO);
+                       if(!ldt->pages[i]){
+                               err = -ENOMEM;
+                               /* Undo the change in host */
+                               memset(&ldt_info, 0, sizeof(ldt_info));
+                               write_ldt_entry(mm_idp, 1, &ldt_info, &addr, 1);
+                               goto out_unlock;
+                       }
+                       if(i == 0) {
+                               memcpy(ldt->pages[0], &entry0, sizeof(entry0));
+                               memcpy(ldt->pages[0]+1, ldt->entries+1,
+                                      sizeof(entry0)*(LDT_DIRECT_ENTRIES-1));
+                       }
+                       ldt->entry_count = (i + 1) * LDT_ENTRIES_PER_PAGE;
+               }
+       }
+       if(ldt->entry_count <= ldt_info.entry_number)
+               ldt->entry_count = ldt_info.entry_number + 1;
+
+       if(ldt->entry_count <= LDT_DIRECT_ENTRIES)
+               ldt_p = ldt->entries + ldt_info.entry_number;
+       else
+               ldt_p = ldt->pages[ldt_info.entry_number/LDT_ENTRIES_PER_PAGE] +
+                       ldt_info.entry_number%LDT_ENTRIES_PER_PAGE;
+
+       if(ldt_info.base_addr == 0 && ldt_info.limit == 0 &&
+          (func == 1 || LDT_empty(&ldt_info))){
+               ldt_p->a = 0;
+               ldt_p->b = 0;
+       }
+       else{
+               if (func == 1)
+                       ldt_info.useable = 0;
+               ldt_p->a = LDT_entry_a(&ldt_info);
+               ldt_p->b = LDT_entry_b(&ldt_info);
+       }
+       err = 0;
+
+out_unlock:
+       up(&ldt->semaphore);
+out:
+       return err;
+}
+
+static long do_modify_ldt_skas(int func, void __user *ptr,
+                              unsigned long bytecount)
+{
+       int ret = -ENOSYS;
+
+       switch (func) {
+               case 0:
+                       ret = read_ldt(ptr, bytecount);
+                       break;
+               case 1:
+               case 0x11:
+                       ret = write_ldt(ptr, bytecount, func);
+                       break;
+               case 2:
+                       ret = read_default_ldt(ptr, bytecount);
+                       break;
+       }
+       return ret;
+}
+
+short dummy_list[9] = {0, -1};
+short * host_ldt_entries = NULL;
+
+void ldt_get_host_info(void)
+{
+       long ret;
+       struct ldt_entry * ldt;
+       int i, size, k, order;
+
+       host_ldt_entries = dummy_list+1;
+
+       for(i = LDT_PAGES_MAX-1, order=0; i; i>>=1, order++);
+
+       ldt = (struct ldt_entry *)
+             __get_free_pages(GFP_KERNEL|__GFP_ZERO, order);
+       if(ldt == NULL) {
+               printk("ldt_get_host_info: couldn't allocate buffer for host ldt\n");
+               return;
+       }
+
+       ret = modify_ldt(0, ldt, (1<<order)*PAGE_SIZE);
+       if(ret < 0) {
+               printk("ldt_get_host_info: couldn't read host ldt\n");
+               goto out_free;
+       }
+       if(ret == 0) {
+               /* default_ldt is active, simply write an empty entry 0 */
+               host_ldt_entries = dummy_list;
+               goto out_free;
+       }
+
+       for(i=0, size=0; i<ret/LDT_ENTRY_SIZE; i++){
+               if(ldt[i].a != 0 || ldt[i].b != 0)
+                       size++;
+       }
+
+       if(size < sizeof(dummy_list)/sizeof(dummy_list[0])) {
+               host_ldt_entries = dummy_list;
+       }
+       else {
+               size = (size + 1) * sizeof(dummy_list[0]);
+               host_ldt_entries = (short *)kmalloc(size, GFP_KERNEL);
+               if(host_ldt_entries == NULL) {
+                       printk("ldt_get_host_info: couldn't allocate host ldt list\n");
+                       goto out_free;
+               }
+       }
+
+       for(i=0, k=0; i<ret/LDT_ENTRY_SIZE; i++){
+               if(ldt[i].a != 0 || ldt[i].b != 0) {
+                       host_ldt_entries[k++] = i;
+               }
+       }
+       host_ldt_entries[k] = -1;
+
+out_free:
+       free_pages((unsigned long)ldt, order);
+}
+
+long init_new_ldt(struct mmu_context_skas * new_mm,
+                 struct mmu_context_skas * from_mm)
+{
+       struct user_desc desc;
+       short * num_p;
+       int i;
+       long page, err=0;
+       void *addr = NULL;
+
+       memset(&desc, 0, sizeof(desc));
+
+       if(!ptrace_ldt)
+               init_MUTEX(&new_mm->ldt.semaphore);
+
+       if(!from_mm){
+               /*
+                * We have to initialize a clean ldt.
+                */
+               if(proc_mm) {
+                       /*
+                        * If the new mm was created using proc_mm, host's
+                        * default-ldt currently is assigned, which normally
+                        * contains the call-gates for lcall7 and lcall27.
+                        * To remove these gates, we simply write an empty
+                        * entry as number 0 to the host.
+                        */
+                       err = write_ldt_entry(&new_mm->id, 1, &desc,
+                                             &addr, 1);
+               }
+               else{
+                       /*
+                        * Now we try to retrieve info about the ldt, we
+                        * inherited from the host. All ldt-entries found
+                        * will be reset in the following loop
+                        */
+                       if(host_ldt_entries == NULL)
+                               ldt_get_host_info();
+                       for(num_p=host_ldt_entries; *num_p != -1; num_p++){
+                               desc.entry_number = *num_p;
+                               err = write_ldt_entry(&new_mm->id, 1, &desc,
+                                                     &addr, *(num_p + 1) == -1);
+                               if(err)
+                                       break;
+                       }
+               }
+               new_mm->ldt.entry_count = 0;
+       }
+       else if (!ptrace_ldt) {
+               /* Our local LDT is used to supply the data for
+                * modify_ldt(READLDT), if PTRACE_LDT isn't available,
+                * i.e., we have to use the stub for modify_ldt, which
+                * can't handle the big read buffer of up to 64kB.
+                */
+               down(&from_mm->ldt.semaphore);
+               if(from_mm->ldt.entry_count <= LDT_DIRECT_ENTRIES){
+                       memcpy(new_mm->ldt.entries, from_mm->ldt.entries,
+                              sizeof(new_mm->ldt.entries));
+               }
+               else{
+                       i = from_mm->ldt.entry_count / LDT_ENTRIES_PER_PAGE;
+                       while(i-->0){
+                               page = __get_free_page(GFP_KERNEL|__GFP_ZERO);
+                               if (!page){
+                                       err = -ENOMEM;
+                                       break;
+                               }
+                               new_mm->ldt.pages[i] = (struct ldt_entry*)page;
+                               memcpy(new_mm->ldt.pages[i],
+                                      from_mm->ldt.pages[i], PAGE_SIZE);
+                       }
+               }
+               new_mm->ldt.entry_count = from_mm->ldt.entry_count;
+               up(&from_mm->ldt.semaphore);
+       }
+
+       return err;
+}
+
+
+void free_ldt(struct mmu_context_skas * mm)
+{
+       int i;
+
+       if(!ptrace_ldt && mm->ldt.entry_count > LDT_DIRECT_ENTRIES){
+               i = mm->ldt.entry_count / LDT_ENTRIES_PER_PAGE;
+               while(i-- > 0){
+                       free_page((long )mm->ldt.pages[i]);
+               }
+       }
+       mm->ldt.entry_count = 0;
+}
+#endif
+
+int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount)
+{
+       return(CHOOSE_MODE_PROC(do_modify_ldt_tt, do_modify_ldt_skas, func,
+                               ptr, bytecount));
+}
index 06c3633457a2b28a9a6ad8b69dc523bb60d3ced9..ea977df395a10eb3254625e46b06483ce35d6b6b 100644 (file)
@@ -5,7 +5,7 @@
 #
 
 #XXX: why into lib-y?
-lib-y = bitops.o bugs.o csum-partial.o delay.o fault.o mem.o memcpy.o \
+lib-y = bitops.o bugs.o csum-partial.o delay.o fault.o ldt.o mem.o memcpy.o \
        ptrace.o ptrace_user.o sigcontext.o signal.o stub.o \
        stub_segv.o syscalls.o syscall_table.o sysrq.o thunk.o
 
@@ -14,7 +14,7 @@ obj-$(CONFIG_MODULES) += module.o um_module.o
 
 USER_OBJS := ptrace_user.o sigcontext.o
 
-SYMLINKS = bitops.c csum-copy.S csum-partial.c csum-wrappers.c memcpy.S \
+SYMLINKS = bitops.c csum-copy.S csum-partial.c csum-wrappers.c ldt.c memcpy.S \
        thunk.S module.c
 
 include arch/um/scripts/Makefile.rules
@@ -23,6 +23,7 @@ bitops.c-dir = lib
 csum-copy.S-dir = lib
 csum-partial.c-dir = lib
 csum-wrappers.c-dir = lib
+ldt.c-dir = /arch/um/sys-i386
 memcpy.S-dir = lib
 thunk.S-dir = lib
 module.c-dir = kernel
index 3259a4db453462e0d50b438ae295ff8cf9568326..6acee5c4ada6fcdff56ddd95313865dd295df508 100644 (file)
@@ -28,81 +28,6 @@ asmlinkage long sys_uname64(struct new_utsname __user * name)
        return err ? -EFAULT : 0;
 }
 
-#ifdef CONFIG_MODE_TT
-extern int modify_ldt(int func, void *ptr, unsigned long bytecount);
-
-long sys_modify_ldt_tt(int func, void *ptr, unsigned long bytecount)
-{
-       /* XXX This should check VERIFY_WRITE depending on func, check this
-        * in i386 as well.
-        */
-       if (!access_ok(VERIFY_READ, ptr, bytecount))
-               return -EFAULT;
-       return(modify_ldt(func, ptr, bytecount));
-}
-#endif
-
-#ifdef CONFIG_MODE_SKAS
-extern int userspace_pid[];
-
-#include "skas_ptrace.h"
-
-long sys_modify_ldt_skas(int func, void *ptr, unsigned long bytecount)
-{
-       struct ptrace_ldt ldt;
-        void *buf;
-        int res, n;
-
-        buf = kmalloc(bytecount, GFP_KERNEL);
-        if(buf == NULL)
-                return(-ENOMEM);
-
-        res = 0;
-
-        switch(func){
-        case 1:
-        case 0x11:
-                res = copy_from_user(buf, ptr, bytecount);
-                break;
-        }
-
-        if(res != 0){
-                res = -EFAULT;
-                goto out;
-        }
-
-       ldt = ((struct ptrace_ldt) { .func      = func,
-                                    .ptr       = buf,
-                                    .bytecount = bytecount });
-#warning Need to look up userspace_pid by cpu
-       res = ptrace(PTRACE_LDT, userspace_pid[0], 0, (unsigned long) &ldt);
-        if(res < 0)
-                goto out;
-
-        switch(func){
-        case 0:
-        case 2:
-                n = res;
-                res = copy_to_user(ptr, buf, n);
-                if(res != 0)
-                        res = -EFAULT;
-                else
-                        res = n;
-                break;
-        }
-
- out:
-        kfree(buf);
-        return(res);
-}
-#endif
-
-long sys_modify_ldt(int func, void *ptr, unsigned long bytecount)
-{
-        return(CHOOSE_MODE_PROC(sys_modify_ldt_tt, sys_modify_ldt_skas, func,
-                                ptr, bytecount));
-}
-
 #ifdef CONFIG_MODE_TT
 extern long arch_prctl(int code, unsigned long addr);
 
index d6077ff47d229282b3fcd7a1f0a8341bd932f392..18492d02aaf6dcffb146233fe14450493c9fcbce 100644 (file)
@@ -113,45 +113,10 @@ static int set_single_step (struct task_struct *t, int val)
        return 1;
 }
 
-long sys_ptrace(long request, long pid, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
 {
-       struct task_struct *child;
        int rval;
 
-       lock_kernel();
-
-       if (request == PTRACE_TRACEME) {
-               /* are we already being traced? */
-               if (current->ptrace & PT_PTRACED) {
-                       rval = -EPERM;
-                       goto out;
-               }
-               /* set the ptrace bit in the process flags. */
-               current->ptrace |= PT_PTRACED;
-               rval = 0;
-               goto out;
-       }
-       rval = -ESRCH;
-       read_lock(&tasklist_lock);
-       child = find_task_by_pid(pid);
-       if (child)
-               get_task_struct(child);
-       read_unlock(&tasklist_lock);
-       if (!child)
-               goto out;
-
-       rval = -EPERM;
-       if (pid == 1)           /* you may not mess with init */
-               goto out_tsk;
-
-       if (request == PTRACE_ATTACH) {
-               rval = ptrace_attach(child);
-               goto out_tsk;
-       }
-       rval = ptrace_check_attach(child, request == PTRACE_KILL);
-       if (rval < 0)
-               goto out_tsk;
-
        switch (request) {
                unsigned long val, copied;
 
@@ -248,11 +213,7 @@ long sys_ptrace(long request, long pid, long addr, long data)
                rval = -EIO;
                goto out;
        }
-
-out_tsk:
-       put_task_struct(child);
-out:
-       unlock_kernel();
+ out:
        return rval;
 }
 
index 21afa69a086d6826c41b6d26650486a941377b34..4cce2f6f170c0712dda1a1e6f60cbf545def6b70 100644 (file)
@@ -532,8 +532,21 @@ source "drivers/firmware/Kconfig"
 
 source fs/Kconfig
 
+menu "Instrumentation Support"
+        depends on EXPERIMENTAL
+
 source "arch/x86_64/oprofile/Kconfig"
 
+config KPROBES
+       bool "Kprobes (EXPERIMENTAL)"
+       help
+         Kprobes allows you to trap at almost any kernel address and
+         execute a callback function.  register_kprobe() establishes
+         a probepoint and specifies the callback.  Kprobes is useful
+         for kernel debugging, non-intrusive instrumentation and testing.
+         If in doubt, say "N".
+endmenu
+
 source "arch/x86_64/Kconfig.debug"
 
 source "security/Kconfig"
index 9cf1410d2f5ab0fbcab1a965637f556571c2a6df..d584ecc27ea1902e038329335486a60b8e72f9eb 100644 (file)
@@ -33,16 +33,6 @@ config IOMMU_DEBUG
         options. See Documentation/x86_64/boot-options.txt for more
         details.
 
-config KPROBES
-       bool "Kprobes"
-       depends on DEBUG_KERNEL
-       help
-         Kprobes allows you to trap at almost any kernel address and
-         execute a callback function.  register_kprobe() establishes
-         a probepoint and specifies the callback.  Kprobes is useful
-         for kernel debugging, non-intrusive instrumentation and testing.
-         If in doubt, say "N".
-
 config IOMMU_LEAK
        bool "IOMMU leak tracing"
        depends on DEBUG_KERNEL
index 76a28b007be95fcb17344fe48c7a1b93935a6bc0..dddeb678b440df5782af858f8db64100082c6f8a 100644 (file)
@@ -34,7 +34,6 @@
 #include <linux/config.h>
 #include <linux/kprobes.h>
 #include <linux/ptrace.h>
-#include <linux/spinlock.h>
 #include <linux/string.h>
 #include <linux/slab.h>
 #include <linux/preempt.h>
 #include <asm/kdebug.h>
 
 static DECLARE_MUTEX(kprobe_mutex);
-
-static struct kprobe *current_kprobe;
-static unsigned long kprobe_status, kprobe_old_rflags, kprobe_saved_rflags;
-static struct kprobe *kprobe_prev;
-static unsigned long kprobe_status_prev, kprobe_old_rflags_prev, kprobe_saved_rflags_prev;
-static struct pt_regs jprobe_saved_regs;
-static long *jprobe_saved_rsp;
 void jprobe_return_end(void);
 
-/* copy of the kernel stack at the probe fire time */
-static kprobe_opcode_t jprobes_stack[MAX_STACK_SIZE];
+DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
+DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
 
 /*
  * returns non-zero if opcode modifies the interrupt flag.
@@ -236,29 +228,30 @@ void __kprobes arch_remove_kprobe(struct kprobe *p)
        up(&kprobe_mutex);
 }
 
-static inline void save_previous_kprobe(void)
+static inline void save_previous_kprobe(struct kprobe_ctlblk *kcb)
 {
-       kprobe_prev = current_kprobe;
-       kprobe_status_prev = kprobe_status;
-       kprobe_old_rflags_prev = kprobe_old_rflags;
-       kprobe_saved_rflags_prev = kprobe_saved_rflags;
+       kcb->prev_kprobe.kp = kprobe_running();
+       kcb->prev_kprobe.status = kcb->kprobe_status;
+       kcb->prev_kprobe.old_rflags = kcb->kprobe_old_rflags;
+       kcb->prev_kprobe.saved_rflags = kcb->kprobe_saved_rflags;
 }
 
-static inline void restore_previous_kprobe(void)
+static inline void restore_previous_kprobe(struct kprobe_ctlblk *kcb)
 {
-       current_kprobe = kprobe_prev;
-       kprobe_status = kprobe_status_prev;
-       kprobe_old_rflags = kprobe_old_rflags_prev;
-       kprobe_saved_rflags = kprobe_saved_rflags_prev;
+       __get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp;
+       kcb->kprobe_status = kcb->prev_kprobe.status;
+       kcb->kprobe_old_rflags = kcb->prev_kprobe.old_rflags;
+       kcb->kprobe_saved_rflags = kcb->prev_kprobe.saved_rflags;
 }
 
-static inline void set_current_kprobe(struct kprobe *p, struct pt_regs *regs)
+static inline void set_current_kprobe(struct kprobe *p, struct pt_regs *regs,
+                               struct kprobe_ctlblk *kcb)
 {
-       current_kprobe = p;
-       kprobe_saved_rflags = kprobe_old_rflags
+       __get_cpu_var(current_kprobe) = p;
+       kcb->kprobe_saved_rflags = kcb->kprobe_old_rflags
                = (regs->eflags & (TF_MASK | IF_MASK));
        if (is_IF_modifier(p->ainsn.insn))
-               kprobe_saved_rflags &= ~IF_MASK;
+               kcb->kprobe_saved_rflags &= ~IF_MASK;
 }
 
 static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
@@ -272,6 +265,7 @@ static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
                regs->rip = (unsigned long)p->ainsn.insn;
 }
 
+/* Called with kretprobe_lock held */
 void __kprobes arch_prepare_kretprobe(struct kretprobe *rp,
                                      struct pt_regs *regs)
 {
@@ -292,32 +286,30 @@ void __kprobes arch_prepare_kretprobe(struct kretprobe *rp,
         }
 }
 
-/*
- * Interrupts are disabled on entry as trap3 is an interrupt gate and they
- * remain disabled thorough out this function.
- */
 int __kprobes kprobe_handler(struct pt_regs *regs)
 {
        struct kprobe *p;
        int ret = 0;
        kprobe_opcode_t *addr = (kprobe_opcode_t *)(regs->rip - sizeof(kprobe_opcode_t));
+       struct kprobe_ctlblk *kcb;
 
-       /* We're in an interrupt, but this is clear and BUG()-safe. */
+       /*
+        * We don't want to be preempted for the entire
+        * duration of kprobe processing
+        */
        preempt_disable();
+       kcb = get_kprobe_ctlblk();
 
        /* Check we're not actually recursing */
        if (kprobe_running()) {
-               /* We *are* holding lock here, so this is safe.
-                  Disarm the probe we just hit, and ignore it. */
                p = get_kprobe(addr);
                if (p) {
-                       if (kprobe_status == KPROBE_HIT_SS &&
+                       if (kcb->kprobe_status == KPROBE_HIT_SS &&
                                *p->ainsn.insn == BREAKPOINT_INSTRUCTION) {
                                regs->eflags &= ~TF_MASK;
-                               regs->eflags |= kprobe_saved_rflags;
-                               unlock_kprobes();
+                               regs->eflags |= kcb->kprobe_saved_rflags;
                                goto no_kprobe;
-                       } else if (kprobe_status == KPROBE_HIT_SSDONE) {
+                       } else if (kcb->kprobe_status == KPROBE_HIT_SSDONE) {
                                /* TODO: Provide re-entrancy from
                                 * post_kprobes_handler() and avoid exception
                                 * stack corruption while single-stepping on
@@ -325,6 +317,7 @@ int __kprobes kprobe_handler(struct pt_regs *regs)
                                 */
                                arch_disarm_kprobe(p);
                                regs->rip = (unsigned long)p->addr;
+                               reset_current_kprobe();
                                ret = 1;
                        } else {
                                /* We have reentered the kprobe_handler(), since
@@ -334,27 +327,24 @@ int __kprobes kprobe_handler(struct pt_regs *regs)
                                 * of the new probe without calling any user
                                 * handlers.
                                 */
-                               save_previous_kprobe();
-                               set_current_kprobe(p, regs);
+                               save_previous_kprobe(kcb);
+                               set_current_kprobe(p, regs, kcb);
                                p->nmissed++;
                                prepare_singlestep(p, regs);
-                               kprobe_status = KPROBE_REENTER;
+                               kcb->kprobe_status = KPROBE_REENTER;
                                return 1;
                        }
                } else {
-                       p = current_kprobe;
+                       p = __get_cpu_var(current_kprobe);
                        if (p->break_handler && p->break_handler(p, regs)) {
                                goto ss_probe;
                        }
                }
-               /* If it's not ours, can't be delete race, (we hold lock). */
                goto no_kprobe;
        }
 
-       lock_kprobes();
        p = get_kprobe(addr);
        if (!p) {
-               unlock_kprobes();
                if (*addr != BREAKPOINT_INSTRUCTION) {
                        /*
                         * The breakpoint instruction was removed right
@@ -372,8 +362,8 @@ int __kprobes kprobe_handler(struct pt_regs *regs)
                goto no_kprobe;
        }
 
-       kprobe_status = KPROBE_HIT_ACTIVE;
-       set_current_kprobe(p, regs);
+       set_current_kprobe(p, regs, kcb);
+       kcb->kprobe_status = KPROBE_HIT_ACTIVE;
 
        if (p->pre_handler && p->pre_handler(p, regs))
                /* handler has already set things up, so skip ss setup */
@@ -381,7 +371,7 @@ int __kprobes kprobe_handler(struct pt_regs *regs)
 
 ss_probe:
        prepare_singlestep(p, regs);
-       kprobe_status = KPROBE_HIT_SS;
+       kcb->kprobe_status = KPROBE_HIT_SS;
        return 1;
 
 no_kprobe:
@@ -409,9 +399,10 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
         struct kretprobe_instance *ri = NULL;
         struct hlist_head *head;
         struct hlist_node *node, *tmp;
-       unsigned long orig_ret_address = 0;
+       unsigned long flags, orig_ret_address = 0;
        unsigned long trampoline_address =(unsigned long)&kretprobe_trampoline;
 
+       spin_lock_irqsave(&kretprobe_lock, flags);
         head = kretprobe_inst_table_head(current);
 
        /*
@@ -450,13 +441,14 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
        BUG_ON(!orig_ret_address || (orig_ret_address == trampoline_address));
        regs->rip = orig_ret_address;
 
-       unlock_kprobes();
+       reset_current_kprobe();
+       spin_unlock_irqrestore(&kretprobe_lock, flags);
        preempt_enable_no_resched();
 
         /*
          * By returning a non-zero value, we are telling
-         * kprobe_handler() that we have handled unlocking
-         * and re-enabling preemption.
+         * kprobe_handler() that we don't want the post_handler
+        * to run (and have re-enabled preemption)
          */
         return 1;
 }
@@ -483,7 +475,8 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
  * that is atop the stack is the address following the copied instruction.
  * We need to make it the address following the original instruction.
  */
-static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs)
+static void __kprobes resume_execution(struct kprobe *p,
+               struct pt_regs *regs, struct kprobe_ctlblk *kcb)
 {
        unsigned long *tos = (unsigned long *)regs->rsp;
        unsigned long next_rip = 0;
@@ -498,7 +491,7 @@ static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs)
        switch (*insn) {
        case 0x9c:              /* pushfl */
                *tos &= ~(TF_MASK | IF_MASK);
-               *tos |= kprobe_old_rflags;
+               *tos |= kcb->kprobe_old_rflags;
                break;
        case 0xc3:              /* ret/lret */
        case 0xcb:
@@ -537,30 +530,28 @@ static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs)
        }
 }
 
-/*
- * Interrupts are disabled on entry as trap1 is an interrupt gate and they
- * remain disabled thoroughout this function.  And we hold kprobe lock.
- */
 int __kprobes post_kprobe_handler(struct pt_regs *regs)
 {
-       if (!kprobe_running())
+       struct kprobe *cur = kprobe_running();
+       struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+
+       if (!cur)
                return 0;
 
-       if ((kprobe_status != KPROBE_REENTER) && current_kprobe->post_handler) {
-               kprobe_status = KPROBE_HIT_SSDONE;
-               current_kprobe->post_handler(current_kprobe, regs, 0);
+       if ((kcb->kprobe_status != KPROBE_REENTER) && cur->post_handler) {
+               kcb->kprobe_status = KPROBE_HIT_SSDONE;
+               cur->post_handler(cur, regs, 0);
        }
 
-       resume_execution(current_kprobe, regs);
-       regs->eflags |= kprobe_saved_rflags;
+       resume_execution(cur, regs, kcb);
+       regs->eflags |= kcb->kprobe_saved_rflags;
 
        /* Restore the original saved kprobes variables and continue. */
-       if (kprobe_status == KPROBE_REENTER) {
-               restore_previous_kprobe();
+       if (kcb->kprobe_status == KPROBE_REENTER) {
+               restore_previous_kprobe(kcb);
                goto out;
-       } else {
-               unlock_kprobes();
        }
+       reset_current_kprobe();
 out:
        preempt_enable_no_resched();
 
@@ -575,18 +566,19 @@ out:
        return 1;
 }
 
-/* Interrupts disabled, kprobe_lock held. */
 int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr)
 {
-       if (current_kprobe->fault_handler
-           && current_kprobe->fault_handler(current_kprobe, regs, trapnr))
+       struct kprobe *cur = kprobe_running();
+       struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+
+       if (cur->fault_handler && cur->fault_handler(cur, regs, trapnr))
                return 1;
 
-       if (kprobe_status & KPROBE_HIT_SS) {
-               resume_execution(current_kprobe, regs);
-               regs->eflags |= kprobe_old_rflags;
+       if (kcb->kprobe_status & KPROBE_HIT_SS) {
+               resume_execution(cur, regs, kcb);
+               regs->eflags |= kcb->kprobe_old_rflags;
 
-               unlock_kprobes();
+               reset_current_kprobe();
                preempt_enable_no_resched();
        }
        return 0;
@@ -599,39 +591,41 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
                                       unsigned long val, void *data)
 {
        struct die_args *args = (struct die_args *)data;
+       int ret = NOTIFY_DONE;
+
        switch (val) {
        case DIE_INT3:
                if (kprobe_handler(args->regs))
-                       return NOTIFY_STOP;
+                       ret = NOTIFY_STOP;
                break;
        case DIE_DEBUG:
                if (post_kprobe_handler(args->regs))
-                       return NOTIFY_STOP;
+                       ret = NOTIFY_STOP;
                break;
        case DIE_GPF:
-               if (kprobe_running() &&
-                   kprobe_fault_handler(args->regs, args->trapnr))
-                       return NOTIFY_STOP;
-               break;
        case DIE_PAGE_FAULT:
+               /* kprobe_running() needs smp_processor_id() */
+               preempt_disable();
                if (kprobe_running() &&
                    kprobe_fault_handler(args->regs, args->trapnr))
-                       return NOTIFY_STOP;
+                       ret = NOTIFY_STOP;
+               preempt_enable();
                break;
        default:
                break;
        }
-       return NOTIFY_DONE;
+       return ret;
 }
 
 int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
 {
        struct jprobe *jp = container_of(p, struct jprobe, kp);
        unsigned long addr;
+       struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
 
-       jprobe_saved_regs = *regs;
-       jprobe_saved_rsp = (long *) regs->rsp;
-       addr = (unsigned long)jprobe_saved_rsp;
+       kcb->jprobe_saved_regs = *regs;
+       kcb->jprobe_saved_rsp = (long *) regs->rsp;
+       addr = (unsigned long)(kcb->jprobe_saved_rsp);
        /*
         * As Linus pointed out, gcc assumes that the callee
         * owns the argument space and could overwrite it, e.g.
@@ -639,7 +633,8 @@ int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
         * we also save and restore enough stack bytes to cover
         * the argument area.
         */
-       memcpy(jprobes_stack, (kprobe_opcode_t *) addr, MIN_STACK_SIZE(addr));
+       memcpy(kcb->jprobes_stack, (kprobe_opcode_t *)addr,
+                       MIN_STACK_SIZE(addr));
        regs->eflags &= ~IF_MASK;
        regs->rip = (unsigned long)(jp->entry);
        return 1;
@@ -647,36 +642,40 @@ int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
 
 void __kprobes jprobe_return(void)
 {
-       preempt_enable_no_resched();
+       struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+
        asm volatile ("       xchg   %%rbx,%%rsp     \n"
                      "       int3                      \n"
                      "       .globl jprobe_return_end  \n"
                      "       jprobe_return_end:        \n"
                      "       nop                       \n"::"b"
-                     (jprobe_saved_rsp):"memory");
+                     (kcb->jprobe_saved_rsp):"memory");
 }
 
 int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
 {
+       struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
        u8 *addr = (u8 *) (regs->rip - 1);
-       unsigned long stack_addr = (unsigned long)jprobe_saved_rsp;
+       unsigned long stack_addr = (unsigned long)(kcb->jprobe_saved_rsp);
        struct jprobe *jp = container_of(p, struct jprobe, kp);
 
        if ((addr > (u8 *) jprobe_return) && (addr < (u8 *) jprobe_return_end)) {
-               if ((long *)regs->rsp != jprobe_saved_rsp) {
+               if ((long *)regs->rsp != kcb->jprobe_saved_rsp) {
                        struct pt_regs *saved_regs =
-                           container_of(jprobe_saved_rsp, struct pt_regs, rsp);
+                           container_of(kcb->jprobe_saved_rsp,
+                                           struct pt_regs, rsp);
                        printk("current rsp %p does not match saved rsp %p\n",
-                              (long *)regs->rsp, jprobe_saved_rsp);
+                              (long *)regs->rsp, kcb->jprobe_saved_rsp);
                        printk("Saved registers for jprobe %p\n", jp);
                        show_registers(saved_regs);
                        printk("Current registers\n");
                        show_registers(regs);
                        BUG();
                }
-               *regs = jprobe_saved_regs;
-               memcpy((kprobe_opcode_t *) stack_addr, jprobes_stack,
+               *regs = kcb->jprobe_saved_regs;
+               memcpy((kprobe_opcode_t *) stack_addr, kcb->jprobes_stack,
                       MIN_STACK_SIZE(stack_addr));
+               preempt_enable_no_resched();
                return 1;
        }
        return 0;
index bbf64b59a21e217b64085f7ce378d7fa332a4bab..a87b6cebe80fc45e3fced915120c619215e5e87a 100644 (file)
@@ -313,48 +313,11 @@ static unsigned long getreg(struct task_struct *child, unsigned long regno)
 
 }
 
-asmlinkage long sys_ptrace(long request, long pid, unsigned long addr, long data)
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
 {
-       struct task_struct *child;
        long i, ret;
        unsigned ui;
 
-       /* This lock_kernel fixes a subtle race with suid exec */
-       lock_kernel();
-       ret = -EPERM;
-       if (request == PTRACE_TRACEME) {
-               /* are we already being traced? */
-               if (current->ptrace & PT_PTRACED)
-                       goto out;
-               ret = security_ptrace(current->parent, current);
-               if (ret)
-                       goto out;
-               /* set the ptrace bit in the process flags. */
-               current->ptrace |= PT_PTRACED;
-               ret = 0;
-               goto out;
-       }
-       ret = -ESRCH;
-       read_lock(&tasklist_lock);
-       child = find_task_by_pid(pid);
-       if (child)
-               get_task_struct(child);
-       read_unlock(&tasklist_lock);
-       if (!child)
-               goto out;
-
-       ret = -EPERM;
-       if (pid == 1)           /* you may not mess with init */
-               goto out_tsk;
-
-       if (request == PTRACE_ATTACH) {
-               ret = ptrace_attach(child);
-               goto out_tsk;
-       }
-       ret = ptrace_check_attach(child, request == PTRACE_KILL); 
-       if (ret < 0) 
-               goto out_tsk;
-
        switch (request) {
        /* when I and D space are separate, these will need to be fixed. */
        case PTRACE_PEEKTEXT: /* read word at location addr. */ 
@@ -608,10 +571,6 @@ asmlinkage long sys_ptrace(long request, long pid, unsigned long addr, long data
                ret = ptrace_request(child, request, addr, data);
                break;
        }
-out_tsk:
-       put_task_struct(child);
-out:
-       unlock_kernel();
        return ret;
 }
 
index 658a81b33f3bf1a1d31087f2e3b3637bd76ddab0..4b5b088ec1022a5d28c6e0e2dae76df9c4eed785 100644 (file)
@@ -65,8 +65,6 @@ int smp_num_siblings = 1;
 /* Package ID of each logical CPU */
 u8 phys_proc_id[NR_CPUS] __read_mostly = { [0 ... NR_CPUS-1] = BAD_APICID };
 u8 cpu_core_id[NR_CPUS] __read_mostly = { [0 ... NR_CPUS-1] = BAD_APICID };
-EXPORT_SYMBOL(phys_proc_id);
-EXPORT_SYMBOL(cpu_core_id);
 
 /* Bitmask of currently online CPUs */
 cpumask_t cpu_online_map __read_mostly;
index 5ade19801b97a598829b4b1dff817a6cc59a028e..d8a84088471a1c011868aae0b44558d15c9f1c0b 100644 (file)
@@ -1,7 +1,3 @@
-
-menu "Profiling support"
-       depends on EXPERIMENTAL
-
 config PROFILING
        bool "Profiling support (EXPERIMENTAL)"
        help
@@ -19,5 +15,3 @@ config OPROFILE
 
          If unsure, say N.
 
-endmenu
-
index 14460743de079dd32263a003b6d58d640f335027..ab5c4c65b5c416848b553efda177b10038243858 100644 (file)
@@ -45,58 +45,10 @@ void ptrace_disable(struct task_struct *child)
        /* Nothing to do.. */
 }
 
-long sys_ptrace(long request, long pid, long addr, long data)
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
 {
-       struct task_struct *child;
        int ret = -EPERM;
 
-       lock_kernel();
-
-#if 0
-       if ((int)request != 1)
-       printk("ptrace(r=%d,pid=%d,addr=%08lx,data=%08lx)\n",
-              (int) request, (int) pid, (unsigned long) addr,
-              (unsigned long) data);
-#endif
-
-       if (request == PTRACE_TRACEME) {
-
-               /* Are we already being traced? */
-
-               if (current->ptrace & PT_PTRACED)
-                       goto out;
-
-               if ((ret = security_ptrace(current->parent, current)))
-                       goto out;
-
-               /* Set the ptrace bit in the process flags. */
-
-               current->ptrace |= PT_PTRACED;
-               ret = 0;
-               goto out;
-       }
-
-       ret = -ESRCH;
-       read_lock(&tasklist_lock);
-       child = find_task_by_pid(pid);
-       if (child)
-               get_task_struct(child);
-       read_unlock(&tasklist_lock);
-       if (!child)
-               goto out;
-
-       ret = -EPERM;
-       if (pid == 1)           /* you may not mess with init */
-               goto out;
-
-       if (request == PTRACE_ATTACH) {
-               ret = ptrace_attach(child);
-               goto out_tsk;
-       }
-
-       if ((ret = ptrace_check_attach(child, request == PTRACE_KILL)) < 0)
-               goto out_tsk;
-
        switch (request) {
        case PTRACE_PEEKTEXT: /* read word at location addr. */
        case PTRACE_PEEKDATA:
@@ -375,10 +327,7 @@ long sys_ptrace(long request, long pid, long addr, long data)
                ret = ptrace_request(child, request, addr, data);
                goto out;
        }
-out_tsk:
-       put_task_struct(child);
-out:
-       unlock_kernel();
+ out:
        return ret;
 }
 
index 65670be6ff1a15ac86d8213a08533cbaf498037a..fac1e1603097d46bcc66e076c083601cfa37c52f 100644 (file)
@@ -7,6 +7,7 @@
 
 obj-$(CONFIG_PCI)              += pci/ usb/
 obj-$(CONFIG_PARISC)           += parisc/
+obj-$(CONFIG_RAPIDIO)          += rapidio/
 obj-y                          += video/
 obj-$(CONFIG_ACPI)             += acpi/
 # PnP must come after ACPI since it will eventually need to check if acpi
@@ -67,3 +68,4 @@ obj-$(CONFIG_INFINIBAND)      += infiniband/
 obj-$(CONFIG_SGI_IOC4)         += sn/
 obj-y                          += firmware/
 obj-$(CONFIG_CRYPTO)           += crypto/
+obj-$(CONFIG_SUPERH)           += sh/
index 10dd695a1dd93e06d43497b5b4c49ce8680a7cac..27ec12c1fab084c2ea1bba43c24be5e00c636e71 100644 (file)
@@ -118,11 +118,9 @@ static int acpi_container_remove(struct acpi_device *device, int type)
 {
        acpi_status status = AE_OK;
        struct acpi_container *pc = NULL;
-       pc = (struct acpi_container *)acpi_driver_data(device);
-
-       if (pc)
-               kfree(pc);
 
+       pc = (struct acpi_container *)acpi_driver_data(device);
+       kfree(pc);
        return status;
 }
 
index d528c750a3801bd65591639baec49d3f64a381fe..e3cd0b16031ad32c70ee1b47516c23b02856cbcb 100644 (file)
@@ -313,8 +313,7 @@ acpi_status acpi_os_remove_interrupt_handler(u32 irq, acpi_osd_handler handler)
 
 void acpi_os_sleep(acpi_integer ms)
 {
-       current->state = TASK_INTERRUPTIBLE;
-       schedule_timeout(((signed long)ms * HZ) / 1000);
+       schedule_timeout_interruptible(msecs_to_jiffies(ms));
 }
 
 EXPORT_SYMBOL(acpi_os_sleep);
@@ -838,8 +837,7 @@ acpi_status acpi_os_wait_semaphore(acpi_handle handle, u32 units, u16 timeout)
 
                        ret = down_trylock(sem);
                        for (i = timeout; (i > 0 && ret < 0); i -= quantum_ms) {
-                               current->state = TASK_INTERRUPTIBLE;
-                               schedule_timeout(1);
+                               schedule_timeout_interruptible(1);
                                ret = down_trylock(sem);
                        }
 
index c6db591479de3e02504d40ac8e0cee2d2bebdeab..23e2c6968a1164f9f54aa6f9a5493c619965019a 100644 (file)
@@ -28,8 +28,7 @@ static int acpi_bus_trim(struct acpi_device *start, int rmdevice);
 static void acpi_device_release(struct kobject *kobj)
 {
        struct acpi_device *dev = container_of(kobj, struct acpi_device, kobj);
-       if (dev->pnp.cid_list)
-               kfree(dev->pnp.cid_list);
+       kfree(dev->pnp.cid_list);
        kfree(dev);
 }
 
@@ -1117,8 +1116,7 @@ acpi_add_single_object(struct acpi_device **child,
        if (!result)
                *child = device;
        else {
-               if (device->pnp.cid_list)
-                       kfree(device->pnp.cid_list);
+               kfree(device->pnp.cid_list);
                kfree(device);
        }
 
index e383d6109ae109c6963d43abe7ca71449e554518..f051b151580d7de14647213f6c4497a75a4eff57 100644 (file)
@@ -334,8 +334,7 @@ acpi_video_device_lcd_query_levels(struct acpi_video_device *device,
        return_VALUE(0);
 
       err:
-       if (buffer.pointer)
-               kfree(buffer.pointer);
+       kfree(buffer.pointer);
 
        return_VALUE(status);
 }
@@ -1488,8 +1487,7 @@ static int acpi_video_device_enumerate(struct acpi_video_bus *video)
        }
        active_device_list[count].value.int_val = ACPI_VIDEO_HEAD_END;
 
-       if (video->attached_array)
-               kfree(video->attached_array);
+       kfree(video->attached_array);
 
        video->attached_array = active_device_list;
        video->attached_count = count;
@@ -1645,8 +1643,7 @@ static int acpi_video_bus_put_devices(struct acpi_video_bus *video)
                        printk(KERN_WARNING PREFIX
                               "hhuuhhuu bug in acpi video driver.\n");
 
-               if (data->brightness)
-                       kfree(data->brightness);
+               kfree(data->brightness);
 
                kfree(data);
        }
@@ -1831,8 +1828,7 @@ static int acpi_video_bus_remove(struct acpi_device *device, int type)
        acpi_video_bus_put_devices(video);
        acpi_video_bus_remove_fs(device);
 
-       if (video->attached_array)
-               kfree(video->attached_array);
+       kfree(video->attached_array);
        kfree(video);
 
        return_VALUE(0);
index 89c57875f3e53c25f666cbb943933cb518396adb..f3a0c562bcb53ff019aa8db27cfd40860a1a6335 100644 (file)
@@ -3,6 +3,7 @@
  */
 
 #include <linux/device.h>
+#include <linux/string.h>
 #include "power.h"
 
 
index 3760edfdc65cc54f9cb6525eb2d26ebd0833b1e4..70eaa5c7ac088c7db5ed6c8363bf8b5e1f75f881 100644 (file)
@@ -417,14 +417,12 @@ static void DAC960_DestroyAuxiliaryStructures(DAC960_Controller_T *Controller)
             * Remember the beginning of the group, but don't free it
            * until we've reached the beginning of the next group.
            */
-          if (CommandGroup != NULL)
-               kfree(CommandGroup);
-           CommandGroup = Command;
+          kfree(CommandGroup);
+          CommandGroup = Command;
       }
       Controller->Commands[i] = NULL;
     }
-  if (CommandGroup != NULL)
-      kfree(CommandGroup);
+  kfree(CommandGroup);
 
   if (Controller->CombinedStatusBuffer != NULL)
     {
@@ -435,30 +433,23 @@ static void DAC960_DestroyAuxiliaryStructures(DAC960_Controller_T *Controller)
 
   if (ScatterGatherPool != NULL)
        pci_pool_destroy(ScatterGatherPool);
-  if (Controller->FirmwareType == DAC960_V1_Controller) return;
+  if (Controller->FirmwareType == DAC960_V1_Controller)
+       return;
 
   if (RequestSensePool != NULL)
        pci_pool_destroy(RequestSensePool);
 
-  for (i = 0; i < DAC960_MaxLogicalDrives; i++)
-    if (Controller->V2.LogicalDeviceInformation[i] != NULL)
-      {
+  for (i = 0; i < DAC960_MaxLogicalDrives; i++) {
        kfree(Controller->V2.LogicalDeviceInformation[i]);
        Controller->V2.LogicalDeviceInformation[i] = NULL;
-      }
+  }
 
   for (i = 0; i < DAC960_V2_MaxPhysicalDevices; i++)
     {
-      if (Controller->V2.PhysicalDeviceInformation[i] != NULL)
-       {
-         kfree(Controller->V2.PhysicalDeviceInformation[i]);
-         Controller->V2.PhysicalDeviceInformation[i] = NULL;
-       }
-      if (Controller->V2.InquiryUnitSerialNumber[i] != NULL)
-       {
-         kfree(Controller->V2.InquiryUnitSerialNumber[i]);
-         Controller->V2.InquiryUnitSerialNumber[i] = NULL;
-       }
+      kfree(Controller->V2.PhysicalDeviceInformation[i]);
+      Controller->V2.PhysicalDeviceInformation[i] = NULL;
+      kfree(Controller->V2.InquiryUnitSerialNumber[i]);
+      Controller->V2.InquiryUnitSerialNumber[i] = NULL;
     }
 }
 
index c6744ff382944a590767cef1827e627c1915c7ad..a78e160b59a3545b8a06b78e2c78e503f1494d24 100644 (file)
@@ -4,7 +4,7 @@
  *  Anticipatory & deadline i/o scheduler.
  *
  *  Copyright (C) 2002 Jens Axboe <axboe@suse.de>
- *                     Nick Piggin <piggin@cyberone.com.au>
+ *                     Nick Piggin <nickpiggin@yahoo.com.au>
  *
  */
 #include <linux/kernel.h>
@@ -69,7 +69,7 @@
 
 /* Bits in as_io_context.state */
 enum as_io_states {
-       AS_TASK_RUNNING=0,      /* Process has not exitted */
+       AS_TASK_RUNNING=0,      /* Process has not exited */
        AS_TASK_IOSTARTED,      /* Process has started some IO */
        AS_TASK_IORUNNING,      /* Process has completed some IO */
 };
@@ -102,6 +102,9 @@ struct as_data {
 
        unsigned long exit_prob;        /* probability a task will exit while
                                           being waited on */
+       unsigned long exit_no_coop;     /* probablility an exited task will
+                                          not be part of a later cooperating
+                                          request */
        unsigned long new_ttime_total;  /* mean thinktime on new proc */
        unsigned long new_ttime_mean;
        u64 new_seek_total;             /* mean seek on new proc */
@@ -636,37 +639,152 @@ static void as_antic_timeout(unsigned long data)
                kblockd_schedule_work(&ad->antic_work);
 
                if (aic->ttime_samples == 0) {
-                       /* process anticipated on has exitted or timed out*/
+                       /* process anticipated on has exited or timed out*/
                        ad->exit_prob = (7*ad->exit_prob + 256)/8;
                }
+               if (!test_bit(AS_TASK_RUNNING, &aic->state)) {
+                       /* process not "saved" by a cooperating request */
+                       ad->exit_no_coop = (7*ad->exit_no_coop + 256)/8;
+               }
        }
        spin_unlock_irqrestore(q->queue_lock, flags);
 }
 
+static void as_update_thinktime(struct as_data *ad, struct as_io_context *aic,
+                               unsigned long ttime)
+{
+       /* fixed point: 1.0 == 1<<8 */
+       if (aic->ttime_samples == 0) {
+               ad->new_ttime_total = (7*ad->new_ttime_total + 256*ttime) / 8;
+               ad->new_ttime_mean = ad->new_ttime_total / 256;
+
+               ad->exit_prob = (7*ad->exit_prob)/8;
+       }
+       aic->ttime_samples = (7*aic->ttime_samples + 256) / 8;
+       aic->ttime_total = (7*aic->ttime_total + 256*ttime) / 8;
+       aic->ttime_mean = (aic->ttime_total + 128) / aic->ttime_samples;
+}
+
+static void as_update_seekdist(struct as_data *ad, struct as_io_context *aic,
+                               sector_t sdist)
+{
+       u64 total;
+
+       if (aic->seek_samples == 0) {
+               ad->new_seek_total = (7*ad->new_seek_total + 256*(u64)sdist)/8;
+               ad->new_seek_mean = ad->new_seek_total / 256;
+       }
+
+       /*
+        * Don't allow the seek distance to get too large from the
+        * odd fragment, pagein, etc
+        */
+       if (aic->seek_samples <= 60) /* second&third seek */
+               sdist = min(sdist, (aic->seek_mean * 4) + 2*1024*1024);
+       else
+               sdist = min(sdist, (aic->seek_mean * 4) + 2*1024*64);
+
+       aic->seek_samples = (7*aic->seek_samples + 256) / 8;
+       aic->seek_total = (7*aic->seek_total + (u64)256*sdist) / 8;
+       total = aic->seek_total + (aic->seek_samples/2);
+       do_div(total, aic->seek_samples);
+       aic->seek_mean = (sector_t)total;
+}
+
+/*
+ * as_update_iohist keeps a decaying histogram of IO thinktimes, and
+ * updates @aic->ttime_mean based on that. It is called when a new
+ * request is queued.
+ */
+static void as_update_iohist(struct as_data *ad, struct as_io_context *aic,
+                               struct request *rq)
+{
+       struct as_rq *arq = RQ_DATA(rq);
+       int data_dir = arq->is_sync;
+       unsigned long thinktime = 0;
+       sector_t seek_dist;
+
+       if (aic == NULL)
+               return;
+
+       if (data_dir == REQ_SYNC) {
+               unsigned long in_flight = atomic_read(&aic->nr_queued)
+                                       + atomic_read(&aic->nr_dispatched);
+               spin_lock(&aic->lock);
+               if (test_bit(AS_TASK_IORUNNING, &aic->state) ||
+                       test_bit(AS_TASK_IOSTARTED, &aic->state)) {
+                       /* Calculate read -> read thinktime */
+                       if (test_bit(AS_TASK_IORUNNING, &aic->state)
+                                                       && in_flight == 0) {
+                               thinktime = jiffies - aic->last_end_request;
+                               thinktime = min(thinktime, MAX_THINKTIME-1);
+                       }
+                       as_update_thinktime(ad, aic, thinktime);
+
+                       /* Calculate read -> read seek distance */
+                       if (aic->last_request_pos < rq->sector)
+                               seek_dist = rq->sector - aic->last_request_pos;
+                       else
+                               seek_dist = aic->last_request_pos - rq->sector;
+                       as_update_seekdist(ad, aic, seek_dist);
+               }
+               aic->last_request_pos = rq->sector + rq->nr_sectors;
+               set_bit(AS_TASK_IOSTARTED, &aic->state);
+               spin_unlock(&aic->lock);
+       }
+}
+
 /*
  * as_close_req decides if one request is considered "close" to the
  * previous one issued.
  */
-static int as_close_req(struct as_data *ad, struct as_rq *arq)
+static int as_close_req(struct as_data *ad, struct as_io_context *aic,
+                               struct as_rq *arq)
 {
        unsigned long delay;    /* milliseconds */
        sector_t last = ad->last_sector[ad->batch_data_dir];
        sector_t next = arq->request->sector;
        sector_t delta; /* acceptable close offset (in sectors) */
+       sector_t s;
 
        if (ad->antic_status == ANTIC_OFF || !ad->ioc_finished)
                delay = 0;
        else
                delay = ((jiffies - ad->antic_start) * 1000) / HZ;
 
-       if (delay <= 1)
-               delta = 64;
+       if (delay == 0)
+               delta = 8192;
        else if (delay <= 20 && delay <= ad->antic_expire)
-               delta = 64 << (delay-1);
+               delta = 8192 << delay;
        else
                return 1;
 
-       return (last - (delta>>1) <= next) && (next <= last + delta);
+       if ((last <= next + (delta>>1)) && (next <= last + delta))
+               return 1;
+
+       if (last < next)
+               s = next - last;
+       else
+               s = last - next;
+
+       if (aic->seek_samples == 0) {
+               /*
+                * Process has just started IO. Use past statistics to
+                * gauge success possibility
+                */
+               if (ad->new_seek_mean > s) {
+                       /* this request is better than what we're expecting */
+                       return 1;
+               }
+
+       } else {
+               if (aic->seek_mean > s) {
+                       /* this request is better than what we're expecting */
+                       return 1;
+               }
+       }
+
+       return 0;
 }
 
 /*
@@ -678,7 +796,7 @@ static int as_close_req(struct as_data *ad, struct as_rq *arq)
  * dispatch it ASAP, because we know that application will not be submitting
  * any new reads.
  *
- * If the task which has submitted the request has exitted, break anticipation.
+ * If the task which has submitted the request has exited, break anticipation.
  *
  * If this task has queued some other IO, do not enter enticipation.
  */
@@ -686,7 +804,6 @@ static int as_can_break_anticipation(struct as_data *ad, struct as_rq *arq)
 {
        struct io_context *ioc;
        struct as_io_context *aic;
-       sector_t s;
 
        ioc = ad->io_context;
        BUG_ON(!ioc);
@@ -708,13 +825,6 @@ static int as_can_break_anticipation(struct as_data *ad, struct as_rq *arq)
        if (!aic)
                return 0;
 
-       if (!test_bit(AS_TASK_RUNNING, &aic->state)) {
-               /* process anticipated on has exitted */
-               if (aic->ttime_samples == 0)
-                       ad->exit_prob = (7*ad->exit_prob + 256)/8;
-               return 1;
-       }
-
        if (atomic_read(&aic->nr_queued) > 0) {
                /* process has more requests queued */
                return 1;
@@ -725,57 +835,45 @@ static int as_can_break_anticipation(struct as_data *ad, struct as_rq *arq)
                return 1;
        }
 
-       if (arq && arq->is_sync == REQ_SYNC && as_close_req(ad, arq)) {
+       if (arq && arq->is_sync == REQ_SYNC && as_close_req(ad, aic, arq)) {
                /*
                 * Found a close request that is not one of ours.
                 *
-                * This makes close requests from another process reset
-                * our thinktime delay. Is generally useful when there are
+                * This makes close requests from another process update
+                * our IO history. Is generally useful when there are
                 * two or more cooperating processes working in the same
                 * area.
                 */
-               spin_lock(&aic->lock);
-               aic->last_end_request = jiffies;
-               spin_unlock(&aic->lock);
+               if (!test_bit(AS_TASK_RUNNING, &aic->state)) {
+                       if (aic->ttime_samples == 0)
+                               ad->exit_prob = (7*ad->exit_prob + 256)/8;
+
+                       ad->exit_no_coop = (7*ad->exit_no_coop)/8;
+               }
+
+               as_update_iohist(ad, aic, arq->request);
                return 1;
        }
 
+       if (!test_bit(AS_TASK_RUNNING, &aic->state)) {
+               /* process anticipated on has exited */
+               if (aic->ttime_samples == 0)
+                       ad->exit_prob = (7*ad->exit_prob + 256)/8;
+
+               if (ad->exit_no_coop > 128)
+                       return 1;
+       }
 
        if (aic->ttime_samples == 0) {
                if (ad->new_ttime_mean > ad->antic_expire)
                        return 1;
-               if (ad->exit_prob > 128)
+               if (ad->exit_prob * ad->exit_no_coop > 128*256)
                        return 1;
        } else if (aic->ttime_mean > ad->antic_expire) {
                /* the process thinks too much between requests */
                return 1;
        }
 
-       if (!arq)
-               return 0;
-
-       if (ad->last_sector[REQ_SYNC] < arq->request->sector)
-               s = arq->request->sector - ad->last_sector[REQ_SYNC];
-       else
-               s = ad->last_sector[REQ_SYNC] - arq->request->sector;
-
-       if (aic->seek_samples == 0) {
-               /*
-                * Process has just started IO. Use past statistics to
-                * guage success possibility
-                */
-               if (ad->new_seek_mean > s) {
-                       /* this request is better than what we're expecting */
-                       return 1;
-               }
-
-       } else {
-               if (aic->seek_mean > s) {
-                       /* this request is better than what we're expecting */
-                       return 1;
-               }
-       }
-
        return 0;
 }
 
@@ -809,94 +907,11 @@ static int as_can_anticipate(struct as_data *ad, struct as_rq *arq)
         * Status is either ANTIC_OFF so start waiting,
         * ANTIC_WAIT_REQ so continue waiting for request to finish
         * or ANTIC_WAIT_NEXT so continue waiting for an acceptable request.
-        *
         */
 
        return 1;
 }
 
-static void as_update_thinktime(struct as_data *ad, struct as_io_context *aic, unsigned long ttime)
-{
-       /* fixed point: 1.0 == 1<<8 */
-       if (aic->ttime_samples == 0) {
-               ad->new_ttime_total = (7*ad->new_ttime_total + 256*ttime) / 8;
-               ad->new_ttime_mean = ad->new_ttime_total / 256;
-
-               ad->exit_prob = (7*ad->exit_prob)/8;
-       }
-       aic->ttime_samples = (7*aic->ttime_samples + 256) / 8;
-       aic->ttime_total = (7*aic->ttime_total + 256*ttime) / 8;
-       aic->ttime_mean = (aic->ttime_total + 128) / aic->ttime_samples;
-}
-
-static void as_update_seekdist(struct as_data *ad, struct as_io_context *aic, sector_t sdist)
-{
-       u64 total;
-
-       if (aic->seek_samples == 0) {
-               ad->new_seek_total = (7*ad->new_seek_total + 256*(u64)sdist)/8;
-               ad->new_seek_mean = ad->new_seek_total / 256;
-       }
-
-       /*
-        * Don't allow the seek distance to get too large from the
-        * odd fragment, pagein, etc
-        */
-       if (aic->seek_samples <= 60) /* second&third seek */
-               sdist = min(sdist, (aic->seek_mean * 4) + 2*1024*1024);
-       else
-               sdist = min(sdist, (aic->seek_mean * 4) + 2*1024*64);
-
-       aic->seek_samples = (7*aic->seek_samples + 256) / 8;
-       aic->seek_total = (7*aic->seek_total + (u64)256*sdist) / 8;
-       total = aic->seek_total + (aic->seek_samples/2);
-       do_div(total, aic->seek_samples);
-       aic->seek_mean = (sector_t)total;
-}
-
-/*
- * as_update_iohist keeps a decaying histogram of IO thinktimes, and
- * updates @aic->ttime_mean based on that. It is called when a new
- * request is queued.
- */
-static void as_update_iohist(struct as_data *ad, struct as_io_context *aic, struct request *rq)
-{
-       struct as_rq *arq = RQ_DATA(rq);
-       int data_dir = arq->is_sync;
-       unsigned long thinktime;
-       sector_t seek_dist;
-
-       if (aic == NULL)
-               return;
-
-       if (data_dir == REQ_SYNC) {
-               unsigned long in_flight = atomic_read(&aic->nr_queued)
-                                       + atomic_read(&aic->nr_dispatched);
-               spin_lock(&aic->lock);
-               if (test_bit(AS_TASK_IORUNNING, &aic->state) ||
-                       test_bit(AS_TASK_IOSTARTED, &aic->state)) {
-                       /* Calculate read -> read thinktime */
-                       if (test_bit(AS_TASK_IORUNNING, &aic->state)
-                                                       && in_flight == 0) {
-                               thinktime = jiffies - aic->last_end_request;
-                               thinktime = min(thinktime, MAX_THINKTIME-1);
-                       } else
-                               thinktime = 0;
-                       as_update_thinktime(ad, aic, thinktime);
-
-                       /* Calculate read -> read seek distance */
-                       if (aic->last_request_pos < rq->sector)
-                               seek_dist = rq->sector - aic->last_request_pos;
-                       else
-                               seek_dist = aic->last_request_pos - rq->sector;
-                       as_update_seekdist(ad, aic, seek_dist);
-               }
-               aic->last_request_pos = rq->sector + rq->nr_sectors;
-               set_bit(AS_TASK_IOSTARTED, &aic->state);
-               spin_unlock(&aic->lock);
-       }
-}
-
 /*
  * as_update_arq must be called whenever a request (arq) is added to
  * the sort_list. This function keeps caches up to date, and checks if the
@@ -1201,7 +1216,7 @@ static int as_dispatch_request(request_queue_t *q, int force)
                || ad->changed_batch)
                return 0;
 
-       if (!(reads && writes && as_batch_expired(ad)) ) {
+       if (!(reads && writes && as_batch_expired(ad))) {
                /*
                 * batch is still running or no reads or no writes
                 */
@@ -1316,7 +1331,8 @@ fifo_expired:
  * Add arq to a list behind alias
  */
 static inline void
-as_add_aliased_request(struct as_data *ad, struct as_rq *arq, struct as_rq *alias)
+as_add_aliased_request(struct as_data *ad, struct as_rq *arq,
+                               struct as_rq *alias)
 {
        struct request  *req = arq->request;
        struct list_head *insert = alias->request->queuelist.prev;
@@ -1441,8 +1457,8 @@ static int as_queue_empty(request_queue_t *q)
                && list_empty(&ad->fifo_list[REQ_SYNC]);
 }
 
-static struct request *
-as_former_request(request_queue_t *q, struct request *rq)
+static struct request *as_former_request(request_queue_t *q,
+                                       struct request *rq)
 {
        struct as_rq *arq = RQ_DATA(rq);
        struct rb_node *rbprev = rb_prev(&arq->rb_node);
@@ -1454,8 +1470,8 @@ as_former_request(request_queue_t *q, struct request *rq)
        return ret;
 }
 
-static struct request *
-as_latter_request(request_queue_t *q, struct request *rq)
+static struct request *as_latter_request(request_queue_t *q,
+                                       struct request *rq)
 {
        struct as_rq *arq = RQ_DATA(rq);
        struct rb_node *rbnext = rb_next(&arq->rb_node);
@@ -1537,7 +1553,7 @@ static void as_merged_request(request_queue_t *q, struct request *req)
                 * currently don't bother. Ditto the next function.
                 */
                as_del_arq_rb(ad, arq);
-               if ((alias = as_add_arq_rb(ad, arq)) ) {
+               if ((alias = as_add_arq_rb(ad, arq))) {
                        list_del_init(&arq->fifo);
                        as_add_aliased_request(ad, arq, alias);
                        if (next_arq)
@@ -1551,9 +1567,8 @@ static void as_merged_request(request_queue_t *q, struct request *req)
        }
 }
 
-static void
-as_merged_requests(request_queue_t *q, struct request *req,
-                        struct request *next)
+static void as_merged_requests(request_queue_t *q, struct request *req,
+                               struct request *next)
 {
        struct as_data *ad = q->elevator->elevator_data;
        struct as_rq *arq = RQ_DATA(req);
@@ -1576,7 +1591,7 @@ as_merged_requests(request_queue_t *q, struct request *req,
                        next_arq = as_find_next_arq(ad, arq);
 
                as_del_arq_rb(ad, arq);
-               if ((alias = as_add_arq_rb(ad, arq)) ) {
+               if ((alias = as_add_arq_rb(ad, arq))) {
                        list_del_init(&arq->fifo);
                        as_add_aliased_request(ad, arq, alias);
                        if (next_arq)
@@ -1806,9 +1821,14 @@ static ssize_t as_est_show(struct as_data *ad, char *page)
 {
        int pos = 0;
 
-       pos += sprintf(page+pos, "%lu %% exit probability\n", 100*ad->exit_prob/256);
+       pos += sprintf(page+pos, "%lu %% exit probability\n",
+                               100*ad->exit_prob/256);
+       pos += sprintf(page+pos, "%lu %% probability of exiting without a "
+                               "cooperating process submitting IO\n",
+                               100*ad->exit_no_coop/256);
        pos += sprintf(page+pos, "%lu ms new thinktime\n", ad->new_ttime_mean);
-       pos += sprintf(page+pos, "%llu sectors new seek distance\n", (unsigned long long)ad->new_seek_mean);
+       pos += sprintf(page+pos, "%llu sectors new seek distance\n",
+                               (unsigned long long)ad->new_seek_mean);
 
        return pos;
 }
index 486b6e1c7dfb96aaa1a8e98e06169d7ce7164f27..a97c80b57737528b3e5cf6b1da2f351584dc14ca 100644 (file)
@@ -1096,14 +1096,11 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
 cleanup1:
                if (buff) {
                        for(i=0; i<sg_used; i++)
-                               if(buff[i] != NULL)
-                                       kfree(buff[i]);
+                               kfree(buff[i]);
                        kfree(buff);
                }
-               if (buff_size)
-                       kfree(buff_size);
-               if (ioc)
-                       kfree(ioc);
+               kfree(buff_size);
+               kfree(ioc);
                return(status);
        }
        default:
@@ -3034,8 +3031,7 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
        return(1);
 
 clean4:
-       if(hba[i]->cmd_pool_bits)
-                       kfree(hba[i]->cmd_pool_bits);
+       kfree(hba[i]->cmd_pool_bits);
        if(hba[i]->cmd_pool)
                pci_free_consistent(hba[i]->pdev,
                        NR_CMDS * sizeof(CommandList_struct),
index 2747741677fb0d92c10dc76c272763eb6f2b1a96..5f52e30b43f812c75cef8289571e9a1a35bd2808 100644 (file)
@@ -706,7 +706,6 @@ EXPORT_SYMBOL(blk_queue_dma_alignment);
 
 /**
  * blk_queue_find_tag - find a request by its tag and queue
- *
  * @q:  The request queue for the device
  * @tag: The tag of the request
  *
index 5fd3e4cb7525a94e376d03a10a6cf18768d5ef5d..8e7fb355177528fe544d32a990d5d7849ed85fda 100644 (file)
@@ -179,14 +179,12 @@ static int bcm203x_probe(struct usb_interface *intf, const struct usb_device_id
        if (ignore || (intf->cur_altsetting->desc.bInterfaceNumber != 0))
                return -ENODEV;
 
-       data = kmalloc(sizeof(*data), GFP_KERNEL);
+       data = kzalloc(sizeof(*data), GFP_KERNEL);
        if (!data) {
                BT_ERR("Can't allocate memory for data structure");
                return -ENOMEM;
        }
 
-       memset(data, 0, sizeof(*data));
-
        data->udev  = udev;
        data->state = BCM203X_LOAD_MINIDRV;
 
index 1e9db0156ea7d5e574f62cf08283fd5bd19f45f3..067e27893e4a8e4d5b1cbcc1692edd26d0034228 100644 (file)
@@ -673,13 +673,11 @@ static int bfusb_probe(struct usb_interface *intf, const struct usb_device_id *i
        }
 
        /* Initialize control structure and load firmware */
-       if (!(bfusb = kmalloc(sizeof(struct bfusb), GFP_KERNEL))) {
+       if (!(bfusb = kzalloc(sizeof(struct bfusb), GFP_KERNEL))) {
                BT_ERR("Can't allocate memory for control structure");
                goto done;
        }
 
-       memset(bfusb, 0, sizeof(struct bfusb));
-
        bfusb->udev = udev;
        bfusb->bulk_in_ep    = bulk_in_ep->desc.bEndpointAddress;
        bfusb->bulk_out_ep   = bulk_out_ep->desc.bEndpointAddress;
index 26fe9c0e1d20e4c1ef51c47428cf5672ae5db56c..f36c563d72c4f49f8334ee8e6a9ee3c8793f51a9 100644 (file)
@@ -870,10 +870,9 @@ static dev_link_t *bluecard_attach(void)
        int ret;
 
        /* Create new info device */
-       info = kmalloc(sizeof(*info), GFP_KERNEL);
+       info = kzalloc(sizeof(*info), GFP_KERNEL);
        if (!info)
                return NULL;
-       memset(info, 0, sizeof(*info));
 
        link = &info->link;
        link->priv = info;
index 0db0400519c95ee5f32bd576f371580ae8c6f463..ecbeb7eaba8e25c3c45ee0a8de1cd8163a8446b8 100644 (file)
@@ -553,14 +553,12 @@ static int bpa10x_probe(struct usb_interface *intf, const struct usb_device_id *
        if (intf->cur_altsetting->desc.bInterfaceNumber > 0)
                return -ENODEV;
 
-       data = kmalloc(sizeof(*data), GFP_KERNEL);
+       data = kzalloc(sizeof(*data), GFP_KERNEL);
        if (!data) {
                BT_ERR("Can't allocate data structure");
                return -ENOMEM;
        }
 
-       memset(data, 0, sizeof(*data));
-
        data->udev = udev;
 
        rwlock_init(&data->lock);
index 2e0338d80f32c1db8ba8e2f1a4e524e08298aeb6..d2a0add19cc88a52ddcd703495fdcf0584b00022 100644 (file)
@@ -671,10 +671,9 @@ static dev_link_t *bt3c_attach(void)
        int ret;
 
        /* Create new info device */
-       info = kmalloc(sizeof(*info), GFP_KERNEL);
+       info = kzalloc(sizeof(*info), GFP_KERNEL);
        if (!info)
                return NULL;
-       memset(info, 0, sizeof(*info));
 
        link = &info->link;
        link->priv = info;
index 89486ea7a0216db3712b3182fddde49824920d15..529a28a3209d1999961b12b02b6eba8ea80b7b63 100644 (file)
@@ -590,10 +590,9 @@ static dev_link_t *btuart_attach(void)
        int ret;
 
        /* Create new info device */
-       info = kmalloc(sizeof(*info), GFP_KERNEL);
+       info = kzalloc(sizeof(*info), GFP_KERNEL);
        if (!info)
                return NULL;
-       memset(info, 0, sizeof(*info));
 
        link = &info->link;
        link->priv = info;
index 84c1f88394225504ff7c2e02f77a8f043db85960..dec5980a1cd6811f79906b278ed09c0cf9d70c44 100644 (file)
@@ -569,10 +569,9 @@ static dev_link_t *dtl1_attach(void)
        int ret;
 
        /* Create new info device */
-       info = kmalloc(sizeof(*info), GFP_KERNEL);
+       info = kzalloc(sizeof(*info), GFP_KERNEL);
        if (!info)
                return NULL;
-       memset(info, 0, sizeof(*info));
 
        link = &info->link;
        link->priv = info;
index 0a4761415ac39be6cedd01b0d77c4cb570bd2495..8fddfdfd0fbdcca1c779cc12736051f8c9439c6c 100644 (file)
@@ -715,10 +715,9 @@ static int bcsp_open(struct hci_uart *hu)
 
        BT_DBG("hu %p", hu);
 
-       bcsp = kmalloc(sizeof(*bcsp), GFP_ATOMIC);
+       bcsp = kzalloc(sizeof(*bcsp), GFP_ATOMIC);
        if (!bcsp)
                return -ENOMEM;
-       memset(bcsp, 0, sizeof(*bcsp));
 
        hu->priv = bcsp;
        skb_queue_head_init(&bcsp->unack);
index 12e369a66fc24be1e2dba29cae82a679576ca32d..4804d474dc8735d4a2365258385551134134c616 100644 (file)
@@ -76,12 +76,10 @@ static int h4_open(struct hci_uart *hu)
 
        BT_DBG("hu %p", hu);
 
-       h4 = kmalloc(sizeof(*h4), GFP_ATOMIC);
+       h4 = kzalloc(sizeof(*h4), GFP_ATOMIC);
        if (!h4)
                return -ENOMEM;
 
-       memset(h4, 0, sizeof(*h4));
-
        skb_queue_head_init(&h4->txq);
 
        hu->priv = h4;
index 4a775f6ea3907134fe8f0fa64b69086bc515e31a..573ff6c1be5f6080362407f17f0785729317025c 100644 (file)
@@ -272,13 +272,11 @@ static int hci_uart_tty_open(struct tty_struct *tty)
        if (hu)
                return -EEXIST;
 
-       if (!(hu = kmalloc(sizeof(struct hci_uart), GFP_KERNEL))) {
+       if (!(hu = kzalloc(sizeof(struct hci_uart), GFP_KERNEL))) {
                BT_ERR("Can't allocate controll structure");
                return -ENFILE;
        }
 
-       memset(hu, 0, sizeof(struct hci_uart));
-
        tty->disc_data = hu;
        hu->tty = tty;
 
index 6756cb20b753875e7a22cc3c7f047d2e134b9ea6..f510b25b2c59010c0967e4488eebccbeaee994cc 100644 (file)
@@ -875,13 +875,11 @@ static int hci_usb_probe(struct usb_interface *intf, const struct usb_device_id
                goto done;
        }
 
-       if (!(husb = kmalloc(sizeof(struct hci_usb), GFP_KERNEL))) {
+       if (!(husb = kzalloc(sizeof(struct hci_usb), GFP_KERNEL))) {
                BT_ERR("Can't allocate: control structure");
                goto done;
        }
 
-       memset(husb, 0, sizeof(struct hci_usb));
-
        husb->udev = udev;
        husb->bulk_out_ep = bulk_out_ep;
        husb->bulk_in_ep  = bulk_in_ep;
index 52cbd45c308fa0189d9d0a6ef044ebc49651a379..85738223ff0c47648c50b5985652baa0e1387e87 100644 (file)
@@ -261,12 +261,10 @@ static int vhci_open(struct inode *inode, struct file *file)
        struct vhci_data *vhci;
        struct hci_dev *hdev;
 
-       vhci = kmalloc(sizeof(struct vhci_data), GFP_KERNEL);
+       vhci = kzalloc(sizeof(struct vhci_data), GFP_KERNEL);
        if (!vhci)
                return -ENOMEM;
 
-       memset(vhci, 0, sizeof(struct vhci_data));
-
        skb_queue_head_init(&vhci->readq);
        init_waitqueue_head(&vhci->read_wait);
 
index b89420e6d7047ce41e7c252363e07e8b4de43904..a0b580c22d80942dbd75536609076f219edce33b 100644 (file)
@@ -1085,7 +1085,7 @@ static int __init mcdx_init_drive(int drive)
 
        xtrace(INIT, "kmalloc space for stuffpt's\n");
        xtrace(MALLOC, "init() malloc %d bytes\n", size);
-       if (!(stuffp = kmalloc(size, GFP_KERNEL))) {
+       if (!(stuffp = kzalloc(size, GFP_KERNEL))) {
                xwarn("init() malloc failed\n");
                return 1;
        }
@@ -1101,8 +1101,6 @@ static int __init mcdx_init_drive(int drive)
               sizeof(*stuffp), stuffp);
 
        /* set default values */
-       memset(stuffp, 0, sizeof(*stuffp));
-
        stuffp->present = 0;    /* this should be 0 already */
        stuffp->toc = NULL;     /* this should be NULL already */
 
index 0e6c3a31d3448a820f4f8a95d8f43d6d6d2a9915..78ce98a69f37044dfe17c98d6f264f3989535a23 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/agp_backend.h>
+#include <linux/mmzone.h>
 #include <asm/page.h>          /* PAGE_SIZE */
 #include "agp.h"
 
index 406dea914635f166a529ddb7529bb01f805f19ce..c85a4fa60da7e235b207a6ba84d305928ec1e142 100644 (file)
@@ -345,17 +345,15 @@ static void con_release_unimap(struct uni_pagedir *p)
        for (i = 0; i < 32; i++) {
                if ((p1 = p->uni_pgdir[i]) != NULL) {
                        for (j = 0; j < 32; j++)
-                               if (p1[j])
-                                       kfree(p1[j]);
+                               kfree(p1[j]);
                        kfree(p1);
                }
                p->uni_pgdir[i] = NULL;
        }
-       for (i = 0; i < 4; i++)
-               if (p->inverse_translations[i]) {
-                       kfree(p->inverse_translations[i]);
-                       p->inverse_translations[i] = NULL;
-               }
+       for (i = 0; i < 4; i++) {
+               kfree(p->inverse_translations[i]);
+               p->inverse_translations[i] = NULL;
+       }
 }
 
 void con_free_unimap(struct vc_data *vc)
index 8a6cc2751bc9253a2f2b779177972081e0c23cfe..1383727b443ad98fb28795b1f71c7ecd02ff0d46 100644 (file)
@@ -526,10 +526,8 @@ int ffb_driver_rmctx(struct inode *inode, struct file *filp, unsigned int cmd,
        if (idx < 0 || idx >= FFB_MAX_CTXS)
                return -EINVAL;
 
-       if (fpriv->hw_state[idx] != NULL) {
-               kfree(fpriv->hw_state[idx]);
-               fpriv->hw_state[idx] = NULL;
-       }
+       kfree(fpriv->hw_state[idx]);
+       fpriv->hw_state[idx] = NULL;
        return 0;
 }
 
index 5c121d6df9f2d4139d4ae76a7451bd6e826da216..c13f9abb41e9b2f3ad88a8303e525ebf874b35d5 100644 (file)
@@ -245,14 +245,12 @@ static void ffb_driver_release(drm_device_t * dev, struct file *filp)
 
 static void ffb_driver_pretakedown(drm_device_t * dev)
 {
-       if (dev->dev_private)
-               kfree(dev->dev_private);
+       kfree(dev->dev_private);
 }
 
 static int ffb_driver_postcleanup(drm_device_t * dev)
 {
-       if (ffb_position != NULL)
-               kfree(ffb_position);
+       kfree(ffb_position);
        return 0;
 }
 
index f834d05ccc976bb90828047c29fd1af28350e7fa..dd761a1e4f084709bd1e5c3dfac6ccbab5878826 100644 (file)
@@ -106,9 +106,7 @@ iiEllisInit(void)
 static void
 iiEllisCleanup(void)
 {
-       if ( pDelayTimer != NULL ) {
-               kfree ( pDelayTimer );
-       }
+       kfree(pDelayTimer);
 }
 
 //******************************************************************************
index 33862670e285542fe7f4733fc299aef0346db31c..58dcdee1cd719ab3d165907fb76f53c6e55c5db6 100644 (file)
@@ -28,6 +28,8 @@
 
 #include <linux/kernel.h> /* For printk. */
 #include <linux/string.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
 #include <linux/ipmi_msgdefs.h>                /* for completion codes */
 #include "ipmi_si_sm.h"
 
@@ -36,6 +38,8 @@ static int bt_debug = 0x00;   /* Production value 0, see following flags */
 #define        BT_DEBUG_ENABLE 1
 #define BT_DEBUG_MSG   2
 #define BT_DEBUG_STATES        4
+module_param(bt_debug, int, 0644);
+MODULE_PARM_DESC(bt_debug, "debug bitmask, 1=enable, 2=messages, 4=states");
 
 /* Typical "Get BT Capabilities" values are 2-3 retries, 5-10 seconds,
    and 64 byte buffers.  However, one HP implementation wants 255 bytes of
@@ -43,7 +47,7 @@ static int bt_debug = 0x00;   /* Production value 0, see following flags */
    Since the Open IPMI architecture is single-message oriented at this
    stage, the queue depth of BT is of no concern. */
 
-#define BT_NORMAL_TIMEOUT      2000000 /* seconds in microseconds */
+#define BT_NORMAL_TIMEOUT      5000000 /* seconds in microseconds */
 #define BT_RETRY_LIMIT         2
 #define BT_RESET_DELAY         6000000 /* 6 seconds after warm reset */
 
@@ -202,7 +206,7 @@ static int bt_get_result(struct si_sm_data *bt,
        msg_len = bt->read_count - 2;           /* account for length & seq */
        /* Always NetFn, Cmd, cCode */
        if (msg_len < 3 || msg_len > IPMI_MAX_MSG_LENGTH) {
-               printk(KERN_WARNING "BT results: bad msg_len = %d\n", msg_len);
+               printk(KERN_DEBUG "BT results: bad msg_len = %d\n", msg_len);
                data[0] = bt->write_data[1] | 0x4;      /* Kludge a response */
                data[1] = bt->write_data[3];
                data[2] = IPMI_ERR_UNSPECIFIED;
@@ -240,7 +244,7 @@ static void reset_flags(struct si_sm_data *bt)
               BT_CONTROL(BT_B_BUSY);
        BT_CONTROL(BT_CLR_WR_PTR);
        BT_CONTROL(BT_SMS_ATN);
-#ifdef DEVELOPMENT_ONLY_NOT_FOR_PRODUCTION
+
        if (BT_STATUS & BT_B2H_ATN) {
                int i;
                BT_CONTROL(BT_H_BUSY);
@@ -250,7 +254,6 @@ static void reset_flags(struct si_sm_data *bt)
                       BMC2HOST;
                BT_CONTROL(BT_H_BUSY);
        }
-#endif
 }
 
 static inline void write_all_bytes(struct si_sm_data *bt)
@@ -295,7 +298,7 @@ static inline int read_all_bytes(struct si_sm_data *bt)
                printk ("\n");
        }
        if (bt->seq != bt->write_data[2])       /* idiot check */
-               printk(KERN_WARNING "BT: internal error: sequence mismatch\n");
+               printk(KERN_DEBUG "BT: internal error: sequence mismatch\n");
 
        /* per the spec, the (NetFn, Seq, Cmd) tuples should match */
        if ((bt->read_data[3] == bt->write_data[3]) &&          /* Cmd */
@@ -321,18 +324,17 @@ static void error_recovery(struct si_sm_data *bt, char *reason)
        bt->timeout = BT_NORMAL_TIMEOUT; /* various places want to retry */
 
        status = BT_STATUS;
-       printk(KERN_WARNING "BT: %s in %s %s ", reason, STATE2TXT,
+       printk(KERN_DEBUG "BT: %s in %s %s\n", reason, STATE2TXT,
               STATUS2TXT(buf));
 
        (bt->error_retries)++;
        if (bt->error_retries > BT_RETRY_LIMIT) {
-               printk("retry limit (%d) exceeded\n", BT_RETRY_LIMIT);
+               printk(KERN_DEBUG "retry limit (%d) exceeded\n", BT_RETRY_LIMIT);
                bt->state = BT_STATE_HOSED;
                if (!bt->nonzero_status)
                        printk(KERN_ERR "IPMI: BT stuck, try power cycle\n");
-               else if (bt->seq == FIRST_SEQ + BT_RETRY_LIMIT) {
-                       /* most likely during insmod */
-                       printk(KERN_WARNING "IPMI: BT reset (takes 5 secs)\n");
+               else if (bt->error_retries <= BT_RETRY_LIMIT + 1) {
+                       printk(KERN_DEBUG "IPMI: BT reset (takes 5 secs)\n");
                        bt->state = BT_STATE_RESET1;
                }
        return;
@@ -340,11 +342,11 @@ static void error_recovery(struct si_sm_data *bt, char *reason)
 
        /* Sometimes the BMC queues get in an "off-by-one" state...*/
        if ((bt->state == BT_STATE_B2H_WAIT) && (status & BT_B2H_ATN)) {
-               printk("retry B2H_WAIT\n");
+               printk(KERN_DEBUG "retry B2H_WAIT\n");
                return;
        }
 
-       printk("restart command\n");
+       printk(KERN_DEBUG "restart command\n");
        bt->state = BT_STATE_RESTART;
 }
 
@@ -372,17 +374,6 @@ static enum si_sm_result bt_event(struct si_sm_data *bt, long time)
               return SI_SM_HOSED;
 
        if (bt->state != BT_STATE_IDLE) {       /* do timeout test */
-
-               /* Certain states, on error conditions, can lock up a CPU
-                  because they are effectively in an infinite loop with
-                  CALL_WITHOUT_DELAY (right back here with time == 0).
-                  Prevent infinite lockup by ALWAYS decrementing timeout. */
-
-       /* FIXME: bt_event is sometimes called with time > BT_NORMAL_TIMEOUT
-              (noticed in ipmi_smic_sm.c January 2004) */
-
-               if ((time <= 0) || (time >= BT_NORMAL_TIMEOUT))
-                      time = 100;
                bt->timeout -= time;
                if ((bt->timeout < 0) && (bt->state < BT_STATE_RESET1)) {
                        error_recovery(bt, "timed out");
@@ -483,6 +474,7 @@ static enum si_sm_result bt_event(struct si_sm_data *bt, long time)
                break;
 
        case BT_STATE_RESTART:          /* don't reset retries! */
+               reset_flags(bt);
                bt->write_data[2] = ++bt->seq;
                bt->read_count = 0;
                bt->nonzero_status = 0;
index d21853a594a3b74c2354988d523f8cdd0bbcf71d..da1554194d3db10677996060fb37d66ecdfe4058 100644 (file)
  */
 
 #include <linux/kernel.h> /* For printk. */
+#include <linux/module.h>
+#include <linux/moduleparam.h>
 #include <linux/string.h>
+#include <linux/jiffies.h>
 #include <linux/ipmi_msgdefs.h>                /* for completion codes */
 #include "ipmi_si_sm.h"
 
-/* Set this if you want a printout of why the state machine was hosed
-   when it gets hosed. */
-#define DEBUG_HOSED_REASON
+/* kcs_debug is a bit-field
+ *     KCS_DEBUG_ENABLE -      turned on for now
+ *     KCS_DEBUG_MSG    -      commands and their responses
+ *     KCS_DEBUG_STATES -      state machine
+ */
+#define KCS_DEBUG_STATES       4
+#define KCS_DEBUG_MSG          2
+#define        KCS_DEBUG_ENABLE        1
 
-/* Print the state machine state on entry every time. */
-#undef DEBUG_STATE
+static int kcs_debug;
+module_param(kcs_debug, int, 0644);
+MODULE_PARM_DESC(kcs_debug, "debug bitmask, 1=enable, 2=messages, 4=states");
 
 /* The states the KCS driver may be in. */
 enum kcs_states {
@@ -91,6 +100,7 @@ enum kcs_states {
 #define IBF_RETRY_TIMEOUT 1000000
 #define OBF_RETRY_TIMEOUT 1000000
 #define MAX_ERROR_RETRIES 10
+#define ERROR0_OBF_WAIT_JIFFIES (2*HZ)
 
 struct si_sm_data
 {
@@ -107,6 +117,7 @@ struct si_sm_data
        unsigned int  error_retries;
        long          ibf_timeout;
        long          obf_timeout;
+       unsigned long  error0_timeout;
 };
 
 static unsigned int init_kcs_data(struct si_sm_data *kcs,
@@ -175,11 +186,11 @@ static inline void start_error_recovery(struct si_sm_data *kcs, char *reason)
 {
        (kcs->error_retries)++;
        if (kcs->error_retries > MAX_ERROR_RETRIES) {
-#ifdef DEBUG_HOSED_REASON
-               printk("ipmi_kcs_sm: kcs hosed: %s\n", reason);
-#endif
+               if (kcs_debug & KCS_DEBUG_ENABLE)
+                       printk(KERN_DEBUG "ipmi_kcs_sm: kcs hosed: %s\n", reason);
                kcs->state = KCS_HOSED;
        } else {
+               kcs->error0_timeout = jiffies + ERROR0_OBF_WAIT_JIFFIES;
                kcs->state = KCS_ERROR0;
        }
 }
@@ -248,14 +259,21 @@ static void restart_kcs_transaction(struct si_sm_data *kcs)
 static int start_kcs_transaction(struct si_sm_data *kcs, unsigned char *data,
                                 unsigned int size)
 {
+       unsigned int i;
+
        if ((size < 2) || (size > MAX_KCS_WRITE_SIZE)) {
                return -1;
        }
-
        if ((kcs->state != KCS_IDLE) && (kcs->state != KCS_HOSED)) {
                return -2;
        }
-
+       if (kcs_debug & KCS_DEBUG_MSG) {
+               printk(KERN_DEBUG "start_kcs_transaction -");
+               for (i = 0; i < size; i ++) {
+                       printk(" %02x", (unsigned char) (data [i]));
+               }
+               printk ("\n");
+       }
        kcs->error_retries = 0;
        memcpy(kcs->write_data, data, size);
        kcs->write_count = size;
@@ -305,9 +323,9 @@ static enum si_sm_result kcs_event(struct si_sm_data *kcs, long time)
 
        status = read_status(kcs);
 
-#ifdef DEBUG_STATE
-       printk("  State = %d, %x\n", kcs->state, status);
-#endif
+       if (kcs_debug & KCS_DEBUG_STATES)
+               printk(KERN_DEBUG "KCS: State = %d, %x\n", kcs->state, status);
+
        /* All states wait for ibf, so just do it here. */
        if (!check_ibf(kcs, status, time))
                return SI_SM_CALL_WITH_DELAY;
@@ -409,6 +427,10 @@ static enum si_sm_result kcs_event(struct si_sm_data *kcs, long time)
 
        case KCS_ERROR0:
                clear_obf(kcs, status);
+               status = read_status(kcs);
+               if  (GET_STATUS_OBF(status)) /* controller isn't responding */
+                       if (time_before(jiffies, kcs->error0_timeout))
+                               return SI_SM_CALL_WITH_TICK_DELAY;
                write_cmd(kcs, KCS_GET_STATUS_ABORT);
                kcs->state = KCS_ERROR1;
                break;
index 32fa82c78c73c16336a8527b7b9b4acceffa581a..c1d06ba449b60455fcffdeb908fca20f4952df8d 100644 (file)
 #include <linux/sched.h>
 #include <linux/poll.h>
 #include <linux/spinlock.h>
-#include <linux/rwsem.h>
 #include <linux/slab.h>
 #include <linux/ipmi.h>
 #include <linux/ipmi_smi.h>
 #include <linux/notifier.h>
 #include <linux/init.h>
 #include <linux/proc_fs.h>
+#include <linux/rcupdate.h>
 
 #define PFX "IPMI message handler: "
 
@@ -65,10 +65,19 @@ struct proc_dir_entry *proc_ipmi_root = NULL;
    the max message timer.  This is in milliseconds. */
 #define MAX_MSG_TIMEOUT                60000
 
+
+/*
+ * The main "user" data structure.
+ */
 struct ipmi_user
 {
        struct list_head link;
 
+       /* Set to "0" when the user is destroyed. */
+       int valid;
+
+       struct kref refcount;
+
        /* The upper layer that handles receive messages. */
        struct ipmi_user_hndl *handler;
        void             *handler_data;
@@ -87,6 +96,15 @@ struct cmd_rcvr
        ipmi_user_t   user;
        unsigned char netfn;
        unsigned char cmd;
+
+       /*
+        * This is used to form a linked lised during mass deletion.
+        * Since this is in an RCU list, we cannot use the link above
+        * or change any data until the RCU period completes.  So we
+        * use this next variable during mass deletion so we can have
+        * a list and don't have to wait and restart the search on
+        * every individual deletion of a command. */
+       struct cmd_rcvr *next;
 };
 
 struct seq_table
@@ -150,13 +168,11 @@ struct ipmi_smi
        /* What interface number are we? */
        int intf_num;
 
-       /* The list of upper layers that are using me.  We read-lock
-           this when delivering messages to the upper layer to keep
-           the user from going away while we are processing the
-           message.  This means that you cannot add or delete a user
-           from the receive callback. */
-       rwlock_t                users_lock;
-       struct list_head        users;
+       struct kref refcount;
+
+       /* The list of upper layers that are using me.  seq_lock
+        * protects this. */
+       struct list_head users;
 
        /* Used for wake ups at startup. */
        wait_queue_head_t waitq;
@@ -193,7 +209,7 @@ struct ipmi_smi
 
        /* The list of command receivers that are registered for commands
           on this interface. */
-       rwlock_t         cmd_rcvr_lock;
+       struct semaphore cmd_rcvrs_lock;
        struct list_head cmd_rcvrs;
 
        /* Events that were queues because no one was there to receive
@@ -296,16 +312,17 @@ struct ipmi_smi
        unsigned int events;
 };
 
+/* Used to mark an interface entry that cannot be used but is not a
+ * free entry, either, primarily used at creation and deletion time so
+ * a slot doesn't get reused too quickly. */
+#define IPMI_INVALID_INTERFACE_ENTRY ((ipmi_smi_t) ((long) 1))
+#define IPMI_INVALID_INTERFACE(i) (((i) == NULL) \
+                                  || (i == IPMI_INVALID_INTERFACE_ENTRY))
+
 #define MAX_IPMI_INTERFACES 4
 static ipmi_smi_t ipmi_interfaces[MAX_IPMI_INTERFACES];
 
-/* Used to keep interfaces from going away while operations are
-   operating on interfaces.  Grab read if you are not modifying the
-   interfaces, write if you are. */
-static DECLARE_RWSEM(interfaces_sem);
-
-/* Directly protects the ipmi_interfaces data structure.  This is
-   claimed in the timer interrupt. */
+/* Directly protects the ipmi_interfaces data structure. */
 static DEFINE_SPINLOCK(interfaces_lock);
 
 /* List of watchers that want to know when smi's are added and
@@ -313,20 +330,72 @@ static DEFINE_SPINLOCK(interfaces_lock);
 static struct list_head smi_watchers = LIST_HEAD_INIT(smi_watchers);
 static DECLARE_RWSEM(smi_watchers_sem);
 
+
+static void free_recv_msg_list(struct list_head *q)
+{
+       struct ipmi_recv_msg *msg, *msg2;
+
+       list_for_each_entry_safe(msg, msg2, q, link) {
+               list_del(&msg->link);
+               ipmi_free_recv_msg(msg);
+       }
+}
+
+static void clean_up_interface_data(ipmi_smi_t intf)
+{
+       int              i;
+       struct cmd_rcvr  *rcvr, *rcvr2;
+       struct list_head list;
+
+       free_recv_msg_list(&intf->waiting_msgs);
+       free_recv_msg_list(&intf->waiting_events);
+
+       /* Wholesale remove all the entries from the list in the
+        * interface and wait for RCU to know that none are in use. */
+       down(&intf->cmd_rcvrs_lock);
+       list_add_rcu(&list, &intf->cmd_rcvrs);
+       list_del_rcu(&intf->cmd_rcvrs);
+       up(&intf->cmd_rcvrs_lock);
+       synchronize_rcu();
+
+       list_for_each_entry_safe(rcvr, rcvr2, &list, link)
+               kfree(rcvr);
+
+       for (i = 0; i < IPMI_IPMB_NUM_SEQ; i++) {
+               if ((intf->seq_table[i].inuse)
+                   && (intf->seq_table[i].recv_msg))
+               {
+                       ipmi_free_recv_msg(intf->seq_table[i].recv_msg);
+               }
+       }
+}
+
+static void intf_free(struct kref *ref)
+{
+       ipmi_smi_t intf = container_of(ref, struct ipmi_smi, refcount);
+
+       clean_up_interface_data(intf);
+       kfree(intf);
+}
+
 int ipmi_smi_watcher_register(struct ipmi_smi_watcher *watcher)
 {
-       int i;
+       int           i;
+       unsigned long flags;
 
-       down_read(&interfaces_sem);
        down_write(&smi_watchers_sem);
        list_add(&(watcher->link), &smi_watchers);
+       up_write(&smi_watchers_sem);
+       spin_lock_irqsave(&interfaces_lock, flags);
        for (i = 0; i < MAX_IPMI_INTERFACES; i++) {
-               if (ipmi_interfaces[i] != NULL) {
-                       watcher->new_smi(i);
-               }
+               ipmi_smi_t intf = ipmi_interfaces[i];
+               if (IPMI_INVALID_INTERFACE(intf))
+                       continue;
+               spin_unlock_irqrestore(&interfaces_lock, flags);
+               watcher->new_smi(i);
+               spin_lock_irqsave(&interfaces_lock, flags);
        }
-       up_write(&smi_watchers_sem);
-       up_read(&interfaces_sem);
+       spin_unlock_irqrestore(&interfaces_lock, flags);
        return 0;
 }
 
@@ -471,8 +540,8 @@ static void deliver_response(struct ipmi_recv_msg *msg)
                }
                ipmi_free_recv_msg(msg);
        } else {
-               msg->user->handler->ipmi_recv_hndl(msg,
-                                                  msg->user->handler_data);
+               ipmi_user_t user = msg->user;
+               user->handler->ipmi_recv_hndl(msg, user->handler_data);
        }
 }
 
@@ -662,15 +731,18 @@ int ipmi_create_user(unsigned int          if_num,
        if (! new_user)
                return -ENOMEM;
 
-       down_read(&interfaces_sem);
-       if ((if_num >= MAX_IPMI_INTERFACES) || ipmi_interfaces[if_num] == NULL)
-       {
-               rv = -EINVAL;
-               goto out_unlock;
+       spin_lock_irqsave(&interfaces_lock, flags);
+       intf = ipmi_interfaces[if_num];
+       if ((if_num >= MAX_IPMI_INTERFACES) || IPMI_INVALID_INTERFACE(intf)) {
+               spin_unlock_irqrestore(&interfaces_lock, flags);
+               return -EINVAL;
        }
 
-       intf = ipmi_interfaces[if_num];
+       /* Note that each existing user holds a refcount to the interface. */
+       kref_get(&intf->refcount);
+       spin_unlock_irqrestore(&interfaces_lock, flags);
 
+       kref_init(&new_user->refcount);
        new_user->handler = handler;
        new_user->handler_data = handler_data;
        new_user->intf = intf;
@@ -678,98 +750,92 @@ int ipmi_create_user(unsigned int          if_num,
 
        if (!try_module_get(intf->handlers->owner)) {
                rv = -ENODEV;
-               goto out_unlock;
+               goto out_err;
        }
 
        if (intf->handlers->inc_usecount) {
                rv = intf->handlers->inc_usecount(intf->send_info);
                if (rv) {
                        module_put(intf->handlers->owner);
-                       goto out_unlock;
+                       goto out_err;
                }
        }
 
-       write_lock_irqsave(&intf->users_lock, flags);
-       list_add_tail(&new_user->link, &intf->users);
-       write_unlock_irqrestore(&intf->users_lock, flags);
-
- out_unlock:   
-       if (rv) {
-               kfree(new_user);
-       } else {
-               *user = new_user;
-       }
+       new_user->valid = 1;
+       spin_lock_irqsave(&intf->seq_lock, flags);
+       list_add_rcu(&new_user->link, &intf->users);
+       spin_unlock_irqrestore(&intf->seq_lock, flags);
+       *user = new_user;
+       return 0;
 
-       up_read(&interfaces_sem);
+ out_err:
+       kfree(new_user);
+       kref_put(&intf->refcount, intf_free);
        return rv;
 }
 
-static int ipmi_destroy_user_nolock(ipmi_user_t user)
+static void free_user(struct kref *ref)
+{
+       ipmi_user_t user = container_of(ref, struct ipmi_user, refcount);
+       kfree(user);
+}
+
+int ipmi_destroy_user(ipmi_user_t user)
 {
        int              rv = -ENODEV;
-       ipmi_user_t      t_user;
-       struct cmd_rcvr  *rcvr, *rcvr2;
+       ipmi_smi_t       intf = user->intf;
        int              i;
        unsigned long    flags;
+       struct cmd_rcvr  *rcvr;
+       struct list_head *entry1, *entry2;
+       struct cmd_rcvr  *rcvrs = NULL;
 
-       /* Find the user and delete them from the list. */
-       list_for_each_entry(t_user, &(user->intf->users), link) {
-               if (t_user == user) {
-                       list_del(&t_user->link);
-                       rv = 0;
-                       break;
-               }
-       }
+       user->valid = 1;
 
-       if (rv) {
-               goto out_unlock;
-       }
+       /* Remove the user from the interface's sequence table. */
+       spin_lock_irqsave(&intf->seq_lock, flags);
+       list_del_rcu(&user->link);
 
-       /* Remove the user from the interfaces sequence table. */
-       spin_lock_irqsave(&(user->intf->seq_lock), flags);
        for (i = 0; i < IPMI_IPMB_NUM_SEQ; i++) {
-               if (user->intf->seq_table[i].inuse
-                   && (user->intf->seq_table[i].recv_msg->user == user))
+               if (intf->seq_table[i].inuse
+                   && (intf->seq_table[i].recv_msg->user == user))
                {
-                       user->intf->seq_table[i].inuse = 0;
+                       intf->seq_table[i].inuse = 0;
                }
        }
-       spin_unlock_irqrestore(&(user->intf->seq_lock), flags);
-
-       /* Remove the user from the command receiver's table. */
-       write_lock_irqsave(&(user->intf->cmd_rcvr_lock), flags);
-       list_for_each_entry_safe(rcvr, rcvr2, &(user->intf->cmd_rcvrs), link) {
+       spin_unlock_irqrestore(&intf->seq_lock, flags);
+
+       /*
+        * Remove the user from the command receiver's table.  First
+        * we build a list of everything (not using the standard link,
+        * since other things may be using it till we do
+        * synchronize_rcu()) then free everything in that list.
+        */
+       down(&intf->cmd_rcvrs_lock);
+       list_for_each_safe_rcu(entry1, entry2, &intf->cmd_rcvrs) {
+               rcvr = list_entry(entry1, struct cmd_rcvr, link);
                if (rcvr->user == user) {
-                       list_del(&rcvr->link);
-                       kfree(rcvr);
+                       list_del_rcu(&rcvr->link);
+                       rcvr->next = rcvrs;
+                       rcvrs = rcvr;
                }
        }
-       write_unlock_irqrestore(&(user->intf->cmd_rcvr_lock), flags);
+       up(&intf->cmd_rcvrs_lock);
+       synchronize_rcu();
+       while (rcvrs) {
+               rcvr = rcvrs;
+               rcvrs = rcvr->next;
+               kfree(rcvr);
+       }
 
-       kfree(user);
+       module_put(intf->handlers->owner);
+       if (intf->handlers->dec_usecount)
+               intf->handlers->dec_usecount(intf->send_info);
 
- out_unlock:
+       kref_put(&intf->refcount, intf_free);
 
-       return rv;
-}
-
-int ipmi_destroy_user(ipmi_user_t user)
-{
-       int           rv;
-       ipmi_smi_t    intf = user->intf;
-       unsigned long flags;
+       kref_put(&user->refcount, free_user);
 
-       down_read(&interfaces_sem);
-       write_lock_irqsave(&intf->users_lock, flags);
-       rv = ipmi_destroy_user_nolock(user);
-       if (!rv) {
-               module_put(intf->handlers->owner);
-               if (intf->handlers->dec_usecount)
-                       intf->handlers->dec_usecount(intf->send_info);
-       }
-               
-       write_unlock_irqrestore(&intf->users_lock, flags);
-       up_read(&interfaces_sem);
        return rv;
 }
 
@@ -823,62 +889,78 @@ int ipmi_get_my_LUN(ipmi_user_t   user,
 
 int ipmi_set_gets_events(ipmi_user_t user, int val)
 {
-       unsigned long         flags;
-       struct ipmi_recv_msg  *msg, *msg2;
+       unsigned long        flags;
+       ipmi_smi_t           intf = user->intf;
+       struct ipmi_recv_msg *msg, *msg2;
+       struct list_head     msgs;
 
-       read_lock(&(user->intf->users_lock));
-       spin_lock_irqsave(&(user->intf->events_lock), flags);
+       INIT_LIST_HEAD(&msgs);
+
+       spin_lock_irqsave(&intf->events_lock, flags);
        user->gets_events = val;
 
        if (val) {
                /* Deliver any queued events. */
-               list_for_each_entry_safe(msg, msg2, &(user->intf->waiting_events), link) {
+               list_for_each_entry_safe(msg, msg2, &intf->waiting_events, link) {
                        list_del(&msg->link);
-                       msg->user = user;
-                       deliver_response(msg);
+                       list_add_tail(&msg->link, &msgs);
                }
        }
-       
-       spin_unlock_irqrestore(&(user->intf->events_lock), flags);
-       read_unlock(&(user->intf->users_lock));
+
+       /* Hold the events lock while doing this to preserve order. */
+       list_for_each_entry_safe(msg, msg2, &msgs, link) {
+               msg->user = user;
+               kref_get(&user->refcount);
+               deliver_response(msg);
+       }
+
+       spin_unlock_irqrestore(&intf->events_lock, flags);
 
        return 0;
 }
 
+static struct cmd_rcvr *find_cmd_rcvr(ipmi_smi_t    intf,
+                                     unsigned char netfn,
+                                     unsigned char cmd)
+{
+       struct cmd_rcvr *rcvr;
+
+       list_for_each_entry_rcu(rcvr, &intf->cmd_rcvrs, link) {
+               if ((rcvr->netfn == netfn) && (rcvr->cmd == cmd))
+                       return rcvr;
+       }
+       return NULL;
+}
+
 int ipmi_register_for_cmd(ipmi_user_t   user,
                          unsigned char netfn,
                          unsigned char cmd)
 {
-       struct cmd_rcvr  *cmp;
-       unsigned long    flags;
-       struct cmd_rcvr  *rcvr;
-       int              rv = 0;
+       ipmi_smi_t      intf = user->intf;
+       struct cmd_rcvr *rcvr;
+       struct cmd_rcvr *entry;
+       int             rv = 0;
 
 
        rcvr = kmalloc(sizeof(*rcvr), GFP_KERNEL);
        if (! rcvr)
                return -ENOMEM;
+       rcvr->cmd = cmd;
+       rcvr->netfn = netfn;
+       rcvr->user = user;
 
-       read_lock(&(user->intf->users_lock));
-       write_lock_irqsave(&(user->intf->cmd_rcvr_lock), flags);
+       down(&intf->cmd_rcvrs_lock);
        /* Make sure the command/netfn is not already registered. */
-       list_for_each_entry(cmp, &(user->intf->cmd_rcvrs), link) {
-               if ((cmp->netfn == netfn) && (cmp->cmd == cmd)) {
-                       rv = -EBUSY;
-                       break;
-               }
-       }
-
-       if (! rv) {
-               rcvr->cmd = cmd;
-               rcvr->netfn = netfn;
-               rcvr->user = user;
-               list_add_tail(&(rcvr->link), &(user->intf->cmd_rcvrs));
+       entry = find_cmd_rcvr(intf, netfn, cmd);
+       if (entry) {
+               rv = -EBUSY;
+               goto out_unlock;
        }
 
-       write_unlock_irqrestore(&(user->intf->cmd_rcvr_lock), flags);
-       read_unlock(&(user->intf->users_lock));
+       list_add_rcu(&rcvr->link, &intf->cmd_rcvrs);
 
+ out_unlock:
+       up(&intf->cmd_rcvrs_lock);
        if (rv)
                kfree(rcvr);
 
@@ -889,31 +971,28 @@ int ipmi_unregister_for_cmd(ipmi_user_t   user,
                            unsigned char netfn,
                            unsigned char cmd)
 {
-       unsigned long    flags;
-       struct cmd_rcvr  *rcvr;
-       int              rv = -ENOENT;
+       ipmi_smi_t      intf = user->intf;
+       struct cmd_rcvr *rcvr;
 
-       read_lock(&(user->intf->users_lock));
-       write_lock_irqsave(&(user->intf->cmd_rcvr_lock), flags);
+       down(&intf->cmd_rcvrs_lock);
        /* Make sure the command/netfn is not already registered. */
-       list_for_each_entry(rcvr, &(user->intf->cmd_rcvrs), link) {
-               if ((rcvr->netfn == netfn) && (rcvr->cmd == cmd)) {
-                       rv = 0;
-                       list_del(&rcvr->link);
-                       kfree(rcvr);
-                       break;
-               }
+       rcvr = find_cmd_rcvr(intf, netfn, cmd);
+       if ((rcvr) && (rcvr->user == user)) {
+               list_del_rcu(&rcvr->link);
+               up(&intf->cmd_rcvrs_lock);
+               synchronize_rcu();
+               kfree(rcvr);
+               return 0;
+       } else {
+               up(&intf->cmd_rcvrs_lock);
+               return -ENOENT;
        }
-       write_unlock_irqrestore(&(user->intf->cmd_rcvr_lock), flags);
-       read_unlock(&(user->intf->users_lock));
-
-       return rv;
 }
 
 void ipmi_user_set_run_to_completion(ipmi_user_t user, int val)
 {
-       user->intf->handlers->set_run_to_completion(user->intf->send_info,
-                                                   val);
+       ipmi_smi_t intf = user->intf;
+       intf->handlers->set_run_to_completion(intf->send_info, val);
 }
 
 static unsigned char
@@ -1010,19 +1089,19 @@ static inline void format_lan_msg(struct ipmi_smi_msg   *smi_msg,
    supplied in certain circumstances (mainly at panic time).  If
    messages are supplied, they will be freed, even if an error
    occurs. */
-static inline int i_ipmi_request(ipmi_user_t          user,
-                                ipmi_smi_t           intf,
-                                struct ipmi_addr     *addr,
-                                long                 msgid,
-                                struct kernel_ipmi_msg *msg,
-                                void                 *user_msg_data,
-                                void                 *supplied_smi,
-                                struct ipmi_recv_msg *supplied_recv,
-                                int                  priority,
-                                unsigned char        source_address,
-                                unsigned char        source_lun,
-                                int                  retries,
-                                unsigned int         retry_time_ms)
+static int i_ipmi_request(ipmi_user_t          user,
+                         ipmi_smi_t           intf,
+                         struct ipmi_addr     *addr,
+                         long                 msgid,
+                         struct kernel_ipmi_msg *msg,
+                         void                 *user_msg_data,
+                         void                 *supplied_smi,
+                         struct ipmi_recv_msg *supplied_recv,
+                         int                  priority,
+                         unsigned char        source_address,
+                         unsigned char        source_lun,
+                         int                  retries,
+                         unsigned int         retry_time_ms)
 {
        int                  rv = 0;
        struct ipmi_smi_msg  *smi_msg;
@@ -1051,6 +1130,8 @@ static inline int i_ipmi_request(ipmi_user_t          user,
        }
 
        recv_msg->user = user;
+       if (user)
+               kref_get(&user->refcount);
        recv_msg->msgid = msgid;
        /* Store the message to send in the receive message so timeout
           responses can get the proper response data. */
@@ -1725,11 +1806,11 @@ int ipmi_register_smi(struct ipmi_smi_handlers *handlers,
                      unsigned char            version_major,
                      unsigned char            version_minor,
                      unsigned char            slave_addr,
-                     ipmi_smi_t               *intf)
+                     ipmi_smi_t               *new_intf)
 {
        int              i, j;
        int              rv;
-       ipmi_smi_t       new_intf;
+       ipmi_smi_t       intf;
        unsigned long    flags;
 
 
@@ -1745,189 +1826,142 @@ int ipmi_register_smi(struct ipmi_smi_handlers *handlers,
                        return -ENODEV;
        }
 
-       new_intf = kmalloc(sizeof(*new_intf), GFP_KERNEL);
-       if (!new_intf)
+       intf = kmalloc(sizeof(*intf), GFP_KERNEL);
+       if (!intf)
                return -ENOMEM;
-       memset(new_intf, 0, sizeof(*new_intf));
-
-       new_intf->proc_dir = NULL;
+       memset(intf, 0, sizeof(*intf));
+       intf->intf_num = -1;
+       kref_init(&intf->refcount);
+       intf->version_major = version_major;
+       intf->version_minor = version_minor;
+       for (j = 0; j < IPMI_MAX_CHANNELS; j++) {
+               intf->channels[j].address = IPMI_BMC_SLAVE_ADDR;
+               intf->channels[j].lun = 2;
+       }
+       if (slave_addr != 0)
+               intf->channels[0].address = slave_addr;
+       INIT_LIST_HEAD(&intf->users);
+       intf->handlers = handlers;
+       intf->send_info = send_info;
+       spin_lock_init(&intf->seq_lock);
+       for (j = 0; j < IPMI_IPMB_NUM_SEQ; j++) {
+               intf->seq_table[j].inuse = 0;
+               intf->seq_table[j].seqid = 0;
+       }
+       intf->curr_seq = 0;
+#ifdef CONFIG_PROC_FS
+       spin_lock_init(&intf->proc_entry_lock);
+#endif
+       spin_lock_init(&intf->waiting_msgs_lock);
+       INIT_LIST_HEAD(&intf->waiting_msgs);
+       spin_lock_init(&intf->events_lock);
+       INIT_LIST_HEAD(&intf->waiting_events);
+       intf->waiting_events_count = 0;
+       init_MUTEX(&intf->cmd_rcvrs_lock);
+       INIT_LIST_HEAD(&intf->cmd_rcvrs);
+       init_waitqueue_head(&intf->waitq);
+
+       spin_lock_init(&intf->counter_lock);
+       intf->proc_dir = NULL;
 
        rv = -ENOMEM;
-
-       down_write(&interfaces_sem);
+       spin_lock_irqsave(&interfaces_lock, flags);
        for (i = 0; i < MAX_IPMI_INTERFACES; i++) {
                if (ipmi_interfaces[i] == NULL) {
-                       new_intf->intf_num = i;
-                       new_intf->version_major = version_major;
-                       new_intf->version_minor = version_minor;
-                       for (j = 0; j < IPMI_MAX_CHANNELS; j++) {
-                               new_intf->channels[j].address
-                                       = IPMI_BMC_SLAVE_ADDR;
-                               new_intf->channels[j].lun = 2;
-                       }
-                       if (slave_addr != 0)
-                               new_intf->channels[0].address = slave_addr;
-                       rwlock_init(&(new_intf->users_lock));
-                       INIT_LIST_HEAD(&(new_intf->users));
-                       new_intf->handlers = handlers;
-                       new_intf->send_info = send_info;
-                       spin_lock_init(&(new_intf->seq_lock));
-                       for (j = 0; j < IPMI_IPMB_NUM_SEQ; j++) {
-                               new_intf->seq_table[j].inuse = 0;
-                               new_intf->seq_table[j].seqid = 0;
-                       }
-                       new_intf->curr_seq = 0;
-#ifdef CONFIG_PROC_FS
-                       spin_lock_init(&(new_intf->proc_entry_lock));
-#endif
-                       spin_lock_init(&(new_intf->waiting_msgs_lock));
-                       INIT_LIST_HEAD(&(new_intf->waiting_msgs));
-                       spin_lock_init(&(new_intf->events_lock));
-                       INIT_LIST_HEAD(&(new_intf->waiting_events));
-                       new_intf->waiting_events_count = 0;
-                       rwlock_init(&(new_intf->cmd_rcvr_lock));
-                       init_waitqueue_head(&new_intf->waitq);
-                       INIT_LIST_HEAD(&(new_intf->cmd_rcvrs));
-
-                       spin_lock_init(&(new_intf->counter_lock));
-
-                       spin_lock_irqsave(&interfaces_lock, flags);
-                       ipmi_interfaces[i] = new_intf;
-                       spin_unlock_irqrestore(&interfaces_lock, flags);
-
+                       intf->intf_num = i;
+                       /* Reserve the entry till we are done. */
+                       ipmi_interfaces[i] = IPMI_INVALID_INTERFACE_ENTRY;
                        rv = 0;
-                       *intf = new_intf;
                        break;
                }
        }
+       spin_unlock_irqrestore(&interfaces_lock, flags);
+       if (rv)
+               goto out;
 
-       downgrade_write(&interfaces_sem);
-
-       if (rv == 0)
-               rv = add_proc_entries(*intf, i);
-
-       if (rv == 0) {
-               if ((version_major > 1)
-                   || ((version_major == 1) && (version_minor >= 5)))
-               {
-                       /* Start scanning the channels to see what is
-                          available. */
-                       (*intf)->null_user_handler = channel_handler;
-                       (*intf)->curr_channel = 0;
-                       rv = send_channel_info_cmd(*intf, 0);
-                       if (rv)
-                               goto out;
+       /* FIXME - this is an ugly kludge, this sets the intf for the
+          caller before sending any messages with it. */
+       *new_intf = intf;
 
-                       /* Wait for the channel info to be read. */
-                       up_read(&interfaces_sem);
-                       wait_event((*intf)->waitq,
-                                  ((*intf)->curr_channel>=IPMI_MAX_CHANNELS));
-                       down_read(&interfaces_sem);
+       if ((version_major > 1)
+           || ((version_major == 1) && (version_minor >= 5)))
+       {
+               /* Start scanning the channels to see what is
+                  available. */
+               intf->null_user_handler = channel_handler;
+               intf->curr_channel = 0;
+               rv = send_channel_info_cmd(intf, 0);
+               if (rv)
+                       goto out;
 
-                       if (ipmi_interfaces[i] != new_intf)
-                               /* Well, it went away.  Just return. */
-                               goto out;
-               } else {
-                       /* Assume a single IPMB channel at zero. */
-                       (*intf)->channels[0].medium = IPMI_CHANNEL_MEDIUM_IPMB;
-                       (*intf)->channels[0].protocol
-                               = IPMI_CHANNEL_PROTOCOL_IPMB;
-               }
-
-               /* Call all the watcher interfaces to tell
-                  them that a new interface is available. */
-               call_smi_watchers(i);
+               /* Wait for the channel info to be read. */
+               wait_event(intf->waitq,
+                          intf->curr_channel >= IPMI_MAX_CHANNELS);
+       } else {
+               /* Assume a single IPMB channel at zero. */
+               intf->channels[0].medium = IPMI_CHANNEL_MEDIUM_IPMB;
+               intf->channels[0].protocol = IPMI_CHANNEL_PROTOCOL_IPMB;
        }
 
- out:
-       up_read(&interfaces_sem);
+       if (rv == 0)
+               rv = add_proc_entries(intf, i);
 
+ out:
        if (rv) {
-               if (new_intf->proc_dir)
-                       remove_proc_entries(new_intf);
-               kfree(new_intf);
+               if (intf->proc_dir)
+                       remove_proc_entries(intf);
+               kref_put(&intf->refcount, intf_free);
+               if (i < MAX_IPMI_INTERFACES) {
+                       spin_lock_irqsave(&interfaces_lock, flags);
+                       ipmi_interfaces[i] = NULL;
+                       spin_unlock_irqrestore(&interfaces_lock, flags);
+               }
+       } else {
+               spin_lock_irqsave(&interfaces_lock, flags);
+               ipmi_interfaces[i] = intf;
+               spin_unlock_irqrestore(&interfaces_lock, flags);
+               call_smi_watchers(i);
        }
 
        return rv;
 }
 
-static void free_recv_msg_list(struct list_head *q)
-{
-       struct ipmi_recv_msg *msg, *msg2;
-
-       list_for_each_entry_safe(msg, msg2, q, link) {
-               list_del(&msg->link);
-               ipmi_free_recv_msg(msg);
-       }
-}
-
-static void free_cmd_rcvr_list(struct list_head *q)
-{
-       struct cmd_rcvr  *rcvr, *rcvr2;
-
-       list_for_each_entry_safe(rcvr, rcvr2, q, link) {
-               list_del(&rcvr->link);
-               kfree(rcvr);
-       }
-}
-
-static void clean_up_interface_data(ipmi_smi_t intf)
-{
-       int i;
-
-       free_recv_msg_list(&(intf->waiting_msgs));
-       free_recv_msg_list(&(intf->waiting_events));
-       free_cmd_rcvr_list(&(intf->cmd_rcvrs));
-
-       for (i = 0; i < IPMI_IPMB_NUM_SEQ; i++) {
-               if ((intf->seq_table[i].inuse)
-                   && (intf->seq_table[i].recv_msg))
-               {
-                       ipmi_free_recv_msg(intf->seq_table[i].recv_msg);
-               }       
-       }
-}
-
 int ipmi_unregister_smi(ipmi_smi_t intf)
 {
-       int                     rv = -ENODEV;
        int                     i;
        struct ipmi_smi_watcher *w;
        unsigned long           flags;
 
-       down_write(&interfaces_sem);
-       if (list_empty(&(intf->users)))
-       {
-               for (i = 0; i < MAX_IPMI_INTERFACES; i++) {
-                       if (ipmi_interfaces[i] == intf) {
-                               remove_proc_entries(intf);
-                               spin_lock_irqsave(&interfaces_lock, flags);
-                               ipmi_interfaces[i] = NULL;
-                               clean_up_interface_data(intf);
-                               spin_unlock_irqrestore(&interfaces_lock,flags);
-                               kfree(intf);
-                               rv = 0;
-                               goto out_call_watcher;
-                       }
+       spin_lock_irqsave(&interfaces_lock, flags);
+       for (i = 0; i < MAX_IPMI_INTERFACES; i++) {
+               if (ipmi_interfaces[i] == intf) {
+                       /* Set the interface number reserved until we
+                        * are done. */
+                       ipmi_interfaces[i] = IPMI_INVALID_INTERFACE_ENTRY;
+                       intf->intf_num = -1;
+                       break;
                }
-       } else {
-               rv = -EBUSY;
        }
-       up_write(&interfaces_sem);
+       spin_unlock_irqrestore(&interfaces_lock,flags);
 
-       return rv;
+       if (i == MAX_IPMI_INTERFACES)
+               return -ENODEV;
 
- out_call_watcher:
-       downgrade_write(&interfaces_sem);
+       remove_proc_entries(intf);
 
        /* Call all the watcher interfaces to tell them that
           an interface is gone. */
        down_read(&smi_watchers_sem);
-       list_for_each_entry(w, &smi_watchers, link) {
+       list_for_each_entry(w, &smi_watchers, link)
                w->smi_gone(i);
-       }
        up_read(&smi_watchers_sem);
-       up_read(&interfaces_sem);
+
+       /* Allow the entry to be reused now. */
+       spin_lock_irqsave(&interfaces_lock, flags);
+       ipmi_interfaces[i] = NULL;
+       spin_unlock_irqrestore(&interfaces_lock,flags);
+
+       kref_put(&intf->refcount, intf_free);
        return 0;
 }
 
@@ -1998,14 +2032,14 @@ static int handle_ipmb_get_msg_rsp(ipmi_smi_t          intf,
 static int handle_ipmb_get_msg_cmd(ipmi_smi_t          intf,
                                   struct ipmi_smi_msg *msg)
 {
-       struct cmd_rcvr       *rcvr;
-       int                   rv = 0;
-       unsigned char         netfn;
-       unsigned char         cmd;
-       ipmi_user_t           user = NULL;
-       struct ipmi_ipmb_addr *ipmb_addr;
-       struct ipmi_recv_msg  *recv_msg;
-       unsigned long         flags;
+       struct cmd_rcvr          *rcvr;
+       int                      rv = 0;
+       unsigned char            netfn;
+       unsigned char            cmd;
+       ipmi_user_t              user = NULL;
+       struct ipmi_ipmb_addr    *ipmb_addr;
+       struct ipmi_recv_msg     *recv_msg;
+       unsigned long            flags;
 
        if (msg->rsp_size < 10) {
                /* Message not big enough, just ignore it. */
@@ -2023,16 +2057,14 @@ static int handle_ipmb_get_msg_cmd(ipmi_smi_t          intf,
        netfn = msg->rsp[4] >> 2;
        cmd = msg->rsp[8];
 
-       read_lock(&(intf->cmd_rcvr_lock));
-       
-       /* Find the command/netfn. */
-       list_for_each_entry(rcvr, &(intf->cmd_rcvrs), link) {
-               if ((rcvr->netfn == netfn) && (rcvr->cmd == cmd)) {
-                       user = rcvr->user;
-                       break;
-               }
-       }
-       read_unlock(&(intf->cmd_rcvr_lock));
+       rcu_read_lock();
+       rcvr = find_cmd_rcvr(intf, netfn, cmd);
+       if (rcvr) {
+               user = rcvr->user;
+               kref_get(&user->refcount);
+       } else
+               user = NULL;
+       rcu_read_unlock();
 
        if (user == NULL) {
                /* We didn't find a user, deliver an error response. */
@@ -2079,6 +2111,7 @@ static int handle_ipmb_get_msg_cmd(ipmi_smi_t          intf,
                            message, so requeue it for handling
                            later. */
                        rv = 1;
+                       kref_put(&user->refcount, free_user);
                } else {
                        /* Extract the source address from the data. */
                        ipmb_addr = (struct ipmi_ipmb_addr *) &recv_msg->addr;
@@ -2179,14 +2212,14 @@ static int handle_lan_get_msg_rsp(ipmi_smi_t          intf,
 static int handle_lan_get_msg_cmd(ipmi_smi_t          intf,
                                  struct ipmi_smi_msg *msg)
 {
-       struct cmd_rcvr       *rcvr;
-       int                   rv = 0;
-       unsigned char         netfn;
-       unsigned char         cmd;
-       ipmi_user_t           user = NULL;
-       struct ipmi_lan_addr  *lan_addr;
-       struct ipmi_recv_msg  *recv_msg;
-       unsigned long         flags;
+       struct cmd_rcvr          *rcvr;
+       int                      rv = 0;
+       unsigned char            netfn;
+       unsigned char            cmd;
+       ipmi_user_t              user = NULL;
+       struct ipmi_lan_addr     *lan_addr;
+       struct ipmi_recv_msg     *recv_msg;
+       unsigned long            flags;
 
        if (msg->rsp_size < 12) {
                /* Message not big enough, just ignore it. */
@@ -2204,19 +2237,17 @@ static int handle_lan_get_msg_cmd(ipmi_smi_t          intf,
        netfn = msg->rsp[6] >> 2;
        cmd = msg->rsp[10];
 
-       read_lock(&(intf->cmd_rcvr_lock));
-
-       /* Find the command/netfn. */
-       list_for_each_entry(rcvr, &(intf->cmd_rcvrs), link) {
-               if ((rcvr->netfn == netfn) && (rcvr->cmd == cmd)) {
-                       user = rcvr->user;
-                       break;
-               }
-       }
-       read_unlock(&(intf->cmd_rcvr_lock));
+       rcu_read_lock();
+       rcvr = find_cmd_rcvr(intf, netfn, cmd);
+       if (rcvr) {
+               user = rcvr->user;
+               kref_get(&user->refcount);
+       } else
+               user = NULL;
+       rcu_read_unlock();
 
        if (user == NULL) {
-               /* We didn't find a user, deliver an error response. */
+               /* We didn't find a user, just give up. */
                spin_lock_irqsave(&intf->counter_lock, flags);
                intf->unhandled_commands++;
                spin_unlock_irqrestore(&intf->counter_lock, flags);
@@ -2235,6 +2266,7 @@ static int handle_lan_get_msg_cmd(ipmi_smi_t          intf,
                            message, so requeue it for handling
                            later. */
                        rv = 1;
+                       kref_put(&user->refcount, free_user);
                } else {
                        /* Extract the source address from the data. */
                        lan_addr = (struct ipmi_lan_addr *) &recv_msg->addr;
@@ -2286,8 +2318,6 @@ static void copy_event_into_recv_msg(struct ipmi_recv_msg *recv_msg,
        recv_msg->msg.data_len = msg->rsp_size - 3;
 }
 
-/* This will be called with the intf->users_lock read-locked, so no need
-   to do that here. */
 static int handle_read_event_rsp(ipmi_smi_t          intf,
                                 struct ipmi_smi_msg *msg)
 {
@@ -2313,7 +2343,7 @@ static int handle_read_event_rsp(ipmi_smi_t          intf,
 
        INIT_LIST_HEAD(&msgs);
 
-       spin_lock_irqsave(&(intf->events_lock), flags);
+       spin_lock_irqsave(&intf->events_lock, flags);
 
        spin_lock(&intf->counter_lock);
        intf->events++;
@@ -2321,12 +2351,14 @@ static int handle_read_event_rsp(ipmi_smi_t          intf,
 
        /* Allocate and fill in one message for every user that is getting
           events. */
-       list_for_each_entry(user, &(intf->users), link) {
+       rcu_read_lock();
+       list_for_each_entry_rcu(user, &intf->users, link) {
                if (! user->gets_events)
                        continue;
 
                recv_msg = ipmi_alloc_recv_msg();
                if (! recv_msg) {
+                       rcu_read_unlock();
                        list_for_each_entry_safe(recv_msg, recv_msg2, &msgs, link) {
                                list_del(&recv_msg->link);
                                ipmi_free_recv_msg(recv_msg);
@@ -2342,8 +2374,10 @@ static int handle_read_event_rsp(ipmi_smi_t          intf,
 
                copy_event_into_recv_msg(recv_msg, msg);
                recv_msg->user = user;
+               kref_get(&user->refcount);
                list_add_tail(&(recv_msg->link), &msgs);
        }
+       rcu_read_unlock();
 
        if (deliver_count) {
                /* Now deliver all the messages. */
@@ -2382,9 +2416,8 @@ static int handle_bmc_rsp(ipmi_smi_t          intf,
                          struct ipmi_smi_msg *msg)
 {
        struct ipmi_recv_msg *recv_msg;
-       int                  found = 0;
-       struct ipmi_user     *user;
        unsigned long        flags;
+       struct ipmi_user     *user;
 
        recv_msg = (struct ipmi_recv_msg *) msg->user_data;
        if (recv_msg == NULL)
@@ -2396,16 +2429,9 @@ static int handle_bmc_rsp(ipmi_smi_t          intf,
                return 0;
        }
 
+       user = recv_msg->user;
        /* Make sure the user still exists. */
-       list_for_each_entry(user, &(intf->users), link) {
-               if (user == recv_msg->user) {
-                       /* Found it, so we can deliver it */
-                       found = 1;
-                       break;
-               }
-       }
-
-       if ((! found) && recv_msg->user) {
+       if (user && !user->valid) {
                /* The user for the message went away, so give up. */
                spin_lock_irqsave(&intf->counter_lock, flags);
                intf->unhandled_local_responses++;
@@ -2486,7 +2512,7 @@ static int handle_new_recv_msg(ipmi_smi_t          intf,
        {
                /* It's a response to a response we sent.  For this we
                   deliver a send message response to the user. */
-               struct ipmi_recv_msg *recv_msg = msg->user_data;
+               struct ipmi_recv_msg     *recv_msg = msg->user_data;
 
                requeue = 0;
                if (msg->rsp_size < 2)
@@ -2498,13 +2524,18 @@ static int handle_new_recv_msg(ipmi_smi_t          intf,
                        /* Invalid channel number */
                        goto out;
 
-               if (recv_msg) {
-                       recv_msg->recv_type = IPMI_RESPONSE_RESPONSE_TYPE;
-                       recv_msg->msg.data = recv_msg->msg_data;
-                       recv_msg->msg.data_len = 1;
-                       recv_msg->msg_data[0] = msg->rsp[2];
-                       deliver_response(recv_msg);
-               }
+               if (!recv_msg)
+                       goto out;
+
+               /* Make sure the user still exists. */
+               if (!recv_msg->user || !recv_msg->user->valid)
+                       goto out;
+
+               recv_msg->recv_type = IPMI_RESPONSE_RESPONSE_TYPE;
+               recv_msg->msg.data = recv_msg->msg_data;
+               recv_msg->msg.data_len = 1;
+               recv_msg->msg_data[0] = msg->rsp[2];
+               deliver_response(recv_msg);
        } else if ((msg->rsp[0] == ((IPMI_NETFN_APP_REQUEST|1) << 2))
                   && (msg->rsp[1] == IPMI_GET_MSG_CMD))
        {
@@ -2570,14 +2601,11 @@ void ipmi_smi_msg_received(ipmi_smi_t          intf,
        int           rv;
 
 
-       /* Lock the user lock so the user can't go away while we are
-          working on it. */
-       read_lock(&(intf->users_lock));
-
        if ((msg->data_size >= 2)
            && (msg->data[0] == (IPMI_NETFN_APP_REQUEST << 2))
            && (msg->data[1] == IPMI_SEND_MSG_CMD)
-           && (msg->user_data == NULL)) {
+           && (msg->user_data == NULL))
+       {
                /* This is the local response to a command send, start
                    the timer for these.  The user_data will not be
                    NULL if this is a response send, and we will let
@@ -2612,46 +2640,46 @@ void ipmi_smi_msg_received(ipmi_smi_t          intf,
                }
 
                ipmi_free_smi_msg(msg);
-               goto out_unlock;
+               goto out;
        }
 
        /* To preserve message order, if the list is not empty, we
            tack this message onto the end of the list. */
-       spin_lock_irqsave(&(intf->waiting_msgs_lock), flags);
-       if (!list_empty(&(intf->waiting_msgs))) {
-               list_add_tail(&(msg->link), &(intf->waiting_msgs));
-               spin_unlock_irqrestore(&(intf->waiting_msgs_lock), flags);
-               goto out_unlock;
+       spin_lock_irqsave(&intf->waiting_msgs_lock, flags);
+       if (!list_empty(&intf->waiting_msgs)) {
+               list_add_tail(&msg->link, &intf->waiting_msgs);
+               spin_unlock(&intf->waiting_msgs_lock);
+               goto out;
        }
-       spin_unlock_irqrestore(&(intf->waiting_msgs_lock), flags);
+       spin_unlock_irqrestore(&intf->waiting_msgs_lock, flags);
                
        rv = handle_new_recv_msg(intf, msg);
        if (rv > 0) {
                /* Could not handle the message now, just add it to a
                    list to handle later. */
-               spin_lock_irqsave(&(intf->waiting_msgs_lock), flags);
-               list_add_tail(&(msg->link), &(intf->waiting_msgs));
-               spin_unlock_irqrestore(&(intf->waiting_msgs_lock), flags);
+               spin_lock(&intf->waiting_msgs_lock);
+               list_add_tail(&msg->link, &intf->waiting_msgs);
+               spin_unlock(&intf->waiting_msgs_lock);
        } else if (rv == 0) {
                ipmi_free_smi_msg(msg);
        }
 
- out_unlock:
-       read_unlock(&(intf->users_lock));
+ out:
+       return;
 }
 
 void ipmi_smi_watchdog_pretimeout(ipmi_smi_t intf)
 {
        ipmi_user_t user;
 
-       read_lock(&(intf->users_lock));
-       list_for_each_entry(user, &(intf->users), link) {
+       rcu_read_lock();
+       list_for_each_entry_rcu(user, &intf->users, link) {
                if (! user->handler->ipmi_watchdog_pretimeout)
                        continue;
 
                user->handler->ipmi_watchdog_pretimeout(user->handler_data);
        }
-       read_unlock(&(intf->users_lock));
+       rcu_read_unlock();
 }
 
 static void
@@ -2691,8 +2719,65 @@ smi_from_recv_msg(ipmi_smi_t intf, struct ipmi_recv_msg *recv_msg,
        return smi_msg;
 }
 
-static void
-ipmi_timeout_handler(long timeout_period)
+static void check_msg_timeout(ipmi_smi_t intf, struct seq_table *ent,
+                             struct list_head *timeouts, long timeout_period,
+                             int slot, unsigned long *flags)
+{
+       struct ipmi_recv_msg *msg;
+
+       if (!ent->inuse)
+               return;
+
+       ent->timeout -= timeout_period;
+       if (ent->timeout > 0)
+               return;
+
+       if (ent->retries_left == 0) {
+               /* The message has used all its retries. */
+               ent->inuse = 0;
+               msg = ent->recv_msg;
+               list_add_tail(&msg->link, timeouts);
+               spin_lock(&intf->counter_lock);
+               if (ent->broadcast)
+                       intf->timed_out_ipmb_broadcasts++;
+               else if (ent->recv_msg->addr.addr_type == IPMI_LAN_ADDR_TYPE)
+                       intf->timed_out_lan_commands++;
+               else
+                       intf->timed_out_ipmb_commands++;
+               spin_unlock(&intf->counter_lock);
+       } else {
+               struct ipmi_smi_msg *smi_msg;
+               /* More retries, send again. */
+
+               /* Start with the max timer, set to normal
+                  timer after the message is sent. */
+               ent->timeout = MAX_MSG_TIMEOUT;
+               ent->retries_left--;
+               spin_lock(&intf->counter_lock);
+               if (ent->recv_msg->addr.addr_type == IPMI_LAN_ADDR_TYPE)
+                       intf->retransmitted_lan_commands++;
+               else
+                       intf->retransmitted_ipmb_commands++;
+               spin_unlock(&intf->counter_lock);
+
+               smi_msg = smi_from_recv_msg(intf, ent->recv_msg, slot,
+                                           ent->seqid);
+               if (! smi_msg)
+                       return;
+
+               spin_unlock_irqrestore(&intf->seq_lock, *flags);
+               /* Send the new message.  We send with a zero
+                * priority.  It timed out, I doubt time is
+                * that critical now, and high priority
+                * messages are really only for messages to the
+                * local MC, which don't get resent. */
+               intf->handlers->sender(intf->send_info,
+                                      smi_msg, 0);
+               spin_lock_irqsave(&intf->seq_lock, *flags);
+       }
+}
+
+static void ipmi_timeout_handler(long timeout_period)
 {
        ipmi_smi_t           intf;
        struct list_head     timeouts;
@@ -2706,14 +2791,14 @@ ipmi_timeout_handler(long timeout_period)
        spin_lock(&interfaces_lock);
        for (i = 0; i < MAX_IPMI_INTERFACES; i++) {
                intf = ipmi_interfaces[i];
-               if (intf == NULL)
+               if (IPMI_INVALID_INTERFACE(intf))
                        continue;
-
-               read_lock(&(intf->users_lock));
+               kref_get(&intf->refcount);
+               spin_unlock(&interfaces_lock);
 
                /* See if any waiting messages need to be processed. */
-               spin_lock_irqsave(&(intf->waiting_msgs_lock), flags);
-               list_for_each_entry_safe(smi_msg, smi_msg2, &(intf->waiting_msgs), link) {
+               spin_lock_irqsave(&intf->waiting_msgs_lock, flags);
+               list_for_each_entry_safe(smi_msg, smi_msg2, &intf->waiting_msgs, link) {
                        if (! handle_new_recv_msg(intf, smi_msg)) {
                                list_del(&smi_msg->link);
                                ipmi_free_smi_msg(smi_msg);
@@ -2723,73 +2808,23 @@ ipmi_timeout_handler(long timeout_period)
                                break;
                        }
                }
-               spin_unlock_irqrestore(&(intf->waiting_msgs_lock), flags);
+               spin_unlock_irqrestore(&intf->waiting_msgs_lock, flags);
 
                /* Go through the seq table and find any messages that
                   have timed out, putting them in the timeouts
                   list. */
-               spin_lock_irqsave(&(intf->seq_lock), flags);
-               for (j = 0; j < IPMI_IPMB_NUM_SEQ; j++) {
-                       struct seq_table *ent = &(intf->seq_table[j]);
-                       if (!ent->inuse)
-                               continue;
-
-                       ent->timeout -= timeout_period;
-                       if (ent->timeout > 0)
-                               continue;
-
-                       if (ent->retries_left == 0) {
-                               /* The message has used all its retries. */
-                               ent->inuse = 0;
-                               msg = ent->recv_msg;
-                               list_add_tail(&(msg->link), &timeouts);
-                               spin_lock(&intf->counter_lock);
-                               if (ent->broadcast)
-                                       intf->timed_out_ipmb_broadcasts++;
-                               else if (ent->recv_msg->addr.addr_type
-                                        == IPMI_LAN_ADDR_TYPE)
-                                       intf->timed_out_lan_commands++;
-                               else
-                                       intf->timed_out_ipmb_commands++;
-                               spin_unlock(&intf->counter_lock);
-                       } else {
-                               struct ipmi_smi_msg *smi_msg;
-                               /* More retries, send again. */
-
-                               /* Start with the max timer, set to normal
-                                  timer after the message is sent. */
-                               ent->timeout = MAX_MSG_TIMEOUT;
-                               ent->retries_left--;
-                               spin_lock(&intf->counter_lock);
-                               if (ent->recv_msg->addr.addr_type
-                                   == IPMI_LAN_ADDR_TYPE)
-                                       intf->retransmitted_lan_commands++;
-                               else
-                                       intf->retransmitted_ipmb_commands++;
-                               spin_unlock(&intf->counter_lock);
-                               smi_msg = smi_from_recv_msg(intf,
-                                               ent->recv_msg, j, ent->seqid);
-                               if (! smi_msg)
-                                       continue;
-
-                               spin_unlock_irqrestore(&(intf->seq_lock),flags);
-                               /* Send the new message.  We send with a zero
-                                * priority.  It timed out, I doubt time is
-                                * that critical now, and high priority
-                                * messages are really only for messages to the
-                                * local MC, which don't get resent. */
-                               intf->handlers->sender(intf->send_info,
-                                                       smi_msg, 0);
-                               spin_lock_irqsave(&(intf->seq_lock), flags);
-                       }
-               }
-               spin_unlock_irqrestore(&(intf->seq_lock), flags);
-
-               list_for_each_entry_safe(msg, msg2, &timeouts, link) {
+               spin_lock_irqsave(&intf->seq_lock, flags);
+               for (j = 0; j < IPMI_IPMB_NUM_SEQ; j++)
+                       check_msg_timeout(intf, &(intf->seq_table[j]),
+                                         &timeouts, timeout_period, j,
+                                         &flags);
+               spin_unlock_irqrestore(&intf->seq_lock, flags);
+
+               list_for_each_entry_safe(msg, msg2, &timeouts, link)
                        handle_msg_timeout(msg);
-               }
 
-               read_unlock(&(intf->users_lock));
+               kref_put(&intf->refcount, intf_free);
+               spin_lock(&interfaces_lock);
        }
        spin_unlock(&interfaces_lock);
 }
@@ -2802,7 +2837,7 @@ static void ipmi_request_event(void)
        spin_lock(&interfaces_lock);
        for (i = 0; i < MAX_IPMI_INTERFACES; i++) {
                intf = ipmi_interfaces[i];
-               if (intf == NULL)
+               if (IPMI_INVALID_INTERFACE(intf))
                        continue;
 
                intf->handlers->request_events(intf->send_info);
@@ -2884,6 +2919,13 @@ struct ipmi_recv_msg *ipmi_alloc_recv_msg(void)
        return rv;
 }
 
+void ipmi_free_recv_msg(struct ipmi_recv_msg *msg)
+{
+       if (msg->user)
+               kref_put(&msg->user->refcount, free_user);
+       msg->done(msg);
+}
+
 #ifdef CONFIG_IPMI_PANIC_EVENT
 
 static void dummy_smi_done_handler(struct ipmi_smi_msg *msg)
@@ -2964,7 +3006,7 @@ static void send_panic_events(char *str)
        /* For every registered interface, send the event. */
        for (i = 0; i < MAX_IPMI_INTERFACES; i++) {
                intf = ipmi_interfaces[i];
-               if (intf == NULL)
+               if (IPMI_INVALID_INTERFACE(intf))
                        continue;
 
                /* Send the event announcing the panic. */
@@ -2995,7 +3037,7 @@ static void send_panic_events(char *str)
                int                   j;
 
                intf = ipmi_interfaces[i];
-               if (intf == NULL)
+               if (IPMI_INVALID_INTERFACE(intf))
                        continue;
 
                /* First job here is to figure out where to send the
@@ -3131,7 +3173,7 @@ static int panic_event(struct notifier_block *this,
        /* For every registered interface, set it to run to completion. */
        for (i = 0; i < MAX_IPMI_INTERFACES; i++) {
                intf = ipmi_interfaces[i];
-               if (intf == NULL)
+               if (IPMI_INVALID_INTERFACE(intf))
                        continue;
 
                intf->handlers->set_run_to_completion(intf->send_info, 1);
@@ -3160,9 +3202,8 @@ static int ipmi_init_msghandler(void)
        printk(KERN_INFO "ipmi message handler version "
               IPMI_DRIVER_VERSION "\n");
 
-       for (i = 0; i < MAX_IPMI_INTERFACES; i++) {
+       for (i = 0; i < MAX_IPMI_INTERFACES; i++)
                ipmi_interfaces[i] = NULL;
-       }
 
 #ifdef CONFIG_PROC_FS
        proc_ipmi_root = proc_mkdir("ipmi", NULL);
@@ -3258,3 +3299,4 @@ EXPORT_SYMBOL(ipmi_get_my_LUN);
 EXPORT_SYMBOL(ipmi_smi_add_proc_entry);
 EXPORT_SYMBOL(proc_ipmi_root);
 EXPORT_SYMBOL(ipmi_user_set_run_to_completion);
+EXPORT_SYMBOL(ipmi_free_recv_msg);
index f66947722e1282196a4d60e8c777d8ea250b3750..e053eade0366b070a90772305f91a3f884f5fd38 100644 (file)
@@ -56,7 +56,7 @@ static int poweroff_powercycle;
 
 /* parameter definition to allow user to flag power cycle */
 module_param(poweroff_powercycle, int, 0644);
-MODULE_PARM_DESC(poweroff_powercycles, " Set to non-zero to enable power cycle instead of power down. Power cycle is contingent on hardware support, otherwise it defaults back to power down.");
+MODULE_PARM_DESC(poweroff_powercycle, " Set to non-zero to enable power cycle instead of power down. Power cycle is contingent on hardware support, otherwise it defaults back to power down.");
 
 /* Stuff from the get device id command. */
 static unsigned int mfg_id;
@@ -611,9 +611,7 @@ static int ipmi_poweroff_init (void)
        }
 #endif
 
-#ifdef CONFIG_PROC_FS
        rv = ipmi_smi_watcher_register(&smi_watcher);
-#endif
        if (rv) {
                unregister_sysctl_table(ipmi_table_header);
                printk(KERN_ERR PFX "Unable to register SMI watcher: %d\n", rv);
index b6e5cbfb09f81d897c1dd95079c4e9281dda4ba5..ea89dca3dbb58f16b057ea9878173059b6611e6b 100644 (file)
@@ -51,6 +51,8 @@
 #include <linux/list.h>
 #include <linux/pci.h>
 #include <linux/ioport.h>
+#include <linux/notifier.h>
+#include <linux/kthread.h>
 #include <asm/irq.h>
 #ifdef CONFIG_HIGH_RES_TIMERS
 #include <linux/hrtime.h>
@@ -125,6 +127,7 @@ struct ipmi_device_id {
 
 struct smi_info
 {
+       int                    intf_num;
        ipmi_smi_t             intf;
        struct si_sm_data      *si_sm;
        struct si_sm_handlers  *handlers;
@@ -192,8 +195,7 @@ struct smi_info
        unsigned long       last_timeout_jiffies;
 
        /* Used to gracefully stop the timer without race conditions. */
-       volatile int        stop_operation;
-       volatile int        timer_stopped;
+       atomic_t            stop_operation;
 
        /* The driver will disable interrupts when it gets into a
           situation where it cannot handle messages due to lack of
@@ -220,8 +222,16 @@ struct smi_info
        unsigned long events;
        unsigned long watchdog_pretimeouts;
        unsigned long incoming_messages;
+
+        struct task_struct *thread;
 };
 
+static struct notifier_block *xaction_notifier_list;
+static int register_xaction_notifier(struct notifier_block * nb)
+{
+       return notifier_chain_register(&xaction_notifier_list, nb);
+}
+
 static void si_restart_short_timer(struct smi_info *smi_info);
 
 static void deliver_recv_msg(struct smi_info *smi_info,
@@ -281,6 +291,11 @@ static enum si_sm_result start_next_msg(struct smi_info *smi_info)
                do_gettimeofday(&t);
                printk("**Start2: %d.%9.9d\n", t.tv_sec, t.tv_usec);
 #endif
+               err = notifier_call_chain(&xaction_notifier_list, 0, smi_info);
+               if (err & NOTIFY_STOP_MASK) {
+                       rv = SI_SM_CALL_WITHOUT_DELAY;
+                       goto out;
+               }
                err = smi_info->handlers->start_transaction(
                        smi_info->si_sm,
                        smi_info->curr_msg->data,
@@ -291,6 +306,7 @@ static enum si_sm_result start_next_msg(struct smi_info *smi_info)
 
                rv = SI_SM_CALL_WITHOUT_DELAY;
        }
+       out:
        spin_unlock(&(smi_info->msg_lock));
 
        return rv;
@@ -766,6 +782,29 @@ static void set_run_to_completion(void *send_info, int i_run_to_completion)
        spin_unlock_irqrestore(&(smi_info->si_lock), flags);
 }
 
+static int ipmi_thread(void *data)
+{
+       struct smi_info *smi_info = data;
+       unsigned long flags;
+       enum si_sm_result smi_result;
+
+       set_user_nice(current, 19);
+       while (!kthread_should_stop()) {
+               spin_lock_irqsave(&(smi_info->si_lock), flags);
+               smi_result=smi_event_handler(smi_info, 0);
+               spin_unlock_irqrestore(&(smi_info->si_lock), flags);
+               if (smi_result == SI_SM_CALL_WITHOUT_DELAY) {
+                       /* do nothing */
+               }
+               else if (smi_result == SI_SM_CALL_WITH_DELAY)
+                       udelay(1);
+               else
+                       schedule_timeout_interruptible(1);
+       }
+       return 0;
+}
+
+
 static void poll(void *send_info)
 {
        struct smi_info *smi_info = send_info;
@@ -819,15 +858,13 @@ static void smi_timeout(unsigned long data)
        enum si_sm_result smi_result;
        unsigned long     flags;
        unsigned long     jiffies_now;
-       unsigned long     time_diff;
+       long              time_diff;
 #ifdef DEBUG_TIMING
        struct timeval    t;
 #endif
 
-       if (smi_info->stop_operation) {
-               smi_info->timer_stopped = 1;
+       if (atomic_read(&smi_info->stop_operation))
                return;
-       }
 
        spin_lock_irqsave(&(smi_info->si_lock), flags);
 #ifdef DEBUG_TIMING
@@ -835,7 +872,7 @@ static void smi_timeout(unsigned long data)
        printk("**Timer: %d.%9.9d\n", t.tv_sec, t.tv_usec);
 #endif
        jiffies_now = jiffies;
-       time_diff = ((jiffies_now - smi_info->last_timeout_jiffies)
+       time_diff = (((long)jiffies_now - (long)smi_info->last_timeout_jiffies)
                     * SI_USEC_PER_JIFFY);
        smi_result = smi_event_handler(smi_info, time_diff);
 
@@ -900,7 +937,7 @@ static irqreturn_t si_irq_handler(int irq, void *data, struct pt_regs *regs)
        smi_info->interrupts++;
        spin_unlock(&smi_info->count_lock);
 
-       if (smi_info->stop_operation)
+       if (atomic_read(&smi_info->stop_operation))
                goto out;
 
 #ifdef DEBUG_TIMING
@@ -1419,7 +1456,7 @@ static u32 ipmi_acpi_gpe(void *context)
        smi_info->interrupts++;
        spin_unlock(&smi_info->count_lock);
 
-       if (smi_info->stop_operation)
+       if (atomic_read(&smi_info->stop_operation))
                goto out;
 
 #ifdef DEBUG_TIMING
@@ -1919,7 +1956,8 @@ static int try_get_dev_id(struct smi_info *smi_info)
        smi_result = smi_info->handlers->event(smi_info->si_sm, 0);
        for (;;)
        {
-               if (smi_result == SI_SM_CALL_WITH_DELAY) {
+               if (smi_result == SI_SM_CALL_WITH_DELAY ||
+                   smi_result == SI_SM_CALL_WITH_TICK_DELAY) {
                        schedule_timeout_uninterruptible(1);
                        smi_result = smi_info->handlers->event(
                                smi_info->si_sm, 100);
@@ -2052,6 +2090,9 @@ static int oem_data_avail_to_receive_msg_avail(struct smi_info *smi_info)
  * IPMI Version = 0x51             IPMI 1.5
  * Manufacturer ID = A2 02 00      Dell IANA
  *
+ * Additionally, PowerEdge systems with IPMI < 1.5 may also assert
+ * OEM0_DATA_AVAIL and needs to be treated as RECEIVE_MSG_AVAIL.
+ *
  */
 #define DELL_POWEREDGE_8G_BMC_DEVICE_ID  0x20
 #define DELL_POWEREDGE_8G_BMC_DEVICE_REV 0x80
@@ -2061,16 +2102,87 @@ static void setup_dell_poweredge_oem_data_handler(struct smi_info *smi_info)
 {
        struct ipmi_device_id *id = &smi_info->device_id;
        const char mfr[3]=DELL_IANA_MFR_ID;
-       if (! memcmp(mfr, id->manufacturer_id, sizeof(mfr))
-           && (id->device_id       == DELL_POWEREDGE_8G_BMC_DEVICE_ID)
-           && (id->device_revision == DELL_POWEREDGE_8G_BMC_DEVICE_REV)
-           && (id->ipmi_version    == DELL_POWEREDGE_8G_BMC_IPMI_VERSION))
-       {
-               smi_info->oem_data_avail_handler =
-                       oem_data_avail_to_receive_msg_avail;
+       if (! memcmp(mfr, id->manufacturer_id, sizeof(mfr))) {
+               if (id->device_id       == DELL_POWEREDGE_8G_BMC_DEVICE_ID  &&
+                   id->device_revision == DELL_POWEREDGE_8G_BMC_DEVICE_REV &&
+                   id->ipmi_version    == DELL_POWEREDGE_8G_BMC_IPMI_VERSION) {
+                       smi_info->oem_data_avail_handler =
+                               oem_data_avail_to_receive_msg_avail;
+               }
+               else if (ipmi_version_major(id) < 1 ||
+                        (ipmi_version_major(id) == 1 &&
+                         ipmi_version_minor(id) < 5)) {
+                       smi_info->oem_data_avail_handler =
+                               oem_data_avail_to_receive_msg_avail;
+               }
        }
 }
 
+#define CANNOT_RETURN_REQUESTED_LENGTH 0xCA
+static void return_hosed_msg_badsize(struct smi_info *smi_info)
+{
+       struct ipmi_smi_msg *msg = smi_info->curr_msg;
+
+       /* Make it a reponse */
+       msg->rsp[0] = msg->data[0] | 4;
+       msg->rsp[1] = msg->data[1];
+       msg->rsp[2] = CANNOT_RETURN_REQUESTED_LENGTH;
+       msg->rsp_size = 3;
+       smi_info->curr_msg = NULL;
+       deliver_recv_msg(smi_info, msg);
+}
+
+/*
+ * dell_poweredge_bt_xaction_handler
+ * @info - smi_info.device_id must be populated
+ *
+ * Dell PowerEdge servers with the BT interface (x6xx and 1750) will
+ * not respond to a Get SDR command if the length of the data
+ * requested is exactly 0x3A, which leads to command timeouts and no
+ * data returned.  This intercepts such commands, and causes userspace
+ * callers to try again with a different-sized buffer, which succeeds.
+ */
+
+#define STORAGE_NETFN 0x0A
+#define STORAGE_CMD_GET_SDR 0x23
+static int dell_poweredge_bt_xaction_handler(struct notifier_block *self,
+                                            unsigned long unused,
+                                            void *in)
+{
+       struct smi_info *smi_info = in;
+       unsigned char *data = smi_info->curr_msg->data;
+       unsigned int size   = smi_info->curr_msg->data_size;
+       if (size >= 8 &&
+           (data[0]>>2) == STORAGE_NETFN &&
+           data[1] == STORAGE_CMD_GET_SDR &&
+           data[7] == 0x3A) {
+               return_hosed_msg_badsize(smi_info);
+               return NOTIFY_STOP;
+       }
+       return NOTIFY_DONE;
+}
+
+static struct notifier_block dell_poweredge_bt_xaction_notifier = {
+       .notifier_call  = dell_poweredge_bt_xaction_handler,
+};
+
+/*
+ * setup_dell_poweredge_bt_xaction_handler
+ * @info - smi_info.device_id must be filled in already
+ *
+ * Fills in smi_info.device_id.start_transaction_pre_hook
+ * when we know what function to use there.
+ */
+static void
+setup_dell_poweredge_bt_xaction_handler(struct smi_info *smi_info)
+{
+       struct ipmi_device_id *id = &smi_info->device_id;
+       const char mfr[3]=DELL_IANA_MFR_ID;
+       if (! memcmp(mfr, id->manufacturer_id, sizeof(mfr)) &&
+           smi_info->si_type == SI_BT)
+               register_xaction_notifier(&dell_poweredge_bt_xaction_notifier);
+}
+
 /*
  * setup_oem_data_handler
  * @info - smi_info.device_id must be filled in already
@@ -2084,6 +2196,18 @@ static void setup_oem_data_handler(struct smi_info *smi_info)
        setup_dell_poweredge_oem_data_handler(smi_info);
 }
 
+static void setup_xaction_handlers(struct smi_info *smi_info)
+{
+       setup_dell_poweredge_bt_xaction_handler(smi_info);
+}
+
+static inline void wait_for_timer_and_thread(struct smi_info *smi_info)
+{
+       if (smi_info->thread != ERR_PTR(-ENOMEM))
+               kthread_stop(smi_info->thread);
+       del_timer_sync(&smi_info->si_timer);
+}
+
 /* Returns 0 if initialized, or negative on an error. */
 static int init_one_smi(int intf_num, struct smi_info **smi)
 {
@@ -2179,6 +2303,7 @@ static int init_one_smi(int intf_num, struct smi_info **smi)
                goto out_err;
 
        setup_oem_data_handler(new_smi);
+       setup_xaction_handlers(new_smi);
 
        /* Try to claim any interrupts. */
        new_smi->irq_setup(new_smi);
@@ -2190,8 +2315,8 @@ static int init_one_smi(int intf_num, struct smi_info **smi)
        new_smi->run_to_completion = 0;
 
        new_smi->interrupt_disabled = 0;
-       new_smi->timer_stopped = 0;
-       new_smi->stop_operation = 0;
+       atomic_set(&new_smi->stop_operation, 0);
+       new_smi->intf_num = intf_num;
 
        /* Start clearing the flags before we enable interrupts or the
           timer to avoid racing with the timer. */
@@ -2209,7 +2334,11 @@ static int init_one_smi(int intf_num, struct smi_info **smi)
        new_smi->si_timer.function = smi_timeout;
        new_smi->last_timeout_jiffies = jiffies;
        new_smi->si_timer.expires = jiffies + SI_TIMEOUT_JIFFIES;
+
        add_timer(&(new_smi->si_timer));
+       if (new_smi->si_type != SI_BT)
+               new_smi->thread = kthread_run(ipmi_thread, new_smi,
+                                             "kipmi%d", new_smi->intf_num);
 
        rv = ipmi_register_smi(&handlers,
                               new_smi,
@@ -2251,12 +2380,8 @@ static int init_one_smi(int intf_num, struct smi_info **smi)
        return 0;
 
  out_err_stop_timer:
-       new_smi->stop_operation = 1;
-
-       /* Wait for the timer to stop.  This avoids problems with race
-          conditions removing the timer here. */
-       while (!new_smi->timer_stopped)
-               schedule_timeout_uninterruptible(1);
+       atomic_inc(&new_smi->stop_operation);
+       wait_for_timer_and_thread(new_smi);
 
  out_err:
        if (new_smi->intf)
@@ -2362,8 +2487,7 @@ static void __exit cleanup_one_si(struct smi_info *to_clean)
        spin_lock_irqsave(&(to_clean->si_lock), flags);
        spin_lock(&(to_clean->msg_lock));
 
-       to_clean->stop_operation = 1;
-
+       atomic_inc(&to_clean->stop_operation);
        to_clean->irq_cleanup(to_clean);
 
        spin_unlock(&(to_clean->msg_lock));
@@ -2374,10 +2498,7 @@ static void __exit cleanup_one_si(struct smi_info *to_clean)
           interrupt. */
        synchronize_sched();
 
-       /* Wait for the timer to stop.  This avoids problems with race
-          conditions removing the timer here. */
-       while (!to_clean->timer_stopped)
-               schedule_timeout_uninterruptible(1);
+       wait_for_timer_and_thread(to_clean);
 
        /* Interrupts and timeouts are stopped, now make sure the
           interface is in a clean state. */
index 62791dd429856d3755fe4898e83791b25dabaca3..bf3d4962d6a5973c51d99f21cb7b5de0ad2be867 100644 (file)
@@ -62,6 +62,7 @@ enum si_sm_result
 {
        SI_SM_CALL_WITHOUT_DELAY, /* Call the driver again immediately */
        SI_SM_CALL_WITH_DELAY,  /* Delay some before calling again. */
+       SI_SM_CALL_WITH_TICK_DELAY,     /* Delay at least 1 tick before calling again. */
        SI_SM_TRANSACTION_COMPLETE, /* A transaction is finished. */
        SI_SM_IDLE,             /* The SM is in idle state. */
        SI_SM_HOSED,            /* The hardware violated the state machine. */
index add2aa2732f0c56c4324088a1a18b08ec08c7b9a..39d7e5ef1a2ba82ff6d9b3526f397b0e2184a550 100644 (file)
@@ -43,6 +43,8 @@
 
 #include <linux/kernel.h> /* For printk. */
 #include <linux/string.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
 #include <linux/ipmi_msgdefs.h>                /* for completion codes */
 #include "ipmi_si_sm.h"
 
@@ -56,6 +58,8 @@
 #define        SMIC_DEBUG_ENABLE       1
 
 static int smic_debug = 1;
+module_param(smic_debug, int, 0644);
+MODULE_PARM_DESC(smic_debug, "debug bitmask, 1=enable, 2=messages, 4=states");
 
 enum smic_states {
        SMIC_IDLE,
@@ -76,11 +80,17 @@ enum smic_states {
 #define SMIC_MAX_ERROR_RETRIES 3
 
 /* Timeouts in microseconds. */
-#define SMIC_RETRY_TIMEOUT 100000
+#define SMIC_RETRY_TIMEOUT 2000000
 
 /* SMIC Flags Register Bits */
 #define SMIC_RX_DATA_READY     0x80
 #define SMIC_TX_DATA_READY     0x40
+/*
+ * SMIC_SMI and SMIC_EVM_DATA_AVAIL are only used by
+ * a few systems, and then only by Systems Management
+ * Interrupts, not by the OS.  Always ignore these bits.
+ *
+ */
 #define SMIC_SMI               0x10
 #define SMIC_EVM_DATA_AVAIL    0x08
 #define SMIC_SMS_DATA_AVAIL    0x04
@@ -364,8 +374,7 @@ static enum si_sm_result smic_event (struct si_sm_data *smic, long time)
        switch (smic->state) {
        case SMIC_IDLE:
                /* in IDLE we check for available messages */
-               if (flags & (SMIC_SMI |
-                            SMIC_EVM_DATA_AVAIL | SMIC_SMS_DATA_AVAIL))
+               if (flags & SMIC_SMS_DATA_AVAIL)
                {
                        return SI_SM_ATTN;
                }
index 2da64bf7469c6963e008e6215c610dae78dd3e3a..1f3159eb1ede18fd146a23c6d14e670acb75860c 100644 (file)
@@ -47,6 +47,9 @@
 #include <linux/reboot.h>
 #include <linux/wait.h>
 #include <linux/poll.h>
+#include <linux/string.h>
+#include <linux/ctype.h>
+#include <asm/atomic.h>
 #ifdef CONFIG_X86_LOCAL_APIC
 #include <asm/apic.h>
 #endif
@@ -158,27 +161,120 @@ static struct fasync_struct *fasync_q = NULL;
 static char pretimeout_since_last_heartbeat = 0;
 static char expect_close;
 
+static DECLARE_RWSEM(register_sem);
+
+/* Parameters to ipmi_set_timeout */
+#define IPMI_SET_TIMEOUT_NO_HB                 0
+#define IPMI_SET_TIMEOUT_HB_IF_NECESSARY       1
+#define IPMI_SET_TIMEOUT_FORCE_HB              2
+
+static int ipmi_set_timeout(int do_heartbeat);
+
 /* If true, the driver will start running as soon as it is configured
    and ready. */
 static int start_now = 0;
 
-module_param(timeout, int, 0);
+static int set_param_int(const char *val, struct kernel_param *kp)
+{
+       char *endp;
+       int  l;
+       int  rv = 0;
+
+       if (!val)
+               return -EINVAL;
+       l = simple_strtoul(val, &endp, 0);
+       if (endp == val)
+               return -EINVAL;
+
+       down_read(&register_sem);
+       *((int *)kp->arg) = l;
+       if (watchdog_user)
+               rv = ipmi_set_timeout(IPMI_SET_TIMEOUT_HB_IF_NECESSARY);
+       up_read(&register_sem);
+
+       return rv;
+}
+
+static int get_param_int(char *buffer, struct kernel_param *kp)
+{
+       return sprintf(buffer, "%i", *((int *)kp->arg));
+}
+
+typedef int (*action_fn)(const char *intval, char *outval);
+
+static int action_op(const char *inval, char *outval);
+static int preaction_op(const char *inval, char *outval);
+static int preop_op(const char *inval, char *outval);
+static void check_parms(void);
+
+static int set_param_str(const char *val, struct kernel_param *kp)
+{
+       action_fn  fn = (action_fn) kp->arg;
+       int        rv = 0;
+       const char *end;
+       char       valcp[16];
+       int        len;
+
+       /* Truncate leading and trailing spaces. */
+       while (isspace(*val))
+               val++;
+       end = val + strlen(val) - 1;
+       while ((end >= val) && isspace(*end))
+               end--;
+       len = end - val + 1;
+       if (len > sizeof(valcp) - 1)
+               return -EINVAL;
+       memcpy(valcp, val, len);
+       valcp[len] = '\0';
+
+       down_read(&register_sem);
+       rv = fn(valcp, NULL);
+       if (rv)
+               goto out_unlock;
+
+       check_parms();
+       if (watchdog_user)
+               rv = ipmi_set_timeout(IPMI_SET_TIMEOUT_HB_IF_NECESSARY);
+
+ out_unlock:
+       up_read(&register_sem);
+       return rv;
+}
+
+static int get_param_str(char *buffer, struct kernel_param *kp)
+{
+       action_fn fn = (action_fn) kp->arg;
+       int       rv;
+
+       rv = fn(NULL, buffer);
+       if (rv)
+               return rv;
+       return strlen(buffer);
+}
+
+module_param_call(timeout, set_param_int, get_param_int, &timeout, 0644);
 MODULE_PARM_DESC(timeout, "Timeout value in seconds.");
-module_param(pretimeout, int, 0);
+
+module_param_call(pretimeout, set_param_int, get_param_int, &pretimeout, 0644);
 MODULE_PARM_DESC(pretimeout, "Pretimeout value in seconds.");
-module_param_string(action, action, sizeof(action), 0);
+
+module_param_call(action, set_param_str, get_param_str, action_op, 0644);
 MODULE_PARM_DESC(action, "Timeout action. One of: "
                 "reset, none, power_cycle, power_off.");
-module_param_string(preaction, preaction, sizeof(preaction), 0);
+
+module_param_call(preaction, set_param_str, get_param_str, preaction_op, 0644);
 MODULE_PARM_DESC(preaction, "Pretimeout action.  One of: "
                 "pre_none, pre_smi, pre_nmi, pre_int.");
-module_param_string(preop, preop, sizeof(preop), 0);
+
+module_param_call(preop, set_param_str, get_param_str, preop_op, 0644);
 MODULE_PARM_DESC(preop, "Pretimeout driver operation.  One of: "
                 "preop_none, preop_panic, preop_give_data.");
+
 module_param(start_now, int, 0);
 MODULE_PARM_DESC(start_now, "Set to 1 to start the watchdog as"
                 "soon as the driver is loaded.");
-module_param(nowayout, int, 0);
+
+module_param(nowayout, int, 0644);
 MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
 
 /* Default state of the timer. */
@@ -200,6 +296,8 @@ static int ipmi_start_timer_on_heartbeat = 0;
 static unsigned char ipmi_version_major;
 static unsigned char ipmi_version_minor;
 
+/* If a pretimeout occurs, this is used to allow only one panic to happen. */
+static atomic_t preop_panic_excl = ATOMIC_INIT(-1);
 
 static int ipmi_heartbeat(void);
 static void panic_halt_ipmi_heartbeat(void);
@@ -294,11 +392,6 @@ static int i_ipmi_set_timeout(struct ipmi_smi_msg  *smi_msg,
        return rv;
 }
 
-/* Parameters to ipmi_set_timeout */
-#define IPMI_SET_TIMEOUT_NO_HB                 0
-#define IPMI_SET_TIMEOUT_HB_IF_NECESSARY       1
-#define IPMI_SET_TIMEOUT_FORCE_HB              2
-
 static int ipmi_set_timeout(int do_heartbeat)
 {
        int send_heartbeat_now;
@@ -732,8 +825,6 @@ static struct miscdevice ipmi_wdog_miscdev = {
        .fops           = &ipmi_wdog_fops
 };
 
-static DECLARE_RWSEM(register_sem);
-
 static void ipmi_wdog_msg_handler(struct ipmi_recv_msg *msg,
                                  void                 *handler_data)
 {
@@ -749,9 +840,10 @@ static void ipmi_wdog_msg_handler(struct ipmi_recv_msg *msg,
 static void ipmi_wdog_pretimeout_handler(void *handler_data)
 {
        if (preaction_val != WDOG_PRETIMEOUT_NONE) {
-               if (preop_val == WDOG_PREOP_PANIC)
-                       panic("Watchdog pre-timeout");
-               else if (preop_val == WDOG_PREOP_GIVE_DATA) {
+               if (preop_val == WDOG_PREOP_PANIC) {
+                       if (atomic_inc_and_test(&preop_panic_excl))
+                               panic("Watchdog pre-timeout");
+               } else if (preop_val == WDOG_PREOP_GIVE_DATA) {
                        spin_lock(&ipmi_read_lock);
                        data_to_read = 1;
                        wake_up_interruptible(&read_q);
@@ -825,7 +917,8 @@ ipmi_nmi(void *dev_id, struct pt_regs *regs, int cpu, int handled)
                   an error and not work unless we re-enable
                   the timer.   So do so. */
                pretimeout_since_last_heartbeat = 1;
-               panic(PFX "pre-timeout");
+               if (atomic_inc_and_test(&preop_panic_excl))
+                       panic(PFX "pre-timeout");
        }
 
        return NOTIFY_DONE;
@@ -839,6 +932,7 @@ static struct nmi_handler ipmi_nmi_handler =
        .handler  = ipmi_nmi,
        .priority = 0, /* Call us last. */
 };
+int nmi_handler_registered;
 #endif
 
 static int wdog_reboot_handler(struct notifier_block *this,
@@ -921,59 +1015,86 @@ static struct ipmi_smi_watcher smi_watcher =
        .smi_gone = ipmi_smi_gone
 };
 
-static int __init ipmi_wdog_init(void)
+static int action_op(const char *inval, char *outval)
 {
-       int rv;
+       if (outval)
+               strcpy(outval, action);
+
+       if (!inval)
+               return 0;
 
-       if (strcmp(action, "reset") == 0) {
+       if (strcmp(inval, "reset") == 0)
                action_val = WDOG_TIMEOUT_RESET;
-       } else if (strcmp(action, "none") == 0) {
+       else if (strcmp(inval, "none") == 0)
                action_val = WDOG_TIMEOUT_NONE;
-       } else if (strcmp(action, "power_cycle") == 0) {
+       else if (strcmp(inval, "power_cycle") == 0)
                action_val = WDOG_TIMEOUT_POWER_CYCLE;
-       } else if (strcmp(action, "power_off") == 0) {
+       else if (strcmp(inval, "power_off") == 0)
                action_val = WDOG_TIMEOUT_POWER_DOWN;
-       } else {
-               action_val = WDOG_TIMEOUT_RESET;
-               printk(KERN_INFO PFX "Unknown action '%s', defaulting to"
-                      " reset\n", action);
-       }
+       else
+               return -EINVAL;
+       strcpy(action, inval);
+       return 0;
+}
+
+static int preaction_op(const char *inval, char *outval)
+{
+       if (outval)
+               strcpy(outval, preaction);
 
-       if (strcmp(preaction, "pre_none") == 0) {
+       if (!inval)
+               return 0;
+
+       if (strcmp(inval, "pre_none") == 0)
                preaction_val = WDOG_PRETIMEOUT_NONE;
-       } else if (strcmp(preaction, "pre_smi") == 0) {
+       else if (strcmp(inval, "pre_smi") == 0)
                preaction_val = WDOG_PRETIMEOUT_SMI;
 #ifdef HAVE_NMI_HANDLER
-       } else if (strcmp(preaction, "pre_nmi") == 0) {
+       else if (strcmp(inval, "pre_nmi") == 0)
                preaction_val = WDOG_PRETIMEOUT_NMI;
 #endif
-       } else if (strcmp(preaction, "pre_int") == 0) {
+       else if (strcmp(inval, "pre_int") == 0)
                preaction_val = WDOG_PRETIMEOUT_MSG_INT;
-       } else {
-               preaction_val = WDOG_PRETIMEOUT_NONE;
-               printk(KERN_INFO PFX "Unknown preaction '%s', defaulting to"
-                      " none\n", preaction);
-       }
+       else
+               return -EINVAL;
+       strcpy(preaction, inval);
+       return 0;
+}
+
+static int preop_op(const char *inval, char *outval)
+{
+       if (outval)
+               strcpy(outval, preop);
 
-       if (strcmp(preop, "preop_none") == 0) {
+       if (!inval)
+               return 0;
+
+       if (strcmp(inval, "preop_none") == 0)
                preop_val = WDOG_PREOP_NONE;
-       } else if (strcmp(preop, "preop_panic") == 0) {
+       else if (strcmp(inval, "preop_panic") == 0)
                preop_val = WDOG_PREOP_PANIC;
-       } else if (strcmp(preop, "preop_give_data") == 0) {
+       else if (strcmp(inval, "preop_give_data") == 0)
                preop_val = WDOG_PREOP_GIVE_DATA;
-       } else {
-               preop_val = WDOG_PREOP_NONE;
-               printk(KERN_INFO PFX "Unknown preop '%s', defaulting to"
-                      " none\n", preop);
-       }
+       else
+               return -EINVAL;
+       strcpy(preop, inval);
+       return 0;
+}
 
+static void check_parms(void)
+{
 #ifdef HAVE_NMI_HANDLER
+       int do_nmi = 0;
+       int rv;
+
        if (preaction_val == WDOG_PRETIMEOUT_NMI) {
+               do_nmi = 1;
                if (preop_val == WDOG_PREOP_GIVE_DATA) {
                        printk(KERN_WARNING PFX "Pretimeout op is to give data"
                               " but NMI pretimeout is enabled, setting"
                               " pretimeout op to none\n");
-                       preop_val = WDOG_PREOP_NONE;
+                       preop_op("preop_none", NULL);
+                       do_nmi = 0;
                }
 #ifdef CONFIG_X86_LOCAL_APIC
                if (nmi_watchdog == NMI_IO_APIC) {
@@ -983,18 +1104,48 @@ static int __init ipmi_wdog_init(void)
                               " Disabling IPMI nmi pretimeout.\n",
                               nmi_watchdog);
                        preaction_val = WDOG_PRETIMEOUT_NONE;
-               } else {
+                       do_nmi = 0;
+               }
 #endif
+       }
+       if (do_nmi && !nmi_handler_registered) {
                rv = request_nmi(&ipmi_nmi_handler);
                if (rv) {
-                       printk(KERN_WARNING PFX "Can't register nmi handler\n");
-                       return rv;
-               }
-#ifdef CONFIG_X86_LOCAL_APIC
-               }
-#endif
+                       printk(KERN_WARNING PFX
+                              "Can't register nmi handler\n");
+                       return;
+               } else
+                       nmi_handler_registered = 1;
+       } else if (!do_nmi && nmi_handler_registered) {
+               release_nmi(&ipmi_nmi_handler);
+               nmi_handler_registered = 0;
        }
 #endif
+}
+
+static int __init ipmi_wdog_init(void)
+{
+       int rv;
+
+       if (action_op(action, NULL)) {
+               action_op("reset", NULL);
+               printk(KERN_INFO PFX "Unknown action '%s', defaulting to"
+                      " reset\n", action);
+       }
+
+       if (preaction_op(preaction, NULL)) {
+               preaction_op("pre_none", NULL);
+               printk(KERN_INFO PFX "Unknown preaction '%s', defaulting to"
+                      " none\n", preaction);
+       }
+
+       if (preop_op(preop, NULL)) {
+               preop_op("preop_none", NULL);
+               printk(KERN_INFO PFX "Unknown preop '%s', defaulting to"
+                      " none\n", preop);
+       }
+
+       check_parms();
 
        rv = ipmi_smi_watcher_register(&smi_watcher);
        if (rv) {
@@ -1021,7 +1172,7 @@ static __exit void ipmi_unregister_watchdog(void)
        down_write(&register_sem);
 
 #ifdef HAVE_NMI_HANDLER
-       if (preaction_val == WDOG_PRETIMEOUT_NMI)
+       if (nmi_handler_registered)
                release_nmi(&ipmi_nmi_handler);
 #endif
 
index e3ddbdb85a2f3d4d6addf22ddc360cfbafa57299..ce3bc0d45f1f0c8fb2794257e5971078688045ac 100644 (file)
@@ -860,10 +860,9 @@ static void __exit istallion_module_exit(void)
        if ((i = unregister_chrdev(STL_SIOMEMMAJOR, "staliomem")))
                printk("STALLION: failed to un-register serial memory device, "
                        "errno=%d\n", -i);
-       if (stli_tmpwritebuf != (char *) NULL)
-               kfree(stli_tmpwritebuf);
-       if (stli_txcookbuf != (char *) NULL)
-               kfree(stli_txcookbuf);
+
+       kfree(stli_tmpwritebuf);
+       kfree(stli_txcookbuf);
 
        for (i = 0; (i < stli_nrbrds); i++) {
                if ((brdp = stli_brds[i]) == (stlibrd_t *) NULL)
index 45d012d85e8c3d436d33c46e1b809f8dee9216d3..3b965a651da4352cf91b91ca6f9a11fd7663929c 100644 (file)
@@ -470,6 +470,8 @@ static struct tty_operations mxser_ops = {
        .stop = mxser_stop,
        .start = mxser_start,
        .hangup = mxser_hangup,
+       .break_ctl = mxser_rs_break,
+       .wait_until_sent = mxser_wait_until_sent,
        .tiocmget = mxser_tiocmget,
        .tiocmset = mxser_tiocmset,
 };
@@ -492,14 +494,18 @@ static int __init mxser_module_init(void)
 
 static void __exit mxser_module_exit(void)
 {
-       int i, err = 0;
+       int i, err;
 
        if (verbose)
                printk(KERN_DEBUG "Unloading module mxser ...\n");
 
-       if ((err |= tty_unregister_driver(mxvar_sdriver)))
+       err = tty_unregister_driver(mxvar_sdriver);
+       if (!err)
+               put_tty_driver(mxvar_sdriver);
+       else
                printk(KERN_ERR "Couldn't unregister MOXA Smartio/Industio family serial driver\n");
 
+
        for (i = 0; i < MXSER_BOARDS; i++) {
                struct pci_dev *pdev;
 
@@ -688,7 +694,6 @@ static int mxser_get_PCI_conf(int busnum, int devnum, int board_type, struct mxs
 static int mxser_init(void)
 {
        int i, m, retval, b, n;
-       int ret1;
        struct pci_dev *pdev = NULL;
        int index;
        unsigned char busnum, devnum;
@@ -722,24 +727,6 @@ static int mxser_init(void)
        mxvar_sdriver->termios = mxvar_termios;
        mxvar_sdriver->termios_locked = mxvar_termios_locked;
 
-       mxvar_sdriver->open = mxser_open;
-       mxvar_sdriver->close = mxser_close;
-       mxvar_sdriver->write = mxser_write;
-       mxvar_sdriver->put_char = mxser_put_char;
-       mxvar_sdriver->flush_chars = mxser_flush_chars;
-       mxvar_sdriver->write_room = mxser_write_room;
-       mxvar_sdriver->chars_in_buffer = mxser_chars_in_buffer;
-       mxvar_sdriver->flush_buffer = mxser_flush_buffer;
-       mxvar_sdriver->ioctl = mxser_ioctl;
-       mxvar_sdriver->throttle = mxser_throttle;
-       mxvar_sdriver->unthrottle = mxser_unthrottle;
-       mxvar_sdriver->set_termios = mxser_set_termios;
-       mxvar_sdriver->stop = mxser_stop;
-       mxvar_sdriver->start = mxser_start;
-       mxvar_sdriver->hangup = mxser_hangup;
-       mxvar_sdriver->break_ctl = mxser_rs_break;
-       mxvar_sdriver->wait_until_sent = mxser_wait_until_sent;
-
        mxvar_diagflag = 0;
        memset(mxvar_table, 0, MXSER_PORTS * sizeof(struct mxser_struct));
        memset(&mxvar_log, 0, sizeof(struct mxser_log));
@@ -870,14 +857,11 @@ static int mxser_init(void)
        }
 #endif
 
-       ret1 = 0;
-       if (!(ret1 = tty_register_driver(mxvar_sdriver))) {
-               return 0;
-       } else
+       retval = tty_register_driver(mxvar_sdriver);
+       if (retval) {
                printk(KERN_ERR "Couldn't install MOXA Smartio/Industio family driver !\n");
+               put_tty_driver(mxvar_sdriver);
 
-
-       if (ret1) {
                for (i = 0; i < MXSER_BOARDS; i++) {
                        if (mxsercfg[i].board_type == -1)
                                continue;
@@ -886,10 +870,10 @@ static int mxser_init(void)
                                //todo: release io, vector
                        }
                }
-               return -1;
+               return retval;
        }
 
-       return (0);
+       return 0;
 }
 
 static void mxser_do_softint(void *private_)
@@ -933,6 +917,9 @@ static int mxser_open(struct tty_struct *tty, struct file *filp)
        struct mxser_struct *info;
        int retval, line;
 
+       /* initialize driver_data in case something fails */
+       tty->driver_data = NULL;
+
        line = tty->index;
        if (line == MXSER_PORTS)
                return 0;
@@ -995,7 +982,7 @@ static void mxser_close(struct tty_struct *tty, struct file *filp)
        if (tty->index == MXSER_PORTS)
                return;
        if (!info)
-               BUG();
+               return;
 
        spin_lock_irqsave(&info->slock, flags);
 
index 5079beda69b5af142af8e9bfaa4ffd62c635c881..c3660d8781a4ef35e6fce62532d2629bfa4039ab 100644 (file)
@@ -264,8 +264,7 @@ static void n_hdlc_release(struct n_hdlc *n_hdlc)
                } else
                        break;
        }
-       if (n_hdlc->tbuf)
-               kfree(n_hdlc->tbuf);
+       kfree(n_hdlc->tbuf);
        kfree(n_hdlc);
        
 }      /* end of n_hdlc_release() */
index 02d7f046c10aeae25e831b2f15f9f85e63a22d99..2c326ea53421be1797e4405e20a69926a51c8e78 100644 (file)
@@ -2994,8 +2994,7 @@ int rx_alloc_buffers(MGSLPC_INFO *info)
 
 void rx_free_buffers(MGSLPC_INFO *info)
 {
-       if (info->rx_buf)
-               kfree(info->rx_buf);
+       kfree(info->rx_buf);
        info->rx_buf = NULL;
 }
 
index 928b850cc679839707c47e44d3e13ab4a06ac09e..d3bc731fbb2773cbe6c94c92505781cb63a0bb50 100644 (file)
@@ -2512,10 +2512,8 @@ static void rp_cleanup_module(void)
                       "rocketport driver\n", -retval);
        put_tty_driver(rocket_driver);
 
-       for (i = 0; i < MAX_RP_PORTS; i++) {
-               if (rp_table[i])
-                       kfree(rp_table[i]);
-       }
+       for (i = 0; i < MAX_RP_PORTS; i++)
+               kfree(rp_table[i]);
 
        for (i = 0; i < NUM_BOARDS; i++) {
                if (rcktpt_io_addr[i] <= 0 || is_PCI[i])
index 16d630f58bb491cbf5394960ef5a8e90f30f4b4f..5b187c895c1831fc1bf274aeaa6e7fe35f0c8244 100644 (file)
@@ -246,8 +246,7 @@ int set_selection(const struct tiocl_selection __user *sel, struct tty_struct *t
                clear_selection();
                return -ENOMEM;
        }
-       if (sel_buffer)
-               kfree(sel_buffer);
+       kfree(sel_buffer);
        sel_buffer = bp;
 
        obp = bp;
index 1c686414e0a1f6dfc2b5d40e9584666302bc951a..95af2a941595517ca0ea30daa4a380a739724475 100644 (file)
@@ -785,8 +785,7 @@ static void __exit stallion_module_exit(void)
                        "errno=%d\n", -i);
        class_destroy(stallion_class);
 
-       if (stl_tmpwritebuf != (char *) NULL)
-               kfree(stl_tmpwritebuf);
+       kfree(stl_tmpwritebuf);
 
        for (i = 0; (i < stl_nrbrds); i++) {
                if ((brdp = stl_brds[i]) == (stlbrd_t *) NULL)
@@ -804,8 +803,7 @@ static void __exit stallion_module_exit(void)
                                        continue;
                                if (portp->tty != (struct tty_struct *) NULL)
                                        stl_hangup(portp->tty);
-                               if (portp->tx.buf != (char *) NULL)
-                                       kfree(portp->tx.buf);
+                               kfree(portp->tx.buf);
                                kfree(portp);
                        }
                        kfree(panelp);
index 0133dc0e25d087cfd4cabedb261d28f0572fdd98..5d1ffa3bd4c3e0bd7d9a39e1cfc68ebbfb7c515c 100644 (file)
@@ -4016,9 +4016,7 @@ static int mgsl_alloc_intermediate_rxbuffer_memory(struct mgsl_struct *info)
  */
 static void mgsl_free_intermediate_rxbuffer_memory(struct mgsl_struct *info)
 {
-       if ( info->intermediate_rxbuffer )
-               kfree(info->intermediate_rxbuffer);
-
+       kfree(info->intermediate_rxbuffer);
        info->intermediate_rxbuffer = NULL;
 
 }      /* end of mgsl_free_intermediate_rxbuffer_memory() */
@@ -4072,10 +4070,8 @@ static void mgsl_free_intermediate_txbuffer_memory(struct mgsl_struct *info)
        int i;
 
        for ( i=0; i<info->num_tx_holding_buffers; ++i ) {
-               if ( info->tx_holding_buffers[i].buffer ) {
-                               kfree(info->tx_holding_buffers[i].buffer);
-                               info->tx_holding_buffers[i].buffer=NULL;
-               }
+               kfree(info->tx_holding_buffers[i].buffer);
+               info->tx_holding_buffers[i].buffer = NULL;
        }
 
        info->get_tx_holding_index = 0;
index f185724448b142e6da58b3761e10ac74f85f9a05..7c063c5abc5596532b5aa2aec0c4586d40253210 100644 (file)
@@ -2788,10 +2788,8 @@ static void shutdown(SLMP_INFO * info)
        del_timer(&info->tx_timer);
        del_timer(&info->status_timer);
 
-       if (info->tx_buf) {
-               kfree(info->tx_buf);
-               info->tx_buf = NULL;
-       }
+       kfree(info->tx_buf);
+       info->tx_buf = NULL;
 
        spin_lock_irqsave(&info->lock,flags);
 
@@ -3611,8 +3609,7 @@ int alloc_tmp_rx_buf(SLMP_INFO *info)
 
 void free_tmp_rx_buf(SLMP_INFO *info)
 {
-       if (info->tmp_rx_buf)
-               kfree(info->tmp_rx_buf);
+       kfree(info->tmp_rx_buf);
        info->tmp_rx_buf = NULL;
 }
 
index 8d125c974a2d4d7f92a0f5f4b9aa39b6d6f3bc45..680a8e3318877b6c6bd7f09ae61d46abd5605871 100644 (file)
@@ -287,10 +287,6 @@ static int __init init_nsc(void)
        int lo, hi;
        int nscAddrBase = TPM_ADDR;
 
-       driver_register(&nsc_drv);
-
-       /* select PM channel 1 */
-       tpm_write_index(nscAddrBase,NSC_LDN_INDEX, 0x12);
 
        /* verify that it is a National part (SID) */
        if (tpm_read_index(TPM_ADDR, NSC_SID_INDEX) != 0xEF) {
@@ -300,6 +296,8 @@ static int __init init_nsc(void)
                        return -ENODEV;
        }
 
+       driver_register(&nsc_drv);
+
        hi = tpm_read_index(nscAddrBase, TPM_NSC_BASE0_HI);
        lo = tpm_read_index(nscAddrBase, TPM_NSC_BASE0_LO);
        tpm_nsc.base = (hi<<8) | lo;
@@ -307,11 +305,11 @@ static int __init init_nsc(void)
        /* enable the DPM module */
        tpm_write_index(nscAddrBase, NSC_LDC_INDEX, 0x01);
 
-       pdev = kmalloc(sizeof(struct platform_device), GFP_KERNEL);
-       if ( !pdev )
-               return -ENOMEM;
-
-       memset(pdev, 0, sizeof(struct platform_device));
+       pdev = kzalloc(sizeof(struct platform_device), GFP_KERNEL);
+       if (!pdev) {
+               rc = -ENOMEM;
+               goto err_unreg_drv;
+       }
 
        pdev->name = "tpm_nscl0";
        pdev->id = -1;
@@ -319,26 +317,16 @@ static int __init init_nsc(void)
        pdev->dev.release = tpm_nsc_remove;
        pdev->dev.driver = &nsc_drv;
 
-       if ((rc=platform_device_register(pdev)) < 0) {
-               kfree(pdev);
-               pdev = NULL;
-               return rc;
-       }
+       if ((rc = platform_device_register(pdev)) < 0)
+               goto err_free_dev;
 
        if (request_region(tpm_nsc.base, 2, "tpm_nsc0") == NULL ) {
-               platform_device_unregister(pdev);
-               kfree(pdev);
-               pdev = NULL;
-               return -EBUSY;
+               rc = -EBUSY;
+               goto err_unreg_dev;
        }
 
-       if ((rc = tpm_register_hardware(&pdev->dev, &tpm_nsc)) < 0) {
-               release_region(tpm_nsc.base, 2);
-               platform_device_unregister(pdev);
-               kfree(pdev);
-               pdev = NULL;
-               return rc;
-       }
+       if ((rc = tpm_register_hardware(&pdev->dev, &tpm_nsc)) < 0)
+               goto err_rel_reg;
 
        dev_dbg(&pdev->dev, "NSC TPM detected\n");
        dev_dbg(&pdev->dev,
@@ -374,6 +362,16 @@ static int __init init_nsc(void)
                 tpm_read_index(nscAddrBase, 0x27) & 0x1F);
 
        return 0;
+
+err_rel_reg:
+       release_region(tpm_nsc.base, 2);
+err_unreg_dev:
+       platform_device_unregister(pdev);
+err_free_dev:
+       kfree(pdev);
+err_unreg_drv:
+       driver_unregister(&nsc_drv);
+       return rc;
 }
 
 static void __exit cleanup_nsc(void)
index c586bfa852eec510c2e486a331e4564655791fab..4b1eef51ec5926d97918331f20740c3664067375 100644 (file)
@@ -1416,14 +1416,11 @@ end_init:
 
        /* Release locally allocated memory ... nothing placed in slots */
 free_mem_out:
-       if (o_tp)
-               kfree(o_tp);
+       kfree(o_tp);
        if (o_tty)
                free_tty_struct(o_tty);
-       if (ltp)
-               kfree(ltp);
-       if (tp)
-               kfree(tp);
+       kfree(ltp);
+       kfree(tp);
        free_tty_struct(tty);
 
 fail_no_mem:
index 003dda147cd093a226d52a485d7b98d64186874d..24011e7c81ff72fa6bade2d7c889c8a0c2c48c5a 100644 (file)
@@ -80,6 +80,9 @@ do_kdsk_ioctl(int cmd, struct kbentry __user *user_kbe, int perm, struct kbd_str
        if (copy_from_user(&tmp, user_kbe, sizeof(struct kbentry)))
                return -EFAULT;
 
+       if (!capable(CAP_SYS_TTY_CONFIG))
+               perm = 0;
+
        switch (cmd) {
        case KDGKBENT:
                key_map = key_maps[s];
@@ -193,7 +196,7 @@ do_kdgkb_ioctl(int cmd, struct kbsentry __user *user_kdgkb, int perm)
        int ret;
 
        if (!capable(CAP_SYS_TTY_CONFIG))
-               return -EPERM;
+               perm = 0;
 
        kbs = kmalloc(sizeof(*kbs), GFP_KERNEL);
        if (!kbs) {
index 0bc2059c1e088b4e618ca18bf37f61948719ba6f..e0bdc0db9640e51647dda54472a5919eb3b0ec45 100644 (file)
@@ -10,4 +10,12 @@ config CONNECTOR
          Connector support can also be built as a module.  If so, the module
          will be called cn.ko.
 
+config PROC_EVENTS
+       boolean "Report process events to userspace"
+       depends on CONNECTOR=y
+       default y
+       ---help---
+         Provide a connector that reports process events to userspace. Send
+         events such as fork, exec, id change (uid, gid, suid, etc), and exit.
+
 endmenu
index 12ca79e8234d3fbe10226316a404d7bbb0cbf82b..1f255e46e9164128e432481bafae04197a23f2a3 100644 (file)
@@ -1,3 +1,4 @@
 obj-$(CONFIG_CONNECTOR)                += cn.o
+obj-$(CONFIG_PROC_EVENTS)      += cn_proc.o
 
 cn-y                           += cn_queue.o connector.o
diff --git a/drivers/connector/cn_proc.c b/drivers/connector/cn_proc.c
new file mode 100644 (file)
index 0000000..fcdf0ff
--- /dev/null
@@ -0,0 +1,222 @@
+/*
+ * cn_proc.c - process events connector
+ *
+ * Copyright (C) Matt Helsley, IBM Corp. 2005
+ * Based on cn_fork.c by Guillaume Thouvenin <guillaume.thouvenin@bull.net>
+ * Original copyright notice follows:
+ * Copyright (C) 2005 BULL SA.
+ *
+ *
+ * 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/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <asm/atomic.h>
+
+#include <linux/cn_proc.h>
+
+#define CN_PROC_MSG_SIZE (sizeof(struct cn_msg) + sizeof(struct proc_event))
+
+static atomic_t proc_event_num_listeners = ATOMIC_INIT(0);
+static struct cb_id cn_proc_event_id = { CN_IDX_PROC, CN_VAL_PROC };
+
+/* proc_counts is used as the sequence number of the netlink message */
+static DEFINE_PER_CPU(__u32, proc_event_counts) = { 0 };
+
+static inline void get_seq(__u32 *ts, int *cpu)
+{
+       *ts = get_cpu_var(proc_event_counts)++;
+       *cpu = smp_processor_id();
+       put_cpu_var(proc_counts);
+}
+
+void proc_fork_connector(struct task_struct *task)
+{
+       struct cn_msg *msg;
+       struct proc_event *ev;
+       __u8 buffer[CN_PROC_MSG_SIZE];
+
+       if (atomic_read(&proc_event_num_listeners) < 1)
+               return;
+
+       msg = (struct cn_msg*)buffer;
+       ev = (struct proc_event*)msg->data;
+       get_seq(&msg->seq, &ev->cpu);
+       ev->what = PROC_EVENT_FORK;
+       ev->event_data.fork.parent_pid = task->real_parent->pid;
+       ev->event_data.fork.parent_tgid = task->real_parent->tgid;
+       ev->event_data.fork.child_pid = task->pid;
+       ev->event_data.fork.child_tgid = task->tgid;
+
+       memcpy(&msg->id, &cn_proc_event_id, sizeof(msg->id));
+       msg->ack = 0; /* not used */
+       msg->len = sizeof(*ev);
+       /*  If cn_netlink_send() failed, the data is not sent */
+       cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL);
+}
+
+void proc_exec_connector(struct task_struct *task)
+{
+       struct cn_msg *msg;
+       struct proc_event *ev;
+       __u8 buffer[CN_PROC_MSG_SIZE];
+
+       if (atomic_read(&proc_event_num_listeners) < 1)
+               return;
+
+       msg = (struct cn_msg*)buffer;
+       ev = (struct proc_event*)msg->data;
+       get_seq(&msg->seq, &ev->cpu);
+       ev->what = PROC_EVENT_EXEC;
+       ev->event_data.exec.process_pid = task->pid;
+       ev->event_data.exec.process_tgid = task->tgid;
+
+       memcpy(&msg->id, &cn_proc_event_id, sizeof(msg->id));
+       msg->ack = 0; /* not used */
+       msg->len = sizeof(*ev);
+       cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL);
+}
+
+void proc_id_connector(struct task_struct *task, int which_id)
+{
+       struct cn_msg *msg;
+       struct proc_event *ev;
+       __u8 buffer[CN_PROC_MSG_SIZE];
+
+       if (atomic_read(&proc_event_num_listeners) < 1)
+               return;
+
+       msg = (struct cn_msg*)buffer;
+       ev = (struct proc_event*)msg->data;
+       ev->what = which_id;
+       ev->event_data.id.process_pid = task->pid;
+       ev->event_data.id.process_tgid = task->tgid;
+       if (which_id == PROC_EVENT_UID) {
+               ev->event_data.id.r.ruid = task->uid;
+               ev->event_data.id.e.euid = task->euid;
+       } else if (which_id == PROC_EVENT_GID) {
+               ev->event_data.id.r.rgid = task->gid;
+               ev->event_data.id.e.egid = task->egid;
+       } else
+               return;
+       get_seq(&msg->seq, &ev->cpu);
+
+       memcpy(&msg->id, &cn_proc_event_id, sizeof(msg->id));
+       msg->ack = 0; /* not used */
+       msg->len = sizeof(*ev);
+       cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL);
+}
+
+void proc_exit_connector(struct task_struct *task)
+{
+       struct cn_msg *msg;
+       struct proc_event *ev;
+       __u8 buffer[CN_PROC_MSG_SIZE];
+
+       if (atomic_read(&proc_event_num_listeners) < 1)
+               return;
+
+       msg = (struct cn_msg*)buffer;
+       ev = (struct proc_event*)msg->data;
+       get_seq(&msg->seq, &ev->cpu);
+       ev->what = PROC_EVENT_EXIT;
+       ev->event_data.exit.process_pid = task->pid;
+       ev->event_data.exit.process_tgid = task->tgid;
+       ev->event_data.exit.exit_code = task->exit_code;
+       ev->event_data.exit.exit_signal = task->exit_signal;
+
+       memcpy(&msg->id, &cn_proc_event_id, sizeof(msg->id));
+       msg->ack = 0; /* not used */
+       msg->len = sizeof(*ev);
+       cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL);
+}
+
+/*
+ * Send an acknowledgement message to userspace
+ *
+ * Use 0 for success, EFOO otherwise.
+ * Note: this is the negative of conventional kernel error
+ * values because it's not being returned via syscall return
+ * mechanisms.
+ */
+static void cn_proc_ack(int err, int rcvd_seq, int rcvd_ack)
+{
+       struct cn_msg *msg;
+       struct proc_event *ev;
+       __u8 buffer[CN_PROC_MSG_SIZE];
+
+       if (atomic_read(&proc_event_num_listeners) < 1)
+               return;
+
+       msg = (struct cn_msg*)buffer;
+       ev = (struct proc_event*)msg->data;
+       msg->seq = rcvd_seq;
+       ev->cpu = -1;
+       ev->what = PROC_EVENT_NONE;
+       ev->event_data.ack.err = err;
+       memcpy(&msg->id, &cn_proc_event_id, sizeof(msg->id));
+       msg->ack = rcvd_ack + 1;
+       msg->len = sizeof(*ev);
+       cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL);
+}
+
+/**
+ * cn_proc_mcast_ctl
+ * @data: message sent from userspace via the connector
+ */
+static void cn_proc_mcast_ctl(void *data)
+{
+       struct cn_msg *msg = data;
+       enum proc_cn_mcast_op *mc_op = NULL;
+       int err = 0;
+
+       if (msg->len != sizeof(*mc_op))
+               return;
+
+       mc_op = (enum proc_cn_mcast_op*)msg->data;
+       switch (*mc_op) {
+       case PROC_CN_MCAST_LISTEN:
+               atomic_inc(&proc_event_num_listeners);
+               break;
+       case PROC_CN_MCAST_IGNORE:
+               atomic_dec(&proc_event_num_listeners);
+               break;
+       default:
+               err = EINVAL;
+               break;
+       }
+       cn_proc_ack(err, msg->seq, msg->ack);
+}
+
+/*
+ * cn_proc_init - initialization entry point
+ *
+ * Adds the connector callback to the connector driver.
+ */
+static int __init cn_proc_init(void)
+{
+       int err;
+
+       if ((err = cn_add_callback(&cn_proc_event_id, "cn_proc",
+                                  &cn_proc_mcast_ctl))) {
+               printk(KERN_WARNING "cn_proc failed to register\n");
+               return err;
+       }
+       return 0;
+}
+
+module_init(cn_proc_init);
index a620f7d9ac8e730c4258a1f8e2c5c0d334e488f6..17502d6efae788c2bb614f3833a550de9059a59c 100644 (file)
@@ -224,11 +224,10 @@ static int __init dio_init(void)
                set_fs(fs);
 
                 /* Found a board, allocate it an entry in the list */
-               dev = kmalloc(sizeof(struct dio_dev), GFP_KERNEL);
+               dev = kzalloc(sizeof(struct dio_dev), GFP_KERNEL);
                if (!dev)
                        return 0;
 
-               memset(dev, 0, sizeof(struct dio_dev));
                dev->bus = &dio_bus;
                dev->dev.parent = &dio_bus.dev;
                dev->dev.bus = &dio_bus_type;
index 1937743c8e2971bb15b9f1d703aca168be4240e2..4196137e66dea5b9e191b86b6988766985a040ba 100644 (file)
@@ -281,13 +281,11 @@ static int __init eisa_probe (struct eisa_root_device *root)
        /* First try to get hold of slot 0. If there is no device
         * here, simply fail, unless root->force_probe is set. */
        
-       if (!(edev = kmalloc (sizeof (*edev), GFP_KERNEL))) {
+       if (!(edev = kzalloc (sizeof (*edev), GFP_KERNEL))) {
                printk (KERN_ERR "EISA: Couldn't allocate mainboard slot\n");
                return -ENOMEM;
        }
                
-       memset (edev, 0, sizeof (*edev));
-
        if (eisa_request_resources (root, edev, 0)) {
                printk (KERN_WARNING \
                        "EISA: Cannot allocate resource for mainboard\n");
@@ -317,13 +315,11 @@ static int __init eisa_probe (struct eisa_root_device *root)
  force_probe:
        
         for (c = 0, i = 1; i <= root->slots; i++) {
-               if (!(edev = kmalloc (sizeof (*edev), GFP_KERNEL))) {
+               if (!(edev = kzalloc (sizeof (*edev), GFP_KERNEL))) {
                        printk (KERN_ERR "EISA: Out of memory for slot %d\n",
                                i);
                        continue;
                }
-               
-               memset (edev, 0, sizeof (*edev));
 
                if (eisa_request_resources (root, edev, i)) {
                        printk (KERN_WARNING \
index e4710d1d1f9d8db1757e84965c2ccbcfcbc8f50a..5c8943509cc1b7b668a784685861c9e9fab94a89 100644 (file)
@@ -266,13 +266,12 @@ static void fcp_report_map_done(fc_channel *fc, int i, int status)
                        printk ("FC: Bad magic from REPORT_AL_MAP on %s - %08x\n", fc->name, p->magic);
                        fc->state = FC_STATE_OFFLINE;
                } else {
-                       fc->posmap = (fcp_posmap *)kmalloc(sizeof(fcp_posmap)+p->len, GFP_KERNEL);
+                       fc->posmap = (fcp_posmap *)kzalloc(sizeof(fcp_posmap)+p->len, GFP_KERNEL);
                        if (!fc->posmap) {
                                printk("FC: Not enough memory, offlining channel\n");
                                fc->state = FC_STATE_OFFLINE;
                        } else {
                                int k;
-                               memset(fc->posmap, 0, sizeof(fcp_posmap)+p->len);
                                /* FIXME: This is where SOCAL transfers our AL-PA.
                                   Keep it here till we found out what other cards do... */
                                fc->sid = (p->magic & 0xff);
@@ -351,14 +350,12 @@ void fcp_register(fc_channel *fc, u8 type, int unregister)
                        fc->dma_scsi_rsp = fc->dma_scsi_cmd + slots * sizeof (fcp_cmd);
                        fc->scsi_bitmap_end = (slots + 63) & ~63;
                        size = fc->scsi_bitmap_end / 8;
-                       fc->scsi_bitmap = kmalloc (size, GFP_KERNEL);
-                       memset (fc->scsi_bitmap, 0, size);
+                       fc->scsi_bitmap = kzalloc (size, GFP_KERNEL);
                        set_bit (0, fc->scsi_bitmap);
                        for (i = fc->can_queue; i < fc->scsi_bitmap_end; i++)
                                set_bit (i, fc->scsi_bitmap);
                        fc->scsi_free = fc->can_queue;
-                       fc->cmd_slots = (fcp_cmnd **)kmalloc(slots * sizeof(fcp_cmnd*), GFP_KERNEL);
-                       memset(fc->cmd_slots, 0, slots * sizeof(fcp_cmnd*));
+                       fc->cmd_slots = (fcp_cmnd **)kzalloc(slots * sizeof(fcp_cmnd*), GFP_KERNEL);
                        fc->abort_count = 0;
                } else {
                        fc->scsi_name[0] = 0;
@@ -541,12 +538,11 @@ int fcp_initialize(fc_channel *fcchain, int count)
        FCND(("fcp_inititialize %08lx\n", (long)fcp_init))
        FCND(("fc_channels %08lx\n", (long)fc_channels))
        FCND((" SID %d DID %d\n", fcchain->sid, fcchain->did))
-       l = kmalloc(sizeof (ls) + count, GFP_KERNEL);
+       l = kzalloc(sizeof (ls) + count, GFP_KERNEL);
        if (!l) {
                printk ("FC: Cannot allocate memory for initialization\n");
                return -ENOMEM;
        }
-       memset (l, 0, sizeof(ls) + count);
        l->magic = LSMAGIC;
        l->count = count;
        FCND(("FCP Init for %d channels\n", count))
@@ -555,17 +551,15 @@ int fcp_initialize(fc_channel *fcchain, int count)
        l->timer.function = fcp_login_timeout;
        l->timer.data = (unsigned long)l;
        atomic_set (&l->todo, count);
-       l->logi = kmalloc (count * 3 * sizeof(logi), GFP_KERNEL);
-       l->fcmds = kmalloc (count * sizeof(fcp_cmnd), GFP_KERNEL);
+       l->logi = kzalloc (count * 3 * sizeof(logi), GFP_KERNEL);
+       l->fcmds = kzalloc (count * sizeof(fcp_cmnd), GFP_KERNEL);
        if (!l->logi || !l->fcmds) {
-               if (l->logi) kfree (l->logi);
-               if (l->fcmds) kfree (l->fcmds);
+               kfree (l->logi);
+               kfree (l->fcmds);
                kfree (l);
                printk ("FC: Cannot allocate DMA memory for initialization\n");
                return -ENOMEM;
        }
-       memset (l->logi, 0, count * 3 * sizeof(logi));
-       memset (l->fcmds, 0, count * sizeof(fcp_cmnd));
        for (fc = fcchain, i = 0; fc && i < count; fc = fc->next, i++) {
                fc->state = FC_STATE_UNINITED;
                fc->rst_pkt = NULL;     /* kmalloc when first used */
@@ -678,13 +672,11 @@ int fcp_forceoffline(fc_channel *fcchain, int count)
        l.timer.function = fcp_login_timeout;
        l.timer.data = (unsigned long)&l;
        atomic_set (&l.todo, count);
-       l.fcmds = kmalloc (count * sizeof(fcp_cmnd), GFP_KERNEL);
+       l.fcmds = kzalloc (count * sizeof(fcp_cmnd), GFP_KERNEL);
        if (!l.fcmds) {
-               kfree (l.fcmds);
                printk ("FC: Cannot allocate memory for forcing offline\n");
                return -ENOMEM;
        }
-       memset (l.fcmds, 0, count * sizeof(fcp_cmnd));
        FCND(("Initializing OFFLINE packets\n"))
        for (fc = fcchain, i = 0; fc && i < count; fc = fc->next, i++) {
                fc->state = FC_STATE_UNINITED;
@@ -1114,9 +1106,8 @@ int fc_do_plogi(fc_channel *fc, unsigned char alpa, fc_wwn *node, fc_wwn *nport)
        logi *l;
        int status;
 
-       l = (logi *)kmalloc(2 * sizeof(logi), GFP_KERNEL);
+       l = (logi *)kzalloc(2 * sizeof(logi), GFP_KERNEL);
        if (!l) return -ENOMEM;
-       memset(l, 0, 2 * sizeof(logi));
        l->code = LS_PLOGI;
        memcpy (&l->nport_wwn, &fc->wwn_nport, sizeof(fc_wwn));
        memcpy (&l->node_wwn, &fc->wwn_node, sizeof(fc_wwn));
@@ -1149,9 +1140,8 @@ int fc_do_prli(fc_channel *fc, unsigned char alpa)
        prli *p;
        int status;
 
-       p = (prli *)kmalloc(2 * sizeof(prli), GFP_KERNEL);
+       p = (prli *)kzalloc(2 * sizeof(prli), GFP_KERNEL);
        if (!p) return -ENOMEM;
-       memset(p, 0, 2 * sizeof(prli));
        p->code = LS_PRLI;
        p->params[0] = 0x08002000;
        p->params[3] = 0x00000022;
index 247b4630277748acd536e142270cf3b5f4214002..ec1f94738c59712d47091ff38a8a8cc8ac66f2ea 100644 (file)
@@ -556,10 +556,9 @@ static inline void soc_init(struct sbus_dev *sdev, int no)
        int size, i;
        int irq;
        
-       s = kmalloc (sizeof (struct soc), GFP_KERNEL);
+       s = kzalloc (sizeof (struct soc), GFP_KERNEL);
        if (s == NULL)
                return;
-       memset (s, 0, sizeof(struct soc));
        spin_lock_init(&s->lock);
        s->soc_no = no;
 
index b2377dbd84a14223f2aa8ef5340388e7593fb883..922e9613b2cf547fe6c708d2c5a7aab4af1d33fc 100644 (file)
@@ -665,9 +665,8 @@ static inline void socal_init(struct sbus_dev *sdev, int no)
        int size, i;
        int irq, node;
        
-       s = kmalloc (sizeof (struct socal), GFP_KERNEL);
+       s = kzalloc (sizeof (struct socal), GFP_KERNEL);
        if (!s) return;
-       memset (s, 0, sizeof(struct socal));
        spin_lock_init(&s->lock);
        s->socal_no = no;
 
index 125929c9048f0be47b4e59543d79a5b62a0e0ff6..ba17292eb2902b5c7acb676beeb7fb840813414a 100644 (file)
@@ -50,7 +50,7 @@
 MODULE_AUTHOR("Abhay Salunke <abhay_salunke@dell.com>");
 MODULE_DESCRIPTION("Driver for updating BIOS image on DELL systems");
 MODULE_LICENSE("GPL");
-MODULE_VERSION("3.0");
+MODULE_VERSION("3.1");
 
 #define BIOS_SCAN_LIMIT 0xffffffff
 #define MAX_IMAGE_LENGTH 16
@@ -73,6 +73,11 @@ module_param_string(image_type, image_type, sizeof (image_type), 0);
 MODULE_PARM_DESC(image_type,
        "BIOS image type. choose- mono or packet or init");
 
+static unsigned long allocation_floor = 0x100000;
+module_param(allocation_floor, ulong, 0644);
+MODULE_PARM_DESC(allocation_floor,
+    "Minimum address for allocations when using Packet mode");
+
 struct packet_data {
        struct list_head list;
        size_t length;
@@ -99,61 +104,122 @@ static int create_packet(void *data, size_t length)
 {
        struct packet_data *newpacket;
        int ordernum = 0;
+       int retval = 0;
+       unsigned int packet_array_size = 0;
+       void **invalid_addr_packet_array = 0;
+       void *packet_data_temp_buf = 0;
+       unsigned int idx = 0;
 
        pr_debug("create_packet: entry \n");
 
        if (!rbu_data.packetsize) {
                pr_debug("create_packet: packetsize not specified\n");
-               return -EINVAL;
+               retval = -EINVAL;
+               goto out_noalloc;
        }
+
        spin_unlock(&rbu_data.lock);
-       newpacket = kmalloc(sizeof (struct packet_data), GFP_KERNEL);
-       spin_lock(&rbu_data.lock);
+
+       newpacket = kzalloc(sizeof (struct packet_data), GFP_KERNEL);
 
        if (!newpacket) {
                printk(KERN_WARNING
                        "dell_rbu:%s: failed to allocate new "
                        "packet\n", __FUNCTION__);
-               return -ENOMEM;
+               retval = -ENOMEM;
+               spin_lock(&rbu_data.lock);
+               goto out_noalloc;
        }
 
        ordernum = get_order(length);
+
        /*
-        * there is no upper limit on memory
-        * address for packetized mechanism
+        * BIOS errata mean we cannot allocate packets below 1MB or they will
+        * be overwritten by BIOS.
+        *
+        * array to temporarily hold packets
+        * that are below the allocation floor
+        *
+        * NOTE: very simplistic because we only need the floor to be at 1MB
+        *       due to BIOS errata. This shouldn't be used for higher floors
+        *       or you will run out of mem trying to allocate the array.
         */
-       spin_unlock(&rbu_data.lock);
-       newpacket->data = (unsigned char *) __get_free_pages(GFP_KERNEL,
-               ordernum);
-       spin_lock(&rbu_data.lock);
+       packet_array_size = max(
+                       (unsigned int)(allocation_floor / rbu_data.packetsize),
+                       (unsigned int)1);
+       invalid_addr_packet_array = kzalloc(packet_array_size * sizeof(void*),
+                                               GFP_KERNEL);
 
-       pr_debug("create_packet: newpacket %p\n", newpacket->data);
-
-       if (!newpacket->data) {
+       if (!invalid_addr_packet_array) {
                printk(KERN_WARNING
-                       "dell_rbu:%s: failed to allocate new "
-                       "packet\n", __FUNCTION__);
-               kfree(newpacket);
-               return -ENOMEM;
+                       "dell_rbu:%s: failed to allocate "
+                       "invalid_addr_packet_array \n",
+                       __FUNCTION__);
+               retval = -ENOMEM;
+               spin_lock(&rbu_data.lock);
+               goto out_alloc_packet;
        }
 
+       while (!packet_data_temp_buf) {
+               packet_data_temp_buf = (unsigned char *)
+                       __get_free_pages(GFP_KERNEL, ordernum);
+               if (!packet_data_temp_buf) {
+                       printk(KERN_WARNING
+                               "dell_rbu:%s: failed to allocate new "
+                               "packet\n", __FUNCTION__);
+                       retval = -ENOMEM;
+                       spin_lock(&rbu_data.lock);
+                       goto out_alloc_packet_array;
+               }
+
+               if ((unsigned long)virt_to_phys(packet_data_temp_buf)
+                               < allocation_floor) {
+                       pr_debug("packet 0x%lx below floor at 0x%lx.\n",
+                                       (unsigned long)virt_to_phys(
+                                               packet_data_temp_buf),
+                                       allocation_floor);
+                       invalid_addr_packet_array[idx++] = packet_data_temp_buf;
+                       packet_data_temp_buf = 0;
+               }
+       }
+       spin_lock(&rbu_data.lock);
+
+       newpacket->data = packet_data_temp_buf;
+
+       pr_debug("create_packet: newpacket at physical addr %lx\n",
+               (unsigned long)virt_to_phys(newpacket->data));
+
+       /* packets may not have fixed size */
+       newpacket->length = length;
        newpacket->ordernum = ordernum;
        ++rbu_data.num_packets;
-       /*
-        * initialize the newly created packet headers
-        */
+
+       /* initialize the newly created packet headers */
        INIT_LIST_HEAD(&newpacket->list);
        list_add_tail(&newpacket->list, &packet_data_head.list);
-       /*
-        * packets may not have fixed size
-        */
-       newpacket->length = length;
 
        memcpy(newpacket->data, data, length);
 
        pr_debug("create_packet: exit \n");
 
-       return 0;
+out_alloc_packet_array:
+       /* always free packet array */
+       for (;idx>0;idx--) {
+               pr_debug("freeing unused packet below floor 0x%lx.\n",
+                       (unsigned long)virt_to_phys(
+                               invalid_addr_packet_array[idx-1]));
+               free_pages((unsigned long)invalid_addr_packet_array[idx-1],
+                       ordernum);
+       }
+       kfree(invalid_addr_packet_array);
+
+out_alloc_packet:
+       /* if error, free data */
+       if (retval)
+               kfree(newpacket);
+
+out_noalloc:
+       return retval;
 }
 
 static int packetize_data(void *data, size_t length)
@@ -693,3 +759,6 @@ static __exit void dcdrbu_exit(void)
 
 module_exit(dcdrbu_exit);
 module_init(dcdrbu_init);
+
+/* vim:noet:ts=8:sw=8
+*/
index 6996476669f17397d1f9b1cab8e8b2f2a094cb6d..b4502ed65793a01a198b666ecba4fc7e45ac286a 100644 (file)
@@ -715,7 +715,6 @@ edd_device_register(struct edd_device *edev, int i)
 
        if (!edev)
                return 1;
-       memset(edev, 0, sizeof (*edev));
        edd_dev_set_info(edev, i);
        kobject_set_name(&edev->kobj, "int13_dev%02x",
                         0x80 + i);
@@ -756,7 +755,7 @@ edd_init(void)
                return rc;
 
        for (i = 0; i < edd_num_devices() && !rc; i++) {
-               edev = kmalloc(sizeof (*edev), GFP_KERNEL);
+               edev = kzalloc(sizeof (*edev), GFP_KERNEL);
                if (!edev)
                        return -ENOMEM;
 
index 33b17c6a46fb9a32e7c84b94b6b7970f9862fe45..bda5bce681b6bbdf0962c39e50cc3e8b4c3e1877 100644 (file)
@@ -614,16 +614,14 @@ efivar_create_sysfs_entry(unsigned long variable_name_size,
        char *short_name;
        struct efivar_entry *new_efivar;
 
-       short_name = kmalloc(short_name_size + 1, GFP_KERNEL);
-       new_efivar = kmalloc(sizeof(struct efivar_entry), GFP_KERNEL);
+       short_name = kzalloc(short_name_size + 1, GFP_KERNEL);
+       new_efivar = kzalloc(sizeof(struct efivar_entry), GFP_KERNEL);
 
        if (!short_name || !new_efivar)  {
                kfree(short_name);
                kfree(new_efivar);
                return 1;
        }
-       memset(short_name, 0, short_name_size+1);
-       memset(new_efivar, 0, sizeof(struct efivar_entry));
 
        memcpy(new_efivar->var.VariableName, variable_name,
                variable_name_size);
@@ -674,14 +672,12 @@ efivars_init(void)
        if (!efi_enabled)
                return -ENODEV;
 
-       variable_name = kmalloc(variable_name_size, GFP_KERNEL);
+       variable_name = kzalloc(variable_name_size, GFP_KERNEL);
        if (!variable_name) {
                printk(KERN_ERR "efivars: Memory allocation failed.\n");
                return -ENOMEM;
        }
 
-       memset(variable_name, 0, variable_name_size);
-
        printk(KERN_INFO "EFI Variables Facility v%s %s\n", EFIVARS_VERSION,
               EFIVARS_DATE);
 
index 6f48579799b588b456a59f18b41cccae19bc8d2b..dddd3eb9b3870ef060e84db9d8db4e099303c71d 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/kdev_t.h>
 #include <linux/idr.h>
 #include <linux/hwmon.h>
+#include <linux/gfp.h>
 
 #define HWMON_ID_PREFIX "hwmon"
 #define HWMON_ID_FORMAT HWMON_ID_PREFIX "%d"
index 6a82ffae1bfd6af15ce3fb89c92cae3c62edaab7..69e7e125683bb4f13b19a0d1b8fe6a4af8b22f83 100644 (file)
@@ -193,7 +193,7 @@ static int max1619_detect(struct i2c_adapter *adapter, int address, int kind)
        int err = 0;
        const char *name = "";  
        u8 reg_config=0, reg_convrate=0, reg_status=0;
-       u8 man_id, chip_id;
+
        if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
                goto exit;
 
@@ -238,16 +238,15 @@ static int max1619_detect(struct i2c_adapter *adapter, int address, int kind)
        }
 
        if (kind <= 0) { /* identification */
+               u8 man_id, chip_id;
        
                man_id = i2c_smbus_read_byte_data(new_client,
                         MAX1619_REG_R_MAN_ID);
                chip_id = i2c_smbus_read_byte_data(new_client,
                          MAX1619_REG_R_CHIP_ID);
                
-               if ((man_id == 0x4D) && (chip_id == 0x04)){  
-                               kind = max1619;
-                       }
-               }
+               if ((man_id == 0x4D) && (chip_id == 0x04))
+                       kind = max1619;
 
                if (kind <= 0) { /* identification failed */
                        dev_info(&adapter->dev,
@@ -255,11 +254,10 @@ static int max1619_detect(struct i2c_adapter *adapter, int address, int kind)
                            "chip_id=0x%02X).\n", man_id, chip_id);
                        goto exit_free;
                }
-       
+       }
 
-       if (kind == max1619){
+       if (kind == max1619)
                name = "max1619";
-       }
 
        /* We can fill in the remaining client fields */
        strlcpy(new_client->name, name, I2C_NAME_SIZE);
index 9265f32122fa4b59d072b98134c18bf383fb57d0..ffdb3a03e2b5f9bd39bc8c551f04506df4a92081 100644 (file)
@@ -976,11 +976,9 @@ w83781d_detect_subclients(struct i2c_adapter *adapter, int address, int kind,
 ERROR_SC_3:
        i2c_detach_client(data->lm75[0]);
 ERROR_SC_2:
-       if (data->lm75[1])
-               kfree(data->lm75[1]);
+       kfree(data->lm75[1]);
 ERROR_SC_1:
-       if (data->lm75[0])
-               kfree(data->lm75[0]);
+       kfree(data->lm75[0]);
 ERROR_SC_0:
        return err;
 }
index f51ab652300a66a5d629ac3937622e289f379bf7..56c7d987590f51704ea22363796ab34d838c9c1b 100644 (file)
@@ -245,10 +245,8 @@ static void __exit amd756_s4882_exit(void)
                kfree(s4882_adapter);
                s4882_adapter = NULL;
        }
-       if (s4882_algo) {
-               kfree(s4882_algo);
-               s4882_algo = NULL;
-       }
+       kfree(s4882_algo);
+       s4882_algo = NULL;
 
        /* Restore physical bus */
        if (i2c_add_adapter(&amd756_smbus))
index 8b9d85526596a38380dbf65ce0a3f6dcc82527d7..c2f47923d174bd6eedb352ec9164b52eac38b488 100644 (file)
@@ -3292,12 +3292,9 @@ static void ide_cd_release(struct kref *kref)
        ide_drive_t *drive = info->drive;
        struct gendisk *g = info->disk;
 
-       if (info->buffer != NULL)
-               kfree(info->buffer);
-       if (info->toc != NULL)
-               kfree(info->toc);
-       if (info->changer_info != NULL)
-               kfree(info->changer_info);
+       kfree(info->buffer);
+       kfree(info->toc);
+       kfree(info->changer_info);
        if (devinfo->handle == drive && unregister_cdrom(devinfo))
                printk(KERN_ERR "%s: %s failed to unregister device from the cdrom "
                                "driver.\n", __FUNCTION__, drive->name);
@@ -3455,7 +3452,7 @@ static int ide_cd_probe(struct device *dev)
                printk(KERN_INFO "ide-cd: passing drive %s to ide-scsi emulation.\n", drive->name);
                goto failed;
        }
-       info = kmalloc(sizeof(struct cdrom_info), GFP_KERNEL);
+       info = kzalloc(sizeof(struct cdrom_info), GFP_KERNEL);
        if (info == NULL) {
                printk(KERN_ERR "%s: Can't allocate a cdrom structure\n", drive->name);
                goto failed;
@@ -3469,8 +3466,6 @@ static int ide_cd_probe(struct device *dev)
 
        ide_register_subdriver(drive, &ide_cdrom_driver);
 
-       memset(info, 0, sizeof (struct cdrom_info));
-
        kref_init(&info->kref);
 
        info->drive = drive;
@@ -3489,12 +3484,9 @@ static int ide_cd_probe(struct device *dev)
        if (ide_cdrom_setup(drive)) {
                struct cdrom_device_info *devinfo = &info->devinfo;
                ide_unregister_subdriver(drive, &ide_cdrom_driver);
-               if (info->buffer != NULL)
-                       kfree(info->buffer);
-               if (info->toc != NULL)
-                       kfree(info->toc);
-               if (info->changer_info != NULL)
-                       kfree(info->changer_info);
+               kfree(info->buffer);
+               kfree(info->toc);
+               kfree(info->changer_info);
                if (devinfo->handle == drive && unregister_cdrom(devinfo))
                        printk (KERN_ERR "%s: ide_cdrom_cleanup failed to unregister device from the cdrom driver.\n", drive->name);
                kfree(info);
index 234f5de3e929b6c0d10ee46a994e200f16f62646..e827b39e4b3c7f0c02d1a964a6a9a3a5b0a7cb29 100644 (file)
@@ -1215,7 +1215,7 @@ static int ide_disk_probe(struct device *dev)
        if (drive->media != ide_disk)
                goto failed;
 
-       idkp = kmalloc(sizeof(*idkp), GFP_KERNEL);
+       idkp = kzalloc(sizeof(*idkp), GFP_KERNEL);
        if (!idkp)
                goto failed;
 
@@ -1228,8 +1228,6 @@ static int ide_disk_probe(struct device *dev)
 
        ide_register_subdriver(drive, &idedisk_driver);
 
-       memset(idkp, 0, sizeof(*idkp));
-
        kref_init(&idkp->kref);
 
        idkp->drive = drive;
index 29c22fc278c6510b75209ea6fea80649fe23fe77..e83f54d37f9668625d95649f766d4fe74e2741e7 100644 (file)
@@ -2146,7 +2146,7 @@ static int ide_floppy_probe(struct device *dev)
                printk("ide-floppy: passing drive %s to ide-scsi emulation.\n", drive->name);
                goto failed;
        }
-       if ((floppy = (idefloppy_floppy_t *) kmalloc (sizeof (idefloppy_floppy_t), GFP_KERNEL)) == NULL) {
+       if ((floppy = (idefloppy_floppy_t *) kzalloc (sizeof (idefloppy_floppy_t), GFP_KERNEL)) == NULL) {
                printk (KERN_ERR "ide-floppy: %s: Can't allocate a floppy structure\n", drive->name);
                goto failed;
        }
@@ -2159,8 +2159,6 @@ static int ide_floppy_probe(struct device *dev)
 
        ide_register_subdriver(drive, &idefloppy_driver);
 
-       memset(floppy, 0, sizeof(*floppy));
-
        kref_init(&floppy->kref);
 
        floppy->drive = drive;
index c1128ae5cd2f98319ee889b74fefd7e69916edd4..02167a5b751dbe40a0b1be304766903fceb43c52 100644 (file)
@@ -596,14 +596,13 @@ static inline u8 probe_for_drive (ide_drive_t *drive)
         *      Also note that 0 everywhere means "can't do X"
         */
  
-       drive->id = kmalloc(SECTOR_WORDS *4, GFP_KERNEL);
+       drive->id = kzalloc(SECTOR_WORDS *4, GFP_KERNEL);
        drive->id_read = 0;
        if(drive->id == NULL)
        {
                printk(KERN_ERR "ide: out of memory for id data.\n");
                return 0;
        }
-       memset(drive->id, 0, SECTOR_WORDS * 4);
        strcpy(drive->id->model, "UNKNOWN");
        
        /* skip probing? */
@@ -1316,10 +1315,8 @@ static void drive_release_dev (struct device *dev)
                drive->devfs_name[0] = '\0';
        }
        ide_remove_drive_from_hwgroup(drive);
-       if (drive->id != NULL) {
-               kfree(drive->id);
-               drive->id = NULL;
-       }
+       kfree(drive->id);
+       drive->id = NULL;
        drive->present = 0;
        /* Messed up locking ... */
        spin_unlock_irq(&ide_lock);
index 47f2b832555fd27fefd6650c728cf81de980c363..0ac7eb8f40d537ae04c2db1b23a2d819df835e69 100644 (file)
@@ -4850,7 +4850,7 @@ static int ide_tape_probe(struct device *dev)
                printk(KERN_WARNING "ide-tape: Use drive %s with ide-scsi emulation and osst.\n", drive->name);
                printk(KERN_WARNING "ide-tape: OnStream support will be removed soon from ide-tape!\n");
        }
-       tape = (idetape_tape_t *) kmalloc (sizeof (idetape_tape_t), GFP_KERNEL);
+       tape = (idetape_tape_t *) kzalloc (sizeof (idetape_tape_t), GFP_KERNEL);
        if (tape == NULL) {
                printk(KERN_ERR "ide-tape: %s: Can't allocate a tape structure\n", drive->name);
                goto failed;
@@ -4864,8 +4864,6 @@ static int ide_tape_probe(struct device *dev)
 
        ide_register_subdriver(drive, &idetape_driver);
 
-       memset(tape, 0, sizeof(*tape));
-
        kref_init(&tape->kref);
 
        tape->drive = drive;
index ace8edad6e9620ac685dc0e038a89c6e1d0ef546..7ec18fa3b5ff8f8f6d0e8fc8ae7eda36a2186afe 100644 (file)
@@ -528,9 +528,8 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
 
 //     printk("IDE Taskfile ...\n");
 
-       req_task = kmalloc(tasksize, GFP_KERNEL);
+       req_task = kzalloc(tasksize, GFP_KERNEL);
        if (req_task == NULL) return -ENOMEM;
-       memset(req_task, 0, tasksize);
        if (copy_from_user(req_task, buf, tasksize)) {
                kfree(req_task);
                return -EFAULT;
@@ -541,12 +540,11 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
 
        if (taskout) {
                int outtotal = tasksize;
-               outbuf = kmalloc(taskout, GFP_KERNEL);
+               outbuf = kzalloc(taskout, GFP_KERNEL);
                if (outbuf == NULL) {
                        err = -ENOMEM;
                        goto abort;
                }
-               memset(outbuf, 0, taskout);
                if (copy_from_user(outbuf, buf + outtotal, taskout)) {
                        err = -EFAULT;
                        goto abort;
@@ -555,12 +553,11 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
 
        if (taskin) {
                int intotal = tasksize + taskout;
-               inbuf = kmalloc(taskin, GFP_KERNEL);
+               inbuf = kzalloc(taskin, GFP_KERNEL);
                if (inbuf == NULL) {
                        err = -ENOMEM;
                        goto abort;
                }
-               memset(inbuf, 0, taskin);
                if (copy_from_user(inbuf, buf + intotal, taskin)) {
                        err = -EFAULT;
                        goto abort;
@@ -649,10 +646,8 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
        }
 abort:
        kfree(req_task);
-       if (outbuf != NULL)
-               kfree(outbuf);
-       if (inbuf != NULL)
-               kfree(inbuf);
+       kfree(outbuf);
+       kfree(inbuf);
 
 //     printk("IDE Taskfile ioctl ended. rc = %i\n", err);
 
@@ -709,10 +704,9 @@ int ide_cmd_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
 
        if (args[3]) {
                argsize = 4 + (SECTOR_WORDS * 4 * args[3]);
-               argbuf = kmalloc(argsize, GFP_KERNEL);
+               argbuf = kzalloc(argsize, GFP_KERNEL);
                if (argbuf == NULL)
                        return -ENOMEM;
-               memcpy(argbuf, args, 4);
        }
        if (set_transfer(drive, &tfargs)) {
                xfer_rate = args[1];
index 73ca8f73917d9172bba616311437ccb3de9966e9..9fe19808d8153853332891595776b7f1e27659ba 100644 (file)
@@ -864,9 +864,8 @@ static int __ide_add_setting(ide_drive_t *drive, const char *name, int rw, int r
        down(&ide_setting_sem);
        while ((*p) && strcmp((*p)->name, name) < 0)
                p = &((*p)->next);
-       if ((setting = kmalloc(sizeof(*setting), GFP_KERNEL)) == NULL)
+       if ((setting = kzalloc(sizeof(*setting), GFP_KERNEL)) == NULL)
                goto abort;
-       memset(setting, 0, sizeof(*setting));
        if ((setting->name = kmalloc(strlen(name) + 1, GFP_KERNEL)) == NULL)
                goto abort;
        strcpy(setting->name, name);
@@ -889,8 +888,7 @@ static int __ide_add_setting(ide_drive_t *drive, const char *name, int rw, int r
        return 0;
 abort:
        up(&ide_setting_sem);
-       if (setting)
-               kfree(setting);
+       kfree(setting);
        return -1;
 }
 
index a35a58bef1a4eb4d1752bc2929eb528956206035..1dafffa7e51333ac262495882907d78f39212cf6 100644 (file)
@@ -116,9 +116,8 @@ static dev_link_t *ide_attach(void)
     DEBUG(0, "ide_attach()\n");
 
     /* Create new ide device */
-    info = kmalloc(sizeof(*info), GFP_KERNEL);
+    info = kzalloc(sizeof(*info), GFP_KERNEL);
     if (!info) return NULL;
-    memset(info, 0, sizeof(*info));
     link = &info->link; link->priv = info;
 
     link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
@@ -221,9 +220,8 @@ static void ide_config(dev_link_t *link)
 
     DEBUG(0, "ide_config(0x%p)\n", link);
 
-    stk = kmalloc(sizeof(*stk), GFP_KERNEL);
+    stk = kzalloc(sizeof(*stk), GFP_KERNEL);
     if (!stk) goto err_mem;
-    memset(stk, 0, sizeof(*stk));
     cfg = &stk->parse.cftable_entry;
 
     tuple.TupleData = (cisdata_t *)&stk->buf;
index 127619a109eda2ef119c9deeecd44793ae53a834..7b589d948bf98bce6405196a55444787d4eff920 100644 (file)
@@ -1516,7 +1516,7 @@ static void __devinit init_dma_hpt366(ide_hwif_t *hwif, unsigned long dmabase)
 
 static void __devinit init_iops_hpt366(ide_hwif_t *hwif)
 {
-       struct hpt_info *info = kmalloc(sizeof(struct hpt_info), GFP_KERNEL);
+       struct hpt_info *info = kzalloc(sizeof(struct hpt_info), GFP_KERNEL);
        unsigned long dmabase = pci_resource_start(hwif->pci_dev, 4);
        u8 did, rid;
 
@@ -1524,7 +1524,6 @@ static void __devinit init_iops_hpt366(ide_hwif_t *hwif)
                printk(KERN_WARNING "hpt366: out of memory.\n");
                return;
        }
-       memset(info, 0, sizeof(struct hpt_info));
        ide_set_hwifdata(hwif, info);
 
        if(dmabase) {
index e440036e651fb63999d980db8ad82579f031d734..108fda83fea476bc2ab4d13e96ac3c09e847cd22 100644 (file)
@@ -642,14 +642,13 @@ static void __devinit it821x_fixups(ide_hwif_t *hwif)
 
 static void __devinit init_hwif_it821x(ide_hwif_t *hwif)
 {
-       struct it821x_dev *idev = kmalloc(sizeof(struct it821x_dev), GFP_KERNEL);
+       struct it821x_dev *idev = kzalloc(sizeof(struct it821x_dev), GFP_KERNEL);
        u8 conf;
 
        if(idev == NULL) {
                printk(KERN_ERR "it821x: out of memory, falling back to legacy behaviour.\n");
                goto fallback;
        }
-       memset(idev, 0, sizeof(struct it821x_dev));
        ide_set_hwifdata(hwif, idev);
 
        pci_read_config_byte(hwif->pci_dev, 0x50, &conf);
index e8e28569a6684feb2c0ae4e5d41447479c5480bc..75897509c4017c3a2f8175b79181cfae4c87bab8 100644 (file)
@@ -320,8 +320,7 @@ static void ohci1394_stop_it_ctx(struct ti_ohci *ohci, int ctx, int synchronous)
                        if ((control & OHCI1394_CONTEXT_ACTIVE) == 0)
                                break;
 
-                       set_current_state(TASK_INTERRUPTIBLE);
-                       schedule_timeout(1);
+                       schedule_timeout_interruptible(1);
                }
        }
 }
index 7545775d38efe1957a2fe490ad23fbe4bd329622..34b724afd28daf15ca52e14270a796fc9cfcede3 100644 (file)
@@ -37,6 +37,9 @@
  * $Id: agent.c 1389 2004-12-27 22:56:47Z roland $
  */
 
+#include <linux/slab.h>
+#include <linux/string.h>
+
 #include "agent.h"
 #include "smi.h"
 
index 3d8175e5f0544e7cf22e97649049f8e0635cf30f..41d6b4017acb9d24aebdd5aed278b079bf382d85 100644 (file)
@@ -508,8 +508,7 @@ static void unregister_mad_agent(struct ib_mad_agent_private *mad_agent_priv)
        wait_event(mad_agent_priv->wait,
                   !atomic_read(&mad_agent_priv->refcount));
 
-       if (mad_agent_priv->reg_req)
-               kfree(mad_agent_priv->reg_req);
+       kfree(mad_agent_priv->reg_req);
        ib_dereg_mr(mad_agent_priv->agent.mr);
        kfree(mad_agent_priv);
 }
@@ -2500,8 +2499,7 @@ error:
 static void destroy_mad_qp(struct ib_mad_qp_info *qp_info)
 {
        ib_destroy_qp(qp_info->qp);
-       if (qp_info->snoop_table)
-               kfree(qp_info->snoop_table);
+       kfree(qp_info->snoop_table);
 }
 
 /*
index 35df5010e723ecf9d466f0a27fd33f51bfe80e86..c972d72357647e874302a979d36bc22eee9c3f17 100644 (file)
@@ -33,6 +33,8 @@
  * $Id: packer.c 1349 2004-12-16 21:09:43Z roland $
  */
 
+#include <linux/string.h>
+
 #include <rdma/ib_pack.h>
 
 static u64 value_read(int offset, int size, void *structure)
index b8120650e71187c56dad658533979d5fbd24519a..08648b1a387e4bed61961d2aedf4f163a8e0a0f5 100644 (file)
@@ -36,6 +36,9 @@
 
 #include "core_priv.h"
 
+#include <linux/slab.h>
+#include <linux/string.h>
+
 #include <rdma/ib_mad.h>
 
 struct ib_port {
index 527b23450ab3d72dc12e3298e8bbdc49a871e12b..997c07db6d8fb216a132b12555d4cc27357e7531 100644 (file)
@@ -34,6 +34,7 @@
  */
 
 #include <linux/errno.h>
+#include <linux/string.h>
 
 #include <rdma/ib_pack.h>
 
index 72d3ef786db50acf3194612b43bbe3910b5cc955..4186cc888ea5b209f8c078b3d97e0faa4732cb11 100644 (file)
@@ -40,6 +40,7 @@
 
 #include <linux/errno.h>
 #include <linux/err.h>
+#include <linux/string.h>
 
 #include <rdma/ib_verbs.h>
 #include <rdma/ib_cache.h>
index 7ac52af43b999caade4645d19f1b2cd244808917..25ebab64bc4257a29548d8e398249f38d91e67a8 100644 (file)
@@ -32,6 +32,9 @@
  * $Id$
  */
 
+#include <linux/jiffies.h>
+#include <linux/timer.h>
+
 #include "mthca_dev.h"
 
 enum {
index 292f55be8cbd8c6eef90a0a6d884ac0261de9652..26d5161fde0719620313b01d5205f6ced2a65c84 100644 (file)
@@ -32,6 +32,9 @@
  * $Id: mthca_srq.c 3047 2005-08-10 03:59:35Z roland $
  */
 
+#include <linux/slab.h>
+#include <linux/string.h>
+
 #include "mthca_dev.h"
 #include "mthca_cmd.h"
 #include "mthca_memfree.h"
index 4015a91f4b6e7bcc0a17089f155ebb36233ce16d..948c1cc01bc95ea5291a843b107f86f2e7cf70bd 100644 (file)
@@ -271,8 +271,7 @@ static int uinput_alloc_device(struct file *file, const char __user *buffer, siz
                goto exit;
        }
 
-       if (dev->name)
-               kfree(dev->name);
+       kfree(dev->name);
 
        size = strnlen(user_dev->name, UINPUT_MAX_NAME_SIZE) + 1;
        dev->name = name = kmalloc(size, GFP_KERNEL);
@@ -372,11 +371,8 @@ static int uinput_burn_device(struct uinput_device *udev)
        if (test_bit(UIST_CREATED, &udev->state))
                uinput_destroy_device(udev);
 
-       if (udev->dev->name)
-               kfree(udev->dev->name);
-       if (udev->dev->phys)
-               kfree(udev->dev->phys);
-
+       kfree(udev->dev->name);
+       kfree(udev->dev->phys);
        kfree(udev->dev);
        kfree(udev);
 
index db9bad2b3d165cec9aab180cbe50bdd5697651dc..27391c32f3ebbe3e7a04be2a8609ae30e45d1fbf 100644 (file)
@@ -212,11 +212,8 @@ static void avmcs_detach(dev_link_t *link)
     
     /* Unlink device structure, free pieces */
     *linkp = link->next;
-    if (link->priv) {
-       kfree(link->priv);
-    }
+    kfree(link->priv);
     kfree(link);
-    
 } /* avmcs_detach */
 
 /*======================================================================
index 625799ab0d14d5292c96d3c41e01c90148e55567..5d8ee7368f7b79828abc89ec32b9e64724417bc9 100644 (file)
@@ -552,14 +552,10 @@ close_hdlcstate(struct BCState *bcs)
 {
        modehdlc(bcs, 0, 0);
        if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) {
-               if (bcs->hw.hdlc.rcvbuf) {
-                       kfree(bcs->hw.hdlc.rcvbuf);
-                       bcs->hw.hdlc.rcvbuf = NULL;
-               }
-               if (bcs->blog) {
-                       kfree(bcs->blog);
-                       bcs->blog = NULL;
-               }
+               kfree(bcs->hw.hdlc.rcvbuf);
+               bcs->hw.hdlc.rcvbuf = NULL;
+               kfree(bcs->blog);
+               bcs->blog = NULL;
                skb_queue_purge(&bcs->rqueue);
                skb_queue_purge(&bcs->squeue);
                if (bcs->tx_skb) {
index 0e22991635e7510ddd6f91f6fcd090ca213bce4a..5f5a5ae740d2aa9a2afb83b26a0f5075dc94538f 100644 (file)
@@ -236,9 +236,7 @@ static void avma1cs_detach(dev_link_t *link)
     
     /* Unlink device structure, free pieces */
     *linkp = link->next;
-    if (link->priv) {
-       kfree(link->priv);
-    }
+    kfree(link->priv);
     kfree(link);
     
 } /* avma1cs_detach */
index fbaab4352902621d183b318353c89460746a1d56..8159bcecd0c2e1c6fabe01a6dbbe13fbb2d86024 100644 (file)
@@ -787,8 +787,7 @@ static void ll_unload(struct IsdnCardState *cs)
        ic.command = ISDN_STAT_UNLOAD;
        ic.driver = cs->myid;
        cs->iif.statcallb(&ic);
-       if (cs->status_buf)
-               kfree(cs->status_buf);
+       kfree(cs->status_buf);
        cs->status_read = NULL;
        cs->status_write = NULL;
        cs->status_end = NULL;
@@ -807,10 +806,8 @@ static void closecard(int cardnr)
 
        skb_queue_purge(&csta->rq);
        skb_queue_purge(&csta->sq);
-       if (csta->rcvbuf) {
-               kfree(csta->rcvbuf);
-               csta->rcvbuf = NULL;
-       }
+       kfree(csta->rcvbuf);
+       csta->rcvbuf = NULL;
        if (csta->tx_skb) {
                dev_kfree_skb(csta->tx_skb);
                csta->tx_skb = NULL;
index 7cf87793e7907d5bdf4d354a1fc4011cce151ad6..637a261c93122a5929d3459e6d4a9e346b32b16e 100644 (file)
@@ -1052,18 +1052,12 @@ init2bds0(struct IsdnCardState *cs)
 void
 release2bds0(struct IsdnCardState *cs)
 {
-       if (cs->bcs[0].hw.hfc.send) {
-               kfree(cs->bcs[0].hw.hfc.send);
-               cs->bcs[0].hw.hfc.send = NULL;
-       }
-       if (cs->bcs[1].hw.hfc.send) {
-               kfree(cs->bcs[1].hw.hfc.send);
-               cs->bcs[1].hw.hfc.send = NULL;
-       }
-       if (cs->hw.hfcD.send) {
-               kfree(cs->hw.hfcD.send);
-               cs->hw.hfcD.send = NULL;
-       }
+       kfree(cs->bcs[0].hw.hfc.send);
+       cs->bcs[0].hw.hfc.send = NULL;
+       kfree(cs->bcs[1].hw.hfc.send);
+       cs->bcs[1].hw.hfc.send = NULL;
+       kfree(cs->hw.hfcD.send);
+       cs->hw.hfcD.send = NULL;
 }
 
 void
index f978a5af866292489ceb58b267219c5a3b86b32e..c964539cc43e537daa1fe135dbd66afa22da2117 100644 (file)
@@ -582,12 +582,8 @@ inithfc(struct IsdnCardState *cs)
 void
 releasehfc(struct IsdnCardState *cs)
 {
-       if (cs->bcs[0].hw.hfc.send) {
-               kfree(cs->bcs[0].hw.hfc.send);
-               cs->bcs[0].hw.hfc.send = NULL;
-       }
-       if (cs->bcs[1].hw.hfc.send) {
-               kfree(cs->bcs[1].hw.hfc.send);
-               cs->bcs[1].hw.hfc.send = NULL;
-       }
+       kfree(cs->bcs[0].hw.hfc.send);
+       cs->bcs[0].hw.hfc.send = NULL;
+       kfree(cs->bcs[1].hw.hfc.send);
+       cs->bcs[1].hw.hfc.send = NULL;
 }
index e2c3af49d72b9af938d47fd109924d74e7c84949..32bf0d5d0f9a0d0692414c683a6547c3050be5e9 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * hfc_usb.c
  *
- * $Id: hfc_usb.c,v 4.34 2005/01/26 17:25:53 martinb1 Exp $
+ * $Id: hfc_usb.c,v 4.36 2005/04/08 09:55:13 martinb1 Exp $
  *
  * modular HiSax ISDN driver for Colognechip HFC-S USB chip
  *
 #include "hisax_if.h"
 #include "hfc_usb.h"
 
-/*
-* Version Information
-* (do not modify the CVS Makros $Revision: 4.34 $ and $Date: 2005/01/26 17:25:53 $ !)
-*/
 static const char *hfcusb_revision =
-    "Revision: 4.34 $ Date: 2005/01/26 17:25:53 $ ";
+    "$Revision: 4.36 $ $Date: 2005/04/08 09:55:13 $ ";
 
 /* Hisax debug support
 * use "modprobe debug=x" where x is bitfield of USB_DBG & ISDN_DBG
@@ -63,81 +59,89 @@ module_param(debug, uint, 0);
 static int hfc_debug;
 #endif
 
+/* private vendor specific data */
+typedef struct {
+       __u8 led_scheme;        // led display scheme
+       signed short led_bits[8];       // array of 8 possible LED bitmask settings
+       char *vend_name;        // device name
+} hfcsusb_vdata;
 
 /****************************************/
 /* data defining the devices to be used */
 /****************************************/
-static struct usb_device_id hfc_usb_idtab[] = {
-       {USB_DEVICE(0x0959, 0x2bd0)},   /* Colognechip USB eval TA */
-       {USB_DEVICE(0x0675, 0x1688)},   /* DrayTek miniVigor 128 USB ISDN TA */
-       {USB_DEVICE(0x07b0, 0x0007)},   /* Billion USB TA 2 */
-       {USB_DEVICE(0x0742, 0x2008)},   /* Stollmann USB TA */
-       {USB_DEVICE(0x0742, 0x2009)},   /* Aceex USB ISDN TA */
-       {USB_DEVICE(0x0742, 0x200A)},   /* OEM USB ISDN TA */
-       {USB_DEVICE(0x08e3, 0x0301)},   /* OliTec ISDN USB */
-       {USB_DEVICE(0x07fa, 0x0846)},   /* Bewan ISDN USB TA */
-       {USB_DEVICE(0x07fa, 0x0847)},   /* Djinn Numeris USB */
-       {USB_DEVICE(0x07b0, 0x0006)},   /* Twister ISDN USB TA */
-       {}                      /* end with an all-zeroes entry */
+static struct usb_device_id hfcusb_idtab[] = {
+       {
+        .idVendor = 0x0959,
+        .idProduct = 0x2bd0,
+        .driver_info = (unsigned long) &((hfcsusb_vdata)
+                         {LED_OFF, {4, 0, 2, 1},
+                          "ISDN USB TA (Cologne Chip HFC-S USB based)"}),
+       },
+       {
+        .idVendor = 0x0675,
+        .idProduct = 0x1688,
+        .driver_info = (unsigned long) &((hfcsusb_vdata)
+                         {LED_SCHEME1, {1, 2, 0, 0},
+                          "DrayTek miniVigor 128 USB ISDN TA"}),
+       },
+       {
+        .idVendor = 0x07b0,
+        .idProduct = 0x0007,
+        .driver_info = (unsigned long) &((hfcsusb_vdata)
+                         {LED_SCHEME1, {0x80, -64, -32, -16},
+                          "Billion tiny USB ISDN TA 128"}),
+       },
+       {
+        .idVendor = 0x0742,
+        .idProduct = 0x2008,
+        .driver_info = (unsigned long) &((hfcsusb_vdata)
+                         {LED_SCHEME1, {4, 0, 2, 1},
+                          "Stollmann USB TA"}),
+        },
+       {
+        .idVendor = 0x0742,
+        .idProduct = 0x2009,
+        .driver_info = (unsigned long) &((hfcsusb_vdata)
+                         {LED_SCHEME1, {4, 0, 2, 1},
+                          "Aceex USB ISDN TA"}),
+        },
+       {
+        .idVendor = 0x0742,
+        .idProduct = 0x200A,
+        .driver_info = (unsigned long) &((hfcsusb_vdata)
+                         {LED_SCHEME1, {4, 0, 2, 1},
+                          "OEM USB ISDN TA"}),
+        },
+       {
+        .idVendor = 0x08e3,
+        .idProduct = 0x0301,
+        .driver_info = (unsigned long) &((hfcsusb_vdata)
+                         {LED_SCHEME1, {2, 0, 1, 4},
+                          "Olitec USB RNIS"}),
+        },
+       {
+        .idVendor = 0x07fa,
+        .idProduct = 0x0846,
+        .driver_info = (unsigned long) &((hfcsusb_vdata)
+                         {LED_SCHEME1, {0x80, -64, -32, -16},
+                          "Bewan Modem RNIS USB"}),
+        },
+       {
+        .idVendor = 0x07fa,
+        .idProduct = 0x0847,
+        .driver_info = (unsigned long) &((hfcsusb_vdata)
+                         {LED_SCHEME1, {0x80, -64, -32, -16},
+                          "Djinn Numeris USB"}),
+        },
+       {
+        .idVendor = 0x07b0,
+        .idProduct = 0x0006,
+        .driver_info = (unsigned long) &((hfcsusb_vdata)
+                         {LED_SCHEME1, {0x80, -64, -32, -16},
+                          "Twister ISDN TA"}),
+        },
 };
 
-/* driver internal device specific data:
-*   VendorID, ProductID, Devicename, LED_SCHEME,
-*   LED's BitMask in HFCUSB_P_DATA Register : LED_USB, LED_S0, LED_B1, LED_B2
-*/
-static vendor_data vdata[] = {
-       /* CologneChip Eval TA */
-       {0x0959, 0x2bd0, "ISDN USB TA (Cologne Chip HFC-S USB based)",
-        LED_OFF, {4, 0, 2, 1}
-        }
-       ,
-       /* DrayTek miniVigor 128 USB ISDN TA */
-       {0x0675, 0x1688, "DrayTek miniVigor 128 USB ISDN TA",
-        LED_SCHEME1, {1, 2, 0, 0}
-        }
-       ,
-       /* Billion TA */
-       {0x07b0, 0x0007, "Billion tiny USB ISDN TA 128",
-        LED_SCHEME1, {0x80, -64, -32, -16}
-        }
-       ,
-       /* Stollmann TA */
-       {0x0742, 0x2008, "Stollmann USB TA",
-        LED_SCHEME1, {4, 0, 2, 1}
-        }
-       ,
-       /* Aceex USB ISDN TA */
-       {0x0742, 0x2009, "Aceex USB ISDN TA",
-        LED_SCHEME1, {4, 0, 2, 1}
-        }
-       ,
-       /* OEM USB ISDN TA */
-       {0x0742, 0x200A, "OEM USB ISDN TA",
-        LED_SCHEME1, {4, 0, 2, 1}
-        }
-       ,
-       /* Olitec TA  */
-       {0x08e3, 0x0301, "Olitec USB RNIS",
-        LED_SCHEME1, {2, 0, 1, 4}
-        }
-       ,
-       /* Bewan TA   */
-       {0x07fa, 0x0846, "Bewan Modem RNIS USB",
-        LED_SCHEME1, {0x80, -64, -32, -16}
-        }
-       ,
-       /* Bewan TA   */
-       {0x07fa, 0x0847, "Djinn Numeris USB",
-        LED_SCHEME1, {0x80, -64, -32, -16}
-        }
-       ,
-       /* Twister ISDN TA   */
-       {0x07b0, 0x0006, "Twister ISDN TA",
-        LED_SCHEME1, {0x80, -64, -32, -16}
-        }
-       ,
-       {0, 0, 0}               /* EOL element */
-};
 
 /***************************************************************/
 /* structure defining input+output fifos (interrupt/bulk mode) */
@@ -211,8 +215,6 @@ typedef struct hfcusb_data {
        volatile __u8 l1_state; /* actual l1 state */
        struct timer_list t3_timer;     /* timer 3 for activation/deactivation */
        struct timer_list t4_timer;     /* timer 4 for activation/deactivation */
-       struct timer_list led_timer;    /* timer flashing leds */
-
 } hfcusb_data;
 
 
@@ -227,7 +229,7 @@ symbolic(struct hfcusb_symbolic_list list[], const int num)
        for (i = 0; list[i].name != NULL; i++)
                if (list[i].num == num)
                        return (list[i].name);
-       return "<unkown>";
+       return "<unkown ERROR>";
 }
 
 
@@ -335,93 +337,57 @@ set_led_bit(hfcusb_data * hfc, signed short led_bits, int unset)
        }
 }
 
-/******************************************/
-/* invert B-channel LEDs if data is sent  */
-/******************************************/
-static void
-led_timer(hfcusb_data * hfc)
-{
-       static int cnt = 0;
-
-       if (cnt) {
-               if (hfc->led_b_active & 1)
-                       set_led_bit(hfc, vdata[hfc->vend_idx].led_bits[2],
-                                   0);
-               if (hfc->led_b_active & 2)
-                       set_led_bit(hfc, vdata[hfc->vend_idx].led_bits[3],
-                                   0);
-       } else {
-               if (!(hfc->led_b_active & 1) || hfc->led_new_data & 1)
-                       set_led_bit(hfc, vdata[hfc->vend_idx].led_bits[2],
-                                   1);
-               if (!(hfc->led_b_active & 2) || hfc->led_new_data & 2)
-                       set_led_bit(hfc, vdata[hfc->vend_idx].led_bits[3],
-                                   1);
-       }
-
-       write_led(hfc, hfc->led_state);
-       hfc->led_new_data = 0;
-
-       cnt = !cnt;
-
-       /* restart 4 hz timer */
-       if (!timer_pending(&hfc->led_timer)) {
-               add_timer(&hfc->led_timer);
-               hfc->led_timer.expires = jiffies + (LED_TIME * HZ) / 1000;
-       }
-}
-
 /**************************/
 /* handle LED requests    */
 /**************************/
 static void
 handle_led(hfcusb_data * hfc, int event)
 {
+       hfcsusb_vdata *driver_info =
+           (hfcsusb_vdata *) hfcusb_idtab[hfc->vend_idx].driver_info;
+
        /* if no scheme -> no LED action */
-       if (vdata[hfc->vend_idx].led_scheme == LED_OFF)
+       if (driver_info->led_scheme == LED_OFF)
                return;
 
        switch (event) {
                case LED_POWER_ON:
-                       set_led_bit(hfc, vdata[hfc->vend_idx].led_bits[0],
+                       set_led_bit(hfc, driver_info->led_bits[0],
                                    0);
-                       set_led_bit(hfc, vdata[hfc->vend_idx].led_bits[1],
+                       set_led_bit(hfc, driver_info->led_bits[1],
                                    1);
-                       set_led_bit(hfc, vdata[hfc->vend_idx].led_bits[2],
+                       set_led_bit(hfc, driver_info->led_bits[2],
                                    1);
-                       set_led_bit(hfc, vdata[hfc->vend_idx].led_bits[3],
+                       set_led_bit(hfc, driver_info->led_bits[3],
                                    1);
                        break;
                case LED_POWER_OFF:     /* no Power off handling */
                        break;
                case LED_S0_ON:
-                       set_led_bit(hfc, vdata[hfc->vend_idx].led_bits[1],
+                       set_led_bit(hfc, driver_info->led_bits[1],
                                    0);
                        break;
                case LED_S0_OFF:
-                       set_led_bit(hfc, vdata[hfc->vend_idx].led_bits[1],
+                       set_led_bit(hfc, driver_info->led_bits[1],
                                    1);
                        break;
                case LED_B1_ON:
-                       hfc->led_b_active |= 1;
+                       set_led_bit(hfc, driver_info->led_bits[2],
+                                   0);
                        break;
                case LED_B1_OFF:
-                       hfc->led_b_active &= ~1;
-                       break;
-               case LED_B1_DATA:
-                       hfc->led_new_data |= 1;
+                       set_led_bit(hfc, driver_info->led_bits[2],
+                                   1);
                        break;
                case LED_B2_ON:
-                       hfc->led_b_active |= 2;
+                       set_led_bit(hfc, driver_info->led_bits[3],
+                                   0);
                        break;
                case LED_B2_OFF:
-                       hfc->led_b_active &= ~2;
-                       break;
-               case LED_B2_DATA:
-                       hfc->led_new_data |= 2;
+                       set_led_bit(hfc, driver_info->led_bits[3],
+                                   1);
                        break;
        }
-
        write_led(hfc, hfc->led_state);
 }
 
@@ -725,14 +691,6 @@ tx_iso_complete(struct urb *urb, struct pt_regs *regs)
                                    current_len + 1;
 
                                tx_offset += (current_len + 1);
-                               if (!transp_mode) {
-                                       if (fifon == HFCUSB_B1_TX)
-                                               handle_led(hfc,
-                                                          LED_B1_DATA);
-                                       if (fifon == HFCUSB_B2_TX)
-                                               handle_led(hfc,
-                                                          LED_B2_DATA);
-                               }
                        } else {
                                urb->iso_frame_desc[k].offset =
                                    tx_offset++;
@@ -966,14 +924,6 @@ collect_rx_frame(usb_fifo * fifo, __u8 * data, int len, int finish)
                        skb_trim(fifo->skbuff, 0);
                }
        }
-
-       /* LED flashing only in HDLC mode */
-       if (!transp_mode) {
-               if (fifon == HFCUSB_B1_RX)
-                       handle_led(hfc, LED_B1_DATA);
-               if (fifon == HFCUSB_B2_RX)
-                       handle_led(hfc, LED_B2_DATA);
-       }
 }
 
 /***********************************************/
@@ -1339,17 +1289,6 @@ usb_init(hfcusb_data * hfc)
        hfc->t4_timer.data = (long) hfc;
        hfc->t4_timer.function = (void *) l1_timer_expire_t4;
 
-       /* init the led timer */
-       init_timer(&hfc->led_timer);
-       hfc->led_timer.data = (long) hfc;
-       hfc->led_timer.function = (void *) led_timer;
-
-       /* trigger 4 hz led timer */
-       if (!timer_pending(&hfc->led_timer)) {
-               hfc->led_timer.expires = jiffies + (LED_TIME * HZ) / 1000;
-               add_timer(&hfc->led_timer);
-       }
-
        /* init the background machinery for control requests */
        hfc->ctrl_read.bRequestType = 0xc0;
        hfc->ctrl_read.bRequest = 1;
@@ -1440,13 +1379,18 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
            attr, cfg_found, cidx, ep_addr;
        int cmptbl[16], small_match, iso_packet_size, packet_size,
            alt_used = 0;
+       hfcsusb_vdata *driver_info;
 
        vend_idx = 0xffff;
-       for (i = 0; vdata[i].vendor; i++) {
-               if (dev->descriptor.idVendor == vdata[i].vendor
-                   && dev->descriptor.idProduct == vdata[i].prod_id)
+       for (i = 0; hfcusb_idtab[i].idVendor; i++) {
+               if (dev->descriptor.idVendor == hfcusb_idtab[i].idVendor
+                   && dev->descriptor.idProduct ==
+                   hfcusb_idtab[i].idProduct) {
                        vend_idx = i;
+                       continue;
+               }
        }
+
 #ifdef CONFIG_HISAX_DEBUG
        DBG(USB_DBG,
            "HFC-USB: probing interface(%d) actalt(%d) minor(%d)\n", ifnum,
@@ -1457,10 +1401,6 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
               ifnum, iface->desc.bAlternateSetting, intf->minor);
 
        if (vend_idx != 0xffff) {
-#ifdef CONFIG_HISAX_DEBUG
-               DBG(USB_DBG, "HFC-S USB: found vendor idx:%d  name:%s",
-                   vend_idx, vdata[vend_idx].vend_name);
-#endif
                /* if vendor and product ID is OK, start probing alternate settings */
                alt_idx = 0;
                small_match = 0xffff;
@@ -1687,9 +1627,11 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
                            usb_sndctrlpipe(context->dev, 0);
                        context->ctrl_urb = usb_alloc_urb(0, GFP_KERNEL);
 
-                       printk(KERN_INFO
-                              "HFC-S USB: detected \"%s\"\n",
-                              vdata[vend_idx].vend_name);
+                       driver_info =
+                           (hfcsusb_vdata *) hfcusb_idtab[vend_idx].
+                           driver_info;
+                       printk(KERN_INFO "HFC-S USB: detected \"%s\"\n",
+                              driver_info->vend_name);
 #ifdef CONFIG_HISAX_DEBUG
                        DBG(USB_DBG,
                            "HFC-S USB: Endpoint-Config: %s (if=%d alt=%d)\n",
@@ -1740,8 +1682,6 @@ hfc_usb_disconnect(struct usb_interface
                del_timer(&context->t3_timer);
        if (timer_pending(&context->t4_timer))
                del_timer(&context->t4_timer);
-       if (timer_pending(&context->led_timer))
-               del_timer(&context->led_timer);
        /* tell all fifos to terminate */
        for (i = 0; i < HFCUSB_NUM_FIFOS; i++) {
                if (context->fifos[i].usb_transfer_mode == USB_ISOC) {
@@ -1785,9 +1725,11 @@ hfc_usb_disconnect(struct usb_interface
 /* our driver information structure */
 /************************************/
 static struct usb_driver hfc_drv = {
-       .owner = THIS_MODULE,.name =
-           "hfc_usb",.id_table = hfc_usb_idtab,.probe =
-           hfc_usb_probe,.disconnect = hfc_usb_disconnect,
+       .owner = THIS_MODULE,
+       .name  = "hfc_usb",
+       .id_table = hfcusb_idtab,
+       .probe = hfc_usb_probe,
+       .disconnect = hfc_usb_disconnect,
 };
 static void __exit
 hfc_usb_exit(void)
@@ -1825,4 +1767,4 @@ module_exit(hfc_usb_exit);
 MODULE_AUTHOR(DRIVER_AUTHOR);
 MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_LICENSE("GPL");
-MODULE_DEVICE_TABLE(usb, hfc_usb_idtab);
+MODULE_DEVICE_TABLE(usb, hfcusb_idtab);
index 280dd29b30d6fbd0efaaf0f715a15637ab759b49..ec52c1a7c22afca97308f353e139eead2dd2b33a 100644 (file)
@@ -1,7 +1,7 @@
 /*
 * hfc_usb.h
 *
-* $Id: hfc_usb.h,v 4.1 2005/01/26 17:25:53 martinb1 Exp $
+* $Id: hfc_usb.h,v 4.2 2005/04/07 15:27:17 martinb1 Exp $
 */
 
 #ifndef __HFC_USB_H__
@@ -91,7 +91,7 @@
 /**********/
 /* macros */
 /**********/
-#define write_usb(a,b,c)usb_control_msg((a)->dev,(a)->ctrl_out_pipe,0,0x40,(c),(b),0,0,HFC_CTRL_TIMEOUT)
+#define write_usb(a,b,c)usb_control_msg((a)->dev,(a)->ctrl_out_pipe,0,0x40,(c),(b),NULL,0,HFC_CTRL_TIMEOUT)
 #define read_usb(a,b,c) usb_control_msg((a)->dev,(a)->ctrl_in_pipe,1,0xC0,0,(b),(c),1,HFC_CTRL_TIMEOUT)
 
 
@@ -186,6 +186,7 @@ static int validconf[][19] = {
        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}        // EOL element
 };
 
+#ifdef CONFIG_HISAX_DEBUG
 // string description of chosen config
 static char *conf_str[] = {
        "4 Interrupt IN + 3 Isochron OUT",
@@ -193,6 +194,7 @@ static char *conf_str[] = {
        "4 Isochron IN + 3 Isochron OUT",
        "3 Isochron IN + 3 Isochron OUT"
 };
+#endif
 
 
 typedef struct {
index 66dbaee77bfbd005ecd5db41b32e4cd459bec8c3..c8f9951f7914a4c8d1e387544c3d5bbab4a1cd8f 100644 (file)
@@ -156,14 +156,10 @@ close_hscxstate(struct BCState *bcs)
 {
        modehscx(bcs, 0, bcs->channel);
        if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) {
-               if (bcs->hw.hscx.rcvbuf) {
-                       kfree(bcs->hw.hscx.rcvbuf);
-                       bcs->hw.hscx.rcvbuf = NULL;
-               }
-               if (bcs->blog) {
-                       kfree(bcs->blog);
-                       bcs->blog = NULL;
-               }
+               kfree(bcs->hw.hscx.rcvbuf);
+               bcs->hw.hscx.rcvbuf = NULL;
+               kfree(bcs->blog);
+               bcs->blog = NULL;
                skb_queue_purge(&bcs->rqueue);
                skb_queue_purge(&bcs->squeue);
                if (bcs->tx_skb) {
index b4ca5859b1777cb1e99f88f7fb95714644a845ee..c615752b96aa21b3fb55db5be71e4df42963b3d9 100644 (file)
@@ -571,14 +571,10 @@ setstack_icc(struct PStack *st, struct IsdnCardState *cs)
 
 static void
 DC_Close_icc(struct IsdnCardState *cs) {
-       if (cs->dc.icc.mon_rx) {
-               kfree(cs->dc.icc.mon_rx);
-               cs->dc.icc.mon_rx = NULL;
-       }
-       if (cs->dc.icc.mon_tx) {
-               kfree(cs->dc.icc.mon_tx);
-               cs->dc.icc.mon_tx = NULL;
-       }
+       kfree(cs->dc.icc.mon_rx);
+       cs->dc.icc.mon_rx = NULL;
+       kfree(cs->dc.icc.mon_tx);
+       cs->dc.icc.mon_tx = NULL;
 }
 
 static void
index efba2f44801797f726f30c6033b14dfc3d65611a..2e9afae1254a1a42731936e7e68ef6e1d95cda8a 100644 (file)
@@ -762,14 +762,10 @@ bch_close_state(struct BCState *bcs)
 {
        bch_mode(bcs, 0, bcs->channel);
        if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) {
-               if (bcs->hw.hscx.rcvbuf) {
-                       kfree(bcs->hw.hscx.rcvbuf);
-                       bcs->hw.hscx.rcvbuf = NULL;
-               }
-               if (bcs->blog) {
-                       kfree(bcs->blog);
-                       bcs->blog = NULL;
-               }
+               kfree(bcs->hw.hscx.rcvbuf);
+               bcs->hw.hscx.rcvbuf = NULL;
+               kfree(bcs->blog);
+               bcs->blog = NULL;
                skb_queue_purge(&bcs->rqueue);
                skb_queue_purge(&bcs->squeue);
                if (bcs->tx_skb) {
index 85e063a08d23e3410215e8c519a729b59a5352de..565b7892c2672780dc31d773e8d5a492b37a6229 100644 (file)
@@ -570,15 +570,12 @@ setstack_isac(struct PStack *st, struct IsdnCardState *cs)
 }
 
 static void
-DC_Close_isac(struct IsdnCardState *cs) {
-       if (cs->dc.isac.mon_rx) {
-               kfree(cs->dc.isac.mon_rx);
-               cs->dc.isac.mon_rx = NULL;
-       }
-       if (cs->dc.isac.mon_tx) {
-               kfree(cs->dc.isac.mon_tx);
-               cs->dc.isac.mon_tx = NULL;
-       }
+DC_Close_isac(struct IsdnCardState *cs)
+{
+       kfree(cs->dc.isac.mon_rx);
+       cs->dc.isac.mon_rx = NULL;
+       kfree(cs->dc.isac.mon_tx);
+       cs->dc.isac.mon_tx = NULL;
 }
 
 static void
index 642a87c51295c70055509678fa71a370a766f9f2..674af673ff965e9bb48b8e7c2ac9b4452e1607e5 100644 (file)
@@ -1688,10 +1688,8 @@ close_isarstate(struct BCState *bcs)
 {
        modeisar(bcs, 0, bcs->channel);
        if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) {
-               if (bcs->hw.isar.rcvbuf) {
-                       kfree(bcs->hw.isar.rcvbuf);
-                       bcs->hw.isar.rcvbuf = NULL;
-               }
+               kfree(bcs->hw.isar.rcvbuf);
+               bcs->hw.isar.rcvbuf = NULL;
                skb_queue_purge(&bcs->rqueue);
                skb_queue_purge(&bcs->squeue);
                if (bcs->tx_skb) {
index 363ae3179bbde9a255148c56c5e90a5e6d0eaf81..2659fecc26747a470ef2f099c1a98aab84dd23a0 100644 (file)
@@ -195,14 +195,10 @@ close_jadestate(struct BCState *bcs)
 {
     modejade(bcs, 0, bcs->channel);
     if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) {
-       if (bcs->hw.hscx.rcvbuf) {
-               kfree(bcs->hw.hscx.rcvbuf);
-               bcs->hw.hscx.rcvbuf = NULL;
-       }
-       if (bcs->blog) {
-               kfree(bcs->blog);
-               bcs->blog = NULL;
-       }
+       kfree(bcs->hw.hscx.rcvbuf);
+       bcs->hw.hscx.rcvbuf = NULL;
+       kfree(bcs->blog);
+       bcs->blog = NULL;
        skb_queue_purge(&bcs->rqueue);
        skb_queue_purge(&bcs->squeue);
        if (bcs->tx_skb) {
index 94da03c30c51507c1af9c74d449e04930a4a3c52..47a47ef0968bf3d0abaf612fdfd58598187b94c8 100644 (file)
@@ -855,14 +855,10 @@ close_tigerstate(struct BCState *bcs)
 {
        mode_tiger(bcs, 0, bcs->channel);
        if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) {
-               if (bcs->hw.tiger.rcvbuf) {
-                       kfree(bcs->hw.tiger.rcvbuf);
-                       bcs->hw.tiger.rcvbuf = NULL;
-               }
-               if (bcs->hw.tiger.sendbuf) {
-                       kfree(bcs->hw.tiger.sendbuf);
-                       bcs->hw.tiger.sendbuf = NULL;
-               }
+               kfree(bcs->hw.tiger.rcvbuf);
+               bcs->hw.tiger.rcvbuf = NULL;
+               kfree(bcs->hw.tiger.sendbuf);
+               bcs->hw.tiger.sendbuf = NULL;
                skb_queue_purge(&bcs->rqueue);
                skb_queue_purge(&bcs->squeue);
                if (bcs->tx_skb) {
@@ -967,20 +963,12 @@ inittiger(struct IsdnCardState *cs)
 static void
 releasetiger(struct IsdnCardState *cs)
 {
-       if (cs->bcs[0].hw.tiger.send) {
-               kfree(cs->bcs[0].hw.tiger.send);
-               cs->bcs[0].hw.tiger.send = NULL;
-       }
-       if (cs->bcs[1].hw.tiger.send) {
-               cs->bcs[1].hw.tiger.send = NULL;
-       }
-       if (cs->bcs[0].hw.tiger.rec) {
-               kfree(cs->bcs[0].hw.tiger.rec);
-               cs->bcs[0].hw.tiger.rec = NULL;
-       }
-       if (cs->bcs[1].hw.tiger.rec) {
-               cs->bcs[1].hw.tiger.rec = NULL;
-       }
+       kfree(cs->bcs[0].hw.tiger.send);
+       cs->bcs[0].hw.tiger.send = NULL;
+       cs->bcs[1].hw.tiger.send = NULL;
+       kfree(cs->bcs[0].hw.tiger.rec);
+       cs->bcs[0].hw.tiger.rec = NULL;
+       cs->bcs[1].hw.tiger.rec = NULL;
 }
 
 void
index 89fbeb58485de92d158631bf69822d314176a9c4..b096b64b0253cd2e95806356d698d128af5b2b2b 100644 (file)
@@ -335,14 +335,12 @@ void st5481_release_usb(struct st5481_adapter *adapter)
 
        // Stop and free Control and Interrupt URBs
        usb_kill_urb(ctrl->urb);
-       if (ctrl->urb->transfer_buffer)
-               kfree(ctrl->urb->transfer_buffer);
+       kfree(ctrl->urb->transfer_buffer);
        usb_free_urb(ctrl->urb);
        ctrl->urb = NULL;
 
        usb_kill_urb(intr->urb);
-       if (intr->urb->transfer_buffer)
-               kfree(intr->urb->transfer_buffer);
+       kfree(intr->urb->transfer_buffer);
        usb_free_urb(intr->urb);
        ctrl->urb = NULL;
 }
@@ -457,8 +455,7 @@ st5481_setup_isocpipes(struct urb* urb[2], struct usb_device *dev,
  err:
        for (j = 0; j < 2; j++) {
                if (urb[j]) {
-                       if (urb[j]->transfer_buffer)
-                               kfree(urb[j]->transfer_buffer);
+                       kfree(urb[j]->transfer_buffer);
                        urb[j]->transfer_buffer = NULL;
                        usb_free_urb(urb[j]);
                        urb[j] = NULL;
@@ -473,8 +470,7 @@ void st5481_release_isocpipes(struct urb* urb[2])
 
        for (j = 0; j < 2; j++) {
                usb_kill_urb(urb[j]);
-               if (urb[j]->transfer_buffer)
-                       kfree(urb[j]->transfer_buffer);                 
+               kfree(urb[j]->transfer_buffer);
                usb_free_urb(urb[j]);
                urb[j] = NULL;
        }
index 7baf8e4884716080266b3eb3df37a7d41152da41..0352ee5f706ca904244839b102edb84746ca580a 100644 (file)
@@ -819,14 +819,10 @@ close_w6692state(struct BCState *bcs)
 {
        W6692Bmode(bcs, 0, bcs->channel);
        if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) {
-               if (bcs->hw.w6692.rcvbuf) {
-                       kfree(bcs->hw.w6692.rcvbuf);
-                       bcs->hw.w6692.rcvbuf = NULL;
-               }
-               if (bcs->blog) {
-                       kfree(bcs->blog);
-                       bcs->blog = NULL;
-               }
+               kfree(bcs->hw.w6692.rcvbuf);
+               bcs->hw.w6692.rcvbuf = NULL;
+               kfree(bcs->blog);
+               bcs->blog = NULL;
                skb_queue_purge(&bcs->rqueue);
                skb_queue_purge(&bcs->squeue);
                if (bcs->tx_skb) {
index 639582f61f41e416e98dbb493a70a9a3d1f7df15..87f59a0e2a959cbabd23ded727e53949dc49eb75 100644 (file)
@@ -359,8 +359,7 @@ hysdn_conf_close(struct inode *ino, struct file *filep)
        } else if ((filep->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ) {
                /* read access -> output card info data */
 
-               if (filep->private_data)
-                       kfree(filep->private_data);     /* release memory */
+               kfree(filep->private_data);     /* release memory */
        }
        unlock_kernel();
        return (retval);
index d97a9be5469c45deb6f8d5965a3a84125c446314..1a19a0f894288907c30ea2fbb91790db3d67a584 100644 (file)
@@ -364,10 +364,8 @@ isdn_ppp_release(int min, struct file *file)
                isdn_net_hangup(&p->dev);
        }
        for (i = 0; i < NUM_RCV_BUFFS; i++) {
-               if (is->rq[i].buf) {
-                       kfree(is->rq[i].buf);
-                       is->rq[i].buf = NULL;
-               }
+               kfree(is->rq[i].buf);
+               is->rq[i].buf = NULL;
        }
        is->first = is->rq + NUM_RCV_BUFFS - 1; /* receive queue */
        is->last = is->rq;
@@ -378,14 +376,10 @@ isdn_ppp_release(int min, struct file *file)
        is->slcomp = NULL;
 #endif
 #ifdef CONFIG_IPPP_FILTER
-       if (is->pass_filter) {
-               kfree(is->pass_filter);
-               is->pass_filter = NULL;
-       }
-       if (is->active_filter) {
-               kfree(is->active_filter);
-               is->active_filter = NULL;
-       }
+       kfree(is->pass_filter);
+       is->pass_filter = NULL;
+       kfree(is->active_filter);
+       is->active_filter = NULL;
 #endif
 
 /* TODO: if this was the previous master: link the stuff to the new master */
@@ -914,8 +908,7 @@ isdn_ppp_cleanup(void)
                kfree(ippp_table[i]);
 
 #ifdef CONFIG_ISDN_MPP
-       if (isdn_ppp_bundle_arr)
-               kfree(isdn_ppp_bundle_arr);
+       kfree(isdn_ppp_bundle_arr);
 #endif /* CONFIG_ISDN_MPP */
 
 }
index b37ef1f06b3dffa55e36c313f7dd7238a1b6ceb0..8c404b4e2482d4769a263514faa9b68eb05ca4e6 100644 (file)
@@ -712,22 +712,14 @@ isdn_tty_modem_hup(modem_info * info, int local)
 #endif
        info->emu.vpar[4] = 0;
        info->emu.vpar[5] = 8;
-       if (info->dtmf_state) {
-               kfree(info->dtmf_state);
-               info->dtmf_state = NULL;
-       }
-       if (info->silence_state) {
-               kfree(info->silence_state);
-               info->silence_state = NULL;
-       }
-       if (info->adpcms) {
-               kfree(info->adpcms);
-               info->adpcms = NULL;
-       }
-       if (info->adpcmr) {
-               kfree(info->adpcmr);
-               info->adpcmr = NULL;
-       }
+       kfree(info->dtmf_state);
+       info->dtmf_state = NULL;
+       kfree(info->silence_state);
+       info->silence_state = NULL;
+       kfree(info->adpcms);
+       info->adpcms = NULL;
+       kfree(info->adpcmr);
+       info->adpcmr = NULL;
 #endif
        if ((info->msr & UART_MSR_RI) &&
                (info->emu.mdmreg[REG_RUNG] & BIT_RUNG))
@@ -1721,8 +1713,7 @@ isdn_tty_close(struct tty_struct *tty, struct file *filp)
                 */
                timeout = jiffies + HZ;
                while (!(info->lsr & UART_LSR_TEMT)) {
-                       set_current_state(TASK_INTERRUPTIBLE);
-                       schedule_timeout(20);
+                       schedule_timeout_interruptible(20);
                        if (time_after(jiffies,timeout))
                                break;
                }
index 386df71eee7473f0c7582c26331bdee63c623b68..6649f8bc99512247cdbfb6142dbfcce40f0669b0 100644 (file)
@@ -947,8 +947,7 @@ icn_loadproto(u_char __user * buffer, icn_card * card)
                                icn_maprelease_channel(card, 0);
                                return -EIO;
                        }
-                       set_current_state(TASK_INTERRUPTIBLE);
-                       schedule_timeout(10);
+                       schedule_timeout_interruptible(10);
                }
        }
        writeb(0x20, &sbuf_n);
index 14e1f8fbc61f05643dd4abcf3f4ee1ba4261981a..33d33970041173e54fe52cd25f21fe7e5275abf3 100644 (file)
@@ -1161,12 +1161,9 @@ isdnloop_command(isdn_ctrl * c, isdnloop_card * card)
                                        if (a) {
                                                if (!card->leased) {
                                                        card->leased = 1;
-                                                       while (card->ptype == ISDN_PTYPE_UNKNOWN) {
-                                                               set_current_state(TASK_INTERRUPTIBLE);
-                                                               schedule_timeout(10);
-                                                       }
-                                                       set_current_state(TASK_INTERRUPTIBLE);
-                                                       schedule_timeout(10);
+                                                       while (card->ptype == ISDN_PTYPE_UNKNOWN)
+                                                               schedule_timeout_interruptible(10);
+                                                       schedule_timeout_interruptible(10);
                                                        sprintf(cbuf, "00;FV2ON\n01;EAZ1\n02;EAZ2\n");
                                                        i = isdnloop_writecmd(cbuf, strlen(cbuf), 0, card);
                                                        printk(KERN_INFO
index 5de861f4081605ec66d0c375291dda166c8bae80..94f21486bb24d667b4c22b29e2c507e30262919b 100644 (file)
@@ -561,10 +561,8 @@ void pcbit_l3_receive(struct pcbit_dev * dev, ulong msg,
                else
                        pcbit_fsm_event(dev, chan, EV_USR_RELEASE_REQ, NULL);
 
-               if (cbdata.data.setup.CalledPN)
-                       kfree(cbdata.data.setup.CalledPN);
-               if (cbdata.data.setup.CallingPN)
-                       kfree(cbdata.data.setup.CallingPN);
+               kfree(cbdata.data.setup.CalledPN);
+               kfree(cbdata.data.setup.CallingPN);
                break;
     
        case MSG_CONN_CONF:
index 1ebed041672d0c3876c892c515e218997a58f38a..62b7acfad8a4fcd289b05735d1f51a21790c658e 100644 (file)
@@ -529,8 +529,7 @@ static int identify_board(unsigned long rambase, unsigned int iobase)
         */
        x = 0;
        while((inb(iobase + FIFOSTAT_OFFSET) & RF_HAS_DATA) && x < 100) {
-               set_current_state(TASK_INTERRUPTIBLE);
-               schedule_timeout(1);
+               schedule_timeout_interruptible(1);
                x++;
        }
        if(x == 100) {
index ca204da3257d3918ae150c30d8b08a2e92bd35db..0a0fe6b8039bbe8cea80b815a1526799c31c8376 100644 (file)
@@ -208,8 +208,7 @@ int send_and_receive(int card,
        tries = 0;
        /* wait for the response */
        while (tries < timeout) {
-               set_current_state(TASK_INTERRUPTIBLE);
-               schedule_timeout(1);
+               schedule_timeout_interruptible(1);
                
                pr_debug("SAR waiting..\n");
 
index 8f02c155fdc0e26693ce5babe3abe1b5e14221be..c0b46bceb5df88709348e4e6e4bdc68ec93499ed 100644 (file)
@@ -857,8 +857,7 @@ adbhid_input_register(int id, int default_id, int original_handler_id,
 static void adbhid_input_unregister(int id)
 {
        input_unregister_device(adbhid[id]->input);
-       if (adbhid[id]->keycode)
-               kfree(adbhid[id]->keycode);
+       kfree(adbhid[id]->keycode);
        kfree(adbhid[id]);
        adbhid[id] = NULL;
 }
index cc507ceef15388175917ef3852c504731dd66c24..3fc8cdd94c3daa9b4154b8d721b381bb0eb09797 100644 (file)
@@ -1678,10 +1678,9 @@ static int main_control_loop(void *x)
                }
 
                // FIXME: Deal with signals
-               set_current_state(TASK_INTERRUPTIBLE);
                elapsed = jiffies - start;
                if (elapsed < HZ)
-                       schedule_timeout(HZ - elapsed);
+                       schedule_timeout_interruptible(HZ - elapsed);
        }
 
  out:
index 6497295ebfb93150d1cf4087bfca7b60c3e2bf63..1223e98ecd70f538419790c48bfe19f664561480 100644 (file)
@@ -1587,8 +1587,7 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
                /* make sure we don't swamp the stripe cache if someone else
                 * is trying to get access 
                 */
-               set_current_state(TASK_UNINTERRUPTIBLE);
-               schedule_timeout(1);
+               schedule_timeout_uninterruptible(1);
        }
        bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks, 0);
        spin_lock(&sh->lock);   
index 6437a95ffc1cd573da840c4a0c29674973a14efb..7757869477019ea5a87a186b6b46ced5fcb1fcd7 100644 (file)
@@ -1746,8 +1746,7 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
                /* make sure we don't swamp the stripe cache if someone else
                 * is trying to get access
                 */
-               set_current_state(TASK_UNINTERRUPTIBLE);
-               schedule_timeout(1);
+               schedule_timeout_uninterruptible(1);
        }
        bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks, 0);
        spin_lock(&sh->lock);
index 34a837a1abf4f1d5beeef0dd0dec301eba984d87..b3c9d7327ac1d4228a2eecc810bf6e98df75d172 100644 (file)
@@ -1331,9 +1331,7 @@ struct dst_state *dst_attach(struct dst_state *state, struct dvb_adapter *dvb_ad
 {
        /* check if the ASIC is there */
        if (dst_probe(state) < 0) {
-               if (state)
-                       kfree(state);
-
+               kfree(state);
                return NULL;
        }
        /* determine settings based on type */
@@ -1349,9 +1347,7 @@ struct dst_state *dst_attach(struct dst_state *state, struct dvb_adapter *dvb_ad
                break;
        default:
                dprintk(verbose, DST_ERROR, 1, "unknown DST type. please report to the LinuxTV.org DVB mailinglist.");
-               if (state)
-                       kfree(state);
-
+               kfree(state);
                return NULL;
        }
 
index d4b97989e3ed058b93fc926206e110906eb14a7e..654d7dc879d9fbb7e7d7fd9acdf43620215270e4 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/init.h>
+#include <linux/jiffies.h>
 
 #include "dvb_frontend.h"
 #include "cx24110.h"
index 794be520d5902fdad363d1a44486a76d9f5ecafc..645946a992d94b1dda65bf33e14561238ee6329f 100644 (file)
@@ -148,7 +148,7 @@ struct dvb_frontend* dvb_dummy_fe_qpsk_attach()
        return &state->frontend;
 
 error:
-       if (state) kfree(state);
+       kfree(state);
        return NULL;
 }
 
@@ -171,7 +171,7 @@ struct dvb_frontend* dvb_dummy_fe_qam_attach()
        return &state->frontend;
 
 error:
-       if (state) kfree(state);
+       kfree(state);
        return NULL;
 }
 
index faaad1ae85594bbfa4a205c3638baa0c6399e12d..19b4bf7c21a752eed6fa9c390ba803826bb1e59c 100644 (file)
@@ -559,7 +559,8 @@ struct dvb_frontend* l64781_attach(const struct l64781_config* config,
        return &state->frontend;
 
 error:
-       if (reg0x3e >= 0) l64781_writereg (state, 0x3e, reg0x3e);  /* restore reg 0x3e */
+       if (reg0x3e >= 0)
+               l64781_writereg (state, 0x3e, reg0x3e);  /* restore reg 0x3e */
        kfree(state);
        return NULL;
 }
index 8dde72bd10461fb5997cf13e6748e73bfee43535..7852b83b82d44737413cd013ff657b8afc0cfc7c 100644 (file)
@@ -731,8 +731,7 @@ struct dvb_frontend* lgdt330x_attach(const struct lgdt330x_config* config,
        return &state->frontend;
 
 error:
-       if (state)
-               kfree(state);
+       kfree(state);
        dprintk("%s: ERROR\n",__FUNCTION__);
        return NULL;
 }
index e38454901dd12e31d281a9e2ec9d1210534ae43d..9c67f406d581a7d9a7fe7d964bd1786492ad8c9d 100644 (file)
@@ -677,8 +677,7 @@ struct dvb_frontend* mt312_attach(const struct mt312_config* config,
        return &state->frontend;
 
 error:
-       if (state)
-               kfree(state);
+       kfree(state);
        return NULL;
 }
 
index 817b044c7fd1dd992898b6d680d62426d572729f..fc74c40d64777a500ae7748fde5e06bfdb11a7bd 100644 (file)
@@ -577,8 +577,7 @@ struct dvb_frontend* or51132_attach(const struct or51132_config* config,
        return &state->frontend;
 
 error:
-       if (state)
-               kfree(state);
+       kfree(state);
        return NULL;
 }
 
index 87fd3a7bb392cfc9a4bb7b9fc0a01cc79c677f8c..0823ddaf70049a0daa625196da95b80662f49fe0 100644 (file)
@@ -865,10 +865,8 @@ out_dev:
 
 out_irq:
 #endif
-       for (i = 0; i < MAX_AR_HEIGHT; i++) {
-               if (ar->frame[i])
-                       kfree(ar->frame[i]);
-       }
+       for (i = 0; i < MAX_AR_HEIGHT; i++)
+               kfree(ar->frame[i]);
 
 out_line_buff:
 #if USE_INT
@@ -899,10 +897,8 @@ static void __exit ar_cleanup_module(void)
 #if USE_INT
        free_irq(M32R_IRQ_INT3, ar);
 #endif
-       for (i = 0; i < MAX_AR_HEIGHT; i++) {
-               if (ar->frame[i])
-                       kfree(ar->frame[i]);
-       }
+       for (i = 0; i < MAX_AR_HEIGHT; i++)
+               kfree(ar->frame[i]);
 #if USE_INT
        kfree(ar->line_buff);
 #endif
index c062a017491e4bb08bf8c853d265b349ed464c59..d538a994ff04da1d68bcfe9ddc5023671c53d1a8 100644 (file)
@@ -1951,8 +1951,7 @@ static int setup_window(struct bttv_fh *fh, struct bttv *btv,
        }
 
        down(&fh->cap.lock);
-       if (fh->ov.clips)
-               kfree(fh->ov.clips);
+       kfree(fh->ov.clips);
        fh->ov.clips    = clips;
        fh->ov.nclips   = n;
 
@@ -2723,8 +2722,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
                        fh->ov.w.height = fb->fmt.height;
                        btv->init.ov.w.width  = fb->fmt.width;
                        btv->init.ov.w.height = fb->fmt.height;
-                       if (fh->ov.clips)
-                               kfree(fh->ov.clips);
+                       kfree(fh->ov.clips);
                        fh->ov.clips = NULL;
                        fh->ov.nclips = 0;
 
index 262890cb20a7daf55de5d25d6840db40a6eb9dc3..e75e7948fd9d84b32ea51642beadf9c676f6b113 100644 (file)
@@ -741,8 +741,8 @@ static int msp34xx_sleep(struct msp3400c *msp, int timeout)
                        set_current_state(TASK_INTERRUPTIBLE);
                        schedule();
                } else {
-                       set_current_state(TASK_INTERRUPTIBLE);
-                       schedule_timeout(msecs_to_jiffies(timeout));
+                       schedule_timeout_interruptible
+                                               (msecs_to_jiffies(timeout));
                }
        }
 
index badf2f9e3072bf8befeaba2278551ee463903e60..61a2d6b50eef29ad67948a5a04a324fcde367554 100644 (file)
@@ -342,8 +342,8 @@ static int tvaudio_sleep(struct saa7134_dev *dev, int timeout)
                        set_current_state(TASK_INTERRUPTIBLE);
                        schedule();
                } else {
-                       set_current_state(TASK_INTERRUPTIBLE);
-                       schedule_timeout(msecs_to_jiffies(timeout));
+                       schedule_timeout_interruptible
+                                               (msecs_to_jiffies(timeout));
                }
        }
        remove_wait_queue(&dev->thread.wq, &wait);
index 59bb71381a1b19f18877348fee0561a8215efba3..d679ca23ded71aac49e7ea70f229e40137ddd300 100644 (file)
@@ -1006,10 +1006,8 @@ v4l_compat_translate_ioctl(struct inode         *inode,
                break;
        }
 
-       if (cap2)
-               kfree(cap2);
-       if (fmt2)
-               kfree(fmt2);
+       kfree(cap2);
+       kfree(fmt2);
        return err;
 }
 
index c9d5f1a873cc094474033143a8c4937a4dbc7987..839db622040dcdcfe1ff344d7f8846b5c9a7ef53 100644 (file)
@@ -353,8 +353,7 @@ videocodec_build_table (void)
        dprintk(3, "videocodec_build table: %d entries, %d bytes\n", i,
                size);
 
-       if (videocodec_buf)
-               kfree(videocodec_buf);
+       kfree(videocodec_buf);
        videocodec_buf = (char *) kmalloc(size, GFP_KERNEL);
 
        i = 0;
@@ -471,8 +470,7 @@ videocodec_exit (void)
 {
 #ifdef CONFIG_PROC_FS
        remove_proc_entry("videocodecs", NULL);
-       if (videocodec_buf)
-               kfree(videocodec_buf);
+       kfree(videocodec_buf);
 #endif
 }
 
index 06df15f75de94d2fdf34268fd799737e99d7c5d1..83c49f9610d0b0bff75209c556eed46062f01d70 100644 (file)
@@ -215,8 +215,7 @@ video_usercopy(struct inode *inode, struct file *file,
        }
 
 out:
-       if (mbuf)
-               kfree(mbuf);
+       kfree(mbuf);
        return err;
 }
 
index eed2acea17791305a94965ab63020b7f9d41459f..39a0d238900e63f26c34992944b73a441e66b8f4 100644 (file)
@@ -1057,10 +1057,8 @@ zr36057_init (struct zoran *zr)
                        KERN_ERR
                        "%s: zr36057_init() - kmalloc (STAT_COM) failed\n",
                        ZR_DEVNAME(zr));
-               if (vdev)
-                       kfree(vdev);
-               if (mem)
-                       kfree((void *)mem);
+               kfree(vdev);
+               kfree((void *)mem);
                return -ENOMEM;
        }
        memset((void *) mem, 0, mem_needed);
@@ -1105,15 +1103,15 @@ zoran_release (struct zoran *zr)
        /* unregister videocodec bus */
        if (zr->codec) {
                struct videocodec_master *master = zr->codec->master_data;
+
                videocodec_detach(zr->codec);
-               if (master)
-                       kfree(master);
+               kfree(master);
        }
        if (zr->vfe) {
                struct videocodec_master *master = zr->vfe->master_data;
+
                videocodec_detach(zr->vfe);
-               if (master)
-                       kfree(master);
+               kfree(master);
        }
 
        /* unregister i2c bus */
index 53adeb70f2cafb2f7a551ff5e121782f306df329..07bde9acd672cbac58f1973f0b4a3a1697d32907 100644 (file)
@@ -996,8 +996,6 @@ zoran_jpg_queue_frame (struct file          *file,
                return -EINVAL;
        }
 
-       spin_lock_irqsave(&zr->spinlock, flags);
-
        if (fh->jpg_buffers.active == ZORAN_FREE) {
                if (zr->jpg_buffers.active == ZORAN_FREE) {
                        zr->jpg_buffers = fh->jpg_buffers;
@@ -1016,6 +1014,8 @@ zoran_jpg_queue_frame (struct file          *file,
                zr36057_enable_jpg(zr, mode);
        }
 
+       spin_lock_irqsave(&zr->spinlock, flags);
+
        if (!res) {
                switch (zr->jpg_buffers.buffer[num].state) {
                case BUZ_STATE_DONE:
index ed3c891e388f9ee3c73184dc0b445202bb208ab8..014085d8ec85cfd370fb15b4add8f59e0015931b 100644 (file)
@@ -511,7 +511,7 @@ mpt_lan_close(struct net_device *dev)
 {
        struct mpt_lan_priv *priv = netdev_priv(dev);
        MPT_ADAPTER *mpt_dev = priv->mpt_dev;
-       unsigned int timeout;
+       unsigned long timeout;
        int i;
 
        dlprintk((KERN_INFO MYNAM ": mpt_lan_close called\n"));
@@ -526,11 +526,9 @@ mpt_lan_close(struct net_device *dev)
 
        mpt_lan_reset(dev);
 
-       timeout = 2 * HZ;
-       while (atomic_read(&priv->buckets_out) && --timeout) {
-               set_current_state(TASK_INTERRUPTIBLE);
-               schedule_timeout(1);
-       }
+       timeout = jiffies + 2 * HZ;
+       while (atomic_read(&priv->buckets_out) && time_before(jiffies, timeout))
+               schedule_timeout_interruptible(1);
 
        for (i = 0; i < priv->max_buckets_out; i++) {
                if (priv->RcvCtl[i].skb != NULL) {
index 5cb07eb224d71be05a3c39f6db4fb474ec4bf6a7..4330ed0cedaaaafbc2a435b73c1b42b4aadc43d9 100644 (file)
@@ -1013,10 +1013,8 @@ mptscsih_remove(struct pci_dev *pdev)
        spin_lock_irqsave(&dvtaskQ_lock, flags);
        if (dvtaskQ_active) {
                spin_unlock_irqrestore(&dvtaskQ_lock, flags);
-               while(dvtaskQ_active && --count) {
-                       set_current_state(TASK_INTERRUPTIBLE);
-                       schedule_timeout(1);
-               }
+               while(dvtaskQ_active && --count)
+                       schedule_timeout_interruptible(1);
        } else {
                spin_unlock_irqrestore(&dvtaskQ_lock, flags);
        }
index b675b4ebbebdff558521b181d81b4eb2ab59b7c7..9c339a2505b006ed630d315436563733c7831393 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/workqueue.h>
 #include <linux/string.h>
 #include <linux/slab.h>
+#include <linux/sched.h>   /* wait_event_interruptible_timeout() needs this */
 #include <asm/param.h>         /* HZ */
 #include "core.h"
 
index 61b837de4b6a134756e5af4eb0892b9a8c318685..4eb53258842eaef0ad01f68dd3cceee28b96223b 100644 (file)
@@ -93,8 +93,7 @@ u32 i2o_msg_get_wait(struct i2o_controller *c,
                                  c->name);
                        return I2O_QUEUE_EMPTY;
                }
-               set_current_state(TASK_UNINTERRUPTIBLE);
-               schedule_timeout(1);
+               schedule_timeout_uninterruptible(1);
        }
 
        return m;
@@ -485,8 +484,7 @@ static int i2o_iop_init_outbound_queue(struct i2o_controller *c)
                        osm_warn("%s: Timeout Initializing\n", c->name);
                        return -ETIMEDOUT;
                }
-               set_current_state(TASK_UNINTERRUPTIBLE);
-               schedule_timeout(1);
+               schedule_timeout_uninterruptible(1);
        }
 
        m = c->out_queue.phys;
@@ -548,8 +546,7 @@ static int i2o_iop_reset(struct i2o_controller *c)
                if (time_after(jiffies, timeout))
                        break;
 
-               set_current_state(TASK_UNINTERRUPTIBLE);
-               schedule_timeout(1);
+               schedule_timeout_uninterruptible(1);
        }
 
        switch (*status) {
@@ -577,8 +574,7 @@ static int i2o_iop_reset(struct i2o_controller *c)
                                rc = -ETIMEDOUT;
                                goto exit;
                        }
-                       set_current_state(TASK_UNINTERRUPTIBLE);
-                       schedule_timeout(1);
+                       schedule_timeout_uninterruptible(1);
 
                        m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_RESET);
                }
@@ -989,8 +985,7 @@ int i2o_status_get(struct i2o_controller *c)
                        return -ETIMEDOUT;
                }
 
-               set_current_state(TASK_UNINTERRUPTIBLE);
-               schedule_timeout(1);
+               schedule_timeout_uninterruptible(1);
        }
 
 #ifdef DEBUG
index c75d713c01e4a9c9680410b2de2c75fabdf6802d..55ba23075c90ed688ad2ee88c9608a1fefcda77a 100644 (file)
@@ -15,6 +15,8 @@
 #include <linux/errno.h>
 #include <linux/smp.h>
 #include <linux/device.h>
+#include <linux/slab.h>
+#include <linux/string.h>
 
 #include <asm/dma.h>
 #include <asm/system.h>
index 4ff67e7363d95436de496a044ce2e076bddefb7a..e954b8354fef74f3e7f8d6a9dabdfef7814a9c95 100644 (file)
@@ -1602,8 +1602,7 @@ static void __devexit wbsd_release_dma(struct wbsd_host* host)
        if (host->dma_addr)
                dma_unmap_single(host->mmc->dev, host->dma_addr, WBSD_DMA_SIZE,
                        DMA_BIDIRECTIONAL);
-       if (host->dma_buffer)
-               kfree(host->dma_buffer);
+       kfree(host->dma_buffer);
        if (host->dma >= 0)
                free_dma(host->dma);
 
index 0cfcd88468e0ed3c2db5da780bc3d7e428c3ab3c..c3fc9b2f21fbd5988a39dd2c9c0f12d0fd69190f 100644 (file)
@@ -455,8 +455,7 @@ static struct mtd_info *cfi_intelext_setup(struct mtd_info *mtd)
 
  setup_err:
        if(mtd) {
-               if(mtd->eraseregions)
-                       kfree(mtd->eraseregions);
+               kfree(mtd->eraseregions);
                kfree(mtd);
        }
        kfree(cfi->cmdset_priv);
index 8505f118f2dbfcd8d7275c3cb1af5292eaaaca0d..0e6475050da91b90c47a78c8d6532395c55c482d 100644 (file)
@@ -378,8 +378,7 @@ static struct mtd_info *cfi_amdstd_setup(struct mtd_info *mtd)
 
  setup_err:
        if(mtd) {
-               if(mtd->eraseregions)
-                       kfree(mtd->eraseregions);
+               kfree(mtd->eraseregions);
                kfree(mtd);
        }
        kfree(cfi->cmdset_priv);
@@ -1742,6 +1741,7 @@ static void cfi_amdstd_destroy(struct mtd_info *mtd)
 {
        struct map_info *map = mtd->priv;
        struct cfi_private *cfi = map->fldrv_priv;
+
        kfree(cfi->cmdset_priv);
        kfree(cfi->cfiq);
        kfree(cfi);
index 662e807801ed046e71a99ad8b50f781bc14f1fee..59a29e616a226f82112851ef76ae8a57ca1db012 100644 (file)
@@ -539,11 +539,8 @@ static void free_device(struct blkmtd_dev *dev)
 {
        DEBUG(2, "blkmtd: free_device() dev = %p\n", dev);
        if(dev) {
-               if(dev->mtd_info.eraseregions)
-                       kfree(dev->mtd_info.eraseregions);
-               if(dev->mtd_info.name)
-                       kfree(dev->mtd_info.name);
-
+               kfree(dev->mtd_info.eraseregions);
+               kfree(dev->mtd_info.name);
                if(dev->blkdev) {
                        invalidate_inode_pages(dev->blkdev->bd_inode->i_mapping);
                        close_bdev_excl(dev->blkdev);
index 39eb53f6551f0d96943539ce0ce0a41aba1dc22f..8db65bf029ea6db3ed59f30a568d5434e1b8c067 100644 (file)
@@ -126,10 +126,8 @@ static void inftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
        }
 
        if (add_mtd_blktrans_dev(&inftl->mbd)) {
-               if (inftl->PUtable)
-                       kfree(inftl->PUtable);
-               if (inftl->VUtable)
-                       kfree(inftl->VUtable);
+               kfree(inftl->PUtable);
+               kfree(inftl->VUtable);
                kfree(inftl);
                return;
        }
@@ -147,10 +145,8 @@ static void inftl_remove_dev(struct mtd_blktrans_dev *dev)
 
        del_mtd_blktrans_dev(dev);
 
-       if (inftl->PUtable)
-               kfree(inftl->PUtable);
-       if (inftl->VUtable)
-               kfree(inftl->VUtable);
+       kfree(inftl->PUtable);
+       kfree(inftl->VUtable);
        kfree(inftl);
 }
 
index b5dda47395a71db2f3db02601e9722a73fc98edc..3dac53feeee27561a28b8cc6c35a1bd313ebb17a 100644 (file)
@@ -574,6 +574,12 @@ int INFTL_mount(struct INFTLrecord *s)
 
        /* Temporary buffer to store ANAC numbers. */
        ANACtable = kmalloc(s->nb_blocks * sizeof(u8), GFP_KERNEL);
+       if (!ANACtable) {
+               printk(KERN_WARNING "INFTL: allocation of ANACtable "
+                               "failed (%zd bytes)\n",
+                               s->nb_blocks * sizeof(u8));
+               return -ENOMEM;
+       }
        memset(ANACtable, 0, s->nb_blocks);
 
        /*
index e8a900a77685e4bb024a3c510a2b3e5dc3d11c1b..9a64149f431d2a547383bd97b1861e81fafd2596 100644 (file)
@@ -259,9 +259,7 @@ static int __devinit amd76xrom_init_one (struct pci_dev *pdev,
 
  out:
        /* Free any left over map structures */
-       if (map) {
-               kfree(map);
-       }
+       kfree(map);
        /* See if I have any map structures */
        if (list_empty(&window->maps)) {
                amd76xrom_cleanup(window);
index bfe994e59265d57772da814b0b08eab199e2e793..8c19d722ac796178c9d0cda7ecd3de29c8223927 100644 (file)
@@ -104,8 +104,7 @@ static int bast_flash_remove(struct device *dev)
                map_destroy(info->mtd);
        }
 
-       if (info->partitions)
-               kfree(info->partitions);
+       kfree(info->partitions);
 
        if (info->area) {
                release_resource(info->area);
index c68b31dc7e6d4979c363a8ac1e32bb0abba09f5b..5a95ab370a970cf6150d857de460a02bfeba29df 100644 (file)
@@ -313,8 +313,7 @@ static void __init clps_locate_partitions(struct mtd_info *mtd)
 
 static void __exit clps_destroy_partitions(void)
 {
-       if (parsed_parts)
-               kfree(parsed_parts);
+       kfree(parsed_parts);
 }
 
 static struct mtd_info *mymtd;
index e505207cd4892918b27c59a3ccc2f00afc0c3c59..c5e2111ba146df5535e0b90f451cc5c55d99ac63 100644 (file)
@@ -306,9 +306,8 @@ static int __devinit ichxrom_init_one (struct pci_dev *pdev,
 
  out:
        /* Free any left over map structures */
-       if (map) {
-               kfree(map);
-       }
+       kfree(map);
+
        /* See if I have any map structures */
        if (list_empty(&window->maps)) {
                ichxrom_cleanup(window);
index d14a0185b8f419f97d14595caee88803c64769d9..93f50d6d5488817cd4d2af10072a7acddd6a12a2 100644 (file)
@@ -148,8 +148,7 @@ static int armflash_probe(struct device *_dev)
                        del_mtd_partitions(info->mtd);
                        map_destroy(info->mtd);
                }
-               if (info->parts)
-                       kfree(info->parts);
+               kfree(info->parts);
 
  no_device:
                iounmap(base);
@@ -176,8 +175,7 @@ static int armflash_remove(struct device *_dev)
                        del_mtd_partitions(info->mtd);
                        map_destroy(info->mtd);
                }
-               if (info->parts)
-                       kfree(info->parts);
+               kfree(info->parts);
 
                iounmap(info->map.virt);
                release_resource(info->res);
index 712401810841bf1f1d5358b12108ddffac8affbf..70b0e0b82c34f8e7384b2fb0bae3ea51503dc10d 100644 (file)
@@ -431,8 +431,7 @@ static void __exit ipaq_mtd_cleanup(void)
                                if (my_sub_mtd[i])
                                        map_destroy(my_sub_mtd[i]);
                        }
-               if (parsed_parts)
-                       kfree(parsed_parts);
+               kfree(parsed_parts);
        }
 }
 
index 558d014e7acc0365adb8b8d2bb3ec502bf73ca0b..2e7577492a2c3602b135386f0ac0f4b6d122214d 100644 (file)
@@ -103,8 +103,7 @@ static void __exit cleanup_iq80310(void)
        if (mymtd) {
                del_mtd_partitions(mymtd);
                map_destroy(mymtd);
-               if (parsed_parts)
-                       kfree(parsed_parts);
+               kfree(parsed_parts);
        }
        if (iq80310_map.virt)
                iounmap((void *)iq80310_map.virt);
index 00b9f67580f1566550950327479fd59af1ca2a33..6f36497022d19bed60f57e78bd8882bf21b7dedb 100644 (file)
@@ -129,8 +129,7 @@ static int ixp2000_flash_remove(struct device *_dev)
        if (info->map.map_priv_1)
                iounmap((void *) info->map.map_priv_1);
 
-       if (info->partitions) {
-               kfree(info->partitions); }
+       kfree(info->partitions);
 
        if (info->res) {
                release_resource(info->res);
index 733a9297a56263eda2c49bfe7db2545f86ed78d6..0d87c02dee046f32070427b8e743ac550fa1f8ed 100644 (file)
@@ -124,8 +124,7 @@ static int ixp4xx_flash_remove(struct device *_dev)
        if (info->map.map_priv_1)
                iounmap((void *) info->map.map_priv_1);
 
-       if (info->partitions)
-               kfree(info->partitions);
+       kfree(info->partitions);
 
        if (info->res) {
                release_resource(info->res);
index 2337e0c4675061419bb9ddc6f64c4f7ff9f40378..2b4c5058787d76426b536d304374cb82ae92b82d 100644 (file)
@@ -158,8 +158,7 @@ static void __exit cleanup_lubbock(void)
                if (lubbock_maps[i].cached)
                        iounmap(lubbock_maps[i].cached);
 
-               if (parsed_parts[i])
-                       kfree(parsed_parts[i]);
+               kfree(parsed_parts[i]);
        }
 }
 
index da36e8dddd17e9833d222d108bb20fdabb53a4e3..763304154a923364151b7b4b789bf7db2e0ebbff 100644 (file)
@@ -124,8 +124,7 @@ static void  __exit omap_toto_mtd_cleanup(void)
        if (flash_mtd) {
                del_mtd_partitions(flash_mtd);
                map_destroy(flash_mtd);
-               if (parsed_parts)
-                       kfree(parsed_parts);
+               kfree(parsed_parts);
        }
 }
 
index c8d0da19d897e461a18efaace5076bfc12111d59..a31f6ee8a4be5834d5d2f7ff9b583c236ba121f1 100644 (file)
@@ -241,8 +241,7 @@ static void sa1100_destroy(struct sa_info *info, struct flash_platform_data *pla
 #endif
        }
 
-       if (info->parts)
-               kfree(info->parts);
+       kfree(info->parts);
 
        for (i = info->num_subdev - 1; i >= 0; i--)
                sa1100_destroy_subdev(&info->subdev[i]);
index 29091d10030a091651c935f6126221d1de92ff8e..1355c28f90a4d7432a59171a9622dfc710a92dea 100644 (file)
@@ -166,9 +166,7 @@ static void __exit uflash_cleanup(void)
                        iounmap(udev->map.virt);
                        udev->map.virt = NULL;
                }
-               if(0 != udev->name) {
-                       kfree(udev->name);
-               }
+               kfree(udev->name);
                kfree(udev);
        }       
 }
index 4e28b977f224120db3c5dc5d278c3593081accfb..0aca8179f27f676f022a6efb5eed81cd9a9412aa 100644 (file)
@@ -224,10 +224,8 @@ int __init init_tqm_mtd(void)
 error_mem:
        for(idx = 0 ; idx < FLASH_BANK_MAX ; idx++) {
                if(map_banks[idx] != NULL) {
-                       if(map_banks[idx]->name != NULL) {
-                               kfree(map_banks[idx]->name);
-                               map_banks[idx]->name = NULL;
-                       }
+                       kfree(map_banks[idx]->name);
+                       map_banks[idx]->name = NULL;
                        kfree(map_banks[idx]);
                        map_banks[idx] = NULL;
                }
index 04e54318bc6a603f2c44b32e3b2f8b5b260a64dc..8e78d7b96a5671af16033227e4582e694e502438 100644 (file)
@@ -2676,9 +2676,8 @@ void nand_release (struct mtd_info *mtd)
        /* Deregister the device */
        del_mtd_device (mtd);
 
-       /* Free bad block table memory, if allocated */
-       if (this->bbt)
-               kfree (this->bbt);
+       /* Free bad block table memory */
+       kfree (this->bbt);
        /* Buffer allocated by nand_scan ? */
        if (this->options & NAND_OOBBUF_ALLOC)
                kfree (this->oob_buf);
index b2014043634fc5eb842516ad1b75ebe0ed682f7b..062ff3877536066e04a56bdd2bac8d0a3b0829ff 100644 (file)
@@ -114,10 +114,8 @@ static void nftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
        }
 
        if (add_mtd_blktrans_dev(&nftl->mbd)) {
-               if (nftl->ReplUnitTable)
-                       kfree(nftl->ReplUnitTable);
-               if (nftl->EUNtable)
-                       kfree(nftl->EUNtable);
+               kfree(nftl->ReplUnitTable);
+               kfree(nftl->EUNtable);
                kfree(nftl);
                return;
        }
@@ -133,10 +131,8 @@ static void nftl_remove_dev(struct mtd_blktrans_dev *dev)
        DEBUG(MTD_DEBUG_LEVEL1, "NFTL: remove_dev (i=%d)\n", dev->devnum);
 
        del_mtd_blktrans_dev(dev);
-       if (nftl->ReplUnitTable)
-               kfree(nftl->ReplUnitTable);
-       if (nftl->EUNtable)
-               kfree(nftl->EUNtable);
+       kfree(nftl->ReplUnitTable);
+       kfree(nftl->EUNtable);
        kfree(nftl);
 }
 
index 455ba915ede738adc53f533f1b0a672cb07228d9..7488ee7f7cafa1075c6079b0f20081a614eeccb0 100644 (file)
@@ -602,7 +602,7 @@ MODULE_DEVICE_TABLE(pci, vortex_pci_tbl);
    First the windows.  There are eight register windows, with the command
    and status registers available in each.
    */
-#define EL3WINDOW(win_num) outw(SelectWindow + (win_num), ioaddr + EL3_CMD)
+#define EL3WINDOW(win_num) iowrite16(SelectWindow + (win_num), ioaddr + EL3_CMD)
 #define EL3_CMD 0x0e
 #define EL3_STATUS 0x0e
 
@@ -776,7 +776,8 @@ struct vortex_private {
 
        /* PCI configuration space information. */
        struct device *gendev;
-       char __iomem *cb_fn_base;               /* CardBus function status addr space. */
+       void __iomem *ioaddr;                   /* IO address space */
+       void __iomem *cb_fn_base;               /* CardBus function status addr space. */
 
        /* Some values here only for performance evaluation and path-coverage */
        int rx_nocopy, rx_copy, queued_packet, rx_csumhits;
@@ -869,12 +870,12 @@ static struct {
 /* number of ETHTOOL_GSTATS u64's */
 #define VORTEX_NUM_STATS     3
 
-static int vortex_probe1(struct device *gendev, long ioaddr, int irq,
+static int vortex_probe1(struct device *gendev, void __iomem *ioaddr, int irq,
                                   int chip_idx, int card_idx);
 static void vortex_up(struct net_device *dev);
 static void vortex_down(struct net_device *dev, int final);
 static int vortex_open(struct net_device *dev);
-static void mdio_sync(long ioaddr, int bits);
+static void mdio_sync(void __iomem *ioaddr, int bits);
 static int mdio_read(struct net_device *dev, int phy_id, int location);
 static void mdio_write(struct net_device *vp, int phy_id, int location, int value);
 static void vortex_timer(unsigned long arg);
@@ -887,7 +888,7 @@ 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 int vortex_close(struct net_device *dev);
 static void dump_tx_ring(struct net_device *dev);
-static void update_stats(long ioaddr, struct net_device *dev);
+static void update_stats(void __iomem *ioaddr, struct net_device *dev);
 static struct net_device_stats *vortex_get_stats(struct net_device *dev);
 static void set_rx_mode(struct net_device *dev);
 #ifdef CONFIG_PCI
@@ -902,14 +903,16 @@ static void set_8021q_mode(struct net_device *dev, int enable);
 /* This driver uses 'options' to pass the media type, full-duplex flag, etc. */
 /* Option count limit only -- unlimited interfaces are supported. */
 #define MAX_UNITS 8
-static int options[MAX_UNITS] = { -1, -1, -1, -1, -1, -1, -1, -1,};
-static int full_duplex[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};
-static int hw_checksums[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};
-static int flow_ctrl[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};
-static int enable_wol[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};
+static int options[MAX_UNITS] = { [0 ... MAX_UNITS-1] = -1 };
+static int full_duplex[MAX_UNITS] = {[0 ... MAX_UNITS-1] = -1 };
+static int hw_checksums[MAX_UNITS] = {[0 ... MAX_UNITS-1] = -1 };
+static int flow_ctrl[MAX_UNITS] = {[0 ... MAX_UNITS-1] = -1 };
+static int enable_wol[MAX_UNITS] = {[0 ... MAX_UNITS-1] = -1 };
+static int use_mmio[MAX_UNITS] = {[0 ... MAX_UNITS-1] = -1 };
 static int global_options = -1;
 static int global_full_duplex = -1;
 static int global_enable_wol = -1;
+static int global_use_mmio = -1;
 
 /* #define dev_alloc_skb dev_alloc_skb_debug */
 
@@ -934,21 +937,25 @@ module_param(compaq_ioaddr, int, 0);
 module_param(compaq_irq, int, 0);
 module_param(compaq_device_id, int, 0);
 module_param(watchdog, int, 0);
+module_param(global_use_mmio, int, 0);
+module_param_array(use_mmio, int, NULL, 0);
 MODULE_PARM_DESC(debug, "3c59x debug level (0-6)");
 MODULE_PARM_DESC(options, "3c59x: Bits 0-3: media type, bit 4: bus mastering, bit 9: full duplex");
 MODULE_PARM_DESC(global_options, "3c59x: same as options, but applies to all NICs if options is unset");
 MODULE_PARM_DESC(full_duplex, "3c59x full duplex setting(s) (1)");
-MODULE_PARM_DESC(global_full_duplex, "3c59x: same as full_duplex, but applies to all NICs if options is unset");
+MODULE_PARM_DESC(global_full_duplex, "3c59x: same as full_duplex, but applies to all NICs if full_duplex is unset");
 MODULE_PARM_DESC(hw_checksums, "3c59x Hardware checksum checking by adapter(s) (0-1)");
 MODULE_PARM_DESC(flow_ctrl, "3c59x 802.3x flow control usage (PAUSE only) (0-1)");
 MODULE_PARM_DESC(enable_wol, "3c59x: Turn on Wake-on-LAN for adapter(s) (0-1)");
-MODULE_PARM_DESC(global_enable_wol, "3c59x: same as enable_wol, but applies to all NICs if options is unset");
+MODULE_PARM_DESC(global_enable_wol, "3c59x: same as enable_wol, but applies to all NICs if enable_wol is unset");
 MODULE_PARM_DESC(rx_copybreak, "3c59x copy breakpoint for copy-only-tiny-frames");
 MODULE_PARM_DESC(max_interrupt_work, "3c59x maximum events handled per interrupt");
 MODULE_PARM_DESC(compaq_ioaddr, "3c59x PCI I/O base address (Compaq BIOS problem workaround)");
 MODULE_PARM_DESC(compaq_irq, "3c59x PCI IRQ number (Compaq BIOS problem workaround)");
 MODULE_PARM_DESC(compaq_device_id, "3c59x PCI device ID (Compaq BIOS problem workaround)");
 MODULE_PARM_DESC(watchdog, "3c59x transmit timeout in milliseconds");
+MODULE_PARM_DESC(global_use_mmio, "3c59x: same as use_mmio, but applies to all NICs if options is unset");
+MODULE_PARM_DESC(use_mmio, "3c59x: use memory-mapped PCI I/O resource (0-1)");
 
 #ifdef CONFIG_NET_POLL_CONTROLLER
 static void poll_vortex(struct net_device *dev)
@@ -1029,18 +1036,19 @@ static struct eisa_driver vortex_eisa_driver = {
 
 static int vortex_eisa_probe (struct device *device)
 {
-       long ioaddr;
+       void __iomem *ioaddr;
        struct eisa_device *edev;
 
        edev = to_eisa_device (device);
-       ioaddr = edev->base_addr;
 
-       if (!request_region(ioaddr, VORTEX_TOTAL_SIZE, DRV_NAME))
+       if (!request_region(edev->base_addr, VORTEX_TOTAL_SIZE, DRV_NAME))
                return -EBUSY;
 
-       if (vortex_probe1(device, ioaddr, inw(ioaddr + 0xC88) >> 12,
+       ioaddr = ioport_map(edev->base_addr, VORTEX_TOTAL_SIZE);
+
+       if (vortex_probe1(device, ioaddr, ioread16(ioaddr + 0xC88) >> 12,
                                          edev->id.driver_data, vortex_cards_found)) {
-               release_region (ioaddr, VORTEX_TOTAL_SIZE);
+               release_region (edev->base_addr, VORTEX_TOTAL_SIZE);
                return -ENODEV;
        }
 
@@ -1054,7 +1062,7 @@ static int vortex_eisa_remove (struct device *device)
        struct eisa_device *edev;
        struct net_device *dev;
        struct vortex_private *vp;
-       long ioaddr;
+       void __iomem *ioaddr;
 
        edev = to_eisa_device (device);
        dev = eisa_get_drvdata (edev);
@@ -1065,11 +1073,11 @@ static int vortex_eisa_remove (struct device *device)
        }
 
        vp = netdev_priv(dev);
-       ioaddr = dev->base_addr;
+       ioaddr = vp->ioaddr;
        
        unregister_netdev (dev);
-       outw (TotalReset|0x14, ioaddr + EL3_CMD);
-       release_region (ioaddr, VORTEX_TOTAL_SIZE);
+       iowrite16 (TotalReset|0x14, ioaddr + EL3_CMD);
+       release_region (dev->base_addr, VORTEX_TOTAL_SIZE);
 
        free_netdev (dev);
        return 0;
@@ -1096,8 +1104,8 @@ static int __init vortex_eisa_init (void)
        
        /* Special code to work-around the Compaq PCI BIOS32 problem. */
        if (compaq_ioaddr) {
-               vortex_probe1(NULL, compaq_ioaddr, compaq_irq,
-                                         compaq_device_id, vortex_cards_found++);
+               vortex_probe1(NULL, ioport_map(compaq_ioaddr, VORTEX_TOTAL_SIZE),
+                             compaq_irq, compaq_device_id, vortex_cards_found++);
        }
 
        return vortex_cards_found - orig_cards_found + eisa_found;
@@ -1107,15 +1115,32 @@ static int __init vortex_eisa_init (void)
 static int __devinit vortex_init_one (struct pci_dev *pdev,
                                      const struct pci_device_id *ent)
 {
-       int rc;
+       int rc, unit, pci_bar;
+       struct vortex_chip_info *vci;
+       void __iomem *ioaddr;
 
        /* wake up and enable device */         
        rc = pci_enable_device (pdev);
        if (rc < 0)
                goto out;
 
-       rc = vortex_probe1 (&pdev->dev, pci_resource_start (pdev, 0),
-                                               pdev->irq, ent->driver_data, vortex_cards_found);
+       unit = vortex_cards_found;
+
+       if (global_use_mmio < 0 && (unit >= MAX_UNITS || use_mmio[unit] < 0)) {
+               /* Determine the default if the user didn't override us */
+               vci = &vortex_info_tbl[ent->driver_data];
+               pci_bar = vci->drv_flags & (IS_CYCLONE | IS_TORNADO) ? 1 : 0;
+       } else if (unit < MAX_UNITS && use_mmio[unit] >= 0)
+               pci_bar = use_mmio[unit] ? 1 : 0;
+       else
+               pci_bar = global_use_mmio ? 1 : 0;
+
+       ioaddr = pci_iomap(pdev, pci_bar, 0);
+       if (!ioaddr) /* If mapping fails, fall-back to BAR 0... */
+               ioaddr = pci_iomap(pdev, 0, 0);
+
+       rc = vortex_probe1(&pdev->dev, ioaddr, pdev->irq,
+                          ent->driver_data, unit);
        if (rc < 0) {
                pci_disable_device (pdev);
                goto out;
@@ -1134,7 +1159,7 @@ out:
  * NOTE: pdev can be NULL, for the case of a Compaq device
  */
 static int __devinit vortex_probe1(struct device *gendev,
-                                  long ioaddr, int irq,
+                                  void __iomem *ioaddr, int irq,
                                   int chip_idx, int card_idx)
 {
        struct vortex_private *vp;
@@ -1202,15 +1227,16 @@ static int __devinit vortex_probe1(struct device *gendev,
        if (print_info)
                printk (KERN_INFO "See Documentation/networking/vortex.txt\n");
 
-       printk(KERN_INFO "%s: 3Com %s %s at 0x%lx. Vers " DRV_VERSION "\n",
+       printk(KERN_INFO "%s: 3Com %s %s at %p. Vers " DRV_VERSION "\n",
               print_name,
               pdev ? "PCI" : "EISA",
               vci->name,
               ioaddr);
 
-       dev->base_addr = ioaddr;
+       dev->base_addr = (unsigned long)ioaddr;
        dev->irq = irq;
        dev->mtu = mtu;
+       vp->ioaddr = ioaddr;
        vp->large_frames = mtu > 1500;
        vp->drv_flags = vci->drv_flags;
        vp->has_nway = (vci->drv_flags & HAS_NWAY) ? 1 : 0;
@@ -1226,7 +1252,7 @@ static int __devinit vortex_probe1(struct device *gendev,
        if (pdev) {
                /* EISA resources already marked, so only PCI needs to do this here */
                /* Ignore return value, because Cardbus drivers already allocate for us */
-               if (request_region(ioaddr, vci->io_size, print_name) != NULL)
+               if (request_region(dev->base_addr, vci->io_size, print_name) != NULL)
                        vp->must_free_region = 1;
 
                /* enable bus-mastering if necessary */         
@@ -1316,14 +1342,14 @@ static int __devinit vortex_probe1(struct device *gendev,
 
                for (i = 0; i < 0x40; i++) {
                        int timer;
-                       outw(base + i, ioaddr + Wn0EepromCmd);
+                       iowrite16(base + i, ioaddr + Wn0EepromCmd);
                        /* Pause for at least 162 us. for the read to take place. */
                        for (timer = 10; timer >= 0; timer--) {
                                udelay(162);
-                               if ((inw(ioaddr + Wn0EepromCmd) & 0x8000) == 0)
+                               if ((ioread16(ioaddr + Wn0EepromCmd) & 0x8000) == 0)
                                        break;
                        }
-                       eeprom[i] = inw(ioaddr + Wn0EepromData);
+                       eeprom[i] = ioread16(ioaddr + Wn0EepromData);
                }
        }
        for (i = 0; i < 0x18; i++)
@@ -1338,6 +1364,7 @@ static int __devinit vortex_probe1(struct device *gendev,
                printk(" ***INVALID CHECKSUM %4.4x*** ", checksum);
        for (i = 0; i < 3; i++)
                ((u16 *)dev->dev_addr)[i] = htons(eeprom[i + 10]);
+       memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
        if (print_info) {
                for (i = 0; i < 6; i++)
                        printk("%c%2.2x", i ? ':' : ' ', dev->dev_addr[i]);
@@ -1351,7 +1378,7 @@ static int __devinit vortex_probe1(struct device *gendev,
        }
        EL3WINDOW(2);
        for (i = 0; i < 6; i++)
-               outb(dev->dev_addr[i], ioaddr + i);
+               iowrite8(dev->dev_addr[i], ioaddr + i);
 
 #ifdef __sparc__
        if (print_info)
@@ -1366,7 +1393,7 @@ static int __devinit vortex_probe1(struct device *gendev,
 #endif
 
        EL3WINDOW(4);
-       step = (inb(ioaddr + Wn4_NetDiag) & 0x1e) >> 1;
+       step = (ioread8(ioaddr + Wn4_NetDiag) & 0x1e) >> 1;
        if (print_info) {
                printk(KERN_INFO "  product code %02x%02x rev %02x.%d date %02d-"
                        "%02d-%02d\n", eeprom[6]&0xff, eeprom[6]>>8, eeprom[0x14],
@@ -1375,31 +1402,30 @@ static int __devinit vortex_probe1(struct device *gendev,
 
 
        if (pdev && vci->drv_flags & HAS_CB_FNS) {
-               unsigned long fn_st_addr;                       /* Cardbus function status space */
                unsigned short n;
 
-               fn_st_addr = pci_resource_start (pdev, 2);
-               if (fn_st_addr) {
-                       vp->cb_fn_base = ioremap(fn_st_addr, 128);
+               vp->cb_fn_base = pci_iomap(pdev, 2, 0);
+               if (!vp->cb_fn_base) {
                        retval = -ENOMEM;
-                       if (!vp->cb_fn_base)
-                               goto free_ring;
+                       goto free_ring;
                }
+
                if (print_info) {
                        printk(KERN_INFO "%s: CardBus functions mapped %8.8lx->%p\n",
-                               print_name, fn_st_addr, vp->cb_fn_base);
+                               print_name, pci_resource_start(pdev, 2),
+                               vp->cb_fn_base);
                }
                EL3WINDOW(2);
 
-               n = inw(ioaddr + Wn2_ResetOptions) & ~0x4010;
+               n = ioread16(ioaddr + Wn2_ResetOptions) & ~0x4010;
                if (vp->drv_flags & INVERT_LED_PWR)
                        n |= 0x10;
                if (vp->drv_flags & INVERT_MII_PWR)
                        n |= 0x4000;
-               outw(n, ioaddr + Wn2_ResetOptions);
+               iowrite16(n, ioaddr + Wn2_ResetOptions);
                if (vp->drv_flags & WNO_XCVR_PWR) {
                        EL3WINDOW(0);
-                       outw(0x0800, ioaddr);
+                       iowrite16(0x0800, ioaddr);
                }
        }
 
@@ -1418,13 +1444,13 @@ static int __devinit vortex_probe1(struct device *gendev,
                static const char * ram_split[] = {"5:3", "3:1", "1:1", "3:5"};
                unsigned int config;
                EL3WINDOW(3);
-               vp->available_media = inw(ioaddr + Wn3_Options);
+               vp->available_media = ioread16(ioaddr + Wn3_Options);
                if ((vp->available_media & 0xff) == 0)          /* Broken 3c916 */
                        vp->available_media = 0x40;
-               config = inl(ioaddr + Wn3_Config);
+               config = ioread32(ioaddr + Wn3_Config);
                if (print_info) {
                        printk(KERN_DEBUG "  Internal config register is %4.4x, "
-                                  "transceivers %#x.\n", config, inw(ioaddr + Wn3_Options));
+                                  "transceivers %#x.\n", config, ioread16(ioaddr + Wn3_Options));
                        printk(KERN_INFO "  %dK %s-wide RAM %s Rx:Tx split, %s%s interface.\n",
                                   8 << RAM_SIZE(config),
                                   RAM_WIDTH(config) ? "word" : "byte",
@@ -1455,7 +1481,7 @@ static int __devinit vortex_probe1(struct device *gendev,
                if (vp->drv_flags & EXTRA_PREAMBLE)
                        mii_preamble_required++;
                mdio_sync(ioaddr, 32);
-               mdio_read(dev, 24, 1);
+               mdio_read(dev, 24, MII_BMSR);
                for (phy = 0; phy < 32 && phy_idx < 1; phy++) {
                        int mii_status, phyx;
 
@@ -1469,7 +1495,7 @@ static int __devinit vortex_probe1(struct device *gendev,
                                phyx = phy - 1;
                        else
                                phyx = phy;
-                       mii_status = mdio_read(dev, phyx, 1);
+                       mii_status = mdio_read(dev, phyx, MII_BMSR);
                        if (mii_status  &&  mii_status != 0xffff) {
                                vp->phys[phy_idx++] = phyx;
                                if (print_info) {
@@ -1485,7 +1511,7 @@ static int __devinit vortex_probe1(struct device *gendev,
                        printk(KERN_WARNING"  ***WARNING*** No MII transceivers found!\n");
                        vp->phys[0] = 24;
                } else {
-                       vp->advertising = mdio_read(dev, vp->phys[0], 4);
+                       vp->advertising = mdio_read(dev, vp->phys[0], MII_ADVERTISE);
                        if (vp->full_duplex) {
                                /* Only advertise the FD media types. */
                                vp->advertising &= ~0x02A0;
@@ -1510,10 +1536,10 @@ static int __devinit vortex_probe1(struct device *gendev,
        if (vp->full_bus_master_tx) {
                dev->hard_start_xmit = boomerang_start_xmit;
                /* Actually, it still should work with iommu. */
-               dev->features |= NETIF_F_SG;
-               if (((hw_checksums[card_idx] == -1) && (vp->drv_flags & HAS_HWCKSM)) ||
-                                       (hw_checksums[card_idx] == 1)) {
-                               dev->features |= NETIF_F_IP_CSUM;
+               if (card_idx < MAX_UNITS &&
+                   ((hw_checksums[card_idx] == -1 && (vp->drv_flags & HAS_HWCKSM)) ||
+                               hw_checksums[card_idx] == 1)) {
+                       dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG;
                }
        } else {
                dev->hard_start_xmit = vortex_start_xmit;
@@ -1555,7 +1581,7 @@ free_ring:
                                                vp->rx_ring_dma);
 free_region:
        if (vp->must_free_region)
-               release_region(ioaddr, vci->io_size);
+               release_region(dev->base_addr, vci->io_size);
        free_netdev(dev);
        printk(KERN_ERR PFX "vortex_probe1 fails.  Returns %d\n", retval);
 out:
@@ -1565,17 +1591,19 @@ out:
 static void
 issue_and_wait(struct net_device *dev, int cmd)
 {
+       struct vortex_private *vp = netdev_priv(dev);
+       void __iomem *ioaddr = vp->ioaddr;
        int i;
 
-       outw(cmd, dev->base_addr + EL3_CMD);
+       iowrite16(cmd, ioaddr + EL3_CMD);
        for (i = 0; i < 2000; i++) {
-               if (!(inw(dev->base_addr + EL3_STATUS) & CmdInProgress))
+               if (!(ioread16(ioaddr + EL3_STATUS) & CmdInProgress))
                        return;
        }
 
        /* OK, that didn't work.  Do it the slow way.  One second */
        for (i = 0; i < 100000; i++) {
-               if (!(inw(dev->base_addr + EL3_STATUS) & CmdInProgress)) {
+               if (!(ioread16(ioaddr + EL3_STATUS) & CmdInProgress)) {
                        if (vortex_debug > 1)
                                printk(KERN_INFO "%s: command 0x%04x took %d usecs\n",
                                           dev->name, cmd, i * 10);
@@ -1584,14 +1612,14 @@ issue_and_wait(struct net_device *dev, int cmd)
                udelay(10);
        }
        printk(KERN_ERR "%s: command 0x%04x did not complete! Status=0x%x\n",
-                          dev->name, cmd, inw(dev->base_addr + EL3_STATUS));
+                          dev->name, cmd, ioread16(ioaddr + EL3_STATUS));
 }
 
 static void
 vortex_up(struct net_device *dev)
 {
-       long ioaddr = dev->base_addr;
        struct vortex_private *vp = netdev_priv(dev);
+       void __iomem *ioaddr = vp->ioaddr;
        unsigned int config;
        int i;
 
@@ -1604,7 +1632,7 @@ vortex_up(struct net_device *dev)
 
        /* Before initializing select the active media port. */
        EL3WINDOW(3);
-       config = inl(ioaddr + Wn3_Config);
+       config = ioread32(ioaddr + Wn3_Config);
 
        if (vp->media_override != 7) {
                printk(KERN_INFO "%s: Media override to transceiver %d (%s).\n",
@@ -1651,14 +1679,14 @@ vortex_up(struct net_device *dev)
        config = BFINS(config, dev->if_port, 20, 4);
        if (vortex_debug > 6)
                printk(KERN_DEBUG "vortex_up(): writing 0x%x to InternalConfig\n", config);
-       outl(config, ioaddr + Wn3_Config);
+       iowrite32(config, ioaddr + Wn3_Config);
 
        if (dev->if_port == XCVR_MII || dev->if_port == XCVR_NWAY) {
                int mii_reg1, mii_reg5;
                EL3WINDOW(4);
                /* Read BMSR (reg1) only to clear old status. */
-               mii_reg1 = mdio_read(dev, vp->phys[0], 1);
-               mii_reg5 = mdio_read(dev, vp->phys[0], 5);
+               mii_reg1 = mdio_read(dev, vp->phys[0], MII_BMSR);
+               mii_reg5 = mdio_read(dev, vp->phys[0], MII_LPA);
                if (mii_reg5 == 0xffff  ||  mii_reg5 == 0x0000) {
                        netif_carrier_off(dev); /* No MII device or no link partner report */
                } else {
@@ -1679,7 +1707,7 @@ vortex_up(struct net_device *dev)
        }
 
        /* Set the full-duplex bit. */
-       outw(   ((vp->info1 & 0x8000) || vp->full_duplex ? 0x20 : 0) |
+       iowrite16(      ((vp->info1 & 0x8000) || vp->full_duplex ? 0x20 : 0) |
                        (vp->large_frames ? 0x40 : 0) |
                        ((vp->full_duplex && vp->flow_ctrl && vp->partner_flow_ctrl) ? 0x100 : 0),
                        ioaddr + Wn3_MAC_Ctrl);
@@ -1695,51 +1723,51 @@ vortex_up(struct net_device *dev)
         */
        issue_and_wait(dev, RxReset|0x04);
 
-       outw(SetStatusEnb | 0x00, ioaddr + EL3_CMD);
+       iowrite16(SetStatusEnb | 0x00, ioaddr + EL3_CMD);
 
        if (vortex_debug > 1) {
                EL3WINDOW(4);
                printk(KERN_DEBUG "%s: vortex_up() irq %d media status %4.4x.\n",
-                          dev->name, dev->irq, inw(ioaddr + Wn4_Media));
+                          dev->name, dev->irq, ioread16(ioaddr + Wn4_Media));
        }
 
        /* Set the station address and mask in window 2 each time opened. */
        EL3WINDOW(2);
        for (i = 0; i < 6; i++)
-               outb(dev->dev_addr[i], ioaddr + i);
+               iowrite8(dev->dev_addr[i], ioaddr + i);
        for (; i < 12; i+=2)
-               outw(0, ioaddr + i);
+               iowrite16(0, ioaddr + i);
 
        if (vp->cb_fn_base) {
-               unsigned short n = inw(ioaddr + Wn2_ResetOptions) & ~0x4010;
+               unsigned short n = ioread16(ioaddr + Wn2_ResetOptions) & ~0x4010;
                if (vp->drv_flags & INVERT_LED_PWR)
                        n |= 0x10;
                if (vp->drv_flags & INVERT_MII_PWR)
                        n |= 0x4000;
-               outw(n, ioaddr + Wn2_ResetOptions);
+               iowrite16(n, ioaddr + Wn2_ResetOptions);
        }
 
        if (dev->if_port == XCVR_10base2)
                /* Start the thinnet transceiver. We should really wait 50ms...*/
-               outw(StartCoax, ioaddr + EL3_CMD);
+               iowrite16(StartCoax, ioaddr + EL3_CMD);
        if (dev->if_port != XCVR_NWAY) {
                EL3WINDOW(4);
-               outw((inw(ioaddr + Wn4_Media) & ~(Media_10TP|Media_SQE)) |
+               iowrite16((ioread16(ioaddr + Wn4_Media) & ~(Media_10TP|Media_SQE)) |
                         media_tbl[dev->if_port].media_bits, ioaddr + Wn4_Media);
        }
 
        /* Switch to the stats window, and clear all stats by reading. */
-       outw(StatsDisable, ioaddr + EL3_CMD);
+       iowrite16(StatsDisable, ioaddr + EL3_CMD);
        EL3WINDOW(6);
        for (i = 0; i < 10; i++)
-               inb(ioaddr + i);
-       inw(ioaddr + 10);
-       inw(ioaddr + 12);
+               ioread8(ioaddr + i);
+       ioread16(ioaddr + 10);
+       ioread16(ioaddr + 12);
        /* New: On the Vortex we must also clear the BadSSD counter. */
        EL3WINDOW(4);
-       inb(ioaddr + 12);
+       ioread8(ioaddr + 12);
        /* ..and on the Boomerang we enable the extra statistics bits. */
-       outw(0x0040, ioaddr + Wn4_NetDiag);
+       iowrite16(0x0040, ioaddr + Wn4_NetDiag);
 
        /* Switch to register set 7 for normal use. */
        EL3WINDOW(7);
@@ -1747,30 +1775,30 @@ vortex_up(struct net_device *dev)
        if (vp->full_bus_master_rx) { /* Boomerang bus master. */
                vp->cur_rx = vp->dirty_rx = 0;
                /* Initialize the RxEarly register as recommended. */
-               outw(SetRxThreshold + (1536>>2), ioaddr + EL3_CMD);
-               outl(0x0020, ioaddr + PktStatus);
-               outl(vp->rx_ring_dma, ioaddr + UpListPtr);
+               iowrite16(SetRxThreshold + (1536>>2), ioaddr + EL3_CMD);
+               iowrite32(0x0020, ioaddr + PktStatus);
+               iowrite32(vp->rx_ring_dma, ioaddr + UpListPtr);
        }
        if (vp->full_bus_master_tx) {           /* Boomerang bus master Tx. */
                vp->cur_tx = vp->dirty_tx = 0;
                if (vp->drv_flags & IS_BOOMERANG)
-                       outb(PKT_BUF_SZ>>8, ioaddr + TxFreeThreshold); /* Room for a packet. */
+                       iowrite8(PKT_BUF_SZ>>8, ioaddr + TxFreeThreshold); /* Room for a packet. */
                /* Clear the Rx, Tx rings. */
                for (i = 0; i < RX_RING_SIZE; i++)      /* AKPM: this is done in vortex_open, too */
                        vp->rx_ring[i].status = 0;
                for (i = 0; i < TX_RING_SIZE; i++)
                        vp->tx_skbuff[i] = NULL;
-               outl(0, ioaddr + DownListPtr);
+               iowrite32(0, ioaddr + DownListPtr);
        }
        /* Set receiver mode: presumably accept b-case and phys addr only. */
        set_rx_mode(dev);
        /* enable 802.1q tagged frames */
        set_8021q_mode(dev, 1);
-       outw(StatsEnable, ioaddr + EL3_CMD); /* Turn on statistics. */
+       iowrite16(StatsEnable, ioaddr + EL3_CMD); /* Turn on statistics. */
 
 //     issue_and_wait(dev, SetTxStart|0x07ff);
-       outw(RxEnable, ioaddr + EL3_CMD); /* Enable the receiver. */
-       outw(TxEnable, ioaddr + EL3_CMD); /* Enable transmitter. */
+       iowrite16(RxEnable, ioaddr + EL3_CMD); /* Enable the receiver. */
+       iowrite16(TxEnable, ioaddr + EL3_CMD); /* Enable transmitter. */
        /* Allow status bits to be seen. */
        vp->status_enable = SetStatusEnb | HostError|IntReq|StatsFull|TxComplete|
                (vp->full_bus_master_tx ? DownComplete : TxAvailable) |
@@ -1780,13 +1808,13 @@ vortex_up(struct net_device *dev)
                (vp->full_bus_master_rx ? 0 : RxComplete) |
                StatsFull | HostError | TxComplete | IntReq
                | (vp->bus_master ? DMADone : 0) | UpComplete | DownComplete;
-       outw(vp->status_enable, ioaddr + EL3_CMD);
+       iowrite16(vp->status_enable, ioaddr + EL3_CMD);
        /* Ack all pending events, and set active indicator mask. */
-       outw(AckIntr | IntLatch | TxAvailable | RxEarly | IntReq,
+       iowrite16(AckIntr | IntLatch | TxAvailable | RxEarly | IntReq,
                 ioaddr + EL3_CMD);
-       outw(vp->intr_enable, ioaddr + EL3_CMD);
+       iowrite16(vp->intr_enable, ioaddr + EL3_CMD);
        if (vp->cb_fn_base)                     /* The PCMCIA people are idiots.  */
-               writel(0x8000, vp->cb_fn_base + 4);
+               iowrite32(0x8000, vp->cb_fn_base + 4);
        netif_start_queue (dev);
 }
 
@@ -1852,7 +1880,7 @@ vortex_timer(unsigned long data)
 {
        struct net_device *dev = (struct net_device *)data;
        struct vortex_private *vp = netdev_priv(dev);
-       long ioaddr = dev->base_addr;
+       void __iomem *ioaddr = vp->ioaddr;
        int next_tick = 60*HZ;
        int ok = 0;
        int media_status, mii_status, old_window;
@@ -1866,9 +1894,9 @@ vortex_timer(unsigned long data)
        if (vp->medialock)
                goto leave_media_alone;
        disable_irq(dev->irq);
-       old_window = inw(ioaddr + EL3_CMD) >> 13;
+       old_window = ioread16(ioaddr + EL3_CMD) >> 13;
        EL3WINDOW(4);
-       media_status = inw(ioaddr + Wn4_Media);
+       media_status = ioread16(ioaddr + Wn4_Media);
        switch (dev->if_port) {
        case XCVR_10baseT:  case XCVR_100baseTx:  case XCVR_100baseFx:
                if (media_status & Media_LnkBeat) {
@@ -1888,14 +1916,17 @@ vortex_timer(unsigned long data)
        case XCVR_MII: case XCVR_NWAY:
                {
                        spin_lock_bh(&vp->lock);
-                       mii_status = mdio_read(dev, vp->phys[0], 1);
-                       mii_status = mdio_read(dev, vp->phys[0], 1);
+                       mii_status = mdio_read(dev, vp->phys[0], MII_BMSR);
+                       if (!(mii_status & BMSR_LSTATUS)) {
+                               /* Re-read to get actual link status */
+                               mii_status = mdio_read(dev, vp->phys[0], MII_BMSR);
+                       }
                        ok = 1;
                        if (vortex_debug > 2)
                                printk(KERN_DEBUG "%s: MII transceiver has status %4.4x.\n",
                                        dev->name, mii_status);
                        if (mii_status & BMSR_LSTATUS) {
-                               int mii_reg5 = mdio_read(dev, vp->phys[0], 5);
+                               int mii_reg5 = mdio_read(dev, vp->phys[0], MII_LPA);
                                if (! vp->force_fd  &&  mii_reg5 != 0xffff) {
                                        int duplex;
 
@@ -1909,7 +1940,7 @@ vortex_timer(unsigned long data)
                                                        vp->phys[0], mii_reg5);
                                                /* Set the full-duplex bit. */
                                                EL3WINDOW(3);
-                                               outw(   (vp->full_duplex ? 0x20 : 0) |
+                                               iowrite16(      (vp->full_duplex ? 0x20 : 0) |
                                                                (vp->large_frames ? 0x40 : 0) |
                                                                ((vp->full_duplex && vp->flow_ctrl && vp->partner_flow_ctrl) ? 0x100 : 0),
                                                                ioaddr + Wn3_MAC_Ctrl);
@@ -1950,15 +1981,15 @@ vortex_timer(unsigned long data)
                                           dev->name, media_tbl[dev->if_port].name);
                        next_tick = media_tbl[dev->if_port].wait;
                }
-               outw((media_status & ~(Media_10TP|Media_SQE)) |
+               iowrite16((media_status & ~(Media_10TP|Media_SQE)) |
                         media_tbl[dev->if_port].media_bits, ioaddr + Wn4_Media);
 
                EL3WINDOW(3);
-               config = inl(ioaddr + Wn3_Config);
+               config = ioread32(ioaddr + Wn3_Config);
                config = BFINS(config, dev->if_port, 20, 4);
-               outl(config, ioaddr + Wn3_Config);
+               iowrite32(config, ioaddr + Wn3_Config);
 
-               outw(dev->if_port == XCVR_10base2 ? StartCoax : StopCoax,
+               iowrite16(dev->if_port == XCVR_10base2 ? StartCoax : StopCoax,
                         ioaddr + EL3_CMD);
                if (vortex_debug > 1)
                        printk(KERN_DEBUG "wrote 0x%08x to Wn3_Config\n", config);
@@ -1974,29 +2005,29 @@ leave_media_alone:
 
        mod_timer(&vp->timer, RUN_AT(next_tick));
        if (vp->deferred)
-               outw(FakeIntr, ioaddr + EL3_CMD);
+               iowrite16(FakeIntr, ioaddr + EL3_CMD);
        return;
 }
 
 static void vortex_tx_timeout(struct net_device *dev)
 {
        struct vortex_private *vp = netdev_priv(dev);
-       long ioaddr = dev->base_addr;
+       void __iomem *ioaddr = vp->ioaddr;
 
        printk(KERN_ERR "%s: transmit timed out, tx_status %2.2x status %4.4x.\n",
-                  dev->name, inb(ioaddr + TxStatus),
-                  inw(ioaddr + EL3_STATUS));
+                  dev->name, ioread8(ioaddr + TxStatus),
+                  ioread16(ioaddr + EL3_STATUS));
        EL3WINDOW(4);
        printk(KERN_ERR "  diagnostics: net %04x media %04x dma %08x fifo %04x\n",
-                       inw(ioaddr + Wn4_NetDiag),
-                       inw(ioaddr + Wn4_Media),
-                       inl(ioaddr + PktStatus),
-                       inw(ioaddr + Wn4_FIFODiag));
+                       ioread16(ioaddr + Wn4_NetDiag),
+                       ioread16(ioaddr + Wn4_Media),
+                       ioread32(ioaddr + PktStatus),
+                       ioread16(ioaddr + Wn4_FIFODiag));
        /* Slight code bloat to be user friendly. */
-       if ((inb(ioaddr + TxStatus) & 0x88) == 0x88)
+       if ((ioread8(ioaddr + TxStatus) & 0x88) == 0x88)
                printk(KERN_ERR "%s: Transmitter encountered 16 collisions --"
                           " network cable problem?\n", dev->name);
-       if (inw(ioaddr + EL3_STATUS) & IntLatch) {
+       if (ioread16(ioaddr + EL3_STATUS) & IntLatch) {
                printk(KERN_ERR "%s: Interrupt posted but not delivered --"
                           " IRQ blocked by another device?\n", dev->name);
                /* Bad idea here.. but we might as well handle a few events. */
@@ -2022,21 +2053,21 @@ static void vortex_tx_timeout(struct net_device *dev)
        vp->stats.tx_errors++;
        if (vp->full_bus_master_tx) {
                printk(KERN_DEBUG "%s: Resetting the Tx ring pointer.\n", dev->name);
-               if (vp->cur_tx - vp->dirty_tx > 0  &&  inl(ioaddr + DownListPtr) == 0)
-                       outl(vp->tx_ring_dma + (vp->dirty_tx % TX_RING_SIZE) * sizeof(struct boom_tx_desc),
+               if (vp->cur_tx - vp->dirty_tx > 0  &&  ioread32(ioaddr + DownListPtr) == 0)
+                       iowrite32(vp->tx_ring_dma + (vp->dirty_tx % TX_RING_SIZE) * sizeof(struct boom_tx_desc),
                                 ioaddr + DownListPtr);
                if (vp->cur_tx - vp->dirty_tx < TX_RING_SIZE)
                        netif_wake_queue (dev);
                if (vp->drv_flags & IS_BOOMERANG)
-                       outb(PKT_BUF_SZ>>8, ioaddr + TxFreeThreshold);
-               outw(DownUnstall, ioaddr + EL3_CMD);
+                       iowrite8(PKT_BUF_SZ>>8, ioaddr + TxFreeThreshold);
+               iowrite16(DownUnstall, ioaddr + EL3_CMD);
        } else {
                vp->stats.tx_dropped++;
                netif_wake_queue(dev);
        }
        
        /* Issue Tx Enable */
-       outw(TxEnable, ioaddr + EL3_CMD);
+       iowrite16(TxEnable, ioaddr + EL3_CMD);
        dev->trans_start = jiffies;
        
        /* Switch to register set 7 for normal use. */
@@ -2051,7 +2082,7 @@ static void
 vortex_error(struct net_device *dev, int status)
 {
        struct vortex_private *vp = netdev_priv(dev);
-       long ioaddr = dev->base_addr;
+       void __iomem *ioaddr = vp->ioaddr;
        int do_tx_reset = 0, reset_mask = 0;
        unsigned char tx_status = 0;
 
@@ -2060,7 +2091,7 @@ vortex_error(struct net_device *dev, int status)
        }
 
        if (status & TxComplete) {                      /* Really "TxError" for us. */
-               tx_status = inb(ioaddr + TxStatus);
+               tx_status = ioread8(ioaddr + TxStatus);
                /* Presumably a tx-timeout. We must merely re-enable. */
                if (vortex_debug > 2
                        || (tx_status != 0x88 && vortex_debug > 0)) {
@@ -2074,20 +2105,20 @@ vortex_error(struct net_device *dev, int status)
                }
                if (tx_status & 0x14)  vp->stats.tx_fifo_errors++;
                if (tx_status & 0x38)  vp->stats.tx_aborted_errors++;
-               outb(0, ioaddr + TxStatus);
+               iowrite8(0, ioaddr + TxStatus);
                if (tx_status & 0x30) {                 /* txJabber or txUnderrun */
                        do_tx_reset = 1;
                } else if ((tx_status & 0x08) && (vp->drv_flags & MAX_COLLISION_RESET)) {       /* maxCollisions */
                        do_tx_reset = 1;
                        reset_mask = 0x0108;            /* Reset interface logic, but not download logic */
                } else {                                                /* Merely re-enable the transmitter. */
-                       outw(TxEnable, ioaddr + EL3_CMD);
+                       iowrite16(TxEnable, ioaddr + EL3_CMD);
                }
        }
 
        if (status & RxEarly) {                         /* Rx early is unused. */
                vortex_rx(dev);
-               outw(AckIntr | RxEarly, ioaddr + EL3_CMD);
+               iowrite16(AckIntr | RxEarly, ioaddr + EL3_CMD);
        }
        if (status & StatsFull) {                       /* Empty statistics. */
                static int DoneDidThat;
@@ -2097,29 +2128,29 @@ vortex_error(struct net_device *dev, int status)
                /* HACK: Disable statistics as an interrupt source. */
                /* This occurs when we have the wrong media type! */
                if (DoneDidThat == 0  &&
-                       inw(ioaddr + EL3_STATUS) & StatsFull) {
+                       ioread16(ioaddr + EL3_STATUS) & StatsFull) {
                        printk(KERN_WARNING "%s: Updating statistics failed, disabling "
                                   "stats as an interrupt source.\n", dev->name);
                        EL3WINDOW(5);
-                       outw(SetIntrEnb | (inw(ioaddr + 10) & ~StatsFull), ioaddr + EL3_CMD);
+                       iowrite16(SetIntrEnb | (ioread16(ioaddr + 10) & ~StatsFull), ioaddr + EL3_CMD);
                        vp->intr_enable &= ~StatsFull;
                        EL3WINDOW(7);
                        DoneDidThat++;
                }
        }
        if (status & IntReq) {          /* Restore all interrupt sources.  */
-               outw(vp->status_enable, ioaddr + EL3_CMD);
-               outw(vp->intr_enable, ioaddr + EL3_CMD);
+               iowrite16(vp->status_enable, ioaddr + EL3_CMD);
+               iowrite16(vp->intr_enable, ioaddr + EL3_CMD);
        }
        if (status & HostError) {
                u16 fifo_diag;
                EL3WINDOW(4);
-               fifo_diag = inw(ioaddr + Wn4_FIFODiag);
+               fifo_diag = ioread16(ioaddr + Wn4_FIFODiag);
                printk(KERN_ERR "%s: Host error, FIFO diagnostic register %4.4x.\n",
                           dev->name, fifo_diag);
                /* Adapter failure requires Tx/Rx reset and reinit. */
                if (vp->full_bus_master_tx) {
-                       int bus_status = inl(ioaddr + PktStatus);
+                       int bus_status = ioread32(ioaddr + PktStatus);
                        /* 0x80000000 PCI master abort. */
                        /* 0x40000000 PCI target abort. */
                        if (vortex_debug)
@@ -2139,14 +2170,14 @@ vortex_error(struct net_device *dev, int status)
                        set_rx_mode(dev);
                        /* enable 802.1q VLAN tagged frames */
                        set_8021q_mode(dev, 1);
-                       outw(RxEnable, ioaddr + EL3_CMD); /* Re-enable the receiver. */
-                       outw(AckIntr | HostError, ioaddr + EL3_CMD);
+                       iowrite16(RxEnable, ioaddr + EL3_CMD); /* Re-enable the receiver. */
+                       iowrite16(AckIntr | HostError, ioaddr + EL3_CMD);
                }
        }
 
        if (do_tx_reset) {
                issue_and_wait(dev, TxReset|reset_mask);
-               outw(TxEnable, ioaddr + EL3_CMD);
+               iowrite16(TxEnable, ioaddr + EL3_CMD);
                if (!vp->full_bus_master_tx)
                        netif_wake_queue(dev);
        }
@@ -2156,29 +2187,29 @@ static int
 vortex_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
        struct vortex_private *vp = netdev_priv(dev);
-       long ioaddr = dev->base_addr;
+       void __iomem *ioaddr = vp->ioaddr;
 
        /* Put out the doubleword header... */
-       outl(skb->len, ioaddr + TX_FIFO);
+       iowrite32(skb->len, ioaddr + TX_FIFO);
        if (vp->bus_master) {
                /* Set the bus-master controller to transfer the packet. */
                int len = (skb->len + 3) & ~3;
-               outl(   vp->tx_skb_dma = pci_map_single(VORTEX_PCI(vp), skb->data, len, PCI_DMA_TODEVICE),
+               iowrite32(      vp->tx_skb_dma = pci_map_single(VORTEX_PCI(vp), skb->data, len, PCI_DMA_TODEVICE),
                                ioaddr + Wn7_MasterAddr);
-               outw(len, ioaddr + Wn7_MasterLen);
+               iowrite16(len, ioaddr + Wn7_MasterLen);
                vp->tx_skb = skb;
-               outw(StartDMADown, ioaddr + EL3_CMD);
+               iowrite16(StartDMADown, ioaddr + EL3_CMD);
                /* netif_wake_queue() will be called at the DMADone interrupt. */
        } else {
                /* ... and the packet rounded to a doubleword. */
-               outsl(ioaddr + TX_FIFO, skb->data, (skb->len + 3) >> 2);
+               iowrite32_rep(ioaddr + TX_FIFO, skb->data, (skb->len + 3) >> 2);
                dev_kfree_skb (skb);
-               if (inw(ioaddr + TxFree) > 1536) {
+               if (ioread16(ioaddr + TxFree) > 1536) {
                        netif_start_queue (dev);        /* AKPM: redundant? */
                } else {
                        /* Interrupt us when the FIFO has room for max-sized packet. */
                        netif_stop_queue(dev);
-                       outw(SetTxThreshold + (1536>>2), ioaddr + EL3_CMD);
+                       iowrite16(SetTxThreshold + (1536>>2), ioaddr + EL3_CMD);
                }
        }
 
@@ -2189,7 +2220,7 @@ vortex_start_xmit(struct sk_buff *skb, struct net_device *dev)
                int tx_status;
                int i = 32;
 
-               while (--i > 0  &&      (tx_status = inb(ioaddr + TxStatus)) > 0) {
+               while (--i > 0  &&      (tx_status = ioread8(ioaddr + TxStatus)) > 0) {
                        if (tx_status & 0x3C) {         /* A Tx-disabling error occurred.  */
                                if (vortex_debug > 2)
                                  printk(KERN_DEBUG "%s: Tx error, status %2.2x.\n",
@@ -2199,9 +2230,9 @@ vortex_start_xmit(struct sk_buff *skb, struct net_device *dev)
                                if (tx_status & 0x30) {
                                        issue_and_wait(dev, TxReset);
                                }
-                               outw(TxEnable, ioaddr + EL3_CMD);
+                               iowrite16(TxEnable, ioaddr + EL3_CMD);
                        }
-                       outb(0x00, ioaddr + TxStatus); /* Pop the status stack. */
+                       iowrite8(0x00, ioaddr + TxStatus); /* Pop the status stack. */
                }
        }
        return 0;
@@ -2211,7 +2242,7 @@ static int
 boomerang_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
        struct vortex_private *vp = netdev_priv(dev);
-       long ioaddr = dev->base_addr;
+       void __iomem *ioaddr = vp->ioaddr;
        /* Calculate the next Tx descriptor entry. */
        int entry = vp->cur_tx % TX_RING_SIZE;
        struct boom_tx_desc *prev_entry = &vp->tx_ring[(vp->cur_tx-1) % TX_RING_SIZE];
@@ -2275,8 +2306,8 @@ boomerang_start_xmit(struct sk_buff *skb, struct net_device *dev)
        /* Wait for the stall to complete. */
        issue_and_wait(dev, DownStall);
        prev_entry->next = cpu_to_le32(vp->tx_ring_dma + entry * sizeof(struct boom_tx_desc));
-       if (inl(ioaddr + DownListPtr) == 0) {
-               outl(vp->tx_ring_dma + entry * sizeof(struct boom_tx_desc), ioaddr + DownListPtr);
+       if (ioread32(ioaddr + DownListPtr) == 0) {
+               iowrite32(vp->tx_ring_dma + entry * sizeof(struct boom_tx_desc), ioaddr + DownListPtr);
                vp->queued_packet++;
        }
 
@@ -2291,7 +2322,7 @@ boomerang_start_xmit(struct sk_buff *skb, struct net_device *dev)
                prev_entry->status &= cpu_to_le32(~TxIntrUploaded);
 #endif
        }
-       outw(DownUnstall, ioaddr + EL3_CMD);
+       iowrite16(DownUnstall, ioaddr + EL3_CMD);
        spin_unlock_irqrestore(&vp->lock, flags);
        dev->trans_start = jiffies;
        return 0;
@@ -2310,15 +2341,15 @@ vortex_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
        struct net_device *dev = dev_id;
        struct vortex_private *vp = netdev_priv(dev);
-       long ioaddr;
+       void __iomem *ioaddr;
        int status;
        int work_done = max_interrupt_work;
        int handled = 0;
 
-       ioaddr = dev->base_addr;
+       ioaddr = vp->ioaddr;
        spin_lock(&vp->lock);
 
-       status = inw(ioaddr + EL3_STATUS);
+       status = ioread16(ioaddr + EL3_STATUS);
 
        if (vortex_debug > 6)
                printk("vortex_interrupt(). status=0x%4x\n", status);
@@ -2337,7 +2368,7 @@ vortex_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 
        if (vortex_debug > 4)
                printk(KERN_DEBUG "%s: interrupt, status %4.4x, latency %d ticks.\n",
-                          dev->name, status, inb(ioaddr + Timer));
+                          dev->name, status, ioread8(ioaddr + Timer));
 
        do {
                if (vortex_debug > 5)
@@ -2350,16 +2381,16 @@ vortex_interrupt(int irq, void *dev_id, struct pt_regs *regs)
                        if (vortex_debug > 5)
                                printk(KERN_DEBUG "     TX room bit was handled.\n");
                        /* There's room in the FIFO for a full-sized packet. */
-                       outw(AckIntr | TxAvailable, ioaddr + EL3_CMD);
+                       iowrite16(AckIntr | TxAvailable, ioaddr + EL3_CMD);
                        netif_wake_queue (dev);
                }
 
                if (status & DMADone) {
-                       if (inw(ioaddr + Wn7_MasterStatus) & 0x1000) {
-                               outw(0x1000, ioaddr + Wn7_MasterStatus); /* Ack the event. */
+                       if (ioread16(ioaddr + Wn7_MasterStatus) & 0x1000) {
+                               iowrite16(0x1000, ioaddr + Wn7_MasterStatus); /* Ack the event. */
                                pci_unmap_single(VORTEX_PCI(vp), vp->tx_skb_dma, (vp->tx_skb->len + 3) & ~3, PCI_DMA_TODEVICE);
                                dev_kfree_skb_irq(vp->tx_skb); /* Release the transferred buffer */
-                               if (inw(ioaddr + TxFree) > 1536) {
+                               if (ioread16(ioaddr + TxFree) > 1536) {
                                        /*
                                         * AKPM: FIXME: I don't think we need this.  If the queue was stopped due to
                                         * insufficient FIFO room, the TxAvailable test will succeed and call
@@ -2367,7 +2398,7 @@ vortex_interrupt(int irq, void *dev_id, struct pt_regs *regs)
                                         */
                                        netif_wake_queue(dev);
                                } else { /* Interrupt when FIFO has room for max-sized packet. */
-                                       outw(SetTxThreshold + (1536>>2), ioaddr + EL3_CMD);
+                                       iowrite16(SetTxThreshold + (1536>>2), ioaddr + EL3_CMD);
                                        netif_stop_queue(dev);
                                }
                        }
@@ -2385,17 +2416,17 @@ vortex_interrupt(int irq, void *dev_id, struct pt_regs *regs)
                        /* Disable all pending interrupts. */
                        do {
                                vp->deferred |= status;
-                               outw(SetStatusEnb | (~vp->deferred & vp->status_enable),
+                               iowrite16(SetStatusEnb | (~vp->deferred & vp->status_enable),
                                         ioaddr + EL3_CMD);
-                               outw(AckIntr | (vp->deferred & 0x7ff), ioaddr + EL3_CMD);
-                       } while ((status = inw(ioaddr + EL3_CMD)) & IntLatch);
+                               iowrite16(AckIntr | (vp->deferred & 0x7ff), ioaddr + EL3_CMD);
+                       } while ((status = ioread16(ioaddr + EL3_CMD)) & IntLatch);
                        /* The timer will reenable interrupts. */
                        mod_timer(&vp->timer, jiffies + 1*HZ);
                        break;
                }
                /* Acknowledge the IRQ. */
-               outw(AckIntr | IntReq | IntLatch, ioaddr + EL3_CMD);
-       } while ((status = inw(ioaddr + EL3_STATUS)) & (IntLatch | RxComplete));
+               iowrite16(AckIntr | IntReq | IntLatch, ioaddr + EL3_CMD);
+       } while ((status = ioread16(ioaddr + EL3_STATUS)) & (IntLatch | RxComplete));
 
        if (vortex_debug > 4)
                printk(KERN_DEBUG "%s: exiting interrupt, status %4.4x.\n",
@@ -2415,11 +2446,11 @@ boomerang_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
        struct net_device *dev = dev_id;
        struct vortex_private *vp = netdev_priv(dev);
-       long ioaddr;
+       void __iomem *ioaddr;
        int status;
        int work_done = max_interrupt_work;
 
-       ioaddr = dev->base_addr;
+       ioaddr = vp->ioaddr;
 
        /*
         * It seems dopey to put the spinlock this early, but we could race against vortex_tx_timeout
@@ -2427,7 +2458,7 @@ boomerang_interrupt(int irq, void *dev_id, struct pt_regs *regs)
         */
        spin_lock(&vp->lock);
 
-       status = inw(ioaddr + EL3_STATUS);
+       status = ioread16(ioaddr + EL3_STATUS);
 
        if (vortex_debug > 6)
                printk(KERN_DEBUG "boomerang_interrupt. status=0x%4x\n", status);
@@ -2448,13 +2479,13 @@ boomerang_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 
        if (vortex_debug > 4)
                printk(KERN_DEBUG "%s: interrupt, status %4.4x, latency %d ticks.\n",
-                          dev->name, status, inb(ioaddr + Timer));
+                          dev->name, status, ioread8(ioaddr + Timer));
        do {
                if (vortex_debug > 5)
                                printk(KERN_DEBUG "%s: In interrupt loop, status %4.4x.\n",
                                           dev->name, status);
                if (status & UpComplete) {
-                       outw(AckIntr | UpComplete, ioaddr + EL3_CMD);
+                       iowrite16(AckIntr | UpComplete, ioaddr + EL3_CMD);
                        if (vortex_debug > 5)
                                printk(KERN_DEBUG "boomerang_interrupt->boomerang_rx\n");
                        boomerang_rx(dev);
@@ -2463,11 +2494,11 @@ boomerang_interrupt(int irq, void *dev_id, struct pt_regs *regs)
                if (status & DownComplete) {
                        unsigned int dirty_tx = vp->dirty_tx;
 
-                       outw(AckIntr | DownComplete, ioaddr + EL3_CMD);
+                       iowrite16(AckIntr | DownComplete, ioaddr + EL3_CMD);
                        while (vp->cur_tx - dirty_tx > 0) {
                                int entry = dirty_tx % TX_RING_SIZE;
 #if 1  /* AKPM: the latter is faster, but cyclone-only */
-                               if (inl(ioaddr + DownListPtr) ==
+                               if (ioread32(ioaddr + DownListPtr) ==
                                        vp->tx_ring_dma + entry * sizeof(struct boom_tx_desc))
                                        break;                  /* It still hasn't been processed. */
 #else
@@ -2514,20 +2545,20 @@ boomerang_interrupt(int irq, void *dev_id, struct pt_regs *regs)
                        /* Disable all pending interrupts. */
                        do {
                                vp->deferred |= status;
-                               outw(SetStatusEnb | (~vp->deferred & vp->status_enable),
+                               iowrite16(SetStatusEnb | (~vp->deferred & vp->status_enable),
                                         ioaddr + EL3_CMD);
-                               outw(AckIntr | (vp->deferred & 0x7ff), ioaddr + EL3_CMD);
-                       } while ((status = inw(ioaddr + EL3_CMD)) & IntLatch);
+                               iowrite16(AckIntr | (vp->deferred & 0x7ff), ioaddr + EL3_CMD);
+                       } while ((status = ioread16(ioaddr + EL3_CMD)) & IntLatch);
                        /* The timer will reenable interrupts. */
                        mod_timer(&vp->timer, jiffies + 1*HZ);
                        break;
                }
                /* Acknowledge the IRQ. */
-               outw(AckIntr | IntReq | IntLatch, ioaddr + EL3_CMD);
+               iowrite16(AckIntr | IntReq | IntLatch, ioaddr + EL3_CMD);
                if (vp->cb_fn_base)                     /* The PCMCIA people are idiots.  */
-                       writel(0x8000, vp->cb_fn_base + 4);
+                       iowrite32(0x8000, vp->cb_fn_base + 4);
 
-       } while ((status = inw(ioaddr + EL3_STATUS)) & IntLatch);
+       } while ((status = ioread16(ioaddr + EL3_STATUS)) & IntLatch);
 
        if (vortex_debug > 4)
                printk(KERN_DEBUG "%s: exiting interrupt, status %4.4x.\n",
@@ -2540,16 +2571,16 @@ handler_exit:
 static int vortex_rx(struct net_device *dev)
 {
        struct vortex_private *vp = netdev_priv(dev);
-       long ioaddr = dev->base_addr;
+       void __iomem *ioaddr = vp->ioaddr;
        int i;
        short rx_status;
 
        if (vortex_debug > 5)
                printk(KERN_DEBUG "vortex_rx(): status %4.4x, rx_status %4.4x.\n",
-                          inw(ioaddr+EL3_STATUS), inw(ioaddr+RxStatus));
-       while ((rx_status = inw(ioaddr + RxStatus)) > 0) {
+                          ioread16(ioaddr+EL3_STATUS), ioread16(ioaddr+RxStatus));
+       while ((rx_status = ioread16(ioaddr + RxStatus)) > 0) {
                if (rx_status & 0x4000) { /* Error, update stats. */
-                       unsigned char rx_error = inb(ioaddr + RxErrors);
+                       unsigned char rx_error = ioread8(ioaddr + RxErrors);
                        if (vortex_debug > 2)
                                printk(KERN_DEBUG " Rx error: status %2.2x.\n", rx_error);
                        vp->stats.rx_errors++;
@@ -2572,34 +2603,35 @@ static int vortex_rx(struct net_device *dev)
                                skb_reserve(skb, 2);    /* Align IP on 16 byte boundaries */
                                /* 'skb_put()' points to the start of sk_buff data area. */
                                if (vp->bus_master &&
-                                       ! (inw(ioaddr + Wn7_MasterStatus) & 0x8000)) {
+                                       ! (ioread16(ioaddr + Wn7_MasterStatus) & 0x8000)) {
                                        dma_addr_t dma = pci_map_single(VORTEX_PCI(vp), skb_put(skb, pkt_len),
                                                                           pkt_len, PCI_DMA_FROMDEVICE);
-                                       outl(dma, ioaddr + Wn7_MasterAddr);
-                                       outw((skb->len + 3) & ~3, ioaddr + Wn7_MasterLen);
-                                       outw(StartDMAUp, ioaddr + EL3_CMD);
-                                       while (inw(ioaddr + Wn7_MasterStatus) & 0x8000)
+                                       iowrite32(dma, ioaddr + Wn7_MasterAddr);
+                                       iowrite16((skb->len + 3) & ~3, ioaddr + Wn7_MasterLen);
+                                       iowrite16(StartDMAUp, ioaddr + EL3_CMD);
+                                       while (ioread16(ioaddr + Wn7_MasterStatus) & 0x8000)
                                                ;
                                        pci_unmap_single(VORTEX_PCI(vp), dma, pkt_len, PCI_DMA_FROMDEVICE);
                                } else {
-                                       insl(ioaddr + RX_FIFO, skb_put(skb, pkt_len),
-                                                (pkt_len + 3) >> 2);
+                                       ioread32_rep(ioaddr + RX_FIFO,
+                                                    skb_put(skb, pkt_len),
+                                                    (pkt_len + 3) >> 2);
                                }
-                               outw(RxDiscard, ioaddr + EL3_CMD); /* Pop top Rx packet. */
+                               iowrite16(RxDiscard, ioaddr + EL3_CMD); /* Pop top Rx packet. */
                                skb->protocol = eth_type_trans(skb, dev);
                                netif_rx(skb);
                                dev->last_rx = jiffies;
                                vp->stats.rx_packets++;
                                /* Wait a limited time to go to next packet. */
                                for (i = 200; i >= 0; i--)
-                                       if ( ! (inw(ioaddr + EL3_STATUS) & CmdInProgress))
+                                       if ( ! (ioread16(ioaddr + EL3_STATUS) & CmdInProgress))
                                                break;
                                continue;
                        } else if (vortex_debug > 0)
                                printk(KERN_NOTICE "%s: No memory to allocate a sk_buff of "
                                           "size %d.\n", dev->name, pkt_len);
+                       vp->stats.rx_dropped++;
                }
-               vp->stats.rx_dropped++;
                issue_and_wait(dev, RxDiscard);
        }
 
@@ -2611,12 +2643,12 @@ boomerang_rx(struct net_device *dev)
 {
        struct vortex_private *vp = netdev_priv(dev);
        int entry = vp->cur_rx % RX_RING_SIZE;
-       long ioaddr = dev->base_addr;
+       void __iomem *ioaddr = vp->ioaddr;
        int rx_status;
        int rx_work_limit = vp->dirty_rx + RX_RING_SIZE - vp->cur_rx;
 
        if (vortex_debug > 5)
-               printk(KERN_DEBUG "boomerang_rx(): status %4.4x\n", inw(ioaddr+EL3_STATUS));
+               printk(KERN_DEBUG "boomerang_rx(): status %4.4x\n", ioread16(ioaddr+EL3_STATUS));
 
        while ((rx_status = le32_to_cpu(vp->rx_ring[entry].status)) & RxDComplete){
                if (--rx_work_limit < 0)
@@ -2699,7 +2731,7 @@ boomerang_rx(struct net_device *dev)
                        vp->rx_skbuff[entry] = skb;
                }
                vp->rx_ring[entry].status = 0;  /* Clear complete bit. */
-               outw(UpUnstall, ioaddr + EL3_CMD);
+               iowrite16(UpUnstall, ioaddr + EL3_CMD);
        }
        return 0;
 }
@@ -2728,7 +2760,7 @@ static void
 vortex_down(struct net_device *dev, int final_down)
 {
        struct vortex_private *vp = netdev_priv(dev);
-       long ioaddr = dev->base_addr;
+       void __iomem *ioaddr = vp->ioaddr;
 
        netif_stop_queue (dev);
 
@@ -2736,26 +2768,26 @@ vortex_down(struct net_device *dev, int final_down)
        del_timer_sync(&vp->timer);
 
        /* Turn off statistics ASAP.  We update vp->stats below. */
-       outw(StatsDisable, ioaddr + EL3_CMD);
+       iowrite16(StatsDisable, ioaddr + EL3_CMD);
 
        /* Disable the receiver and transmitter. */
-       outw(RxDisable, ioaddr + EL3_CMD);
-       outw(TxDisable, ioaddr + EL3_CMD);
+       iowrite16(RxDisable, ioaddr + EL3_CMD);
+       iowrite16(TxDisable, ioaddr + EL3_CMD);
 
        /* Disable receiving 802.1q tagged frames */
        set_8021q_mode(dev, 0);
 
        if (dev->if_port == XCVR_10base2)
                /* Turn off thinnet power.  Green! */
-               outw(StopCoax, ioaddr + EL3_CMD);
+               iowrite16(StopCoax, ioaddr + EL3_CMD);
 
-       outw(SetIntrEnb | 0x0000, ioaddr + EL3_CMD);
+       iowrite16(SetIntrEnb | 0x0000, ioaddr + EL3_CMD);
 
        update_stats(ioaddr, dev);
        if (vp->full_bus_master_rx)
-               outl(0, ioaddr + UpListPtr);
+               iowrite32(0, ioaddr + UpListPtr);
        if (vp->full_bus_master_tx)
-               outl(0, ioaddr + DownListPtr);
+               iowrite32(0, ioaddr + DownListPtr);
 
        if (final_down && VORTEX_PCI(vp)) {
                vp->pm_state_valid = 1;
@@ -2768,7 +2800,7 @@ static int
 vortex_close(struct net_device *dev)
 {
        struct vortex_private *vp = netdev_priv(dev);
-       long ioaddr = dev->base_addr;
+       void __iomem *ioaddr = vp->ioaddr;
        int i;
 
        if (netif_device_present(dev))
@@ -2776,17 +2808,18 @@ vortex_close(struct net_device *dev)
 
        if (vortex_debug > 1) {
                printk(KERN_DEBUG"%s: vortex_close() status %4.4x, Tx status %2.2x.\n",
-                          dev->name, inw(ioaddr + EL3_STATUS), inb(ioaddr + TxStatus));
+                          dev->name, ioread16(ioaddr + EL3_STATUS), ioread8(ioaddr + TxStatus));
                printk(KERN_DEBUG "%s: vortex close stats: rx_nocopy %d rx_copy %d"
                           " tx_queued %d Rx pre-checksummed %d.\n",
                           dev->name, vp->rx_nocopy, vp->rx_copy, vp->queued_packet, vp->rx_csumhits);
        }
 
 #if DO_ZEROCOPY
-       if (    vp->rx_csumhits &&
-                       ((vp->drv_flags & HAS_HWCKSM) == 0) &&
-                       (hw_checksums[vp->card_idx] == -1)) {
-               printk(KERN_WARNING "%s supports hardware checksums, and we're not using them!\n", dev->name);
+       if (vp->rx_csumhits &&
+           (vp->drv_flags & HAS_HWCKSM) == 0 &&
+           (vp->card_idx >= MAX_UNITS || hw_checksums[vp->card_idx] == -1)) {
+                       printk(KERN_WARNING "%s supports hardware checksums, and we're "
+                                               "not using them!\n", dev->name);
        }
 #endif
                
@@ -2830,18 +2863,18 @@ dump_tx_ring(struct net_device *dev)
 {
        if (vortex_debug > 0) {
        struct vortex_private *vp = netdev_priv(dev);
-               long ioaddr = dev->base_addr;
+               void __iomem *ioaddr = vp->ioaddr;
                
                if (vp->full_bus_master_tx) {
                        int i;
-                       int stalled = inl(ioaddr + PktStatus) & 0x04;   /* Possible racy. But it's only debug stuff */
+                       int stalled = ioread32(ioaddr + PktStatus) & 0x04;      /* Possible racy. But it's only debug stuff */
 
                        printk(KERN_ERR "  Flags; bus-master %d, dirty %d(%d) current %d(%d)\n",
                                        vp->full_bus_master_tx,
                                        vp->dirty_tx, vp->dirty_tx % TX_RING_SIZE,
                                        vp->cur_tx, vp->cur_tx % TX_RING_SIZE);
                        printk(KERN_ERR "  Transmit list %8.8x vs. %p.\n",
-                                  inl(ioaddr + DownListPtr),
+                                  ioread32(ioaddr + DownListPtr),
                                   &vp->tx_ring[vp->dirty_tx % TX_RING_SIZE]);
                        issue_and_wait(dev, DownStall);
                        for (i = 0; i < TX_RING_SIZE; i++) {
@@ -2855,7 +2888,7 @@ dump_tx_ring(struct net_device *dev)
                                           le32_to_cpu(vp->tx_ring[i].status));
                        }
                        if (!stalled)
-                               outw(DownUnstall, ioaddr + EL3_CMD);
+                               iowrite16(DownUnstall, ioaddr + EL3_CMD);
                }
        }
 }
@@ -2863,11 +2896,12 @@ dump_tx_ring(struct net_device *dev)
 static struct net_device_stats *vortex_get_stats(struct net_device *dev)
 {
        struct vortex_private *vp = netdev_priv(dev);
+       void __iomem *ioaddr = vp->ioaddr;
        unsigned long flags;
 
        if (netif_device_present(dev)) {        /* AKPM: Used to be netif_running */
                spin_lock_irqsave (&vp->lock, flags);
-               update_stats(dev->base_addr, dev);
+               update_stats(ioaddr, dev);
                spin_unlock_irqrestore (&vp->lock, flags);
        }
        return &vp->stats;
@@ -2880,37 +2914,37 @@ static struct net_device_stats *vortex_get_stats(struct net_device *dev)
        table.  This is done by checking that the ASM (!) code generated uses
        atomic updates with '+='.
        */
-static void update_stats(long ioaddr, struct net_device *dev)
+static void update_stats(void __iomem *ioaddr, struct net_device *dev)
 {
        struct vortex_private *vp = netdev_priv(dev);
-       int old_window = inw(ioaddr + EL3_CMD);
+       int old_window = ioread16(ioaddr + EL3_CMD);
 
        if (old_window == 0xffff)       /* Chip suspended or ejected. */
                return;
        /* Unlike the 3c5x9 we need not turn off stats updates while reading. */
        /* Switch to the stats window, and read everything. */
        EL3WINDOW(6);
-       vp->stats.tx_carrier_errors             += inb(ioaddr + 0);
-       vp->stats.tx_heartbeat_errors           += inb(ioaddr + 1);
-       vp->stats.collisions                    += inb(ioaddr + 3);
-       vp->stats.tx_window_errors              += inb(ioaddr + 4);
-       vp->stats.rx_fifo_errors                += inb(ioaddr + 5);
-       vp->stats.tx_packets                    += inb(ioaddr + 6);
-       vp->stats.tx_packets                    += (inb(ioaddr + 9)&0x30) << 4;
-       /* Rx packets   */                      inb(ioaddr + 7);   /* Must read to clear */
+       vp->stats.tx_carrier_errors             += ioread8(ioaddr + 0);
+       vp->stats.tx_heartbeat_errors           += ioread8(ioaddr + 1);
+       vp->stats.collisions                    += ioread8(ioaddr + 3);
+       vp->stats.tx_window_errors              += ioread8(ioaddr + 4);
+       vp->stats.rx_fifo_errors                += ioread8(ioaddr + 5);
+       vp->stats.tx_packets                    += ioread8(ioaddr + 6);
+       vp->stats.tx_packets                    += (ioread8(ioaddr + 9)&0x30) << 4;
+       /* Rx packets   */                      ioread8(ioaddr + 7);   /* Must read to clear */
        /* Don't bother with register 9, an extension of registers 6&7.
           If we do use the 6&7 values the atomic update assumption above
           is invalid. */
-       vp->stats.rx_bytes                      += inw(ioaddr + 10);
-       vp->stats.tx_bytes                      += inw(ioaddr + 12);
+       vp->stats.rx_bytes                      += ioread16(ioaddr + 10);
+       vp->stats.tx_bytes                      += ioread16(ioaddr + 12);
        /* Extra stats for get_ethtool_stats() */
-       vp->xstats.tx_multiple_collisions       += inb(ioaddr + 2);
-       vp->xstats.tx_deferred                  += inb(ioaddr + 8);
+       vp->xstats.tx_multiple_collisions       += ioread8(ioaddr + 2);
+       vp->xstats.tx_deferred                  += ioread8(ioaddr + 8);
        EL3WINDOW(4);
-       vp->xstats.rx_bad_ssd                   += inb(ioaddr + 12);
+       vp->xstats.rx_bad_ssd                   += ioread8(ioaddr + 12);
 
        {
-               u8 up = inb(ioaddr + 13);
+               u8 up = ioread8(ioaddr + 13);
                vp->stats.rx_bytes += (up & 0x0f) << 16;
                vp->stats.tx_bytes += (up & 0xf0) << 12;
        }
@@ -2922,7 +2956,7 @@ static void update_stats(long ioaddr, struct net_device *dev)
 static int vortex_nway_reset(struct net_device *dev)
 {
        struct vortex_private *vp = netdev_priv(dev);
-       long ioaddr = dev->base_addr;
+       void __iomem *ioaddr = vp->ioaddr;
        unsigned long flags;
        int rc;
 
@@ -2936,7 +2970,7 @@ static int vortex_nway_reset(struct net_device *dev)
 static u32 vortex_get_link(struct net_device *dev)
 {
        struct vortex_private *vp = netdev_priv(dev);
-       long ioaddr = dev->base_addr;
+       void __iomem *ioaddr = vp->ioaddr;
        unsigned long flags;
        int rc;
 
@@ -2950,7 +2984,7 @@ static u32 vortex_get_link(struct net_device *dev)
 static int vortex_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 {
        struct vortex_private *vp = netdev_priv(dev);
-       long ioaddr = dev->base_addr;
+       void __iomem *ioaddr = vp->ioaddr;
        unsigned long flags;
        int rc;
 
@@ -2964,7 +2998,7 @@ static int vortex_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 static int vortex_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 {
        struct vortex_private *vp = netdev_priv(dev);
-       long ioaddr = dev->base_addr;
+       void __iomem *ioaddr = vp->ioaddr;
        unsigned long flags;
        int rc;
 
@@ -2994,10 +3028,11 @@ static void vortex_get_ethtool_stats(struct net_device *dev,
        struct ethtool_stats *stats, u64 *data)
 {
        struct vortex_private *vp = netdev_priv(dev);
+       void __iomem *ioaddr = vp->ioaddr;
        unsigned long flags;
 
        spin_lock_irqsave(&vp->lock, flags);
-       update_stats(dev->base_addr, dev);
+       update_stats(ioaddr, dev);
        spin_unlock_irqrestore(&vp->lock, flags);
 
        data[0] = vp->xstats.tx_deferred;
@@ -3047,6 +3082,7 @@ static struct ethtool_ops vortex_ethtool_ops = {
        .set_settings           = vortex_set_settings,
        .get_link               = vortex_get_link,
        .nway_reset             = vortex_nway_reset,
+       .get_perm_addr                  = ethtool_op_get_perm_addr,
 };
 
 #ifdef CONFIG_PCI
@@ -3057,7 +3093,7 @@ static int vortex_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
        int err;
        struct vortex_private *vp = netdev_priv(dev);
-       long ioaddr = dev->base_addr;
+       void __iomem *ioaddr = vp->ioaddr;
        unsigned long flags;
        int state = 0;
 
@@ -3085,7 +3121,8 @@ static int vortex_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
    the chip has a very clean way to set the mode, unlike many others. */
 static void set_rx_mode(struct net_device *dev)
 {
-       long ioaddr = dev->base_addr;
+       struct vortex_private *vp = netdev_priv(dev);
+       void __iomem *ioaddr = vp->ioaddr;
        int new_mode;
 
        if (dev->flags & IFF_PROMISC) {
@@ -3097,7 +3134,7 @@ static void set_rx_mode(struct net_device *dev)
        } else
                new_mode = SetRxFilter | RxStation | RxBroadcast;
 
-       outw(new_mode, ioaddr + EL3_CMD);
+       iowrite16(new_mode, ioaddr + EL3_CMD);
 }
 
 #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
@@ -3111,8 +3148,8 @@ static void set_rx_mode(struct net_device *dev)
 static void set_8021q_mode(struct net_device *dev, int enable)
 {
        struct vortex_private *vp = netdev_priv(dev);
-       long ioaddr = dev->base_addr;
-       int old_window = inw(ioaddr + EL3_CMD);
+       void __iomem *ioaddr = vp->ioaddr;
+       int old_window = ioread16(ioaddr + EL3_CMD);
        int mac_ctrl;
 
        if ((vp->drv_flags&IS_CYCLONE) || (vp->drv_flags&IS_TORNADO)) {
@@ -3124,24 +3161,24 @@ static void set_8021q_mode(struct net_device *dev, int enable)
                        max_pkt_size += 4;      /* 802.1Q VLAN tag */
 
                EL3WINDOW(3);
-               outw(max_pkt_size, ioaddr+Wn3_MaxPktSize);
+               iowrite16(max_pkt_size, ioaddr+Wn3_MaxPktSize);
 
                /* set VlanEtherType to let the hardware checksumming
                   treat tagged frames correctly */
                EL3WINDOW(7);
-               outw(VLAN_ETHER_TYPE, ioaddr+Wn7_VlanEtherType);
+               iowrite16(VLAN_ETHER_TYPE, ioaddr+Wn7_VlanEtherType);
        } else {
                /* on older cards we have to enable large frames */
 
                vp->large_frames = dev->mtu > 1500 || enable;
 
                EL3WINDOW(3);
-               mac_ctrl = inw(ioaddr+Wn3_MAC_Ctrl);
+               mac_ctrl = ioread16(ioaddr+Wn3_MAC_Ctrl);
                if (vp->large_frames)
                        mac_ctrl |= 0x40;
                else
                        mac_ctrl &= ~0x40;
-               outw(mac_ctrl, ioaddr+Wn3_MAC_Ctrl);
+               iowrite16(mac_ctrl, ioaddr+Wn3_MAC_Ctrl);
        }
 
        EL3WINDOW(old_window);
@@ -3163,7 +3200,7 @@ static void set_8021q_mode(struct net_device *dev, int enable)
 /* The maximum data clock rate is 2.5 Mhz.  The minimum timing is usually
    met by back-to-back PCI I/O cycles, but we insert a delay to avoid
    "overclocking" issues. */
-#define mdio_delay() inl(mdio_addr)
+#define mdio_delay() ioread32(mdio_addr)
 
 #define MDIO_SHIFT_CLK 0x01
 #define MDIO_DIR_WRITE 0x04
@@ -3174,15 +3211,15 @@ static void set_8021q_mode(struct net_device *dev, int enable)
 
 /* Generate the preamble required for initial synchronization and
    a few older transceivers. */
-static void mdio_sync(long ioaddr, int bits)
+static void mdio_sync(void __iomem *ioaddr, int bits)
 {
-       long mdio_addr = ioaddr + Wn4_PhysicalMgmt;
+       void __iomem *mdio_addr = ioaddr + Wn4_PhysicalMgmt;
 
        /* Establish sync by sending at least 32 logic ones. */
        while (-- bits >= 0) {
-               outw(MDIO_DATA_WRITE1, mdio_addr);
+               iowrite16(MDIO_DATA_WRITE1, mdio_addr);
                mdio_delay();
-               outw(MDIO_DATA_WRITE1 | MDIO_SHIFT_CLK, mdio_addr);
+               iowrite16(MDIO_DATA_WRITE1 | MDIO_SHIFT_CLK, mdio_addr);
                mdio_delay();
        }
 }
@@ -3190,10 +3227,11 @@ static void mdio_sync(long ioaddr, int bits)
 static int mdio_read(struct net_device *dev, int phy_id, int location)
 {
        int i;
-       long ioaddr = dev->base_addr;
+       struct vortex_private *vp = netdev_priv(dev);
+       void __iomem *ioaddr = vp->ioaddr;
        int read_cmd = (0xf6 << 10) | (phy_id << 5) | location;
        unsigned int retval = 0;
-       long mdio_addr = ioaddr + Wn4_PhysicalMgmt;
+       void __iomem *mdio_addr = ioaddr + Wn4_PhysicalMgmt;
 
        if (mii_preamble_required)
                mdio_sync(ioaddr, 32);
@@ -3201,17 +3239,17 @@ static int mdio_read(struct net_device *dev, int phy_id, int location)
        /* Shift the read command bits out. */
        for (i = 14; i >= 0; i--) {
                int dataval = (read_cmd&(1<<i)) ? MDIO_DATA_WRITE1 : MDIO_DATA_WRITE0;
-               outw(dataval, mdio_addr);
+               iowrite16(dataval, mdio_addr);
                mdio_delay();
-               outw(dataval | MDIO_SHIFT_CLK, mdio_addr);
+               iowrite16(dataval | MDIO_SHIFT_CLK, mdio_addr);
                mdio_delay();
        }
        /* Read the two transition, 16 data, and wire-idle bits. */
        for (i = 19; i > 0; i--) {
-               outw(MDIO_ENB_IN, mdio_addr);
+               iowrite16(MDIO_ENB_IN, mdio_addr);
                mdio_delay();
-               retval = (retval << 1) | ((inw(mdio_addr) & MDIO_DATA_READ) ? 1 : 0);
-               outw(MDIO_ENB_IN | MDIO_SHIFT_CLK, mdio_addr);
+               retval = (retval << 1) | ((ioread16(mdio_addr) & MDIO_DATA_READ) ? 1 : 0);
+               iowrite16(MDIO_ENB_IN | MDIO_SHIFT_CLK, mdio_addr);
                mdio_delay();
        }
        return retval & 0x20000 ? 0xffff : retval>>1 & 0xffff;
@@ -3219,9 +3257,10 @@ static int mdio_read(struct net_device *dev, int phy_id, int location)
 
 static void mdio_write(struct net_device *dev, int phy_id, int location, int value)
 {
-       long ioaddr = dev->base_addr;
+       struct vortex_private *vp = netdev_priv(dev);
+       void __iomem *ioaddr = vp->ioaddr;
        int write_cmd = 0x50020000 | (phy_id << 23) | (location << 18) | value;
-       long mdio_addr = ioaddr + Wn4_PhysicalMgmt;
+       void __iomem *mdio_addr = ioaddr + Wn4_PhysicalMgmt;
        int i;
 
        if (mii_preamble_required)
@@ -3230,16 +3269,16 @@ static void mdio_write(struct net_device *dev, int phy_id, int location, int val
        /* Shift the command bits out. */
        for (i = 31; i >= 0; i--) {
                int dataval = (write_cmd&(1<<i)) ? MDIO_DATA_WRITE1 : MDIO_DATA_WRITE0;
-               outw(dataval, mdio_addr);
+               iowrite16(dataval, mdio_addr);
                mdio_delay();
-               outw(dataval | MDIO_SHIFT_CLK, mdio_addr);
+               iowrite16(dataval | MDIO_SHIFT_CLK, mdio_addr);
                mdio_delay();
        }
        /* Leave the interface idle. */
        for (i = 1; i >= 0; i--) {
-               outw(MDIO_ENB_IN, mdio_addr);
+               iowrite16(MDIO_ENB_IN, mdio_addr);
                mdio_delay();
-               outw(MDIO_ENB_IN | MDIO_SHIFT_CLK, mdio_addr);
+               iowrite16(MDIO_ENB_IN | MDIO_SHIFT_CLK, mdio_addr);
                mdio_delay();
        }
        return;
@@ -3250,15 +3289,15 @@ static void mdio_write(struct net_device *dev, int phy_id, int location, int val
 static void acpi_set_WOL(struct net_device *dev)
 {
        struct vortex_private *vp = netdev_priv(dev);
-       long ioaddr = dev->base_addr;
+       void __iomem *ioaddr = vp->ioaddr;
 
        if (vp->enable_wol) {
                /* Power up on: 1==Downloaded Filter, 2==Magic Packets, 4==Link Status. */
                EL3WINDOW(7);
-               outw(2, ioaddr + 0x0c);
+               iowrite16(2, ioaddr + 0x0c);
                /* The RxFilter must accept the WOL frames. */
-               outw(SetRxFilter|RxStation|RxMulticast|RxBroadcast, ioaddr + EL3_CMD);
-               outw(RxEnable, ioaddr + EL3_CMD);
+               iowrite16(SetRxFilter|RxStation|RxMulticast|RxBroadcast, ioaddr + EL3_CMD);
+               iowrite16(RxEnable, ioaddr + EL3_CMD);
 
                pci_enable_wake(VORTEX_PCI(vp), 0, 1);
 
@@ -3280,10 +3319,9 @@ static void __devexit vortex_remove_one (struct pci_dev *pdev)
 
        vp = netdev_priv(dev);
 
-       /* AKPM: FIXME: we should have
-        *      if (vp->cb_fn_base) iounmap(vp->cb_fn_base);
-        * here
-        */
+       if (vp->cb_fn_base)
+               pci_iounmap(VORTEX_PCI(vp), vp->cb_fn_base);
+
        unregister_netdev(dev);
 
        if (VORTEX_PCI(vp)) {
@@ -3293,8 +3331,10 @@ static void __devexit vortex_remove_one (struct pci_dev *pdev)
                pci_disable_device(VORTEX_PCI(vp));
        }
        /* Should really use issue_and_wait() here */
-       outw(TotalReset | ((vp->drv_flags & EEPROM_RESET) ? 0x04 : 0x14),
-            dev->base_addr + EL3_CMD);
+       iowrite16(TotalReset | ((vp->drv_flags & EEPROM_RESET) ? 0x04 : 0x14),
+            vp->ioaddr + EL3_CMD);
+
+       pci_iounmap(VORTEX_PCI(vp), vp->ioaddr);
 
        pci_free_consistent(pdev,
                                                sizeof(struct boom_rx_desc) * RX_RING_SIZE
@@ -3342,7 +3382,7 @@ static int __init vortex_init (void)
 static void __exit vortex_eisa_cleanup (void)
 {
        struct vortex_private *vp;
-       long ioaddr;
+       void __iomem *ioaddr;
 
 #ifdef CONFIG_EISA
        /* Take care of the EISA devices */
@@ -3351,11 +3391,13 @@ static void __exit vortex_eisa_cleanup (void)
        
        if (compaq_net_device) {
                vp = compaq_net_device->priv;
-               ioaddr = compaq_net_device->base_addr;
+               ioaddr = ioport_map(compaq_net_device->base_addr,
+                                   VORTEX_TOTAL_SIZE);
 
                unregister_netdev (compaq_net_device);
-               outw (TotalReset, ioaddr + EL3_CMD);
-               release_region (ioaddr, VORTEX_TOTAL_SIZE);
+               iowrite16 (TotalReset, ioaddr + EL3_CMD);
+               release_region(compaq_net_device->base_addr,
+                              VORTEX_TOTAL_SIZE);
 
                free_netdev (compaq_net_device);
        }
index 85504fb900dab5a62402a2ddc60e7ec5febe52e3..bd6983d1afbac77ed852c8991cb7b653d4272128 100644 (file)
@@ -18,8 +18,8 @@
  * Much better multiple PHY support by Magnus Damm.
  * Copyright (c) 2000 Ericsson Radio Systems AB.
  *
- * Support for FEC controller of ColdFire/5270/5271/5272/5274/5275/5280/5282.
- * Copyright (c) 2001-2004 Greg Ungerer (gerg@snapgear.com)
+ * Support for FEC controller of ColdFire processors.
+ * Copyright (c) 2001-2005 Greg Ungerer (gerg@snapgear.com)
  *
  * Bug fixes and cleanup by Philippe De Muyter (phdm@macqel.be)
  * Copyright (c) 2004-2005 Macq Electronique SA.
@@ -50,7 +50,8 @@
 #include <asm/pgtable.h>
 
 #if defined(CONFIG_M523x) || defined(CONFIG_M527x) || \
-    defined(CONFIG_M5272) || defined(CONFIG_M528x)
+    defined(CONFIG_M5272) || defined(CONFIG_M528x) || \
+    defined(CONFIG_M520x)
 #include <asm/coldfire.h>
 #include <asm/mcfsim.h>
 #include "fec.h"
@@ -77,6 +78,8 @@ static unsigned int fec_hw[] = {
        (MCF_MBAR + 0x1800),
 #elif defined(CONFIG_M523x) || defined(CONFIG_M528x)
        (MCF_MBAR + 0x1000),
+#elif defined(CONFIG_M520x)
+       (MCF_MBAR+0x30000),
 #else
        &(((immap_t *)IMAP_ADDR)->im_cpm.cp_fec),
 #endif
@@ -139,6 +142,10 @@ typedef struct {
 #define TX_RING_SIZE           16      /* Must be power of two */
 #define TX_RING_MOD_MASK       15      /*   for this to work */
 
+#if (((RX_RING_SIZE + TX_RING_SIZE) * 8) > PAGE_SIZE)
+#error "FEC: descriptor ring size contants too large"
+#endif
+
 /* Interrupt events/masks.
 */
 #define FEC_ENET_HBERR ((uint)0x80000000)      /* Heartbeat error */
@@ -164,7 +171,8 @@ typedef struct {
  * size bits. Other FEC hardware does not, so we need to take that into
  * account when setting it.
  */
-#if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x)
+#if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \
+    defined(CONFIG_M520x)
 #define        OPT_FRAME_SIZE  (PKT_MAXBUF_SIZE << 16)
 #else
 #define        OPT_FRAME_SIZE  0
@@ -1136,6 +1144,65 @@ static phy_info_t const phy_info_ks8721bl = {
        .shutdown = phy_cmd_ks8721bl_shutdown
 };
 
+/* ------------------------------------------------------------------------- */
+/* register definitions for the DP83848 */
+
+#define MII_DP8384X_PHYSTST    16  /* PHY Status Register */
+
+static void mii_parse_dp8384x_sr2(uint mii_reg, struct net_device *dev)
+{
+       struct fec_enet_private *fep = dev->priv;
+       volatile uint *s = &(fep->phy_status);
+
+       *s &= ~(PHY_STAT_SPMASK | PHY_STAT_LINK | PHY_STAT_ANC);
+
+       /* Link up */
+       if (mii_reg & 0x0001) {
+               fep->link = 1;
+               *s |= PHY_STAT_LINK;
+       } else
+               fep->link = 0;
+       /* Status of link */
+       if (mii_reg & 0x0010)   /* Autonegotioation complete */
+               *s |= PHY_STAT_ANC;
+       if (mii_reg & 0x0002) {   /* 10MBps? */
+               if (mii_reg & 0x0004)   /* Full Duplex? */
+                       *s |= PHY_STAT_10FDX;
+               else
+                       *s |= PHY_STAT_10HDX;
+       } else {                  /* 100 Mbps? */
+               if (mii_reg & 0x0004)   /* Full Duplex? */
+                       *s |= PHY_STAT_100FDX;
+               else
+                       *s |= PHY_STAT_100HDX;
+       }
+       if (mii_reg & 0x0008)
+               *s |= PHY_STAT_FAULT;
+}
+
+static phy_info_t phy_info_dp83848= {
+       0x020005c9,
+       "DP83848",
+
+       (const phy_cmd_t []) {  /* config */
+               { mk_mii_read(MII_REG_CR), mii_parse_cr },
+               { mk_mii_read(MII_REG_ANAR), mii_parse_anar },
+               { mk_mii_read(MII_DP8384X_PHYSTST), mii_parse_dp8384x_sr2 },
+               { mk_mii_end, }
+       },
+       (const phy_cmd_t []) {  /* startup - enable interrupts */
+               { mk_mii_write(MII_REG_CR, 0x1200), NULL }, /* autonegotiate */
+               { mk_mii_read(MII_REG_SR), mii_parse_sr },
+               { mk_mii_end, }
+       },
+       (const phy_cmd_t []) { /* ack_int - never happens, no interrupt */
+               { mk_mii_end, }
+       },
+       (const phy_cmd_t []) {  /* shutdown */
+               { mk_mii_end, }
+       },
+};
+
 /* ------------------------------------------------------------------------- */
 
 static phy_info_t const * const phy_info[] = {
@@ -1144,6 +1211,7 @@ static phy_info_t const * const phy_info[] = {
        &phy_info_qs6612,
        &phy_info_am79c874,
        &phy_info_ks8721bl,
+       &phy_info_dp83848,
        NULL
 };
 
@@ -1422,6 +1490,134 @@ static void __inline__ fec_uncache(unsigned long addr)
 
 /* ------------------------------------------------------------------------- */
 
+#elif defined(CONFIG_M520x)
+
+/*
+ *     Code specific to Coldfire 520x
+ */
+static void __inline__ fec_request_intrs(struct net_device *dev)
+{
+       struct fec_enet_private *fep;
+       int b;
+       static const struct idesc {
+               char *name;
+               unsigned short irq;
+       } *idp, id[] = {
+               { "fec(TXF)", 23 },
+               { "fec(TXB)", 24 },
+               { "fec(TXFIFO)", 25 },
+               { "fec(TXCR)", 26 },
+               { "fec(RXF)", 27 },
+               { "fec(RXB)", 28 },
+               { "fec(MII)", 29 },
+               { "fec(LC)", 30 },
+               { "fec(HBERR)", 31 },
+               { "fec(GRA)", 32 },
+               { "fec(EBERR)", 33 },
+               { "fec(BABT)", 34 },
+               { "fec(BABR)", 35 },
+               { NULL },
+       };
+
+       fep = netdev_priv(dev);
+       b = 64 + 13;
+
+       /* Setup interrupt handlers. */
+       for (idp = id; idp->name; idp++) {
+               if (request_irq(b+idp->irq,fec_enet_interrupt,0,idp->name,dev)!=0)
+                       printk("FEC: Could not allocate %s IRQ(%d)!\n", idp->name, b+idp->irq);
+       }
+
+       /* Unmask interrupts at ColdFire interrupt controller */
+       {
+               volatile unsigned char  *icrp;
+               volatile unsigned long  *imrp;
+
+               icrp = (volatile unsigned char *) (MCF_IPSBAR + MCFICM_INTC0 +
+                       MCFINTC_ICR0);
+               for (b = 36; (b < 49); b++)
+                       icrp[b] = 0x04;
+               imrp = (volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 +
+                       MCFINTC_IMRH);
+               *imrp &= ~0x0001FFF0;
+       }
+       *(volatile unsigned char *)(MCF_IPSBAR + MCF_GPIO_PAR_FEC) |= 0xf0;
+       *(volatile unsigned char *)(MCF_IPSBAR + MCF_GPIO_PAR_FECI2C) |= 0x0f;
+}
+
+static void __inline__ fec_set_mii(struct net_device *dev, struct fec_enet_private *fep)
+{
+       volatile fec_t *fecp;
+
+       fecp = fep->hwp;
+       fecp->fec_r_cntrl = OPT_FRAME_SIZE | 0x04;
+       fecp->fec_x_cntrl = 0x00;
+
+       /*
+        * Set MII speed to 2.5 MHz
+        * See 5282 manual section 17.5.4.7: MSCR
+        */
+       fep->phy_speed = ((((MCF_CLK / 2) / (2500000 / 10)) + 5) / 10) * 2;
+       fecp->fec_mii_speed = fep->phy_speed;
+
+       fec_restart(dev, 0);
+}
+
+static void __inline__ fec_get_mac(struct net_device *dev)
+{
+       struct fec_enet_private *fep = netdev_priv(dev);
+       volatile fec_t *fecp;
+       unsigned char *iap, tmpaddr[ETH_ALEN];
+
+       fecp = fep->hwp;
+
+       if (FEC_FLASHMAC) {
+               /*
+                * Get MAC address from FLASH.
+                * If it is all 1's or 0's, use the default.
+                */
+               iap = FEC_FLASHMAC;
+               if ((iap[0] == 0) && (iap[1] == 0) && (iap[2] == 0) &&
+                  (iap[3] == 0) && (iap[4] == 0) && (iap[5] == 0))
+                       iap = fec_mac_default;
+               if ((iap[0] == 0xff) && (iap[1] == 0xff) && (iap[2] == 0xff) &&
+                  (iap[3] == 0xff) && (iap[4] == 0xff) && (iap[5] == 0xff))
+                       iap = fec_mac_default;
+       } else {
+               *((unsigned long *) &tmpaddr[0]) = fecp->fec_addr_low;
+               *((unsigned short *) &tmpaddr[4]) = (fecp->fec_addr_high >> 16);
+               iap = &tmpaddr[0];
+       }
+
+       memcpy(dev->dev_addr, iap, ETH_ALEN);
+
+       /* Adjust MAC if using default MAC address */
+       if (iap == fec_mac_default)
+               dev->dev_addr[ETH_ALEN-1] = fec_mac_default[ETH_ALEN-1] + fep->index;
+}
+
+static void __inline__ fec_enable_phy_intr(void)
+{
+}
+
+static void __inline__ fec_disable_phy_intr(void)
+{
+}
+
+static void __inline__ fec_phy_ack_intr(void)
+{
+}
+
+static void __inline__ fec_localhw_setup(void)
+{
+}
+
+static void __inline__ fec_uncache(unsigned long addr)
+{
+}
+
+/* ------------------------------------------------------------------------- */
+
 #else
 
 /*
@@ -1952,6 +2148,14 @@ int __init fec_enet_init(struct net_device *dev)
        if (index >= FEC_MAX_PORTS)
                return -ENXIO;
 
+       /* Allocate memory for buffer descriptors.
+       */
+       mem_addr = __get_free_page(GFP_KERNEL);
+       if (mem_addr == 0) {
+               printk("FEC: allocate descriptor memory failed?\n");
+               return -ENOMEM;
+       }
+
        /* Create an Ethernet device instance.
        */
        fecp = (volatile fec_t *) fec_hw[index];
@@ -1964,16 +2168,6 @@ int __init fec_enet_init(struct net_device *dev)
        fecp->fec_ecntrl = 1;
        udelay(10);
 
-       /* Clear and enable interrupts */
-       fecp->fec_ievent = 0xffc00000;
-       fecp->fec_imask = (FEC_ENET_TXF | FEC_ENET_TXB |
-               FEC_ENET_RXF | FEC_ENET_RXB | FEC_ENET_MII);
-       fecp->fec_hash_table_high = 0;
-       fecp->fec_hash_table_low = 0;
-       fecp->fec_r_buff_size = PKT_MAXBLR_SIZE;
-        fecp->fec_ecntrl = 2;
-        fecp->fec_r_des_active = 0x01000000;
-
        /* Set the Ethernet address.  If using multiple Enets on the 8xx,
         * this needs some work to get unique addresses.
         *
@@ -1982,14 +2176,6 @@ int __init fec_enet_init(struct net_device *dev)
         */
        fec_get_mac(dev);
 
-       /* Allocate memory for buffer descriptors.
-       */
-       if (((RX_RING_SIZE + TX_RING_SIZE) * sizeof(cbd_t)) > PAGE_SIZE) {
-               printk("FEC init error.  Need more space.\n");
-               printk("FEC initialization failed.\n");
-               return 1;
-       }
-       mem_addr = __get_free_page(GFP_KERNEL);
        cbd_base = (cbd_t *)mem_addr;
        /* XXX: missing check for allocation failure */
 
@@ -2067,6 +2253,16 @@ int __init fec_enet_init(struct net_device *dev)
        */
        fec_request_intrs(dev);
 
+       /* Clear and enable interrupts */
+       fecp->fec_ievent = 0xffc00000;
+       fecp->fec_imask = (FEC_ENET_TXF | FEC_ENET_TXB |
+               FEC_ENET_RXF | FEC_ENET_RXB | FEC_ENET_MII);
+       fecp->fec_hash_table_high = 0;
+       fecp->fec_hash_table_low = 0;
+       fecp->fec_r_buff_size = PKT_MAXBLR_SIZE;
+       fecp->fec_ecntrl = 2;
+       fecp->fec_r_des_active = 0x01000000;
+
        dev->base_addr = (unsigned long)fecp;
 
        /* The FEC Ethernet specific entries in the device structure. */
index 045761b8a6004ab1f25c73bcd082d00573024589..965c5c49fcdce023906942f2aa117d7cb94a35f4 100644 (file)
@@ -1,11 +1,10 @@
 /****************************************************************************/
 
 /*
- *     fec.h  --  Fast Ethernet Controller for Motorola ColdFire 5230,
- *                5231, 5232, 5234, 5235, 5270, 5271, 5272, 5274, 5275,
- *                5280 and 5282.
+ *     fec.h  --  Fast Ethernet Controller for Motorola ColdFire SoC
+ *                processors.
  *
- *     (C) Copyright 2000-2003, Greg Ungerer (gerg@snapgear.com)
+ *     (C) Copyright 2000-2005, Greg Ungerer (gerg@snapgear.com)
  *     (C) Copyright 2000-2001, Lineo (www.lineo.com)
  */
 
@@ -14,7 +13,8 @@
 #define        FEC_H
 /****************************************************************************/
 
-#if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x)
+#if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \
+    defined(CONFIG_M520x)
 /*
  *     Just figures, Motorola would have to change the offsets for
  *     registers in the same peripheral device on different models
index 6e6f42d01e64847cc626ca974e01f58f15d755f5..4b48b31ec235ae16457ccc0b31678f502db8d493 100644 (file)
@@ -78,17 +78,15 @@ static void parse_data(struct parport *port, int device, char *str)
                                u++;
                        }
                        if (!strcmp(p, "MFG") || !strcmp(p, "MANUFACTURER")) {
-                               if (info->mfr)
-                                       kfree (info->mfr);
+                               kfree(info->mfr);
                                info->mfr = kstrdup(sep, GFP_KERNEL);
                        } else if (!strcmp(p, "MDL") || !strcmp(p, "MODEL")) {
-                               if (info->model)
-                                       kfree (info->model);
+                               kfree(info->model);
                                info->model = kstrdup(sep, GFP_KERNEL);
                        } else if (!strcmp(p, "CLS") || !strcmp(p, "CLASS")) {
                                int i;
-                               if (info->class_name)
-                                       kfree (info->class_name);
+
+                               kfree(info->class_name);
                                info->class_name = kstrdup(sep, GFP_KERNEL);
                                for (u = sep; *u; u++)
                                        *u = toupper(*u);
@@ -102,21 +100,22 @@ static void parse_data(struct parport *port, int device, char *str)
                                info->class = PARPORT_CLASS_OTHER;
                        } else if (!strcmp(p, "CMD") ||
                                   !strcmp(p, "COMMAND SET")) {
-                               if (info->cmdset)
-                                       kfree (info->cmdset);
+                               kfree(info->cmdset);
                                info->cmdset = kstrdup(sep, GFP_KERNEL);
                                /* if it speaks printer language, it's
                                   probably a printer */
                                if (strstr(sep, "PJL") || strstr(sep, "PCL"))
                                        guessed_class = PARPORT_CLASS_PRINTER;
                        } else if (!strcmp(p, "DES") || !strcmp(p, "DESCRIPTION")) {
-                               if (info->description)
-                                       kfree (info->description);
+                               kfree(info->description);
                                info->description = kstrdup(sep, GFP_KERNEL);
                        }
                }
        rock_on:
-               if (q) p = q+1; else p=NULL;
+               if (q)
+                       p = q + 1;
+               else
+                       p = NULL;
        }
 
        /* If the device didn't tell us its class, maybe we have managed to
index ae7becf7efa5a5b45fef251003c230ce945530ad..9cb3ab156b09c40d82477b23f2de41a15e5d3f42 100644 (file)
@@ -202,16 +202,11 @@ static void free_port (struct parport *port)
        list_del(&port->full_list);
        spin_unlock(&full_list_lock);
        for (d = 0; d < 5; d++) {
-               if (port->probe_info[d].class_name)
-                       kfree (port->probe_info[d].class_name);
-               if (port->probe_info[d].mfr)
-                       kfree (port->probe_info[d].mfr);
-               if (port->probe_info[d].model)
-                       kfree (port->probe_info[d].model);
-               if (port->probe_info[d].cmdset)
-                       kfree (port->probe_info[d].cmdset);
-               if (port->probe_info[d].description)
-                       kfree (port->probe_info[d].description);
+               kfree(port->probe_info[d].class_name);
+               kfree(port->probe_info[d].mfr);
+               kfree(port->probe_info[d].model);
+               kfree(port->probe_info[d].cmdset);
+               kfree(port->probe_info[d].description);
        }
 
        kfree(port->name);
@@ -618,9 +613,9 @@ parport_register_device(struct parport *port, const char *name,
        return tmp;
 
  out_free_all:
-       kfree (tmp->state);
+       kfree(tmp->state);
  out_free_pardevice:
-       kfree (tmp);
+       kfree(tmp);
  out:
        parport_put_port (port);
        module_put(port->ops->owner);
index 93e39c4096a927bf8b6737b298f875b1ebf2583a..00b81a7bdd266a9513a6c39506236bb52c1c3622 100644 (file)
@@ -259,8 +259,7 @@ static int PCI_GetBusDevHelper(struct controller *ctrl, u8 *bus_num, u8 *dev_num
               sizeof(struct irq_routing_table)) / sizeof(struct irq_info);
        // Make sure I got at least one entry
        if (len == 0) {
-               if (PCIIRQRoutingInfoLength != NULL)
-                       kfree(PCIIRQRoutingInfoLength );
+               kfree(PCIIRQRoutingInfoLength );
                return -1;
        }
 
@@ -275,8 +274,7 @@ static int PCI_GetBusDevHelper(struct controller *ctrl, u8 *bus_num, u8 *dev_num
                        ctrl->pci_bus->number = tbus;
                        pci_bus_read_config_dword (ctrl->pci_bus, *dev_num, PCI_VENDOR_ID, &work);
                        if (!nobridge || (work == 0xffffffff)) {
-                               if (PCIIRQRoutingInfoLength != NULL)
-                                       kfree(PCIIRQRoutingInfoLength );
+                               kfree(PCIIRQRoutingInfoLength );
                                return 0;
                        }
 
@@ -289,20 +287,17 @@ static int PCI_GetBusDevHelper(struct controller *ctrl, u8 *bus_num, u8 *dev_num
                                dbg("Scan bus for Non Bridge: bus %d\n", tbus);
                                if (PCI_ScanBusForNonBridge(ctrl, tbus, dev_num) == 0) {
                                        *bus_num = tbus;
-                                       if (PCIIRQRoutingInfoLength != NULL)
-                                               kfree(PCIIRQRoutingInfoLength );
+                                       kfree(PCIIRQRoutingInfoLength );
                                        return 0;
                                }
                        } else {
-                               if (PCIIRQRoutingInfoLength != NULL)
-                                       kfree(PCIIRQRoutingInfoLength );
+                               kfree(PCIIRQRoutingInfoLength );
                                return 0;
                        }
 
                }
        }
-       if (PCIIRQRoutingInfoLength != NULL)
-               kfree(PCIIRQRoutingInfoLength );
+       kfree(PCIIRQRoutingInfoLength );
        return -1;
 }
 
index 33b2c69a08295b786553b5697f5481b99e4c509f..76c727c74cc014c456b4c57c713c7a47a414a136 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
+#include <linux/sched.h>
 #include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/slab.h>
index ae986e590b48213544dd6f322147909bf52efcec..94e68c54d27397bf06c56b32d7539c927b8dcf41 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/mempolicy.h>
 #include <linux/string.h>
 #include <linux/slab.h>
+#include <linux/sched.h>
 #include "pci.h"
 
 /*
index 3afb682255a04d112dfa1a34f5bc4aac4d4e4b5f..2dc3e611a9a3473fbbb2a715db4de58d270a3f63 100644 (file)
@@ -334,10 +334,8 @@ void destroy_cis_cache(struct pcmcia_socket *s)
        /*
         * If there was a fake CIS, destroy that as well.
         */
-       if (s->fake_cis) {
-               kfree(s->fake_cis);
-               s->fake_cis = NULL;
-       }
+       kfree(s->fake_cis);
+       s->fake_cis = NULL;
 }
 EXPORT_SYMBOL(destroy_cis_cache);
 
@@ -386,10 +384,8 @@ int verify_cis_cache(struct pcmcia_socket *s)
 
 int pcmcia_replace_cis(struct pcmcia_socket *s, cisdump_t *cis)
 {
-    if (s->fake_cis != NULL) {
-       kfree(s->fake_cis);
-       s->fake_cis = NULL;
-    }
+    kfree(s->fake_cis);
+    s->fake_cis = NULL;
     if (cis->Length > CISTPL_MAX_CIS_SIZE)
        return CS_BAD_SIZE;
     s->fake_cis = kmalloc(cis->Length, GFP_KERNEL);
index d5e76423a0ee89b15a3888e0b411f688e49b05fb..234cdca6fe137e8967fbe43bf6c71557a84c434b 100644 (file)
@@ -331,10 +331,8 @@ static void shutdown_socket(struct pcmcia_socket *s)
        cb_free(s);
 #endif
        s->functions = 0;
-       if (s->config) {
-               kfree(s->config);
-               s->config = NULL;
-       }
+       kfree(s->config);
+       s->config = NULL;
 
        {
                int status;
index e95ed67d4f050afddf5918d34628e4586ba70951..bd7c966ea2d7f8ee7dfe250bd4e4a26343a6fd72 100644 (file)
@@ -12,7 +12,7 @@
 #include "base.h"
 
 LIST_HEAD(pnp_cards);
-LIST_HEAD(pnp_card_drivers);
+static LIST_HEAD(pnp_card_drivers);
 
 
 static const struct pnp_card_device_id * match_card(struct pnp_card_driver * drv, struct pnp_card * card)
@@ -374,11 +374,13 @@ void pnp_unregister_card_driver(struct pnp_card_driver * drv)
        pnp_unregister_driver(&drv->link);
 }
 
+#if 0
 EXPORT_SYMBOL(pnp_add_card);
 EXPORT_SYMBOL(pnp_remove_card);
 EXPORT_SYMBOL(pnp_add_card_device);
 EXPORT_SYMBOL(pnp_remove_card_device);
 EXPORT_SYMBOL(pnp_add_card_id);
+#endif  /*  0  */
 EXPORT_SYMBOL(pnp_request_card_device);
 EXPORT_SYMBOL(pnp_release_card_device);
 EXPORT_SYMBOL(pnp_register_card_driver);
index deed92459bc5e34feddcb5a27ff3cc3f1163365e..aec83ec5ea23f2471c55fbbe3dafd073b296c42e 100644 (file)
@@ -158,13 +158,14 @@ void __pnp_remove_device(struct pnp_dev *dev)
  *
  * this function will free all mem used by dev
  */
-
+#if 0
 void pnp_remove_device(struct pnp_dev *dev)
 {
        if (!dev || dev->card)
                return;
        __pnp_remove_device(dev);
 }
+#endif  /*  0  */
 
 static int __init pnp_init(void)
 {
@@ -174,7 +175,9 @@ static int __init pnp_init(void)
 
 subsys_initcall(pnp_init);
 
+#if 0
 EXPORT_SYMBOL(pnp_register_protocol);
 EXPORT_SYMBOL(pnp_unregister_protocol);
 EXPORT_SYMBOL(pnp_add_device);
 EXPORT_SYMBOL(pnp_remove_device);
+#endif  /*  0  */
index 33da25f3213f4614a6dc338b9743034452dab3de..d3ccce706ab4ce9ee20bf45e46112249fcdcf4c3 100644 (file)
@@ -214,6 +214,8 @@ int pnp_add_id(struct pnp_id *id, struct pnp_dev *dev)
 
 EXPORT_SYMBOL(pnp_register_driver);
 EXPORT_SYMBOL(pnp_unregister_driver);
+#if 0
 EXPORT_SYMBOL(pnp_add_id);
+#endif
 EXPORT_SYMBOL(pnp_device_attach);
 EXPORT_SYMBOL(pnp_device_detach);
index beedd86800f4e26093643ec765961a2fbd6f0e25..57fd60314d591516e1a7a7c81ff030ac552978a9 100644 (file)
@@ -941,7 +941,9 @@ EXPORT_SYMBOL(isapnp_protocol);
 EXPORT_SYMBOL(isapnp_present);
 EXPORT_SYMBOL(isapnp_cfg_begin);
 EXPORT_SYMBOL(isapnp_cfg_end);
+#if 0
 EXPORT_SYMBOL(isapnp_read_byte);
+#endif
 EXPORT_SYMBOL(isapnp_write_byte);
 
 static int isapnp_read_resources(struct pnp_dev *dev, struct pnp_resource_table *res)
index cbb2749db178e1332be1c0693ce627ad29c502fa..261668618b2d481d8bd5074e8297e0f9374f145b 100644 (file)
@@ -555,7 +555,9 @@ void pnp_resource_change(struct resource *resource, unsigned long start, unsigne
 
 
 EXPORT_SYMBOL(pnp_manual_config_dev);
+#if 0
 EXPORT_SYMBOL(pnp_auto_config_dev);
+#endif
 EXPORT_SYMBOL(pnp_activate_dev);
 EXPORT_SYMBOL(pnp_disable_dev);
 EXPORT_SYMBOL(pnp_resource_change);
index 1a8915e74160bba5b0b4a94f2ecbe6322168b8e6..816479ad217b044dd3c9eb5cd27d3b6683616e6a 100644 (file)
@@ -117,7 +117,7 @@ static int pnpacpi_disable_resources(struct pnp_dev *dev)
        return ACPI_FAILURE(status) ? -ENODEV : 0;
 }
 
-struct pnp_protocol pnpacpi_protocol = {
+static struct pnp_protocol pnpacpi_protocol = {
        .name   = "Plug and Play ACPI",
        .get    = pnpacpi_get_resources,
        .set    = pnpacpi_set_resources,
@@ -234,7 +234,7 @@ static acpi_status __init pnpacpi_add_device_handler(acpi_handle handle,
 }
 
 int pnpacpi_disabled __initdata;
-int __init pnpacpi_init(void)
+static int __init pnpacpi_init(void)
 {
        if (acpi_disabled || pnpacpi_disabled) {
                pnp_info("PnP ACPI: disabled");
@@ -258,4 +258,6 @@ static int __init pnpacpi_setup(char *str)
 }
 __setup("pnpacpi=", pnpacpi_setup);
 
+#if 0
 EXPORT_SYMBOL(pnpacpi_protocol);
+#endif
index 887ad8939349e9f3eb37fc9bcc1ddb893b64fce4..6ded527169f4b805b43a77dba11a5c0b23d42af8 100644 (file)
@@ -477,12 +477,14 @@ int pnp_check_dma(struct pnp_dev * dev, int idx)
 }
 
 
+#if 0
 EXPORT_SYMBOL(pnp_register_dependent_option);
 EXPORT_SYMBOL(pnp_register_independent_option);
 EXPORT_SYMBOL(pnp_register_irq_resource);
 EXPORT_SYMBOL(pnp_register_dma_resource);
 EXPORT_SYMBOL(pnp_register_port_resource);
 EXPORT_SYMBOL(pnp_register_mem_resource);
+#endif  /*  0  */
 
 
 /* format is: pnp_reserve_irq=irq1[,irq2] .... */
diff --git a/drivers/rapidio/Kconfig b/drivers/rapidio/Kconfig
new file mode 100644 (file)
index 0000000..0b2d2c3
--- /dev/null
@@ -0,0 +1,18 @@
+#
+# RapidIO configuration
+#
+config RAPIDIO_8_BIT_TRANSPORT
+       bool "8-bit transport addressing"
+       depends on RAPIDIO
+       ---help---
+         By default, the kernel assumes a 16-bit addressed RapidIO
+         network. By selecting this option, the kernel will support
+         an 8-bit addressed network.
+
+config RAPIDIO_DISC_TIMEOUT
+       int "Discovery timeout duration (seconds)"
+       depends on RAPIDIO
+       default "30"
+       ---help---
+         Amount of time a discovery node waits for a host to complete
+         enumeration beforing giving up.
diff --git a/drivers/rapidio/Makefile b/drivers/rapidio/Makefile
new file mode 100644 (file)
index 0000000..7c0e181
--- /dev/null
@@ -0,0 +1,6 @@
+#
+# Makefile for RapidIO interconnect services
+#
+obj-y += rio.o rio-access.o rio-driver.o rio-scan.o rio-sysfs.o
+
+obj-$(CONFIG_RAPIDIO)          += switches/
diff --git a/drivers/rapidio/rio-access.c b/drivers/rapidio/rio-access.c
new file mode 100644 (file)
index 0000000..b9fab2a
--- /dev/null
@@ -0,0 +1,175 @@
+/*
+ * RapidIO configuration space access support
+ *
+ * Copyright 2005 MontaVista Software, Inc.
+ * Matt Porter <mporter@kernel.crashing.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.
+ */
+
+#include <linux/rio.h>
+#include <linux/module.h>
+
+/*
+ * These interrupt-safe spinlocks protect all accesses to RIO
+ * configuration space and doorbell access.
+ */
+static spinlock_t rio_config_lock = SPIN_LOCK_UNLOCKED;
+static spinlock_t rio_doorbell_lock = SPIN_LOCK_UNLOCKED;
+
+/*
+ *  Wrappers for all RIO configuration access functions.  They just check
+ *  alignment, do locking and call the low-level functions pointed to
+ *  by rio_mport->ops.
+ */
+
+#define RIO_8_BAD 0
+#define RIO_16_BAD (offset & 1)
+#define RIO_32_BAD (offset & 3)
+
+/**
+ * RIO_LOP_READ - Generate rio_local_read_config_* functions
+ * @size: Size of configuration space read (8, 16, 32 bits)
+ * @type: C type of value argument
+ * @len: Length of configuration space read (1, 2, 4 bytes)
+ *
+ * Generates rio_local_read_config_* functions used to access
+ * configuration space registers on the local device.
+ */
+#define RIO_LOP_READ(size,type,len) \
+int __rio_local_read_config_##size \
+       (struct rio_mport *mport, u32 offset, type *value)              \
+{                                                                      \
+       int res;                                                        \
+       unsigned long flags;                                            \
+       u32 data = 0;                                                   \
+       if (RIO_##size##_BAD) return RIO_BAD_SIZE;                      \
+       spin_lock_irqsave(&rio_config_lock, flags);                     \
+       res = mport->ops->lcread(mport->id, offset, len, &data);        \
+       *value = (type)data;                                            \
+       spin_unlock_irqrestore(&rio_config_lock, flags);                \
+       return res;                                                     \
+}
+
+/**
+ * RIO_LOP_WRITE - Generate rio_local_write_config_* functions
+ * @size: Size of configuration space write (8, 16, 32 bits)
+ * @type: C type of value argument
+ * @len: Length of configuration space write (1, 2, 4 bytes)
+ *
+ * Generates rio_local_write_config_* functions used to access
+ * configuration space registers on the local device.
+ */
+#define RIO_LOP_WRITE(size,type,len) \
+int __rio_local_write_config_##size \
+       (struct rio_mport *mport, u32 offset, type value)               \
+{                                                                      \
+       int res;                                                        \
+       unsigned long flags;                                            \
+       if (RIO_##size##_BAD) return RIO_BAD_SIZE;                      \
+       spin_lock_irqsave(&rio_config_lock, flags);                     \
+       res = mport->ops->lcwrite(mport->id, offset, len, value);       \
+       spin_unlock_irqrestore(&rio_config_lock, flags);                \
+       return res;                                                     \
+}
+
+RIO_LOP_READ(8, u8, 1)
+RIO_LOP_READ(16, u16, 2)
+RIO_LOP_READ(32, u32, 4)
+RIO_LOP_WRITE(8, u8, 1)
+RIO_LOP_WRITE(16, u16, 2)
+RIO_LOP_WRITE(32, u32, 4)
+
+EXPORT_SYMBOL_GPL(__rio_local_read_config_8);
+EXPORT_SYMBOL_GPL(__rio_local_read_config_16);
+EXPORT_SYMBOL_GPL(__rio_local_read_config_32);
+EXPORT_SYMBOL_GPL(__rio_local_write_config_8);
+EXPORT_SYMBOL_GPL(__rio_local_write_config_16);
+EXPORT_SYMBOL_GPL(__rio_local_write_config_32);
+
+/**
+ * RIO_OP_READ - Generate rio_mport_read_config_* functions
+ * @size: Size of configuration space read (8, 16, 32 bits)
+ * @type: C type of value argument
+ * @len: Length of configuration space read (1, 2, 4 bytes)
+ *
+ * Generates rio_mport_read_config_* functions used to access
+ * configuration space registers on the local device.
+ */
+#define RIO_OP_READ(size,type,len) \
+int rio_mport_read_config_##size \
+       (struct rio_mport *mport, u16 destid, u8 hopcount, u32 offset, type *value)     \
+{                                                                      \
+       int res;                                                        \
+       unsigned long flags;                                            \
+       u32 data = 0;                                                   \
+       if (RIO_##size##_BAD) return RIO_BAD_SIZE;                      \
+       spin_lock_irqsave(&rio_config_lock, flags);                     \
+       res = mport->ops->cread(mport->id, destid, hopcount, offset, len, &data); \
+       *value = (type)data;                                            \
+       spin_unlock_irqrestore(&rio_config_lock, flags);                \
+       return res;                                                     \
+}
+
+/**
+ * RIO_OP_WRITE - Generate rio_mport_write_config_* functions
+ * @size: Size of configuration space write (8, 16, 32 bits)
+ * @type: C type of value argument
+ * @len: Length of configuration space write (1, 2, 4 bytes)
+ *
+ * Generates rio_mport_write_config_* functions used to access
+ * configuration space registers on the local device.
+ */
+#define RIO_OP_WRITE(size,type,len) \
+int rio_mport_write_config_##size \
+       (struct rio_mport *mport, u16 destid, u8 hopcount, u32 offset, type value)      \
+{                                                                      \
+       int res;                                                        \
+       unsigned long flags;                                            \
+       if (RIO_##size##_BAD) return RIO_BAD_SIZE;                      \
+       spin_lock_irqsave(&rio_config_lock, flags);                     \
+       res = mport->ops->cwrite(mport->id, destid, hopcount, offset, len, value); \
+       spin_unlock_irqrestore(&rio_config_lock, flags);                \
+       return res;                                                     \
+}
+
+RIO_OP_READ(8, u8, 1)
+RIO_OP_READ(16, u16, 2)
+RIO_OP_READ(32, u32, 4)
+RIO_OP_WRITE(8, u8, 1)
+RIO_OP_WRITE(16, u16, 2)
+RIO_OP_WRITE(32, u32, 4)
+
+EXPORT_SYMBOL_GPL(rio_mport_read_config_8);
+EXPORT_SYMBOL_GPL(rio_mport_read_config_16);
+EXPORT_SYMBOL_GPL(rio_mport_read_config_32);
+EXPORT_SYMBOL_GPL(rio_mport_write_config_8);
+EXPORT_SYMBOL_GPL(rio_mport_write_config_16);
+EXPORT_SYMBOL_GPL(rio_mport_write_config_32);
+
+/**
+ * rio_mport_send_doorbell - Send a doorbell message
+ *
+ * @mport: RIO master port
+ * @destid: RIO device destination ID
+ * @data: Doorbell message data
+ *
+ * Send a doorbell message to a RIO device. The doorbell message
+ * has a 16-bit info field provided by the data argument.
+ */
+int rio_mport_send_doorbell(struct rio_mport *mport, u16 destid, u16 data)
+{
+       int res;
+       unsigned long flags;
+
+       spin_lock_irqsave(&rio_doorbell_lock, flags);
+       res = mport->ops->dsend(mport->id, destid, data);
+       spin_unlock_irqrestore(&rio_doorbell_lock, flags);
+
+       return res;
+}
+
+EXPORT_SYMBOL_GPL(rio_mport_send_doorbell);
diff --git a/drivers/rapidio/rio-driver.c b/drivers/rapidio/rio-driver.c
new file mode 100644 (file)
index 0000000..dc74960
--- /dev/null
@@ -0,0 +1,229 @@
+/*
+ * RapidIO driver support
+ *
+ * Copyright 2005 MontaVista Software, Inc.
+ * Matt Porter <mporter@kernel.crashing.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.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/rio.h>
+#include <linux/rio_ids.h>
+
+#include "rio.h"
+
+/**
+ *  rio_match_device - Tell if a RIO device has a matching RIO device id structure
+ *  @id: the RIO device id structure to match against
+ *  @rdev: the RIO device structure to match against
+ *
+ *  Used from driver probe and bus matching to check whether a RIO device
+ *  matches a device id structure provided by a RIO driver. Returns the
+ *  matching &struct rio_device_id or %NULL if there is no match.
+ */
+static const struct rio_device_id *rio_match_device(const struct rio_device_id
+                                                   *id,
+                                                   const struct rio_dev *rdev)
+{
+       while (id->vid || id->asm_vid) {
+               if (((id->vid == RIO_ANY_ID) || (id->vid == rdev->vid)) &&
+                   ((id->did == RIO_ANY_ID) || (id->did == rdev->did)) &&
+                   ((id->asm_vid == RIO_ANY_ID)
+                    || (id->asm_vid == rdev->asm_vid))
+                   && ((id->asm_did == RIO_ANY_ID)
+                       || (id->asm_did == rdev->asm_did)))
+                       return id;
+               id++;
+       }
+       return NULL;
+}
+
+/**
+ * rio_dev_get - Increments the reference count of the RIO device structure
+ *
+ * @rdev: RIO device being referenced
+ *
+ * Each live reference to a device should be refcounted.
+ *
+ * Drivers for RIO devices should normally record such references in
+ * their probe() methods, when they bind to a device, and release
+ * them by calling rio_dev_put(), in their disconnect() methods.
+ */
+struct rio_dev *rio_dev_get(struct rio_dev *rdev)
+{
+       if (rdev)
+               get_device(&rdev->dev);
+
+       return rdev;
+}
+
+/**
+ * rio_dev_put - Release a use of the RIO device structure
+ *
+ * @rdev: RIO device being disconnected
+ *
+ * Must be called when a user of a device is finished with it.
+ * When the last user of the device calls this function, the
+ * memory of the device is freed.
+ */
+void rio_dev_put(struct rio_dev *rdev)
+{
+       if (rdev)
+               put_device(&rdev->dev);
+}
+
+/**
+ *  rio_device_probe - Tell if a RIO device structure has a matching RIO
+ *                     device id structure
+ *  @id: the RIO device id structure to match against
+ *  @dev: the RIO device structure to match against
+ *
+ * return 0 and set rio_dev->driver when drv claims rio_dev, else error
+ */
+static int rio_device_probe(struct device *dev)
+{
+       struct rio_driver *rdrv = to_rio_driver(dev->driver);
+       struct rio_dev *rdev = to_rio_dev(dev);
+       int error = -ENODEV;
+       const struct rio_device_id *id;
+
+       if (!rdev->driver && rdrv->probe) {
+               if (!rdrv->id_table)
+                       return error;
+               id = rio_match_device(rdrv->id_table, rdev);
+               rio_dev_get(rdev);
+               if (id)
+                       error = rdrv->probe(rdev, id);
+               if (error >= 0) {
+                       rdev->driver = rdrv;
+                       error = 0;
+                       rio_dev_put(rdev);
+               }
+       }
+       return error;
+}
+
+/**
+ *  rio_device_remove - Remove a RIO device from the system
+ *
+ *  @dev: the RIO device structure to match against
+ *
+ * Remove a RIO device from the system. If it has an associated
+ * driver, then run the driver remove() method.  Then update
+ * the reference count.
+ */
+static int rio_device_remove(struct device *dev)
+{
+       struct rio_dev *rdev = to_rio_dev(dev);
+       struct rio_driver *rdrv = rdev->driver;
+
+       if (rdrv) {
+               if (rdrv->remove)
+                       rdrv->remove(rdev);
+               rdev->driver = NULL;
+       }
+
+       rio_dev_put(rdev);
+
+       return 0;
+}
+
+/**
+ *  rio_register_driver - register a new RIO driver
+ *  @rdrv: the RIO driver structure to register
+ *
+ *  Adds a &struct rio_driver to the list of registered drivers
+ *  Returns a negative value on error, otherwise 0. If no error
+ *  occurred, the driver remains registered even if no device
+ *  was claimed during registration.
+ */
+int rio_register_driver(struct rio_driver *rdrv)
+{
+       /* initialize common driver fields */
+       rdrv->driver.name = rdrv->name;
+       rdrv->driver.bus = &rio_bus_type;
+       rdrv->driver.probe = rio_device_probe;
+       rdrv->driver.remove = rio_device_remove;
+
+       /* register with core */
+       return driver_register(&rdrv->driver);
+}
+
+/**
+ *  rio_unregister_driver - unregister a RIO driver
+ *  @rdrv: the RIO driver structure to unregister
+ *
+ *  Deletes the &struct rio_driver from the list of registered RIO
+ *  drivers, gives it a chance to clean up by calling its remove()
+ *  function for each device it was responsible for, and marks those
+ *  devices as driverless.
+ */
+void rio_unregister_driver(struct rio_driver *rdrv)
+{
+       driver_unregister(&rdrv->driver);
+}
+
+/**
+ *  rio_match_bus - Tell if a RIO device structure has a matching RIO
+ *                  driver device id structure
+ *  @dev: the standard device structure to match against
+ *  @drv: the standard driver structure containing the ids to match against
+ *
+ *  Used by a driver to check whether a RIO device present in the
+ *  system is in its list of supported devices. Returns 1 if
+ *  there is a matching &struct rio_device_id or 0 if there is
+ *  no match.
+ */
+static int rio_match_bus(struct device *dev, struct device_driver *drv)
+{
+       struct rio_dev *rdev = to_rio_dev(dev);
+       struct rio_driver *rdrv = to_rio_driver(drv);
+       const struct rio_device_id *id = rdrv->id_table;
+       const struct rio_device_id *found_id;
+
+       if (!id)
+               goto out;
+
+       found_id = rio_match_device(id, rdev);
+
+       if (found_id)
+               return 1;
+
+      out:return 0;
+}
+
+static struct device rio_bus = {
+       .bus_id = "rapidio",
+};
+
+struct bus_type rio_bus_type = {
+       .name = "rapidio",
+       .match = rio_match_bus,
+       .dev_attrs = rio_dev_attrs
+};
+
+/**
+ *  rio_bus_init - Register the RapidIO bus with the device model
+ *
+ *  Registers the RIO bus device and RIO bus type with the Linux
+ *  device model.
+ */
+static int __init rio_bus_init(void)
+{
+       if (device_register(&rio_bus) < 0)
+               printk("RIO: failed to register RIO bus device\n");
+       return bus_register(&rio_bus_type);
+}
+
+postcore_initcall(rio_bus_init);
+
+EXPORT_SYMBOL_GPL(rio_register_driver);
+EXPORT_SYMBOL_GPL(rio_unregister_driver);
+EXPORT_SYMBOL_GPL(rio_bus_type);
+EXPORT_SYMBOL_GPL(rio_dev_get);
+EXPORT_SYMBOL_GPL(rio_dev_put);
diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c
new file mode 100644 (file)
index 0000000..4f7ed4b
--- /dev/null
@@ -0,0 +1,945 @@
+/*
+ * RapidIO enumeration and discovery support
+ *
+ * Copyright 2005 MontaVista Software, Inc.
+ * Matt Porter <mporter@kernel.crashing.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.
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/init.h>
+#include <linux/rio.h>
+#include <linux/rio_drv.h>
+#include <linux/rio_ids.h>
+#include <linux/rio_regs.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/timer.h>
+
+#include "rio.h"
+
+LIST_HEAD(rio_devices);
+static LIST_HEAD(rio_switches);
+
+#define RIO_ENUM_CMPL_MAGIC    0xdeadbeef
+
+static void rio_enum_timeout(unsigned long);
+
+DEFINE_SPINLOCK(rio_global_list_lock);
+
+static int next_destid = 0;
+static int next_switchid = 0;
+static int next_net = 0;
+
+static struct timer_list rio_enum_timer =
+TIMER_INITIALIZER(rio_enum_timeout, 0, 0);
+
+static int rio_mport_phys_table[] = {
+       RIO_EFB_PAR_EP_ID,
+       RIO_EFB_PAR_EP_REC_ID,
+       RIO_EFB_SER_EP_ID,
+       RIO_EFB_SER_EP_REC_ID,
+       -1,
+};
+
+static int rio_sport_phys_table[] = {
+       RIO_EFB_PAR_EP_FREE_ID,
+       RIO_EFB_SER_EP_FREE_ID,
+       -1,
+};
+
+/**
+ * rio_get_device_id - Get the base/extended device id for a device
+ * @port: RIO master port
+ * @destid: Destination ID of device
+ * @hopcount: Hopcount to device
+ *
+ * Reads the base/extended device id from a device. Returns the
+ * 8/16-bit device ID.
+ */
+static u16 rio_get_device_id(struct rio_mport *port, u16 destid, u8 hopcount)
+{
+       u32 result;
+
+       rio_mport_read_config_32(port, destid, hopcount, RIO_DID_CSR, &result);
+
+       return RIO_GET_DID(result);
+}
+
+/**
+ * rio_set_device_id - Set the base/extended device id for a device
+ * @port: RIO master port
+ * @destid: Destination ID of device
+ * @hopcount: Hopcount to device
+ * @did: Device ID value to be written
+ *
+ * Writes the base/extended device id from a device.
+ */
+static void rio_set_device_id(struct rio_mport *port, u16 destid, u8 hopcount, u16 did)
+{
+       rio_mport_write_config_32(port, destid, hopcount, RIO_DID_CSR,
+                                 RIO_SET_DID(did));
+}
+
+/**
+ * rio_local_set_device_id - Set the base/extended device id for a port
+ * @port: RIO master port
+ * @did: Device ID value to be written
+ *
+ * Writes the base/extended device id from a device.
+ */
+static void rio_local_set_device_id(struct rio_mport *port, u16 did)
+{
+       rio_local_write_config_32(port, RIO_DID_CSR, RIO_SET_DID(did));
+}
+
+/**
+ * rio_clear_locks- Release all host locks and signal enumeration complete
+ * @port: Master port to issue transaction
+ *
+ * Marks the component tag CSR on each device with the enumeration
+ * complete flag. When complete, it then release the host locks on
+ * each device. Returns 0 on success or %-EINVAL on failure.
+ */
+static int rio_clear_locks(struct rio_mport *port)
+{
+       struct rio_dev *rdev;
+       u32 result;
+       int ret = 0;
+
+       /* Write component tag CSR magic complete value */
+       rio_local_write_config_32(port, RIO_COMPONENT_TAG_CSR,
+                                 RIO_ENUM_CMPL_MAGIC);
+       list_for_each_entry(rdev, &rio_devices, global_list)
+           rio_write_config_32(rdev, RIO_COMPONENT_TAG_CSR,
+                               RIO_ENUM_CMPL_MAGIC);
+
+       /* Release host device id locks */
+       rio_local_write_config_32(port, RIO_HOST_DID_LOCK_CSR,
+                                 port->host_deviceid);
+       rio_local_read_config_32(port, RIO_HOST_DID_LOCK_CSR, &result);
+       if ((result & 0xffff) != 0xffff) {
+               printk(KERN_INFO
+                      "RIO: badness when releasing host lock on master port, result %8.8x\n",
+                      result);
+               ret = -EINVAL;
+       }
+       list_for_each_entry(rdev, &rio_devices, global_list) {
+               rio_write_config_32(rdev, RIO_HOST_DID_LOCK_CSR,
+                                   port->host_deviceid);
+               rio_read_config_32(rdev, RIO_HOST_DID_LOCK_CSR, &result);
+               if ((result & 0xffff) != 0xffff) {
+                       printk(KERN_INFO
+                              "RIO: badness when releasing host lock on vid %4.4x did %4.4x\n",
+                              rdev->vid, rdev->did);
+                       ret = -EINVAL;
+               }
+       }
+
+       return ret;
+}
+
+/**
+ * rio_enum_host- Set host lock and initialize host destination ID
+ * @port: Master port to issue transaction
+ *
+ * Sets the local host master port lock and destination ID register
+ * with the host device ID value. The host device ID value is provided
+ * by the platform. Returns %0 on success or %-1 on failure.
+ */
+static int rio_enum_host(struct rio_mport *port)
+{
+       u32 result;
+
+       /* Set master port host device id lock */
+       rio_local_write_config_32(port, RIO_HOST_DID_LOCK_CSR,
+                                 port->host_deviceid);
+
+       rio_local_read_config_32(port, RIO_HOST_DID_LOCK_CSR, &result);
+       if ((result & 0xffff) != port->host_deviceid)
+               return -1;
+
+       /* Set master port destid and init destid ctr */
+       rio_local_set_device_id(port, port->host_deviceid);
+
+       if (next_destid == port->host_deviceid)
+               next_destid++;
+
+       return 0;
+}
+
+/**
+ * rio_device_has_destid- Test if a device contains a destination ID register
+ * @port: Master port to issue transaction
+ * @src_ops: RIO device source operations
+ * @dst_ops: RIO device destination operations
+ *
+ * Checks the provided @src_ops and @dst_ops for the necessary transaction
+ * capabilities that indicate whether or not a device will implement a
+ * destination ID register. Returns 1 if true or 0 if false.
+ */
+static int rio_device_has_destid(struct rio_mport *port, int src_ops,
+                                int dst_ops)
+{
+       u32 mask = RIO_OPS_READ | RIO_OPS_WRITE | RIO_OPS_ATOMIC_TST_SWP | RIO_OPS_ATOMIC_INC | RIO_OPS_ATOMIC_DEC | RIO_OPS_ATOMIC_SET | RIO_OPS_ATOMIC_CLR;
+
+       return !!((src_ops | dst_ops) & mask);
+}
+
+/**
+ * rio_release_dev- Frees a RIO device struct
+ * @dev: LDM device associated with a RIO device struct
+ *
+ * Gets the RIO device struct associated a RIO device struct.
+ * The RIO device struct is freed.
+ */
+static void rio_release_dev(struct device *dev)
+{
+       struct rio_dev *rdev;
+
+       rdev = to_rio_dev(dev);
+       kfree(rdev);
+}
+
+/**
+ * rio_is_switch- Tests if a RIO device has switch capabilities
+ * @rdev: RIO device
+ *
+ * Gets the RIO device Processing Element Features register
+ * contents and tests for switch capabilities. Returns 1 if
+ * the device is a switch or 0 if it is not a switch.
+ * The RIO device struct is freed.
+ */
+static int rio_is_switch(struct rio_dev *rdev)
+{
+       if (rdev->pef & RIO_PEF_SWITCH)
+               return 1;
+       return 0;
+}
+
+/**
+ * rio_route_set_ops- Sets routing operations for a particular vendor switch
+ * @rdev: RIO device
+ *
+ * Searches the RIO route ops table for known switch types. If the vid
+ * and did match a switch table entry, then set the add_entry() and
+ * get_entry() ops to the table entry values.
+ */
+static void rio_route_set_ops(struct rio_dev *rdev)
+{
+       struct rio_route_ops *cur = __start_rio_route_ops;
+       struct rio_route_ops *end = __end_rio_route_ops;
+
+       while (cur < end) {
+               if ((cur->vid == rdev->vid) && (cur->did == rdev->did)) {
+                       pr_debug("RIO: adding routing ops for %s\n", rio_name(rdev));
+                       rdev->rswitch->add_entry = cur->add_hook;
+                       rdev->rswitch->get_entry = cur->get_hook;
+               }
+               cur++;
+       }
+
+       if (!rdev->rswitch->add_entry || !rdev->rswitch->get_entry)
+               printk(KERN_ERR "RIO: missing routing ops for %s\n",
+                      rio_name(rdev));
+}
+
+/**
+ * rio_add_device- Adds a RIO device to the device model
+ * @rdev: RIO device
+ *
+ * Adds the RIO device to the global device list and adds the RIO
+ * device to the RIO device list.  Creates the generic sysfs nodes
+ * for an RIO device.
+ */
+static void __devinit rio_add_device(struct rio_dev *rdev)
+{
+       device_add(&rdev->dev);
+
+       spin_lock(&rio_global_list_lock);
+       list_add_tail(&rdev->global_list, &rio_devices);
+       spin_unlock(&rio_global_list_lock);
+
+       rio_create_sysfs_dev_files(rdev);
+}
+
+/**
+ * rio_setup_device- Allocates and sets up a RIO device
+ * @net: RIO network
+ * @port: Master port to send transactions
+ * @destid: Current destination ID
+ * @hopcount: Current hopcount
+ * @do_enum: Enumeration/Discovery mode flag
+ *
+ * Allocates a RIO device and configures fields based on configuration
+ * space contents. If device has a destination ID register, a destination
+ * ID is either assigned in enumeration mode or read from configuration
+ * space in discovery mode.  If the device has switch capabilities, then
+ * a switch is allocated and configured appropriately. Returns a pointer
+ * to a RIO device on success or NULL on failure.
+ *
+ */
+static struct rio_dev *rio_setup_device(struct rio_net *net,
+                                       struct rio_mport *port, u16 destid,
+                                       u8 hopcount, int do_enum)
+{
+       struct rio_dev *rdev;
+       struct rio_switch *rswitch;
+       int result, rdid;
+
+       rdev = kmalloc(sizeof(struct rio_dev), GFP_KERNEL);
+       if (!rdev)
+               goto out;
+
+       memset(rdev, 0, sizeof(struct rio_dev));
+       rdev->net = net;
+       rio_mport_read_config_32(port, destid, hopcount, RIO_DEV_ID_CAR,
+                                &result);
+       rdev->did = result >> 16;
+       rdev->vid = result & 0xffff;
+       rio_mport_read_config_32(port, destid, hopcount, RIO_DEV_INFO_CAR,
+                                &rdev->device_rev);
+       rio_mport_read_config_32(port, destid, hopcount, RIO_ASM_ID_CAR,
+                                &result);
+       rdev->asm_did = result >> 16;
+       rdev->asm_vid = result & 0xffff;
+       rio_mport_read_config_32(port, destid, hopcount, RIO_ASM_INFO_CAR,
+                                &result);
+       rdev->asm_rev = result >> 16;
+       rio_mport_read_config_32(port, destid, hopcount, RIO_PEF_CAR,
+                                &rdev->pef);
+       if (rdev->pef & RIO_PEF_EXT_FEATURES)
+               rdev->efptr = result & 0xffff;
+
+       rio_mport_read_config_32(port, destid, hopcount, RIO_SRC_OPS_CAR,
+                                &rdev->src_ops);
+       rio_mport_read_config_32(port, destid, hopcount, RIO_DST_OPS_CAR,
+                                &rdev->dst_ops);
+
+       if (rio_device_has_destid(port, rdev->src_ops, rdev->dst_ops)
+           && do_enum) {
+               rio_set_device_id(port, destid, hopcount, next_destid);
+               rdev->destid = next_destid++;
+               if (next_destid == port->host_deviceid)
+                       next_destid++;
+       } else
+               rdev->destid = rio_get_device_id(port, destid, hopcount);
+
+       /* If a PE has both switch and other functions, show it as a switch */
+       if (rio_is_switch(rdev)) {
+               rio_mport_read_config_32(port, destid, hopcount,
+                                        RIO_SWP_INFO_CAR, &rdev->swpinfo);
+               rswitch = kmalloc(sizeof(struct rio_switch), GFP_KERNEL);
+               if (!rswitch) {
+                       kfree(rdev);
+                       rdev = NULL;
+                       goto out;
+               }
+               rswitch->switchid = next_switchid;
+               rswitch->hopcount = hopcount;
+               rswitch->destid = 0xffff;
+               /* Initialize switch route table */
+               for (rdid = 0; rdid < RIO_MAX_ROUTE_ENTRIES; rdid++)
+                       rswitch->route_table[rdid] = RIO_INVALID_ROUTE;
+               rdev->rswitch = rswitch;
+               sprintf(rio_name(rdev), "%02x:s:%04x", rdev->net->id,
+                       rdev->rswitch->switchid);
+               rio_route_set_ops(rdev);
+
+               list_add_tail(&rswitch->node, &rio_switches);
+
+       } else
+               sprintf(rio_name(rdev), "%02x:e:%04x", rdev->net->id,
+                       rdev->destid);
+
+       rdev->dev.bus = &rio_bus_type;
+
+       device_initialize(&rdev->dev);
+       rdev->dev.release = rio_release_dev;
+       rio_dev_get(rdev);
+
+       rdev->dma_mask = DMA_32BIT_MASK;
+       rdev->dev.dma_mask = &rdev->dma_mask;
+       rdev->dev.coherent_dma_mask = DMA_32BIT_MASK;
+
+       if ((rdev->pef & RIO_PEF_INB_DOORBELL) &&
+           (rdev->dst_ops & RIO_DST_OPS_DOORBELL))
+               rio_init_dbell_res(&rdev->riores[RIO_DOORBELL_RESOURCE],
+                                  0, 0xffff);
+
+       rio_add_device(rdev);
+
+      out:
+       return rdev;
+}
+
+/**
+ * rio_sport_is_active- Tests if a switch port has an active connection.
+ * @port: Master port to send transaction
+ * @destid: Associated destination ID for switch
+ * @hopcount: Hopcount to reach switch
+ * @sport: Switch port number
+ *
+ * Reads the port error status CSR for a particular switch port to
+ * determine if the port has an active link.  Returns
+ * %PORT_N_ERR_STS_PORT_OK if the port is active or %0 if it is
+ * inactive.
+ */
+static int
+rio_sport_is_active(struct rio_mport *port, u16 destid, u8 hopcount, int sport)
+{
+       u32 result;
+       u32 ext_ftr_ptr;
+
+       int *entry = rio_sport_phys_table;
+
+       do {
+               if ((ext_ftr_ptr =
+                    rio_mport_get_feature(port, 0, destid, hopcount, *entry)))
+
+                       break;
+       } while (*++entry >= 0);
+
+       if (ext_ftr_ptr)
+               rio_mport_read_config_32(port, destid, hopcount,
+                                        ext_ftr_ptr +
+                                        RIO_PORT_N_ERR_STS_CSR(sport),
+                                        &result);
+
+       return (result & PORT_N_ERR_STS_PORT_OK);
+}
+
+/**
+ * rio_route_add_entry- Add a route entry to a switch routing table
+ * @mport: Master port to send transaction
+ * @rdev: Switch device
+ * @table: Routing table ID
+ * @route_destid: Destination ID to be routed
+ * @route_port: Port number to be routed
+ *
+ * Calls the switch specific add_entry() method to add a route entry
+ * on a switch. The route table can be specified using the @table
+ * argument if a switch has per port routing tables or the normal
+ * use is to specific all tables (or the global table) by passing
+ * %RIO_GLOBAL_TABLE in @table. Returns %0 on success or %-EINVAL
+ * on failure.
+ */
+static int rio_route_add_entry(struct rio_mport *mport, struct rio_dev *rdev,
+                              u16 table, u16 route_destid, u8 route_port)
+{
+       return rdev->rswitch->add_entry(mport, rdev->rswitch->destid,
+                                       rdev->rswitch->hopcount, table,
+                                       route_destid, route_port);
+}
+
+/**
+ * rio_route_get_entry- Read a route entry in a switch routing table
+ * @mport: Master port to send transaction
+ * @rdev: Switch device
+ * @table: Routing table ID
+ * @route_destid: Destination ID to be routed
+ * @route_port: Pointer to read port number into
+ *
+ * Calls the switch specific get_entry() method to read a route entry
+ * in a switch. The route table can be specified using the @table
+ * argument if a switch has per port routing tables or the normal
+ * use is to specific all tables (or the global table) by passing
+ * %RIO_GLOBAL_TABLE in @table. Returns %0 on success or %-EINVAL
+ * on failure.
+ */
+static int
+rio_route_get_entry(struct rio_mport *mport, struct rio_dev *rdev, u16 table,
+                   u16 route_destid, u8 * route_port)
+{
+       return rdev->rswitch->get_entry(mport, rdev->rswitch->destid,
+                                       rdev->rswitch->hopcount, table,
+                                       route_destid, route_port);
+}
+
+/**
+ * rio_get_host_deviceid_lock- Reads the Host Device ID Lock CSR on a device
+ * @port: Master port to send transaction
+ * @hopcount: Number of hops to the device
+ *
+ * Used during enumeration to read the Host Device ID Lock CSR on a
+ * RIO device. Returns the value of the lock register.
+ */
+static u16 rio_get_host_deviceid_lock(struct rio_mport *port, u8 hopcount)
+{
+       u32 result;
+
+       rio_mport_read_config_32(port, RIO_ANY_DESTID, hopcount,
+                                RIO_HOST_DID_LOCK_CSR, &result);
+
+       return (u16) (result & 0xffff);
+}
+
+/**
+ * rio_get_swpinfo_inport- Gets the ingress port number
+ * @mport: Master port to send transaction
+ * @destid: Destination ID associated with the switch
+ * @hopcount: Number of hops to the device
+ *
+ * Returns port number being used to access the switch device.
+ */
+static u8
+rio_get_swpinfo_inport(struct rio_mport *mport, u16 destid, u8 hopcount)
+{
+       u32 result;
+
+       rio_mport_read_config_32(mport, destid, hopcount, RIO_SWP_INFO_CAR,
+                                &result);
+
+       return (u8) (result & 0xff);
+}
+
+/**
+ * rio_get_swpinfo_tports- Gets total number of ports on the switch
+ * @mport: Master port to send transaction
+ * @destid: Destination ID associated with the switch
+ * @hopcount: Number of hops to the device
+ *
+ * Returns total numbers of ports implemented by the switch device.
+ */
+static u8 rio_get_swpinfo_tports(struct rio_mport *mport, u16 destid,
+                                u8 hopcount)
+{
+       u32 result;
+
+       rio_mport_read_config_32(mport, destid, hopcount, RIO_SWP_INFO_CAR,
+                                &result);
+
+       return RIO_GET_TOTAL_PORTS(result);
+}
+
+/**
+ * rio_net_add_mport- Add a master port to a RIO network
+ * @net: RIO network
+ * @port: Master port to add
+ *
+ * Adds a master port to the network list of associated master
+ * ports..
+ */
+static void rio_net_add_mport(struct rio_net *net, struct rio_mport *port)
+{
+       spin_lock(&rio_global_list_lock);
+       list_add_tail(&port->nnode, &net->mports);
+       spin_unlock(&rio_global_list_lock);
+}
+
+/**
+ * rio_enum_peer- Recursively enumerate a RIO network through a master port
+ * @net: RIO network being enumerated
+ * @port: Master port to send transactions
+ * @hopcount: Number of hops into the network
+ *
+ * Recursively enumerates a RIO network.  Transactions are sent via the
+ * master port passed in @port.
+ */
+static int rio_enum_peer(struct rio_net *net, struct rio_mport *port,
+                        u8 hopcount)
+{
+       int port_num;
+       int num_ports;
+       int cur_destid;
+       struct rio_dev *rdev;
+       u16 destid;
+       int tmp;
+
+       if (rio_get_host_deviceid_lock(port, hopcount) == port->host_deviceid) {
+               pr_debug("RIO: PE already discovered by this host\n");
+               /*
+                * Already discovered by this host. Add it as another
+                * master port for the current network.
+                */
+               rio_net_add_mport(net, port);
+               return 0;
+       }
+
+       /* Attempt to acquire device lock */
+       rio_mport_write_config_32(port, RIO_ANY_DESTID, hopcount,
+                                 RIO_HOST_DID_LOCK_CSR, port->host_deviceid);
+       while ((tmp = rio_get_host_deviceid_lock(port, hopcount))
+              < port->host_deviceid) {
+               /* Delay a bit */
+               mdelay(1);
+               /* Attempt to acquire device lock again */
+               rio_mport_write_config_32(port, RIO_ANY_DESTID, hopcount,
+                                         RIO_HOST_DID_LOCK_CSR,
+                                         port->host_deviceid);
+       }
+
+       if (rio_get_host_deviceid_lock(port, hopcount) > port->host_deviceid) {
+               pr_debug(
+                   "RIO: PE locked by a higher priority host...retreating\n");
+               return -1;
+       }
+
+       /* Setup new RIO device */
+       if ((rdev = rio_setup_device(net, port, RIO_ANY_DESTID, hopcount, 1))) {
+               /* Add device to the global and bus/net specific list. */
+               list_add_tail(&rdev->net_list, &net->devices);
+       } else
+               return -1;
+
+       if (rio_is_switch(rdev)) {
+               next_switchid++;
+
+               for (destid = 0; destid < next_destid; destid++) {
+                       rio_route_add_entry(port, rdev, RIO_GLOBAL_TABLE,
+                                           destid, rio_get_swpinfo_inport(port,
+                                                                          RIO_ANY_DESTID,
+                                                                          hopcount));
+                       rdev->rswitch->route_table[destid] =
+                           rio_get_swpinfo_inport(port, RIO_ANY_DESTID,
+                                                  hopcount);
+               }
+
+               num_ports =
+                   rio_get_swpinfo_tports(port, RIO_ANY_DESTID, hopcount);
+               pr_debug(
+                   "RIO: found %s (vid %4.4x did %4.4x) with %d ports\n",
+                   rio_name(rdev), rdev->vid, rdev->did, num_ports);
+               for (port_num = 0; port_num < num_ports; port_num++) {
+                       if (rio_get_swpinfo_inport
+                           (port, RIO_ANY_DESTID, hopcount) == port_num)
+                               continue;
+
+                       cur_destid = next_destid;
+
+                       if (rio_sport_is_active
+                           (port, RIO_ANY_DESTID, hopcount, port_num)) {
+                               pr_debug(
+                                   "RIO: scanning device on port %d\n",
+                                   port_num);
+                               rio_route_add_entry(port, rdev,
+                                                   RIO_GLOBAL_TABLE,
+                                                   RIO_ANY_DESTID, port_num);
+
+                               if (rio_enum_peer(net, port, hopcount + 1) < 0)
+                                       return -1;
+
+                               /* Update routing tables */
+                               if (next_destid > cur_destid) {
+                                       for (destid = cur_destid;
+                                            destid < next_destid; destid++) {
+                                               rio_route_add_entry(port, rdev,
+                                                                   RIO_GLOBAL_TABLE,
+                                                                   destid,
+                                                                   port_num);
+                                               rdev->rswitch->
+                                                   route_table[destid] =
+                                                   port_num;
+                                       }
+                                       rdev->rswitch->destid = cur_destid;
+                               }
+                       }
+               }
+       } else
+               pr_debug("RIO: found %s (vid %4.4x did %4.4x)\n",
+                   rio_name(rdev), rdev->vid, rdev->did);
+
+       return 0;
+}
+
+/**
+ * rio_enum_complete- Tests if enumeration of a network is complete
+ * @port: Master port to send transaction
+ *
+ * Tests the Component Tag CSR for presence of the magic enumeration
+ * complete flag. Return %1 if enumeration is complete or %0 if
+ * enumeration is incomplete.
+ */
+static int rio_enum_complete(struct rio_mport *port)
+{
+       u32 tag_csr;
+       int ret = 0;
+
+       rio_local_read_config_32(port, RIO_COMPONENT_TAG_CSR, &tag_csr);
+
+       if (tag_csr == RIO_ENUM_CMPL_MAGIC)
+               ret = 1;
+
+       return ret;
+}
+
+/**
+ * rio_disc_peer- Recursively discovers a RIO network through a master port
+ * @net: RIO network being discovered
+ * @port: Master port to send transactions
+ * @destid: Current destination ID in network
+ * @hopcount: Number of hops into the network
+ *
+ * Recursively discovers a RIO network.  Transactions are sent via the
+ * master port passed in @port.
+ */
+static int
+rio_disc_peer(struct rio_net *net, struct rio_mport *port, u16 destid,
+             u8 hopcount)
+{
+       u8 port_num, route_port;
+       int num_ports;
+       struct rio_dev *rdev;
+       u16 ndestid;
+
+       /* Setup new RIO device */
+       if ((rdev = rio_setup_device(net, port, destid, hopcount, 0))) {
+               /* Add device to the global and bus/net specific list. */
+               list_add_tail(&rdev->net_list, &net->devices);
+       } else
+               return -1;
+
+       if (rio_is_switch(rdev)) {
+               next_switchid++;
+
+               /* Associated destid is how we accessed this switch */
+               rdev->rswitch->destid = destid;
+
+               num_ports = rio_get_swpinfo_tports(port, destid, hopcount);
+               pr_debug(
+                   "RIO: found %s (vid %4.4x did %4.4x) with %d ports\n",
+                   rio_name(rdev), rdev->vid, rdev->did, num_ports);
+               for (port_num = 0; port_num < num_ports; port_num++) {
+                       if (rio_get_swpinfo_inport(port, destid, hopcount) ==
+                           port_num)
+                               continue;
+
+                       if (rio_sport_is_active
+                           (port, destid, hopcount, port_num)) {
+                               pr_debug(
+                                   "RIO: scanning device on port %d\n",
+                                   port_num);
+                               for (ndestid = 0; ndestid < RIO_ANY_DESTID;
+                                    ndestid++) {
+                                       rio_route_get_entry(port, rdev,
+                                                           RIO_GLOBAL_TABLE,
+                                                           ndestid,
+                                                           &route_port);
+                                       if (route_port == port_num)
+                                               break;
+                               }
+
+                               if (rio_disc_peer
+                                   (net, port, ndestid, hopcount + 1) < 0)
+                                       return -1;
+                       }
+               }
+       } else
+               pr_debug("RIO: found %s (vid %4.4x did %4.4x)\n",
+                   rio_name(rdev), rdev->vid, rdev->did);
+
+       return 0;
+}
+
+/**
+ * rio_mport_is_active- Tests if master port link is active
+ * @port: Master port to test
+ *
+ * Reads the port error status CSR for the master port to
+ * determine if the port has an active link.  Returns
+ * %PORT_N_ERR_STS_PORT_OK if the  master port is active
+ * or %0 if it is inactive.
+ */
+static int rio_mport_is_active(struct rio_mport *port)
+{
+       u32 result = 0;
+       u32 ext_ftr_ptr;
+       int *entry = rio_mport_phys_table;
+
+       do {
+               if ((ext_ftr_ptr =
+                    rio_mport_get_feature(port, 1, 0, 0, *entry)))
+                       break;
+       } while (*++entry >= 0);
+
+       if (ext_ftr_ptr)
+               rio_local_read_config_32(port,
+                                        ext_ftr_ptr +
+                                        RIO_PORT_N_ERR_STS_CSR(port->index),
+                                        &result);
+
+       return (result & PORT_N_ERR_STS_PORT_OK);
+}
+
+/**
+ * rio_alloc_net- Allocate and configure a new RIO network
+ * @port: Master port associated with the RIO network
+ *
+ * Allocates a RIO network structure, initializes per-network
+ * list heads, and adds the associated master port to the
+ * network list of associated master ports. Returns a
+ * RIO network pointer on success or %NULL on failure.
+ */
+static struct rio_net __devinit *rio_alloc_net(struct rio_mport *port)
+{
+       struct rio_net *net;
+
+       net = kmalloc(sizeof(struct rio_net), GFP_KERNEL);
+       if (net) {
+               memset(net, 0, sizeof(struct rio_net));
+               INIT_LIST_HEAD(&net->node);
+               INIT_LIST_HEAD(&net->devices);
+               INIT_LIST_HEAD(&net->mports);
+               list_add_tail(&port->nnode, &net->mports);
+               net->hport = port;
+               net->id = next_net++;
+       }
+       return net;
+}
+
+/**
+ * rio_enum_mport- Start enumeration through a master port
+ * @mport: Master port to send transactions
+ *
+ * Starts the enumeration process. If somebody has enumerated our
+ * master port device, then give up. If not and we have an active
+ * link, then start recursive peer enumeration. Returns %0 if
+ * enumeration succeeds or %-EBUSY if enumeration fails.
+ */
+int rio_enum_mport(struct rio_mport *mport)
+{
+       struct rio_net *net = NULL;
+       int rc = 0;
+
+       printk(KERN_INFO "RIO: enumerate master port %d, %s\n", mport->id,
+              mport->name);
+       /* If somebody else enumerated our master port device, bail. */
+       if (rio_enum_host(mport) < 0) {
+               printk(KERN_INFO
+                      "RIO: master port %d device has been enumerated by a remote host\n",
+                      mport->id);
+               rc = -EBUSY;
+               goto out;
+       }
+
+       /* If master port has an active link, allocate net and enum peers */
+       if (rio_mport_is_active(mport)) {
+               if (!(net = rio_alloc_net(mport))) {
+                       printk(KERN_ERR "RIO: failed to allocate new net\n");
+                       rc = -ENOMEM;
+                       goto out;
+               }
+               if (rio_enum_peer(net, mport, 0) < 0) {
+                       /* A higher priority host won enumeration, bail. */
+                       printk(KERN_INFO
+                              "RIO: master port %d device has lost enumeration to a remote host\n",
+                              mport->id);
+                       rio_clear_locks(mport);
+                       rc = -EBUSY;
+                       goto out;
+               }
+               rio_clear_locks(mport);
+       } else {
+               printk(KERN_INFO "RIO: master port %d link inactive\n",
+                      mport->id);
+               rc = -EINVAL;
+       }
+
+      out:
+       return rc;
+}
+
+/**
+ * rio_build_route_tables- Generate route tables from switch route entries
+ *
+ * For each switch device, generate a route table by copying existing
+ * route entries from the switch.
+ */
+static void rio_build_route_tables(void)
+{
+       struct rio_dev *rdev;
+       int i;
+       u8 sport;
+
+       list_for_each_entry(rdev, &rio_devices, global_list)
+           if (rio_is_switch(rdev))
+               for (i = 0; i < RIO_MAX_ROUTE_ENTRIES; i++) {
+                       if (rio_route_get_entry
+                           (rdev->net->hport, rdev, RIO_GLOBAL_TABLE, i,
+                            &sport) < 0)
+                               continue;
+                       rdev->rswitch->route_table[i] = sport;
+               }
+}
+
+/**
+ * rio_enum_timeout- Signal that enumeration timed out
+ * @data: Address of timeout flag.
+ *
+ * When the enumeration complete timer expires, set a flag that
+ * signals to the discovery process that enumeration did not
+ * complete in a sane amount of time.
+ */
+static void rio_enum_timeout(unsigned long data)
+{
+       /* Enumeration timed out, set flag */
+       *(int *)data = 1;
+}
+
+/**
+ * rio_disc_mport- Start discovery through a master port
+ * @mport: Master port to send transactions
+ *
+ * Starts the discovery process. If we have an active link,
+ * then wait for the signal that enumeration is complete.
+ * When enumeration completion is signaled, start recursive
+ * peer discovery. Returns %0 if discovery succeeds or %-EBUSY
+ * on failure.
+ */
+int rio_disc_mport(struct rio_mport *mport)
+{
+       struct rio_net *net = NULL;
+       int enum_timeout_flag = 0;
+
+       printk(KERN_INFO "RIO: discover master port %d, %s\n", mport->id,
+              mport->name);
+
+       /* If master port has an active link, allocate net and discover peers */
+       if (rio_mport_is_active(mport)) {
+               if (!(net = rio_alloc_net(mport))) {
+                       printk(KERN_ERR "RIO: Failed to allocate new net\n");
+                       goto bail;
+               }
+
+               pr_debug("RIO: wait for enumeration complete...");
+
+               rio_enum_timer.expires =
+                   jiffies + CONFIG_RAPIDIO_DISC_TIMEOUT * HZ;
+               rio_enum_timer.data = (unsigned long)&enum_timeout_flag;
+               add_timer(&rio_enum_timer);
+               while (!rio_enum_complete(mport)) {
+                       mdelay(1);
+                       if (enum_timeout_flag) {
+                               del_timer_sync(&rio_enum_timer);
+                               goto timeout;
+                       }
+               }
+               del_timer_sync(&rio_enum_timer);
+
+               pr_debug("done\n");
+               if (rio_disc_peer(net, mport, RIO_ANY_DESTID, 0) < 0) {
+                       printk(KERN_INFO
+                              "RIO: master port %d device has failed discovery\n",
+                              mport->id);
+                       goto bail;
+               }
+
+               rio_build_route_tables();
+       }
+
+       return 0;
+
+      timeout:
+       pr_debug("timeout\n");
+      bail:
+       return -EBUSY;
+}
diff --git a/drivers/rapidio/rio-sysfs.c b/drivers/rapidio/rio-sysfs.c
new file mode 100644 (file)
index 0000000..30a1143
--- /dev/null
@@ -0,0 +1,230 @@
+/*
+ * RapidIO sysfs attributes and support
+ *
+ * Copyright 2005 MontaVista Software, Inc.
+ * Matt Porter <mporter@kernel.crashing.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.
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/rio.h>
+#include <linux/rio_drv.h>
+#include <linux/stat.h>
+
+#include "rio.h"
+
+/* Sysfs support */
+#define rio_config_attr(field, format_string)                                  \
+static ssize_t                                                         \
+field##_show(struct device *dev, struct device_attribute *attr, char *buf)                     \
+{                                                                      \
+       struct rio_dev *rdev = to_rio_dev(dev);                         \
+                                                                       \
+       return sprintf(buf, format_string, rdev->field);                \
+}                                                                      \
+
+rio_config_attr(did, "0x%04x\n");
+rio_config_attr(vid, "0x%04x\n");
+rio_config_attr(device_rev, "0x%08x\n");
+rio_config_attr(asm_did, "0x%04x\n");
+rio_config_attr(asm_vid, "0x%04x\n");
+rio_config_attr(asm_rev, "0x%04x\n");
+
+static ssize_t routes_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+       struct rio_dev *rdev = to_rio_dev(dev);
+       char *str = buf;
+       int i;
+
+       if (!rdev->rswitch)
+               goto out;
+
+       for (i = 0; i < RIO_MAX_ROUTE_ENTRIES; i++) {
+               if (rdev->rswitch->route_table[i] == RIO_INVALID_ROUTE)
+                       continue;
+               str +=
+                   sprintf(str, "%04x %02x\n", i,
+                           rdev->rswitch->route_table[i]);
+       }
+
+      out:
+       return (str - buf);
+}
+
+struct device_attribute rio_dev_attrs[] = {
+       __ATTR_RO(did),
+       __ATTR_RO(vid),
+       __ATTR_RO(device_rev),
+       __ATTR_RO(asm_did),
+       __ATTR_RO(asm_vid),
+       __ATTR_RO(asm_rev),
+       __ATTR_RO(routes),
+       __ATTR_NULL,
+};
+
+static ssize_t
+rio_read_config(struct kobject *kobj, char *buf, loff_t off, size_t count)
+{
+       struct rio_dev *dev =
+           to_rio_dev(container_of(kobj, struct device, kobj));
+       unsigned int size = 0x100;
+       loff_t init_off = off;
+       u8 *data = (u8 *) buf;
+
+       /* Several chips lock up trying to read undefined config space */
+       if (capable(CAP_SYS_ADMIN))
+               size = 0x200000;
+
+       if (off > size)
+               return 0;
+       if (off + count > size) {
+               size -= off;
+               count = size;
+       } else {
+               size = count;
+       }
+
+       if ((off & 1) && size) {
+               u8 val;
+               rio_read_config_8(dev, off, &val);
+               data[off - init_off] = val;
+               off++;
+               size--;
+       }
+
+       if ((off & 3) && size > 2) {
+               u16 val;
+               rio_read_config_16(dev, off, &val);
+               data[off - init_off] = (val >> 8) & 0xff;
+               data[off - init_off + 1] = val & 0xff;
+               off += 2;
+               size -= 2;
+       }
+
+       while (size > 3) {
+               u32 val;
+               rio_read_config_32(dev, off, &val);
+               data[off - init_off] = (val >> 24) & 0xff;
+               data[off - init_off + 1] = (val >> 16) & 0xff;
+               data[off - init_off + 2] = (val >> 8) & 0xff;
+               data[off - init_off + 3] = val & 0xff;
+               off += 4;
+               size -= 4;
+       }
+
+       if (size >= 2) {
+               u16 val;
+               rio_read_config_16(dev, off, &val);
+               data[off - init_off] = (val >> 8) & 0xff;
+               data[off - init_off + 1] = val & 0xff;
+               off += 2;
+               size -= 2;
+       }
+
+       if (size > 0) {
+               u8 val;
+               rio_read_config_8(dev, off, &val);
+               data[off - init_off] = val;
+               off++;
+               --size;
+       }
+
+       return count;
+}
+
+static ssize_t
+rio_write_config(struct kobject *kobj, char *buf, loff_t off, size_t count)
+{
+       struct rio_dev *dev =
+           to_rio_dev(container_of(kobj, struct device, kobj));
+       unsigned int size = count;
+       loff_t init_off = off;
+       u8 *data = (u8 *) buf;
+
+       if (off > 0x200000)
+               return 0;
+       if (off + count > 0x200000) {
+               size = 0x200000 - off;
+               count = size;
+       }
+
+       if ((off & 1) && size) {
+               rio_write_config_8(dev, off, data[off - init_off]);
+               off++;
+               size--;
+       }
+
+       if ((off & 3) && (size > 2)) {
+               u16 val = data[off - init_off + 1];
+               val |= (u16) data[off - init_off] << 8;
+               rio_write_config_16(dev, off, val);
+               off += 2;
+               size -= 2;
+       }
+
+       while (size > 3) {
+               u32 val = data[off - init_off + 3];
+               val |= (u32) data[off - init_off + 2] << 8;
+               val |= (u32) data[off - init_off + 1] << 16;
+               val |= (u32) data[off - init_off] << 24;
+               rio_write_config_32(dev, off, val);
+               off += 4;
+               size -= 4;
+       }
+
+       if (size >= 2) {
+               u16 val = data[off - init_off + 1];
+               val |= (u16) data[off - init_off] << 8;
+               rio_write_config_16(dev, off, val);
+               off += 2;
+               size -= 2;
+       }
+
+       if (size) {
+               rio_write_config_8(dev, off, data[off - init_off]);
+               off++;
+               --size;
+       }
+
+       return count;
+}
+
+static struct bin_attribute rio_config_attr = {
+       .attr = {
+                .name = "config",
+                .mode = S_IRUGO | S_IWUSR,
+                .owner = THIS_MODULE,
+                },
+       .size = 0x200000,
+       .read = rio_read_config,
+       .write = rio_write_config,
+};
+
+/**
+ * rio_create_sysfs_dev_files - create RIO specific sysfs files
+ * @rdev: device whose entries should be created
+ *
+ * Create files when @rdev is added to sysfs.
+ */
+int rio_create_sysfs_dev_files(struct rio_dev *rdev)
+{
+       sysfs_create_bin_file(&rdev->dev.kobj, &rio_config_attr);
+
+       return 0;
+}
+
+/**
+ * rio_remove_sysfs_dev_files - cleanup RIO specific sysfs files
+ * @rdev: device whose entries we should free
+ *
+ * Cleanup when @rdev is removed from sysfs.
+ */
+void rio_remove_sysfs_dev_files(struct rio_dev *rdev)
+{
+       sysfs_remove_bin_file(&rdev->dev.kobj, &rio_config_attr);
+}
diff --git a/drivers/rapidio/rio.c b/drivers/rapidio/rio.c
new file mode 100644 (file)
index 0000000..3ca1011
--- /dev/null
@@ -0,0 +1,510 @@
+/*
+ * RapidIO interconnect services
+ * (RapidIO Interconnect Specification, http://www.rapidio.org)
+ *
+ * Copyright 2005 MontaVista Software, Inc.
+ * Matt Porter <mporter@kernel.crashing.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.
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/rio.h>
+#include <linux/rio_drv.h>
+#include <linux/rio_ids.h>
+#include <linux/rio_regs.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+
+#include "rio.h"
+
+static LIST_HEAD(rio_mports);
+
+/**
+ * rio_local_get_device_id - Get the base/extended device id for a port
+ * @port: RIO master port from which to get the deviceid
+ *
+ * Reads the base/extended device id from the local device
+ * implementing the master port. Returns the 8/16-bit device
+ * id.
+ */
+u16 rio_local_get_device_id(struct rio_mport *port)
+{
+       u32 result;
+
+       rio_local_read_config_32(port, RIO_DID_CSR, &result);
+
+       return (RIO_GET_DID(result));
+}
+
+/**
+ * rio_request_inb_mbox - request inbound mailbox service
+ * @mport: RIO master port from which to allocate the mailbox resource
+ * @dev_id: Device specific pointer to pass on event
+ * @mbox: Mailbox number to claim
+ * @entries: Number of entries in inbound mailbox queue
+ * @minb: Callback to execute when inbound message is received
+ *
+ * Requests ownership of an inbound mailbox resource and binds
+ * a callback function to the resource. Returns %0 on success.
+ */
+int rio_request_inb_mbox(struct rio_mport *mport,
+                        void *dev_id,
+                        int mbox,
+                        int entries,
+                        void (*minb) (struct rio_mport * mport, void *dev_id, int mbox,
+                                      int slot))
+{
+       int rc = 0;
+
+       struct resource *res = kmalloc(sizeof(struct resource), GFP_KERNEL);
+
+       if (res) {
+               rio_init_mbox_res(res, mbox, mbox);
+
+               /* Make sure this mailbox isn't in use */
+               if ((rc =
+                    request_resource(&mport->riores[RIO_INB_MBOX_RESOURCE],
+                                     res)) < 0) {
+                       kfree(res);
+                       goto out;
+               }
+
+               mport->inb_msg[mbox].res = res;
+
+               /* Hook the inbound message callback */
+               mport->inb_msg[mbox].mcback = minb;
+
+               rc = rio_open_inb_mbox(mport, dev_id, mbox, entries);
+       } else
+               rc = -ENOMEM;
+
+      out:
+       return rc;
+}
+
+/**
+ * rio_release_inb_mbox - release inbound mailbox message service
+ * @mport: RIO master port from which to release the mailbox resource
+ * @mbox: Mailbox number to release
+ *
+ * Releases ownership of an inbound mailbox resource. Returns 0
+ * if the request has been satisfied.
+ */
+int rio_release_inb_mbox(struct rio_mport *mport, int mbox)
+{
+       rio_close_inb_mbox(mport, mbox);
+
+       /* Release the mailbox resource */
+       return release_resource(mport->inb_msg[mbox].res);
+}
+
+/**
+ * rio_request_outb_mbox - request outbound mailbox service
+ * @mport: RIO master port from which to allocate the mailbox resource
+ * @dev_id: Device specific pointer to pass on event
+ * @mbox: Mailbox number to claim
+ * @entries: Number of entries in outbound mailbox queue
+ * @moutb: Callback to execute when outbound message is sent
+ *
+ * Requests ownership of an outbound mailbox resource and binds
+ * a callback function to the resource. Returns 0 on success.
+ */
+int rio_request_outb_mbox(struct rio_mport *mport,
+                         void *dev_id,
+                         int mbox,
+                         int entries,
+                         void (*moutb) (struct rio_mport * mport, void *dev_id, int mbox, int slot))
+{
+       int rc = 0;
+
+       struct resource *res = kmalloc(sizeof(struct resource), GFP_KERNEL);
+
+       if (res) {
+               rio_init_mbox_res(res, mbox, mbox);
+
+               /* Make sure this outbound mailbox isn't in use */
+               if ((rc =
+                    request_resource(&mport->riores[RIO_OUTB_MBOX_RESOURCE],
+                                     res)) < 0) {
+                       kfree(res);
+                       goto out;
+               }
+
+               mport->outb_msg[mbox].res = res;
+
+               /* Hook the inbound message callback */
+               mport->outb_msg[mbox].mcback = moutb;
+
+               rc = rio_open_outb_mbox(mport, dev_id, mbox, entries);
+       } else
+               rc = -ENOMEM;
+
+      out:
+       return rc;
+}
+
+/**
+ * rio_release_outb_mbox - release outbound mailbox message service
+ * @mport: RIO master port from which to release the mailbox resource
+ * @mbox: Mailbox number to release
+ *
+ * Releases ownership of an inbound mailbox resource. Returns 0
+ * if the request has been satisfied.
+ */
+int rio_release_outb_mbox(struct rio_mport *mport, int mbox)
+{
+       rio_close_outb_mbox(mport, mbox);
+
+       /* Release the mailbox resource */
+       return release_resource(mport->outb_msg[mbox].res);
+}
+
+/**
+ * rio_setup_inb_dbell - bind inbound doorbell callback
+ * @mport: RIO master port to bind the doorbell callback
+ * @dev_id: Device specific pointer to pass on event
+ * @res: Doorbell message resource
+ * @dinb: Callback to execute when doorbell is received
+ *
+ * Adds a doorbell resource/callback pair into a port's
+ * doorbell event list. Returns 0 if the request has been
+ * satisfied.
+ */
+static int
+rio_setup_inb_dbell(struct rio_mport *mport, void *dev_id, struct resource *res,
+                   void (*dinb) (struct rio_mport * mport, void *dev_id, u16 src, u16 dst,
+                                 u16 info))
+{
+       int rc = 0;
+       struct rio_dbell *dbell;
+
+       if (!(dbell = kmalloc(sizeof(struct rio_dbell), GFP_KERNEL))) {
+               rc = -ENOMEM;
+               goto out;
+       }
+
+       dbell->res = res;
+       dbell->dinb = dinb;
+       dbell->dev_id = dev_id;
+
+       list_add_tail(&dbell->node, &mport->dbells);
+
+      out:
+       return rc;
+}
+
+/**
+ * rio_request_inb_dbell - request inbound doorbell message service
+ * @mport: RIO master port from which to allocate the doorbell resource
+ * @dev_id: Device specific pointer to pass on event
+ * @start: Doorbell info range start
+ * @end: Doorbell info range end
+ * @dinb: Callback to execute when doorbell is received
+ *
+ * Requests ownership of an inbound doorbell resource and binds
+ * a callback function to the resource. Returns 0 if the request
+ * has been satisfied.
+ */
+int rio_request_inb_dbell(struct rio_mport *mport,
+                         void *dev_id,
+                         u16 start,
+                         u16 end,
+                         void (*dinb) (struct rio_mport * mport, void *dev_id, u16 src,
+                                       u16 dst, u16 info))
+{
+       int rc = 0;
+
+       struct resource *res = kmalloc(sizeof(struct resource), GFP_KERNEL);
+
+       if (res) {
+               rio_init_dbell_res(res, start, end);
+
+               /* Make sure these doorbells aren't in use */
+               if ((rc =
+                    request_resource(&mport->riores[RIO_DOORBELL_RESOURCE],
+                                     res)) < 0) {
+                       kfree(res);
+                       goto out;
+               }
+
+               /* Hook the doorbell callback */
+               rc = rio_setup_inb_dbell(mport, dev_id, res, dinb);
+       } else
+               rc = -ENOMEM;
+
+      out:
+       return rc;
+}
+
+/**
+ * rio_release_inb_dbell - release inbound doorbell message service
+ * @mport: RIO master port from which to release the doorbell resource
+ * @start: Doorbell info range start
+ * @end: Doorbell info range end
+ *
+ * Releases ownership of an inbound doorbell resource and removes
+ * callback from the doorbell event list. Returns 0 if the request
+ * has been satisfied.
+ */
+int rio_release_inb_dbell(struct rio_mport *mport, u16 start, u16 end)
+{
+       int rc = 0, found = 0;
+       struct rio_dbell *dbell;
+
+       list_for_each_entry(dbell, &mport->dbells, node) {
+               if ((dbell->res->start == start) && (dbell->res->end == end)) {
+                       found = 1;
+                       break;
+               }
+       }
+
+       /* If we can't find an exact match, fail */
+       if (!found) {
+               rc = -EINVAL;
+               goto out;
+       }
+
+       /* Delete from list */
+       list_del(&dbell->node);
+
+       /* Release the doorbell resource */
+       rc = release_resource(dbell->res);
+
+       /* Free the doorbell event */
+       kfree(dbell);
+
+      out:
+       return rc;
+}
+
+/**
+ * rio_request_outb_dbell - request outbound doorbell message range
+ * @rdev: RIO device from which to allocate the doorbell resource
+ * @start: Doorbell message range start
+ * @end: Doorbell message range end
+ *
+ * Requests ownership of a doorbell message range. Returns a resource
+ * if the request has been satisfied or %NULL on failure.
+ */
+struct resource *rio_request_outb_dbell(struct rio_dev *rdev, u16 start,
+                                       u16 end)
+{
+       struct resource *res = kmalloc(sizeof(struct resource), GFP_KERNEL);
+
+       if (res) {
+               rio_init_dbell_res(res, start, end);
+
+               /* Make sure these doorbells aren't in use */
+               if (request_resource(&rdev->riores[RIO_DOORBELL_RESOURCE], res)
+                   < 0) {
+                       kfree(res);
+                       res = NULL;
+               }
+       }
+
+       return res;
+}
+
+/**
+ * rio_release_outb_dbell - release outbound doorbell message range
+ * @rdev: RIO device from which to release the doorbell resource
+ * @res: Doorbell resource to be freed
+ *
+ * Releases ownership of a doorbell message range. Returns 0 if the
+ * request has been satisfied.
+ */
+int rio_release_outb_dbell(struct rio_dev *rdev, struct resource *res)
+{
+       int rc = release_resource(res);
+
+       kfree(res);
+
+       return rc;
+}
+
+/**
+ * rio_mport_get_feature - query for devices' extended features
+ * @port: Master port to issue transaction
+ * @local: Indicate a local master port or remote device access
+ * @destid: Destination ID of the device
+ * @hopcount: Number of switch hops to the device
+ * @ftr: Extended feature code
+ *
+ * Tell if a device supports a given RapidIO capability.
+ * Returns the offset of the requested extended feature
+ * block within the device's RIO configuration space or
+ * 0 in case the device does not support it.  Possible
+ * values for @ftr:
+ *
+ * %RIO_EFB_PAR_EP_ID          LP/LVDS EP Devices
+ *
+ * %RIO_EFB_PAR_EP_REC_ID      LP/LVDS EP Recovery Devices
+ *
+ * %RIO_EFB_PAR_EP_FREE_ID     LP/LVDS EP Free Devices
+ *
+ * %RIO_EFB_SER_EP_ID          LP/Serial EP Devices
+ *
+ * %RIO_EFB_SER_EP_REC_ID      LP/Serial EP Recovery Devices
+ *
+ * %RIO_EFB_SER_EP_FREE_ID     LP/Serial EP Free Devices
+ */
+u32
+rio_mport_get_feature(struct rio_mport * port, int local, u16 destid,
+                     u8 hopcount, int ftr)
+{
+       u32 asm_info, ext_ftr_ptr, ftr_header;
+
+       if (local)
+               rio_local_read_config_32(port, RIO_ASM_INFO_CAR, &asm_info);
+       else
+               rio_mport_read_config_32(port, destid, hopcount,
+                                        RIO_ASM_INFO_CAR, &asm_info);
+
+       ext_ftr_ptr = asm_info & RIO_EXT_FTR_PTR_MASK;
+
+       while (ext_ftr_ptr) {
+               if (local)
+                       rio_local_read_config_32(port, ext_ftr_ptr,
+                                                &ftr_header);
+               else
+                       rio_mport_read_config_32(port, destid, hopcount,
+                                                ext_ftr_ptr, &ftr_header);
+               if (RIO_GET_BLOCK_ID(ftr_header) == ftr)
+                       return ext_ftr_ptr;
+               if (!(ext_ftr_ptr = RIO_GET_BLOCK_PTR(ftr_header)))
+                       break;
+       }
+
+       return 0;
+}
+
+/**
+ * rio_get_asm - Begin or continue searching for a RIO device by vid/did/asm_vid/asm_did
+ * @vid: RIO vid to match or %RIO_ANY_ID to match all vids
+ * @did: RIO did to match or %RIO_ANY_ID to match all dids
+ * @asm_vid: RIO asm_vid to match or %RIO_ANY_ID to match all asm_vids
+ * @asm_did: RIO asm_did to match or %RIO_ANY_ID to match all asm_dids
+ * @from: Previous RIO device found in search, or %NULL for new search
+ *
+ * Iterates through the list of known RIO devices. If a RIO device is
+ * found with a matching @vid, @did, @asm_vid, @asm_did, the reference
+ * count to the device is incrememted and a pointer to its device
+ * structure is returned. Otherwise, %NULL is returned. A new search
+ * is initiated by passing %NULL to 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 rio_dev *rio_get_asm(u16 vid, u16 did,
+                           u16 asm_vid, u16 asm_did, struct rio_dev *from)
+{
+       struct list_head *n;
+       struct rio_dev *rdev;
+
+       WARN_ON(in_interrupt());
+       spin_lock(&rio_global_list_lock);
+       n = from ? from->global_list.next : rio_devices.next;
+
+       while (n && (n != &rio_devices)) {
+               rdev = rio_dev_g(n);
+               if ((vid == RIO_ANY_ID || rdev->vid == vid) &&
+                   (did == RIO_ANY_ID || rdev->did == did) &&
+                   (asm_vid == RIO_ANY_ID || rdev->asm_vid == asm_vid) &&
+                   (asm_did == RIO_ANY_ID || rdev->asm_did == asm_did))
+                       goto exit;
+               n = n->next;
+       }
+       rdev = NULL;
+      exit:
+       rio_dev_put(from);
+       rdev = rio_dev_get(rdev);
+       spin_unlock(&rio_global_list_lock);
+       return rdev;
+}
+
+/**
+ * rio_get_device - Begin or continue searching for a RIO device by vid/did
+ * @vid: RIO vid to match or %RIO_ANY_ID to match all vids
+ * @did: RIO did to match or %RIO_ANY_ID to match all dids
+ * @from: Previous RIO device found in search, or %NULL for new search
+ *
+ * Iterates through the list of known RIO devices. If a RIO device is
+ * found with a matching @vid and @did, the reference count to the
+ * device is incrememted and a pointer to its device structure is returned.
+ * Otherwise, %NULL is returned. A new search is initiated by passing %NULL
+ * to 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 rio_dev *rio_get_device(u16 vid, u16 did, struct rio_dev *from)
+{
+       return rio_get_asm(vid, did, RIO_ANY_ID, RIO_ANY_ID, from);
+}
+
+static void rio_fixup_device(struct rio_dev *dev)
+{
+}
+
+static int __devinit rio_init(void)
+{
+       struct rio_dev *dev = NULL;
+
+       while ((dev = rio_get_device(RIO_ANY_ID, RIO_ANY_ID, dev)) != NULL) {
+               rio_fixup_device(dev);
+       }
+       return 0;
+}
+
+device_initcall(rio_init);
+
+int rio_init_mports(void)
+{
+       int rc = 0;
+       struct rio_mport *port;
+
+       list_for_each_entry(port, &rio_mports, node) {
+               if (!request_mem_region(port->iores.start,
+                                       port->iores.end - port->iores.start,
+                                       port->name)) {
+                       printk(KERN_ERR
+                              "RIO: Error requesting master port region %8.8lx-%8.8lx\n",
+                              port->iores.start, port->iores.end - 1);
+                       rc = -ENOMEM;
+                       goto out;
+               }
+
+               if (port->host_deviceid >= 0)
+                       rio_enum_mport(port);
+               else
+                       rio_disc_mport(port);
+       }
+
+      out:
+       return rc;
+}
+
+void rio_register_mport(struct rio_mport *port)
+{
+       list_add_tail(&port->node, &rio_mports);
+}
+
+EXPORT_SYMBOL_GPL(rio_local_get_device_id);
+EXPORT_SYMBOL_GPL(rio_get_device);
+EXPORT_SYMBOL_GPL(rio_get_asm);
+EXPORT_SYMBOL_GPL(rio_request_inb_dbell);
+EXPORT_SYMBOL_GPL(rio_release_inb_dbell);
+EXPORT_SYMBOL_GPL(rio_request_outb_dbell);
+EXPORT_SYMBOL_GPL(rio_release_outb_dbell);
+EXPORT_SYMBOL_GPL(rio_request_inb_mbox);
+EXPORT_SYMBOL_GPL(rio_release_inb_mbox);
+EXPORT_SYMBOL_GPL(rio_request_outb_mbox);
+EXPORT_SYMBOL_GPL(rio_release_outb_mbox);
diff --git a/drivers/rapidio/rio.h b/drivers/rapidio/rio.h
new file mode 100644 (file)
index 0000000..b242cee
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * RapidIO interconnect services
+ *
+ * Copyright 2005 MontaVista Software, Inc.
+ * Matt Porter <mporter@kernel.crashing.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.
+ */
+
+#include <linux/device.h>
+#include <linux/list.h>
+#include <linux/rio.h>
+
+/* Functions internal to the RIO core code */
+
+extern u32 rio_mport_get_feature(struct rio_mport *mport, int local, u16 destid,
+                                u8 hopcount, int ftr);
+extern int rio_create_sysfs_dev_files(struct rio_dev *rdev);
+extern int rio_enum_mport(struct rio_mport *mport);
+extern int rio_disc_mport(struct rio_mport *mport);
+
+/* Structures internal to the RIO core code */
+extern struct device_attribute rio_dev_attrs[];
+extern spinlock_t rio_global_list_lock;
+
+extern struct rio_route_ops __start_rio_route_ops[];
+extern struct rio_route_ops __end_rio_route_ops[];
+
+/* Helpers internal to the RIO core code */
+#define DECLARE_RIO_ROUTE_SECTION(section, vid, did, add_hook, get_hook)  \
+        static struct rio_route_ops __rio_route_ops __attribute_used__   \
+               __attribute__((__section__(#section))) = { vid, did, add_hook, get_hook };
+
+/**
+ * DECLARE_RIO_ROUTE_OPS - Registers switch routing operations
+ * @vid: RIO vendor ID
+ * @did: RIO device ID
+ * @add_hook: Callback that adds a route entry
+ * @get_hook: Callback that gets a route entry
+ *
+ * Manipulating switch route tables in RIO is switch specific. This
+ * registers a switch by vendor and device ID with two callbacks for
+ * modifying and retrieving route entries in a switch. A &struct
+ * rio_route_ops is initialized with the ops and placed into a
+ * RIO-specific kernel section.
+ */
+#define DECLARE_RIO_ROUTE_OPS(vid, did, add_hook, get_hook)            \
+       DECLARE_RIO_ROUTE_SECTION(.rio_route_ops,                       \
+                       vid, did, add_hook, get_hook)
+
+#ifdef CONFIG_RAPIDIO_8_BIT_TRANSPORT
+#define RIO_GET_DID(x) ((x & 0x00ff0000) >> 16)
+#define RIO_SET_DID(x) ((x & 0x000000ff) << 16)
+#else
+#define RIO_GET_DID(x) (x & 0xffff)
+#define RIO_SET_DID(x) (x & 0xffff)
+#endif
diff --git a/drivers/rapidio/switches/Makefile b/drivers/rapidio/switches/Makefile
new file mode 100644 (file)
index 0000000..b924f83
--- /dev/null
@@ -0,0 +1,5 @@
+#
+# Makefile for RIO switches
+#
+
+obj-$(CONFIG_RAPIDIO)  += tsi500.o
diff --git a/drivers/rapidio/switches/tsi500.c b/drivers/rapidio/switches/tsi500.c
new file mode 100644 (file)
index 0000000..c77c23b
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * RapidIO Tsi500 switch support
+ *
+ * Copyright 2005 MontaVista Software, Inc.
+ * Matt Porter <mporter@kernel.crashing.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.
+ */
+
+#include <linux/rio.h>
+#include <linux/rio_drv.h>
+#include <linux/rio_ids.h>
+#include "../rio.h"
+
+static int
+tsi500_route_add_entry(struct rio_mport *mport, u16 destid, u8 hopcount, u16 table, u16 route_destid, u8 route_port)
+{
+       int i;
+       u32 offset = 0x10000 + 0xa00 + ((route_destid / 2)&~0x3);
+       u32 result;
+
+       if (table == 0xff) {
+               rio_mport_read_config_32(mport, destid, hopcount, offset, &result);
+               result &= ~(0xf << (4*(route_destid & 0x7)));
+               for (i=0;i<4;i++)
+                       rio_mport_write_config_32(mport, destid, hopcount, offset + (0x20000*i), result | (route_port << (4*(route_destid & 0x7))));
+       }
+       else {
+               rio_mport_read_config_32(mport, destid, hopcount, offset + (0x20000*table), &result);
+               result &= ~(0xf << (4*(route_destid & 0x7)));
+               rio_mport_write_config_32(mport, destid, hopcount, offset + (0x20000*table), result | (route_port << (4*(route_destid & 0x7))));
+       }
+
+       return 0;
+}
+
+static int
+tsi500_route_get_entry(struct rio_mport *mport, u16 destid, u8 hopcount, u16 table, u16 route_destid, u8 *route_port)
+{
+       int ret = 0;
+       u32 offset = 0x10000 + 0xa00 + ((route_destid / 2)&~0x3);
+       u32 result;
+
+       if (table == 0xff)
+               rio_mport_read_config_32(mport, destid, hopcount, offset, &result);
+       else
+               rio_mport_read_config_32(mport, destid, hopcount, offset + (0x20000*table), &result);
+
+       result &= 0xf << (4*(route_destid & 0x7));
+       *route_port = result >> (4*(route_destid & 0x7));
+       if (*route_port > 3)
+               ret = -1;
+
+       return ret;
+}
+
+DECLARE_RIO_ROUTE_OPS(RIO_VID_TUNDRA, RIO_DID_TSI500, tsi500_route_add_entry, tsi500_route_get_entry);
index 8fc891a9d47f569b823c02ed7dc85855f464fd0c..7008d32433bf9d12725748f67d8d7c8bc746678b 100644 (file)
@@ -115,8 +115,7 @@ dasd_alloc_device(void)
 void
 dasd_free_device(struct dasd_device *device)
 {
-       if (device->private)
-               kfree(device->private);
+       kfree(device->private);
        free_page((unsigned long) device->erp_mem);
        free_pages((unsigned long) device->ccw_mem, 1);
        kfree(device);
@@ -539,8 +538,7 @@ dasd_kmalloc_request(char *magic, int cplength, int datasize,
        if (datasize > 0) {
                cqr->data = kmalloc(datasize, GFP_ATOMIC | GFP_DMA);
                if (cqr->data == NULL) {
-                       if (cqr->cpaddr != NULL)
-                               kfree(cqr->cpaddr);
+                       kfree(cqr->cpaddr);
                        kfree(cqr);
                        return ERR_PTR(-ENOMEM);
                }
@@ -615,10 +613,8 @@ dasd_kfree_request(struct dasd_ccw_req * cqr, struct dasd_device * device)
                clear_normalized_cda(ccw);
        } while (ccw++->flags & (CCW_FLAG_CC | CCW_FLAG_DC));
 #endif
-       if (cqr->cpaddr != NULL)
-               kfree(cqr->cpaddr);
-       if (cqr->data != NULL)
-               kfree(cqr->data);
+       kfree(cqr->cpaddr);
+       kfree(cqr->data);
        kfree(cqr);
        dasd_put_device(device);
 }
index bda896d9d788f3b4ab83a694324c641a8b02223d..caee16a3dc624d48c3fbb84de7678c9557adbe5d 100644 (file)
@@ -387,8 +387,7 @@ dasd_add_busid(char *bus_id, int features)
                new = 0;
        }
        spin_unlock(&dasd_devmap_lock);
-       if (new)
-               kfree(new);
+       kfree(new);
        return devmap;
 }
 
index 7478423b53bb2e6b1ae09f4296466c0998344e08..ab8754e566bcbdff183f22982dbe91d2ba431cac 100644 (file)
@@ -6,7 +6,7 @@
  * Bugreports.to..: <Linux390@de.ibm.com>
  * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
  *
- * $Revision: 1.49 $
+ * $Revision: 1.51 $
  */
 
 #include <linux/config.h>
@@ -67,9 +67,9 @@ static const u8 DASD_DIAG_CMS1[] = { 0xc3, 0xd4, 0xe2, 0xf1 };/* EBCDIC CMS1 */
 static __inline__ int
 dia250(void *iob, int cmd)
 {
-       typedef struct {
-               char _[max(sizeof (struct dasd_diag_init_io),
-                          sizeof (struct dasd_diag_rw_io))];
+       typedef union {
+               struct dasd_diag_init_io init_io;
+               struct dasd_diag_rw_io rw_io;
        } addr_type;
        int rc;
 
@@ -190,7 +190,7 @@ dasd_start_diag(struct dasd_ccw_req * cqr)
        private->iob.flags = DASD_DIAG_RWFLAG_ASYNC;
        private->iob.block_count = dreq->block_count;
        private->iob.interrupt_params = (addr_t) cqr;
-       private->iob.bio_list = __pa(dreq->bio);
+       private->iob.bio_list = dreq->bio;
        private->iob.flaga = DASD_DIAG_FLAGA_DEFAULT;
 
        cqr->startclk = get_clock();
@@ -394,47 +394,57 @@ dasd_diag_check_device(struct dasd_device *device)
                memset(&bio, 0, sizeof (struct dasd_diag_bio));
                bio.type = MDSK_READ_REQ;
                bio.block_number = private->pt_block + 1;
-               bio.buffer = __pa(label);
+               bio.buffer = label;
                memset(&private->iob, 0, sizeof (struct dasd_diag_rw_io));
                private->iob.dev_nr = rdc_data->dev_nr;
                private->iob.key = 0;
                private->iob.flags = 0; /* do synchronous io */
                private->iob.block_count = 1;
                private->iob.interrupt_params = 0;
-               private->iob.bio_list = __pa(&bio);
+               private->iob.bio_list = &bio;
                private->iob.flaga = DASD_DIAG_FLAGA_DEFAULT;
                rc = dia250(&private->iob, RW_BIO);
-               if (rc == 0 || rc == 3)
-                       break;
+               if (rc == 3) {
+                       DEV_MESSAGE(KERN_WARNING, device, "%s",
+                               "DIAG call failed");
+                       rc = -EOPNOTSUPP;
+                       goto out;
+               }
                mdsk_term_io(device);
+               if (rc == 0)
+                       break;
        }
-       if (rc == 3) {
-               DEV_MESSAGE(KERN_WARNING, device, "%s", "DIAG call failed");
-               rc = -EOPNOTSUPP;
-       } else if (rc != 0) {
+       if (bsize > PAGE_SIZE) {
                DEV_MESSAGE(KERN_WARNING, device, "device access failed "
                            "(rc=%d)", rc);
                rc = -EIO;
+               goto out;
+       }
+       /* check for label block */
+       if (memcmp(label->label_id, DASD_DIAG_CMS1,
+                 sizeof(DASD_DIAG_CMS1)) == 0) {
+               /* get formatted blocksize from label block */
+               bsize = (unsigned int) label->block_size;
+               device->blocks = (unsigned long) label->block_count;
+       } else
+               device->blocks = end_block;
+       device->bp_block = bsize;
+       device->s2b_shift = 0;  /* bits to shift 512 to get a block */
+       for (sb = 512; sb < bsize; sb = sb << 1)
+               device->s2b_shift++;
+       rc = mdsk_init_io(device, device->bp_block, 0, NULL);
+       if (rc) {
+               DEV_MESSAGE(KERN_WARNING, device, "DIAG initialization "
+                       "failed (rc=%d)", rc);
+               rc = -EIO;
        } else {
-               if (memcmp(label->label_id, DASD_DIAG_CMS1,
-                         sizeof(DASD_DIAG_CMS1)) == 0) {
-                       /* get formatted blocksize from label block */
-                       bsize = (unsigned int) label->block_size;
-                       device->blocks = (unsigned long) label->block_count;
-               } else
-                       device->blocks = end_block;
-               device->bp_block = bsize;
-               device->s2b_shift = 0;  /* bits to shift 512 to get a block */
-               for (sb = 512; sb < bsize; sb = sb << 1)
-                       device->s2b_shift++;
-               
                DEV_MESSAGE(KERN_INFO, device,
                            "(%ld B/blk): %ldkB",
                            (unsigned long) device->bp_block,
                            (unsigned long) (device->blocks <<
                                device->s2b_shift) >> 1);
-               rc = 0;
        }
+out:
        free_page((long) label);
        return rc;
 }
@@ -529,7 +539,7 @@ dasd_diag_build_cp(struct dasd_device * device, struct request *req)
                                memset(dbio, 0, sizeof (struct dasd_diag_bio));
                                dbio->type = rw_cmd;
                                dbio->block_number = recid + 1;
-                               dbio->buffer = __pa(dst);
+                               dbio->buffer = dst;
                                dbio++;
                                dst += blksize;
                                recid++;
index b26eb28df4bf093e4b6816275ba46d91d4236896..df31484d73a77a088cb388507db5ad556c457d47 100644 (file)
@@ -6,7 +6,7 @@
  * Bugreports.to..: <Linux390@de.ibm.com>
  * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
  *
- * $Revision: 1.7 $
+ * $Revision: 1.8 $
  */
 
 #define MDSK_WRITE_REQ 0x01
@@ -78,7 +78,7 @@ struct dasd_diag_bio {
        u8 spare1[2];
        u32 alet;
        blocknum_t block_number;
-       u64 buffer;
+       void *buffer;
 } __attribute__ ((packed, aligned(8)));
 
 struct dasd_diag_init_io {
@@ -104,7 +104,7 @@ struct dasd_diag_rw_io {
        u32 alet;
        u8  spare3[4];
        u64 interrupt_params;
-       u64 bio_list;
+       struct dasd_diag_bio *bio_list;
        u8  spare4[8];
 } __attribute__ ((packed, aligned(8)));
 #else /* CONFIG_ARCH_S390X */
@@ -119,7 +119,7 @@ struct dasd_diag_bio {
        u16 spare1;
        blocknum_t block_number;
        u32 alet;
-       u32 buffer;
+       void *buffer;
 } __attribute__ ((packed, aligned(8)));
 
 struct dasd_diag_init_io {
@@ -142,7 +142,7 @@ struct dasd_diag_rw_io {
        u8 spare2[2];
        u32 block_count;
        u32 alet;
-       u32 bio_list;
+       struct dasd_diag_bio *bio_list;
        u32 interrupt_params;
        u8 spare3[20];
 } __attribute__ ((packed, aligned(8)));
index f11a67fda40e55a4a009ff04f16a6217b8fa76c1..75419cf9d35351b0b2c2a3cb1c3296046d1d7e51 100644 (file)
@@ -727,8 +727,7 @@ raw3215_remove (struct ccw_device *cdev)
        raw = cdev->dev.driver_data;
        if (raw) {
                cdev->dev.driver_data = NULL;
-               if (raw->buffer)
-                       kfree(raw->buffer);
+               kfree(raw->buffer);
                kfree(raw);
        }
 }
index fd43d99b45a3359382e17ebd208f643021352635..5bda2340a39d93a843fd1f090da240f0d1c6af36 100644 (file)
@@ -99,13 +99,11 @@ out_fn_handler:
        kfree(kbd->fn_handler);
 out_func:
        for (i = 0; i < ARRAY_SIZE(func_table); i++)
-               if (kbd->func_table[i])
-                       kfree(kbd->func_table[i]);
+               kfree(kbd->func_table[i]);
        kfree(kbd->func_table);
 out_maps:
        for (i = 0; i < ARRAY_SIZE(key_maps); i++)
-               if (kbd->key_maps[i])
-                       kfree(kbd->key_maps[i]);
+               kfree(kbd->key_maps[i]);
        kfree(kbd->key_maps);
 out_kbd:
        kfree(kbd);
@@ -121,12 +119,10 @@ kbd_free(struct kbd_data *kbd)
        kfree(kbd->accent_table);
        kfree(kbd->fn_handler);
        for (i = 0; i < ARRAY_SIZE(func_table); i++)
-               if (kbd->func_table[i])
-                       kfree(kbd->func_table[i]);
+               kfree(kbd->func_table[i]);
        kfree(kbd->func_table);
        for (i = 0; i < ARRAY_SIZE(key_maps); i++)
-               if (kbd->key_maps[i])
-                       kfree(kbd->key_maps[i]);
+               kfree(kbd->key_maps[i]);
        kfree(kbd->key_maps);
        kfree(kbd);
 }
@@ -452,8 +448,7 @@ do_kdgkb_ioctl(struct kbd_data *kbd, struct kbsentry __user *u_kbs,
                        return -EFAULT;
                }
                p[len] = 0;
-               if (kbd->func_table[kb_func])
-                       kfree(kbd->func_table[kb_func]);
+               kfree(kbd->func_table[kb_func]);
                kbd->func_table[kb_func] = p;
                break;
        }
index d66946443dfc19f3df8186bfa9fdd77fb48d9233..f5b7d360fc10ae5973003ad2cd25031b71976503 100644 (file)
@@ -183,8 +183,7 @@ raw3270_request_alloc_bootmem(size_t size)
 void
 raw3270_request_free (struct raw3270_request *rq)
 {
-       if (rq->buffer)
-               kfree(rq->buffer);
+       kfree(rq->buffer);
        kfree(rq);
 }
 
index 6c52e8307dc54bdf009a853fead4619b38573ac8..8f486e1a85075657fd890c94b3016ab4f99a80f1 100644 (file)
@@ -682,8 +682,7 @@ tape_alloc_request(int cplength, int datasize)
                request->cpdata = kmalloc(datasize, GFP_KERNEL | GFP_DMA);
                if (request->cpdata == NULL) {
                        DBF_EXCEPTION(1, "cqra nomem\n");
-                       if (request->cpaddr != NULL)
-                               kfree(request->cpaddr);
+                       kfree(request->cpaddr);
                        kfree(request);
                        return ERR_PTR(-ENOMEM);
                }
@@ -706,10 +705,8 @@ tape_free_request (struct tape_request * request)
        if (request->device != NULL) {
                request->device = tape_put_device(request->device);
        }
-       if (request->cpdata != NULL)
-               kfree(request->cpdata);
-       if (request->cpaddr != NULL)
-               kfree(request->cpaddr);
+       kfree(request->cpdata);
+       kfree(request->cpaddr);
        kfree(request);
 }
 
index 8990d8076e7da0733d7c8bb0a8b32fa55908af2d..19762f3476aadd22289d4ddb4a44d82985465bf4 100644 (file)
@@ -103,8 +103,10 @@ vmcp_write(struct file *file, const char __user * buff, size_t count,
        }
        cmd[count] = '\0';
        session = (struct vmcp_session *)file->private_data;
-       if (down_interruptible(&session->mutex))
+       if (down_interruptible(&session->mutex)) {
+               kfree(cmd);
                return -ERESTARTSYS;
+       }
        if (!session->response)
                session->response = (char *)__get_free_pages(GFP_KERNEL
                                                | __GFP_REPEAT  | GFP_DMA,
index dbb3eb0e330b00d017ca7b98817d8f2fde5f4932..e7bd7f37f080615e2cfe12929d10e3d8c4062c26 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *  drivers/s390/cio/ccwgroup.c
  *  bus driver for ccwgroup
- *   $Revision: 1.29 $
+ *   $Revision: 1.32 $
  *
  *    Copyright (C) 2002 IBM Deutschland Entwicklung GmbH,
  *                       IBM Corporation
@@ -274,7 +274,7 @@ ccwgroup_set_online(struct ccwgroup_device *gdev)
                goto out;
        }
        gdrv = to_ccwgroupdrv (gdev->dev.driver);
-       if ((ret = gdrv->set_online(gdev)))
+       if ((ret = gdrv->set_online ? gdrv->set_online(gdev) : 0))
                goto out;
 
        gdev->state = CCWGROUP_ONLINE;
@@ -300,7 +300,7 @@ ccwgroup_set_offline(struct ccwgroup_device *gdev)
                goto out;
        }
        gdrv = to_ccwgroupdrv (gdev->dev.driver);
-       if ((ret = gdrv->set_offline(gdev)))
+       if ((ret = gdrv->set_offline ? gdrv->set_offline(gdev) : 0))
                goto out;
 
        gdev->state = CCWGROUP_OFFLINE;
index c05b069c29965e9894c5b87a5c6ce10627470eb9..b978f7fe8327546aca8a195f82183a1e87601af4 100644 (file)
@@ -642,8 +642,7 @@ static void
 free_cmbe (struct ccw_device *cdev)
 {
        spin_lock_irq(cdev->ccwlock);
-       if (cdev->private->cmb)
-               kfree(cdev->private->cmb);
+       kfree(cdev->private->cmb);
        cdev->private->cmb = NULL;
        spin_unlock_irq(cdev->ccwlock);
 
index ad3fe5aeb663a01d3f034cba4db8a879ec65e374..85a3026e6900a37c001d5ba48fa63ef63b27643e 100644 (file)
@@ -550,10 +550,8 @@ ccw_device_stlck(struct ccw_device *cdev)
        /* Clear irb. */
        memset(&cdev->private->irb, 0, sizeof(struct irb));
 out_unlock:
-       if (buf)
-               kfree(buf);
-       if (buf2)
-               kfree(buf2);
+       kfree(buf);
+       kfree(buf2);
        spin_unlock_irqrestore(&sch->lock, flags);
        return ret;
 }
index 381f339e3200a9d98d2031d1d30495c18e713a62..eb39218b925e742b5d93ee2c3ca38279f87c136b 100644 (file)
@@ -56,7 +56,7 @@
 #include "ioasm.h"
 #include "chsc.h"
 
-#define VERSION_QDIO_C "$Revision: 1.101 $"
+#define VERSION_QDIO_C "$Revision: 1.108 $"
 
 /****************** MODULE PARAMETER VARIABLES ********************/
 MODULE_AUTHOR("Utz Bacher <utz.bacher@de.ibm.com>");
@@ -1338,16 +1338,14 @@ qdio_release_irq_memory(struct qdio_irq *irq_ptr)
                if (!irq_ptr->input_qs[i])
                        goto next;
 
-               if (irq_ptr->input_qs[i]->slib)
-                       kfree(irq_ptr->input_qs[i]->slib);
+               kfree(irq_ptr->input_qs[i]->slib);
                kfree(irq_ptr->input_qs[i]);
 
 next:
                if (!irq_ptr->output_qs[i])
                        continue;
 
-               if (irq_ptr->output_qs[i]->slib)
-                       kfree(irq_ptr->output_qs[i]->slib);
+               kfree(irq_ptr->output_qs[i]->slib);
                kfree(irq_ptr->output_qs[i]);
 
        }
@@ -2873,10 +2871,10 @@ qdio_establish(struct qdio_initialize *init_data)
                return result;
        }
        
-       wait_event_interruptible_timeout(cdev->private->wait_q,
+       /* Timeout is cared for already by using ccw_device_start_timeout(). */
+       wait_event_interruptible(cdev->private->wait_q,
                 irq_ptr->state == QDIO_IRQ_STATE_ESTABLISHED ||
-                irq_ptr->state == QDIO_IRQ_STATE_ERR,
-                QDIO_ESTABLISH_TIMEOUT);
+                irq_ptr->state == QDIO_IRQ_STATE_ERR);
 
        if (irq_ptr->state == QDIO_IRQ_STATE_ESTABLISHED)
                result = 0;
@@ -3315,8 +3313,7 @@ qdio_get_qdio_memory(void)
 static void
 qdio_release_qdio_memory(void)
 {
-       if (indicators)
-               kfree(indicators);
+       kfree(indicators);
 }
 
 static void
index 0cb47eca91f3d9d459132ee34574da528c7f0831..04c2ef778ec69bc209bf830ab783a5234a56c108 100644 (file)
@@ -3051,8 +3051,7 @@ destroy_crypto_device(int index)
        if (dev_ptr) {
                disabledFlag = dev_ptr->disabled;
                t = dev_ptr->dev_type;
-               if (dev_ptr->dev_resp_p)
-                       kfree(dev_ptr->dev_resp_p);
+               kfree(dev_ptr->dev_resp_p);
                kfree(dev_ptr);
        } else {
                disabledFlag = 0;
@@ -3080,11 +3079,11 @@ static void
 destroy_z90crypt(void)
 {
        int i;
+
        for (i = 0; i < z90crypt.max_count; i++)
                if (z90crypt.device_p[i])
                        destroy_crypto_device(i);
-       if (z90crypt.hdware_info)
-               kfree((void *)z90crypt.hdware_info);
+       kfree(z90crypt.hdware_info);
        memset((void *)&z90crypt, 0, sizeof(z90crypt));
 }
 
index 3092473991a7f7a934a7e242bd432de79c110b24..1a1c3decea728c0ec0ae48fcc50398e662d1ce41 100644 (file)
@@ -2743,14 +2743,10 @@ probe_error( struct ccwgroup_device *cgdev)
 #endif
         privptr=(struct claw_privbk *)cgdev->dev.driver_data;
        if (privptr!=NULL) {
-               if (privptr->p_env != NULL) {
-                       kfree(privptr->p_env);
-                       privptr->p_env=NULL;
-               }
-               if (privptr->p_mtc_envelope!=NULL) {
-                       kfree(privptr->p_mtc_envelope);
-                       privptr->p_mtc_envelope=NULL;
-               }
+               kfree(privptr->p_env);
+               privptr->p_env=NULL;
+                kfree(privptr->p_mtc_envelope);
+                       privptr->p_mtc_envelope=NULL;
                 kfree(privptr);
                 privptr=NULL;
         }
@@ -4121,22 +4117,14 @@ claw_remove_device(struct ccwgroup_device *cgdev)
        if (cgdev->state == CCWGROUP_ONLINE)
                claw_shutdown_device(cgdev);
        claw_remove_files(&cgdev->dev);
-       if (priv->p_mtc_envelope!=NULL) {
-                kfree(priv->p_mtc_envelope);
-                priv->p_mtc_envelope=NULL;
-        }
-       if (priv->p_env != NULL) {
-               kfree(priv->p_env);
-               priv->p_env=NULL;
-       }
-       if (priv->channel[0].irb != NULL) {
-               kfree(priv->channel[0].irb);
-               priv->channel[0].irb=NULL;
-       }
-       if (priv->channel[1].irb != NULL) {
-               kfree(priv->channel[1].irb);
-               priv->channel[1].irb=NULL;
-       }
+       kfree(priv->p_mtc_envelope);
+       priv->p_mtc_envelope=NULL;
+       kfree(priv->p_env);
+       priv->p_env=NULL;
+       kfree(priv->channel[0].irb);
+       priv->channel[0].irb=NULL;
+       kfree(priv->channel[1].irb);
+       priv->channel[1].irb=NULL;
        kfree(priv);
        cgdev->dev.driver_data=NULL;
        cgdev->cdev[READ]->dev.driver_data = NULL;
index 38f50b7129a24fce668493909b15d385de086db3..24029bd9c7d09e682fb97ab8397c4ff6b5c99b51 100644 (file)
@@ -78,8 +78,7 @@ kfree_fsm(fsm_instance *this)
 {
        if (this) {
                if (this->f) {
-                       if (this->f->jumpmatrix)
-                               kfree(this->f->jumpmatrix);
+                       kfree(this->f->jumpmatrix);
                        kfree(this->f);
                }
                kfree(this);
index e08e74e16124704b1f7b8bede6092a2d1cab376e..df7647c3c100dcc14960b8c9cfd69766439751d0 100644 (file)
@@ -447,14 +447,10 @@ static void
 iucv_exit(void)
 {
        iucv_retrieve_buffer();
-       if (iucv_external_int_buffer) {
-               kfree(iucv_external_int_buffer);
-               iucv_external_int_buffer = NULL;
-       }
-       if (iucv_param_pool) {
-               kfree(iucv_param_pool);
-               iucv_param_pool = NULL;
-       }
+       kfree(iucv_external_int_buffer);
+       iucv_external_int_buffer = NULL;
+       kfree(iucv_param_pool);
+       iucv_param_pool = NULL;
        s390_root_dev_unregister(iucv_root);
        bus_unregister(&iucv_bus);
        printk(KERN_INFO "IUCV lowlevel driver unloaded\n");
index 46f34ba93ac5c76de5a821a38e6d75eb94fafea6..1c8ad2fcad8a59d2d67270de4cde2a5cdc43127d 100644 (file)
@@ -145,8 +145,7 @@ lcs_free_channel(struct lcs_channel *channel)
 
        LCS_DBF_TEXT(2, setup, "ichfree");
        for (cnt = 0; cnt < LCS_NUM_BUFFS; cnt++) {
-               if (channel->iob[cnt].data != NULL)
-                       kfree(channel->iob[cnt].data);
+               kfree(channel->iob[cnt].data);
                channel->iob[cnt].data = NULL;
        }
 }
index f94f1f25eec60a8e57ba9d311a90c47b2df58594..011915d5e243c885eccca9e7e3d1131e08963b29 100644 (file)
@@ -62,8 +62,7 @@ qeth_eddp_free_context(struct qeth_eddp_context *ctx)
        for (i = 0; i < ctx->num_pages; ++i)
                free_page((unsigned long)ctx->pages[i]);
        kfree(ctx->pages);
-       if (ctx->elements != NULL)
-               kfree(ctx->elements);
+       kfree(ctx->elements);
        kfree(ctx);
 }
 
index cab098556b44577f3178c040f0daf02bcf9ab1f0..c218b5c944a6f1d54f2f89df3bc8994fee3c9a23 100644 (file)
@@ -450,8 +450,7 @@ zfcp_cfdc_dev_ioctl(struct file *file, unsigned int command,
                kfree(sg_list);
        }
 
-       if (sense_data != NULL)
-               kfree(sense_data);
+       kfree(sense_data);
 
        return retval;
 }
index b0cc3c2588fdd44074cf6ae873c920489b0a111f..ba56762b05f676e69d803234bdc545bedcd5c04a 100644 (file)
@@ -1125,10 +1125,9 @@ out_deregister:
        misc_deregister(&envctrl_dev);
 out_iounmap:
        iounmap(i2c);
-       for (i = 0; i < ENVCTRL_MAX_CPU * 2; i++) {
-               if (i2c_childlist[i].tables)
-                       kfree(i2c_childlist[i].tables);
-       }
+       for (i = 0; i < ENVCTRL_MAX_CPU * 2; i++)
+               kfree(i2c_childlist[i].tables);
+
        return err;
 }
 
@@ -1141,10 +1140,8 @@ static void __exit envctrl_cleanup(void)
        iounmap(i2c);
        misc_deregister(&envctrl_dev);
 
-       for (i = 0; i < ENVCTRL_MAX_CPU * 2; i++) {
-               if (i2c_childlist[i].tables)
-                       kfree(i2c_childlist[i].tables);
-       }
+       for (i = 0; i < ENVCTRL_MAX_CPU * 2; i++)
+               kfree(i2c_childlist[i].tables);
 }
 
 module_init(envctrl_init);
index d06ee65d668d845676d3886c001578073f038be6..3ff74f472249bb638a30933389b9046e75862633 100644 (file)
@@ -1017,8 +1017,7 @@ static void twa_free_device_extension(TW_Device_Extension *tw_dev)
                                    tw_dev->generic_buffer_virt[0],
                                    tw_dev->generic_buffer_phys[0]);
 
-       if (tw_dev->event_queue[0])
-               kfree(tw_dev->event_queue[0]);
+       kfree(tw_dev->event_queue[0]);
 } /* End twa_free_device_extension() */
 
 /* This function will free a request id */
index cc9ecb35b412a2bc51738215ab9c6de1f0dc8378..cba9655d0f14075af5903b7d0c82ab5b6989f36a 100644 (file)
@@ -606,10 +606,7 @@ static int __init NCR5380_probe_irq(struct Scsi_Host *instance, int possible)
        NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_DATA | ICR_ASSERT_SEL);
 
        while (probe_irq == SCSI_IRQ_NONE && time_before(jiffies, timeout))
-       {
-               set_current_state(TASK_UNINTERRUPTIBLE);
-               schedule_timeout(1);
-       }
+               schedule_timeout_uninterruptible(1);
        
        NCR5380_write(SELECT_ENABLE_REG, 0);
        NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
index ee9067255930f8943505cdd6b694af0932ad349f..723c0cea7c04a4ade79767a22eadc27ed2747c67 100644 (file)
@@ -1164,7 +1164,7 @@ int aac_command_thread(struct aac_dev * dev)
                                                kfree(hw_fib_pool);
                                                hw_fib_pool = NULL;
                                        }
-                               } else if (hw_fib_pool) {
+                               } else {
                                        kfree(hw_fib_pool);
                                        hw_fib_pool = NULL;
                                }
@@ -1247,17 +1247,13 @@ int aac_command_thread(struct aac_dev * dev)
                                hw_fib_p = hw_fib_pool;
                                fib_p = fib_pool;
                                while (hw_fib_p < &hw_fib_pool[num]) {
-                                       if (*hw_fib_p)
-                                               kfree(*hw_fib_p);
-                                       if (*fib_p)
-                                               kfree(*fib_p);
+                                       kfree(*hw_fib_p);
+                                       kfree(*fib_p);
                                        ++fib_p;
                                        ++hw_fib_p;
                                }
-                               if (hw_fib_pool)
-                                       kfree(hw_fib_pool);
-                               if (fib_pool)
-                                       kfree(fib_pool);
+                               kfree(hw_fib_pool);
+                               kfree(fib_pool);
                        }
                        kfree(fib);
                        spin_lock_irqsave(dev->queues->queue[HostNormCmdQueue].lock, flags);
index fc4c73c2a6a9ec81b4759b5fd8691f72759c7857..e9b775d6bec9b54b5827e0d82c41665adc3182a5 100644 (file)
@@ -183,8 +183,7 @@ static int rkt_sync_cmd(struct aac_dev *dev, u32 command,
                /*
                 *      Yield the processor in case we are slow 
                 */
-               set_current_state(TASK_UNINTERRUPTIBLE);
-               schedule_timeout(1);
+               schedule_timeout_uninterruptible(1);
        }
        if (ok != 1) {
                /*
@@ -452,8 +451,7 @@ int aac_rkt_init(struct aac_dev *dev)
                                        dev->name, instance, status);
                        goto error_iounmap;
                }
-               set_current_state(TASK_UNINTERRUPTIBLE);
-               schedule_timeout(1);
+               schedule_timeout_uninterruptible(1);
        }
        if (request_irq(dev->scsi_host_ptr->irq, aac_rkt_intr, SA_SHIRQ|SA_INTERRUPT, "aacraid", (void *)dev)<0) 
        {
index da99046e539342e7047ba2d82247086cc3ed9a82..6998bc877dd685726b0c20c1c467ed57d1fe677a 100644 (file)
@@ -183,8 +183,7 @@ static int rx_sync_cmd(struct aac_dev *dev, u32 command,
                /*
                 *      Yield the processor in case we are slow 
                 */
-               set_current_state(TASK_UNINTERRUPTIBLE);
-               schedule_timeout(1);
+               schedule_timeout_uninterruptible(1);
        }
        if (ok != 1) {
                /*
@@ -452,8 +451,7 @@ int aac_rx_init(struct aac_dev *dev)
                                        dev->name, instance, status);
                        goto error_iounmap;
                }
-               set_current_state(TASK_UNINTERRUPTIBLE);
-               schedule_timeout(1);
+               schedule_timeout_uninterruptible(1);
        }
        if (request_irq(dev->scsi_host_ptr->irq, aac_rx_intr, SA_SHIRQ|SA_INTERRUPT, "aacraid", (void *)dev)<0) 
        {
index 8b9596209164904d63b4bf8f197a5ed9f488ed4e..466f05cfbf0ce280596ec955f2e1ec7605ba227f 100644 (file)
@@ -189,8 +189,7 @@ static int sa_sync_cmd(struct aac_dev *dev, u32 command,
                        ok = 1;
                        break;
                }
-               set_current_state(TASK_UNINTERRUPTIBLE);
-               schedule_timeout(1);
+               schedule_timeout_uninterruptible(1);
        }
 
        if (ok != 1)
@@ -325,8 +324,7 @@ int aac_sa_init(struct aac_dev *dev)
                                        name, instance, status);
                        goto error_iounmap;
                }
-               set_current_state(TASK_UNINTERRUPTIBLE);
-               schedule_timeout(1);
+               schedule_timeout_uninterruptible(1);
        }
 
        if (request_irq(dev->scsi_host_ptr->irq, aac_sa_intr, SA_SHIRQ|SA_INTERRUPT, "aacraid", (void *)dev ) < 0) {
index 37ec5411e325578ff572429e4868efa44884789d..f4cfb8f29620f53ba091487c7ac635134299e83e 100644 (file)
@@ -5402,10 +5402,8 @@ advansys_detect(struct scsi_host_template *tpnt)
                 release_region(shp->io_port, boardp->asc_n_io_port);
                 if (ASC_WIDE_BOARD(boardp)) {
                     iounmap(boardp->ioremap_addr);
-                    if (boardp->orig_carrp) {
-                        kfree(boardp->orig_carrp);
-                        boardp->orig_carrp = NULL;
-                    }
+                    kfree(boardp->orig_carrp);
+                    boardp->orig_carrp = NULL;
                     if (boardp->orig_reqp) {
                         kfree(boardp->orig_reqp);
                         boardp->orig_reqp = boardp->adv_reqp = NULL;
@@ -5457,10 +5455,8 @@ advansys_release(struct Scsi_Host *shp)
         adv_sgblk_t    *sgp = NULL;
 
         iounmap(boardp->ioremap_addr);
-        if (boardp->orig_carrp) {
-            kfree(boardp->orig_carrp);
-            boardp->orig_carrp = NULL;
-        }
+        kfree(boardp->orig_carrp);
+        boardp->orig_carrp = NULL;
         if (boardp->orig_reqp) {
             kfree(boardp->orig_reqp);
             boardp->orig_reqp = boardp->adv_reqp = NULL;
index adda750412f29a25ad0d870995062c10b7d54606..1b1adfb384cb9adaec27941fea08067d7582d2e5 100644 (file)
@@ -543,10 +543,8 @@ static void aha1542_intr_handle(struct Scsi_Host *shost, void *dev_id, struct pt
                        return;
                }
                my_done = SCtmp->scsi_done;
-               if (SCtmp->host_scribble) {
-                       kfree(SCtmp->host_scribble);
-                       SCtmp->host_scribble = NULL;
-               }
+               kfree(SCtmp->host_scribble);
+               SCtmp->host_scribble = NULL;
                /* Fetch the sense data, and tuck it away, in the required slot.  The
                   Adaptec automatically fetches it, and there is no guarantee that
                   we will still have it in the cdb when we come back */
@@ -1432,10 +1430,8 @@ static int aha1542_dev_reset(Scsi_Cmnd * SCpnt)
                    HOSTDATA(SCpnt->host)->SCint[i]->target == SCpnt->target) {
                        Scsi_Cmnd *SCtmp;
                        SCtmp = HOSTDATA(SCpnt->host)->SCint[i];
-                       if (SCtmp->host_scribble) {
-                               kfree(SCtmp->host_scribble);
-                               SCtmp->host_scribble = NULL;
-                       }
+                       kfree(SCtmp->host_scribble);
+                       SCtmp->host_scribble = NULL;
                        HOSTDATA(SCpnt->host)->SCint[i] = NULL;
                        HOSTDATA(SCpnt->host)->mb[i].status = 0;
                }
@@ -1495,10 +1491,8 @@ static int aha1542_bus_reset(Scsi_Cmnd * SCpnt)
                                 */
                                continue;
                        }
-                       if (SCtmp->host_scribble) {
-                               kfree(SCtmp->host_scribble);
-                               SCtmp->host_scribble = NULL;
-                       }
+                       kfree(SCtmp->host_scribble);
+                       SCtmp->host_scribble = NULL;
                        HOSTDATA(SCpnt->device->host)->SCint[i] = NULL;
                        HOSTDATA(SCpnt->device->host)->mb[i].status = 0;
                }
@@ -1565,10 +1559,8 @@ static int aha1542_host_reset(Scsi_Cmnd * SCpnt)
                                 */
                                continue;
                        }
-                       if (SCtmp->host_scribble) {
-                               kfree(SCtmp->host_scribble);
-                               SCtmp->host_scribble = NULL;
-                       }
+                       kfree(SCtmp->host_scribble);
+                       SCtmp->host_scribble = NULL;
                        HOSTDATA(SCpnt->device->host)->SCint[i] = NULL;
                        HOSTDATA(SCpnt->device->host)->mb[i].status = 0;
                }
@@ -1711,10 +1703,8 @@ static int aha1542_old_reset(Scsi_Cmnd * SCpnt, unsigned int reset_flags)
                                Scsi_Cmnd *SCtmp;
                                SCtmp = HOSTDATA(SCpnt->host)->SCint[i];
                                SCtmp->result = DID_RESET << 16;
-                               if (SCtmp->host_scribble) {
-                                       kfree(SCtmp->host_scribble);
-                                       SCtmp->host_scribble = NULL;
-                               }
+                               kfree(SCtmp->host_scribble);
+                               SCtmp->host_scribble = NULL;
                                printk(KERN_WARNING "Sending DID_RESET for target %d\n", SCpnt->target);
                                SCtmp->scsi_done(SCpnt);
 
@@ -1757,10 +1747,8 @@ fail:
                                                Scsi_Cmnd *SCtmp;
                                                SCtmp = HOSTDATA(SCpnt->host)->SCint[i];
                                                SCtmp->result = DID_RESET << 16;
-                                               if (SCtmp->host_scribble) {
-                                                       kfree(SCtmp->host_scribble);
-                                                       SCtmp->host_scribble = NULL;
-                                               }
+                                               kfree(SCtmp->host_scribble);
+                                               SCtmp->host_scribble = NULL;
                                                printk(KERN_WARNING "Sending DID_RESET for target %d\n", SCpnt->target);
                                                SCtmp->scsi_done(SCpnt);
 
index 52b72d7794f51aeadc11df93a1a53aed02f1b478..880e2d9ffe9bde841fec29501f7cdd28c0e4bd56 100644 (file)
@@ -8492,8 +8492,7 @@ aic7xxx_free(struct aic7xxx_host *p)
                                      - scb_dma->dma_offset),
                            scb_dma->dma_address);
       }
-      if (p->scb_data->scb_array[i]->kmalloc_ptr != NULL)
-        kfree(p->scb_data->scb_array[i]->kmalloc_ptr);
+      kfree(p->scb_data->scb_array[i]->kmalloc_ptr);
       p->scb_data->scb_array[i] = NULL;
     }
   
index e6d159270d294836ad6eb91436ae1785fe3b890c..b10750bb5c09b428687419376507190f125afec4 100644 (file)
@@ -91,8 +91,7 @@ void queue_free (Queue_t *queue)
 {
        if (!list_empty(&queue->head))
                printk(KERN_WARNING "freeing non-empty queue %p\n", queue);
-       if (queue->alloc)
-               kfree(queue->alloc);
+       kfree(queue->alloc);
 }
      
 
index 7026045527fd41a01309b9bf60489a3e2830553d..8d5d2a5da961e195dc2882e6523c8ed670f363e6 100644 (file)
@@ -19,6 +19,8 @@
  * this code.
  */
 
+#include <linux/compiler.h>
+#include <asm/thread_info.h>
 #include <asm/uaccess.h>
 
 #define hades_dma_ctrl         (*(unsigned char *) 0xffff8717)
index c44af5795b10a547f0c7e915a7aed4de90e7cc0b..c8a32cf47d738fba4e991d1c2f37e09c6a5b08c2 100644 (file)
@@ -4270,8 +4270,7 @@ static void adapter_sg_tables_free(struct AdapterCtlBlk *acb)
        const unsigned srbs_per_page = PAGE_SIZE/SEGMENTX_LEN;
 
        for (i = 0; i < DC395x_MAX_SRB_CNT; i += srbs_per_page)
-               if (acb->srb_array[i].segment_x)
-                       kfree(acb->srb_array[i].segment_x);
+               kfree(acb->srb_array[i].segment_x);
 }
 
 
index 7235f94f1191ef06ce816e0539527c0cd11f256d..c28e3aea1c3cef83f28e3b3bccb00dac2e8ada27 100644 (file)
@@ -1037,18 +1037,10 @@ static void adpt_i2o_delete_hba(adpt_hba* pHba)
        if(pHba->msg_addr_virt != pHba->base_addr_virt){
                iounmap(pHba->msg_addr_virt);
        }
-       if(pHba->hrt) {
-               kfree(pHba->hrt);
-       }
-       if(pHba->lct){
-               kfree(pHba->lct);
-       }
-       if(pHba->status_block) {
-               kfree(pHba->status_block);
-       }
-       if(pHba->reply_pool){
-               kfree(pHba->reply_pool);
-       }
+       kfree(pHba->hrt);
+       kfree(pHba->lct);
+       kfree(pHba->status_block);
+       kfree(pHba->reply_pool);
 
        for(d = pHba->devices; d ; d = next){
                next = d->next;
@@ -1218,8 +1210,7 @@ static s32 adpt_i2o_post_this(adpt_hba* pHba, u32* data, int len)
                        printk(KERN_WARNING"dpti%d: Timeout waiting for message frame!\n", pHba->unit);
                        return -ETIMEDOUT;
                }
-               set_current_state(TASK_UNINTERRUPTIBLE);
-               schedule_timeout(1);
+               schedule_timeout_uninterruptible(1);
        } while(m == EMPTY_QUEUE);
                
        msg = pHba->msg_addr_virt + m;
@@ -1294,8 +1285,7 @@ static s32 adpt_i2o_reset_hba(adpt_hba* pHba)
                        printk(KERN_WARNING"Timeout waiting for message!\n");
                        return -ETIMEDOUT;
                }
-               set_current_state(TASK_UNINTERRUPTIBLE);
-               schedule_timeout(1);
+               schedule_timeout_uninterruptible(1);
        } while (m == EMPTY_QUEUE);
 
        status = (u8*)kmalloc(4, GFP_KERNEL|ADDR32);
@@ -1327,8 +1317,7 @@ static s32 adpt_i2o_reset_hba(adpt_hba* pHba)
                        return -ETIMEDOUT;
                }
                rmb();
-               set_current_state(TASK_UNINTERRUPTIBLE);
-               schedule_timeout(1);
+               schedule_timeout_uninterruptible(1);
        }
 
        if(*status == 0x01 /*I2O_EXEC_IOP_RESET_IN_PROGRESS*/) {
@@ -1345,8 +1334,7 @@ static s32 adpt_i2o_reset_hba(adpt_hba* pHba)
                                printk(KERN_ERR "%s:Timeout waiting for IOP Reset.\n",pHba->name);
                                return -ETIMEDOUT;
                        }
-                       set_current_state(TASK_UNINTERRUPTIBLE);
-                       schedule_timeout(1);
+                       schedule_timeout_uninterruptible(1);
                } while (m == EMPTY_QUEUE);
                // Flush the offset
                adpt_send_nop(pHba, m);
@@ -1917,11 +1905,8 @@ static int adpt_ioctl(struct inode *inode, struct file *file, uint cmd,
                return -ENXIO;
        }
 
-       while((volatile u32) pHba->state & DPTI_STATE_RESET ) {
-               set_task_state(current,TASK_UNINTERRUPTIBLE);
-               schedule_timeout(2);
-
-       }
+       while((volatile u32) pHba->state & DPTI_STATE_RESET )
+               schedule_timeout_uninterruptible(2);
 
        switch (cmd) {
        // TODO: handle 3 cases
@@ -2635,8 +2620,7 @@ static s32 adpt_send_nop(adpt_hba*pHba,u32 m)
                        printk(KERN_ERR "%s: Timeout waiting for message frame!\n",pHba->name);
                        return 2;
                }
-               set_current_state(TASK_UNINTERRUPTIBLE);
-               schedule_timeout(1);
+               schedule_timeout_uninterruptible(1);
        }
        msg = (u32 __iomem *)(pHba->msg_addr_virt + m);
        writel( THREE_WORD_MSG_SIZE | SGL_OFFSET_0,&msg[0]);
@@ -2670,8 +2654,7 @@ static s32 adpt_i2o_init_outbound_q(adpt_hba* pHba)
                        printk(KERN_WARNING"%s: Timeout waiting for message frame\n",pHba->name);
                        return -ETIMEDOUT;
                }
-               set_current_state(TASK_UNINTERRUPTIBLE);
-               schedule_timeout(1);
+               schedule_timeout_uninterruptible(1);
        } while(m == EMPTY_QUEUE);
 
        msg=(u32 __iomem *)(pHba->msg_addr_virt+m);
@@ -2709,21 +2692,18 @@ static s32 adpt_i2o_init_outbound_q(adpt_hba* pHba)
                        printk(KERN_WARNING"%s: Timeout Initializing\n",pHba->name);
                        return -ETIMEDOUT;
                }
-               set_current_state(TASK_UNINTERRUPTIBLE);
-               schedule_timeout(1);
+               schedule_timeout_uninterruptible(1);
        } while (1);
 
        // If the command was successful, fill the fifo with our reply
        // message packets
        if(*status != 0x04 /*I2O_EXEC_OUTBOUND_INIT_COMPLETE*/) {
-               kfree((void*)status);
+               kfree(status);
                return -2;
        }
-       kfree((void*)status);
+       kfree(status);
 
-       if(pHba->reply_pool != NULL){
-               kfree(pHba->reply_pool);
-       }
+       kfree(pHba->reply_pool);
 
        pHba->reply_pool = (u32*)kmalloc(pHba->reply_fifo_size * REPLY_FRAME_SIZE * 4, GFP_KERNEL|ADDR32);
        if(!pHba->reply_pool){
@@ -2788,8 +2768,7 @@ static s32 adpt_i2o_status_get(adpt_hba* pHba)
                                        pHba->name);
                        return -ETIMEDOUT;
                }
-               set_current_state(TASK_UNINTERRUPTIBLE);
-               schedule_timeout(1);
+               schedule_timeout_uninterruptible(1);
        } while(m==EMPTY_QUEUE);
 
        
@@ -2816,8 +2795,7 @@ static s32 adpt_i2o_status_get(adpt_hba* pHba)
                        return -ETIMEDOUT;
                }
                rmb();
-               set_current_state(TASK_UNINTERRUPTIBLE);
-               schedule_timeout(1);
+               schedule_timeout_uninterruptible(1);
        }
 
        // Set up our number of outbound and inbound messages
@@ -2941,8 +2919,7 @@ static int adpt_i2o_build_sys_table(void)
        sys_tbl_len = sizeof(struct i2o_sys_tbl) +      // Header + IOPs
                                (hba_count) * sizeof(struct i2o_sys_tbl_entry);
 
-       if(sys_tbl)
-               kfree(sys_tbl);
+       kfree(sys_tbl);
 
        sys_tbl = kmalloc(sys_tbl_len, GFP_KERNEL|ADDR32);
        if(!sys_tbl) {
index b45a4c7302305d5b78e19494f431604362c893e0..b3f9de8f75955f69d7bfa9f0a69c0d22cd8432da 100644 (file)
@@ -2580,8 +2580,7 @@ static int eata2x_release(struct Scsi_Host *shost)
        unsigned int i;
 
        for (i = 0; i < shost->can_queue; i++)
-               if ((&ha->cp[i])->sglist)
-                       kfree((&ha->cp[i])->sglist);
+               kfree((&ha->cp[i])->sglist);
 
        for (i = 0; i < shost->can_queue; i++)
                pci_unmap_single(ha->pdev, ha->cp[i].cp_dma_addr,
index f04f3289938d1c6f3ee30ac9faaff26b70f125c9..c888af4a45629cf8fa138dabcc99646f8199723d 100644 (file)
@@ -331,9 +331,9 @@ static int idescsi_check_condition(ide_drive_t *drive, struct request *failed_co
        rq = kmalloc (sizeof (struct request), GFP_ATOMIC);
        buf = kmalloc(SCSI_SENSE_BUFFERSIZE, GFP_ATOMIC);
        if (pc == NULL || rq == NULL || buf == NULL) {
-               if (pc) kfree(pc);
-               if (rq) kfree(rq);
-               if (buf) kfree(buf);
+               kfree(buf);
+               kfree(rq);
+               kfree(pc);
                return -ENOMEM;
        }
        memset (pc, 0, sizeof (idescsi_pc_t));
@@ -949,8 +949,8 @@ static int idescsi_queue (struct scsi_cmnd *cmd,
        spin_lock_irq(host->host_lock);
        return 0;
 abort:
-       if (pc) kfree (pc);
-       if (rq) kfree (rq);
+       kfree (pc);
+       kfree (rq);
        cmd->result = DID_ERROR << 16;
        done(cmd);
        return 0;
index 68e5b2ab27c4ac346d02ae4eb3926aa3212bf589..cd9b95db5a7d419ba29f82d6fd8aa45233d2b146 100644 (file)
@@ -4517,10 +4517,8 @@ ips_free(ips_ha_t * ha)
                        ha->enq = NULL;
                }
 
-               if (ha->conf) {
-                       kfree(ha->conf);
-                       ha->conf = NULL;
-               }
+               kfree(ha->conf);
+               ha->conf = NULL;
 
                if (ha->adapt) {
                        pci_free_consistent(ha->pcidev,
@@ -4538,15 +4536,11 @@ ips_free(ips_ha_t * ha)
                        ha->logical_drive_info = NULL;
                }
 
-               if (ha->nvram) {
-                       kfree(ha->nvram);
-                       ha->nvram = NULL;
-               }
+               kfree(ha->nvram);
+               ha->nvram = NULL;
 
-               if (ha->subsys) {
-                       kfree(ha->subsys);
-                       ha->subsys = NULL;
-               }
+               kfree(ha->subsys);
+               ha->subsys = NULL;
 
                if (ha->ioctl_data) {
                        pci_free_consistent(ha->pcidev, ha->ioctl_len,
index 08a0c00cfc302eee9f97a8f9668910672d39d08a..bcc29ec126dc1a29761885fe31193f75c1ad29d9 100644 (file)
@@ -127,8 +127,7 @@ lpfc_prep_els_iocb(struct lpfc_hba * phba,
        if (((pcmd = kmalloc(sizeof (struct lpfc_dmabuf), GFP_KERNEL)) == 0) ||
            ((pcmd->virt = lpfc_mbuf_alloc(phba,
                                           MEM_PRI, &(pcmd->phys))) == 0)) {
-               if (pcmd)
-                       kfree(pcmd);
+               kfree(pcmd);
 
                spin_lock_irq(phba->host->host_lock);
                lpfc_sli_release_iocbq(phba, elsiocb);
@@ -145,8 +144,7 @@ lpfc_prep_els_iocb(struct lpfc_hba * phba,
                        prsp->virt = lpfc_mbuf_alloc(phba, MEM_PRI,
                                                     &prsp->phys);
                if (prsp == 0 || prsp->virt == 0) {
-                       if (prsp)
-                               kfree(prsp);
+                       kfree(prsp);
                        lpfc_mbuf_free(phba, pcmd->virt, pcmd->phys);
                        kfree(pcmd);
                        spin_lock_irq(phba->host->host_lock);
@@ -172,8 +170,7 @@ lpfc_prep_els_iocb(struct lpfc_hba * phba,
                lpfc_mbuf_free(phba, prsp->virt, prsp->phys);
                kfree(pcmd);
                kfree(prsp);
-               if (pbuflist)
-                       kfree(pbuflist);
+               kfree(pbuflist);
                return NULL;
        }
 
index 4e04470321a27352391d78708d21133be8d48515..c90723860a049e15232452b60921909645c81bde 100644 (file)
@@ -894,8 +894,7 @@ lpfc_post_buffer(struct lpfc_hba * phba, struct lpfc_sli_ring * pring, int cnt,
                    mp1->virt = lpfc_mbuf_alloc(phba, MEM_PRI,
                                                &mp1->phys);
                if (mp1 == 0 || mp1->virt == 0) {
-                       if (mp1)
-                               kfree(mp1);
+                       kfree(mp1);
                        spin_lock_irq(phba->host->host_lock);
                        lpfc_sli_release_iocbq(phba, iocb);
                        spin_unlock_irq(phba->host->host_lock);
@@ -911,8 +910,7 @@ lpfc_post_buffer(struct lpfc_hba * phba, struct lpfc_sli_ring * pring, int cnt,
                                mp2->virt = lpfc_mbuf_alloc(phba, MEM_PRI,
                                                            &mp2->phys);
                        if (mp2 == 0 || mp2->virt == 0) {
-                               if (mp2)
-                                       kfree(mp2);
+                               kfree(mp2);
                                lpfc_mbuf_free(phba, mp1->virt, mp1->phys);
                                kfree(mp1);
                                spin_lock_irq(phba->host->host_lock);
index 31c20cc00609cda49a41ec52c144c548fb87b6f7..e3bc8d3f7302fa7bd9326ea34d39d60b6a2c1dfe 100644 (file)
@@ -248,8 +248,7 @@ lpfc_read_sparam(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
 
        if (((mp = kmalloc(sizeof (struct lpfc_dmabuf), GFP_KERNEL)) == 0) ||
            ((mp->virt = lpfc_mbuf_alloc(phba, 0, &(mp->phys))) == 0)) {
-               if (mp)
-                       kfree(mp);
+               kfree(mp);
                mb->mbxCommand = MBX_READ_SPARM64;
                /* READ_SPARAM: no buffers */
                lpfc_printf_log(phba,
@@ -363,9 +362,7 @@ lpfc_reg_login(struct lpfc_hba * phba,
        /* Get a buffer to hold NPorts Service Parameters */
        if (((mp = kmalloc(sizeof (struct lpfc_dmabuf), GFP_KERNEL)) == NULL) ||
            ((mp->virt = lpfc_mbuf_alloc(phba, 0, &(mp->phys))) == 0)) {
-               if (mp)
-                       kfree(mp);
-
+               kfree(mp);
                mb->mbxCommand = MBX_REG_LOGIN64;
                /* REG_LOGIN: no buffers */
                lpfc_printf_log(phba,
index c34d3cf4f19c09b0ba945f07e80e1eaa51310e0b..c63275e66e2e6644c1e187904b4838476eda8e37 100644 (file)
@@ -825,8 +825,7 @@ __lpfc_abort_handler(struct scsi_cmnd *cmnd)
        while (lpfc_cmd->pCmd == cmnd)
        {
                spin_unlock_irq(phba->host->host_lock);
-               set_current_state(TASK_UNINTERRUPTIBLE);
-               schedule_timeout(LPFC_ABORT_WAIT*HZ);
+                       schedule_timeout_uninterruptible(LPFC_ABORT_WAIT*HZ);
                spin_lock_irq(phba->host->host_lock);
                if (++loop_count
                    > (2 * phba->cfg_nodev_tmo)/LPFC_ABORT_WAIT)
@@ -885,8 +884,7 @@ __lpfc_reset_lun_handler(struct scsi_cmnd *cmnd)
 
                if (pnode->nlp_state != NLP_STE_MAPPED_NODE) {
                        spin_unlock_irq(phba->host->host_lock);
-                       set_current_state(TASK_UNINTERRUPTIBLE);
-                       schedule_timeout( HZ/2);
+                       schedule_timeout_uninterruptible(msecs_to_jiffies(500));
                        spin_lock_irq(phba->host->host_lock);
                }
                if ((pnode) && (pnode->nlp_state == NLP_STE_MAPPED_NODE))
@@ -939,8 +937,7 @@ __lpfc_reset_lun_handler(struct scsi_cmnd *cmnd)
                                       cmnd->device->id, cmnd->device->lun,
                                       LPFC_CTX_LUN))) {
                spin_unlock_irq(phba->host->host_lock);
-               set_current_state(TASK_UNINTERRUPTIBLE);
-               schedule_timeout(LPFC_RESET_WAIT*HZ);
+               schedule_timeout_uninterruptible(LPFC_RESET_WAIT*HZ);
                spin_lock_irq(phba->host->host_lock);
 
                if (++loopcnt
@@ -1038,8 +1035,7 @@ __lpfc_reset_bus_handler(struct scsi_cmnd *cmnd)
                                &phba->sli.ring[phba->sli.fcp_ring],
                                0, 0, LPFC_CTX_HOST))) {
                spin_unlock_irq(phba->host->host_lock);
-               set_current_state(TASK_UNINTERRUPTIBLE);
-               schedule_timeout(LPFC_RESET_WAIT*HZ);
+               schedule_timeout_uninterruptible(LPFC_RESET_WAIT*HZ);
                spin_lock_irq(phba->host->host_lock);
 
                if (++loopcnt
index 508710001ed61a9de13bdc37f3a34f4b0b885b54..e2c08c5d83fb3d75b605d2596152951baa6114e0 100644 (file)
@@ -2269,11 +2269,8 @@ lpfc_sli_hba_down(struct lpfc_hba * phba)
 
                INIT_LIST_HEAD(&(pring->txq));
 
-               if (pring->fast_lookup) {
-                       kfree(pring->fast_lookup);
-                       pring->fast_lookup = NULL;
-               }
-
+               kfree(pring->fast_lookup);
+               pring->fast_lookup = NULL;
        }
 
        spin_unlock_irqrestore(phba->host->host_lock, flags);
index c9e743ba09ec108d23129ae9d06d90092299aa8e..1a3d195a2d366d3994a39bc525bf5a0e5b69fe20 100644 (file)
@@ -3937,9 +3937,8 @@ megaraid_sysfs_free_resources(adapter_t *adapter)
 {
        mraid_device_t  *raid_dev = ADAP2RAIDDEV(adapter);
 
-       if (raid_dev->sysfs_uioc) kfree(raid_dev->sysfs_uioc);
-
-       if (raid_dev->sysfs_mbox64) kfree(raid_dev->sysfs_mbox64);
+       kfree(raid_dev->sysfs_uioc);
+       kfree(raid_dev->sysfs_mbox64);
 
        if (raid_dev->sysfs_buffer) {
                pci_free_consistent(adapter->pdev, PAGE_SIZE,
index 37d110e864c49c9c524e8347118e42050cdd3e49..8f3ce0432295b38424903a339cfb39bb1dee39d8 100644 (file)
@@ -995,17 +995,13 @@ pthru_dma_pool_error:
 
 memalloc_error:
 
-       if (adapter->kioc_list)
-               kfree(adapter->kioc_list);
-
-       if (adapter->mbox_list)
-               kfree(adapter->mbox_list);
+       kfree(adapter->kioc_list);
+       kfree(adapter->mbox_list);
 
        if (adapter->pthru_dma_pool)
                pci_pool_destroy(adapter->pthru_dma_pool);
 
-       if (adapter)
-               kfree(adapter);
+       kfree(adapter);
 
        return rval;
 }
@@ -1157,7 +1153,6 @@ mraid_mm_free_adp_resources(mraid_mmadp_t *adp)
        }
 
        kfree(adp->kioc_list);
-
        kfree(adp->mbox_list);
 
        pci_pool_destroy(adp->pthru_dma_pool);
index 1cf11c3322fbd0b4d1c3fe7a2ea1adf3e02d835f..d9946bd95492e68ae43d9df891d497c86592d58d 100644 (file)
@@ -862,8 +862,7 @@ static int osst_recover_wait_frame(struct osst_tape * STp, struct scsi_request *
                                retval = osst_write_error_recovery(STp, aSRpnt, 0);
                                break;
                        }
-                       set_current_state(TASK_INTERRUPTIBLE);
-                       schedule_timeout (HZ / OSST_POLL_PER_SEC);
+                       schedule_timeout_interruptible(HZ / OSST_POLL_PER_SEC);
 
                        STp->buffer->b_data = mybuf; STp->buffer->buffer_size = 24;
                        memset(cmd, 0, MAX_COMMAND_SIZE);
@@ -1558,8 +1557,7 @@ static int osst_reposition_and_retry(struct osst_tape * STp, struct scsi_request
                        osst_set_frame_position(STp, aSRpnt, frame + skip, 1);
                        flag = 0;
                        attempts--;
-                       set_current_state(TASK_INTERRUPTIBLE);
-                       schedule_timeout(HZ / 10);
+                       schedule_timeout_interruptible(msecs_to_jiffies(100));
                }
                if (osst_get_frame_position(STp, aSRpnt) < 0) {         /* additional write error */
 #if DEBUG
@@ -1620,8 +1618,7 @@ static int osst_reposition_and_retry(struct osst_tape * STp, struct scsi_request
                        debugging = 0;
                }
 #endif
-               set_current_state(TASK_INTERRUPTIBLE);
-               schedule_timeout(HZ / 10);
+               schedule_timeout_interruptible(msecs_to_jiffies(100));
        }
        printk(KERN_ERR "%s:E: Failed to find valid tape media\n", name);
 #if DEBUG
index 290a6b92616ca9c83e6fa3b23abed5ce476671ca..72d9090df3dff8e8863204183b938c854392ce38 100644 (file)
@@ -1977,8 +1977,7 @@ qla2x00_configure_local_loop(scsi_qla_host_t *ha)
        }
 
 cleanup_allocation:
-       if (new_fcport)
-               kfree(new_fcport);
+       kfree(new_fcport);
 
        if (rval != QLA_SUCCESS) {
                DEBUG2(printk("scsi(%ld): Configure local loop error exit: "
@@ -2348,8 +2347,7 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *ha, struct list_head *new_fcports)
        /* Allocate temporary fcport for any new fcports discovered. */
        new_fcport = qla2x00_alloc_fcport(ha, GFP_KERNEL);
        if (new_fcport == NULL) {
-               if (swl)
-                       kfree(swl);
+               kfree(swl);
                return (QLA_MEMORY_ALLOC_FAILED);
        }
        new_fcport->flags |= (FCF_FABRIC_DEVICE | FCF_LOGIN_NEEDED);
@@ -2485,19 +2483,15 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *ha, struct list_head *new_fcports)
                nxt_d_id.b24 = new_fcport->d_id.b24;
                new_fcport = qla2x00_alloc_fcport(ha, GFP_KERNEL);
                if (new_fcport == NULL) {
-                       if (swl)
-                               kfree(swl);
+                       kfree(swl);
                        return (QLA_MEMORY_ALLOC_FAILED);
                }
                new_fcport->flags |= (FCF_FABRIC_DEVICE | FCF_LOGIN_NEEDED);
                new_fcport->d_id.b24 = nxt_d_id.b24;
        }
 
-       if (swl)
-               kfree(swl);
-
-       if (new_fcport)
-               kfree(new_fcport);
+       kfree(swl);
+       kfree(new_fcport);
 
        if (!list_empty(new_fcports))
                ha->device_flags |= DFLG_FABRIC_DEVICES;
index f1ea5027865f5851310769b08e0f5b53df163f71..caa0c3629626c3a6102d28df8164521964a228ca 100644 (file)
@@ -4,6 +4,8 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/list.h>
+#include <linux/slab.h>
+#include <linux/string.h>
 #include <linux/raid_class.h>
 #include <scsi/scsi_device.h>
 #include <scsi/scsi_host.h>
index 0cc766a9aa6585a5ffef2292b355478cd31b4235..edabbd05d258882050661058b8bb32da15e69672 100644 (file)
@@ -26,6 +26,8 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/string.h>
 
 #include <scsi/scsi_device.h>
 #include <scsi/scsi_host.h>
index 4f30a37db63c90c26e111036aaf70d51af916507..62e3f340cc5200c38e630ff04151852fbf1c1a32 100644 (file)
@@ -476,8 +476,7 @@ sg_read(struct file *filp, char __user *buf, size_t count, loff_t * ppos)
        sg_finish_rem_req(srp);
        retval = count;
 free_old_hdr:
-       if (old_hdr)
-               kfree(old_hdr);
+       kfree(old_hdr);
        return retval;
 }
 
@@ -1703,10 +1702,8 @@ exit_sg(void)
        sg_sysfs_valid = 0;
        unregister_chrdev_region(MKDEV(SCSI_GENERIC_MAJOR, 0),
                                 SG_MAX_DEVS);
-       if (sg_dev_arr != NULL) {
-               kfree((char *) sg_dev_arr);
-               sg_dev_arr = NULL;
-       }
+       kfree((char *)sg_dev_arr);
+       sg_dev_arr = NULL;
        sg_dev_max = 0;
 }
 
index 6b85f84c839756680e8373ad45532ad946f8fce8..770c4324f3d5750e51eae824fd59a985209b9732 100644 (file)
@@ -4107,8 +4107,7 @@ out_free_tape:
        write_unlock(&st_dev_arr_lock);
 out_put_disk:
        put_disk(disk);
-       if (tpnt)
-               kfree(tpnt);
+       kfree(tpnt);
 out_buffer_free:
        kfree(buffer);
 out:
index a1a58e1d5ad327330b96603c18afd511bbf9dd40..a7420cad4547d068951fe768408f6f6a150db102 100644 (file)
@@ -39,6 +39,7 @@
  */
 
 #include <linux/slab.h>
+#include <asm/param.h>         /* for timeouts in units of HZ */
 
 #include "sym_glue.h"
 #include "sym_nvram.h"
index cfab8f197084f167ed2dc5d2610e783583c40be3..1ce29ba683eb72a8953adb95cd9fa0e2d660d83c 100644 (file)
@@ -1953,11 +1953,11 @@ static int u14_34f_release(struct Scsi_Host *shpnt) {
 
    for (j = 0; sh[j] != NULL && sh[j] != shpnt; j++);
 
-   if (sh[j] == NULL) panic("%s: release, invalid Scsi_Host pointer.\n",
-                            driver_name);
+   if (sh[j] == NULL)
+      panic("%s: release, invalid Scsi_Host pointer.\n", driver_name);
 
    for (i = 0; i < sh[j]->can_queue; i++)
-      if ((&HD(j)->cp[i])->sglist) kfree((&HD(j)->cp[i])->sglist);
+      kfree((&HD(j)->cp[i])->sglist);
 
    for (i = 0; i < sh[j]->can_queue; i++)
       pci_unmap_single(HD(j)->pdev, HD(j)->cp[i].cp_dma_addr,
@@ -1965,7 +1965,8 @@ static int u14_34f_release(struct Scsi_Host *shpnt) {
 
    free_irq(sh[j]->irq, &sha[j]);
 
-   if (sh[j]->dma_channel != NO_DMA) free_dma(sh[j]->dma_channel);
+   if (sh[j]->dma_channel != NO_DMA)
+      free_dma(sh[j]->dma_channel);
 
    release_region(sh[j]->io_port, sh[j]->n_io_port);
    scsi_unregister(sh[j]);
index 186e96c47b3da09cfe06a66b17d545a6facc9ae9..98820603e75fd2a4a7b27206817744d60c10f833 100644 (file)
@@ -40,6 +40,7 @@
 #include <linux/serial_core.h>
 #include <linux/serial.h>
 #include <linux/serial_8250.h>
+#include <linux/nmi.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
@@ -2208,6 +2209,8 @@ serial8250_console_write(struct console *co, const char *s, unsigned int count)
        unsigned int ier;
        int i;
 
+       touch_nmi_watchdog();
+
        /*
         *      First save the UER then disable the interrupts
         */
index 40d3e7139cfea2518fff6c2a758e0bdc4c5cd53d..08c42c000188405f6363b3d49293dbe1e43a104b 100644 (file)
@@ -4416,10 +4416,8 @@ rs_close(struct tty_struct *tty, struct file * filp)
        info->event = 0;
        info->tty = 0;
        if (info->blocked_open) {
-               if (info->close_delay) {
-                       set_current_state(TASK_INTERRUPTIBLE);
-                       schedule_timeout(info->close_delay);
-               }
+               if (info->close_delay)
+                       schedule_timeout_interruptible(info->close_delay);
                wake_up_interruptible(&info->open_wait);
        }
        info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
@@ -4469,8 +4467,7 @@ static void rs_wait_until_sent(struct tty_struct *tty, int timeout)
        while (info->xmit.head != info->xmit.tail || /* More in send queue */
               (*info->ostatusadr & 0x007f) ||  /* more in FIFO */
               (elapsed_usec < 2*info->char_time_usec)) {
-               set_current_state(TASK_INTERRUPTIBLE);
-               schedule_timeout(1);
+               schedule_timeout_interruptible(1);
                if (signal_pending(current))
                        break;
                if (timeout && time_after(jiffies, orig_jiffies + timeout))
index e2ebdcad553c405b012a83c7674fe69472b42a1f..47f7404cb04542a80408254685b3d57451eaea06 100644 (file)
@@ -57,7 +57,8 @@ struct timer_list mcfrs_timer_struct;
  *     keep going.  Perhaps one day the cflag settings for the
  *     console can be used instead.
  */
-#if defined(CONFIG_ARNEWSH) || defined(CONFIG_MOTOROLA) || defined(CONFIG_senTec) || defined(CONFIG_SNEHA)
+#if defined(CONFIG_ARNEWSH) || defined(CONFIG_FREESCALE) || \
+    defined(CONFIG_senTec) || defined(CONFIG_SNEHA)
 #define        CONSOLE_BAUD_RATE       19200
 #define        DEFAULT_CBAUD           B19200
 #endif
@@ -67,7 +68,7 @@ struct timer_list mcfrs_timer_struct;
 #define        DEFAULT_CBAUD           B38400
 #endif
 
-#if defined(CONFIG_MOD5272)
+#if defined(CONFIG_MOD5272) || defined(CONFIG_M5208EVB)
 #define CONSOLE_BAUD_RATE      115200
 #define DEFAULT_CBAUD          B115200
 #endif
@@ -95,7 +96,8 @@ static struct tty_driver *mcfrs_serial_driver;
 #undef SERIAL_DEBUG_OPEN
 #undef SERIAL_DEBUG_FLOW
 
-#if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x)
+#if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \
+    defined(CONFIG_M520x)
 #define        IRQBASE (MCFINT_VECBASE+MCFINT_UART0)
 #else
 #define        IRQBASE 73
@@ -1528,6 +1530,35 @@ static void mcfrs_irqinit(struct mcf_serial *info)
        imrp = (volatile unsigned long *) (MCF_MBAR + MCFICM_INTC0 +
                MCFINTC_IMRL);
        *imrp &= ~((1 << (info->irq - MCFINT_VECBASE)) | 1);
+#elif defined(CONFIG_M520x)
+       volatile unsigned char *icrp, *uartp;
+       volatile unsigned long *imrp;
+
+       uartp = info->addr;
+
+       icrp = (volatile unsigned char *) (MCF_MBAR + MCFICM_INTC0 +
+               MCFINTC_ICR0 + MCFINT_UART0 + info->line);
+       *icrp = 0x03;
+
+       imrp = (volatile unsigned long *) (MCF_MBAR + MCFICM_INTC0 +
+               MCFINTC_IMRL);
+       *imrp &= ~((1 << (info->irq - MCFINT_VECBASE)) | 1);
+       if (info->line < 2) {
+               unsigned short *uart_par;
+               uart_par = (unsigned short *)(MCF_IPSBAR + MCF_GPIO_PAR_UART);
+               if (info->line == 0)
+                       *uart_par |=  MCF_GPIO_PAR_UART_PAR_UTXD0
+                                 | MCF_GPIO_PAR_UART_PAR_URXD0;
+               else if (info->line == 1)
+                       *uart_par |=  MCF_GPIO_PAR_UART_PAR_UTXD1
+                                 | MCF_GPIO_PAR_UART_PAR_URXD1;
+               } else if (info->line == 2) {
+                       unsigned char *feci2c_par;
+                       feci2c_par = (unsigned char *)(MCF_IPSBAR +  MCF_GPIO_PAR_FECI2C);
+                       *feci2c_par &= ~0x0F;
+                       *feci2c_par |=  MCF_GPIO_PAR_FECI2C_PAR_SCL_UTXD2
+                                   | MCF_GPIO_PAR_FECI2C_PAR_SDA_URXD2;
+               }
 #else
        volatile unsigned char  *icrp, *uartp;
 
index dc119ce68e3eafa7a0c6c4e03d244224b3e3c8df..55434330867b27c1b90c331fb1189202439dcff8 100644 (file)
@@ -30,7 +30,7 @@ superhyway_ro_attr(bot_mb, "0x%02x\n", vcr.bot_mb);
 superhyway_ro_attr(top_mb, "0x%02x\n", vcr.top_mb);
 
 /* Misc */
-superhyway_ro_attr(resource, "0x%08lx\n", resource.start);
+superhyway_ro_attr(resource, "0x%08lx\n", resource[0].start);
 
 struct device_attribute superhyway_dev_attrs[] = {
        __ATTR_RO(perr_flags),
index 28757cb9d246665ad8e4eba116f19679657aea57..7bdab2a7f59c61f25f7dd8b6b44c1b10e5ff6b42 100644 (file)
@@ -27,19 +27,20 @@ static struct device superhyway_bus_device = {
 
 static void superhyway_device_release(struct device *dev)
 {
-       kfree(to_superhyway_device(dev));
+       struct superhyway_device *sdev = to_superhyway_device(dev);
+
+       kfree(sdev->resource);
+       kfree(sdev);
 }
 
 /**
  * superhyway_add_device - Add a SuperHyway module
- * @mod_id: Module ID (taken from MODULE.VCR.MOD_ID).
  * @base: Physical address where module is mapped.
- * @vcr: VCR value.
+ * @sdev: SuperHyway device to add, or NULL to allocate a new one.
+ * @bus: Bus where SuperHyway module resides.
  *
  * This is responsible for adding a new SuperHyway module. This sets up a new
- * struct superhyway_device for the module being added. Each one of @mod_id,
- * @base, and @vcr are registered with the new device for further use
- * elsewhere.
+ * struct superhyway_device for the module being added if @sdev == NULL.
  *
  * Devices are initially added in the order that they are scanned (from the
  * top-down of the memory map), and are assigned an ID based on the order that
@@ -49,28 +50,40 @@ static void superhyway_device_release(struct device *dev)
  * Further work can and should be done in superhyway_scan_bus(), to be sure
  * that any new modules are properly discovered and subsequently registered.
  */
-int superhyway_add_device(unsigned int mod_id, unsigned long base,
-                         unsigned long long vcr)
+int superhyway_add_device(unsigned long base, struct superhyway_device *sdev,
+                         struct superhyway_bus *bus)
 {
-       struct superhyway_device *dev;
+       struct superhyway_device *dev = sdev;
+
+       if (!dev) {
+               dev = kmalloc(sizeof(struct superhyway_device), GFP_KERNEL);
+               if (!dev)
+                       return -ENOMEM;
 
-       dev = kmalloc(sizeof(struct superhyway_device), GFP_KERNEL);
-       if (!dev)
-               return -ENOMEM;
+               memset(dev, 0, sizeof(struct superhyway_device));
+       }
 
-       memset(dev, 0, sizeof(struct superhyway_device));
+       dev->bus = bus;
+       superhyway_read_vcr(dev, base, &dev->vcr);
 
-       dev->id.id = mod_id;
-       sprintf(dev->name, "SuperHyway device %04x", dev->id.id);
+       if (!dev->resource) {
+               dev->resource = kmalloc(sizeof(struct resource), GFP_KERNEL);
+               if (!dev->resource) {
+                       kfree(dev);
+                       return -ENOMEM;
+               }
+
+               dev->resource->name     = dev->name;
+               dev->resource->start    = base;
+               dev->resource->end      = dev->resource->start + 0x01000000;
+       }
 
-       dev->vcr                = *((struct vcr_info *)(&vcr));
-       dev->resource.name      = dev->name;
-       dev->resource.start     = base;
-       dev->resource.end       = dev->resource.start + 0x01000000;
        dev->dev.parent         = &superhyway_bus_device;
        dev->dev.bus            = &superhyway_bus_type;
        dev->dev.release        = superhyway_device_release;
+       dev->id.id              = dev->vcr.mod_id;
 
+       sprintf(dev->name, "SuperHyway device %04x", dev->id.id);
        sprintf(dev->dev.bus_id, "%02x", superhyway_devices);
 
        superhyway_devices++;
@@ -78,10 +91,31 @@ int superhyway_add_device(unsigned int mod_id, unsigned long base,
        return device_register(&dev->dev);
 }
 
+int superhyway_add_devices(struct superhyway_bus *bus,
+                          struct superhyway_device **devices,
+                          int nr_devices)
+{
+       int i, ret = 0;
+
+       for (i = 0; i < nr_devices; i++) {
+               struct superhyway_device *dev = devices[i];
+               ret |= superhyway_add_device(dev->resource[0].start, dev, bus);
+       }
+
+       return ret;
+}
+
 static int __init superhyway_init(void)
 {
+       struct superhyway_bus *bus;
+       int ret = 0;
+
        device_register(&superhyway_bus_device);
-       return superhyway_scan_bus();
+
+       for (bus = superhyway_channels; bus->ops; bus++)
+               ret |= superhyway_scan_bus(bus);
+
+       return ret;
 }
 
 postcore_initcall(superhyway_init);
@@ -197,6 +231,7 @@ module_exit(superhyway_bus_exit);
 
 EXPORT_SYMBOL(superhyway_bus_type);
 EXPORT_SYMBOL(superhyway_add_device);
+EXPORT_SYMBOL(superhyway_add_devices);
 EXPORT_SYMBOL(superhyway_register_driver);
 EXPORT_SYMBOL(superhyway_unregister_driver);
 
index 6a3cfbdc6dc92ed56d2f522f6ea9b7f18378b4ad..3b0ddc55236b7624a5ee48a2fad150711ad90f35 100644 (file)
@@ -113,7 +113,6 @@ static struct fb_ops mc68x328fb_ops = {
        .fb_fillrect    = cfb_fillrect,
        .fb_copyarea    = cfb_copyarea,
        .fb_imageblit   = cfb_imageblit,
-       .fb_cursor      = soft_cursor,
        .fb_mmap        = mc68x328fb_mmap,
 };
 
index 7192b770bfb650a7c68ca2b76a735617f78dec72..44b6ca290ce36bdcde56a22a8ec13b02e5fa8fd8 100644 (file)
@@ -65,15 +65,6 @@ config FB_CFB_IMAGEBLIT
          blitting. This is used by drivers that don't provide their own
          (accelerated) version.
 
-config FB_SOFT_CURSOR
-       tristate
-       depends on FB
-       default n
-       ---help---
-         Include the soft_cursor function for generic software cursor support.
-         This is used by drivers that don't provide their own (accelerated)
-         version.
-
 config FB_MACMODES
        tristate
        depends on FB
@@ -114,7 +105,6 @@ config FB_CIRRUS
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
        select FB_CFB_IMAGEBLIT
-       select FB_SOFT_CURSOR
        ---help---
          This enables support for Cirrus Logic GD542x/543x based boards on
          Amiga: SD64, Piccolo, Picasso II/II+, Picasso IV, or EGS Spectrum.
@@ -133,7 +123,6 @@ config FB_PM2
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
        select FB_CFB_IMAGEBLIT
-       select FB_SOFT_CURSOR
        help
          This is the frame buffer device driver for the Permedia2 AGP frame
          buffer card from ASK, aka `Graphic Blaster Exxtreme'.  There is a
@@ -152,7 +141,6 @@ config FB_ARMCLCD
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
        select FB_CFB_IMAGEBLIT
-       select FB_SOFT_CURSOR
        help
          This framebuffer device driver is for the ARM PrimeCell PL110
          Colour LCD controller.  ARM PrimeCells provide the building
@@ -169,7 +157,6 @@ config FB_ACORN
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
        select FB_CFB_IMAGEBLIT
-       select FB_SOFT_CURSOR
        help
          This is the frame buffer device driver for the Acorn VIDC graphics
          hardware found in Acorn RISC PCs and other ARM-based machines.  If
@@ -181,7 +168,9 @@ config FB_CLPS711X
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
        select FB_CFB_IMAGEBLIT
-       select FB_SOFT_CURSOR
+       help
+         Say Y to enable the Framebuffer driver for the CLPS7111 and
+         EP7212 processors.
 
 config FB_SA1100
        bool "SA-1100 LCD support"
@@ -189,7 +178,6 @@ config FB_SA1100
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
        select FB_CFB_IMAGEBLIT
-       select FB_SOFT_CURSOR
        help
          This is a framebuffer device for the SA-1100 LCD Controller.
          See <http://www.linux-fbdev.org/> for information on framebuffer
@@ -204,7 +192,6 @@ config FB_IMX
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
        select FB_CFB_IMAGEBLIT
-       select FB_SOFT_CURSOR
 
 config FB_CYBER2000
        tristate "CyberPro 2000/2010/5000 support"
@@ -212,7 +199,6 @@ config FB_CYBER2000
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
        select FB_CFB_IMAGEBLIT
-       select FB_SOFT_CURSOR
        help
          This enables support for the Integraphics CyberPro 20x0 and 5000
          VGA chips used in the Rebel.com Netwinder and other machines.
@@ -225,7 +211,6 @@ config FB_APOLLO
        default y
        select FB_CFB_FILLRECT
        select FB_CFB_IMAGEBLIT
-       select FB_SOFT_CURSOR
 
 config FB_Q40
        bool
@@ -234,12 +219,10 @@ config FB_Q40
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
        select FB_CFB_IMAGEBLIT
-       select FB_SOFT_CURSOR
 
 config FB_AMIGA
        tristate "Amiga native chipset support"
        depends on FB && AMIGA
-       select FB_SOFT_CURSOR
        help
          This is the frame buffer device driver for the builtin graphics
          chipset found in Amigas.
@@ -279,7 +262,6 @@ config FB_CYBER
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
        select FB_CFB_IMAGEBLIT
-       select FB_SOFT_CURSOR
        help
          This enables support for the Cybervision 64 graphics card from
          Phase5. Please note that its use is not all that intuitive (i.e. if
@@ -294,7 +276,6 @@ config FB_VIRGE
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
        select FB_CFB_IMAGEBLIT
-       select FB_SOFT_CURSOR
        help
          This enables support for the Cybervision 64/3D graphics card from
          Phase5. Please note that its use is not all that intuitive (i.e. if
@@ -317,7 +298,6 @@ config FB_FM2
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
        select FB_CFB_IMAGEBLIT
-       select FB_SOFT_CURSOR
        help
          This is the frame buffer device driver for the Amiga FrameMaster
          card from BSC (exhibited 1992 but not shipped as a CBM product).
@@ -328,7 +308,6 @@ config FB_ARC
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
        select FB_CFB_IMAGEBLIT
-       select FB_SOFT_CURSOR
        help
          This enables support for the Arc Monochrome LCD board. The board
          is based on the KS-108 lcd controller and is typically a matrix
@@ -351,7 +330,6 @@ config FB_OF
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
        select FB_CFB_IMAGEBLIT
-       select FB_SOFT_CURSOR
        select FB_MACMODES
        help
          Say Y if you want support with Open Firmware for your graphics
@@ -363,7 +341,6 @@ config FB_CONTROL
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
        select FB_CFB_IMAGEBLIT
-       select FB_SOFT_CURSOR
        select FB_MACMODES
        help
          This driver supports a frame buffer for the graphics adapter in the
@@ -375,7 +352,6 @@ config FB_PLATINUM
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
        select FB_CFB_IMAGEBLIT
-       select FB_SOFT_CURSOR
        select FB_MACMODES
        help
          This driver supports a frame buffer for the "platinum" graphics
@@ -387,7 +363,6 @@ config FB_VALKYRIE
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
        select FB_CFB_IMAGEBLIT
-       select FB_SOFT_CURSOR
        select FB_MACMODES
        help
          This driver supports a frame buffer for the "valkyrie" graphics
@@ -399,42 +374,32 @@ config FB_CT65550
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
        select FB_CFB_IMAGEBLIT
-       select FB_SOFT_CURSOR
        help
          This is the frame buffer device driver for the Chips & Technologies
          65550 graphics chip in PowerBooks.
 
 config FB_ASILIANT
-       bool "Chips 69000 display support"
+       bool "Asiliant (Chips) 69000 display support"
        depends on (FB = y) && PCI
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
        select FB_CFB_IMAGEBLIT
-       select FB_SOFT_CURSOR
 
 config FB_IMSTT
        bool "IMS Twin Turbo display support"
        depends on (FB = y) && PCI
        select FB_CFB_IMAGEBLIT
-       select FB_SOFT_CURSOR
        select FB_MACMODES if PPC
        help
          The IMS Twin Turbo is a PCI-based frame buffer card bundled with
          many Macintosh and compatible computers.
 
-config FB_S3TRIO
-       bool "S3 Trio display support"
-       depends on (FB = y) && PPC && BROKEN
-       help
-         If you have a S3 Trio say Y. Say N for S3 Virge.
-
 config FB_VGA16
        tristate "VGA 16-color graphics support"
        depends on FB && (X86 || PPC)
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
        select FB_CFB_IMAGEBLIT
-       select FB_SOFT_CURSOR
        help
          This is the frame buffer device driver for VGA 16 color graphic
          cards. Say Y if you have such a card.
@@ -448,7 +413,6 @@ config FB_STI
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
        select FB_CFB_IMAGEBLIT
-       select FB_SOFT_CURSOR
        default y
        ---help---
          STI refers to the HP "Standard Text Interface" which is a set of
@@ -469,7 +433,6 @@ config FB_MAC
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
        select FB_CFB_IMAGEBLIT
-       select FB_SOFT_CURSOR
        select FB_MACMODES
 
 #      bool '  Apple DAFB display support' CONFIG_FB_DAFB
@@ -478,7 +441,6 @@ config FB_HP300
        depends on (FB = y) && HP300
        select FB_CFB_FILLRECT
        select FB_CFB_IMAGEBLIT
-       select FB_SOFT_CURSOR
        default y
 
 config FB_TGA
@@ -487,7 +449,6 @@ config FB_TGA
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
        select FB_CFB_IMAGEBLIT
-       select FB_SOFT_CURSOR
        help
          This is the frame buffer device driver for generic TGA graphic
          cards. Say Y if you have one of those.
@@ -498,7 +459,6 @@ config FB_VESA
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
        select FB_CFB_IMAGEBLIT
-       select FB_SOFT_CURSOR
        help
          This is the frame buffer device driver for generic VESA 2.0
          compliant graphic cards. The older VESA 1.2 cards are not supported.
@@ -516,7 +476,6 @@ config FB_HGA
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
        select FB_CFB_IMAGEBLIT
-       select FB_SOFT_CURSOR
        help
          Say Y here if you have a Hercules mono graphics card.
 
@@ -545,7 +504,6 @@ config FB_SGIVW
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
        select FB_CFB_IMAGEBLIT
-       select FB_SOFT_CURSOR
        help
          SGI Visual Workstation support for framebuffer graphics.
 
@@ -555,7 +513,6 @@ config FB_GBE
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
        select FB_CFB_IMAGEBLIT
-       select FB_SOFT_CURSOR
        help
          This is the frame buffer device driver for SGI Graphics Backend.
          This chip is used in SGI O2 and Visual Workstation 320/540.
@@ -583,7 +540,6 @@ config FB_BW2
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
        select FB_CFB_IMAGEBLIT
-       select FB_SOFT_CURSOR
        help
          This is the frame buffer device driver for the BWtwo frame buffer.
 
@@ -592,7 +548,6 @@ config FB_CG3
        depends on (FB = y) && ((SPARC32 || SPARC64) && FB_SBUS || (SUN3 || SUN3X) && FB_SUN3)
        select FB_CFB_COPYAREA
        select FB_CFB_IMAGEBLIT
-       select FB_SOFT_CURSOR
        help
          This is the frame buffer device driver for the CGthree frame buffer.
 
@@ -601,7 +556,6 @@ config FB_CG6
        depends on (FB = y) && ((SPARC32 || SPARC64) && FB_SBUS || (SUN3 || SUN3X) && FB_SUN3)
        select FB_CFB_COPYAREA
        select FB_CFB_IMAGEBLIT
-       select FB_SOFT_CURSOR
        help
          This is the frame buffer device driver for the CGsix (GX, TurboGX)
          frame buffer.
@@ -612,7 +566,6 @@ config FB_PVR2
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
        select FB_CFB_IMAGEBLIT
-       select FB_SOFT_CURSOR
        ---help---
          Say Y here if you have a PowerVR 2 card in your box.  If you plan to
          run linux on your Dreamcast, you will have to say Y here.
@@ -634,13 +587,55 @@ config FB_EPSON1355
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
        select FB_CFB_IMAGEBLIT
-       select FB_SOFT_CURSOR
        help
          Build in support for the SED1355 Epson Research Embedded RAMDAC
          LCD/CRT Controller (since redesignated as the S1D13505) as a
          framebuffer.  Product specs at
          <http://www.erd.epson.com/vdc/html/products.htm>.
 
+config FB_E1356
+       tristate "Epson SED1356 framebuffer support"
+       depends on FB && EXPERIMENTAL && PCI && MIPS
+
+config PB1000_CRT
+       bool "Use CRT on Pb1000 (J65)"
+       depends on MIPS_PB1000=y && FB_E1356
+
+config PB1000_NTSC
+       bool "Use Compsite NTSC on Pb1000 (J63)"
+       depends on MIPS_PB1000=y && FB_E1356
+
+config PB1000_TFT
+       bool "Use TFT Panel on Pb1000 (J64)"
+       depends on MIPS_PB1000=y && FB_E1356
+
+config PB1500_CRT
+       bool "Use CRT on Pb1500 " if MIPS_PB1500=y
+       depends on FB_E1356
+
+config PB1500_CRT
+       prompt "Use CRT on Pb1100 "
+       depends on FB_E1356 && MIPS_PB1100=y
+
+config PB1500_TFT
+       bool "Use TFT Panel on Pb1500 " if MIPS_PB1500=y
+       depends on FB_E1356
+
+config PB1500_TFT
+       prompt "Use TFT Panel on Pb1100 "
+       depends on FB_E1356 && MIPS_PB1100=y
+
+config FB_S1D13XXX
+       tristate "Epson S1D13XXX framebuffer support"
+       depends on FB
+       select FB_CFB_FILLRECT
+       select FB_CFB_COPYAREA
+       select FB_CFB_IMAGEBLIT
+       help
+         Support for S1D13XXX framebuffer device family (currently only
+         working with S1D13806). Product specs at
+         <http://www.erd.epson.com/vdc/html/legacy_13xxx.htm>
+
 config FB_NVIDIA
        tristate "nVidia Framebuffer Support"
        depends on FB && PCI
@@ -650,7 +645,6 @@ config FB_NVIDIA
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
        select FB_CFB_IMAGEBLIT
-       select FB_SOFT_CURSOR
        help
          This driver supports graphics boards with the nVidia chips, TNT
          and newer. For very old chipsets, such as the RIVA128, then use
@@ -662,7 +656,7 @@ config FB_NVIDIA
 
 config FB_NVIDIA_I2C
        bool "Enable DDC Support"
-       depends on FB_NVIDIA && !PPC_OF
+       depends on FB_NVIDIA
        help
          This enables I2C support for nVidia Chipsets.  This is used
          only for getting EDID information from the attached display
@@ -768,7 +762,6 @@ config FB_INTEL
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
        select FB_CFB_IMAGEBLIT
-       select FB_SOFT_CURSOR
        help
          This driver supports the on-board graphics built in to the Intel
           830M/845G/852GM/855GM/865G chipsets.
@@ -791,7 +784,6 @@ config FB_MATROX
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
        select FB_CFB_IMAGEBLIT
-       select FB_SOFT_CURSOR
        select FB_TILEBLITTING
        select FB_MACMODES if PPC_PMAC
        ---help---
@@ -932,7 +924,6 @@ config FB_RADEON_OLD
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
        select FB_CFB_IMAGEBLIT
-       select FB_SOFT_CURSOR
        select FB_MACMODES if PPC
        help
          Choose this option if you want to use an ATI Radeon graphics card as
@@ -950,7 +941,6 @@ config FB_RADEON
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
        select FB_CFB_IMAGEBLIT
-       select FB_SOFT_CURSOR
        select FB_MACMODES if PPC_OF
        help
          Choose this option if you want to use an ATI Radeon graphics card as
@@ -988,7 +978,6 @@ config FB_ATY128
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
        select FB_CFB_IMAGEBLIT
-       select FB_SOFT_CURSOR
        select FB_MACMODES if PPC_PMAC
        help
          This driver supports graphics boards with the ATI Rage128 chips.
@@ -1004,7 +993,6 @@ config FB_ATY
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
        select FB_CFB_IMAGEBLIT
-       select FB_SOFT_CURSOR
        select FB_MACMODES if PPC
        help
          This driver supports graphics boards with the ATI Mach64 chips.
@@ -1047,6 +1035,12 @@ config FB_ATY_GX
          is at
          <http://support.ati.com/products/pc/mach64/graphics_xpression.html>.
 
+config FB_S3TRIO
+       bool "S3 Trio display support"
+       depends on (FB = y) && PPC && BROKEN
+       help
+         If you have a S3 Trio say Y. Say N for S3 Virge.
+
 config FB_SAVAGE
        tristate "S3 Savage support"
        depends on FB && PCI && EXPERIMENTAL
@@ -1056,7 +1050,6 @@ config FB_SAVAGE
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
        select FB_CFB_IMAGEBLIT
-       select FB_SOFT_CURSOR
        help
          This driver supports notebooks and computers with S3 Savage PCI/AGP
          chips.
@@ -1093,7 +1086,6 @@ config FB_SIS
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
        select FB_CFB_IMAGEBLIT
-       select FB_SOFT_CURSOR
        help
          This is the frame buffer device driver for the SiS 300, 315, 330
          and 340 series as well as XGI V3XT, V5, V8, Z7 graphics chipsets.
@@ -1123,7 +1115,6 @@ config FB_NEOMAGIC
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
        select FB_CFB_IMAGEBLIT
-       select FB_SOFT_CURSOR
        help
          This driver supports notebooks with NeoMagic PCI chips.
          Say Y if you have such a graphics card. 
@@ -1137,7 +1128,6 @@ config FB_KYRO
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
        select FB_CFB_IMAGEBLIT
-       select FB_SOFT_CURSOR
        help
          Say Y here if you have a STG4000 / Kyro / PowerVR 3 based
          graphics board.
@@ -1151,7 +1141,6 @@ config FB_3DFX
        select FB_CFB_IMAGEBLIT
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
-       select FB_SOFT_CURSOR
        help
          This driver supports graphics boards with the 3Dfx Banshee/Voodoo3
          chips. Say Y if you have such a graphics board.
@@ -1173,7 +1162,6 @@ config FB_VOODOO1
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
        select FB_CFB_IMAGEBLIT
-       select FB_SOFT_CURSOR
        ---help---
          Say Y here if you have a 3Dfx Voodoo Graphics (Voodoo1/sst1) or 
          Voodoo2 (cvg) based graphics card.
@@ -1190,7 +1178,6 @@ config FB_CYBLA
        tristate "Cyberblade/i1 support"
        depends on FB && PCI
        select FB_CFB_IMAGEBLIT
-       select FB_SOFT_CURSOR
        select VIDEO_SELECT
        ---help---
          This driver is supposed to support the Trident Cyberblade/i1
@@ -1218,7 +1205,6 @@ config FB_TRIDENT
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
        select FB_CFB_IMAGEBLIT
-       select FB_SOFT_CURSOR
        ---help---
          This driver is supposed to support graphics boards with the
          Trident CyberXXXX/Image/CyberBlade chips mostly found in laptops
@@ -1250,38 +1236,6 @@ config FB_PM3
          similar boards, 3DLabs Permedia3 Create!, Appian Jeronimo 2000
          and maybe other boards.
 
-config FB_E1356
-       tristate "Epson SED1356 framebuffer support"
-       depends on FB && EXPERIMENTAL && PCI && MIPS
-
-config PB1000_CRT
-       bool "Use CRT on Pb1000 (J65)"
-       depends on MIPS_PB1000=y && FB_E1356
-
-config PB1000_NTSC
-       bool "Use Compsite NTSC on Pb1000 (J63)"
-       depends on MIPS_PB1000=y && FB_E1356
-
-config PB1000_TFT
-       bool "Use TFT Panel on Pb1000 (J64)"
-       depends on MIPS_PB1000=y && FB_E1356
-
-config PB1500_CRT
-       bool "Use CRT on Pb1500 " if MIPS_PB1500=y
-       depends on FB_E1356
-
-config PB1500_CRT
-       prompt "Use CRT on Pb1100 "
-       depends on FB_E1356 && MIPS_PB1100=y
-
-config PB1500_TFT
-       bool "Use TFT Panel on Pb1500 " if MIPS_PB1500=y
-       depends on FB_E1356
-
-config PB1500_TFT
-       prompt "Use TFT Panel on Pb1100 "
-       depends on FB_E1356 && MIPS_PB1100=y
-
 config FB_AU1100
        bool "Au1100 LCD Driver"
        depends on (FB = y) && EXPERIMENTAL && PCI && MIPS && MIPS_PB1100=y
@@ -1299,7 +1253,6 @@ config FB_FFB
        depends on FB_SBUS && SPARC64
        select FB_CFB_COPYAREA
        select FB_CFB_IMAGEBLIT
-       select FB_SOFT_CURSOR
        help
          This is the frame buffer device driver for the Creator, Creator3D,
          and Elite3D graphics boards.
@@ -1310,7 +1263,6 @@ config FB_TCX
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
        select FB_CFB_IMAGEBLIT
-       select FB_SOFT_CURSOR
        help
          This is the frame buffer device driver for the TCX 24/8bit frame
          buffer.
@@ -1321,7 +1273,6 @@ config FB_CG14
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
        select FB_CFB_IMAGEBLIT
-       select FB_SOFT_CURSOR
        help
          This is the frame buffer device driver for the CGfourteen frame
          buffer on Desktop SPARCsystems with the SX graphics option.
@@ -1332,7 +1283,6 @@ config FB_P9100
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
        select FB_CFB_IMAGEBLIT
-       select FB_SOFT_CURSOR
        help
          This is the frame buffer device driver for the P9100 card
          supported on Sparcbook 3 machines.
@@ -1343,7 +1293,6 @@ config FB_LEO
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
        select FB_CFB_IMAGEBLIT
-       select FB_SOFT_CURSOR
        help
          This is the frame buffer device driver for the SBUS-based Sun ZX
          (leo) frame buffer cards.
@@ -1358,7 +1307,6 @@ config FB_IGA
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
        select FB_CFB_IMAGEBLIT
-       select FB_SOFT_CURSOR
        help
          This is the framebuffer device for the INTERGRAPHICS 1680 and
          successor frame buffer cards.
@@ -1369,7 +1317,6 @@ config FB_HIT
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
        select FB_CFB_IMAGEBLIT
-       select FB_SOFT_CURSOR
        help
          This is the frame buffer device driver for the Hitachi HD64461 LCD
          frame buffer card.
@@ -1380,7 +1327,6 @@ config FB_PMAG_AA
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
        select FB_CFB_IMAGEBLIT
-       select FB_SOFT_CURSOR
        help
          Support for the PMAG-AA TURBOchannel framebuffer card (1280x1024x1)
          used mainly in the MIPS-based DECstation series.
@@ -1391,7 +1337,6 @@ config FB_PMAG_BA
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
        select FB_CFB_IMAGEBLIT
-       select FB_SOFT_CURSOR
        help
          Support for the PMAG-BA TURBOchannel framebuffer card (1024x864x8)
          used mainly in the MIPS-based DECstation series.
@@ -1402,7 +1347,6 @@ config FB_PMAGB_B
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
        select FB_CFB_IMAGEBLIT
-       select FB_SOFT_CURSOR
        help
          Support for the PMAGB-B TURBOchannel framebuffer card used mainly
          in the MIPS-based DECstation series. The card is currently only
@@ -1414,7 +1358,6 @@ config FB_MAXINE
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
        select FB_CFB_IMAGEBLIT
-       select FB_SOFT_CURSOR
        help
          Support for the onboard framebuffer (1024x768x8) in the Personal
          DECstation series (Personal DECstation 5000/20, /25, /33, /50,
@@ -1426,7 +1369,6 @@ config FB_TX3912
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
        select FB_CFB_IMAGEBLIT
-       select FB_SOFT_CURSOR
        help
          The TX3912 is a Toshiba RISC processor based on the MIPS 3900 core
          see <http://www.toshiba.com/taec/components/Generic/risc/tx3912.htm>.
@@ -1439,7 +1381,6 @@ config FB_G364
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
        select FB_CFB_IMAGEBLIT
-       select FB_SOFT_CURSOR
        help
          The G364 driver is the framebuffer used in MIPS Magnum 4000 and
          Olivetti M700-10 systems.
@@ -1450,7 +1391,6 @@ config FB_68328
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
        select FB_CFB_IMAGEBLIT
-       select FB_SOFT_CURSOR
        help
          Say Y here if you want to support the built-in frame buffer of
          the Motorola 68328 CPU family.
@@ -1461,7 +1401,6 @@ config FB_PXA
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
        select FB_CFB_IMAGEBLIT
-       select FB_SOFT_CURSOR
        ---help---
          Frame buffer driver for the built-in LCD controller in the Intel
          PXA2x0 processor.
@@ -1473,23 +1412,6 @@ config FB_PXA
 
          If unsure, say N.
 
-config FB_W100
-       tristate "W100 frame buffer support"
-       depends on FB && PXA_SHARPSL
-       select FB_CFB_FILLRECT
-       select FB_CFB_COPYAREA
-       select FB_CFB_IMAGEBLIT
-       select FB_SOFT_CURSOR
-       ---help---
-         Frame buffer driver for the w100 as found on the Sharp SL-Cxx series.
-
-         This driver is also available as a module ( = code which can be
-         inserted and removed from the running kernel whenever you want). The
-         module will be called vfb. If you want to compile it as a module,
-         say M here and read <file:Documentation/modules.txt>.
-
-         If unsure, say N.
-
 config FB_PXA_PARAMETERS
        bool "PXA LCD command line parameters"
        default n
@@ -1507,17 +1429,21 @@ config FB_PXA_PARAMETERS
 
          <file:Documentation/fb/pxafb.txt> describes the available parameters.
 
-config FB_S1D13XXX
-       tristate "Epson S1D13XXX framebuffer support"
-       depends on FB
-       select FB_CFB_FILLRECT
-       select FB_CFB_COPYAREA
-       select FB_CFB_IMAGEBLIT
-       select FB_SOFT_CURSOR
-       help
-         Support for S1D13XXX framebuffer device family (currently only
-         working with S1D13806). Product specs at
-         <http://www.erd.epson.com/vdc/html/legacy_13xxx.htm>
+config FB_W100
+       tristate "W100 frame buffer support"
+       depends on FB && PXA_SHARPSL
+       select FB_CFB_FILLRECT
+       select FB_CFB_COPYAREA
+       select FB_CFB_IMAGEBLIT
+       ---help---
+         Frame buffer driver for the w100 as found on the Sharp SL-Cxx series.
+
+         This driver is also available as a module ( = code which can be
+         inserted and removed from the running kernel whenever you want). The
+         module will be called vfb. If you want to compile it as a module,
+         say M here and read <file:Documentation/modules.txt>.
+
+         If unsure, say N.
 
 config FB_S3C2410
        tristate "S3C2410 LCD framebuffer support"
@@ -1525,7 +1451,6 @@ config FB_S3C2410
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
        select FB_CFB_IMAGEBLIT
-       select FB_SOFT_CURSOR
        ---help---
          Frame buffer driver for the built-in LCD controller in the Samsung
          S3C2410 processor.
@@ -1549,7 +1474,6 @@ config FB_VIRTUAL
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
        select FB_CFB_IMAGEBLIT
-       select FB_SOFT_CURSOR
        ---help---
          This is a `virtual' frame buffer device. It operates on a chunk of
          unswappable kernel memory instead of on the memory of a graphics
index 97c5d03ac8d99e7d70936d90c466eb62e44ab587..aa434e725c0d844af830a0f273339d26c19d0d1b 100644 (file)
@@ -16,7 +16,6 @@ fb-objs                           := $(fb-y)
 obj-$(CONFIG_FB_CFB_FILLRECT)  += cfbfillrect.o
 obj-$(CONFIG_FB_CFB_COPYAREA)  += cfbcopyarea.o
 obj-$(CONFIG_FB_CFB_IMAGEBLIT) += cfbimgblt.o
-obj-$(CONFIG_FB_SOFT_CURSOR)   += softcursor.o
 obj-$(CONFIG_FB_MACMODES)      += macmodes.o
 
 # Hardware specific drivers go first
index 9b6a39348f81ab4415f01d8837c0990219b88efb..193b482570c7e9cc1ee41303ad67d5871b37db90 100644 (file)
@@ -926,7 +926,6 @@ static struct fb_ops acornfb_ops = {
        .fb_copyarea    = cfb_copyarea,
        .fb_imageblit   = cfb_imageblit,
        .fb_mmap        = acornfb_mmap,
-       .fb_cursor      = soft_cursor,
 };
 
 /*
index 4fc93dc2b4d3eb2e1d09536b657e9875cd5d54b7..467a1d7ebbdecdf14f129a34c172e8e0ae5ae5d9 100644 (file)
@@ -333,7 +333,6 @@ static struct fb_ops clcdfb_ops = {
        .fb_fillrect    = cfb_fillrect,
        .fb_copyarea    = cfb_copyarea,
        .fb_imageblit   = cfb_imageblit,
-       .fb_cursor      = soft_cursor,
        .fb_mmap        = clcdfb_mmap,
 };
 
index cf8bb67462dc59de02088f46429a134052d8b53a..d549e215f3c57fe944c39583baa6718d9554ee1b 100644 (file)
@@ -1185,7 +1185,6 @@ static struct fb_ops amifb_ops = {
        .fb_fillrect    = amifb_fillrect,
        .fb_copyarea    = amifb_copyarea,
        .fb_imageblit   = amifb_imageblit,
-       .fb_cursor      = soft_cursor,
        .fb_ioctl       = amifb_ioctl,
 };
 
index 6aa9f824c185ce62749e276c0e05eb80755e786a..a1fc8bbb1090bfe41bfd6bc8b64e4824bc6fe748 100644 (file)
@@ -511,7 +511,6 @@ static struct fb_ops arcfb_ops = {
        .fb_fillrect    = arcfb_fillrect,
        .fb_copyarea    = arcfb_copyarea,
        .fb_imageblit   = arcfb_imageblit,
-       .fb_cursor      = soft_cursor,
        .fb_ioctl       = arcfb_ioctl,
 };
 
index f4729f4df8cec0f28aa8157e35c68051dc924df3..c64de59398f499e80507a3e3d582f90d8515bf19 100644 (file)
@@ -106,7 +106,6 @@ static struct fb_ops asiliantfb_ops = {
        .fb_fillrect    = cfb_fillrect,
        .fb_copyarea    = cfb_copyarea,
        .fb_imageblit   = cfb_imageblit,
-       .fb_cursor      = soft_cursor,
 };
 
 /* Calculate the ratios for the dot clocks without using a single long long
index 13321c689cf68a8937ee766e9e776f5dc0ed4581..39ab483fc25011112f7a47898c56716c3be30b43 100644 (file)
 #define PCI_CHIP_RV200_QX              0x5158
 #define PCI_CHIP_RV100_QY              0x5159
 #define PCI_CHIP_RV100_QZ              0x515A
+#define PCI_CHIP_RN50                  0x515E
 #define PCI_CHIP_RAGE128RE             0x5245
 #define PCI_CHIP_RAGE128RF             0x5246
 #define PCI_CHIP_RAGE128RG             0x5247
index e380ee8b0247d629ed65f62557737c2e28d58524..e686185a076d0ee52fabf164f8fa39abc9a66a0c 100644 (file)
@@ -478,7 +478,6 @@ static struct fb_ops aty128fb_ops = {
        .fb_fillrect    = cfb_fillrect,
        .fb_copyarea    = cfb_copyarea,
        .fb_imageblit   = cfb_imageblit,
-       .fb_cursor      = soft_cursor,
 };
 
 #ifdef CONFIG_PMAC_BACKLIGHT
index 037fe9d32fe39bf19ed41ee1c83671565ab748b9..08edbfcfca588eaa2b6628b8eb37bcd43d4b6fde 100644 (file)
@@ -292,7 +292,6 @@ static struct fb_ops atyfb_ops = {
        .fb_fillrect    = atyfb_fillrect,
        .fb_copyarea    = atyfb_copyarea,
        .fb_imageblit   = atyfb_imageblit,
-       .fb_cursor      = soft_cursor,
 #ifdef __sparc__
        .fb_mmap        = atyfb_mmap,
 #endif
@@ -2157,11 +2156,38 @@ static void __init aty_calc_mem_refresh(struct atyfb_par *par, int xclk)
 
 static struct fb_info *fb_list = NULL;
 
+#if defined(__i386__) && defined(CONFIG_FB_ATY_GENERIC_LCD)
+static int __devinit atyfb_get_timings_from_lcd(struct atyfb_par *par,
+                                               struct fb_var_screeninfo *var)
+{
+       int ret = -EINVAL;
+
+       if (par->lcd_table != 0 && (aty_ld_lcd(LCD_GEN_CNTL, par) & LCD_ON)) {
+               *var = default_var;
+               var->xres = var->xres_virtual = par->lcd_hdisp;
+               var->right_margin = par->lcd_right_margin;
+               var->left_margin = par->lcd_hblank_len -
+                       (par->lcd_right_margin + par->lcd_hsync_dly +
+                        par->lcd_hsync_len);
+               var->hsync_len = par->lcd_hsync_len + par->lcd_hsync_dly;
+               var->yres = var->yres_virtual = par->lcd_vdisp;
+               var->lower_margin = par->lcd_lower_margin;
+               var->upper_margin = par->lcd_vblank_len -
+                       (par->lcd_lower_margin + par->lcd_vsync_len);
+               var->vsync_len = par->lcd_vsync_len;
+               var->pixclock = par->lcd_pixclock;
+               ret = 0;
+       }
+
+       return ret;
+}
+#endif /* defined(__i386__) && defined(CONFIG_FB_ATY_GENERIC_LCD) */
+
 static int __init aty_init(struct fb_info *info, const char *name)
 {
        struct atyfb_par *par = (struct atyfb_par *) info->par;
        const char *ramname = NULL, *xtal;
-       int gtb_memsize;
+       int gtb_memsize, has_var = 0;
        struct fb_var_screeninfo var;
        u8 pll_ref_div;
        u32 i;
@@ -2469,8 +2495,8 @@ static int __init aty_init(struct fb_info *info, const char *name)
                 *         applies to all Mac video cards
                 */
                if (mode) {
-                       if (!mac_find_mode(&var, info, mode, 8))
-                               var = default_var;
+                       if (mac_find_mode(&var, info, mode, 8))
+                               has_var = 1;
                } else {
                        if (default_vmode == VMODE_CHOOSE) {
                                if (M64_HAS(G3_PB_1024x768))
@@ -2492,20 +2518,23 @@ static int __init aty_init(struct fb_info *info, const char *name)
                                default_vmode = VMODE_640_480_60;
                        if (default_cmode < CMODE_8 || default_cmode > CMODE_32)
                                default_cmode = CMODE_8;
-                       if (mac_vmode_to_var(default_vmode, default_cmode, &var))
-                               var = default_var;
+                       if (!mac_vmode_to_var(default_vmode, default_cmode,
+                                              &var))
+                               has_var = 1;
                }
-       } else
+       }
+
 #endif /* !CONFIG_PPC */
-       if (
-#if defined(CONFIG_SPARC32) || defined(CONFIG_SPARC64)
-          /* On Sparc, unless the user gave a specific mode
-           * specification, use the PROM probed values in
-           * default_var.
-           */
-           !mode ||
+
+#if defined(__i386__) && defined(CONFIG_FB_ATY_GENERIC_LCD)
+       if (!atyfb_get_timings_from_lcd(par, &var))
+               has_var = 1;
 #endif
-           !fb_find_mode(&var, info, mode, NULL, 0, &defmode, 8))
+
+       if (mode && fb_find_mode(&var, info, mode, NULL, 0, &defmode, 8))
+               has_var = 1;
+
+       if (!has_var)
                var = default_var;
 
        if (noaccel)
index 8a24a66d9ba8f6e7033ce0a4667c613ba8e7a183..4f01ccc02aa4c47750a22a5d338641aa86442b3e 100644 (file)
@@ -69,7 +69,6 @@
 #include <linux/pci.h>
 #include <linux/vmalloc.h>
 #include <linux/device.h>
-#include <linux/i2c.h>
 
 #include <asm/io.h>
 #include <asm/uaccess.h>
@@ -113,6 +112,7 @@ static struct pci_device_id radeonfb_pci_table[] = {
        /* Radeon VE/7000 */
        CHIP_DEF(PCI_CHIP_RV100_QY,     RV100,  CHIP_HAS_CRTC2),
        CHIP_DEF(PCI_CHIP_RV100_QZ,     RV100,  CHIP_HAS_CRTC2),
+       CHIP_DEF(PCI_CHIP_RN50,         RV100,  CHIP_HAS_CRTC2),
        /* Radeon IGP320M (U1) */
        CHIP_DEF(PCI_CHIP_RS100_4336,   RS100,  CHIP_HAS_CRTC2 | CHIP_IS_IGP | CHIP_IS_MOBILITY),
        /* Radeon IGP320 (A3) */
@@ -1874,7 +1874,6 @@ static struct fb_ops radeonfb_ops = {
        .fb_fillrect            = radeonfb_fillrect,
        .fb_copyarea            = radeonfb_copyarea,
        .fb_imageblit           = radeonfb_imageblit,
-       .fb_cursor              = soft_cursor,
 };
 
 
index 01b8b2f785140677d249fb2d72e12cf6a4396472..217e00ab4a2d284ba899679e39727fb9b4d5dee6 100644 (file)
 #include <linux/fb.h>
 
 
+#ifdef CONFIG_FB_RADEON_I2C
 #include <linux/i2c.h>
-#include <linux/i2c-id.h>
 #include <linux/i2c-algo-bit.h>
+#endif
 
 #include <asm/io.h>
 
index 3d20b2d47d46cbbcfa7445453faa5ee14ec41040..f53bf3ba127898c01a480b69be8b211bf02ab561 100644 (file)
@@ -51,7 +51,6 @@ static struct fb_ops bw2_ops = {
        .fb_imageblit           = cfb_imageblit,
        .fb_mmap                = bw2_mmap,
        .fb_ioctl               = bw2_ioctl,
-       .fb_cursor              = soft_cursor,
 };
 
 /* OBio addresses for the bwtwo registers */
index 67711f7b11b14229f6cd8604c73c05b48c966b3c..cdc71572cf356d26955ec256d42e6c1149663108 100644 (file)
@@ -349,46 +349,10 @@ void cfb_copyarea(struct fb_info *p, const struct fb_copyarea *area)
        unsigned long __iomem *dst = NULL, *src = NULL;
        int bits = BITS_PER_LONG, bytes = bits >> 3;
        int dst_idx = 0, src_idx = 0, rev_copy = 0;
-       int x2, y2, vxres, vyres;
 
        if (p->state != FBINFO_STATE_RUNNING)
                return;
 
-       /* We want rotation but lack hardware to do it for us. */
-       if (!p->fbops->fb_rotate && p->var.rotate) {
-       }
-
-       vxres = p->var.xres_virtual;
-       vyres = p->var.yres_virtual;
-
-       if (area->dx > vxres || area->sx > vxres ||
-           area->dy > vyres || area->sy > vyres)
-               return;
-
-       /* clip the destination
-        * We could use hardware clipping but on many cards you get around
-        * hardware clipping by writing to framebuffer directly.
-        */
-       x2 = area->dx + area->width;
-       y2 = area->dy + area->height;
-       dx = area->dx > 0 ? area->dx : 0;
-       dy = area->dy > 0 ? area->dy : 0;
-       x2 = x2 < vxres ? x2 : vxres;
-       y2 = y2 < vyres ? y2 : vyres;
-       width = x2 - dx;
-       height = y2 - dy;
-
-       if ((width==0) ||(height==0))
-               return;
-
-       /* update sx1,sy1 */
-       sx += (dx - area->dx);
-       sy += (dy - area->dy);
-
-       /* the source must be completely inside the virtual screen */
-       if (sx < 0 || sy < 0 || (sx + width) > vxres || (sy + height) > vyres)
-               return;
-
        /* if the beginning of the target area might overlap with the end of
        the source area, be have to copy the area reverse. */
        if ((dy == sy && dx > sx) || (dy > sy)) {
index e4fc42b013ebdb7f3bab16ef7f33c0d4d7a2573f..167d9314e6eb49c6ae25683e940563ef92f6ca1c 100644 (file)
@@ -344,7 +344,8 @@ bitfill_unaligned_rev(unsigned long __iomem *dst, int dst_idx, unsigned long pat
 
 void cfb_fillrect(struct fb_info *p, const struct fb_fillrect *rect)
 {
-       unsigned long x2, y2, vxres, vyres, height, width, pat, fg;
+       unsigned long pat, fg;
+       unsigned long width = rect->width, height = rect->height;
        int bits = BITS_PER_LONG, bytes = bits >> 3;
        u32 bpp = p->var.bits_per_pixel;
        unsigned long __iomem *dst;
@@ -353,27 +354,6 @@ void cfb_fillrect(struct fb_info *p, const struct fb_fillrect *rect)
        if (p->state != FBINFO_STATE_RUNNING)
                return;
 
-       /* We want rotation but lack hardware to do it for us. */
-       if (!p->fbops->fb_rotate && p->var.rotate) {
-       }
-
-       vxres = p->var.xres_virtual;
-       vyres = p->var.yres_virtual;
-
-       if (!rect->width || !rect->height ||
-           rect->dx > vxres || rect->dy > vyres)
-               return;
-
-       /* We could use hardware clipping but on many cards you get around
-        * hardware clipping by writing to framebuffer directly. */
-
-       x2 = rect->dx + rect->width;
-       y2 = rect->dy + rect->height;
-       x2 = x2 < vxres ? x2 : vxres;
-       y2 = y2 < vyres ? y2 : vyres;
-       width = x2 - rect->dx;
-       height = y2 - rect->dy;
-
        if (p->fix.visual == FB_VISUAL_TRUECOLOR ||
            p->fix.visual == FB_VISUAL_DIRECTCOLOR )
                fg = ((u32 *) (p->pseudo_palette))[rect->color];
index 4c123abaa843166f43dd1ae93e77ef43fb4d1f8f..da664cea7ecac216072d5fda2aeaa05178a3e696 100644 (file)
@@ -272,33 +272,13 @@ void cfb_imageblit(struct fb_info *p, const struct fb_image *image)
 {
        u32 fgcolor, bgcolor, start_index, bitstart, pitch_index = 0;
        u32 bpl = sizeof(u32), bpp = p->var.bits_per_pixel;
-       u32 width = image->width, height = image->height; 
+       u32 width = image->width;
        u32 dx = image->dx, dy = image->dy;
-       int x2, y2, vxres, vyres;
        u8 __iomem *dst1;
 
        if (p->state != FBINFO_STATE_RUNNING)
                return;
 
-       vxres = p->var.xres_virtual;
-       vyres = p->var.yres_virtual;
-       /* 
-        * We could use hardware clipping but on many cards you get around
-        * hardware clipping by writing to framebuffer directly like we are
-        * doing here. 
-        */
-       if (image->dx > vxres || image->dy > vyres)
-               return;
-
-       x2 = image->dx + image->width;
-       y2 = image->dy + image->height;
-       dx = image->dx > 0 ? image->dx : 0;
-       dy = image->dy > 0 ? image->dy : 0;
-       x2 = x2 < vxres ? x2 : vxres;
-       y2 = y2 < vyres ? y2 : vyres;
-       width  = x2 - dx;
-       height = y2 - dy;
-
        bitstart = (dy * p->fix.line_length * 8) + (dx * bpp);
        start_index = bitstart & (32 - 1);
        pitch_index = (p->fix.line_length & (bpl - 1)) * 8;
index 18e60b941e214df0311eeeb227f191775881c2d6..030d4b13b1c206a5e0ff8ec61012b00d145d8923 100644 (file)
@@ -49,7 +49,6 @@ static struct fb_ops cg14_ops = {
        .fb_imageblit           = cfb_imageblit,
        .fb_mmap                = cg14_mmap,
        .fb_ioctl               = cg14_ioctl,
-       .fb_cursor              = soft_cursor,
 };
 
 #define CG14_MCR_INTENABLE_SHIFT       7
index 6e7d8d45dc68f4e81fb29f5c1740f6c95ae23aa2..b94eee8c42d5dbacba3f2ef509d58e60726cfa2a 100644 (file)
@@ -50,7 +50,6 @@ static struct fb_ops cg3_ops = {
        .fb_imageblit           = cfb_imageblit,
        .fb_mmap                = cg3_mmap,
        .fb_ioctl               = cg3_ioctl,
-       .fb_cursor              = soft_cursor,
 };
 
 
index 49a2545671d99f92d293e66a31deb12d5bfd9d0a..3280bb9560e26b2f1ddf9b79511ac1aac7643b84 100644 (file)
@@ -54,7 +54,6 @@ static struct fb_ops cg6_ops = {
        .fb_sync                = cg6_sync,
        .fb_mmap                = cg6_mmap,
        .fb_ioctl               = cg6_ioctl,
-       .fb_cursor              = soft_cursor,
 };
 
 /* Offset of interesting structures in the OBIO space */
index 4131243cfdf85e621263f547b7ebe6baf01985ca..bc061d4ec78695f70369f1276bb45b50cdd6f04f 100644 (file)
@@ -91,7 +91,6 @@ static struct fb_ops chipsfb_ops = {
        .fb_fillrect    = cfb_fillrect,
        .fb_copyarea    = cfb_copyarea,
        .fb_imageblit   = cfb_imageblit,
-       .fb_cursor      = soft_cursor,
 };
 
 static int chipsfb_check_var(struct fb_var_screeninfo *var,
index 3a26f9cc8585e796c9824bef75b7a10559d925d0..2858c5c8ba3c2fbca07c0cc4979f024d0853cd5a 100644 (file)
@@ -548,7 +548,6 @@ static struct fb_ops cirrusfb_ops = {
        .fb_fillrect    = cirrusfb_fillrect,
        .fb_copyarea    = cirrusfb_copyarea,
        .fb_imageblit   = cirrusfb_imageblit,
-       .fb_cursor      = soft_cursor,
 };
 
 /*--- Hardware Specific Routines -------------------------------------------*/
index 8692e002986b39206d566aea80827ff859f753a9..50b78af0fa2412d4c11e5901b391f3912db55306 100644 (file)
@@ -219,7 +219,6 @@ static struct fb_ops clps7111fb_ops = {
        .fb_fillrect    = cfb_fillrect,
        .fb_copyarea    = cfb_copyarea,
        .fb_imageblit   = cfb_imageblit,
-       .fb_cursor      = soft_cursor,
 };
 
 static int 
index 6a9ae2b3d1aba76a50a76554b5ab7ee81118e31e..fadf7c5d216e8dbae9c43c0a9eb8e91889e3dee6 100644 (file)
@@ -98,6 +98,8 @@ config FRAMEBUFFER_CONSOLE
        tristate "Framebuffer Console support"
        depends on FB
        select CRC32
+       help
+         Low-level framebuffer-based console driver.
 
 config STI_CONSOLE
         tristate "STI text console" 
@@ -203,5 +205,12 @@ config FONT_10x18
          big letters. It fits between the sun 12x22 and the normal 8x16 font.
          If other fonts are too big or too small for you, say Y, otherwise say N.
 
+config FONT_RL
+       bool "console Roman Large 8x16 font" if FONTS
+       depends on FRAMEBUFFER_CONSOLE
+       help
+         This is the visually-appealing "RL" console font that is
+         included with the kbd package.
+
 endmenu
 
index 42c7b8dcd22073397da5f89bdf94ddc62dc71204..5222628accce31ca8ea63ce844909dc2a286b64a 100644 (file)
@@ -15,6 +15,7 @@ font-objs-$(CONFIG_FONT_10x18)     += font_10x18.o
 font-objs-$(CONFIG_FONT_PEARL_8x8) += font_pearl_8x8.o
 font-objs-$(CONFIG_FONT_ACORN_8x8) += font_acorn_8x8.o
 font-objs-$(CONFIG_FONT_MINI_4x6)  += font_mini_4x6.o
+font-objs-$(CONFIG_FONT_RL)  += font_rl.o
 
 font-objs += $(font-objs-y)
 
@@ -26,7 +27,7 @@ obj-$(CONFIG_PROM_CONSOLE)        += promcon.o promcon_tbl.o
 obj-$(CONFIG_STI_CONSOLE)         += sticon.o sticore.o font.o
 obj-$(CONFIG_VGA_CONSOLE)         += vgacon.o
 obj-$(CONFIG_MDA_CONSOLE)         += mdacon.o
-obj-$(CONFIG_FRAMEBUFFER_CONSOLE) += fbcon.o bitblit.o font.o
+obj-$(CONFIG_FRAMEBUFFER_CONSOLE) += fbcon.o bitblit.o font.o softcursor.o
 ifeq ($(CONFIG_FB_TILEBLITTING),y)
 obj-$(CONFIG_FRAMEBUFFER_CONSOLE)     += tileblit.o
 endif
index 9f70e512b88bfe0ea54e09c236ec456f5fdc05ac..67857b3cfc8b416f4fe081e940c634ee85531681 100644 (file)
@@ -272,6 +272,7 @@ static void bit_cursor(struct vc_data *vc, struct fb_info *info,
        int w = (vc->vc_font.width + 7) >> 3, c;
        int y = real_y(p, vc->vc_y);
        int attribute, use_sw = (vc->vc_cursor_type & 0x10);
+       int err = 1;
        char *src;
 
        cursor.set = 0;
@@ -408,7 +409,11 @@ static void bit_cursor(struct vc_data *vc, struct fb_info *info,
        cursor.image.depth = 1;
        cursor.rop = ROP_XOR;
 
-       info->fbops->fb_cursor(info, &cursor);
+       if (info->fbops->fb_cursor)
+               err = info->fbops->fb_cursor(info, &cursor);
+
+       if (err)
+               soft_cursor(info, &cursor);
 
        ops->cursor_reset = 0;
 }
index 0fc8bb499c3facf6f75c9ea4259cf62eaf876a13..3cf1b61ff1f8a1dfbdedade08a89cee7381e0c22 100644 (file)
@@ -281,6 +281,18 @@ static inline int get_color(struct vc_data *vc, struct fb_info *info,
        return color;
 }
 
+static void fbcon_update_softback(struct vc_data *vc)
+{
+       int l = fbcon_softback_size / vc->vc_size_row;
+
+       if (l > 5)
+               softback_end = softback_buf + l * vc->vc_size_row;
+       else
+               /* Smaller scrollback makes no sense, and 0 would screw
+                  the operation totally */
+               softback_top = 0;
+}
+
 static void fb_flashcursor(void *private)
 {
        struct fb_info *info = private;
@@ -618,6 +630,15 @@ static int con2fb_release_oldinfo(struct vc_data *vc, struct fb_info *oldinfo,
                kfree(oldinfo->fbcon_par);
                oldinfo->fbcon_par = NULL;
                module_put(oldinfo->fbops->owner);
+               /*
+                 If oldinfo and newinfo are driving the same hardware,
+                 the fb_release() method of oldinfo may attempt to
+                 restore the hardware state.  This will leave the
+                 newinfo in an undefined state. Thus, a call to
+                 fb_set_par() may be needed for the newinfo.
+               */
+               if (newinfo->fbops->fb_set_par)
+                       newinfo->fbops->fb_set_par(newinfo);
        }
 
        return err;
@@ -1007,16 +1028,8 @@ static void fbcon_init(struct vc_data *vc, int init)
        if (logo)
                fbcon_prepare_logo(vc, info, cols, rows, new_cols, new_rows);
 
-       if (vc == svc && softback_buf) {
-               int l = fbcon_softback_size / vc->vc_size_row;
-               if (l > 5)
-                       softback_end = softback_buf + l * vc->vc_size_row;
-               else {
-                       /* Smaller scrollback makes no sense, and 0 would screw
-                          the operation totally */
-                       softback_top = 0;
-               }
-       }
+       if (vc == svc && softback_buf)
+               fbcon_update_softback(vc);
 }
 
 static void fbcon_deinit(struct vc_data *vc)
@@ -1223,18 +1236,8 @@ static void fbcon_set_disp(struct fb_info *info, struct fb_var_screeninfo *var,
        vc_resize(vc, cols, rows);
        if (CON_IS_VISIBLE(vc)) {
                update_screen(vc);
-               if (softback_buf) {
-                       int l = fbcon_softback_size / vc->vc_size_row;
-
-                       if (l > 5)
-                               softback_end = softback_buf + l *
-                                       vc->vc_size_row;
-                       else {
-                               /* Smaller scrollback makes no sense, and 0
-                                  would screw the operation totally */
-                               softback_top = 0;
-                       }
-               }
+               if (softback_buf)
+                       fbcon_update_softback(vc);
        }
 }
 
@@ -1892,24 +1895,11 @@ static int fbcon_resize(struct vc_data *vc, unsigned int width,
                mode = fb_find_best_mode(&var, &info->modelist);
                if (mode == NULL)
                        return -EINVAL;
+               display_to_var(&var, p);
                fb_videomode_to_var(&var, mode);
+
                if (width > var.xres/fw || height > var.yres/fh)
                        return -EINVAL;
-               /*
-                * The following can probably have any value... Do we need to
-                * set all of them?
-                */
-               var.bits_per_pixel = p->bits_per_pixel;
-               var.xres_virtual = p->xres_virtual;
-               var.yres_virtual = p->yres_virtual;
-               var.accel_flags = p->accel_flags;
-               var.width = p->width;
-               var.height = p->height;
-               var.red = p->red;
-               var.green = p->green;
-               var.blue = p->blue;
-               var.transp = p->transp;
-               var.nonstd = p->nonstd;
 
                DPRINTK("resize now %ix%i\n", var.xres, var.yres);
                if (CON_IS_VISIBLE(vc)) {
@@ -1933,19 +1923,11 @@ static int fbcon_switch(struct vc_data *vc)
        info = registered_fb[con2fb_map[vc->vc_num]];
 
        if (softback_top) {
-               int l = fbcon_softback_size / vc->vc_size_row;
                if (softback_lines)
                        fbcon_set_origin(vc);
                softback_top = softback_curr = softback_in = softback_buf;
                softback_lines = 0;
-
-               if (l > 5)
-                       softback_end = softback_buf + l * vc->vc_size_row;
-               else {
-                       /* Smaller scrollback makes no sense, and 0 would screw
-                          the operation totally */
-                       softback_top = 0;
-               }
+               fbcon_update_softback(vc);
        }
 
        if (logo_shown >= 0) {
@@ -2235,17 +2217,8 @@ static int fbcon_do_set_font(struct vc_data *vc, int w, int h,
                /* reset wrap/pan */
                info->var.xoffset = info->var.yoffset = p->yscroll = 0;
                vc_resize(vc, info->var.xres / w, info->var.yres / h);
-               if (CON_IS_VISIBLE(vc) && softback_buf) {
-                       int l = fbcon_softback_size / vc->vc_size_row;
-                       if (l > 5)
-                               softback_end =
-                                   softback_buf + l * vc->vc_size_row;
-                       else {
-                               /* Smaller scrollback makes no sense, and 0 would screw
-                                  the operation totally */
-                               softback_top = 0;
-                       }
-               }
+               if (CON_IS_VISIBLE(vc) && softback_buf)
+                       fbcon_update_softback(vc);
        } else if (CON_IS_VISIBLE(vc)
                   && vc->vc_mode == KD_TEXT) {
                fbcon_clear_margins(vc, 0);
@@ -2615,16 +2588,8 @@ static void fbcon_modechanged(struct fb_info *info)
                update_var(vc->vc_num, info);
                fbcon_set_palette(vc, color_table);
                update_screen(vc);
-               if (softback_buf) {
-                       int l = fbcon_softback_size / vc->vc_size_row;
-                       if (l > 5)
-                               softback_end = softback_buf + l * vc->vc_size_row;
-                       else {
-                               /* Smaller scrollback makes no sense, and 0
-                                  would screw the operation totally */
-                               softback_top = 0;
-                       }
-               }
+               if (softback_buf)
+                       fbcon_update_softback(vc);
        }
 }
 
@@ -2659,16 +2624,8 @@ static void fbcon_set_all_vcs(struct fb_info *info)
                        update_var(vc->vc_num, info);
                        fbcon_set_palette(vc, color_table);
                        update_screen(vc);
-                       if (softback_buf) {
-                               int l = fbcon_softback_size / vc->vc_size_row;
-                               if (l > 5)
-                                       softback_end = softback_buf + l * vc->vc_size_row;
-                               else {
-                                       /* Smaller scrollback makes no sense, and 0
-                                          would screw the operation totally */
-                                       softback_top = 0;
-                               }
-                       }
+                       if (softback_buf)
+                               fbcon_update_softback(vc);
                }
        }
 }
@@ -2758,7 +2715,8 @@ static void fbcon_new_modelist(struct fb_info *info)
                        continue;
                vc = vc_cons[i].d;
                display_to_var(&var, &fb_display[i]);
-               mode = fb_find_nearest_mode(&var, &info->modelist);
+               mode = fb_find_nearest_mode(fb_display[i].mode,
+                                           &info->modelist);
                fb_videomode_to_var(&var, mode);
 
                if (vc)
index 0738cd62def219f743c34b93586efeb9e033596d..b68e0e2c2d1657c1c4c5e1aabd2b26591404bc02 100644 (file)
@@ -167,5 +167,5 @@ extern void fbcon_set_tileops(struct vc_data *vc, struct fb_info *info,
                              struct display *p, struct fbcon_ops *ops);
 #endif
 extern void fbcon_set_bitops(struct fbcon_ops *ops);
-
+extern int  soft_cursor(struct fb_info *info, struct fb_cursor *cursor);
 #endif /* _VIDEO_FBCON_H */
diff --git a/drivers/video/console/font_rl.c b/drivers/video/console/font_rl.c
new file mode 100644 (file)
index 0000000..dfecc27
--- /dev/null
@@ -0,0 +1,4374 @@
+
+/* This font is simply the "rl.fnt" console font from the kbd utility.
+ * Converted by Zack T Smith, fbui@comcast.net.
+ * The original binary file is covered under the GNU Public License.
+ */
+
+#include <linux/font.h>
+
+#define FONTDATAMAX 4096
+
+static unsigned char patterns[4096] = {
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x3c,
+0x42,
+0x81,
+0xe7,
+0xa5,
+0x99,
+0x81,
+0x81,
+0x99,
+0x42,
+0x3c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x3c,
+0x7e,
+0xff,
+0x99,
+0xdb,
+0xe7,
+0xff,
+0xff,
+0xe7,
+0x7e,
+0x3c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x6c,
+0xfe,
+0xfe,
+0xfe,
+0xfe,
+0xfe,
+0x7c,
+0x38,
+0x10,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x10,
+0x38,
+0x7c,
+0xfe,
+0x7c,
+0x38,
+0x10,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x38,
+0x38,
+0x10,
+0xd6,
+0xfe,
+0xd6,
+0x10,
+0x10,
+0x38,
+0x7c,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x10,
+0x38,
+0x7c,
+0xfe,
+0xfe,
+0x54,
+0x10,
+0x10,
+0x38,
+0x7c,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x18,
+0x3c,
+0x3c,
+0x18,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xe7,
+0xc3,
+0xc3,
+0xe7,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x3c,
+0x66,
+0x42,
+0x42,
+0x66,
+0x3c,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xc3,
+0x99,
+0xbd,
+0xbd,
+0x99,
+0xc3,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+
+0x00,
+0x00,
+0x0f,
+0x07,
+0x0d,
+0x18,
+0x78,
+0xcc,
+0xcc,
+0xcc,
+0xcc,
+0x78,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x3c,
+0x66,
+0x66,
+0x66,
+0x3c,
+0x18,
+0x7e,
+0x18,
+0x18,
+0x18,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x08,
+0x0c,
+0x0a,
+0x0a,
+0x0a,
+0x08,
+0x08,
+0x08,
+0x38,
+0x78,
+0x30,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x10,
+0x18,
+0x1c,
+0x1e,
+0x1e,
+0x16,
+0x12,
+0x72,
+0xf2,
+0x62,
+0x0e,
+0x1e,
+0x0c,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x10,
+0x92,
+0x54,
+0x38,
+0xfe,
+0x38,
+0x54,
+0x92,
+0x10,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x80,
+0xc0,
+0xe0,
+0xb8,
+0x8e,
+0xb8,
+0xe0,
+0xc0,
+0x80,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x02,
+0x06,
+0x0e,
+0x3a,
+0xe2,
+0x3a,
+0x0e,
+0x06,
+0x02,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x10,
+0x38,
+0x7c,
+0xd6,
+0x10,
+0x10,
+0x10,
+0x10,
+0xd6,
+0x7c,
+0x38,
+0x10,
+0x00,
+0x00,
+
+0x00,
+0x42,
+0xe7,
+0xe7,
+0xe7,
+0xe7,
+0x42,
+0x42,
+0x42,
+0x00,
+0x66,
+0x66,
+0x66,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x7f,
+0xca,
+0xca,
+0xca,
+0xca,
+0x7a,
+0x0a,
+0x0a,
+0x0a,
+0x0a,
+0x0a,
+0x1b,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x1e,
+0x31,
+0x78,
+0xcc,
+0xc6,
+0xc3,
+0x63,
+0x33,
+0x1e,
+0x8c,
+0x78,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0xfe,
+0xfe,
+0xfe,
+0xfe,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x10,
+0x38,
+0x7c,
+0xd6,
+0x10,
+0x10,
+0x10,
+0x10,
+0xd6,
+0x7c,
+0x38,
+0x10,
+0xfe,
+0x00,
+
+0x00,
+0x00,
+0x10,
+0x38,
+0x7c,
+0xd6,
+0x10,
+0x10,
+0x10,
+0x10,
+0x10,
+0x10,
+0x10,
+0x10,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x10,
+0x10,
+0x10,
+0x10,
+0x10,
+0x10,
+0x10,
+0x10,
+0xd6,
+0x7c,
+0x38,
+0x10,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x08,
+0x0c,
+0x06,
+0xff,
+0x06,
+0x0c,
+0x08,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x10,
+0x30,
+0x60,
+0xff,
+0x60,
+0x30,
+0x10,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x22,
+0x44,
+0x88,
+0xcc,
+0xee,
+0x44,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x24,
+0x42,
+0xff,
+0x42,
+0x24,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x10,
+0x38,
+0x38,
+0x6c,
+0x6c,
+0xc6,
+0xfe,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0xfe,
+0xc6,
+0x6c,
+0x6c,
+0x38,
+0x38,
+0x10,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x18,
+0x3c,
+0x3c,
+0x3c,
+0x3c,
+0x18,
+0x18,
+0x18,
+0x10,
+0x00,
+0x18,
+0x18,
+0x00,
+0x00,
+0x00,
+
+0x22,
+0x77,
+0x33,
+0x11,
+0x22,
+0x44,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x12,
+0x12,
+0x12,
+0x7f,
+0x24,
+0x24,
+0x24,
+0xfe,
+0x48,
+0x48,
+0x48,
+0x00,
+0x00,
+0x00,
+
+0x10,
+0x10,
+0x7c,
+0xd2,
+0xd0,
+0xd0,
+0xd0,
+0x7c,
+0x16,
+0x16,
+0x16,
+0x96,
+0x7c,
+0x10,
+0x10,
+0x00,
+
+0x00,
+0x42,
+0xbe,
+0x44,
+0x0c,
+0x08,
+0x18,
+0x10,
+0x30,
+0x20,
+0x64,
+0x4a,
+0xc4,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x38,
+0x6c,
+0x6c,
+0x6c,
+0x38,
+0x37,
+0x72,
+0xdc,
+0xcc,
+0xcc,
+0xcc,
+0x77,
+0x00,
+0x00,
+0x00,
+
+0x10,
+0x38,
+0x18,
+0x08,
+0x10,
+0x20,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x04,
+0x08,
+0x10,
+0x10,
+0x30,
+0x30,
+0x30,
+0x30,
+0x30,
+0x10,
+0x10,
+0x08,
+0x04,
+0x00,
+0x00,
+
+0x00,
+0x20,
+0x10,
+0x08,
+0x08,
+0x0c,
+0x0c,
+0x0c,
+0x0c,
+0x0c,
+0x08,
+0x08,
+0x10,
+0x20,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x44,
+0x28,
+0x38,
+0xfe,
+0x38,
+0x28,
+0x44,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x18,
+0x18,
+0x7e,
+0x18,
+0x18,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x10,
+0x38,
+0x18,
+0x08,
+0x10,
+0x20,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x7e,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x10,
+0x38,
+0x10,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x06,
+0x06,
+0x0c,
+0x0c,
+0x18,
+0x18,
+0x30,
+0x30,
+0x60,
+0x60,
+0xc0,
+0xc0,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x3c,
+0x46,
+0xc6,
+0xc6,
+0xc6,
+0xc6,
+0xc6,
+0xc4,
+0x78,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x08,
+0x18,
+0x78,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x7e,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x7c,
+0x86,
+0x06,
+0x0c,
+0x18,
+0x20,
+0x40,
+0xc1,
+0xfe,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x3c,
+0x46,
+0x04,
+0x08,
+0x1c,
+0x06,
+0x06,
+0x06,
+0x06,
+0x0c,
+0x70,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x04,
+0x08,
+0x10,
+0x2c,
+0x4c,
+0x8c,
+0x8c,
+0xfe,
+0x0c,
+0x0c,
+0x0c,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x02,
+0x3c,
+0x20,
+0x20,
+0x70,
+0x0c,
+0x06,
+0x06,
+0x06,
+0x06,
+0x0c,
+0x70,
+0x00,
+
+0x00,
+0x00,
+0x18,
+0x20,
+0x40,
+0xc0,
+0xdc,
+0xc6,
+0xc6,
+0xc6,
+0xc6,
+0x44,
+0x38,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x40,
+0x7e,
+0x82,
+0x06,
+0x04,
+0x0c,
+0x18,
+0x18,
+0x30,
+0x30,
+0x30,
+0x30,
+0x00,
+
+0x00,
+0x00,
+0x7c,
+0xc6,
+0xc6,
+0x64,
+0x38,
+0x4c,
+0xc6,
+0xc6,
+0xc6,
+0xc6,
+0x7c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x38,
+0x44,
+0xc6,
+0xc6,
+0x76,
+0x06,
+0x06,
+0x06,
+0x04,
+0x08,
+0x30,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x10,
+0x38,
+0x10,
+0x00,
+0x00,
+0x00,
+0x10,
+0x38,
+0x10,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x10,
+0x38,
+0x10,
+0x00,
+0x00,
+0x00,
+0x10,
+0x38,
+0x18,
+0x08,
+0x10,
+0x20,
+
+0x00,
+0x06,
+0x0c,
+0x18,
+0x30,
+0x60,
+0xa0,
+0xa0,
+0x60,
+0x30,
+0x18,
+0x0c,
+0x06,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x7e,
+0x00,
+0x00,
+0x7e,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x60,
+0x30,
+0x18,
+0x0c,
+0x06,
+0x05,
+0x05,
+0x06,
+0x0c,
+0x18,
+0x30,
+0x60,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x7c,
+0x86,
+0xc6,
+0x06,
+0x04,
+0x08,
+0x10,
+0x10,
+0x18,
+0x00,
+0x18,
+0x18,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x3c,
+0x46,
+0xc6,
+0xce,
+0xd6,
+0xd6,
+0xd6,
+0xdc,
+0xc0,
+0xc4,
+0x78,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x18,
+0x18,
+0x18,
+0x3c,
+0x2c,
+0x2c,
+0x2c,
+0x7e,
+0x46,
+0x46,
+0x46,
+0xef,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0xfc,
+0x66,
+0x66,
+0x66,
+0x66,
+0x7c,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0xfc,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x3a,
+0x66,
+0xc2,
+0xc0,
+0xc0,
+0xc0,
+0xc0,
+0xc0,
+0xc0,
+0xc0,
+0x62,
+0x3c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0xfc,
+0x66,
+0x63,
+0x63,
+0x63,
+0x63,
+0x63,
+0x63,
+0x63,
+0x63,
+0x66,
+0xfc,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0xff,
+0x61,
+0x60,
+0x60,
+0x64,
+0x7c,
+0x64,
+0x60,
+0x60,
+0x60,
+0x61,
+0xfe,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0xff,
+0x61,
+0x61,
+0x60,
+0x64,
+0x7c,
+0x64,
+0x60,
+0x60,
+0x60,
+0x60,
+0xf0,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x3a,
+0x66,
+0xc2,
+0xc0,
+0xc0,
+0xc0,
+0xcf,
+0xc6,
+0xc6,
+0xc6,
+0x66,
+0x38,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0xf7,
+0x62,
+0x62,
+0x62,
+0x62,
+0x7e,
+0x62,
+0x62,
+0x62,
+0x62,
+0x62,
+0xf7,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x3c,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x3c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x1e,
+0x0c,
+0x0c,
+0x0c,
+0x0c,
+0x0c,
+0x0c,
+0x0c,
+0x0c,
+0x0c,
+0x0c,
+0x0c,
+0x0c,
+0x08,
+0xf0,
+
+0x00,
+0xf7,
+0x64,
+0x6c,
+0x68,
+0x68,
+0x78,
+0x6c,
+0x6c,
+0x6c,
+0x66,
+0x66,
+0xf7,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0xf8,
+0x60,
+0x60,
+0x60,
+0x60,
+0x60,
+0x60,
+0x60,
+0x60,
+0x60,
+0x61,
+0xfe,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0xc3,
+0x66,
+0x76,
+0x7e,
+0x56,
+0x56,
+0x46,
+0x46,
+0x46,
+0x46,
+0x46,
+0xef,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0xe7,
+0x62,
+0x62,
+0x72,
+0x52,
+0x5a,
+0x4a,
+0x4e,
+0x46,
+0x46,
+0x42,
+0xe2,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x3c,
+0x66,
+0xc3,
+0xc3,
+0xc3,
+0xc3,
+0xc3,
+0xc3,
+0xc3,
+0xc3,
+0x66,
+0x3c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0xfc,
+0x66,
+0x66,
+0x66,
+0x66,
+0x6c,
+0x60,
+0x60,
+0x60,
+0x60,
+0x60,
+0xf0,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x3c,
+0x66,
+0xc3,
+0xc3,
+0xc3,
+0xc3,
+0xc3,
+0xc3,
+0xc3,
+0xc3,
+0x66,
+0x3c,
+0x10,
+0x39,
+0x0e,
+
+0x00,
+0xfc,
+0x66,
+0x66,
+0x66,
+0x66,
+0x7c,
+0x6c,
+0x66,
+0x66,
+0x66,
+0x66,
+0xf3,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x7a,
+0xc6,
+0xc2,
+0xc0,
+0x70,
+0x3c,
+0x0e,
+0x06,
+0x06,
+0x86,
+0xc6,
+0xbc,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0xff,
+0x99,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x3c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0xf7,
+0x62,
+0x62,
+0x62,
+0x62,
+0x62,
+0x62,
+0x62,
+0x62,
+0x62,
+0x62,
+0x3c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0xf7,
+0x62,
+0x62,
+0x62,
+0x76,
+0x34,
+0x34,
+0x34,
+0x3c,
+0x18,
+0x18,
+0x18,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0xf7,
+0x62,
+0x62,
+0x62,
+0x62,
+0x6a,
+0x6a,
+0x6a,
+0x6a,
+0x7e,
+0x7e,
+0x34,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0xf7,
+0x62,
+0x62,
+0x34,
+0x34,
+0x18,
+0x18,
+0x2c,
+0x2c,
+0x46,
+0x46,
+0xef,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0xf7,
+0x62,
+0x62,
+0x62,
+0x34,
+0x34,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x3c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x7f,
+0x46,
+0x86,
+0x0c,
+0x0c,
+0x18,
+0x18,
+0x30,
+0x30,
+0x61,
+0x62,
+0xfe,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x3c,
+0x30,
+0x30,
+0x30,
+0x30,
+0x30,
+0x30,
+0x30,
+0x30,
+0x30,
+0x30,
+0x3c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0xc0,
+0xc0,
+0x60,
+0x60,
+0x30,
+0x30,
+0x18,
+0x18,
+0x0c,
+0x0c,
+0x06,
+0x06,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x3c,
+0x0c,
+0x0c,
+0x0c,
+0x0c,
+0x0c,
+0x0c,
+0x0c,
+0x0c,
+0x0c,
+0x0c,
+0x3c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x10,
+0x38,
+0x4c,
+0x86,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0xff,
+0x00,
+0x00,
+
+0x00,
+0x18,
+0x20,
+0x30,
+0x38,
+0x10,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x78,
+0x8c,
+0x0c,
+0x3c,
+0xcc,
+0xcc,
+0xcd,
+0x76,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x20,
+0xe0,
+0x60,
+0x60,
+0x6c,
+0x76,
+0x66,
+0x66,
+0x66,
+0x66,
+0x76,
+0x6c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x3c,
+0x66,
+0x60,
+0x60,
+0x60,
+0x60,
+0x62,
+0x3c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x04,
+0x1c,
+0x0c,
+0x0c,
+0x6c,
+0xdc,
+0xcc,
+0xcc,
+0xcc,
+0xcc,
+0xdc,
+0x66,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x3c,
+0x66,
+0x7e,
+0x60,
+0x60,
+0x60,
+0x62,
+0x3c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x1e,
+0x31,
+0x33,
+0x30,
+0x30,
+0x78,
+0x30,
+0x30,
+0x30,
+0x30,
+0x30,
+0x78,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x7b,
+0xce,
+0xcc,
+0xcc,
+0xcc,
+0x78,
+0x60,
+0x7c,
+0x86,
+0xc6,
+0x7c,
+
+0x00,
+0x20,
+0xe0,
+0x60,
+0x60,
+0x6c,
+0x76,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0xf7,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x10,
+0x38,
+0x10,
+0x00,
+0x18,
+0x38,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x3c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x08,
+0x1c,
+0x08,
+0x00,
+0x0c,
+0x1c,
+0x0c,
+0x0c,
+0x0c,
+0x0c,
+0x0c,
+0x6c,
+0x4c,
+0x38,
+0x00,
+
+0x00,
+0x20,
+0xe0,
+0x60,
+0x60,
+0x67,
+0x66,
+0x6c,
+0x78,
+0x6c,
+0x6c,
+0x66,
+0xe7,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x08,
+0x38,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x3c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x6a,
+0xfe,
+0x6a,
+0x6a,
+0x6a,
+0x62,
+0x62,
+0xf7,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x5c,
+0xf6,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0xf7,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x3c,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x3c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x5c,
+0xe6,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x7c,
+0x60,
+0x60,
+0xf0,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x76,
+0xcc,
+0xcc,
+0xcc,
+0xcc,
+0xcc,
+0xcc,
+0x7c,
+0x0c,
+0x0c,
+0x1e,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x5e,
+0xf6,
+0x60,
+0x60,
+0x60,
+0x60,
+0x60,
+0xf0,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x7a,
+0xc6,
+0x72,
+0x1c,
+0x06,
+0x86,
+0xc6,
+0xbc,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x10,
+0x30,
+0x7c,
+0x30,
+0x30,
+0x30,
+0x30,
+0x30,
+0x34,
+0x18,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0xee,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x67,
+0x3a,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0xf7,
+0x62,
+0x76,
+0x34,
+0x34,
+0x3c,
+0x18,
+0x18,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0xf7,
+0x62,
+0x6a,
+0x6a,
+0x6a,
+0x6a,
+0x7e,
+0x24,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0xf7,
+0x62,
+0x34,
+0x18,
+0x2c,
+0x46,
+0x46,
+0xef,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0xf7,
+0x62,
+0x62,
+0x34,
+0x34,
+0x18,
+0x18,
+0x18,
+0x10,
+0xb0,
+0xe0,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0xfe,
+0x8c,
+0x18,
+0x30,
+0x30,
+0x60,
+0xc2,
+0xfe,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x0e,
+0x18,
+0x10,
+0x10,
+0x08,
+0x70,
+0x70,
+0x08,
+0x10,
+0x10,
+0x18,
+0x0e,
+0x00,
+0x00,
+0x00,
+
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x00,
+0x00,
+
+0x00,
+0x70,
+0x18,
+0x08,
+0x08,
+0x10,
+0x0e,
+0x0e,
+0x10,
+0x08,
+0x08,
+0x18,
+0x70,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x76,
+0xdc,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x10,
+0x38,
+0x6c,
+0xc6,
+0xc6,
+0xc6,
+0xfe,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x3a,
+0x66,
+0xc2,
+0xc0,
+0xc0,
+0xc0,
+0xc0,
+0xc0,
+0x62,
+0x3c,
+0x18,
+0x0c,
+0x24,
+0x18,
+
+0x00,
+0x00,
+0x66,
+0x00,
+0x00,
+0xee,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x3b,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x0c,
+0x18,
+0x20,
+0x00,
+0x3c,
+0x66,
+0x7e,
+0x60,
+0x60,
+0x60,
+0x62,
+0x3c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x30,
+0x58,
+0x8c,
+0x00,
+0x78,
+0x8c,
+0x0c,
+0x3c,
+0xcc,
+0xcc,
+0xcd,
+0x76,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x66,
+0x00,
+0x00,
+0x78,
+0x8c,
+0x0c,
+0x3c,
+0xcc,
+0xcc,
+0xcd,
+0x76,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x30,
+0x18,
+0x04,
+0x00,
+0x78,
+0x8c,
+0x0c,
+0x3c,
+0xcc,
+0xcc,
+0xcd,
+0x76,
+0x00,
+0x00,
+0x00,
+
+0x38,
+0x44,
+0x44,
+0x38,
+0x00,
+0x78,
+0x8c,
+0x0c,
+0x3c,
+0xcc,
+0xcc,
+0xcd,
+0x76,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x3c,
+0x66,
+0x60,
+0x60,
+0x60,
+0x60,
+0x62,
+0x3c,
+0x08,
+0x24,
+0x18,
+
+0x00,
+0x18,
+0x2c,
+0x46,
+0x00,
+0x3c,
+0x66,
+0x7e,
+0x60,
+0x60,
+0x60,
+0x62,
+0x3c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x66,
+0x00,
+0x00,
+0x3c,
+0x66,
+0x7e,
+0x60,
+0x60,
+0x60,
+0x62,
+0x3c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x30,
+0x18,
+0x04,
+0x00,
+0x3c,
+0x66,
+0x7e,
+0x60,
+0x60,
+0x60,
+0x62,
+0x3c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x66,
+0x00,
+0x00,
+0x38,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x3c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x18,
+0x2c,
+0x46,
+0x00,
+0x38,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x3c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x60,
+0x30,
+0x08,
+0x00,
+0x38,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x3c,
+0x00,
+0x00,
+0x00,
+
+0x66,
+0x18,
+0x18,
+0x18,
+0x3c,
+0x2c,
+0x2c,
+0x2c,
+0x7e,
+0x46,
+0x46,
+0x46,
+0xef,
+0x00,
+0x00,
+0x00,
+
+0x18,
+0x24,
+0x18,
+0x18,
+0x3c,
+0x2c,
+0x2c,
+0x2c,
+0x7e,
+0x46,
+0x46,
+0x46,
+0xef,
+0x00,
+0x00,
+0x00,
+
+0x0c,
+0x18,
+0xff,
+0x61,
+0x60,
+0x60,
+0x64,
+0x7c,
+0x64,
+0x60,
+0x60,
+0x61,
+0xfe,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x76,
+0x9b,
+0x1b,
+0x3f,
+0xd8,
+0xd8,
+0xd9,
+0x6e,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x1f,
+0x1d,
+0x1d,
+0x3c,
+0x2c,
+0x2e,
+0x2c,
+0x7c,
+0x4c,
+0x4c,
+0x4d,
+0xef,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x18,
+0x2c,
+0x46,
+0x00,
+0x3c,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x3c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x66,
+0x00,
+0x00,
+0x3c,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x3c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x30,
+0x18,
+0x04,
+0x00,
+0x3c,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x3c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x18,
+0x2c,
+0x46,
+0x00,
+0xee,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x67,
+0x3a,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x30,
+0x18,
+0x04,
+0x00,
+0xee,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x67,
+0x3a,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x66,
+0x00,
+0x00,
+0xf7,
+0x62,
+0x62,
+0x34,
+0x34,
+0x18,
+0x18,
+0x18,
+0x10,
+0xb0,
+0xe0,
+
+0x66,
+0x00,
+0x3c,
+0x66,
+0xc3,
+0xc3,
+0xc3,
+0xc3,
+0xc3,
+0xc3,
+0xc3,
+0x66,
+0x3c,
+0x00,
+0x00,
+0x00,
+
+0x66,
+0x00,
+0xf7,
+0x62,
+0x62,
+0x62,
+0x62,
+0x62,
+0x62,
+0x62,
+0x62,
+0x62,
+0x3c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x10,
+0x10,
+0x10,
+0x7c,
+0xc6,
+0xc0,
+0xc0,
+0xc0,
+0xc0,
+0xc2,
+0x7c,
+0x10,
+0x10,
+0x00,
+
+0x00,
+0x38,
+0x64,
+0x6c,
+0x60,
+0x60,
+0xf0,
+0x60,
+0x60,
+0x60,
+0x60,
+0x66,
+0xfc,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x81,
+0xc3,
+0x66,
+0x3c,
+0x18,
+0xff,
+0x18,
+0x18,
+0xff,
+0x18,
+0x18,
+0x18,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0xfe,
+0x63,
+0x63,
+0x63,
+0x63,
+0x6e,
+0x60,
+0x64,
+0x6e,
+0x64,
+0x64,
+0xf5,
+0x06,
+0x00,
+0x00,
+
+0x00,
+0x0e,
+0x19,
+0x1b,
+0x18,
+0x18,
+0x3c,
+0x18,
+0x18,
+0x18,
+0x18,
+0xd8,
+0x98,
+0x70,
+0x00,
+0x00,
+
+0x00,
+0x0c,
+0x18,
+0x20,
+0x00,
+0x78,
+0x8c,
+0x0c,
+0x3c,
+0xcc,
+0xcc,
+0xcd,
+0x76,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x06,
+0x0c,
+0x10,
+0x00,
+0x38,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x3c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x0c,
+0x18,
+0x20,
+0x00,
+0x3c,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x3c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x0c,
+0x18,
+0x20,
+0x00,
+0xee,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x67,
+0x3a,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x32,
+0x4c,
+0x00,
+0x5c,
+0xf6,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0xf7,
+0x00,
+0x00,
+0x00,
+
+0x32,
+0x4c,
+0x00,
+0xe7,
+0x72,
+0x52,
+0x5a,
+0x4a,
+0x4e,
+0x46,
+0x46,
+0x42,
+0xe2,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x78,
+0x8c,
+0x0c,
+0x3c,
+0xcc,
+0xcc,
+0xcd,
+0x76,
+0x00,
+0xfe,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x3c,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x3c,
+0x00,
+0x7e,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x30,
+0x30,
+0x00,
+0x30,
+0x10,
+0x10,
+0x20,
+0x40,
+0xc0,
+0xc6,
+0xc2,
+0x7c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0xfe,
+0xc0,
+0xc0,
+0xc0,
+0xc0,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0xfe,
+0x06,
+0x06,
+0x06,
+0x06,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x20,
+0xe0,
+0x63,
+0x66,
+0xfc,
+0x18,
+0x30,
+0x60,
+0xce,
+0x93,
+0x06,
+0x0c,
+0x1f,
+0x00,
+0x00,
+
+0x00,
+0x20,
+0xe0,
+0x63,
+0x66,
+0xfc,
+0x18,
+0x30,
+0x64,
+0xc8,
+0x96,
+0x3f,
+0x06,
+0x06,
+0x00,
+0x00,
+
+0x00,
+0x18,
+0x18,
+0x00,
+0x08,
+0x18,
+0x18,
+0x18,
+0x3c,
+0x3c,
+0x3c,
+0x3c,
+0x18,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x36,
+0x6c,
+0xd8,
+0xd8,
+0x6c,
+0x36,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0xd8,
+0x6c,
+0x36,
+0x36,
+0x6c,
+0xd8,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x82,
+0x10,
+0x82,
+0x10,
+0x82,
+0x10,
+0x82,
+0x10,
+0x82,
+0x10,
+0x82,
+0x10,
+0x82,
+0x10,
+0x82,
+0x10,
+
+0x00,
+0x95,
+0x00,
+0xa9,
+0x00,
+0x95,
+0x00,
+0xa9,
+0x00,
+0x95,
+0x00,
+0xa9,
+0x00,
+0x95,
+0x00,
+0xa9,
+
+0x92,
+0x49,
+0x92,
+0x49,
+0x92,
+0x49,
+0x92,
+0x49,
+0x92,
+0x49,
+0x92,
+0x49,
+0x92,
+0x49,
+0x92,
+0x49,
+
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0xf8,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0xf8,
+0x18,
+0x18,
+0xf8,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0xe6,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0xfe,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0xf8,
+0x18,
+0x18,
+0xf8,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0xe6,
+0x06,
+0x06,
+0xe6,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0xfe,
+0x06,
+0x06,
+0xe6,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0xe6,
+0x06,
+0x06,
+0xfe,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0xfe,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0xf8,
+0x18,
+0x18,
+0xf8,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0xf8,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x1f,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0xff,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0xff,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x1f,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0xff,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0xff,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x1f,
+0x18,
+0x18,
+0x1f,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x67,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x67,
+0x60,
+0x60,
+0x7f,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x7f,
+0x60,
+0x60,
+0x67,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0xe7,
+0x00,
+0x00,
+0xff,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0xff,
+0x00,
+0x00,
+0xe7,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x67,
+0x60,
+0x60,
+0x67,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0xff,
+0x00,
+0x00,
+0xff,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0xe7,
+0x00,
+0x00,
+0xe7,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0xff,
+0x00,
+0x00,
+0xff,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0xff,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0xff,
+0x00,
+0x00,
+0xff,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0xff,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x7f,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x1f,
+0x18,
+0x18,
+0x1f,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x1f,
+0x18,
+0x18,
+0x1f,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x7f,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0xff,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0xff,
+0x00,
+0x00,
+0xff,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0xf8,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x1f,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+
+0xf0,
+0xf0,
+0xf0,
+0xf0,
+0xf0,
+0xf0,
+0xf0,
+0xf0,
+0xf0,
+0xf0,
+0xf0,
+0xf0,
+0xf0,
+0xf0,
+0xf0,
+0xf0,
+
+0x0f,
+0x0f,
+0x0f,
+0x0f,
+0x0f,
+0x0f,
+0x0f,
+0x0f,
+0x0f,
+0x0f,
+0x0f,
+0x0f,
+0x0f,
+0x0f,
+0x0f,
+0x0f,
+
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x77,
+0xcc,
+0xcc,
+0xcc,
+0xcc,
+0xde,
+0x73,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x7c,
+0xc6,
+0xc6,
+0xc6,
+0xc4,
+0xc8,
+0xc4,
+0xc6,
+0xc6,
+0xc6,
+0xc6,
+0xdc,
+0xc0,
+0xc0,
+0x00,
+
+0x00,
+0xff,
+0x61,
+0x60,
+0x60,
+0x60,
+0x60,
+0x60,
+0x60,
+0x60,
+0x60,
+0x60,
+0xf0,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x01,
+0x7e,
+0xa4,
+0x24,
+0x2c,
+0x6c,
+0x6c,
+0x6c,
+0x48,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0xff,
+0xc1,
+0x60,
+0x30,
+0x18,
+0x0c,
+0x18,
+0x30,
+0x60,
+0xc0,
+0xc1,
+0xfe,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x7f,
+0xc8,
+0xc8,
+0xc8,
+0xc8,
+0xc8,
+0xc8,
+0x70,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x22,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x7c,
+0x60,
+0x60,
+0x60,
+0xc0,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x76,
+0xdc,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x10,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x38,
+0x10,
+0x7c,
+0xd6,
+0xd6,
+0xd6,
+0xd6,
+0xd6,
+0xd6,
+0x7c,
+0x10,
+0x38,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x38,
+0x6c,
+0xc6,
+0xc6,
+0xc6,
+0xfe,
+0xc6,
+0xc6,
+0xc6,
+0xc6,
+0x6c,
+0x38,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x3c,
+0x66,
+0xc3,
+0xc3,
+0xc3,
+0xc3,
+0xc3,
+0x66,
+0x24,
+0x24,
+0xa5,
+0xe7,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x1e,
+0x31,
+0x30,
+0x18,
+0x0c,
+0x3e,
+0x66,
+0x66,
+0x66,
+0x66,
+0x66,
+0x3c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x6e,
+0xff,
+0x99,
+0x99,
+0x99,
+0x99,
+0xff,
+0x76,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x02,
+0x04,
+0x7c,
+0xca,
+0x92,
+0xa6,
+0x7c,
+0x40,
+0x80,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x1c,
+0x30,
+0x60,
+0x60,
+0x60,
+0x7c,
+0x60,
+0x60,
+0x60,
+0x60,
+0x30,
+0x1c,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x7c,
+0xc6,
+0xc6,
+0xc6,
+0xc6,
+0xc6,
+0xc6,
+0xc6,
+0xc6,
+0xc6,
+0xc6,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0xfe,
+0x00,
+0x00,
+0x00,
+0x7c,
+0x00,
+0x00,
+0x00,
+0xfe,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x18,
+0x18,
+0x7e,
+0x18,
+0x18,
+0x00,
+0x00,
+0x7e,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x30,
+0x18,
+0x0c,
+0x06,
+0x0c,
+0x18,
+0x30,
+0x00,
+0x7e,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x0c,
+0x18,
+0x30,
+0x60,
+0x30,
+0x18,
+0x0c,
+0x00,
+0x7e,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x0e,
+0x19,
+0x1b,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0x18,
+0xd8,
+0x98,
+0x70,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x18,
+0x18,
+0x00,
+0x7e,
+0x00,
+0x18,
+0x18,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x76,
+0xdc,
+0x00,
+0x00,
+0x76,
+0xdc,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x38,
+0x44,
+0x44,
+0x44,
+0x38,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x18,
+0x18,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x18,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x07,
+0x06,
+0x06,
+0x0c,
+0x0c,
+0x08,
+0x98,
+0xd0,
+0xf0,
+0x60,
+0x20,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0xcc,
+0x76,
+0x66,
+0x66,
+0x66,
+0x66,
+0xf7,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x70,
+0x98,
+0x18,
+0x30,
+0x60,
+0x88,
+0xf8,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x7c,
+0x64,
+0x64,
+0x64,
+0x64,
+0x64,
+0x7c,
+0x00,
+0x00,
+0x00,
+0x00,
+
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+
+};
+
+
+const struct font_desc font_rl = {
+       RL_IDX,
+       "RomanLarge",
+       8,
+       16,
+       patterns,
+       -1
+};
index 4fd07d9eca039d062c9968c452757f952b962a7e..9be83bed19597dd45bfec2736b51b2d8c7b0c1fa 100644 (file)
@@ -64,6 +64,10 @@ static const struct font_desc *fonts[] = {
 #undef NO_FONTS
     &font_mini_4x6,
 #endif
+#ifdef CONFIG_FONT_RL
+#undef NO_FONTS
+    &font_rl,
+#endif
 };
 
 #define num_fonts (sizeof(fonts)/sizeof(*fonts))
similarity index 97%
rename from drivers/video/softcursor.c
rename to drivers/video/console/softcursor.c
index 229c4bc350798c45f103a475f11f80a5e3f16dfe..8529bf08db28a92807b4e2f5d404be56917ff412 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * linux/drivers/video/softcursor.c -- Generic software cursor for frame buffer devices
  *
- *  Created 14 Nov 2002 by James Simmons 
+ *  Created 14 Nov 2002 by James Simmons
  *
  * 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
@@ -55,9 +55,9 @@ int soft_cursor(struct fb_info *info, struct fb_cursor *cursor)
                                src[i] = image->data[i] & cursor->mask[i];
                        break;
                }
-       } else 
+       } else
                memcpy(src, image->data, dsize);
-       
+
        fb_pad_aligned_buffer(dst, d_pitch, src, s_pitch, image->height);
        image->data = dst;
        info->fbops->fb_imageblit(info, image);
@@ -66,7 +66,7 @@ int soft_cursor(struct fb_info *info, struct fb_cursor *cursor)
 }
 
 EXPORT_SYMBOL(soft_cursor);
+
 MODULE_AUTHOR("James Simmons <jsimmons@users.sf.net>");
 MODULE_DESCRIPTION("Generic software cursor");
 MODULE_LICENSE("GPL");
index 989e700159e011fd6a42a798d3d7a22982c78288..403d17377f8db67fce024dbf52e4091225e6a743 100644 (file)
@@ -176,7 +176,6 @@ static struct fb_ops controlfb_ops = {
        .fb_fillrect    = cfb_fillrect,
        .fb_copyarea    = cfb_copyarea,
        .fb_imageblit   = cfb_imageblit,
-       .fb_cursor      = soft_cursor,
 };
 
 
index 3894b2a501d6e7a4636e5f5382c22741cd75ca6c..c589d23e7f914e6301bc39b7ed0d91f4c30ee7a3 100644 (file)
@@ -1064,7 +1064,6 @@ static struct fb_ops cyber2000fb_ops = {
        .fb_fillrect    = cyber2000fb_fillrect,
        .fb_copyarea    = cyber2000fb_copyarea,
        .fb_imageblit   = cyber2000fb_imageblit,
-       .fb_cursor      = soft_cursor,
        .fb_sync        = cyber2000fb_sync,
 };
 
index 6992100a508c09175cd527bcb9d10d977f3a769e..03fbe83d71a840660ac1486111c2707d71db3ba2 100644 (file)
@@ -968,7 +968,6 @@ static struct fb_ops cyblafb_ops __devinitdata = {
        .fb_fillrect = cyblafb_fillrect,
        .fb_copyarea= cyblafb_copyarea,
        .fb_imageblit = cyblafb_imageblit,
-       .fb_cursor = soft_cursor,
 };
 
 //==========================================================================
index 1785686a7f11cc8a6120323a6106bc327eb6f345..957a3ada2b75487c5188b65369ae3121d8866c20 100644 (file)
@@ -116,7 +116,6 @@ static struct fb_ops dn_fb_ops = {
        .fb_fillrect    = cfb_fillrect,
        .fb_copyarea    = dnfb_copyarea,
        .fb_imageblit   = cfb_imageblit,
-       .fb_cursor      = soft_cursor,
 };
 
 struct fb_var_screeninfo dnfb_var __devinitdata = {
index 7363d0b25fdfc12fda931d845e24321e346a82b4..6a81a1dd8f3d0bb357db89877bf53c8e4a745802 100644 (file)
@@ -484,7 +484,6 @@ static struct fb_ops epson1355fb_fbops = {
        .fb_imageblit   = cfb_imageblit,
        .fb_read        = epson1355fb_read,
        .fb_write       = epson1355fb_write,
-       .fb_cursor      = soft_cursor,
 };
 
 /* ------------------------------------------------------------------------- */
index 713226cdf3c6b7a7ce0a247447d1909d05e57396..fc7965b66775983a97d62d10ab7805c475e0eb73 100644 (file)
@@ -538,25 +538,12 @@ static struct fb_videomode *fb_create_modedb(unsigned char *edid, int *dbsize)
 
        *dbsize = 0;
 
-       DPRINTK("   Supported VESA Modes\n");
-       block = edid + ESTABLISHED_TIMING_1;
-       num += get_est_timing(block, &mode[num]);
-
-       DPRINTK("   Standard Timings\n");
-       block = edid + STD_TIMING_DESCRIPTIONS_START;
-       for (i = 0; i < STD_TIMING; i++, block += STD_TIMING_DESCRIPTION_SIZE) 
-               num += get_std_timing(block, &mode[num]);
-
        DPRINTK("   Detailed Timings\n");
        block = edid + DETAILED_TIMING_DESCRIPTIONS_START;
        for (i = 0; i < 4; i++, block+= DETAILED_TIMING_DESCRIPTION_SIZE) {
                int first = 1;
 
-               if (block[0] == 0x00 && block[1] == 0x00) {
-                       if (block[3] == 0xfa) {
-                               num += get_dst_timing(block + 5, &mode[num]);
-                       }
-               } else  {
+               if (!(block[0] == 0x00 && block[1] == 0x00)) {
                        get_detailed_timing(block, &mode[num]);
                        if (first) {
                                mode[num].flag |= FB_MODE_IS_FIRST;
@@ -565,6 +552,21 @@ static struct fb_videomode *fb_create_modedb(unsigned char *edid, int *dbsize)
                        num++;
                }
        }
+
+       DPRINTK("   Supported VESA Modes\n");
+       block = edid + ESTABLISHED_TIMING_1;
+       num += get_est_timing(block, &mode[num]);
+
+       DPRINTK("   Standard Timings\n");
+       block = edid + STD_TIMING_DESCRIPTIONS_START;
+       for (i = 0; i < STD_TIMING; i++, block += STD_TIMING_DESCRIPTION_SIZE)
+               num += get_std_timing(block, &mode[num]);
+
+       block = edid + DETAILED_TIMING_DESCRIPTIONS_START;
+       for (i = 0; i < 4; i++, block+= DETAILED_TIMING_DESCRIPTION_SIZE) {
+               if (block[0] == 0x00 && block[1] == 0x00 && block[3] == 0xfa)
+                       num += get_dst_timing(block + 5, &mode[num]);
+       }
        
        /* Yikes, EDID data is totally useless */
        if (!num) {
@@ -827,7 +829,7 @@ int fb_parse_edid(unsigned char *edid, struct fb_var_screeninfo *var)
 void fb_edid_to_monspecs(unsigned char *edid, struct fb_monspecs *specs)
 {
        unsigned char *block;
-       int i;
+       int i, found = 0;
 
        if (edid == NULL)
                return;
@@ -869,6 +871,22 @@ void fb_edid_to_monspecs(unsigned char *edid, struct fb_monspecs *specs)
        get_monspecs(edid, specs);
 
        specs->modedb = fb_create_modedb(edid, &specs->modedb_len);
+
+       /*
+        * Workaround for buggy EDIDs that sets that the first
+        * detailed timing is preferred but has not detailed
+        * timing specified
+        */
+       for (i = 0; i < specs->modedb_len; i++) {
+               if (specs->modedb[i].flag & FB_MODE_IS_DETAILED) {
+                       found = 1;
+                       break;
+               }
+       }
+
+       if (!found)
+               specs->misc &= ~FB_MISC_1ST_DETAIL;
+
        DPRINTK("========================================\n");
 }
 
index 10cd05059fe9d2e995f0b03a2c25b6687474c09d..04417dc16c2e3572084a9edaad40a7af3982d71b 100644 (file)
@@ -57,9 +57,6 @@ static struct fb_ops ffb_ops = {
        .fb_sync                = ffb_sync,
        .fb_mmap                = ffb_mmap,
        .fb_ioctl               = ffb_ioctl,
-
-       /* XXX Use FFB hw cursor once fb cursor API is better understood... */
-       .fb_cursor              = soft_cursor,
 };
 
 /* Register layout and definitions */
index a0763283d77651219cacab89273061004c2cd1fb..998374cfae6d0686f992cc00938bf4d460a436ec 100644 (file)
@@ -172,7 +172,6 @@ static struct fb_ops fm2fb_ops = {
        .fb_fillrect    = cfb_fillrect,
        .fb_copyarea    = cfb_copyarea,
        .fb_imageblit   = cfb_imageblit,
-       .fb_cursor      = soft_cursor,
 };
 
     /*
index ed853bef19e9d85ccf4532f8251d00321b28c814..9d5e4f342110acb4dbf34b3f8a835a2d1daaaf69 100644 (file)
@@ -1038,7 +1038,6 @@ static struct fb_ops gbefb_ops = {
        .fb_fillrect    = cfb_fillrect,
        .fb_copyarea    = cfb_copyarea,
        .fb_imageblit   = cfb_imageblit,
-       .fb_cursor      = soft_cursor,
 };
 
 /*
index 5a9b89c3831b1f7e254be8e047a24a2b4be3f904..42fb9a89a7927f833c8ecf24fc34c465a8d24da9 100644 (file)
@@ -14,7 +14,6 @@ config FB_GEODE_GX1
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
        select FB_CFB_IMAGEBLIT
-       select FB_SOFT_CURSOR
        ---help---
          Framebuffer driver for the display controller integrated into the
          AMD Geode GX1 processor.
index 74a5fca86b8ac505c32f9041523fbe04c0082e9f..8e8da743399416eafa71a730f50cca80a4b1f1e8 100644 (file)
@@ -275,7 +275,6 @@ static struct fb_ops gx1fb_ops = {
        .fb_fillrect    = cfb_fillrect,
        .fb_copyarea    = cfb_copyarea,
        .fb_imageblit   = cfb_imageblit,
-       .fb_cursor      = soft_cursor,
 };
 
 static struct fb_info * __init gx1fb_init_fbinfo(struct device *dev)
index 0d376ba54814f94ea4ed0625a82121cb5a30a0e5..f04ca721f94c53895f19f72b23e2998b48d2ffc7 100644 (file)
@@ -262,7 +262,6 @@ static struct fb_ops hitfb_ops = {
        .fb_fillrect    = hitfb_fillrect,
        .fb_copyarea    = hitfb_copyarea,
        .fb_imageblit   = cfb_imageblit,
-       .fb_cursor      = soft_cursor,
 };
 
 int __init hitfb_init(void)
index e97fe8481d59f5b52c17b052dcebd24783c7ca3b..bebdac59d231330c353940a009ba612807f4de37 100644 (file)
@@ -193,7 +193,6 @@ static struct fb_ops hpfb_ops = {
        .fb_fillrect    = hpfb_fillrect,
        .fb_copyarea    = hpfb_copyarea,
        .fb_imageblit   = cfb_imageblit,
-       .fb_cursor      = soft_cursor,
        .fb_sync        = hpfb_sync,
 };
 
index 689d2586366d7ffafbdb7c55741580f6f858f277..c61bad0da20f942c46c537a7107f27074467f8f8 100644 (file)
@@ -46,92 +46,45 @@ static void i810i2c_setscl(void *data, int state)
         struct i810fb_par         *par = chan->par;
        u8                        __iomem *mmio = par->mmio_start_virtual;
 
-       i810_writel(mmio, GPIOB, (state ? SCL_VAL_OUT : 0) | SCL_DIR |
+       i810_writel(mmio, chan->ddc_base, (state ? SCL_VAL_OUT : 0) | SCL_DIR |
                    SCL_DIR_MASK | SCL_VAL_MASK);
-       i810_readl(mmio, GPIOB);        /* flush posted write */
+       i810_readl(mmio, chan->ddc_base);       /* flush posted write */
 }
 
 static void i810i2c_setsda(void *data, int state)
 {
-        struct i810fb_i2c_chan    *chan = (struct i810fb_i2c_chan *)data;
+        struct i810fb_i2c_chan    *chan = data;
         struct i810fb_par         *par = chan->par;
        u8                        __iomem *mmio = par->mmio_start_virtual;
 
-       i810_writel(mmio, GPIOB, (state ? SDA_VAL_OUT : 0) | SDA_DIR |
+       i810_writel(mmio, chan->ddc_base, (state ? SDA_VAL_OUT : 0) | SDA_DIR |
                    SDA_DIR_MASK | SDA_VAL_MASK);
-       i810_readl(mmio, GPIOB);        /* flush posted write */
+       i810_readl(mmio, chan->ddc_base);       /* flush posted write */
 }
 
 static int i810i2c_getscl(void *data)
 {
-        struct i810fb_i2c_chan    *chan = (struct i810fb_i2c_chan *)data;
+        struct i810fb_i2c_chan    *chan = data;
         struct i810fb_par         *par = chan->par;
        u8                        __iomem *mmio = par->mmio_start_virtual;
 
-       i810_writel(mmio, GPIOB, SCL_DIR_MASK);
-       i810_writel(mmio, GPIOB, 0);
-       return (0 != (i810_readl(mmio, GPIOB) & SCL_VAL_IN));
+       i810_writel(mmio, chan->ddc_base, SCL_DIR_MASK);
+       i810_writel(mmio, chan->ddc_base, 0);
+       return ((i810_readl(mmio, chan->ddc_base) & SCL_VAL_IN) != 0);
 }
 
 static int i810i2c_getsda(void *data)
 {
-        struct i810fb_i2c_chan    *chan = (struct i810fb_i2c_chan *)data;
+        struct i810fb_i2c_chan    *chan = data;
         struct i810fb_par         *par = chan->par;
        u8                        __iomem *mmio = par->mmio_start_virtual;
 
-       i810_writel(mmio, GPIOB, SDA_DIR_MASK);
-       i810_writel(mmio, GPIOB, 0);
-       return (0 != (i810_readl(mmio, GPIOB) & SDA_VAL_IN));
-}
-
-static void i810ddc_setscl(void *data, int state)
-{
-        struct i810fb_i2c_chan    *chan = (struct i810fb_i2c_chan *)data;
-        struct i810fb_par       *par = chan->par;
-       u8                      __iomem *mmio = par->mmio_start_virtual;
-
-       i810_writel(mmio, GPIOA, (state ? SCL_VAL_OUT : 0) | SCL_DIR |
-                   SCL_DIR_MASK | SCL_VAL_MASK);
-       i810_readl(mmio, GPIOA);        /* flush posted write */
-}
-
-static void i810ddc_setsda(void *data, int state)
-{
-        struct i810fb_i2c_chan    *chan = (struct i810fb_i2c_chan *)data;
-        struct i810fb_par         *par = chan->par;
-       u8                      __iomem *mmio = par->mmio_start_virtual;
-
-       i810_writel(mmio, GPIOA, (state ? SDA_VAL_OUT : 0) | SDA_DIR |
-                   SDA_DIR_MASK | SDA_VAL_MASK);
-       i810_readl(mmio, GPIOA);        /* flush posted write */
-}
-
-static int i810ddc_getscl(void *data)
-{
-        struct i810fb_i2c_chan    *chan = (struct i810fb_i2c_chan *)data;
-        struct i810fb_par         *par = chan->par;
-       u8                      __iomem *mmio = par->mmio_start_virtual;
-
-       i810_writel(mmio, GPIOA, SCL_DIR_MASK);
-       i810_writel(mmio, GPIOA, 0);
-       return (0 != (i810_readl(mmio, GPIOA) & SCL_VAL_IN));
-}
-
-static int i810ddc_getsda(void *data)
-{
-        struct i810fb_i2c_chan    *chan = (struct i810fb_i2c_chan *)data;
-        struct i810fb_par         *par = chan->par;
-       u8                      __iomem *mmio = par->mmio_start_virtual;
-
-       i810_writel(mmio, GPIOA, SDA_DIR_MASK);
-       i810_writel(mmio, GPIOA, 0);
-       return (0 != (i810_readl(mmio, GPIOA) & SDA_VAL_IN));
+       i810_writel(mmio, chan->ddc_base, SDA_DIR_MASK);
+       i810_writel(mmio, chan->ddc_base, 0);
+       return ((i810_readl(mmio, chan->ddc_base) & SDA_VAL_IN) != 0);
 }
 
-#define I2C_ALGO_DDC_I810   0x0e0000
-#define I2C_ALGO_I2C_I810   0x0f0000
-static int i810_setup_i2c_bus(struct i810fb_i2c_chan *chan, const char *name,
-                             int conn)
+static int i810_setup_i2c_bus(struct i810fb_i2c_chan *chan, const char *name)
 {
         int rc;
 
@@ -139,22 +92,11 @@ static int i810_setup_i2c_bus(struct i810fb_i2c_chan *chan, const char *name,
         chan->adapter.owner             = THIS_MODULE;
         chan->adapter.algo_data         = &chan->algo;
         chan->adapter.dev.parent        = &chan->par->dev->dev;
-       switch (conn) {
-       case 1:
-               chan->adapter.id                = I2C_ALGO_DDC_I810;
-               chan->algo.setsda               = i810ddc_setsda;
-               chan->algo.setscl               = i810ddc_setscl;
-               chan->algo.getsda               = i810ddc_getsda;
-               chan->algo.getscl               = i810ddc_getscl;
-               break;
-       case 2:
-               chan->adapter.id                = I2C_ALGO_I2C_I810;
-               chan->algo.setsda               = i810i2c_setsda;
-               chan->algo.setscl               = i810i2c_setscl;
-               chan->algo.getsda               = i810i2c_getsda;
-               chan->algo.getscl               = i810i2c_getscl;
-               break;
-       }
+       chan->adapter.id                = I2C_HW_B_I810;
+       chan->algo.setsda               = i810i2c_setsda;
+       chan->algo.setscl               = i810i2c_setscl;
+       chan->algo.getsda               = i810i2c_getsda;
+       chan->algo.getscl               = i810i2c_getscl;
        chan->algo.udelay               = 10;
        chan->algo.mdelay               = 10;
         chan->algo.timeout              = (HZ/2);
@@ -168,11 +110,15 @@ static int i810_setup_i2c_bus(struct i810fb_i2c_chan *chan, const char *name,
         udelay(20);
 
         rc = i2c_bit_add_bus(&chan->adapter);
+
         if (rc == 0)
                 dev_dbg(&chan->par->dev->dev, "I2C bus %s registered.\n",name);
-        else
+        else {
                 dev_warn(&chan->par->dev->dev, "Failed to register I2C bus "
                         "%s.\n", name);
+               chan->par = NULL;
+       }
+
         return rc;
 }
 
@@ -180,8 +126,14 @@ void i810_create_i2c_busses(struct i810fb_par *par)
 {
         par->chan[0].par        = par;
        par->chan[1].par        = par;
-       i810_setup_i2c_bus(&par->chan[0], "I810-DDC", 1);
-       i810_setup_i2c_bus(&par->chan[1], "I810-I2C", 2);
+       par->chan[2].par        = par;
+
+       par->chan[0].ddc_base = GPIOA;
+       i810_setup_i2c_bus(&par->chan[0], "I810-DDC");
+       par->chan[1].ddc_base = GPIOB;
+       i810_setup_i2c_bus(&par->chan[1], "I810-I2C");
+       par->chan[2].ddc_base = GPIOC;
+       i810_setup_i2c_bus(&par->chan[2], "I810-GPIOC");
 }
 
 void i810_delete_i2c_busses(struct i810fb_par *par)
@@ -189,9 +141,14 @@ void i810_delete_i2c_busses(struct i810fb_par *par)
         if (par->chan[0].par)
                 i2c_bit_del_bus(&par->chan[0].adapter);
         par->chan[0].par = NULL;
+
        if (par->chan[1].par)
                i2c_bit_del_bus(&par->chan[1].adapter);
        par->chan[1].par = NULL;
+
+       if (par->chan[2].par)
+               i2c_bit_del_bus(&par->chan[2].adapter);
+       par->chan[2].par = NULL;
 }
 
 static u8 *i810_do_probe_i2c_edid(struct i810fb_i2c_chan *chan)
@@ -221,6 +178,7 @@ static u8 *i810_do_probe_i2c_edid(struct i810fb_i2c_chan *chan)
                DPRINTK("i810-i2c: I2C Transfer successful\n");
                 return buf;
        }
+
         DPRINTK("i810-i2c: Unable to read EDID block.\n");
         kfree(buf);
         return NULL;
@@ -233,7 +191,7 @@ int i810_probe_i2c_connector(struct fb_info *info, u8 **out_edid, int conn)
         int i;
 
        DPRINTK("i810-i2c: Probe DDC%i Bus\n", conn);
-       if (conn < 3) {
+       if (conn < 4) {
                for (i = 0; i < 3; i++) {
                        /* Do the real work */
                        edid = i810_do_probe_i2c_edid(&par->chan[conn-1]);
@@ -241,11 +199,14 @@ int i810_probe_i2c_connector(struct fb_info *info, u8 **out_edid, int conn)
                                break;
                }
        } else {
-               DPRINTK("i810-i2c: Getting EDID from BIOS\n");
-               edid = kmalloc(EDID_LENGTH, GFP_KERNEL);
-               if (edid)
-                       memcpy(edid, fb_firmware_edid(info->device),
-                              EDID_LENGTH);
+               const u8 *e = fb_firmware_edid(info->device);
+
+               if (e != NULL) {
+                       DPRINTK("i810-i2c: Getting EDID from BIOS\n");
+                       edid = kmalloc(EDID_LENGTH, GFP_KERNEL);
+                       if (edid)
+                               memcpy(edid, e, EDID_LENGTH);
+               }
        }
 
         if (out_edid)
@@ -253,5 +214,3 @@ int i810_probe_i2c_connector(struct fb_info *info, u8 **out_edid, int conn)
 
         return (edid) ? 0 : 1;
 }
-
-
index d48949ceaacc033988512bb6eb4dabf3e942a0e3..6c187d5fe95170e337ccc09f86457d993d98e207 100644 (file)
@@ -249,6 +249,7 @@ struct i810fb_i2c_chan {
        struct i810fb_par *par;
        struct i2c_adapter adapter;
        struct i2c_algo_bit_data algo;
+       unsigned long ddc_base;
 };
 
 struct i810fb_par {
@@ -262,7 +263,7 @@ struct i810fb_par {
        struct heap_data         iring;
        struct heap_data         cursor_heap;
        struct vgastate          state;
-       struct i810fb_i2c_chan   chan[2];
+       struct i810fb_i2c_chan   chan[3];
        atomic_t                 use_count;
        u32 pseudo_palette[17];
        unsigned long mmio_start_phys;
index 0dbc9ddb6766e78eba0b1b58f5e5eb0c57d0051b..c0c974b1afaa0285fd1cc753affc90f71c96e6f0 100644 (file)
@@ -1854,7 +1854,7 @@ static void __devinit i810fb_find_init_mode(struct fb_info *info)
 #ifdef CONFIG_FB_I810_I2C
        i810_create_i2c_busses(par);
 
-       for (i = 0; i < 3; i++) {
+       for (i = 0; i < 4; i++) {
                err = i810_probe_i2c_connector(info, &par->edid, i+1);
                if (!err)
                        break;
@@ -1871,27 +1871,18 @@ static void __devinit i810fb_find_init_mode(struct fb_info *info)
        fb_videomode_to_modelist(specs->modedb, specs->modedb_len,
                                 &info->modelist);
        if (specs->modedb != NULL) {
-               if (xres && yres) {
-                       struct fb_videomode *m;
+               struct fb_videomode *m;
 
+               if (xres && yres) {
                        if ((m = fb_find_best_mode(&var, &info->modelist))) {
                                mode = *m;
                                found  = 1;
                        }
                }
 
-               if (!found && specs->misc & FB_MISC_1ST_DETAIL) {
-                       for (i = 0; i < specs->modedb_len; i++) {
-                               if (specs->modedb[i].flag & FB_MODE_IS_FIRST) {
-                                       mode = specs->modedb[i];
-                                       found = 1;
-                                       break;
-                               }
-                       }
-               }
-
                if (!found) {
-                       mode = specs->modedb[0];
+                       m = fb_find_best_display(&info->monspecs, &info->modelist);
+                       mode = *m;
                        found = 1;
                }
 
@@ -2066,8 +2057,7 @@ static void i810fb_release_resource(struct fb_info *info,
                iounmap(par->mmio_start_virtual);
        if (par->aperture.virtual)
                iounmap(par->aperture.virtual);
-       if (par->edid)
-               kfree(par->edid);
+       kfree(par->edid);
        if (par->res_flags & FRAMEBUFFER_REQ)
                release_mem_region(par->aperture.physical,
                                   par->aperture.size);
index 6e4b9afa4d9805cb050d2bae68643427b324a785..91c6bd9d0d0d472c7c43cb43d3b89fb18e816c5a 100644 (file)
@@ -70,6 +70,7 @@
 #define HVSYNC                0x05000 
 #define GPIOA                 0x05010
 #define GPIOB                 0x05014 
+#define GPIOC                 0x0501C
 
 /* Clock Control and Power Management Registers (06000h 06FFFh) */
 #define DCLK_0D               0x06000
index 7b9bf45ab6fe89251e59c19deeb890c9583401f5..7fbe24206b190458b8b9aeb89e123cb47b8b6aa2 100644 (file)
@@ -1344,7 +1344,6 @@ static struct fb_ops imsttfb_ops = {
        .fb_fillrect    = imsttfb_fillrect,
        .fb_copyarea    = imsttfb_copyarea,
        .fb_imageblit   = cfb_imageblit,
-       .fb_cursor      = soft_cursor,
        .fb_ioctl       = imsttfb_ioctl,
 };
 
index 64d9bcc38da387fee71f375a0cfde75ce2d9bc4b..e20b9f3a255fb65b99e3a0fd37d276cbbbb8957d 100644 (file)
@@ -298,7 +298,6 @@ static struct fb_ops imxfb_ops = {
        .fb_copyarea    = cfb_copyarea,
        .fb_imageblit   = cfb_imageblit,
        .fb_blank       = imxfb_blank,
-       .fb_cursor      = soft_cursor, /* FIXME: i.MX can do hardware cursor */
 };
 
 /*
index 011e11626558399a98890554878a3c4f6af4fa6c..f077ca34fabad6ed156a256d76908d5bc24a687b 100644 (file)
@@ -10,7 +10,7 @@
 /*** Version/name ***/
 #define INTELFB_VERSION                        "0.9.2"
 #define INTELFB_MODULE_NAME            "intelfb"
-#define SUPPORTED_CHIPSETS             "830M/845G/852GM/855GM/865G/915G"
+#define SUPPORTED_CHIPSETS             "830M/845G/852GM/855GM/865G/915G/915GM"
 
 
 /*** Debug/feature defines ***/
@@ -47,6 +47,7 @@
 #define PCI_DEVICE_ID_INTEL_85XGM      0x3582
 #define PCI_DEVICE_ID_INTEL_865G       0x2572
 #define PCI_DEVICE_ID_INTEL_915G       0x2582
+#define PCI_DEVICE_ID_INTEL_915GM      0x2592
 
 /* Size of MMIO region */
 #define INTEL_REG_SIZE                 0x80000
@@ -119,7 +120,8 @@ enum intel_chips {
        INTEL_855GM,
        INTEL_855GME,
        INTEL_865G,
-       INTEL_915G
+       INTEL_915G,
+       INTEL_915GM
 };
 
 struct intelfb_hwstate {
index 80a09344f1aaedffd1e6e665dd26186fe70e84b4..0799b999b3143e361aef7cf39e0a211137ec50de 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * intelfb
  *
- * Linux framebuffer driver for Intel(R) 830M/845G/852GM/855GM/865G/915G
+ * Linux framebuffer driver for Intel(R) 830M/845G/852GM/855GM/865G/915G/915GM
  * integrated graphics chips.
  *
  * Copyright Â© 2002, 2003 David Dawes <dawes@xfree86.org>
@@ -186,6 +186,7 @@ static struct pci_device_id intelfb_pci_table[] __devinitdata = {
        { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_85XGM, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_85XGM },
        { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_865G, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_865G },
        { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_915G, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_915G },
+       { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_915GM, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_915GM },
        { 0, }
 };
 
@@ -549,10 +550,11 @@ intelfb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent)
        }
 
        /* Set base addresses. */
-       if (ent->device == PCI_DEVICE_ID_INTEL_915G) {
+       if ((ent->device == PCI_DEVICE_ID_INTEL_915G) ||
+                       (ent->device == PCI_DEVICE_ID_INTEL_915GM)) {
                aperture_bar = 2;
                mmio_bar = 0;
-               /* Disable HW cursor on 915G (not implemented yet) */
+               /* Disable HW cursor on 915G/M (not implemented yet) */
                hwcursor = 0;
        }
        dinfo->aperture.physical = pci_resource_start(pdev, aperture_bar);
@@ -1483,7 +1485,7 @@ intelfb_cursor(struct fb_info *info, struct fb_cursor *cursor)
 #endif
 
        if (!dinfo->hwcursor)
-               return soft_cursor(info, cursor);
+               return -ENODEV;
 
        intelfbhw_cursor_hide(dinfo);
 
index 5bafc3c54db767a41730105f18df9f104d8ad694..ac94c2e5ff857720161b9e7291fe10ecb54f2721 100644 (file)
@@ -99,6 +99,11 @@ intelfbhw_get_chipset(struct pci_dev *pdev, const char **name, int *chipset,
                *chipset = INTEL_915G;
                *mobile = 0;
                return 0;
+       case PCI_DEVICE_ID_INTEL_915GM:
+               *name = "Intel(R) 915GM";
+               *chipset = INTEL_915GM;
+               *mobile = 1;
+               return 0;
        default:
                return 1;
        }
index d8bac9e978421b97dcbe09f34f2b8ec893aa6881..5eb4d5c177bd1899a5caeea3d536a7d4ec414e2b 100644 (file)
@@ -669,7 +669,6 @@ static struct fb_ops kyrofb_ops = {
        .fb_fillrect    = cfb_fillrect,
        .fb_copyarea    = cfb_copyarea,
        .fb_imageblit   = cfb_imageblit,
-       .fb_cursor      = soft_cursor,
 };
 
 static int __devinit kyrofb_probe(struct pci_dev *pdev,
index 7e1e7fb168bd3e31dd10b4ad727639389a0b5392..84a7fe435bb82bd082c770b51cbae2b511c8d361 100644 (file)
@@ -51,7 +51,6 @@ static struct fb_ops leo_ops = {
        .fb_imageblit           = cfb_imageblit,
        .fb_mmap                = leo_mmap,
        .fb_ioctl               = leo_ioctl,
-       .fb_cursor              = soft_cursor,
 };
 
 #define LEO_OFF_LC_SS0_KRN     0x00200000UL
index 3e9ccf370ab222cecdd59a0ceacedbac13b6af66..8cb7fb4db4418b8815b6be81d374ef65343afa35 100644 (file)
@@ -7,6 +7,8 @@ menu "Logo configuration"
 config LOGO
        bool "Bootup logo"
        depends on FB || SGI_NEWPORT_CONSOLE
+       help
+         Enable and select frame buffer bootup logos.
 
 config LOGO_LINUX_MONO
        bool "Standard black and white Linux logo"
index 4945a4c02209ed6f87dc98807f03823c9b838721..cfc748e9427260037a075a0ad78ebdc8e90c4560 100644 (file)
@@ -589,7 +589,6 @@ static struct fb_ops macfb_ops = {
        .fb_fillrect    = cfb_fillrect,
        .fb_copyarea    = cfb_copyarea,
        .fb_imageblit   = cfb_imageblit,
-       .fb_cursor      = soft_cursor,
 };
 
 void __init macfb_setup(char *options)
index 149680f8bcf05e33d684d68b8e1c303a9d8bae70..0fbd9b5149f16f7632a64782c6ed3f64556f6156 100644 (file)
@@ -657,7 +657,6 @@ static int MGA1064_preinit(WPMINFO2) {
        /* ACCESS_FBINFO(capable.cfb4) = 0; ... preinitialized by 0 */
        ACCESS_FBINFO(capable.text) = 1;
        ACCESS_FBINFO(capable.vxres) = vxres_mystique;
-       ACCESS_FBINFO(features.accel.has_cacheflush) = 1;
 
        ACCESS_FBINFO(outputs[0]).output = &m1064;
        ACCESS_FBINFO(outputs[0]).src = ACCESS_FBINFO(outputs[0]).default_src;
@@ -842,7 +841,6 @@ static int MGAG100_preinit(WPMINFO2) {
        /* ACCESS_FBINFO(capable.cfb4) = 0; ... preinitialized by 0 */
        ACCESS_FBINFO(capable.text) = 1;
        ACCESS_FBINFO(capable.vxres) = vxres_g100;
-       ACCESS_FBINFO(features.accel.has_cacheflush) = 1;
        ACCESS_FBINFO(capable.plnwt) = ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGAG100
                        ? ACCESS_FBINFO(devflags.sgram) : 1;
 
@@ -980,7 +978,7 @@ static void MGAG100_reset(WPMINFO2) {
                                hw->MXoptionReg |= 0x40;        /* FIXME... */
                                pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg);
                        }
-                       mga_setr(M_EXTVGA_INDEX, 0x06, 0x50);
+                       mga_setr(M_EXTVGA_INDEX, 0x06, 0x00);
                }
        }
        if (ACCESS_FBINFO(devflags.g450dac)) {
index c7f3e1321224d36e582bab8298f37b54d2b5c86e..a5c825d994661090c990e6423fb6245a063902b1 100644 (file)
@@ -122,7 +122,7 @@ void matrox_cfbX_init(WPMINFO2) {
        ACCESS_FBINFO(fbops).fb_copyarea = cfb_copyarea;
        ACCESS_FBINFO(fbops).fb_fillrect = cfb_fillrect;
        ACCESS_FBINFO(fbops).fb_imageblit = cfb_imageblit;
-       ACCESS_FBINFO(fbops).fb_cursor = soft_cursor;
+       ACCESS_FBINFO(fbops).fb_cursor = NULL;
 
        accel = (ACCESS_FBINFO(fbcon).var.accel_flags & FB_ACCELF_TEXT) == FB_ACCELF_TEXT;
 
index e02da41f1b262b9cb780dd19d4d36767ccdbe357..1e74f4cca53b2955d02cef90f29eaf5b4df10227 100644 (file)
@@ -264,7 +264,6 @@ static void matroxfb_disable_irq(WPMINFO2) {
 }
 
 int matroxfb_wait_for_sync(WPMINFO u_int32_t crtc) {
-       wait_queue_t __wait;
        struct matrox_vsync *vs;
        unsigned int cnt;
        int ret;
@@ -286,7 +285,6 @@ int matroxfb_wait_for_sync(WPMINFO u_int32_t crtc) {
        if (ret) {
                return ret;
        }
-        init_waitqueue_entry(&__wait, current);
 
        cnt = vs->cnt;
        ret = wait_event_interruptible_timeout(vs->wait, cnt != vs->cnt, HZ/10);
@@ -500,10 +498,6 @@ static int matroxfb_pitch_adjust(CPMINFO int xres, int bpp) {
        } else {
                xres_new = matroxfb_test_and_set_rounding(PMINFO xres, bpp);
        }
-       if (!xres_new) return 0;
-       if (xres != xres_new) {
-               printk(KERN_INFO "matroxfb: cannot set xres to %d, rounded up to %d\n", xres, xres_new);
-       }
        return xres_new;
 }
 
@@ -1285,7 +1279,7 @@ static int matroxfb_getmemory(WPMINFO unsigned int maxSize, unsigned int *realSi
        vaddr_t vm;
        unsigned int offs;
        unsigned int offs2;
-       unsigned char store, orig;
+       unsigned char orig;
        unsigned char bytes[32];
        unsigned char* tmp;
 
@@ -1301,16 +1295,12 @@ static int matroxfb_getmemory(WPMINFO unsigned int maxSize, unsigned int *realSi
        orig = mga_inb(M_EXTVGA_DATA);
        mga_outb(M_EXTVGA_DATA, orig | 0x80);
 
-       store = mga_readb(vm, 0x1234);
        tmp = bytes;
        for (offs = 0x100000; offs < maxSize; offs += 0x200000)
                *tmp++ = mga_readb(vm, offs);
        for (offs = 0x100000; offs < maxSize; offs += 0x200000)
                mga_writeb(vm, offs, 0x02);
-       if (ACCESS_FBINFO(features.accel.has_cacheflush))
-               mga_outb(M_CACHEFLUSH, 0x00);
-       else
-               mga_writeb(vm, 0x1234, 0x99);
+       mga_outb(M_CACHEFLUSH, 0x00);
        for (offs = 0x100000; offs < maxSize; offs += 0x200000) {
                if (mga_readb(vm, offs) != 0x02)
                        break;
@@ -1321,7 +1311,6 @@ static int matroxfb_getmemory(WPMINFO unsigned int maxSize, unsigned int *realSi
        tmp = bytes;
        for (offs2 = 0x100000; offs2 < maxSize; offs2 += 0x200000)
                mga_writeb(vm, offs2, *tmp++);
-       mga_writeb(vm, 0x1234, store);
 
        mga_outb(M_EXTVGA_INDEX, 0x03);
        mga_outb(M_EXTVGA_DATA, orig);
@@ -1430,6 +1419,20 @@ static struct board {
                MGA_1164,
                &vbMystique,
                "Mystique 220 (PCI)"},
+       {PCI_VENDOR_ID_MATROX,  PCI_DEVICE_ID_MATROX_MYS_AGP,   0x02,
+               0,                      0,
+               DEVF_VIDEO64BIT | DEVF_CROSS4MB,
+               180000,
+               MGA_1064,
+               &vbMystique,
+               "Mystique (AGP)"},
+       {PCI_VENDOR_ID_MATROX,  PCI_DEVICE_ID_MATROX_MYS_AGP,   0xFF,
+               0,                      0,
+               DEVF_VIDEO64BIT | DEVF_SWAPS | DEVF_CROSS4MB,
+               220000,
+               MGA_1164,
+               &vbMystique,
+               "Mystique 220 (AGP)"},
 #endif
 #ifdef CONFIG_FB_MATROX_G
        {PCI_VENDOR_ID_MATROX,  PCI_DEVICE_ID_MATROX_G100_MM,   0xFF,
index 85a0b2558452796659c9f1fbdedd7dba2302dc4f..a8c47ad2cdb6059d63671a685247018415b8632a 100644 (file)
@@ -272,10 +272,6 @@ struct matrox_DAC1064_features {
        u_int8_t        xmiscctrl;
 };
 
-struct matrox_accel_features {
-       int             has_cacheflush;
-};
-
 /* current hardware status */
 struct mavenregs {
        u_int8_t regs[256];
@@ -440,7 +436,6 @@ struct matrox_fb_info {
        struct {
                struct matrox_pll_features pll;
                struct matrox_DAC1064_features DAC1064;
-               struct matrox_accel_features accel;
                              } features;
        struct {
                spinlock_t      DAC;
index 429047ac615a5cf5d3c3f4a103fc1b869c1516b9..d52d7d825c41439ccb7825b0ea9be41d363ae303 100644 (file)
@@ -576,7 +576,6 @@ static struct fb_ops matroxfb_dh_ops = {
        .fb_fillrect =  cfb_fillrect,
        .fb_copyarea =  cfb_copyarea,
        .fb_imageblit = cfb_imageblit,
-       .fb_cursor =    soft_cursor,
 };
 
 static struct fb_var_screeninfo matroxfb_dh_defined = {
index f192d995d0303e64dca0bb3a765cc21690aaeb2e..743e7ad26acc3299f32e5903b9c4bc474a249fcb 100644 (file)
@@ -113,7 +113,6 @@ static struct fb_ops maxinefb_ops = {
        .fb_fillrect    = cfb_fillrect,
        .fb_copyarea    = cfb_copyarea,
        .fb_imageblit   = cfb_imageblit,
-       .fb_cursor      = soft_cursor,
 };
 
 int __init maxinefb_init(void)
index 47516c44a390ac7218a3df538424553f76ac9225..1789a52d776a984ba9bec98371f7fd974157eead 100644 (file)
@@ -676,6 +676,8 @@ void fb_var_to_videomode(struct fb_videomode *mode,
        mode->sync = var->sync;
        mode->vmode = var->vmode & FB_VMODE_MASK;
        mode->flag = FB_MODE_IS_FROM_VAR;
+       mode->refresh = 0;
+
        if (!var->pixclock)
                return;
 
@@ -785,39 +787,39 @@ struct fb_videomode *fb_find_best_mode(struct fb_var_screeninfo *var,
 }
 
 /**
- * fb_find_nearest_mode - find mode closest video mode
+ * fb_find_nearest_mode - find closest videomode
  *
- * @var: pointer to struct fb_var_screeninfo
+ * @mode: pointer to struct fb_videomode
  * @head: pointer to modelist
  *
  * Finds best matching videomode, smaller or greater in dimension.
  * If more than 1 videomode is found, will return the videomode with
- * the closest refresh rate
+ * the closest refresh rate.
  */
-struct fb_videomode *fb_find_nearest_mode(struct fb_var_screeninfo *var,
+struct fb_videomode *fb_find_nearest_mode(struct fb_videomode *mode,
                                          struct list_head *head)
 {
        struct list_head *pos;
        struct fb_modelist *modelist;
-       struct fb_videomode *mode, *best = NULL;
+       struct fb_videomode *cmode, *best = NULL;
        u32 diff = -1, diff_refresh = -1;
 
        list_for_each(pos, head) {
                u32 d;
 
                modelist = list_entry(pos, struct fb_modelist, list);
-               mode = &modelist->mode;
+               cmode = &modelist->mode;
 
-               d = abs(mode->xres - var->xres) +
-                       abs(mode->yres - var->yres);
+               d = abs(cmode->xres - mode->xres) +
+                       abs(cmode->yres - mode->yres);
                if (diff > d) {
                        diff = d;
-                       best = mode;
+                       best = cmode;
                } else if (diff == d) {
-                       d = abs(mode->refresh - best->refresh);
+                       d = abs(cmode->refresh - mode->refresh);
                        if (diff_refresh > d) {
                                diff_refresh = d;
-                               best = mode;
+                               best = cmode;
                        }
                }
        }
@@ -942,6 +944,66 @@ void fb_videomode_to_modelist(struct fb_videomode *modedb, int num,
        }
 }
 
+struct fb_videomode *fb_find_best_display(struct fb_monspecs *specs,
+                                         struct list_head *head)
+{
+       struct list_head *pos;
+       struct fb_modelist *modelist;
+       struct fb_videomode *m, *m1 = NULL, *md = NULL, *best = NULL;
+       int first = 0;
+
+       if (!head->prev || !head->next || list_empty(head))
+               goto finished;
+
+       /* get the first detailed mode and the very first mode */
+       list_for_each(pos, head) {
+               modelist = list_entry(pos, struct fb_modelist, list);
+               m = &modelist->mode;
+
+               if (!first) {
+                       m1 = m;
+                       first = 1;
+               }
+
+               if (m->flag & FB_MODE_IS_FIRST) {
+                       md = m;
+                       break;
+               }
+       }
+
+       /* first detailed timing is preferred */
+       if (specs->misc & FB_MISC_1ST_DETAIL) {
+               best = md;
+               goto finished;
+       }
+
+       /* find best mode based on display width and height */
+       if (specs->max_x && specs->max_y) {
+               struct fb_var_screeninfo var;
+
+               memset(&var, 0, sizeof(struct fb_var_screeninfo));
+               var.xres = (specs->max_x * 7200)/254;
+               var.yres = (specs->max_y * 7200)/254;
+               m = fb_find_best_mode(&var, head);
+               if (m) {
+                       best = m;
+                       goto finished;
+               }
+       }
+
+       /* use first detailed mode */
+       if (md) {
+               best = md;
+               goto finished;
+       }
+
+       /* last resort, use the very first mode */
+       best = m1;
+finished:
+       return best;
+}
+EXPORT_SYMBOL(fb_find_best_display);
+
 EXPORT_SYMBOL(fb_videomode_to_var);
 EXPORT_SYMBOL(fb_var_to_videomode);
 EXPORT_SYMBOL(fb_mode_is_equal);
index 5d424a30270acda396d49c204d04241244a18962..8486e77872dc0a6c1789f230ed85dc9717d1ee6d 100644 (file)
@@ -1665,7 +1665,6 @@ static struct fb_ops neofb_ops = {
        .fb_fillrect    = neofb_fillrect,
        .fb_copyarea    = neofb_copyarea,
        .fb_imageblit   = neofb_imageblit,
-       .fb_cursor      = soft_cursor,
 };
 
 /* --------------------------------------------------------------------- */
index afee284fc73c964bbc4fb2782c0fa251b13ccb28..4243d7fae972a34fc0d197956fd760bb3d77db72 100644 (file)
@@ -105,7 +105,7 @@ do {                            \
        *a = byte_rev[*a];      \
 } while(0)
 #else
-#define reverse_order(l)
+#define reverse_order(l) do { } while(0)
 #endif                          /* __LITTLE_ENDIAN */
 
 #endif                         /* __NV_LOCAL_H__ */
index 4fa2cf9a8af2adbf6e673022ea2655c9810e5de6..7a03d040b1a3255bb0d9e2a5dbc4828b49c36c42 100644 (file)
 #include "nv_local.h"
 #include "nv_proto.h"
 
-void nvidia_create_i2c_busses(struct nvidia_par *par) {}
-void nvidia_delete_i2c_busses(struct nvidia_par *par) {}
+#include "../edid.h"
 
-int nvidia_probe_i2c_connector(struct fb_info *info, int conn, u8 **out_edid)
+int nvidia_probe_of_connector(struct fb_info *info, int conn, u8 **out_edid)
 {
        struct nvidia_par *par = info->par;
-       struct device_node *dp;
+       struct device_node *parent, *dp;
        unsigned char *pedid = NULL;
-       unsigned char *disptype = NULL;
        static char *propnames[] = {
-               "DFP,EDID", "LCD,EDID", "EDID", "EDID1", "EDID,B", "EDID,A", NULL };
+               "DFP,EDID", "LCD,EDID", "EDID", "EDID1",
+               "EDID,B", "EDID,A", NULL };
        int i;
 
-       dp = pci_device_to_OF_node(par->pci_dev);
-       for (; dp != NULL; dp = dp->child) {
-               disptype = (unsigned char *)get_property(dp, "display-type", NULL);
-               if (disptype == NULL)
-                       continue;
-               if (strncmp(disptype, "LCD", 3) != 0)
-                       continue;
+       parent = pci_device_to_OF_node(par->pci_dev);
+       if (parent == NULL)
+               return -1;
+       if (par->twoHeads) {
+               char *pname;
+               int len;
+
+               for (dp = NULL;
+                    (dp = of_get_next_child(parent, dp)) != NULL;) {
+                       pname = (char *)get_property(dp, "name", NULL);
+                       if (!pname)
+                               continue;
+                       len = strlen(pname);
+                       if ((pname[len-1] == 'A' && conn == 1) ||
+                           (pname[len-1] == 'B' && conn == 2)) {
+                               for (i = 0; propnames[i] != NULL; ++i) {
+                                       pedid = (unsigned char *)
+                                               get_property(dp, propnames[i],
+                                                            NULL);
+                                       if (pedid != NULL)
+                                               break;
+                               }
+                               of_node_put(dp);
+                               break;
+                       }
+               }
+       }
+       if (pedid == NULL) {
                for (i = 0; propnames[i] != NULL; ++i) {
                        pedid = (unsigned char *)
-                               get_property(dp, propnames[i], NULL);
-                       if (pedid != NULL) {
-                               *out_edid = pedid;
-                               return 0;
-                       }
+                               get_property(parent, propnames[i], NULL);
+                       if (pedid != NULL)
+                               break;
                }
        }
-       return 1;
+       if (pedid) {
+               *out_edid = kmalloc(EDID_LENGTH, GFP_KERNEL);
+               if (*out_edid == NULL)
+                       return -1;
+               memcpy(*out_edid, pedid, EDID_LENGTH);
+               printk(KERN_DEBUG "nvidiafb: Found OF EDID for head %d\n", conn);
+               return 0;
+       }
+       return -1;
 }
index cac44fc7f58717be955c65c1e43c2156a6343372..f60b1f4322700d2554e729245145c9c8407714d3 100644 (file)
@@ -31,7 +31,7 @@ int NVShowHideCursor(struct nvidia_par *par, int);
 void NVLockUnlock(struct nvidia_par *par, int);
 
 /* in nvidia-i2c.c */
-#if defined(CONFIG_FB_NVIDIA_I2C) || defined (CONFIG_PPC_OF)
+#ifdef CONFIG_FB_NVIDIA_I2C
 void nvidia_create_i2c_busses(struct nvidia_par *par);
 void nvidia_delete_i2c_busses(struct nvidia_par *par);
 int nvidia_probe_i2c_connector(struct fb_info *info, int conn,
@@ -39,10 +39,18 @@ int nvidia_probe_i2c_connector(struct fb_info *info, int conn,
 #else
 #define nvidia_create_i2c_busses(...)
 #define nvidia_delete_i2c_busses(...)
-#define nvidia_probe_i2c_connector(p, c, edid) \
-do {                                           \
-       *(edid) = NULL;                        \
-} while(0)
+#define nvidia_probe_i2c_connector(p, c, edid) (-1)
+#endif
+
+#ifdef CONFIG_FB_OF
+int nvidia_probe_of_connector(struct fb_info *info, int conn,
+                             u8 ** out_edid);
+#else
+static inline int nvidia_probe_of_connector(struct fb_info *info, int conn,
+                                     u8 ** out_edid)
+{
+       return -1;
+}
 #endif
 
 /* in nv_accel.c */
index 11c84178f42069c83163ea01512c39707897d249..1f06a9f1bd0f52d893e4233111174281a23f130e 100644 (file)
@@ -190,9 +190,9 @@ static int NVIsConnected(struct nvidia_par *par, int output)
        present = (NV_RD32(PRAMDAC, 0x0608) & (1 << 28)) ? 1 : 0;
 
        if (present)
-               printk("nvidiafb: CRTC%i found\n", output);
+               printk("nvidiafb: CRTC%i analog found\n", output);
        else
-               printk("nvidiafb: CRTC%i not found\n", output);
+               printk("nvidiafb: CRTC%i analog not found\n", output);
 
        NV_WR32(par->PRAMDAC0, 0x0608, NV_RD32(par->PRAMDAC0, 0x0608) &
                0x0000EFFF);
@@ -305,6 +305,9 @@ void NVCommonSetup(struct fb_info *info)
        int FlatPanel = -1;     /* really means the CRTC is slaved */
        int Television = 0;
 
+       memset(&monitorA, 0, sizeof(struct fb_monspecs));
+       memset(&monitorB, 0, sizeof(struct fb_monspecs));
+
        par->PRAMIN = par->REGS + (0x00710000 / 4);
        par->PCRTC0 = par->REGS + (0x00600000 / 4);
        par->PRAMDAC0 = par->REGS + (0x00680000 / 4);
@@ -401,7 +404,8 @@ void NVCommonSetup(struct fb_info *info)
        nvidia_create_i2c_busses(par);
        if (!par->twoHeads) {
                par->CRTCnumber = 0;
-               nvidia_probe_i2c_connector(info, 1, &edidA);
+               if (nvidia_probe_i2c_connector(info, 1, &edidA))
+                       nvidia_probe_of_connector(info, 1, &edidA);
                if (edidA && !fb_parse_edid(edidA, &var)) {
                        printk("nvidiafb: EDID found from BUS1\n");
                        monA = &monitorA;
@@ -488,14 +492,16 @@ void NVCommonSetup(struct fb_info *info)
                oldhead = NV_RD32(par->PCRTC0, 0x00000860);
                NV_WR32(par->PCRTC0, 0x00000860, oldhead | 0x00000010);
 
-               nvidia_probe_i2c_connector(info, 1, &edidA);
+               if (nvidia_probe_i2c_connector(info, 1, &edidA))
+                       nvidia_probe_of_connector(info, 1, &edidA);
                if (edidA && !fb_parse_edid(edidA, &var)) {
                        printk("nvidiafb: EDID found from BUS1\n");
                        monA = &monitorA;
                        fb_edid_to_monspecs(edidA, monA);
                }
 
-               nvidia_probe_i2c_connector(info, 2, &edidB);
+               if (nvidia_probe_i2c_connector(info, 2, &edidB))
+                       nvidia_probe_of_connector(info, 2, &edidB);
                if (edidB && !fb_parse_edid(edidB, &var)) {
                        printk("nvidiafb: EDID found from BUS2\n");
                        monB = &monitorB;
index 308defc389a263b37fa1d7e58d9b184a691765cd..0b40a2a721c180609c15b16e82e3209b195a846e 100644 (file)
@@ -411,6 +411,7 @@ MODULE_DEVICE_TABLE(pci, nvidiafb_pci_tbl);
 
 /* command line data, set in nvidiafb_setup() */
 static int flatpanel __devinitdata = -1;       /* Autodetect later */
+static int fpdither __devinitdata = -1;
 static int forceCRTC __devinitdata = -1;
 static int hwcur __devinitdata = 0;
 static int noaccel __devinitdata = 0;
@@ -627,41 +628,85 @@ static void nvidia_save_vga(struct nvidia_par *par,
        NVTRACE_LEAVE();
 }
 
+#undef DUMP_REG
+
 static void nvidia_write_regs(struct nvidia_par *par)
 {
        struct _riva_hw_state *state = &par->ModeReg;
        int i;
 
        NVTRACE_ENTER();
-       NVWriteCrtc(par, 0x11, 0x00);
-
-       NVLockUnlock(par, 0);
 
        NVLoadStateExt(par, state);
 
        NVWriteMiscOut(par, state->misc_output);
 
+       for (i = 1; i < NUM_SEQ_REGS; i++) {
+#ifdef DUMP_REG
+               printk(" SEQ[%02x] = %08x\n", i, state->seq[i]);
+#endif
+               NVWriteSeq(par, i, state->seq[i]);
+       }
+
+       /* Ensure CRTC registers 0-7 are unlocked by clearing bit 7 of CRTC[17] */
+       NVWriteCrtc(par, 0x11, state->crtc[0x11] & ~0x80);
+
        for (i = 0; i < NUM_CRT_REGS; i++) {
                switch (i) {
                case 0x19:
                case 0x20 ... 0x40:
                        break;
                default:
+#ifdef DUMP_REG
+                       printk("CRTC[%02x] = %08x\n", i, state->crtc[i]);
+#endif
                        NVWriteCrtc(par, i, state->crtc[i]);
                }
        }
 
-       for (i = 0; i < NUM_ATC_REGS; i++)
-               NVWriteAttr(par, i, state->attr[i]);
-
-       for (i = 0; i < NUM_GRC_REGS; i++)
+       for (i = 0; i < NUM_GRC_REGS; i++) {
+#ifdef DUMP_REG
+               printk(" GRA[%02x] = %08x\n", i, state->gra[i]);
+#endif
                NVWriteGr(par, i, state->gra[i]);
+       }
+
+       for (i = 0; i < NUM_ATC_REGS; i++) {
+#ifdef DUMP_REG
+               printk("ATTR[%02x] = %08x\n", i, state->attr[i]);
+#endif
+               NVWriteAttr(par, i, state->attr[i]);
+       }
 
-       for (i = 0; i < NUM_SEQ_REGS; i++)
-               NVWriteSeq(par, i, state->seq[i]);
        NVTRACE_LEAVE();
 }
 
+static void nvidia_vga_protect(struct nvidia_par *par, int on)
+{
+       unsigned char tmp;
+
+       if (on) {
+               /*
+                * Turn off screen and disable sequencer.
+                */
+               tmp = NVReadSeq(par, 0x01);
+
+               NVWriteSeq(par, 0x00, 0x01);            /* Synchronous Reset */
+               NVWriteSeq(par, 0x01, tmp | 0x20);      /* disable the display */
+       } else {
+               /*
+                * Reenable sequencer, then turn on screen.
+                */
+
+               tmp = NVReadSeq(par, 0x01);
+
+               NVWriteSeq(par, 0x01, tmp & ~0x20);     /* reenable display */
+               NVWriteSeq(par, 0x00, 0x03);            /* End Reset */
+       }
+}
+
+
+
 static int nvidia_calc_regs(struct fb_info *info)
 {
        struct nvidia_par *par = info->par;
@@ -868,7 +913,7 @@ static void nvidia_init_vga(struct fb_info *info)
        for (i = 0; i < 0x10; i++)
                state->attr[i] = i;
        state->attr[0x10] = 0x41;
-       state->attr[0x11] = 0x01;
+       state->attr[0x11] = 0xff;
        state->attr[0x12] = 0x0f;
        state->attr[0x13] = 0x00;
        state->attr[0x14] = 0x00;
@@ -982,16 +1027,24 @@ static int nvidiafb_set_par(struct fb_info *info)
        NVTRACE_ENTER();
 
        NVLockUnlock(par, 1);
-       if (!par->FlatPanel || (info->var.bits_per_pixel != 24) ||
-           !par->twoHeads)
+       if (!par->FlatPanel || !par->twoHeads)
                par->FPDither = 0;
 
+       if (par->FPDither < 0) {
+               if ((par->Chipset & 0x0ff0) == 0x0110)
+                       par->FPDither = !!(NV_RD32(par->PRAMDAC, 0x0528)
+                                          & 0x00010000);
+               else
+                       par->FPDither = !!(NV_RD32(par->PRAMDAC, 0x083C) & 1);
+               printk(KERN_INFO PFX "Flat panel dithering %s\n",
+                      par->FPDither ? "enabled" : "disabled");
+       }
+
        info->fix.visual = (info->var.bits_per_pixel == 8) ?
            FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
 
        nvidia_init_vga(info);
        nvidia_calc_regs(info);
-       nvidia_write_regs(par);
 
        NVLockUnlock(par, 0);
        if (par->twoHeads) {
@@ -1000,7 +1053,22 @@ static int nvidiafb_set_par(struct fb_info *info)
                NVLockUnlock(par, 0);
        }
 
-       NVWriteCrtc(par, 0x11, 0x00);
+       nvidia_vga_protect(par, 1);
+
+       nvidia_write_regs(par);
+
+#if defined (__BIG_ENDIAN)
+       /* turn on LFB swapping */
+       {
+               unsigned char tmp;
+
+               VGA_WR08(par->PCIO, 0x3d4, 0x46);
+               tmp = VGA_RD08(par->PCIO, 0x3d5);
+               tmp |= (1 << 7);
+               VGA_WR08(par->PCIO, 0x3d5, tmp);
+    }
+#endif
+
        info->fix.line_length = (info->var.xres_virtual *
                                 info->var.bits_per_pixel) >> 3;
        if (info->var.accel_flags) {
@@ -1022,7 +1090,7 @@ static int nvidiafb_set_par(struct fb_info *info)
 
        par->cursor_reset = 1;
 
-       NVWriteCrtc(par, 0x11, 0xff);
+       nvidia_vga_protect(par, 0);
 
        NVTRACE_LEAVE();
        return 0;
@@ -1315,22 +1383,10 @@ static int __devinit nvidia_set_fbinfo(struct fb_info *info)
        fb_var_to_videomode(&modedb, &nvidiafb_default_var);
 
        if (specs->modedb != NULL) {
-               /* get preferred timing */
-               if (specs->misc & FB_MISC_1ST_DETAIL) {
-                       int i;
-
-                       for (i = 0; i < specs->modedb_len; i++) {
-                               if (specs->modedb[i].flag & FB_MODE_IS_FIRST) {
-                                       modedb = specs->modedb[i];
-                                       break;
-                               }
-                       }
-               } else {
-                       /* otherwise, get first mode in database */
-                       modedb = specs->modedb[0];
-               }
+               struct fb_videomode *modedb;
 
-               fb_videomode_to_var(&nvidiafb_default_var, &modedb);
+               modedb = fb_find_best_display(specs, &info->modelist);
+               fb_videomode_to_var(&nvidiafb_default_var, modedb);
                nvidiafb_default_var.bits_per_pixel = 8;
        } else if (par->fpWidth && par->fpHeight) {
                char buf[16];
@@ -1365,7 +1421,7 @@ static int __devinit nvidia_set_fbinfo(struct fb_info *info)
        info->pixmap.flags = FB_PIXMAP_SYSTEM;
 
        if (!hwcur)
-           info->fbops->fb_cursor = soft_cursor;
+           info->fbops->fb_cursor = NULL;
 
        info->var.accel_flags = (!noaccel);
 
@@ -1490,9 +1546,9 @@ static int __devinit nvidiafb_probe(struct pci_dev *pd,
        sprintf(nvidiafb_fix.id, "NV%x", (pd->device & 0x0ff0) >> 4);
 
        par->FlatPanel = flatpanel;
-
        if (flatpanel == 1)
                printk(KERN_INFO PFX "flatpanel support enabled\n");
+       par->FPDither = fpdither;
 
        par->CRTCnumber = forceCRTC;
        par->FpScale = (!noscale);
@@ -1671,6 +1727,8 @@ static int __devinit nvidiafb_setup(char *options)
                } else if (!strncmp(this_opt, "nomtrr", 6)) {
                        nomtrr = 1;
 #endif
+               } else if (!strncmp(this_opt, "fpdither:", 9)) {
+                       fpdither = simple_strtol(this_opt+9, NULL, 0);
                } else
                        mode_option = this_opt;
        }
@@ -1717,7 +1775,11 @@ module_exit(nvidiafb_exit);
 module_param(flatpanel, int, 0);
 MODULE_PARM_DESC(flatpanel,
                 "Enables experimental flat panel support for some chipsets. "
-                "(0 or 1=enabled) (default=0)");
+                "(0=disabled, 1=enabled, -1=autodetect) (default=-1)");
+module_param(fpdither, int, 0);
+MODULE_PARM_DESC(fpdither,
+                "Enables dithering of flat panel for 6 bits panels. "
+                "(0=disabled, 1=enabled, -1=autodetect) (default=-1)");
 module_param(hwcur, int, 0);
 MODULE_PARM_DESC(hwcur,
                 "Enables hardware cursor implementation. (0 or 1=enabled) "
index 611922c0b22fbb8e4906be82b85c446c5351a1a4..2c856838694e1c87187ebe655c418ff0a63ae651 100644 (file)
@@ -85,7 +85,6 @@ static struct fb_ops offb_ops = {
        .fb_fillrect    = cfb_fillrect,
        .fb_copyarea    = cfb_copyarea,
        .fb_imageblit   = cfb_imageblit,
-       .fb_cursor      = soft_cursor,
 };
 
     /*
index b76a5a9a125be4dde6d77959e780aed6fa664391..9aaf65fb623ae99e0df6dc2289c1f7e7379af89d 100644 (file)
@@ -48,7 +48,6 @@ static struct fb_ops p9100_ops = {
        .fb_imageblit           = cfb_imageblit,
        .fb_mmap                = p9100_mmap,
        .fb_ioctl               = p9100_ioctl,
-       .fb_cursor              = soft_cursor,
 };
 
 /* P9100 control registers */
index b00887e9851cf938da8fa6dca5994366ef0982ed..ca4082ae5a18d34313a3a71c7ef2b34b977a484e 100644 (file)
@@ -109,7 +109,6 @@ static struct fb_ops platinumfb_ops = {
        .fb_fillrect    = cfb_fillrect,
        .fb_copyarea    = cfb_copyarea,
        .fb_imageblit   = cfb_imageblit,
-       .fb_cursor      = soft_cursor,
 };
 
 /*
index 42c17efa9fb086befad749eb6e8f58021fef72d8..0277ce031e5e0e3b5e941c71f6d4836ac8c2de3d 100644 (file)
@@ -1034,7 +1034,6 @@ static struct fb_ops pm2fb_ops = {
        .fb_fillrect    = cfb_fillrect,
        .fb_copyarea    = cfb_copyarea,
        .fb_imageblit   = cfb_imageblit,
-       .fb_cursor      = soft_cursor,
 };
 
 /*
@@ -1121,6 +1120,22 @@ static int __devinit pm2fb_probe(struct pci_dev *pdev,
                default_par->mem_control, default_par->boot_address,
                default_par->mem_config);
 
+       if(default_par->mem_control == 0 &&
+               default_par->boot_address == 0x31 &&
+               default_par->mem_config == 0x259fffff &&
+               pdev->subsystem_vendor == 0x1048 &&
+               pdev->subsystem_device == 0x0a31) {
+               DPRINTK("subsystem_vendor: %04x, subsystem_device: %04x\n",
+                       pdev->subsystem_vendor, pdev->subsystem_device);
+               DPRINTK("We have not been initialized by VGA BIOS "
+                       "and are running on an Elsa Winner 2000 Office\n");
+               DPRINTK("Initializing card timings manually...\n");
+               default_par->mem_control=0;
+               default_par->boot_address=0x20;
+               default_par->mem_config=0xe6002021;
+               default_par->memclock=100000;
+       }
+
        /* Now work out how big lfb is going to be. */
        switch(default_par->mem_config & PM2F_MEM_CONFIG_RAM_MASK) {
        case PM2F_MEM_BANKS_1:
index c98f1c8d7dc27b6127fc430ceea517772b1de11d..f3927b6cda9d4d7f6edc8c29a65be8249577e5fc 100644 (file)
@@ -128,7 +128,6 @@ static struct fb_ops pmagbafb_ops = {
        .fb_fillrect    = cfb_fillrect,
        .fb_copyarea    = cfb_copyarea,
        .fb_imageblit   = cfb_imageblit,
-       .fb_cursor      = soft_cursor,
 };
 
 
index a483b13e117b71f93eab7b0e042075b481adf547..25148de5fe6795799999269bd3a92cb0991a0311 100644 (file)
@@ -132,7 +132,6 @@ static struct fb_ops pmagbbfb_ops = {
        .fb_fillrect    = cfb_fillrect,
        .fb_copyarea    = cfb_copyarea,
        .fb_imageblit   = cfb_imageblit,
-       .fb_cursor      = soft_cursor,
 };
 
 
index 31c547fd383bf7d49484667e52a2bf779bbd4018..ec4bacf9dd2e90d2c4b0d696356bdcfff6ee9b53 100644 (file)
@@ -230,7 +230,6 @@ static struct fb_ops pvr2fb_ops = {
        .fb_fillrect    = cfb_fillrect,
        .fb_copyarea    = cfb_copyarea,
        .fb_imageblit   = cfb_imageblit,
-       .fb_cursor      = soft_cursor,
 };
 
 static struct fb_videomode pvr2_modedb[] __initdata = {
index efd9333b05c24001b13a8212be03a91215dbcdaf..f305a5b77b23f8db3311315349a5cb24041ad37f 100644 (file)
@@ -418,7 +418,6 @@ static struct fb_ops pxafb_ops = {
        .fb_copyarea    = cfb_copyarea,
        .fb_imageblit   = cfb_imageblit,
        .fb_blank       = pxafb_blank,
-       .fb_cursor      = soft_cursor,
        .fb_mmap        = pxafb_mmap,
 };
 
index 8416b2e2b501f7cc723f95f55525f21196a429bd..bfc41f2c902a2d93576b3a86f051b927a4e692bd 100644 (file)
@@ -84,7 +84,6 @@ static struct fb_ops q40fb_ops = {
        .fb_fillrect    = cfb_fillrect,
        .fb_copyarea    = cfb_copyarea,
        .fb_imageblit   = cfb_imageblit,
-       .fb_cursor      = soft_cursor,
 };
 
 static int __init q40fb_probe(struct device *device)
index a78b9bd8f89752c856d05e06dc4e74c25faecdad..600318f708f294e2aafd4e2c04aa9767778735b8 100644 (file)
@@ -2218,7 +2218,6 @@ static struct fb_ops radeonfb_ops = {
        .fb_copyarea    = cfb_copyarea,
        .fb_imageblit   = cfb_imageblit,
 #endif
-       .fb_cursor      = soft_cursor,
 };
 
 
index f4437430dc5f1bf1633ebd1e00f2d152ce31f452..3edbd14c5c469565500ce970866d2ef24ee86453 100644 (file)
@@ -388,7 +388,6 @@ static struct fb_ops s1d13xxxfb_fbops = {
        .fb_fillrect    = cfb_fillrect,
        .fb_copyarea    = cfb_copyarea,
        .fb_imageblit   = cfb_imageblit,
-       .fb_cursor      = soft_cursor
 };
 
 static int s1d13xxxfb_width_tab[2][4] __devinitdata = {
index 3cef90456a4b3fb341c10defa60043aad77404b8..855a6778b9eba115879bdbde91d4372f414b9d81 100644 (file)
@@ -495,7 +495,6 @@ static struct fb_ops s3c2410fb_ops = {
        .fb_fillrect    = cfb_fillrect,
        .fb_copyarea    = cfb_copyarea,
        .fb_imageblit   = cfb_imageblit,
-       .fb_cursor      = soft_cursor,
 };
 
 
@@ -885,6 +884,7 @@ static int s3c2410fb_resume(struct device *dev)
 
 static struct device_driver s3c2410fb_driver = {
        .name           = "s3c2410-lcd",
+       .owner          = THIS_MODULE,
        .bus            = &platform_bus_type,
        .probe          = s3c2410fb_probe,
        .suspend        = s3c2410fb_suspend,
index 3d35b28aaac7140affeedd874c4e9e3093b82204..a5184575cfae1696da0709d7db4298d638d93c94 100644 (file)
@@ -853,7 +853,6 @@ static struct fb_ops sa1100fb_ops = {
        .fb_copyarea    = cfb_copyarea,
        .fb_imageblit   = cfb_imageblit,
        .fb_blank       = sa1100fb_blank,
-       .fb_cursor      = soft_cursor,
        .fb_mmap        = sa1100fb_mmap,
 };
 
index ea17f7e0482c31be3ce8275144640a7334d769b1..58cfdfb418333dbd58c763b809e3adcb8a61c705 100644 (file)
@@ -169,6 +169,7 @@ struct savagefb_par {
        struct savagefb_i2c_chan chan;
        unsigned char   *edid;
        u32 pseudo_palette[16];
+       int paletteEnabled;
        int pm_state;
        int display_type;
        int dvi;
@@ -244,105 +245,150 @@ struct savagefb_par {
 
 
 /* IO functions */
+static inline u8 savage_in8(u32 addr, struct savagefb_par *par)
+{
+       return readb(par->mmio.vbase + addr);
+}
+
+static inline u16 savage_in16(u32 addr, struct savagefb_par *par)
+{
+       return readw(par->mmio.vbase + addr);
+}
+
+static inline u32 savage_in32(u32 addr, struct savagefb_par *par)
+{
+       return readl(par->mmio.vbase + addr);
+}
+
+static inline void savage_out8(u32 addr, u8 val, struct savagefb_par *par)
+{
+       writeb(val, par->mmio.vbase + addr);
+}
+
+static inline void savage_out16(u32 addr, u16 val, struct savagefb_par *par)
+{
+       writew(val, par->mmio.vbase + addr);
+}
+
+static inline void savage_out32(u32 addr, u32 val, struct savagefb_par *par)
+{
+       writel(val, par->mmio.vbase + addr);
+}
+
+static inline u8 vga_in8(int addr, struct savagefb_par *par)
+{
+       return savage_in8(0x8000 + addr, par);
+}
+
+static inline u16 vga_in16(int addr, struct savagefb_par *par)
+{
+       return savage_in16(0x8000 + addr, par);
+}
+
+static inline u8 vga_in32(int addr, struct savagefb_par *par)
+{
+       return savage_in32(0x8000 + addr, par);
+}
+
+static inline void vga_out8(int addr, u8 val, struct savagefb_par *par)
+{
+       savage_out8(0x8000 + addr, val, par);
+}
+
+static inline void vga_out16(int addr, u16 val, struct savagefb_par *par)
+{
+       savage_out16(0x8000 + addr, val, par);
+}
+
+static inline void vga_out32(int addr, u32 val, struct savagefb_par *par)
+{
+       savage_out32(0x8000 + addr, val, par);
+}
 
-#define  vga_in8(addr)         (inb (addr))
-#define vga_in16(addr)         (inw (addr))
-#define vga_in32(addr)         (inl (addr))
+static inline u8 VGArCR (u8 index, struct savagefb_par *par)
+{
+       vga_out8(0x3d4, index,  par);
+       return vga_in8(0x3d5, par);
+}
+
+static inline u8 VGArGR (u8 index, struct savagefb_par *par)
+{
+       vga_out8(0x3ce, index, par);
+       return vga_in8(0x3cf, par);
+}
+
+static inline u8 VGArSEQ (u8 index, struct savagefb_par *par)
+{
+       vga_out8(0x3c4, index, par);
+       return vga_in8(0x3c5, par);
+}
 
-#define  vga_out8(addr,val)    (outb ((val), (addr)))
-#define vga_out16(addr,val)    (outw ((val), (addr)))
-#define vga_out32(addr,val)    (outl ((val), (addr)))
+static inline void VGAwCR(u8 index, u8 val, struct savagefb_par *par)
+{
+       vga_out8(0x3d4, index, par);
+       vga_out8(0x3d5, val, par);
+}
 
-#define savage_in16(addr)      readw(par->mmio.vbase + (addr))
-#define savage_in32(addr)      readl(par->mmio.vbase + (addr))
+static inline void VGAwGR(u8 index, u8 val, struct savagefb_par *par)
+{
+       vga_out8(0x3ce, index, par);
+       vga_out8(0x3cf, val, par);
+}
 
-#define savage_out16(addr,val) writew((val), par->mmio.vbase + (addr))
-#define savage_out32(addr,val) writel((val), par->mmio.vbase + (addr))
+static inline void VGAwSEQ(u8 index, u8 val, struct savagefb_par *par)
+{
+       vga_out8(0x3c4, index, par);
+       vga_out8 (0x3c5, val, par);
+}
 
-static inline u8 VGArCR (u8 index)
+static inline void VGAenablePalette(struct savagefb_par *par)
 {
-  outb (index, 0x3d4);
-  return inb (0x3d5);
+       u8 tmp;
+
+       tmp = vga_in8(0x3da, par);
+       vga_out8(0x3c0, 0x00, par);
+       par->paletteEnabled = 1;
 }
 
-static inline u8 VGArGR (u8 index)
+static inline void VGAdisablePalette(struct savagefb_par *par)
 {
-  outb (index, 0x3ce);
-  return inb (0x3cf);
+       u8 tmp;
+
+       tmp = vga_in8(0x3da, par);
+       vga_out8(0x3c0, 0x20, par);
+       par->paletteEnabled = 0;
 }
 
-static inline u8 VGArSEQ (u8 index)
+static inline void VGAwATTR(u8 index, u8 value, struct savagefb_par *par)
 {
-  outb (index, 0x3c4);
-  return inb (0x3c5);
+       u8 tmp;
+
+       if (par->paletteEnabled)
+               index &= ~0x20;
+       else
+               index |= 0x20;
+
+       tmp = vga_in8(0x3da, par);
+       vga_out8(0x3c0, index, par);
+       vga_out8 (0x3c0, value, par);
 }
 
-#define VGAwCR(index, val) \
-do {                       \
-  vga_out8 (0x3d4, index); \
-  vga_out8 (0x3d5, val);   \
-} while (0)
-
-#define VGAwGR(index, val) \
-do {                       \
-  vga_out8 (0x3ce, index); \
-  vga_out8 (0x3cf, val);   \
-} while (0)
-
-#define VGAwSEQ(index, val) \
-do {                        \
-  vga_out8 (0x3c4, index);  \
-  vga_out8 (0x3c5, val);    \
-} while (0)
-
-#define VGAenablePalette() \
-do {                       \
-  u8 tmp;                  \
-                           \
-  tmp = vga_in8 (0x3da);   \
-  vga_out8 (0x3c0, 0x00);  \
-  paletteEnabled = 1;      \
-} while (0)
-
-#define VGAdisablePalette() \
-do {                        \
-  u8 tmp;                   \
-                            \
-  tmp = vga_in8 (0x3da);    \
-  vga_out8 (0x3c0, 0x20);   \
-  paletteEnabled = 0;       \
-} while (0)
-
-#define VGAwATTR(index, value) \
-do {                           \
-  u8 tmp;                      \
-                               \
-  if (paletteEnabled)          \
-    index &= ~0x20;            \
-  else                         \
-    index |= 0x20;             \
-                               \
-  tmp = vga_in8 (0x3da);       \
-  vga_out8 (0x3c0, index);     \
-  vga_out8 (0x3c0, value);     \
-} while (0)
-
-#define VGAwMISC(value)    \
-do {                       \
-  vga_out8 (0x3c2, value); \
-} while (0)
+static inline void VGAwMISC(u8 value, struct savagefb_par *par)
+{
+       vga_out8(0x3c2, value, par);
+}
 
 #ifndef CONFIG_FB_SAVAGE_ACCEL
 #define savagefb_set_clip(x)
 #endif
 
-#define VerticalRetraceWait() \
-{ \
-       vga_out8 (0x3d4, 0x17); \
-       if (vga_in8 (0x3d5) & 0x80) { \
-               while ((vga_in8(0x3da) & 0x08) == 0x08) ; \
-               while ((vga_in8(0x3da) & 0x08) == 0x00) ; \
-       } \
+static inline void VerticalRetraceWait(struct savagefb_par *par)
+{
+       vga_out8(0x3d4, 0x17, par);
+       if (vga_in8(0x3d5, par) & 0x80) {
+               while ((vga_in8(0x3da, par) & 0x08) == 0x08);
+               while ((vga_in8(0x3da, par) & 0x08) == 0x00);
+       }
 }
 
 extern int savagefb_probe_i2c_connector(struct fb_info *info,
index 7c285455c924d5c407f13b5a6b5aba55ebf6b694..f0dfb35e3191b4637e76d085927f3e41dd76e5d0 100644 (file)
@@ -74,7 +74,6 @@
 
 
 static char *mode_option __initdata = NULL;
-static int   paletteEnabled = 0;
 
 #ifdef MODULE
 
@@ -90,9 +89,9 @@ MODULE_DESCRIPTION("FBDev driver for S3 Savage PCI/AGP Chips");
 static void vgaHWSeqReset (struct savagefb_par *par, int start)
 {
        if (start)
-               VGAwSEQ (0x00, 0x01);           /* Synchronous Reset */
+               VGAwSEQ (0x00, 0x01, par);      /* Synchronous Reset */
        else
-               VGAwSEQ (0x00, 0x03);           /* End Reset */
+               VGAwSEQ (0x00, 0x03, par);      /* End Reset */
 }
 
 static void vgaHWProtect (struct savagefb_par *par, int on)
@@ -103,23 +102,23 @@ static void vgaHWProtect (struct savagefb_par *par, int on)
                /*
                 * Turn off screen and disable sequencer.
                 */
-               tmp = VGArSEQ (0x01);
+               tmp = VGArSEQ (0x01, par);
 
                vgaHWSeqReset (par, 1);         /* start synchronous reset */
-               VGAwSEQ (0x01, tmp | 0x20);     /* disable the display */
+               VGAwSEQ (0x01, tmp | 0x20, par);/* disable the display */
 
-               VGAenablePalette();
+               VGAenablePalette(par);
        } else {
                /*
                 * Reenable sequencer, then turn on screen.
                 */
 
-               tmp = VGArSEQ (0x01);
+               tmp = VGArSEQ (0x01, par);
 
-               VGAwSEQ (0x01, tmp & ~0x20);    /* reenable display */
+               VGAwSEQ (0x01, tmp & ~0x20, par);/* reenable display */
                vgaHWSeqReset (par, 0);         /* clear synchronous reset */
 
-               VGAdisablePalette();
+               VGAdisablePalette(par);
        }
 }
 
@@ -127,27 +126,27 @@ static void vgaHWRestore (struct savagefb_par  *par)
 {
        int i;
 
-       VGAwMISC (par->MiscOutReg);
+       VGAwMISC (par->MiscOutReg, par);
 
        for (i = 1; i < 5; i++)
-               VGAwSEQ (i, par->Sequencer[i]);
+               VGAwSEQ (i, par->Sequencer[i], par);
 
        /* Ensure CRTC registers 0-7 are unlocked by clearing bit 7 or
           CRTC[17] */
-       VGAwCR (17, par->CRTC[17] & ~0x80);
+       VGAwCR (17, par->CRTC[17] & ~0x80, par);
 
        for (i = 0; i < 25; i++)
-               VGAwCR (i, par->CRTC[i]);
+               VGAwCR (i, par->CRTC[i], par);
 
        for (i = 0; i < 9; i++)
-               VGAwGR (i, par->Graphics[i]);
+               VGAwGR (i, par->Graphics[i], par);
 
-       VGAenablePalette();
+       VGAenablePalette(par);
 
        for (i = 0; i < 21; i++)
-               VGAwATTR (i, par->Attribute[i]);
+               VGAwATTR (i, par->Attribute[i], par);
 
-       VGAdisablePalette();
+       VGAdisablePalette(par);
 }
 
 static void vgaHWInit (struct fb_var_screeninfo *var,
@@ -267,7 +266,7 @@ savage3D_waitfifo(struct savagefb_par *par, int space)
 {
        int slots = MAXFIFO - space;
 
-       while ((savage_in32(0x48C00) & 0x0000ffff) > slots);
+       while ((savage_in32(0x48C00, par) & 0x0000ffff) > slots);
 }
 
 static void
@@ -275,7 +274,7 @@ savage4_waitfifo(struct savagefb_par *par, int space)
 {
        int slots = MAXFIFO - space;
 
-       while ((savage_in32(0x48C60) & 0x001fffff) > slots);
+       while ((savage_in32(0x48C60, par) & 0x001fffff) > slots);
 }
 
 static void
@@ -283,26 +282,26 @@ savage2000_waitfifo(struct savagefb_par *par, int space)
 {
        int slots = MAXFIFO - space;
 
-       while ((savage_in32(0x48C60) & 0x0000ffff) > slots);
+       while ((savage_in32(0x48C60, par) & 0x0000ffff) > slots);
 }
 
 /* Wait for idle accelerator */
 static void
 savage3D_waitidle(struct savagefb_par *par)
 {
-       while ((savage_in32(0x48C00) & 0x0008ffff) != 0x80000);
+       while ((savage_in32(0x48C00, par) & 0x0008ffff) != 0x80000);
 }
 
 static void
 savage4_waitidle(struct savagefb_par *par)
 {
-       while ((savage_in32(0x48C60) & 0x00a00000) != 0x00a00000);
+       while ((savage_in32(0x48C60, par) & 0x00a00000) != 0x00a00000);
 }
 
 static void
 savage2000_waitidle(struct savagefb_par *par)
 {
-       while ((savage_in32(0x48C60) & 0x009fffff));
+       while ((savage_in32(0x48C60, par) & 0x009fffff));
 }
 
 
@@ -319,59 +318,64 @@ SavageSetup2DEngine (struct savagefb_par  *par)
        case S3_SAVAGE3D:
        case S3_SAVAGE_MX:
                /* Disable BCI */
-               savage_out32(0x48C18, savage_in32(0x48C18) & 0x3FF0);
+               savage_out32(0x48C18, savage_in32(0x48C18, par) & 0x3FF0, par);
                /* Setup BCI command overflow buffer */
-               savage_out32(0x48C14, (par->cob_offset >> 11) | (par->cob_index << 29));
+               savage_out32(0x48C14,
+                            (par->cob_offset >> 11) | (par->cob_index << 29),
+                            par);
                /* Program shadow status update. */
-               savage_out32(0x48C10, 0x78207220);
-               savage_out32(0x48C0C, 0);
+               savage_out32(0x48C10, 0x78207220, par);
+               savage_out32(0x48C0C, 0, par);
                /* Enable BCI and command overflow buffer */
-               savage_out32(0x48C18, savage_in32(0x48C18) | 0x0C);
+               savage_out32(0x48C18, savage_in32(0x48C18, par) | 0x0C, par);
                break;
        case S3_SAVAGE4:
        case S3_PROSAVAGE:
        case S3_SUPERSAVAGE:
                /* Disable BCI */
-               savage_out32(0x48C18, savage_in32(0x48C18) & 0x3FF0);
+               savage_out32(0x48C18, savage_in32(0x48C18, par) & 0x3FF0, par);
                /* Program shadow status update */
-               savage_out32(0x48C10, 0x00700040);
-               savage_out32(0x48C0C, 0);
+               savage_out32(0x48C10, 0x00700040, par);
+               savage_out32(0x48C0C, 0, par);
                /* Enable BCI without the COB */
-               savage_out32(0x48C18, savage_in32(0x48C18) | 0x08);
+               savage_out32(0x48C18, savage_in32(0x48C18, par) | 0x08, par);
                break;
        case S3_SAVAGE2000:
                /* Disable BCI */
-               savage_out32(0x48C18, 0);
+               savage_out32(0x48C18, 0, par);
                /* Setup BCI command overflow buffer */
-               savage_out32(0x48C18, (par->cob_offset >> 7) | (par->cob_index));
+               savage_out32(0x48C18,
+                            (par->cob_offset >> 7) | (par->cob_index),
+                            par);
                /* Disable shadow status update */
-               savage_out32(0x48A30, 0);
+               savage_out32(0x48A30, 0, par);
                /* Enable BCI and command overflow buffer */
-               savage_out32(0x48C18, savage_in32(0x48C18) | 0x00280000 );
+               savage_out32(0x48C18, savage_in32(0x48C18, par) | 0x00280000,
+                            par);
                break;
            default:
                break;
        }
        /* Turn on 16-bit register access. */
-       vga_out8(0x3d4, 0x31);
-       vga_out8(0x3d5, 0x0c);
+       vga_out8(0x3d4, 0x31, par);
+       vga_out8(0x3d5, 0x0c, par);
 
        /* Set stride to use GBD. */
-       vga_out8 (0x3d4, 0x50);
-       vga_out8 (0x3d5, vga_in8 (0x3d5 ) | 0xC1);
+       vga_out8 (0x3d4, 0x50, par);
+       vga_out8 (0x3d5, vga_in8(0x3d5, par) | 0xC1, par);
 
        /* Enable 2D engine. */
-       vga_out8 (0x3d4, 0x40 );
-       vga_out8 (0x3d5, 0x01 );
+       vga_out8 (0x3d4, 0x40, par);
+       vga_out8 (0x3d5, 0x01, par);
 
-       savage_out32 (MONO_PAT_0, ~0);
-       savage_out32 (MONO_PAT_1, ~0);
+       savage_out32 (MONO_PAT_0, ~0, par);
+       savage_out32 (MONO_PAT_1, ~0, par);
 
        /* Setup plane masks */
-       savage_out32 (0x8128, ~0 ); /* enable all write planes */
-       savage_out32 (0x812C, ~0 ); /* enable all read planes */
-       savage_out16 (0x8134, 0x27 );
-       savage_out16 (0x8136, 0x07 );
+       savage_out32 (0x8128, ~0, par); /* enable all write planes */
+       savage_out32 (0x812C, ~0, par); /* enable all read planes */
+       savage_out16 (0x8134, 0x27, par);
+       savage_out16 (0x8136, 0x07, par);
 
        /* Now set the GBD */
        par->bci_ptr = 0;
@@ -489,8 +493,8 @@ static void SavagePrintRegs(void)
        for( i = 0; i < 0x70; i++ ) {
                if( !(i % 16) )
                        printk(KERN_DEBUG "\nSR%xx ", i >> 4 );
-               vga_out8( 0x3c4, i );
-               printk(KERN_DEBUG " %02x", vga_in8(0x3c5) );
+               vga_out8( 0x3c4, i, par);
+               printk(KERN_DEBUG " %02x", vga_in8(0x3c5, par) );
        }
 
        printk(KERN_DEBUG "\n\nCR    x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC "
@@ -499,8 +503,8 @@ static void SavagePrintRegs(void)
        for( i = 0; i < 0xB7; i++ ) {
                if( !(i % 16) )
                        printk(KERN_DEBUG "\nCR%xx ", i >> 4 );
-               vga_out8( vgaCRIndex, i );
-               printk(KERN_DEBUG " %02x", vga_in8(vgaCRReg) );
+               vga_out8( vgaCRIndex, i, par);
+               printk(KERN_DEBUG " %02x", vga_in8(vgaCRReg, par) );
        }
 
        printk(KERN_DEBUG "\n\n");
@@ -513,152 +517,152 @@ static void savage_get_default_par(struct savagefb_par *par)
 {
        unsigned char cr3a, cr53, cr66;
 
-       vga_out16 (0x3d4, 0x4838);
-       vga_out16 (0x3d4, 0xa039);
-       vga_out16 (0x3c4, 0x0608);
-
-       vga_out8 (0x3d4, 0x66);
-       cr66 = vga_in8 (0x3d5);
-       vga_out8 (0x3d5, cr66 | 0x80);
-       vga_out8 (0x3d4, 0x3a);
-       cr3a = vga_in8 (0x3d5);
-       vga_out8 (0x3d5, cr3a | 0x80);
-       vga_out8 (0x3d4, 0x53);
-       cr53 = vga_in8 (0x3d5);
-       vga_out8 (0x3d5, cr53 & 0x7f);
-
-       vga_out8 (0x3d4, 0x66);
-       vga_out8 (0x3d5, cr66);
-       vga_out8 (0x3d4, 0x3a);
-       vga_out8 (0x3d5, cr3a);
-
-       vga_out8 (0x3d4, 0x66);
-       vga_out8 (0x3d5, cr66);
-       vga_out8 (0x3d4, 0x3a);
-       vga_out8 (0x3d5, cr3a);
+       vga_out16 (0x3d4, 0x4838, par);
+       vga_out16 (0x3d4, 0xa039, par);
+       vga_out16 (0x3c4, 0x0608, par);
+
+       vga_out8 (0x3d4, 0x66, par);
+       cr66 = vga_in8 (0x3d5, par);
+       vga_out8 (0x3d5, cr66 | 0x80, par);
+       vga_out8 (0x3d4, 0x3a, par);
+       cr3a = vga_in8 (0x3d5, par);
+       vga_out8 (0x3d5, cr3a | 0x80, par);
+       vga_out8 (0x3d4, 0x53, par);
+       cr53 = vga_in8 (0x3d5, par);
+       vga_out8 (0x3d5, cr53 & 0x7f, par);
+
+       vga_out8 (0x3d4, 0x66, par);
+       vga_out8 (0x3d5, cr66, par);
+       vga_out8 (0x3d4, 0x3a, par);
+       vga_out8 (0x3d5, cr3a, par);
+
+       vga_out8 (0x3d4, 0x66, par);
+       vga_out8 (0x3d5, cr66, par);
+       vga_out8 (0x3d4, 0x3a, par);
+       vga_out8 (0x3d5, cr3a, par);
 
        /* unlock extended seq regs */
-       vga_out8 (0x3c4, 0x08);
-       par->SR08 = vga_in8 (0x3c5);
-       vga_out8 (0x3c5, 0x06);
+       vga_out8 (0x3c4, 0x08, par);
+       par->SR08 = vga_in8 (0x3c5, par);
+       vga_out8 (0x3c5, 0x06, par);
 
        /* now save all the extended regs we need */
-       vga_out8 (0x3d4, 0x31);
-       par->CR31 = vga_in8 (0x3d5);
-       vga_out8 (0x3d4, 0x32);
-       par->CR32 = vga_in8 (0x3d5);
-       vga_out8 (0x3d4, 0x34);
-       par->CR34 = vga_in8 (0x3d5);
-       vga_out8 (0x3d4, 0x36);
-       par->CR36 = vga_in8 (0x3d5);
-       vga_out8 (0x3d4, 0x3a);
-       par->CR3A = vga_in8 (0x3d5);
-       vga_out8 (0x3d4, 0x40);
-       par->CR40 = vga_in8 (0x3d5);
-       vga_out8 (0x3d4, 0x42);
-       par->CR42 = vga_in8 (0x3d5);
-       vga_out8 (0x3d4, 0x45);
-       par->CR45 = vga_in8 (0x3d5);
-       vga_out8 (0x3d4, 0x50);
-       par->CR50 = vga_in8 (0x3d5);
-       vga_out8 (0x3d4, 0x51);
-       par->CR51 = vga_in8 (0x3d5);
-       vga_out8 (0x3d4, 0x53);
-       par->CR53 = vga_in8 (0x3d5);
-       vga_out8 (0x3d4, 0x58);
-       par->CR58 = vga_in8 (0x3d5);
-       vga_out8 (0x3d4, 0x60);
-       par->CR60 = vga_in8 (0x3d5);
-       vga_out8 (0x3d4, 0x66);
-       par->CR66 = vga_in8 (0x3d5);
-       vga_out8 (0x3d4, 0x67);
-       par->CR67 = vga_in8 (0x3d5);
-       vga_out8 (0x3d4, 0x68);
-       par->CR68 = vga_in8 (0x3d5);
-       vga_out8 (0x3d4, 0x69);
-       par->CR69 = vga_in8 (0x3d5);
-       vga_out8 (0x3d4, 0x6f);
-       par->CR6F = vga_in8 (0x3d5);
-
-       vga_out8 (0x3d4, 0x33);
-       par->CR33 = vga_in8 (0x3d5);
-       vga_out8 (0x3d4, 0x86);
-       par->CR86 = vga_in8 (0x3d5);
-       vga_out8 (0x3d4, 0x88);
-       par->CR88 = vga_in8 (0x3d5);
-       vga_out8 (0x3d4, 0x90);
-       par->CR90 = vga_in8 (0x3d5);
-       vga_out8 (0x3d4, 0x91);
-       par->CR91 = vga_in8 (0x3d5);
-       vga_out8 (0x3d4, 0xb0);
-       par->CRB0 = vga_in8 (0x3d5) | 0x80;
+       vga_out8 (0x3d4, 0x31, par);
+       par->CR31 = vga_in8 (0x3d5, par);
+       vga_out8 (0x3d4, 0x32, par);
+       par->CR32 = vga_in8 (0x3d5, par);
+       vga_out8 (0x3d4, 0x34, par);
+       par->CR34 = vga_in8 (0x3d5, par);
+       vga_out8 (0x3d4, 0x36, par);
+       par->CR36 = vga_in8 (0x3d5, par);
+       vga_out8 (0x3d4, 0x3a, par);
+       par->CR3A = vga_in8 (0x3d5, par);
+       vga_out8 (0x3d4, 0x40, par);
+       par->CR40 = vga_in8 (0x3d5, par);
+       vga_out8 (0x3d4, 0x42, par);
+       par->CR42 = vga_in8 (0x3d5, par);
+       vga_out8 (0x3d4, 0x45, par);
+       par->CR45 = vga_in8 (0x3d5, par);
+       vga_out8 (0x3d4, 0x50, par);
+       par->CR50 = vga_in8 (0x3d5, par);
+       vga_out8 (0x3d4, 0x51, par);
+       par->CR51 = vga_in8 (0x3d5, par);
+       vga_out8 (0x3d4, 0x53, par);
+       par->CR53 = vga_in8 (0x3d5, par);
+       vga_out8 (0x3d4, 0x58, par);
+       par->CR58 = vga_in8 (0x3d5, par);
+       vga_out8 (0x3d4, 0x60, par);
+       par->CR60 = vga_in8 (0x3d5, par);
+       vga_out8 (0x3d4, 0x66, par);
+       par->CR66 = vga_in8 (0x3d5, par);
+       vga_out8 (0x3d4, 0x67, par);
+       par->CR67 = vga_in8 (0x3d5, par);
+       vga_out8 (0x3d4, 0x68, par);
+       par->CR68 = vga_in8 (0x3d5, par);
+       vga_out8 (0x3d4, 0x69, par);
+       par->CR69 = vga_in8 (0x3d5, par);
+       vga_out8 (0x3d4, 0x6f, par);
+       par->CR6F = vga_in8 (0x3d5, par);
+
+       vga_out8 (0x3d4, 0x33, par);
+       par->CR33 = vga_in8 (0x3d5, par);
+       vga_out8 (0x3d4, 0x86, par);
+       par->CR86 = vga_in8 (0x3d5, par);
+       vga_out8 (0x3d4, 0x88, par);
+       par->CR88 = vga_in8 (0x3d5, par);
+       vga_out8 (0x3d4, 0x90, par);
+       par->CR90 = vga_in8 (0x3d5, par);
+       vga_out8 (0x3d4, 0x91, par);
+       par->CR91 = vga_in8 (0x3d5, par);
+       vga_out8 (0x3d4, 0xb0, par);
+       par->CRB0 = vga_in8 (0x3d5, par) | 0x80;
 
        /* extended mode timing regs */
-       vga_out8 (0x3d4, 0x3b);
-       par->CR3B = vga_in8 (0x3d5);
-       vga_out8 (0x3d4, 0x3c);
-       par->CR3C = vga_in8 (0x3d5);
-       vga_out8 (0x3d4, 0x43);
-       par->CR43 = vga_in8 (0x3d5);
-       vga_out8 (0x3d4, 0x5d);
-       par->CR5D = vga_in8 (0x3d5);
-       vga_out8 (0x3d4, 0x5e);
-       par->CR5E = vga_in8 (0x3d5);
-       vga_out8 (0x3d4, 0x65);
-       par->CR65 = vga_in8 (0x3d5);
+       vga_out8 (0x3d4, 0x3b, par);
+       par->CR3B = vga_in8 (0x3d5, par);
+       vga_out8 (0x3d4, 0x3c, par);
+       par->CR3C = vga_in8 (0x3d5, par);
+       vga_out8 (0x3d4, 0x43, par);
+       par->CR43 = vga_in8 (0x3d5, par);
+       vga_out8 (0x3d4, 0x5d, par);
+       par->CR5D = vga_in8 (0x3d5, par);
+       vga_out8 (0x3d4, 0x5e, par);
+       par->CR5E = vga_in8 (0x3d5, par);
+       vga_out8 (0x3d4, 0x65, par);
+       par->CR65 = vga_in8 (0x3d5, par);
 
        /* save seq extended regs for DCLK PLL programming */
-       vga_out8 (0x3c4, 0x0e);
-       par->SR0E = vga_in8 (0x3c5);
-       vga_out8 (0x3c4, 0x0f);
-       par->SR0F = vga_in8 (0x3c5);
-       vga_out8 (0x3c4, 0x10);
-       par->SR10 = vga_in8 (0x3c5);
-       vga_out8 (0x3c4, 0x11);
-       par->SR11 = vga_in8 (0x3c5);
-       vga_out8 (0x3c4, 0x12);
-       par->SR12 = vga_in8 (0x3c5);
-       vga_out8 (0x3c4, 0x13);
-       par->SR13 = vga_in8 (0x3c5);
-       vga_out8 (0x3c4, 0x29);
-       par->SR29 = vga_in8 (0x3c5);
-
-       vga_out8 (0x3c4, 0x15);
-       par->SR15 = vga_in8 (0x3c5);
-       vga_out8 (0x3c4, 0x30);
-       par->SR30 = vga_in8 (0x3c5);
-       vga_out8 (0x3c4, 0x18);
-       par->SR18 = vga_in8 (0x3c5);
+       vga_out8 (0x3c4, 0x0e, par);
+       par->SR0E = vga_in8 (0x3c5, par);
+       vga_out8 (0x3c4, 0x0f, par);
+       par->SR0F = vga_in8 (0x3c5, par);
+       vga_out8 (0x3c4, 0x10, par);
+       par->SR10 = vga_in8 (0x3c5, par);
+       vga_out8 (0x3c4, 0x11, par);
+       par->SR11 = vga_in8 (0x3c5, par);
+       vga_out8 (0x3c4, 0x12, par);
+       par->SR12 = vga_in8 (0x3c5, par);
+       vga_out8 (0x3c4, 0x13, par);
+       par->SR13 = vga_in8 (0x3c5, par);
+       vga_out8 (0x3c4, 0x29, par);
+       par->SR29 = vga_in8 (0x3c5, par);
+
+       vga_out8 (0x3c4, 0x15, par);
+       par->SR15 = vga_in8 (0x3c5, par);
+       vga_out8 (0x3c4, 0x30, par);
+       par->SR30 = vga_in8 (0x3c5, par);
+       vga_out8 (0x3c4, 0x18, par);
+       par->SR18 = vga_in8 (0x3c5, par);
 
        /* Save flat panel expansion regsters. */
        if (par->chip == S3_SAVAGE_MX) {
                int i;
 
                for (i = 0; i < 8; i++) {
-                       vga_out8 (0x3c4, 0x54+i);
-                       par->SR54[i] = vga_in8 (0x3c5);
+                       vga_out8 (0x3c4, 0x54+i, par);
+                       par->SR54[i] = vga_in8 (0x3c5, par);
                }
        }
 
-       vga_out8 (0x3d4, 0x66);
-       cr66 = vga_in8 (0x3d5);
-       vga_out8 (0x3d5, cr66 | 0x80);
-       vga_out8 (0x3d4, 0x3a);
-       cr3a = vga_in8 (0x3d5);
-       vga_out8 (0x3d5, cr3a | 0x80);
+       vga_out8 (0x3d4, 0x66, par);
+       cr66 = vga_in8 (0x3d5, par);
+       vga_out8 (0x3d5, cr66 | 0x80, par);
+       vga_out8 (0x3d4, 0x3a, par);
+       cr3a = vga_in8 (0x3d5, par);
+       vga_out8 (0x3d5, cr3a | 0x80, par);
 
        /* now save MIU regs */
        if (par->chip != S3_SAVAGE_MX) {
-               par->MMPR0 = savage_in32(FIFO_CONTROL_REG);
-               par->MMPR1 = savage_in32(MIU_CONTROL_REG);
-               par->MMPR2 = savage_in32(STREAMS_TIMEOUT_REG);
-               par->MMPR3 = savage_in32(MISC_TIMEOUT_REG);
+               par->MMPR0 = savage_in32(FIFO_CONTROL_REG, par);
+               par->MMPR1 = savage_in32(MIU_CONTROL_REG, par);
+               par->MMPR2 = savage_in32(STREAMS_TIMEOUT_REG, par);
+               par->MMPR3 = savage_in32(MISC_TIMEOUT_REG, par);
        }
 
-       vga_out8 (0x3d4, 0x3a);
-       vga_out8 (0x3d5, cr3a);
-       vga_out8 (0x3d4, 0x66);
-       vga_out8 (0x3d5, cr66);
+       vga_out8 (0x3d4, 0x3a, par);
+       vga_out8 (0x3d5, cr3a, par);
+       vga_out8 (0x3d4, 0x66, par);
+       vga_out8 (0x3d5, cr66, par);
 }
 
 static void savage_update_var(struct fb_var_screeninfo *var, struct fb_videomode *modedb)
@@ -868,8 +872,8 @@ static int savagefb_decode_var (struct fb_var_screeninfo   *var,
         * match.  Fall back to traditional register-crunching.
         */
 
-       vga_out8 (0x3d4, 0x3a);
-       tmp = vga_in8 (0x3d5);
+       vga_out8 (0x3d4, 0x3a, par);
+       tmp = vga_in8 (0x3d5, par);
        if (1 /*FIXME:psav->pci_burst*/)
                par->CR3A = (tmp & 0x7f) | 0x15;
        else
@@ -879,16 +883,16 @@ static int savagefb_decode_var (struct fb_var_screeninfo   *var,
        par->CR31 = 0x8c;
        par->CR66 = 0x89;
 
-       vga_out8 (0x3d4, 0x58);
-       par->CR58 = vga_in8 (0x3d5) & 0x80;
+       vga_out8 (0x3d4, 0x58, par);
+       par->CR58 = vga_in8 (0x3d5, par) & 0x80;
        par->CR58 |= 0x13;
 
        par->SR15 = 0x03 | 0x80;
        par->SR18 = 0x00;
        par->CR43 = par->CR45 = par->CR65 = 0x00;
 
-       vga_out8 (0x3d4, 0x40);
-       par->CR40 = vga_in8 (0x3d5) & ~0x01;
+       vga_out8 (0x3d4, 0x40, par);
+       par->CR40 = vga_in8 (0x3d5, par) & ~0x01;
 
        par->MMPR0 = 0x010400;
        par->MMPR1 = 0x00;
@@ -992,19 +996,19 @@ static int savagefb_decode_var (struct fb_var_screeninfo   *var,
 
        par->CR67 |= 1;
 
-       vga_out8(0x3d4, 0x36);
-       par->CR36 = vga_in8 (0x3d5);
-       vga_out8 (0x3d4, 0x68);
-       par->CR68 = vga_in8 (0x3d5);
+       vga_out8(0x3d4, 0x36, par);
+       par->CR36 = vga_in8 (0x3d5, par);
+       vga_out8 (0x3d4, 0x68, par);
+       par->CR68 = vga_in8 (0x3d5, par);
        par->CR69 = 0;
-       vga_out8 (0x3d4, 0x6f);
-       par->CR6F = vga_in8 (0x3d5);
-       vga_out8 (0x3d4, 0x86);
-       par->CR86 = vga_in8 (0x3d5);
-       vga_out8 (0x3d4, 0x88);
-       par->CR88 = vga_in8 (0x3d5) | 0x08;
-       vga_out8 (0x3d4, 0xb0);
-       par->CRB0 = vga_in8 (0x3d5) | 0x80;
+       vga_out8 (0x3d4, 0x6f, par);
+       par->CR6F = vga_in8 (0x3d5, par);
+       vga_out8 (0x3d4, 0x86, par);
+       par->CR86 = vga_in8 (0x3d5, par);
+       vga_out8 (0x3d4, 0x88, par);
+       par->CR88 = vga_in8 (0x3d5, par) | 0x08;
+       vga_out8 (0x3d4, 0xb0, par);
+       par->CRB0 = vga_in8 (0x3d5, par) | 0x80;
 
        return 0;
 }
@@ -1033,11 +1037,11 @@ static int savagefb_setcolreg(unsigned        regno,
 
        switch (info->var.bits_per_pixel) {
        case 8:
-               vga_out8 (0x3c8, regno);
+               vga_out8 (0x3c8, regno, par);
 
-               vga_out8 (0x3c9, red   >> 10);
-               vga_out8 (0x3c9, green >> 10);
-               vga_out8 (0x3c9, blue  >> 10);
+               vga_out8 (0x3c9, red   >> 10, par);
+               vga_out8 (0x3c9, green >> 10, par);
+               vga_out8 (0x3c9, blue  >> 10, par);
                break;
 
        case 16:
@@ -1079,11 +1083,11 @@ static void savagefb_set_par_int (struct savagefb_par  *par)
 
        par->SavageWaitIdle (par);
 
-       vga_out8 (0x3c2, 0x23);
+       vga_out8 (0x3c2, 0x23, par);
 
-       vga_out16 (0x3d4, 0x4838);
-       vga_out16 (0x3d4, 0xa539);
-       vga_out16 (0x3c4, 0x0608);
+       vga_out16 (0x3d4, 0x4838, par);
+       vga_out16 (0x3d4, 0xa539, par);
+       vga_out16 (0x3c4, 0x0608, par);
 
        vgaHWProtect (par, 1);
 
@@ -1094,197 +1098,197 @@ static void savagefb_set_par_int (struct savagefb_par  *par)
         * switch to mode 3 here seems to eliminate the issue.
         */
 
-       VerticalRetraceWait();
-       vga_out8 (0x3d4, 0x67);
-       cr67 = vga_in8 (0x3d5);
-       vga_out8 (0x3d5, cr67/*par->CR67*/ & ~0x0c); /* no STREAMS yet */
+       VerticalRetraceWait(par);
+       vga_out8 (0x3d4, 0x67, par);
+       cr67 = vga_in8 (0x3d5, par);
+       vga_out8 (0x3d5, cr67/*par->CR67*/ & ~0x0c, par); /* no STREAMS yet */
 
-       vga_out8 (0x3d4, 0x23);
-       vga_out8 (0x3d5, 0x00);
-       vga_out8 (0x3d4, 0x26);
-       vga_out8 (0x3d5, 0x00);
+       vga_out8 (0x3d4, 0x23, par);
+       vga_out8 (0x3d5, 0x00, par);
+       vga_out8 (0x3d4, 0x26, par);
+       vga_out8 (0x3d5, 0x00, par);
 
        /* restore extended regs */
-       vga_out8 (0x3d4, 0x66);
-       vga_out8 (0x3d5, par->CR66);
-       vga_out8 (0x3d4, 0x3a);
-       vga_out8 (0x3d5, par->CR3A);
-       vga_out8 (0x3d4, 0x31);
-       vga_out8 (0x3d5, par->CR31);
-       vga_out8 (0x3d4, 0x32);
-       vga_out8 (0x3d5, par->CR32);
-       vga_out8 (0x3d4, 0x58);
-       vga_out8 (0x3d5, par->CR58);
-       vga_out8 (0x3d4, 0x53);
-       vga_out8 (0x3d5, par->CR53 & 0x7f);
-
-       vga_out16 (0x3c4, 0x0608);
+       vga_out8 (0x3d4, 0x66, par);
+       vga_out8 (0x3d5, par->CR66, par);
+       vga_out8 (0x3d4, 0x3a, par);
+       vga_out8 (0x3d5, par->CR3A, par);
+       vga_out8 (0x3d4, 0x31, par);
+       vga_out8 (0x3d5, par->CR31, par);
+       vga_out8 (0x3d4, 0x32, par);
+       vga_out8 (0x3d5, par->CR32, par);
+       vga_out8 (0x3d4, 0x58, par);
+       vga_out8 (0x3d5, par->CR58, par);
+       vga_out8 (0x3d4, 0x53, par);
+       vga_out8 (0x3d5, par->CR53 & 0x7f, par);
+
+       vga_out16 (0x3c4, 0x0608, par);
 
        /* Restore DCLK registers. */
 
-       vga_out8 (0x3c4, 0x0e);
-       vga_out8 (0x3c5, par->SR0E);
-       vga_out8 (0x3c4, 0x0f);
-       vga_out8 (0x3c5, par->SR0F);
-       vga_out8 (0x3c4, 0x29);
-       vga_out8 (0x3c5, par->SR29);
-       vga_out8 (0x3c4, 0x15);
-       vga_out8 (0x3c5, par->SR15);
+       vga_out8 (0x3c4, 0x0e, par);
+       vga_out8 (0x3c5, par->SR0E, par);
+       vga_out8 (0x3c4, 0x0f, par);
+       vga_out8 (0x3c5, par->SR0F, par);
+       vga_out8 (0x3c4, 0x29, par);
+       vga_out8 (0x3c5, par->SR29, par);
+       vga_out8 (0x3c4, 0x15, par);
+       vga_out8 (0x3c5, par->SR15, par);
 
        /* Restore flat panel expansion regsters. */
        if( par->chip == S3_SAVAGE_MX ) {
                int i;
 
                for( i = 0; i < 8; i++ ) {
-                       vga_out8 (0x3c4, 0x54+i);
-                       vga_out8 (0x3c5, par->SR54[i]);
+                       vga_out8 (0x3c4, 0x54+i, par);
+                       vga_out8 (0x3c5, par->SR54[i], par);
                }
        }
 
        vgaHWRestore (par);
 
        /* extended mode timing registers */
-       vga_out8 (0x3d4, 0x53);
-       vga_out8 (0x3d5, par->CR53);
-       vga_out8 (0x3d4, 0x5d);
-       vga_out8 (0x3d5, par->CR5D);
-       vga_out8 (0x3d4, 0x5e);
-       vga_out8 (0x3d5, par->CR5E);
-       vga_out8 (0x3d4, 0x3b);
-       vga_out8 (0x3d5, par->CR3B);
-       vga_out8 (0x3d4, 0x3c);
-       vga_out8 (0x3d5, par->CR3C);
-       vga_out8 (0x3d4, 0x43);
-       vga_out8 (0x3d5, par->CR43);
-       vga_out8 (0x3d4, 0x65);
-       vga_out8 (0x3d5, par->CR65);
+       vga_out8 (0x3d4, 0x53, par);
+       vga_out8 (0x3d5, par->CR53, par);
+       vga_out8 (0x3d4, 0x5d, par);
+       vga_out8 (0x3d5, par->CR5D, par);
+       vga_out8 (0x3d4, 0x5e, par);
+       vga_out8 (0x3d5, par->CR5E, par);
+       vga_out8 (0x3d4, 0x3b, par);
+       vga_out8 (0x3d5, par->CR3B, par);
+       vga_out8 (0x3d4, 0x3c, par);
+       vga_out8 (0x3d5, par->CR3C, par);
+       vga_out8 (0x3d4, 0x43, par);
+       vga_out8 (0x3d5, par->CR43, par);
+       vga_out8 (0x3d4, 0x65, par);
+       vga_out8 (0x3d5, par->CR65, par);
 
        /* restore the desired video mode with cr67 */
-       vga_out8 (0x3d4, 0x67);
+       vga_out8 (0x3d4, 0x67, par);
        /* following part not present in X11 driver */
-       cr67 = vga_in8 (0x3d5) & 0xf;
-       vga_out8 (0x3d5, 0x50 | cr67);
+       cr67 = vga_in8 (0x3d5, par) & 0xf;
+       vga_out8 (0x3d5, 0x50 | cr67, par);
        udelay (10000);
-       vga_out8 (0x3d4, 0x67);
+       vga_out8 (0x3d4, 0x67, par);
        /* end of part */
-       vga_out8 (0x3d5, par->CR67 & ~0x0c);
+       vga_out8 (0x3d5, par->CR67 & ~0x0c, par);
 
        /* other mode timing and extended regs */
-       vga_out8 (0x3d4, 0x34);
-       vga_out8 (0x3d5, par->CR34);
-       vga_out8 (0x3d4, 0x40);
-       vga_out8 (0x3d5, par->CR40);
-       vga_out8 (0x3d4, 0x42);
-       vga_out8 (0x3d5, par->CR42);
-       vga_out8 (0x3d4, 0x45);
-       vga_out8 (0x3d5, par->CR45);
-       vga_out8 (0x3d4, 0x50);
-       vga_out8 (0x3d5, par->CR50);
-       vga_out8 (0x3d4, 0x51);
-       vga_out8 (0x3d5, par->CR51);
+       vga_out8 (0x3d4, 0x34, par);
+       vga_out8 (0x3d5, par->CR34, par);
+       vga_out8 (0x3d4, 0x40, par);
+       vga_out8 (0x3d5, par->CR40, par);
+       vga_out8 (0x3d4, 0x42, par);
+       vga_out8 (0x3d5, par->CR42, par);
+       vga_out8 (0x3d4, 0x45, par);
+       vga_out8 (0x3d5, par->CR45, par);
+       vga_out8 (0x3d4, 0x50, par);
+       vga_out8 (0x3d5, par->CR50, par);
+       vga_out8 (0x3d4, 0x51, par);
+       vga_out8 (0x3d5, par->CR51, par);
 
        /* memory timings */
-       vga_out8 (0x3d4, 0x36);
-       vga_out8 (0x3d5, par->CR36);
-       vga_out8 (0x3d4, 0x60);
-       vga_out8 (0x3d5, par->CR60);
-       vga_out8 (0x3d4, 0x68);
-       vga_out8 (0x3d5, par->CR68);
-       vga_out8 (0x3d4, 0x69);
-       vga_out8 (0x3d5, par->CR69);
-       vga_out8 (0x3d4, 0x6f);
-       vga_out8 (0x3d5, par->CR6F);
-
-       vga_out8 (0x3d4, 0x33);
-       vga_out8 (0x3d5, par->CR33);
-       vga_out8 (0x3d4, 0x86);
-       vga_out8 (0x3d5, par->CR86);
-       vga_out8 (0x3d4, 0x88);
-       vga_out8 (0x3d5, par->CR88);
-       vga_out8 (0x3d4, 0x90);
-       vga_out8 (0x3d5, par->CR90);
-       vga_out8 (0x3d4, 0x91);
-       vga_out8 (0x3d5, par->CR91);
+       vga_out8 (0x3d4, 0x36, par);
+       vga_out8 (0x3d5, par->CR36, par);
+       vga_out8 (0x3d4, 0x60, par);
+       vga_out8 (0x3d5, par->CR60, par);
+       vga_out8 (0x3d4, 0x68, par);
+       vga_out8 (0x3d5, par->CR68, par);
+       vga_out8 (0x3d4, 0x69, par);
+       vga_out8 (0x3d5, par->CR69, par);
+       vga_out8 (0x3d4, 0x6f, par);
+       vga_out8 (0x3d5, par->CR6F, par);
+
+       vga_out8 (0x3d4, 0x33, par);
+       vga_out8 (0x3d5, par->CR33, par);
+       vga_out8 (0x3d4, 0x86, par);
+       vga_out8 (0x3d5, par->CR86, par);
+       vga_out8 (0x3d4, 0x88, par);
+       vga_out8 (0x3d5, par->CR88, par);
+       vga_out8 (0x3d4, 0x90, par);
+       vga_out8 (0x3d5, par->CR90, par);
+       vga_out8 (0x3d4, 0x91, par);
+       vga_out8 (0x3d5, par->CR91, par);
 
        if (par->chip == S3_SAVAGE4) {
-               vga_out8 (0x3d4, 0xb0);
-               vga_out8 (0x3d5, par->CRB0);
+               vga_out8 (0x3d4, 0xb0, par);
+               vga_out8 (0x3d5, par->CRB0, par);
        }
 
-       vga_out8 (0x3d4, 0x32);
-       vga_out8 (0x3d5, par->CR32);
+       vga_out8 (0x3d4, 0x32, par);
+       vga_out8 (0x3d5, par->CR32, par);
 
        /* unlock extended seq regs */
-       vga_out8 (0x3c4, 0x08);
-       vga_out8 (0x3c5, 0x06);
+       vga_out8 (0x3c4, 0x08, par);
+       vga_out8 (0x3c5, 0x06, par);
 
        /* Restore extended sequencer regs for MCLK. SR10 == 255 indicates
         * that we should leave the default SR10 and SR11 values there.
         */
        if (par->SR10 != 255) {
-               vga_out8 (0x3c4, 0x10);
-               vga_out8 (0x3c5, par->SR10);
-               vga_out8 (0x3c4, 0x11);
-               vga_out8 (0x3c5, par->SR11);
+               vga_out8 (0x3c4, 0x10, par);
+               vga_out8 (0x3c5, par->SR10, par);
+               vga_out8 (0x3c4, 0x11, par);
+               vga_out8 (0x3c5, par->SR11, par);
        }
 
        /* restore extended seq regs for dclk */
-       vga_out8 (0x3c4, 0x0e);
-       vga_out8 (0x3c5, par->SR0E);
-       vga_out8 (0x3c4, 0x0f);
-       vga_out8 (0x3c5, par->SR0F);
-       vga_out8 (0x3c4, 0x12);
-       vga_out8 (0x3c5, par->SR12);
-       vga_out8 (0x3c4, 0x13);
-       vga_out8 (0x3c5, par->SR13);
-       vga_out8 (0x3c4, 0x29);
-       vga_out8 (0x3c5, par->SR29);
-
-       vga_out8 (0x3c4, 0x18);
-       vga_out8 (0x3c5, par->SR18);
+       vga_out8 (0x3c4, 0x0e, par);
+       vga_out8 (0x3c5, par->SR0E, par);
+       vga_out8 (0x3c4, 0x0f, par);
+       vga_out8 (0x3c5, par->SR0F, par);
+       vga_out8 (0x3c4, 0x12, par);
+       vga_out8 (0x3c5, par->SR12, par);
+       vga_out8 (0x3c4, 0x13, par);
+       vga_out8 (0x3c5, par->SR13, par);
+       vga_out8 (0x3c4, 0x29, par);
+       vga_out8 (0x3c5, par->SR29, par);
+
+       vga_out8 (0x3c4, 0x18, par);
+       vga_out8 (0x3c5, par->SR18, par);
 
        /* load new m, n pll values for dclk & mclk */
-       vga_out8 (0x3c4, 0x15);
-       tmp = vga_in8 (0x3c5) & ~0x21;
+       vga_out8 (0x3c4, 0x15, par);
+       tmp = vga_in8 (0x3c5, par) & ~0x21;
 
-       vga_out8 (0x3c5, tmp | 0x03);
-       vga_out8 (0x3c5, tmp | 0x23);
-       vga_out8 (0x3c5, tmp | 0x03);
-       vga_out8 (0x3c5, par->SR15);
+       vga_out8 (0x3c5, tmp | 0x03, par);
+       vga_out8 (0x3c5, tmp | 0x23, par);
+       vga_out8 (0x3c5, tmp | 0x03, par);
+       vga_out8 (0x3c5, par->SR15, par);
        udelay (100);
 
-       vga_out8 (0x3c4, 0x30);
-       vga_out8 (0x3c5, par->SR30);
-       vga_out8 (0x3c4, 0x08);
-       vga_out8 (0x3c5, par->SR08);
+       vga_out8 (0x3c4, 0x30, par);
+       vga_out8 (0x3c5, par->SR30, par);
+       vga_out8 (0x3c4, 0x08, par);
+       vga_out8 (0x3c5, par->SR08, par);
 
        /* now write out cr67 in full, possibly starting STREAMS */
-       VerticalRetraceWait();
-       vga_out8 (0x3d4, 0x67);
-       vga_out8 (0x3d5, par->CR67);
+       VerticalRetraceWait(par);
+       vga_out8 (0x3d4, 0x67, par);
+       vga_out8 (0x3d5, par->CR67, par);
 
-       vga_out8 (0x3d4, 0x66);
-       cr66 = vga_in8 (0x3d5);
-       vga_out8 (0x3d5, cr66 | 0x80);
-       vga_out8 (0x3d4, 0x3a);
-       cr3a = vga_in8 (0x3d5);
-       vga_out8 (0x3d5, cr3a | 0x80);
+       vga_out8 (0x3d4, 0x66, par);
+       cr66 = vga_in8 (0x3d5, par);
+       vga_out8 (0x3d5, cr66 | 0x80, par);
+       vga_out8 (0x3d4, 0x3a, par);
+       cr3a = vga_in8 (0x3d5, par);
+       vga_out8 (0x3d5, cr3a | 0x80, par);
 
        if (par->chip != S3_SAVAGE_MX) {
-               VerticalRetraceWait();
-               savage_out32 (FIFO_CONTROL_REG, par->MMPR0);
+               VerticalRetraceWait(par);
+               savage_out32 (FIFO_CONTROL_REG, par->MMPR0, par);
                par->SavageWaitIdle (par);
-               savage_out32 (MIU_CONTROL_REG, par->MMPR1);
+               savage_out32 (MIU_CONTROL_REG, par->MMPR1, par);
                par->SavageWaitIdle (par);
-               savage_out32 (STREAMS_TIMEOUT_REG, par->MMPR2);
+               savage_out32 (STREAMS_TIMEOUT_REG, par->MMPR2, par);
                par->SavageWaitIdle (par);
-               savage_out32 (MISC_TIMEOUT_REG, par->MMPR3);
+               savage_out32 (MISC_TIMEOUT_REG, par->MMPR3, par);
        }
 
-       vga_out8 (0x3d4, 0x66);
-       vga_out8 (0x3d5, cr66);
-       vga_out8 (0x3d4, 0x3a);
-       vga_out8 (0x3d5, cr3a);
+       vga_out8 (0x3d4, 0x66, par);
+       vga_out8 (0x3d5, cr66, par);
+       vga_out8 (0x3d4, 0x3a, par);
+       vga_out8 (0x3d5, cr3a, par);
 
        SavageSetup2DEngine (par);
        vgaHWProtect (par, 0);
@@ -1299,10 +1303,10 @@ static void savagefb_update_start (struct savagefb_par      *par,
                * ((var->bits_per_pixel+7) / 8)) >> 2;
 
        /* now program the start address registers */
-       vga_out16(0x3d4, (base & 0x00ff00) | 0x0c);
-       vga_out16(0x3d4, ((base & 0x00ff) << 8) | 0x0d);
-       vga_out8 (0x3d4, 0x69);
-       vga_out8 (0x3d5, (base & 0x7f0000) >> 16);
+       vga_out16(0x3d4, (base & 0x00ff00) | 0x0c, par);
+       vga_out16(0x3d4, ((base & 0x00ff) << 8) | 0x0d, par);
+       vga_out8 (0x3d4, 0x69, par);
+       vga_out8 (0x3d5, (base & 0x7f0000) >> 16, par);
 }
 
 
@@ -1406,12 +1410,12 @@ static int savagefb_blank(int blank, struct fb_info *info)
        u8 sr8 = 0, srd = 0;
 
        if (par->display_type == DISP_CRT) {
-               vga_out8(0x3c4, 0x08);
-               sr8 = vga_in8(0x3c5);
+               vga_out8(0x3c4, 0x08, par);
+               sr8 = vga_in8(0x3c5, par);
                sr8 |= 0x06;
-               vga_out8(0x3c5, sr8);
-               vga_out8(0x3c4, 0x0d);
-               srd = vga_in8(0x3c5);
+               vga_out8(0x3c5, sr8, par);
+               vga_out8(0x3c4, 0x0d, par);
+               srd = vga_in8(0x3c5, par);
                srd &= 0x03;
 
                switch (blank) {
@@ -1429,8 +1433,8 @@ static int savagefb_blank(int blank, struct fb_info *info)
                        break;
                }
 
-               vga_out8(0x3c4, 0x0d);
-               vga_out8(0x3c5, srd);
+               vga_out8(0x3c4, 0x0d, par);
+               vga_out8(0x3c5, srd, par);
        }
 
        if (par->display_type == DISP_LCD ||
@@ -1438,14 +1442,14 @@ static int savagefb_blank(int blank, struct fb_info *info)
                switch(blank) {
                case FB_BLANK_UNBLANK:
                case FB_BLANK_NORMAL:
-                       vga_out8(0x3c4, 0x31); /* SR31 bit 4 - FP enable */
-                       vga_out8(0x3c5, vga_in8(0x3c5) | 0x10);
+                       vga_out8(0x3c4, 0x31, par); /* SR31 bit 4 - FP enable */
+                       vga_out8(0x3c5, vga_in8(0x3c5, par) | 0x10, par);
                        break;
                case FB_BLANK_VSYNC_SUSPEND:
                case FB_BLANK_HSYNC_SUSPEND:
                case FB_BLANK_POWERDOWN:
-                       vga_out8(0x3c4, 0x31); /* SR31 bit 4 - FP enable */
-                       vga_out8(0x3c5, vga_in8(0x3c5) & ~0x10);
+                       vga_out8(0x3c4, 0x31, par); /* SR31 bit 4 - FP enable */
+                       vga_out8(0x3c5, vga_in8(0x3c5, par) & ~0x10, par);
                        break;
                }
        }
@@ -1470,7 +1474,6 @@ static struct fb_ops savagefb_ops = {
        .fb_copyarea    = cfb_copyarea,
        .fb_imageblit   = cfb_imageblit,
 #endif
-       .fb_cursor      = soft_cursor,
 };
 
 /* --------------------------------------------------------------------- */
@@ -1499,15 +1502,15 @@ static void savage_enable_mmio (struct savagefb_par *par)
 
        DBG ("savage_enable_mmio\n");
 
-       val = vga_in8 (0x3c3);
-       vga_out8 (0x3c3, val | 0x01);
-       val = vga_in8 (0x3cc);
-       vga_out8 (0x3c2, val | 0x01);
+       val = vga_in8 (0x3c3, par);
+       vga_out8 (0x3c3, val | 0x01, par);
+       val = vga_in8 (0x3cc, par);
+       vga_out8 (0x3c2, val | 0x01, par);
 
        if (par->chip >= S3_SAVAGE4) {
-               vga_out8 (0x3d4, 0x40);
-               val = vga_in8 (0x3d5);
-               vga_out8 (0x3d5, val | 1);
+               vga_out8 (0x3d4, 0x40, par);
+               val = vga_in8 (0x3d5, par);
+               vga_out8 (0x3d5, val | 1, par);
        }
 }
 
@@ -1519,9 +1522,9 @@ static void savage_disable_mmio (struct savagefb_par *par)
        DBG ("savage_disable_mmio\n");
 
        if(par->chip >= S3_SAVAGE4 ) {
-               vga_out8 (0x3d4, 0x40);
-               val = vga_in8 (0x3d5);
-               vga_out8 (0x3d5, val | 1);
+               vga_out8 (0x3d4, 0x40, par);
+               val = vga_in8 (0x3d5, par);
+               vga_out8 (0x3d5, val | 1, par);
        }
 }
 
@@ -1641,30 +1644,30 @@ static int __devinit savage_init_hw (struct savagefb_par *par)
        DBG("savage_init_hw");
 
        /* unprotect CRTC[0-7] */
-       vga_out8(0x3d4, 0x11);
-       tmp = vga_in8(0x3d5);
-       vga_out8(0x3d5, tmp & 0x7f);
+       vga_out8(0x3d4, 0x11, par);
+       tmp = vga_in8(0x3d5, par);
+       vga_out8(0x3d5, tmp & 0x7f, par);
 
        /* unlock extended regs */
-       vga_out16(0x3d4, 0x4838);
-       vga_out16(0x3d4, 0xa039);
-       vga_out16(0x3c4, 0x0608);
+       vga_out16(0x3d4, 0x4838, par);
+       vga_out16(0x3d4, 0xa039, par);
+       vga_out16(0x3c4, 0x0608, par);
 
-       vga_out8(0x3d4, 0x40);
-       tmp = vga_in8(0x3d5);
-       vga_out8(0x3d5, tmp & ~0x01);
+       vga_out8(0x3d4, 0x40, par);
+       tmp = vga_in8(0x3d5, par);
+       vga_out8(0x3d5, tmp & ~0x01, par);
 
        /* unlock sys regs */
-       vga_out8(0x3d4, 0x38);
-       vga_out8(0x3d5, 0x48);
+       vga_out8(0x3d4, 0x38, par);
+       vga_out8(0x3d5, 0x48, par);
 
        /* Unlock system registers. */
-       vga_out16(0x3d4, 0x4838);
+       vga_out16(0x3d4, 0x4838, par);
 
        /* Next go on to detect amount of installed ram */
 
-       vga_out8(0x3d4, 0x36);            /* for register CR36 (CONFG_REG1), */
-       config1 = vga_in8(0x3d5);           /* get amount of vram installed */
+       vga_out8(0x3d4, 0x36, par);            /* for register CR36 (CONFG_REG1), */
+       config1 = vga_in8(0x3d5, par);    /* get amount of vram installed */
 
        /* Compute the amount of video memory and offscreen memory. */
 
@@ -1680,8 +1683,8 @@ static int __devinit savage_init_hw (struct savagefb_par *par)
                 * when it really means 8MB.  Why do it the same when you
                 * can do it different...
                 */
-               vga_out8(0x3d4, 0x68);  /* memory control 1 */
-               if( (vga_in8(0x3d5) & 0xC0) == (0x01 << 6) )
+               vga_out8(0x3d4, 0x68, par);     /* memory control 1 */
+               if( (vga_in8(0x3d5, par) & 0xC0) == (0x01 << 6) )
                        RamSavage4[1] = 8;
 
                /*FALLTHROUGH*/
@@ -1710,13 +1713,13 @@ static int __devinit savage_init_hw (struct savagefb_par *par)
        printk (KERN_INFO "savagefb: probed videoram:  %dk\n", videoRam);
 
        /* reset graphics engine to avoid memory corruption */
-       vga_out8 (0x3d4, 0x66);
-       cr66 = vga_in8 (0x3d5);
-       vga_out8 (0x3d5, cr66 | 0x02);
+       vga_out8 (0x3d4, 0x66, par);
+       cr66 = vga_in8 (0x3d5, par);
+       vga_out8 (0x3d5, cr66 | 0x02, par);
        udelay (10000);
 
-       vga_out8 (0x3d4, 0x66);
-       vga_out8 (0x3d5, cr66 & ~0x02); /* clear reset flag */
+       vga_out8 (0x3d4, 0x66, par);
+       vga_out8 (0x3d5, cr66 & ~0x02, par);    /* clear reset flag */
        udelay (10000);
 
 
@@ -1724,13 +1727,13 @@ static int __devinit savage_init_hw (struct savagefb_par *par)
         * reset memory interface, 3D engine, AGP master, PCI master,
         * master engine unit, motion compensation/LPB
         */
-       vga_out8 (0x3d4, 0x3f);
-       cr3f = vga_in8 (0x3d5);
-       vga_out8 (0x3d5, cr3f | 0x08);
+       vga_out8 (0x3d4, 0x3f, par);
+       cr3f = vga_in8 (0x3d5, par);
+       vga_out8 (0x3d5, cr3f | 0x08, par);
        udelay (10000);
 
-       vga_out8 (0x3d4, 0x3f);
-       vga_out8 (0x3d5, cr3f & ~0x08); /* clear reset flags */
+       vga_out8 (0x3d4, 0x3f, par);
+       vga_out8 (0x3d5, cr3f & ~0x08, par);    /* clear reset flags */
        udelay (10000);
 
        /* Savage ramdac speeds */
@@ -1741,15 +1744,15 @@ static int __devinit savage_init_hw (struct savagefb_par *par)
        par->clock[3] = 220000;
 
        /* detect current mclk */
-       vga_out8(0x3c4, 0x08);
-       sr8 = vga_in8(0x3c5);
-       vga_out8(0x3c5, 0x06);
-       vga_out8(0x3c4, 0x10);
-       n = vga_in8(0x3c5);
-       vga_out8(0x3c4, 0x11);
-       m = vga_in8(0x3c5);
-       vga_out8(0x3c4, 0x08);
-       vga_out8(0x3c5, sr8);
+       vga_out8(0x3c4, 0x08, par);
+       sr8 = vga_in8(0x3c5, par);
+       vga_out8(0x3c5, 0x06, par);
+       vga_out8(0x3c4, 0x10, par);
+       n = vga_in8(0x3c5, par);
+       vga_out8(0x3c4, 0x11, par);
+       m = vga_in8(0x3c5, par);
+       vga_out8(0x3c4, 0x08, par);
+       vga_out8(0x3c5, sr8, par);
        m &= 0x7f;
        n1 = n & 0x1f;
        n2 = (n >> 5) & 0x03;
@@ -1763,10 +1766,10 @@ static int __devinit savage_init_hw (struct savagefb_par *par)
        if (par->chip == S3_SAVAGE4) {
                unsigned char sr30 = 0x00;
 
-               vga_out8(0x3c4, 0x30);
+               vga_out8(0x3c4, 0x30, par);
                /* clear bit 1 */
-               vga_out8(0x3c5, vga_in8(0x3c5) & ~0x02);
-               sr30 = vga_in8(0x3c5);
+               vga_out8(0x3c5, vga_in8(0x3c5, par) & ~0x02, par);
+               sr30 = vga_in8(0x3c5, par);
                if (sr30 & 0x02 /*0x04 */) {
                        dvi = 1;
                        printk("savagefb: Digital Flat Panel Detected\n");
@@ -1783,12 +1786,12 @@ static int __devinit savage_init_hw (struct savagefb_par *par)
        /* Check LCD panel parrmation */
 
        if (par->display_type == DISP_LCD) {
-               unsigned char cr6b = VGArCR( 0x6b );
+               unsigned char cr6b = VGArCR( 0x6b, par);
 
-               int panelX = (VGArSEQ (0x61) +
-                             ((VGArSEQ (0x66) & 0x02) << 7) + 1) * 8;
-               int panelY = (VGArSEQ (0x69) +
-                             ((VGArSEQ (0x6e) & 0x70) << 4) + 1);
+               int panelX = (VGArSEQ (0x61, par) +
+                             ((VGArSEQ (0x66, par) & 0x02) << 7) + 1) * 8;
+               int panelY = (VGArSEQ (0x69, par) +
+                             ((VGArSEQ (0x6e, par) & 0x70) << 4) + 1);
 
                char * sTechnology = "Unknown";
 
@@ -1810,9 +1813,9 @@ static int __devinit savage_init_hw (struct savagefb_par *par)
                        ActiveDUO = 0x80
                };
 
-               if ((VGArSEQ (0x39) & 0x03) == 0) {
+               if ((VGArSEQ (0x39, par) & 0x03) == 0) {
                        sTechnology = "TFT";
-               } else if ((VGArSEQ (0x30) & 0x01) == 0) {
+               } else if ((VGArSEQ (0x30, par) & 0x01) == 0) {
                        sTechnology = "DSTN";
                } else  {
                        sTechnology = "STN";
@@ -2049,24 +2052,11 @@ static int __devinit savagefb_probe (struct pci_dev* dev,
                             info->monspecs.modedb, info->monspecs.modedb_len,
                             NULL, 8);
        } else if (info->monspecs.modedb != NULL) {
-               struct fb_monspecs *specs = &info->monspecs;
-               struct fb_videomode modedb;
+               struct fb_videomode *modedb;
 
-               if (info->monspecs.misc & FB_MISC_1ST_DETAIL) {
-                       int i;
-
-                       for (i = 0; i < specs->modedb_len; i++) {
-                               if (specs->modedb[i].flag & FB_MODE_IS_FIRST) {
-                                       modedb = specs->modedb[i];
-                                       break;
-                               }
-                       }
-               } else {
-                       /* otherwise, get first mode in database */
-                       modedb = specs->modedb[0];
-               }
-
-               savage_update_var(&info->var, &modedb);
+               modedb = fb_find_best_display(&info->monspecs,
+                                             &info->modelist);
+               savage_update_var(&info->var, modedb);
        }
 
        /* maximize virtual vertical length */
index 5ce81f44c7692f3d05421930cedc1b43e6a838b9..2e8769dd345a8ec0cedf06b3e7a0c1a857c3a19a 100644 (file)
@@ -126,7 +126,6 @@ static struct fb_ops sgivwfb_ops = {
        .fb_fillrect    = cfb_fillrect,
        .fb_copyarea    = cfb_copyarea,
        .fb_imageblit   = cfb_imageblit,
-       .fb_cursor      = soft_cursor,
        .fb_mmap        = sgivwfb_mmap,
 };
 
index 42c54b69726e8b769ada57f5c90ac7eedd5bf093..dea1a46c67c4fe232e24874fd08f15f46e7702b3 100644 (file)
@@ -2002,7 +2002,9 @@ static struct fb_ops sisfb_ops = {
        .fb_fillrect    = fbcon_sis_fillrect,
        .fb_copyarea    = fbcon_sis_copyarea,
        .fb_imageblit   = cfb_imageblit,
+#ifdef CONFIG_FB_SOFT_CURSOR
        .fb_cursor      = soft_cursor,
+#endif
        .fb_sync        = fbcon_sis_sync,
 #ifdef SIS_NEW_CONFIG_COMPAT
        .fb_compat_ioctl= sisfb_compat_ioctl,
index 7b43716ab66565c7d858f6ee2da92fa8318b3f3b..a01e7ecc15ed01daf66d0bcbad8a0834f85688bd 100644 (file)
@@ -457,11 +457,8 @@ void xxxfb_imageblit(struct fb_info *p, const struct fb_image *image)
 }
 
 /**
- *     xxxfb_cursor -  REQUIRED function. If your hardware lacks support
- *                     for a cursor you can use the default cursor whose
- *                     function is called soft_cursor. It will always 
- *                     work since it uses xxxfb_imageblit function which 
- *                     is required.             
+ *     xxxfb_cursor -  OPTIONAL. If your hardware lacks support
+ *                     for a cursor, leave this field NULL.
  *
  *      @info: frame buffer structure that represents a single frame buffer
  *     @cursor: structure defining the cursor to draw.
@@ -663,7 +660,7 @@ static struct fb_ops xxxfb_ops = {
        .fb_fillrect    = xxxfb_fillrect,       /* Needed !!! */ 
        .fb_copyarea    = xxxfb_copyarea,       /* Needed !!! */ 
        .fb_imageblit   = xxxfb_imageblit,      /* Needed !!! */
-       .fb_cursor      = xxxfb_cursor,         /* Needed !!! */
+       .fb_cursor      = xxxfb_cursor,         /* Optional !!! */
        .fb_rotate      = xxxfb_rotate,
        .fb_poll        = xxxfb_poll,
        .fb_sync        = xxxfb_sync,
index 663d53657fa4cf7bbdf50cbe769460ac0c432795..e0f14df840d927129bf4865248c1d066b5ebc6d6 100644 (file)
@@ -1382,7 +1382,6 @@ static struct fb_ops sstfb_ops = {
        .fb_fillrect    = cfb_fillrect, /* sstfb_fillrect */
        .fb_copyarea    = cfb_copyarea, /* sstfb_copyarea */
        .fb_imageblit   = cfb_imageblit,
-       .fb_cursor      = soft_cursor,
        .fb_ioctl       = sstfb_ioctl,
 };
 
index 9e52794768e6110f21c701d3eaf9b7d95e478250..fbb17332afd7118de3ef96fc07353db72e9c1769 100644 (file)
@@ -1147,7 +1147,6 @@ static struct fb_ops stifb_ops = {
        .fb_fillrect    = cfb_fillrect,
        .fb_copyarea    = cfb_copyarea,
        .fb_imageblit   = cfb_imageblit,
-       .fb_cursor      = soft_cursor,
 };
 
 
index 1986a8b3833cee1c6cef12a036263abdff7fc640..59fff29bc02e528c8c4d1c845d340da1de88ee35 100644 (file)
@@ -52,7 +52,6 @@ static struct fb_ops tcx_ops = {
        .fb_imageblit           = cfb_imageblit,
        .fb_mmap                = tcx_mmap,
        .fb_ioctl               = tcx_ioctl,
-       .fb_cursor              = soft_cursor,
 };
 
 /* THC definitions */
index 7044226c5d4c929e394bfcec1e9a85d61304deab..9d53387e6a666119337353c3efeb2e42a77f60fd 100644 (file)
@@ -184,7 +184,6 @@ static struct fb_ops tdfxfb_ops = {
        .fb_copyarea    = cfb_copyarea,
        .fb_imageblit   = cfb_imageblit,
 #endif
-       .fb_cursor      = soft_cursor,
 };
 
 /*
index 9d9d2009ad8caa3af457d263afa5c8717227016a..7398bd48ba6c261c1a18079b1dda976446839570 100644 (file)
@@ -63,7 +63,6 @@ static struct fb_ops tgafb_ops = {
        .fb_fillrect            = tgafb_fillrect,
        .fb_copyarea            = tgafb_copyarea,
        .fb_imageblit           = tgafb_imageblit,
-       .fb_cursor              = soft_cursor,
 };
 
 
index 81a6d9f188cf76ea4fb0020f71f6b75fc027c7f8..9ac2d3171187855286c7869e1ea33f5f0c7cebe2 100644 (file)
@@ -1293,7 +1293,6 @@ static struct fb_ops tridentfb_ops = {
        .fb_fillrect = tridentfb_fillrect,
        .fb_copyarea= tridentfb_copyarea,
        .fb_imageblit = cfb_imageblit,
-       .fb_cursor = soft_cursor,
 };
 
 module_init(tridentfb_init);
index 39d9ca71856b12aae581a72832287731e58c75b0..d904da44e1aacf280497bb174f4caccaf7bf4cb8 100644 (file)
@@ -89,7 +89,6 @@ static struct fb_ops tx3912fb_ops = {
        .fb_fillrect    = cfb_fillrect,
        .fb_copyarea    = cfb_copyarea,
        .fb_imageblit   = cfb_imageblit,
-       .fb_cursor      = soft_cursor,
 };
 
 static int tx3912fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
index 31a2bbc53974e2fd785ade7f0cc8f23f4ebaceb4..ce97ec8eae9756792d150ed33e7391dfe7583c7d 100644 (file)
@@ -135,7 +135,6 @@ static struct fb_ops valkyriefb_ops = {
        .fb_fillrect    = cfb_fillrect,
        .fb_copyarea    = cfb_copyarea,
        .fb_imageblit   = cfb_imageblit,
-       .fb_cursor      = soft_cursor,
 };
 
 /* Sets the video mode according to info->var */
index 3cc23106641db10e1a7787f52c5f9c3ee6d4dcf1..e25eae1a78c1de86e9f1f7f25103c12708c63a38 100644 (file)
@@ -48,7 +48,7 @@ static struct fb_fix_screeninfo vesafb_fix __initdata = {
 };
 
 static int             inverse   = 0;
-static int             mtrr      = 3; /* default to write-combining */
+static int             mtrr      = 0; /* disable mtrr */
 static int            vram_remap __initdata = 0; /* Set amount of memory to be used */
 static int            vram_total __initdata = 0; /* Set total amount of memory */
 static int             pmi_setpal = 0; /* pmi for palette changes ??? */
@@ -166,45 +166,39 @@ static int vesafb_setcolreg(unsigned regno, unsigned red, unsigned green,
        if (regno >= info->cmap.len)
                return 1;
 
-       switch (info->var.bits_per_pixel) {
-       case 8:
+       if (info->var.bits_per_pixel == 8)
                vesa_setpalette(regno,red,green,blue);
-               break;
-       case 16:
-               if (info->var.red.offset == 10) {
-                       /* 1:5:5:5 */
-                       ((u32*) (info->pseudo_palette))[regno] =        
+       else if (regno < 16) {
+               switch (info->var.bits_per_pixel) {
+               case 16:
+                       if (info->var.red.offset == 10) {
+                               /* 1:5:5:5 */
+                               ((u32*) (info->pseudo_palette))[regno] =
                                        ((red   & 0xf800) >>  1) |
                                        ((green & 0xf800) >>  6) |
                                        ((blue  & 0xf800) >> 11);
-               } else {
-                       /* 0:5:6:5 */
-                       ((u32*) (info->pseudo_palette))[regno] =        
+                       } else {
+                               /* 0:5:6:5 */
+                               ((u32*) (info->pseudo_palette))[regno] =
                                        ((red   & 0xf800)      ) |
                                        ((green & 0xfc00) >>  5) |
                                        ((blue  & 0xf800) >> 11);
+                       }
+                       break;
+               case 24:
+               case 32:
+                       red   >>= 8;
+                       green >>= 8;
+                       blue  >>= 8;
+                       ((u32 *)(info->pseudo_palette))[regno] =
+                               (red   << info->var.red.offset)   |
+                               (green << info->var.green.offset) |
+                               (blue  << info->var.blue.offset);
+                       break;
                }
-               break;
-       case 24:
-               red   >>= 8;
-               green >>= 8;
-               blue  >>= 8;
-               ((u32 *)(info->pseudo_palette))[regno] =
-                       (red   << info->var.red.offset)   |
-                       (green << info->var.green.offset) |
-                       (blue  << info->var.blue.offset);
-               break;
-       case 32:
-               red   >>= 8;
-               green >>= 8;
-               blue  >>= 8;
-               ((u32 *)(info->pseudo_palette))[regno] =
-                       (red   << info->var.red.offset)   |
-                       (green << info->var.green.offset) |
-                       (blue  << info->var.blue.offset);
-               break;
-    }
-    return 0;
+       }
+
+       return 0;
 }
 
 static struct fb_ops vesafb_ops = {
@@ -215,7 +209,6 @@ static struct fb_ops vesafb_ops = {
        .fb_fillrect    = cfb_fillrect,
        .fb_copyarea    = cfb_copyarea,
        .fb_imageblit   = cfb_imageblit,
-       .fb_cursor      = soft_cursor,
 };
 
 static int __init vesafb_setup(char *options)
index 92d46555dd86e2fd02ee7985ef8ba41ca44d1b48..8794dc5d24667527fdd838481bd5f18f4b3482eb 100644 (file)
@@ -92,7 +92,6 @@ static struct fb_ops vfb_ops = {
        .fb_fillrect    = cfb_fillrect,
        .fb_copyarea    = cfb_copyarea,
        .fb_imageblit   = cfb_imageblit,
-       .fb_cursor      = soft_cursor,
        .fb_mmap        = vfb_mmap,
 };
 
index b46454c55c91b01767753d356c2963e9ca6b080d..690bb6fe82812082d00dc04a410531aa1e7abaef 100644 (file)
@@ -1326,7 +1326,6 @@ static struct fb_ops vga16fb_ops = {
        .fb_fillrect    = vga16fb_fillrect,
        .fb_copyarea    = vga16fb_copyarea,
        .fb_imageblit   = vga16fb_imageblit,
-       .fb_cursor      = soft_cursor,
 };
 
 #ifndef MODULE
index cf8cdb108fd95c0d1eb2f3be7e947804e6a5abb8..48e70f153c4b23857aea147451418547c431f87f 100644 (file)
@@ -397,7 +397,6 @@ static struct fb_ops w100fb_ops = {
        .fb_fillrect  = cfb_fillrect,
        .fb_copyarea  = cfb_copyarea,
        .fb_imageblit = cfb_imageblit,
-       .fb_cursor    = soft_cursor,
 };
 
 #ifdef CONFIG_PM
index 279e0e0363d6afb7e7326da42381d6c36c5e37f4..1e3d98aac12dbc788b458a6adbb8e2bf70139889 100644 (file)
@@ -299,10 +299,8 @@ static int w1_f23_add_slave(struct w1_slave *sl)
 static void w1_f23_remove_slave(struct w1_slave *sl)
 {
 #ifdef CONFIG_W1_F23_CRC
-       if (sl->family_data) {
-               kfree(sl->family_data);
-               sl->family_data = NULL;
-       }
+       kfree(sl->family_data);
+       sl->family_data = NULL;
 #endif /* CONFIG_W1_F23_CRC */
        sysfs_remove_bin_file(&sl->dev.kobj, &w1_f23_bin_attr);
 }
index fee5d19179c5f1fb8f15c0b5deaed90f42d85c51..834cb179e3888c963ae651fc34a5bf26f915b41b 100644 (file)
@@ -33,6 +33,7 @@
 
 #include <linux/list.h>
 #include <linux/jhash.h>
+#include <linux/string.h>
 
 #include "debug.h"
 #include "error.h"
index 01e26f0013aced186efe40992d34996999ded2da..a93c2bf94c331a7b20326caa5a36c217fab3f023 100644 (file)
@@ -269,8 +269,7 @@ static void v9fs_sock_close(struct v9fs_transport *trans)
                dprintk(DEBUG_TRANS, "socket closed\n");
        }
 
-       if (ts)
-               kfree(ts);
+       kfree(ts);
 
        trans->priv = NULL;
 }
index 82303f3bf76f786f4a939d47c60ba0cd73649a1e..418c3743fdee85c89452f9f6c0dda13dbb404007 100644 (file)
@@ -266,7 +266,7 @@ v9fs_session_init(struct v9fs_session_info *v9ses,
 
        v9ses->remotename = __getname();
        if (!v9ses->remotename) {
-               putname(v9ses->name);
+               __putname(v9ses->name);
                return -ENOMEM;
        }
 
@@ -411,8 +411,8 @@ void v9fs_session_close(struct v9fs_session_info *v9ses)
        if (v9ses->transport)
                v9ses->transport->close(v9ses->transport);
 
-       putname(v9ses->name);
-       putname(v9ses->remotename);
+       __putname(v9ses->name);
+       __putname(v9ses->remotename);
 }
 
 /**
index 2b696ae6655a10306f5111c90f14a5af645c9220..be7288184fa9de0a580f7ec64d86f29fec5d3ce3 100644 (file)
@@ -1105,7 +1105,7 @@ static int v9fs_vfs_readlink(struct dentry *dentry, char __user * buffer,
                }
        }
 
-       putname(link);
+       __putname(link);
        return retval;
 }
 
@@ -1129,7 +1129,7 @@ static void *v9fs_vfs_follow_link(struct dentry *dentry, struct nameidata *nd)
                len = v9fs_readlink(dentry, link, strlen(link));
 
                if (len < 0) {
-                       putname(link);
+                       __putname(link);
                        link = ERR_PTR(len);
                } else
                        link[len] = 0;
@@ -1152,7 +1152,7 @@ static void v9fs_vfs_put_link(struct dentry *dentry, struct nameidata *nd, void
 
        dprintk(DEBUG_VFS, " %s %s\n", dentry->d_name.name, s);
        if (!IS_ERR(s))
-               putname(s);
+               __putname(s);
 }
 
 /**
@@ -1228,7 +1228,7 @@ v9fs_vfs_link(struct dentry *old_dentry, struct inode *dir,
       FreeMem:
        kfree(mistat);
        kfree(fcall);
-       putname(symname);
+       __putname(symname);
        return retval;
 }
 
@@ -1319,7 +1319,7 @@ v9fs_vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev)
       FreeMem:
        kfree(mistat);
        kfree(fcall);
-       putname(symname);
+       __putname(symname);
 
        return retval;
 }
index 01a295232f75dcd53ab1d5a4998e35b92fc47205..7cf36ca157ffed120b4e9a3ec771725964ea245d 100644 (file)
@@ -898,6 +898,7 @@ config AFFS_FS
 config HFS_FS
        tristate "Apple Macintosh file system support (EXPERIMENTAL)"
        depends on EXPERIMENTAL
+       select NLS
        help
          If you say Y here, you will be able to mount Macintosh-formatted
          floppy disks and hard drive partitions with full read-write access.
index 6744924b690557342faa139b9b41ce399e1c0197..f72fb776ecdf86621f95e7e444c2d0ac54191f67 100644 (file)
@@ -22,14 +22,13 @@ static int affs_grow_extcache(struct inode *inode, u32 lc_idx);
 static struct buffer_head *affs_alloc_extblock(struct inode *inode, struct buffer_head *bh, u32 ext);
 static inline struct buffer_head *affs_get_extblock(struct inode *inode, u32 ext);
 static struct buffer_head *affs_get_extblock_slow(struct inode *inode, u32 ext);
-static ssize_t affs_file_write(struct file *filp, const char __user *buf, size_t count, loff_t *ppos);
 static int affs_file_open(struct inode *inode, struct file *filp);
 static int affs_file_release(struct inode *inode, struct file *filp);
 
 struct file_operations affs_file_operations = {
        .llseek         = generic_file_llseek,
        .read           = generic_file_read,
-       .write          = affs_file_write,
+       .write          = generic_file_write,
        .mmap           = generic_file_mmap,
        .open           = affs_file_open,
        .release        = affs_file_release,
@@ -473,21 +472,6 @@ affs_getemptyblk_ino(struct inode *inode, int block)
        return ERR_PTR(err);
 }
 
-static ssize_t
-affs_file_write(struct file *file, const char __user *buf,
-               size_t count, loff_t *ppos)
-{
-       ssize_t retval;
-
-       retval = generic_file_write (file, buf, count, ppos);
-       if (retval >0) {
-               struct inode *inode = file->f_dentry->d_inode;
-               inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC;
-               mark_inode_dirty(inode);
-       }
-       return retval;
-}
-
 static int
 affs_do_readpage_ofs(struct file *file, struct page *page, unsigned from, unsigned to)
 {
index 9c3080716c924526a481c313e9176e093669068d..aaec015a16e4f48d5ee3c124006ac47f91e4ec33 100644 (file)
@@ -35,8 +35,7 @@ affs_put_super(struct super_block *sb)
                mark_buffer_dirty(sbi->s_root_bh);
        }
 
-       if (sbi->s_prefix)
-               kfree(sbi->s_prefix);
+       kfree(sbi->s_prefix);
        affs_free_bitmap(sb);
        affs_brelse(sbi->s_root_bh);
        kfree(sbi);
@@ -198,10 +197,9 @@ parse_options(char *options, uid_t *uid, gid_t *gid, int *mode, int *reserved, s
                        *mount_opts |= SF_MUFS;
                        break;
                case Opt_prefix:
-                       if (*prefix) {          /* Free any previous prefix */
-                               kfree(*prefix);
-                               *prefix = NULL;
-                       }
+                       /* Free any previous prefix */
+                       kfree(*prefix);
+                       *prefix = NULL;
                        *prefix = match_strdup(&args[0]);
                        if (!*prefix)
                                return 0;
@@ -462,11 +460,9 @@ got_root:
 out_error:
        if (root_inode)
                iput(root_inode);
-       if (sbi->s_bitmap)
-               kfree(sbi->s_bitmap);
+       kfree(sbi->s_bitmap);
        affs_brelse(root_bh);
-       if (sbi->s_prefix)
-               kfree(sbi->s_prefix);
+       kfree(sbi->s_prefix);
        kfree(sbi);
        sb->s_fs_info = NULL;
        return -EINVAL;
index 4975c9c193dd37505cbdcfad000fdcd24793676d..150b192279228a3dfee74846a6f8f48d38e933fd 100644 (file)
@@ -31,24 +31,10 @@ static int afs_file_readpage(struct file *file, struct page *page);
 static int afs_file_invalidatepage(struct page *page, unsigned long offset);
 static int afs_file_releasepage(struct page *page, gfp_t gfp_flags);
 
-static ssize_t afs_file_write(struct file *file, const char __user *buf,
-                             size_t size, loff_t *off);
-
 struct inode_operations afs_file_inode_operations = {
        .getattr        = afs_inode_getattr,
 };
 
-struct file_operations afs_file_file_operations = {
-       .read           = generic_file_read,
-       .write          = afs_file_write,
-       .mmap           = generic_file_mmap,
-#if 0
-       .open           = afs_file_open,
-       .release        = afs_file_release,
-       .fsync          = afs_file_fsync,
-#endif
-};
-
 struct address_space_operations afs_fs_aops = {
        .readpage       = afs_file_readpage,
        .sync_page      = block_sync_page,
@@ -57,22 +43,6 @@ struct address_space_operations afs_fs_aops = {
        .invalidatepage = afs_file_invalidatepage,
 };
 
-/*****************************************************************************/
-/*
- * AFS file write
- */
-static ssize_t afs_file_write(struct file *file, const char __user *buf,
-                             size_t size, loff_t *off)
-{
-       struct afs_vnode *vnode;
-
-       vnode = AFS_FS_I(file->f_dentry->d_inode);
-       if (vnode->flags & AFS_VNODE_DELETED)
-               return -ESTALE;
-
-       return -EIO;
-} /* end afs_file_write() */
-
 /*****************************************************************************/
 /*
  * deal with notification that a page was read from the cache
@@ -295,8 +265,7 @@ static int afs_file_releasepage(struct page *page, gfp_t gfp_flags)
                set_page_private(page, 0);
                ClearPagePrivate(page);
 
-               if (pageio)
-                       kfree(pageio);
+               kfree(pageio);
        }
 
        _leave(" = 0");
index c476fde33fbc24ab64ed26137424e8eb7b7d776a..4ebb30a50ed5a876d28c7830e0083c10a1aa26f9 100644 (file)
@@ -49,7 +49,7 @@ static int afs_inode_map_status(struct afs_vnode *vnode)
        case AFS_FTYPE_FILE:
                inode->i_mode   = S_IFREG | vnode->status.mode;
                inode->i_op     = &afs_file_inode_operations;
-               inode->i_fop    = &afs_file_file_operations;
+               inode->i_fop    = &generic_ro_fops;
                break;
        case AFS_FTYPE_DIR:
                inode->i_mode   = S_IFDIR | vnode->status.mode;
index f09860b45c1a303e9f0702bf2ab9636f6a26689d..ab8f87c66319bc4233444e8bcd7c3f17163e5d88 100644 (file)
@@ -71,7 +71,6 @@ extern struct file_operations afs_dir_file_operations;
  */
 extern struct address_space_operations afs_fs_aops;
 extern struct inode_operations afs_file_inode_operations;
-extern struct file_operations afs_file_file_operations;
 
 #ifdef AFS_CACHING_SUPPORT
 extern int afs_cache_get_page_cookie(struct page *page,
index edfca5b7553581c65cddc50ac14e18f84ec2826c..20bb919eb1958e6e4dbbf96f6f04812a23983a24 100644 (file)
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -42,8 +42,9 @@
 #endif
 
 /*------ sysctl variables----*/
-atomic_t aio_nr = ATOMIC_INIT(0);      /* current system wide number of aio requests */
-unsigned aio_max_nr = 0x10000; /* system wide maximum number of aio requests */
+static DEFINE_SPINLOCK(aio_nr_lock);
+unsigned long aio_nr;          /* current system wide number of aio requests */
+unsigned long aio_max_nr = 0x10000; /* system wide maximum number of aio requests */
 /*----end sysctl variables---*/
 
 static kmem_cache_t    *kiocb_cachep;
@@ -208,7 +209,7 @@ static struct kioctx *ioctx_alloc(unsigned nr_events)
                return ERR_PTR(-EINVAL);
        }
 
-       if (nr_events > aio_max_nr)
+       if ((unsigned long)nr_events > aio_max_nr)
                return ERR_PTR(-EAGAIN);
 
        ctx = kmem_cache_alloc(kioctx_cachep, GFP_KERNEL);
@@ -233,8 +234,14 @@ static struct kioctx *ioctx_alloc(unsigned nr_events)
                goto out_freectx;
 
        /* limit the number of system wide aios */
-       atomic_add(ctx->max_reqs, &aio_nr);     /* undone by __put_ioctx */
-       if (unlikely(atomic_read(&aio_nr) > aio_max_nr))
+       spin_lock(&aio_nr_lock);
+       if (aio_nr + ctx->max_reqs > aio_max_nr ||
+           aio_nr + ctx->max_reqs < aio_nr)
+               ctx->max_reqs = 0;
+       else
+               aio_nr += ctx->max_reqs;
+       spin_unlock(&aio_nr_lock);
+       if (ctx->max_reqs == 0)
                goto out_cleanup;
 
        /* now link into global list.  kludge.  FIXME */
@@ -248,8 +255,6 @@ static struct kioctx *ioctx_alloc(unsigned nr_events)
        return ctx;
 
 out_cleanup:
-       atomic_sub(ctx->max_reqs, &aio_nr);
-       ctx->max_reqs = 0;      /* prevent __put_ioctx from sub'ing aio_nr */
        __put_ioctx(ctx);
        return ERR_PTR(-EAGAIN);
 
@@ -374,7 +379,12 @@ void fastcall __put_ioctx(struct kioctx *ctx)
        pr_debug("__put_ioctx: freeing %p\n", ctx);
        kmem_cache_free(kioctx_cachep, ctx);
 
-       atomic_sub(nr_events, &aio_nr);
+       if (nr_events) {
+               spin_lock(&aio_nr_lock);
+               BUG_ON(aio_nr - nr_events > aio_nr);
+               aio_nr -= nr_events;
+               spin_unlock(&aio_nr_lock);
+       }
 }
 
 /* aio_get_req
@@ -1258,8 +1268,9 @@ asmlinkage long sys_io_setup(unsigned nr_events, aio_context_t __user *ctxp)
                goto out;
 
        ret = -EINVAL;
-       if (unlikely(ctx || (int)nr_events <= 0)) {
-               pr_debug("EINVAL: io_setup: ctx or nr_events > max\n");
+       if (unlikely(ctx || nr_events == 0)) {
+               pr_debug("EINVAL: io_setup: ctx %lu nr_events %u\n",
+                        ctx, nr_events);
                goto out;
        }
 
index 1fcaa1568541c79060996da33a52cd6f6b58d189..633f628005b4a773b3e9326263b6892cdbce6b92 100644 (file)
@@ -150,10 +150,8 @@ int autofs_wait(struct autofs_sb_info *sbi, struct qstr *name)
        if ( sbi->catatonic ) {
                /* We might have slept, so check again for catatonic mode */
                wq->status = -ENOENT;
-               if ( wq->name ) {
-                       kfree(wq->name);
-                       wq->name = NULL;
-               }
+               kfree(wq->name);
+               wq->name = NULL;
        }
 
        if ( wq->name ) {
index 0a3c05d101679ea0dd24d2794a9a66f64ab5ba10..818b37be5153f3d7508ac00c215c2f523f01999f 100644 (file)
 
 static void ino_lnkfree(struct autofs_info *ino)
 {
-       if (ino->u.symlink) {
-               kfree(ino->u.symlink);
-               ino->u.symlink = NULL;
-       }
+       kfree(ino->u.symlink);
+       ino->u.symlink = NULL;
 }
 
 struct autofs_info *autofs4_init_ino(struct autofs_info *ino,
index 3df86285a1c7e981e054d145fb134b89673336ab..394ff36ef8f19ec84a4f26a0c1a96e2badb7cb84 100644 (file)
@@ -243,10 +243,8 @@ int autofs4_wait(struct autofs_sb_info *sbi, struct dentry *dentry,
        if ( sbi->catatonic ) {
                /* We might have slept, so check again for catatonic mode */
                wq->status = -ENOENT;
-               if ( wq->name ) {
-                       kfree(wq->name);
-                       wq->name = NULL;
-               }
+               kfree(wq->name);
+               wq->name = NULL;
        }
 
        if ( wq->name ) {
index e0a6025f1d06a72a6423984ab838739ed0bf2bf6..2d365cb8eec60948e631cf7b2d0ea33e45b94219 100644 (file)
@@ -73,12 +73,6 @@ static struct inode_operations befs_dir_inode_operations = {
        .lookup         = befs_lookup,
 };
 
-static struct file_operations befs_file_operations = {
-       .llseek         = default_llseek,
-       .read           = generic_file_read,
-       .mmap           = generic_file_readonly_mmap,
-};
-
 static struct address_space_operations befs_aops = {
        .readpage       = befs_readpage,
        .sync_page      = block_sync_page,
@@ -398,7 +392,7 @@ befs_read_inode(struct inode *inode)
        inode->i_mapping->a_ops = &befs_aops;
 
        if (S_ISREG(inode->i_mode)) {
-               inode->i_fop = &befs_file_operations;
+               inode->i_fop = &generic_ro_fops;
        } else if (S_ISDIR(inode->i_mode)) {
                inode->i_op = &befs_dir_inode_operations;
                inode->i_fop = &befs_dir_operations;
@@ -731,20 +725,16 @@ parse_options(char *options, befs_mount_options * opts)
 static void
 befs_put_super(struct super_block *sb)
 {
-       if (BEFS_SB(sb)->mount_opts.iocharset) {
-               kfree(BEFS_SB(sb)->mount_opts.iocharset);
-               BEFS_SB(sb)->mount_opts.iocharset = NULL;
-       }
+       kfree(BEFS_SB(sb)->mount_opts.iocharset);
+       BEFS_SB(sb)->mount_opts.iocharset = NULL;
 
        if (BEFS_SB(sb)->nls) {
                unload_nls(BEFS_SB(sb)->nls);
                BEFS_SB(sb)->nls = NULL;
        }
 
-       if (sb->s_fs_info) {
-               kfree(sb->s_fs_info);
-               sb->s_fs_info = NULL;
-       }
+       kfree(sb->s_fs_info);
+       sb->s_fs_info = NULL;
        return;
 }
 
index 6fa6adc409726e8b79038bbdac31e510e248fed7..f36f2210204f524b2922fa69ea704295bfbe5a59 100644 (file)
@@ -1006,8 +1006,7 @@ out_free_dentry:
        if (interpreter)
                fput(interpreter);
 out_free_interp:
-       if (elf_interpreter)
-               kfree(elf_interpreter);
+       kfree(elf_interpreter);
 out_free_file:
        sys_close(elf_exec_fileno);
 out_free_fh:
index dda87c4c82a3c98c08109d577d98d24c70a2d5a9..e0344f69c79d971ce4fb95992ca4d3e13f32fbe5 100644 (file)
@@ -411,16 +411,11 @@ error:
                allow_write_access(interpreter);
                fput(interpreter);
        }
-       if (interpreter_name)
-               kfree(interpreter_name);
-       if (exec_params.phdrs)
-               kfree(exec_params.phdrs);
-       if (exec_params.loadmap)
-               kfree(exec_params.loadmap);
-       if (interp_params.phdrs)
-               kfree(interp_params.phdrs);
-       if (interp_params.loadmap)
-               kfree(interp_params.loadmap);
+       kfree(interpreter_name);
+       kfree(exec_params.phdrs);
+       kfree(exec_params.loadmap);
+       kfree(interp_params.phdrs);
+       kfree(interp_params.loadmap);
        return retval;
 
        /* unrecoverable error - kill the process */
index 35fa34977e81f5477b492bc6d7694de8d2c4065a..5287be18633bc7c2b6621fc20c2f5ce97fa8e561 100644 (file)
@@ -396,7 +396,7 @@ asmlinkage long sys_fdatasync(unsigned int fd)
  * private_lock is contended then so is mapping->tree_lock).
  */
 static struct buffer_head *
-__find_get_block_slow(struct block_device *bdev, sector_t block, int unused)
+__find_get_block_slow(struct block_device *bdev, sector_t block)
 {
        struct inode *bd_inode = bdev->bd_inode;
        struct address_space *bd_mapping = bd_inode->i_mapping;
@@ -1438,7 +1438,7 @@ __find_get_block(struct block_device *bdev, sector_t block, int size)
        struct buffer_head *bh = lookup_bh_lru(bdev, block, size);
 
        if (bh == NULL) {
-               bh = __find_get_block_slow(bdev, block, size);
+               bh = __find_get_block_slow(bdev, block);
                if (bh)
                        bh_lru_install(bh);
        }
@@ -1705,7 +1705,7 @@ void unmap_underlying_metadata(struct block_device *bdev, sector_t block)
 
        might_sleep();
 
-       old_bh = __find_get_block_slow(bdev, block, 0);
+       old_bh = __find_get_block_slow(bdev, block);
        if (old_bh) {
                clear_buffer_dirty(old_bh);
                wait_on_buffer(old_bh);
index 98539e2afe81e92494ad27c4c49789126847df8e..086ae8f4a207a22f0d1bfe2863439ed20bd88f89 100644 (file)
@@ -553,8 +553,7 @@ decode_negTokenInit(unsigned char *security_blob, int length,
                                           *(oid + 3)));
                                        rc = compare_oid(oid, oidlen, NTLMSSP_OID,
                                                 NTLMSSP_OID_LEN);
-                                       if(oid)
-                                               kfree(oid);
+                                       kfree(oid);
                                        if (rc)
                                                use_ntlmssp = TRUE;
                                }
index d74367a08d513dd4cf6bb6a3aa090996972ea7f5..450ab75d654623d492c6969fc312bd041083fa2a 100644 (file)
@@ -1265,8 +1265,7 @@ connect_to_dfs_path(int xid, struct cifsSesInfo *pSesInfo,
                the helper that resolves tcp names, mount to it, try to 
                tcon to it unmount it if fail */
 
-       if(referrals)
-               kfree(referrals);
+       kfree(referrals);
 
        return rc;
 }
@@ -1535,10 +1534,8 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
        
        memset(&volume_info,0,sizeof(struct smb_vol));
        if (cifs_parse_mount_options(mount_data, devname, &volume_info)) {
-               if(volume_info.UNC)
-                       kfree(volume_info.UNC);
-               if(volume_info.password)
-                       kfree(volume_info.password);
+               kfree(volume_info.UNC);
+               kfree(volume_info.password);
                FreeXid(xid);
                return -EINVAL;
        }
@@ -1551,10 +1548,8 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
                cifserror("No username specified ");
         /* In userspace mount helper we can get user name from alternate
            locations such as env variables and files on disk */
-               if(volume_info.UNC)
-                       kfree(volume_info.UNC);
-               if(volume_info.password)
-                       kfree(volume_info.password);
+               kfree(volume_info.UNC);
+               kfree(volume_info.password);
                FreeXid(xid);
                return -EINVAL;
        }
@@ -1573,10 +1568,8 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
        
                if(rc <= 0) {
                        /* we failed translating address */
-                       if(volume_info.UNC)
-                               kfree(volume_info.UNC);
-                       if(volume_info.password)
-                               kfree(volume_info.password);
+                       kfree(volume_info.UNC);
+                       kfree(volume_info.password);
                        FreeXid(xid);
                        return -EINVAL;
                }
@@ -1587,19 +1580,15 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
        } else if (volume_info.UNCip){
                /* BB using ip addr as server name connect to the DFS root below */
                cERROR(1,("Connecting to DFS root not implemented yet"));
-               if(volume_info.UNC)
-                       kfree(volume_info.UNC);
-               if(volume_info.password)
-                       kfree(volume_info.password);
+               kfree(volume_info.UNC);
+               kfree(volume_info.password);
                FreeXid(xid);
                return -EINVAL;
        } else /* which servers DFS root would we conect to */ {
                cERROR(1,
                       ("CIFS mount error: No UNC path (e.g. -o unc=//192.168.1.100/public) specified  "));
-               if(volume_info.UNC)
-                       kfree(volume_info.UNC);
-               if(volume_info.password)
-                       kfree(volume_info.password);
+               kfree(volume_info.UNC);
+               kfree(volume_info.password);
                FreeXid(xid);
                return -EINVAL;
        }
@@ -1612,10 +1601,8 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
                cifs_sb->local_nls = load_nls(volume_info.iocharset);
                if(cifs_sb->local_nls == NULL) {
                        cERROR(1,("CIFS mount error: iocharset %s not found",volume_info.iocharset));
-                       if(volume_info.UNC)
-                               kfree(volume_info.UNC);
-                       if(volume_info.password)
-                               kfree(volume_info.password);
+                       kfree(volume_info.UNC);
+                       kfree(volume_info.password);
                        FreeXid(xid);
                        return -ELIBACC;
                }
@@ -1630,10 +1617,8 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
                        &sin_server6.sin6_addr,
                        volume_info.username, &srvTcp);
        else {
-               if(volume_info.UNC)
-                       kfree(volume_info.UNC);
-               if(volume_info.password)
-                       kfree(volume_info.password);
+               kfree(volume_info.UNC);
+               kfree(volume_info.password);
                FreeXid(xid);
                return -EINVAL;
        }
@@ -1654,10 +1639,8 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
                               ("Error connecting to IPv4 socket. Aborting operation"));
                        if(csocket != NULL)
                                sock_release(csocket);
-                       if(volume_info.UNC)
-                               kfree(volume_info.UNC);
-                       if(volume_info.password)
-                               kfree(volume_info.password);
+                       kfree(volume_info.UNC);
+                       kfree(volume_info.password);
                        FreeXid(xid);
                        return rc;
                }
@@ -1666,10 +1649,8 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
                if (srvTcp == NULL) {
                        rc = -ENOMEM;
                        sock_release(csocket);
-                       if(volume_info.UNC)
-                               kfree(volume_info.UNC);
-                       if(volume_info.password)
-                               kfree(volume_info.password);
+                       kfree(volume_info.UNC);
+                       kfree(volume_info.password);
                        FreeXid(xid);
                        return rc;
                } else {
@@ -1692,10 +1673,8 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
                        if(rc < 0) {
                                rc = -ENOMEM;
                                sock_release(csocket);
-                               if(volume_info.UNC)
-                                       kfree(volume_info.UNC);
-                               if(volume_info.password)
-                                       kfree(volume_info.password);
+                               kfree(volume_info.UNC);
+                               kfree(volume_info.password);
                                FreeXid(xid);
                                return rc;
                        }
@@ -1710,8 +1689,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
        if (existingCifsSes) {
                pSesInfo = existingCifsSes;
                cFYI(1, ("Existing smb sess found "));
-               if(volume_info.password)
-                       kfree(volume_info.password);
+               kfree(volume_info.password);
                /* volume_info.UNC freed at end of function */
        } else if (!rc) {
                cFYI(1, ("Existing smb sess not found "));
@@ -1741,8 +1719,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
                        if(!rc)
                                atomic_inc(&srvTcp->socketUseCount);
                } else
-                       if(volume_info.password)
-                               kfree(volume_info.password);
+                       kfree(volume_info.password);
        }
     
        /* search for existing tcon to this server share */
@@ -1821,8 +1798,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
                                                        "", cifs_sb->local_nls,
                                                        cifs_sb->mnt_cifs_flags & 
                                                          CIFS_MOUNT_MAP_SPECIAL_CHR);
-                                       if(volume_info.UNC)
-                                               kfree(volume_info.UNC);
+                                       kfree(volume_info.UNC);
                                        FreeXid(xid);
                                        return -ENODEV;
                                } else {
@@ -1925,8 +1901,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
        (in which case it is not needed anymore) but when new sesion is created
        the password ptr is put in the new session structure (in which case the
        password will be freed at unmount time) */
-       if(volume_info.UNC)
-               kfree(volume_info.UNC);
+       kfree(volume_info.UNC);
        FreeXid(xid);
        return rc;
 }
@@ -3283,8 +3258,7 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
                        if ((bcc_ptr + (2 * length)) -
                             pByteArea(smb_buffer_response) <=
                            BCC(smb_buffer_response)) {
-                               if(tcon->nativeFileSystem)
-                                       kfree(tcon->nativeFileSystem);
+                               kfree(tcon->nativeFileSystem);
                                tcon->nativeFileSystem =
                                    kzalloc(length + 2, GFP_KERNEL);
                                cifs_strfromUCS_le(tcon->nativeFileSystem,
@@ -3301,8 +3275,7 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
                        if ((bcc_ptr + length) -
                            pByteArea(smb_buffer_response) <=
                            BCC(smb_buffer_response)) {
-                               if(tcon->nativeFileSystem)
-                                       kfree(tcon->nativeFileSystem);
+                               kfree(tcon->nativeFileSystem);
                                tcon->nativeFileSystem =
                                    kzalloc(length + 1, GFP_KERNEL);
                                strncpy(tcon->nativeFileSystem, bcc_ptr,
index b43e071fe1106446fc2e48fc05299a7b8fabce4a..0f99aae33162fbd68f5e08a32713db3055a418cf 100644 (file)
@@ -84,10 +84,8 @@ cifs_hardlink(struct dentry *old_file, struct inode *inode,
        cifsInode->time = 0;    /* will force revalidate to go get info when needed */
 
 cifs_hl_exit:
-       if (fromName)
-               kfree(fromName);
-       if (toName)
-               kfree(toName);
+       kfree(fromName);
+       kfree(toName);
        FreeXid(xid);
        return rc;
 }
@@ -206,8 +204,7 @@ cifs_symlink(struct inode *inode, struct dentry *direntry, const char *symname)
                }
        }
 
-       if (full_path)
-               kfree(full_path);
+       kfree(full_path);
        FreeXid(xid);
        return rc;
 }
@@ -253,8 +250,7 @@ cifs_readlink(struct dentry *direntry, char __user *pBuffer, int buflen)
                len = buflen;
        tmpbuffer = kmalloc(len,GFP_KERNEL);   
        if(tmpbuffer == NULL) {
-               if (full_path)
-                       kfree(full_path);
+               kfree(full_path);
                FreeXid(xid);
                return -ENOMEM;
        }
@@ -303,8 +299,7 @@ cifs_readlink(struct dentry *direntry, char __user *pBuffer, int buflen)
                                                        strncpy(tmpbuffer, referrals, len-1);                            
                                                }
                                        }
-                                       if(referrals)
-                                               kfree(referrals);
+                                       kfree(referrals);
                                        kfree(tmp_path);
 }
                                /* BB add code like else decode referrals then memcpy to
@@ -323,12 +318,8 @@ cifs_readlink(struct dentry *direntry, char __user *pBuffer, int buflen)
                      rc));
        }
 
-       if (tmpbuffer) {
-               kfree(tmpbuffer);
-       }
-       if (full_path) {
-               kfree(full_path);
-       }
+       kfree(tmpbuffer);
+       kfree(full_path);
        FreeXid(xid);
        return rc;
 }
index eba1de917f2a87c2d9d5a173978c26f4e10e06b2..34a06692e4fa9461e624e8ace35de0536d4240d9 100644 (file)
@@ -98,14 +98,10 @@ sesInfoFree(struct cifsSesInfo *buf_to_free)
        atomic_dec(&sesInfoAllocCount);
        list_del(&buf_to_free->cifsSessionList);
        write_unlock(&GlobalSMBSeslock);
-       if (buf_to_free->serverOS)
-               kfree(buf_to_free->serverOS);
-       if (buf_to_free->serverDomain)
-               kfree(buf_to_free->serverDomain);
-       if (buf_to_free->serverNOS)
-               kfree(buf_to_free->serverNOS);
-       if (buf_to_free->password)
-               kfree(buf_to_free->password);
+       kfree(buf_to_free->serverOS);
+       kfree(buf_to_free->serverDomain);
+       kfree(buf_to_free->serverNOS);
+       kfree(buf_to_free->password);
        kfree(buf_to_free);
 }
 
@@ -144,8 +140,7 @@ tconInfoFree(struct cifsTconInfo *buf_to_free)
        atomic_dec(&tconInfoAllocCount);
        list_del(&buf_to_free->cifsConnectionList);
        write_unlock(&GlobalSMBSeslock);
-       if (buf_to_free->nativeFileSystem)
-               kfree(buf_to_free->nativeFileSystem);
+       kfree(buf_to_free->nativeFileSystem);
        kfree(buf_to_free);
 }
 
index c1e02eff1d25a222613f48b5312cb055776abc00..f375f87c7dbd3698a07290a9953e219cf49b0513 100644 (file)
@@ -87,8 +87,7 @@ int cifs_removexattr(struct dentry * direntry, const char * ea_name)
                        cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
        }
 remove_ea_exit:
-       if (full_path)
-               kfree(full_path);
+       kfree(full_path);
        FreeXid(xid);
 #endif
        return rc;
@@ -132,8 +131,7 @@ int cifs_setxattr(struct dentry * direntry, const char * ea_name,
                returns as xattrs */
        if(value_size > MAX_EA_VALUE_SIZE) {
                cFYI(1,("size of EA value too large"));
-               if(full_path)
-                       kfree(full_path);
+               kfree(full_path);
                FreeXid(xid);
                return -EOPNOTSUPP;
        }
@@ -195,8 +193,7 @@ int cifs_setxattr(struct dentry * direntry, const char * ea_name,
        }
 
 set_ea_exit:
-       if (full_path)
-               kfree(full_path);
+       kfree(full_path);
        FreeXid(xid);
 #endif
        return rc;
@@ -298,8 +295,7 @@ ssize_t cifs_getxattr(struct dentry * direntry, const char * ea_name,
                rc = -EOPNOTSUPP; 
 
 get_ea_exit:
-       if (full_path)
-               kfree(full_path);
+       kfree(full_path);
        FreeXid(xid);
 #endif
        return rc;
@@ -345,8 +341,7 @@ ssize_t cifs_listxattr(struct dentry * direntry, char * data, size_t buf_size)
                                cifs_sb->mnt_cifs_flags & 
                                        CIFS_MOUNT_MAP_SPECIAL_CHR);
 
-       if (full_path)
-               kfree(full_path);
+       kfree(full_path);
        FreeXid(xid);
 #endif
        return rc;
index 43dbcb0b21ebcc2ec51cfcc1052fc2879b73cbeb..4909754ea84a9873d931280c0af377d3d6abe15e 100644 (file)
@@ -2235,7 +2235,8 @@ static int fd_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
        if (err)
                err = -EFAULT;
 
-out:   if (karg) kfree(karg);
+out:
+       kfree(karg);
        return err;
 }
 
index e90512ed35a4eca72e839434a075d1a4b8886c24..17e4391386818d405ca0203123b9738f8b886cc8 100644 (file)
@@ -644,7 +644,7 @@ void shrink_dcache_parent(struct dentry * parent)
  *
  * Prune the dentries that are anonymous
  *
- * parsing d_hash list does not hlist_for_each_rcu() as it
+ * parsing d_hash list does not hlist_for_each_entry_rcu() as it
  * done under dcache_lock.
  *
  */
@@ -1043,15 +1043,13 @@ struct dentry * __d_lookup(struct dentry * parent, struct qstr * name)
        struct hlist_head *head = d_hash(parent,hash);
        struct dentry *found = NULL;
        struct hlist_node *node;
+       struct dentry *dentry;
 
        rcu_read_lock();
        
-       hlist_for_each_rcu(node, head) {
-               struct dentry *dentry; 
+       hlist_for_each_entry_rcu(dentry, node, head, d_hash) {
                struct qstr *qstr;
 
-               dentry = hlist_entry(node, struct dentry, d_hash);
-
                if (dentry->d_name.hash != hash)
                        continue;
                if (dentry->d_parent != parent)
@@ -1123,7 +1121,7 @@ int d_validate(struct dentry *dentry, struct dentry *dparent)
        spin_lock(&dcache_lock);
        base = d_hash(dparent, dentry->d_name.hash);
        hlist_for_each(lhp,base) { 
-               /* hlist_for_each_rcu() not required for d_hash list
+               /* hlist_for_each_entry_rcu() not required for d_hash list
                 * as it is parsed under dcache_lock
                 */
                if (dentry == hlist_entry(lhp, struct dentry, d_hash)) {
index 8b679b67e5e0f78e18dbd25015f7990cfa6f1f5a..1274422a5384d26e366a57c56152f8383da90677 100644 (file)
@@ -2738,10 +2738,8 @@ static int devfsd_close(struct inode *inode, struct file *file)
        entry = fs_info->devfsd_first_event;
        fs_info->devfsd_first_event = NULL;
        fs_info->devfsd_last_event = NULL;
-       if (fs_info->devfsd_info) {
-               kfree(fs_info->devfsd_info);
-               fs_info->devfsd_info = NULL;
-       }
+       kfree(fs_info->devfsd_info);
+       fs_info->devfsd_info = NULL;
        spin_unlock(&fs_info->devfsd_buffer_lock);
        fs_info->devfsd_pgrp = 0;
        fs_info->devfsd_task = NULL;
index ea7644227a65d7d393758e136d62ca7797235adb..afa06a893468571785ca335a32a6bd89eafda4a0 100644 (file)
@@ -77,6 +77,7 @@
 #include <linux/kmod.h>
 #include <linux/namei.h>
 #include <linux/buffer_head.h>
+#include <linux/quotaops.h>
 
 #include <asm/uaccess.h>
 
index 10d493fea7ce6a9e4de05ff01facdf162bb9dd8b..cd6c574557dc19a0b405d7fac06bc166db72a830 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -48,6 +48,7 @@
 #include <linux/syscalls.h>
 #include <linux/rmap.h>
 #include <linux/acct.h>
+#include <linux/cn_proc.h>
 
 #include <asm/uaccess.h>
 #include <asm/mmu_context.h>
@@ -1096,6 +1097,7 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs)
                                        fput(bprm->file);
                                bprm->file = NULL;
                                current->did_exec = 1;
+                               proc_exec_connector(current);
                                return retval;
                        }
                        read_lock(&binfmt_lock);
@@ -1509,7 +1511,7 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs)
                goto close_fail;
        if (!file->f_op->write)
                goto close_fail;
-       if (do_truncate(file->f_dentry, 0) != 0)
+       if (do_truncate(file->f_dentry, 0, file) != 0)
                goto close_fail;
 
        retval = binfmt->core_dump(signr, regs, file);
index 213148c36ebef341ae8c460af7cd2d9c095a5d3b..6af2f41302905a8e863912b8153e9d30a82911fd 100644 (file)
@@ -194,8 +194,7 @@ ext2_get_acl(struct inode *inode, int type)
                acl = NULL;
        else
                acl = ERR_PTR(retval);
-       if (value)
-               kfree(value);
+       kfree(value);
 
        if (!IS_ERR(acl)) {
                switch(type) {
@@ -262,8 +261,7 @@ ext2_set_acl(struct inode *inode, int type, struct posix_acl *acl)
 
        error = ext2_xattr_set(inode, name_index, "", value, size, 0);
 
-       if (value)
-               kfree(value);
+       kfree(value);
        if (!error) {
                switch(type) {
                        case ACL_TYPE_ACCESS:
index 4dc205546547aae35d1cd613ac27146d706e1d09..c3a5e2fd663b772d7eeb997171d6b052b82d680c 100644 (file)
@@ -35,7 +35,7 @@ static DEFINE_SPINLOCK(filp_count_lock);
  * context and must be fully threaded - use a local spinlock
  * to protect files_stat.nr_files
  */
-void filp_ctor(void * objp, struct kmem_cache_s *cachep, unsigned long cflags)
+void filp_ctor(void *objp, struct kmem_cache *cachep, unsigned long cflags)
 {
        if ((cflags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
            SLAB_CTOR_CONSTRUCTOR) {
@@ -46,7 +46,7 @@ void filp_ctor(void * objp, struct kmem_cache_s *cachep, unsigned long cflags)
        }
 }
 
-void filp_dtor(void * objp, struct kmem_cache_s *cachep, unsigned long dflags)
+void filp_dtor(void *objp, struct kmem_cache *cachep, unsigned long dflags)
 {
        unsigned long flags;
        spin_lock_irqsave(&filp_count_lock, flags);
index d8be917f9797f02065223b9a73e1fcb2e214f3db..927acf70c591c4b9793fc134912a9dc4363d61ea 100644 (file)
@@ -38,7 +38,7 @@
  */
 
 
-struct kmem_cache_s;
+struct kmem_cache;
 struct super_block;
 struct vxfs_inode_info;
 struct inode;
@@ -51,7 +51,7 @@ extern daddr_t                        vxfs_bmap1(struct inode *, long);
 extern int                     vxfs_read_fshead(struct super_block *);
 
 /* vxfs_inode.c */
-extern struct kmem_cache_s     *vxfs_inode_cachep;
+extern struct kmem_cache       *vxfs_inode_cachep;
 extern void                    vxfs_dumpi(struct vxfs_inode_info *, ino_t);
 extern struct inode *          vxfs_get_fake_inode(struct super_block *,
                                        struct vxfs_inode_info *);
index 9672d2facffeeaecc0973923b00ed116a6272134..f544aae9169fb86847a0794006dde0a73910291e 100644 (file)
@@ -46,15 +46,6 @@ extern struct address_space_operations vxfs_immed_aops;
 
 extern struct inode_operations vxfs_immed_symlink_iops;
 
-static struct file_operations vxfs_file_operations = {
-       .open =                 generic_file_open,
-       .llseek =               generic_file_llseek,
-       .read =                 generic_file_read,
-       .mmap =                 generic_file_mmap,
-       .sendfile =             generic_file_sendfile,
-};
-
-
 kmem_cache_t           *vxfs_inode_cachep;
 
 
@@ -318,7 +309,7 @@ vxfs_read_inode(struct inode *ip)
                aops = &vxfs_aops;
 
        if (S_ISREG(ip->i_mode)) {
-               ip->i_fop = &vxfs_file_operations;
+               ip->i_fop = &generic_ro_fops;
                ip->i_mapping->a_ops = aops;
        } else if (S_ISDIR(ip->i_mode)) {
                ip->i_op = &vxfs_dir_inode_ops;
index c27f8d4098be3cd713b2934f6eefdc8d03bb4a68..785c7213a54f513186aa5e403a1a3066f646eb12 100644 (file)
@@ -562,7 +562,7 @@ int write_inode_now(struct inode *inode, int sync)
        };
 
        if (!mapping_cap_writeback_dirty(inode->i_mapping))
-               return 0;
+               wbc.nr_to_write = 0;
 
        might_sleep();
        spin_lock(&inode_lock);
@@ -606,7 +606,7 @@ EXPORT_SYMBOL(sync_inode);
  * O_SYNC flag set, to flush dirty writes to disk.
  *
  * @what is a bitmask, specifying which part of the inode's data should be
- * written and waited upon:
+ * written and waited upon.
  *
  *    OSYNC_DATA:     i_mapping's dirty data
  *    OSYNC_METADATA: the buffers at i_mapping->private_list
@@ -672,8 +672,9 @@ int writeback_acquire(struct backing_dev_info *bdi)
 
 /**
  * writeback_in_progress: determine whether there is writeback in progress
- *                        against a backing device.
  * @bdi: the device's backing_dev_info structure.
+ *
+ * Determine whether there is writeback in progress against a backing device.
  */
 int writeback_in_progress(struct backing_dev_info *bdi)
 {
index a6f90a6c754a1b573ecdaf0eb849cbfc8e802be5..8f873e621f4107e9c3d40d00e21bfaabd848ed66 100644 (file)
@@ -184,6 +184,13 @@ static void request_end(struct fuse_conn *fc, struct fuse_req *req)
                   fuse_putback_request() */
                for (i = 1; i < FUSE_MAX_OUTSTANDING; i++)
                        up(&fc->outstanding_sem);
+       } else if (req->in.h.opcode == FUSE_RELEASE && req->inode == NULL) {
+               /* Special case for failed iget in CREATE */
+               u64 nodeid = req->in.h.nodeid;
+               __fuse_get_request(req);
+               fuse_reset_request(req);
+               fuse_send_forget(fc, req, nodeid, 1);
+               putback = 0;
        }
        if (putback)
                fuse_putback_request(fc, req);
index 70dba721acabe9992416d66bca1d0becd1411f2f..c045cc70c74931864e01763c3573eeae19c2d1e8 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/gfp.h>
 #include <linux/sched.h>
 #include <linux/namei.h>
+#include <linux/mount.h>
 
 static inline unsigned long time_to_jiffies(unsigned long sec,
                                            unsigned long nsec)
@@ -134,6 +135,101 @@ static void fuse_invalidate_entry(struct dentry *entry)
        entry->d_time = jiffies - 1;
 }
 
+static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode,
+                           struct nameidata *nd)
+{
+       int err;
+       struct inode *inode;
+       struct fuse_conn *fc = get_fuse_conn(dir);
+       struct fuse_req *req;
+       struct fuse_open_in inarg;
+       struct fuse_open_out outopen;
+       struct fuse_entry_out outentry;
+       struct fuse_inode *fi;
+       struct fuse_file *ff;
+       struct file *file;
+       int flags = nd->intent.open.flags - 1;
+
+       err = -ENOSYS;
+       if (fc->no_create)
+               goto out;
+
+       err = -ENAMETOOLONG;
+       if (entry->d_name.len > FUSE_NAME_MAX)
+               goto out;
+
+       err = -EINTR;
+       req = fuse_get_request(fc);
+       if (!req)
+               goto out;
+
+       ff = fuse_file_alloc();
+       if (!ff)
+               goto out_put_request;
+
+       flags &= ~O_NOCTTY;
+       memset(&inarg, 0, sizeof(inarg));
+       inarg.flags = flags;
+       inarg.mode = mode;
+       req->in.h.opcode = FUSE_CREATE;
+       req->in.h.nodeid = get_node_id(dir);
+       req->inode = dir;
+       req->in.numargs = 2;
+       req->in.args[0].size = sizeof(inarg);
+       req->in.args[0].value = &inarg;
+       req->in.args[1].size = entry->d_name.len + 1;
+       req->in.args[1].value = entry->d_name.name;
+       req->out.numargs = 2;
+       req->out.args[0].size = sizeof(outentry);
+       req->out.args[0].value = &outentry;
+       req->out.args[1].size = sizeof(outopen);
+       req->out.args[1].value = &outopen;
+       request_send(fc, req);
+       err = req->out.h.error;
+       if (err) {
+               if (err == -ENOSYS)
+                       fc->no_create = 1;
+               goto out_free_ff;
+       }
+
+       err = -EIO;
+       if (!S_ISREG(outentry.attr.mode))
+               goto out_free_ff;
+
+       inode = fuse_iget(dir->i_sb, outentry.nodeid, outentry.generation,
+                         &outentry.attr);
+       err = -ENOMEM;
+       if (!inode) {
+               flags &= ~(O_CREAT | O_EXCL | O_TRUNC);
+               ff->fh = outopen.fh;
+               fuse_send_release(fc, ff, outentry.nodeid, NULL, flags, 0);
+               goto out_put_request;
+       }
+       fuse_put_request(fc, req);
+       entry->d_time = time_to_jiffies(outentry.entry_valid,
+                                       outentry.entry_valid_nsec);
+       fi = get_fuse_inode(inode);
+       fi->i_time = time_to_jiffies(outentry.attr_valid,
+                                    outentry.attr_valid_nsec);
+
+       d_instantiate(entry, inode);
+       file = lookup_instantiate_filp(nd, entry, generic_file_open);
+       if (IS_ERR(file)) {
+               ff->fh = outopen.fh;
+               fuse_send_release(fc, ff, outentry.nodeid, inode, flags, 0);
+               return PTR_ERR(file);
+       }
+       fuse_finish_open(inode, file, ff, &outopen);
+       return 0;
+
+ out_free_ff:
+       fuse_file_free(ff);
+ out_put_request:
+       fuse_put_request(fc, req);
+ out:
+       return err;
+}
+
 static int create_new_entry(struct fuse_conn *fc, struct fuse_req *req,
                            struct inode *dir, struct dentry *entry,
                            int mode)
@@ -208,6 +304,12 @@ static int fuse_mknod(struct inode *dir, struct dentry *entry, int mode,
 static int fuse_create(struct inode *dir, struct dentry *entry, int mode,
                       struct nameidata *nd)
 {
+       if (nd && (nd->flags & LOOKUP_CREATE)) {
+               int err = fuse_create_open(dir, entry, mode, nd);
+               if (err != -ENOSYS)
+                       return err;
+               /* Fall back on mknod */
+       }
        return fuse_mknod(dir, entry, mode, 0);
 }
 
@@ -461,6 +563,38 @@ static int fuse_revalidate(struct dentry *entry)
        return fuse_do_getattr(inode);
 }
 
+static int fuse_access(struct inode *inode, int mask)
+{
+       struct fuse_conn *fc = get_fuse_conn(inode);
+       struct fuse_req *req;
+       struct fuse_access_in inarg;
+       int err;
+
+       if (fc->no_access)
+               return 0;
+
+       req = fuse_get_request(fc);
+       if (!req)
+               return -EINTR;
+
+       memset(&inarg, 0, sizeof(inarg));
+       inarg.mask = mask;
+       req->in.h.opcode = FUSE_ACCESS;
+       req->in.h.nodeid = get_node_id(inode);
+       req->inode = inode;
+       req->in.numargs = 1;
+       req->in.args[0].size = sizeof(inarg);
+       req->in.args[0].value = &inarg;
+       request_send(fc, req);
+       err = req->out.h.error;
+       fuse_put_request(fc, req);
+       if (err == -ENOSYS) {
+               fc->no_access = 1;
+               err = 0;
+       }
+       return err;
+}
+
 static int fuse_permission(struct inode *inode, int mask, struct nameidata *nd)
 {
        struct fuse_conn *fc = get_fuse_conn(inode);
@@ -491,11 +625,11 @@ static int fuse_permission(struct inode *inode, int mask, struct nameidata *nd)
                return err;
        } else {
                int mode = inode->i_mode;
-               if ((mask & MAY_WRITE) && IS_RDONLY(inode) &&
-                    (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)))
-                        return -EROFS;
                if ((mask & MAY_EXEC) && !S_ISDIR(mode) && !(mode & S_IXUGO))
                        return -EACCES;
+
+               if (nd && (nd->flags & LOOKUP_ACCESS))
+                       return fuse_access(inode, mask);
                return 0;
        }
 }
@@ -629,29 +763,29 @@ static int fuse_dir_fsync(struct file *file, struct dentry *de, int datasync)
        return file ? fuse_fsync_common(file, de, datasync, 1) : 0;
 }
 
-static unsigned iattr_to_fattr(struct iattr *iattr, struct fuse_attr *fattr)
+static void iattr_to_fattr(struct iattr *iattr, struct fuse_setattr_in *arg)
 {
        unsigned ivalid = iattr->ia_valid;
-       unsigned fvalid = 0;
-
-       memset(fattr, 0, sizeof(*fattr));
 
        if (ivalid & ATTR_MODE)
-               fvalid |= FATTR_MODE,   fattr->mode = iattr->ia_mode;
+               arg->valid |= FATTR_MODE,   arg->mode = iattr->ia_mode;
        if (ivalid & ATTR_UID)
-               fvalid |= FATTR_UID,    fattr->uid = iattr->ia_uid;
+               arg->valid |= FATTR_UID,    arg->uid = iattr->ia_uid;
        if (ivalid & ATTR_GID)
-               fvalid |= FATTR_GID,    fattr->gid = iattr->ia_gid;
+               arg->valid |= FATTR_GID,    arg->gid = iattr->ia_gid;
        if (ivalid & ATTR_SIZE)
-               fvalid |= FATTR_SIZE,   fattr->size = iattr->ia_size;
+               arg->valid |= FATTR_SIZE,   arg->size = iattr->ia_size;
        /* You can only _set_ these together (they may change by themselves) */
        if ((ivalid & (ATTR_ATIME | ATTR_MTIME)) == (ATTR_ATIME | ATTR_MTIME)) {
-               fvalid |= FATTR_ATIME | FATTR_MTIME;
-               fattr->atime = iattr->ia_atime.tv_sec;
-               fattr->mtime = iattr->ia_mtime.tv_sec;
+               arg->valid |= FATTR_ATIME | FATTR_MTIME;
+               arg->atime = iattr->ia_atime.tv_sec;
+               arg->mtime = iattr->ia_mtime.tv_sec;
+       }
+       if (ivalid & ATTR_FILE) {
+               struct fuse_file *ff = iattr->ia_file->private_data;
+               arg->valid |= FATTR_FH;
+               arg->fh = ff->fh;
        }
-
-       return fvalid;
 }
 
 static int fuse_setattr(struct dentry *entry, struct iattr *attr)
@@ -686,7 +820,7 @@ static int fuse_setattr(struct dentry *entry, struct iattr *attr)
                return -EINTR;
 
        memset(&inarg, 0, sizeof(inarg));
-       inarg.valid = iattr_to_fattr(attr, &inarg.attr);
+       iattr_to_fattr(attr, &inarg);
        req->in.h.opcode = FUSE_SETATTR;
        req->in.h.nodeid = get_node_id(inode);
        req->inode = inode;
@@ -735,7 +869,9 @@ static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry,
                                  struct nameidata *nd)
 {
        struct inode *inode;
-       int err = fuse_lookup_iget(dir, entry, &inode);
+       int err;
+
+       err = fuse_lookup_iget(dir, entry, &inode);
        if (err)
                return ERR_PTR(err);
        if (inode && S_ISDIR(inode->i_mode)) {
index 657ab11c173b38a05678f49c05accc7313b02ede..2ca86141d13ab35f2fd4078ad682f4163ecf058c 100644 (file)
 
 static struct file_operations fuse_direct_io_file_operations;
 
-int fuse_open_common(struct inode *inode, struct file *file, int isdir)
+static int fuse_send_open(struct inode *inode, struct file *file, int isdir,
+                         struct fuse_open_out *outargp)
 {
        struct fuse_conn *fc = get_fuse_conn(inode);
-       struct fuse_req *req;
        struct fuse_open_in inarg;
+       struct fuse_req *req;
+       int err;
+
+       req = fuse_get_request(fc);
+       if (!req)
+               return -EINTR;
+
+       memset(&inarg, 0, sizeof(inarg));
+       inarg.flags = file->f_flags & ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC);
+       req->in.h.opcode = isdir ? FUSE_OPENDIR : FUSE_OPEN;
+       req->in.h.nodeid = get_node_id(inode);
+       req->inode = inode;
+       req->in.numargs = 1;
+       req->in.args[0].size = sizeof(inarg);
+       req->in.args[0].value = &inarg;
+       req->out.numargs = 1;
+       req->out.args[0].size = sizeof(*outargp);
+       req->out.args[0].value = outargp;
+       request_send(fc, req);
+       err = req->out.h.error;
+       fuse_put_request(fc, req);
+
+       return err;
+}
+
+struct fuse_file *fuse_file_alloc(void)
+{
+       struct fuse_file *ff;
+       ff = kmalloc(sizeof(struct fuse_file), GFP_KERNEL);
+       if (ff) {
+               ff->release_req = fuse_request_alloc();
+               if (!ff->release_req) {
+                       kfree(ff);
+                       ff = NULL;
+               }
+       }
+       return ff;
+}
+
+void fuse_file_free(struct fuse_file *ff)
+{
+       fuse_request_free(ff->release_req);
+       kfree(ff);
+}
+
+void fuse_finish_open(struct inode *inode, struct file *file,
+                     struct fuse_file *ff, struct fuse_open_out *outarg)
+{
+       if (outarg->open_flags & FOPEN_DIRECT_IO)
+               file->f_op = &fuse_direct_io_file_operations;
+       if (!(outarg->open_flags & FOPEN_KEEP_CACHE))
+               invalidate_inode_pages(inode->i_mapping);
+       ff->fh = outarg->fh;
+       file->private_data = ff;
+}
+
+int fuse_open_common(struct inode *inode, struct file *file, int isdir)
+{
        struct fuse_open_out outarg;
        struct fuse_file *ff;
        int err;
@@ -34,73 +92,53 @@ int fuse_open_common(struct inode *inode, struct file *file, int isdir)
        /* If opening the root node, no lookup has been performed on
           it, so the attributes must be refreshed */
        if (get_node_id(inode) == FUSE_ROOT_ID) {
-               int err = fuse_do_getattr(inode);
+               err = fuse_do_getattr(inode);
                if (err)
                        return err;
        }
 
-       req = fuse_get_request(fc);
-       if (!req)
-               return -EINTR;
-
-       err = -ENOMEM;
-       ff = kmalloc(sizeof(struct fuse_file), GFP_KERNEL);
+       ff = fuse_file_alloc();
        if (!ff)
-               goto out_put_request;
+               return -ENOMEM;
 
-       ff->release_req = fuse_request_alloc();
-       if (!ff->release_req) {
-               kfree(ff);
-               goto out_put_request;
-       }
-
-       memset(&inarg, 0, sizeof(inarg));
-       inarg.flags = file->f_flags & ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC);
-       req->in.h.opcode = isdir ? FUSE_OPENDIR : FUSE_OPEN;
-       req->in.h.nodeid = get_node_id(inode);
-       req->inode = inode;
-       req->in.numargs = 1;
-       req->in.args[0].size = sizeof(inarg);
-       req->in.args[0].value = &inarg;
-       req->out.numargs = 1;
-       req->out.args[0].size = sizeof(outarg);
-       req->out.args[0].value = &outarg;
-       request_send(fc, req);
-       err = req->out.h.error;
-       if (err) {
-               fuse_request_free(ff->release_req);
-               kfree(ff);
-       } else {
-               if (!isdir && (outarg.open_flags & FOPEN_DIRECT_IO))
-                       file->f_op = &fuse_direct_io_file_operations;
-               if (!(outarg.open_flags & FOPEN_KEEP_CACHE))
-                       invalidate_inode_pages(inode->i_mapping);
-               ff->fh = outarg.fh;
-               file->private_data = ff;
+       err = fuse_send_open(inode, file, isdir, &outarg);
+       if (err)
+               fuse_file_free(ff);
+       else {
+               if (isdir)
+                       outarg.open_flags &= ~FOPEN_DIRECT_IO;
+               fuse_finish_open(inode, file, ff, &outarg);
        }
 
- out_put_request:
-       fuse_put_request(fc, req);
        return err;
 }
 
-int fuse_release_common(struct inode *inode, struct file *file, int isdir)
+void fuse_send_release(struct fuse_conn *fc, struct fuse_file *ff,
+                      u64 nodeid, struct inode *inode, int flags, int isdir)
 {
-       struct fuse_conn *fc = get_fuse_conn(inode);
-       struct fuse_file *ff = file->private_data;
-       struct fuse_req *req = ff->release_req;
+       struct fuse_req * req = ff->release_req;
        struct fuse_release_in *inarg = &req->misc.release_in;
 
        inarg->fh = ff->fh;
-       inarg->flags = file->f_flags & ~O_EXCL;
+       inarg->flags = flags;
        req->in.h.opcode = isdir ? FUSE_RELEASEDIR : FUSE_RELEASE;
-       req->in.h.nodeid = get_node_id(inode);
+       req->in.h.nodeid = nodeid;
        req->inode = inode;
        req->in.numargs = 1;
        req->in.args[0].size = sizeof(struct fuse_release_in);
        req->in.args[0].value = inarg;
        request_send_background(fc, req);
        kfree(ff);
+}
+
+int fuse_release_common(struct inode *inode, struct file *file, int isdir)
+{
+       struct fuse_file *ff = file->private_data;
+       if (ff) {
+               struct fuse_conn *fc = get_fuse_conn(inode);
+               u64 nodeid = get_node_id(inode);
+               fuse_send_release(fc, ff, nodeid, inode, file->f_flags, isdir);
+       }
 
        /* Return value is ignored by VFS */
        return 0;
index 5cb456f572c1c97d7bf016b1ac0493dedccbde35..0ea5301f86bee8b585d5b8b1085ac3199a674bb4 100644 (file)
@@ -266,6 +266,12 @@ struct fuse_conn {
        /** Is removexattr not implemented by fs? */
        unsigned no_removexattr : 1;
 
+       /** Is access not implemented by fs? */
+       unsigned no_access : 1;
+
+       /** Is create not implemented by fs? */
+       unsigned no_create : 1;
+
        /** Backing dev info */
        struct backing_dev_info bdi;
 };
@@ -337,6 +343,17 @@ size_t fuse_send_read_common(struct fuse_req *req, struct file *file,
  */
 int fuse_open_common(struct inode *inode, struct file *file, int isdir);
 
+struct fuse_file *fuse_file_alloc(void);
+void fuse_file_free(struct fuse_file *ff);
+void fuse_finish_open(struct inode *inode, struct file *file,
+                     struct fuse_file *ff, struct fuse_open_out *outarg);
+
+/**
+ * Send a RELEASE request
+ */
+void fuse_send_release(struct fuse_conn *fc, struct fuse_file *ff,
+                      u64 nodeid, struct inode *inode, int flags, int isdir);
+
 /**
  * Send RELEASE or RELEASEDIR request
  */
index dd7113106269992822e97e4bbf07ad2bc5ab5eca..a33fb1d91373f873d559a26e1a8494e363ecc86c 100644 (file)
@@ -294,8 +294,7 @@ static void hostfs_delete_inode(struct inode *inode)
 
 static void hostfs_destroy_inode(struct inode *inode)
 {
-       if(HOSTFS_I(inode)->host_filename)
-               kfree(HOSTFS_I(inode)->host_filename);
+       kfree(HOSTFS_I(inode)->host_filename);
 
        /*XXX: This should not happen, probably. The check is here for
         * additional safety.*/
index 1d21307730a8362cd9e8a1f961bcf81e19c39dc2..229ff2fb1809f7b6276c66655b47679f013225c6 100644 (file)
@@ -244,12 +244,12 @@ static int hpfs_add_to_dnode(struct inode *i, dnode_secno dno,
        go_up:
        if (namelen >= 256) {
                hpfs_error(i->i_sb, "hpfs_add_to_dnode: namelen == %d", namelen);
-               if (nd) kfree(nd);
+               kfree(nd);
                kfree(nname);
                return 1;
        }
        if (!(d = hpfs_map_dnode(i->i_sb, dno, &qbh))) {
-               if (nd) kfree(nd);
+               kfree(nd);
                kfree(nname);
                return 1;
        }
@@ -257,7 +257,7 @@ static int hpfs_add_to_dnode(struct inode *i, dnode_secno dno,
        if (hpfs_sb(i->i_sb)->sb_chk)
                if (hpfs_stop_cycles(i->i_sb, dno, &c1, &c2, "hpfs_add_to_dnode")) {
                        hpfs_brelse4(&qbh);
-                       if (nd) kfree(nd);
+                       kfree(nd);
                        kfree(nname);
                        return 1;
                }
@@ -270,7 +270,7 @@ static int hpfs_add_to_dnode(struct inode *i, dnode_secno dno,
                for_all_poss(i, hpfs_pos_subst, 5, t + 1);
                hpfs_mark_4buffers_dirty(&qbh);
                hpfs_brelse4(&qbh);
-               if (nd) kfree(nd);
+               kfree(nd);
                kfree(nname);
                return 0;
        }
index 8eefa6366db748ae145dde7bfb8ca6b4325a81f4..63e88d7e2c3b56842fb38d12a9bebb2d6d837724 100644 (file)
@@ -75,7 +75,7 @@ void hpfs_error(struct super_block *s, char *m,...)
                } else if (s->s_flags & MS_RDONLY) printk("; going on - but anything won't be destroyed because it's read-only\n");
                else printk("; corrupted filesystem mounted read/write - your computer will explode within 20 seconds ... but you wanted it so!\n");
        } else printk("\n");
-       if (buf) kfree(buf);
+       kfree(buf);
        hpfs_sb(s)->sb_was_error = 1;
 }
 
@@ -102,8 +102,8 @@ int hpfs_stop_cycles(struct super_block *s, int key, int *c1, int *c2,
 static void hpfs_put_super(struct super_block *s)
 {
        struct hpfs_sb_info *sbi = hpfs_sb(s);
-       if (sbi->sb_cp_table) kfree(sbi->sb_cp_table);
-       if (sbi->sb_bmp_dir) kfree(sbi->sb_bmp_dir);
+       kfree(sbi->sb_cp_table);
+       kfree(sbi->sb_bmp_dir);
        unmark_dirty(s);
        s->s_fs_info = NULL;
        kfree(sbi);
@@ -654,8 +654,8 @@ bail3:      brelse(bh1);
 bail2: brelse(bh0);
 bail1:
 bail0:
-       if (sbi->sb_bmp_dir) kfree(sbi->sb_bmp_dir);
-       if (sbi->sb_cp_table) kfree(sbi->sb_cp_table);
+       kfree(sbi->sb_bmp_dir);
+       kfree(sbi->sb_cp_table);
        s->s_fs_info = NULL;
        kfree(sbi);
        return -EINVAL;
index 1652de1b6cb9e0a57bb9d33f6dff568b3f84196d..298f08be22d46ceb2e8a0d11121d9e3de7ecd594 100644 (file)
@@ -855,8 +855,7 @@ root_found:
        if (opt.check == 'r') table++;
        s->s_root->d_op = &isofs_dentry_ops[table];
 
-       if (opt.iocharset)
-               kfree(opt.iocharset);
+       kfree(opt.iocharset);
 
        return 0;
 
@@ -895,8 +894,7 @@ out_unknown_format:
 out_freebh:
        brelse(bh);
 out_freesbi:
-       if (opt.iocharset)
-               kfree(opt.iocharset);
+       kfree(opt.iocharset);
        kfree(sbi);
        s->s_fs_info = NULL;
        return -EINVAL;
@@ -1164,8 +1162,7 @@ out_nomem:
 
 out_noread:
        printk(KERN_INFO "ISOFS: unable to read i-node block %lu\n", block);
-       if (tmpde)
-               kfree(tmpde);
+       kfree(tmpde);
        return -EIO;
 
 out_toomany:
@@ -1334,8 +1331,7 @@ static void isofs_read_inode(struct inode *inode)
                init_special_inode(inode, inode->i_mode, inode->i_rdev);
 
 out:
-       if (tmpde)
-               kfree(tmpde);
+       kfree(tmpde);
        if (bh)
                brelse(bh);
        return;
index 2a3e310f79efa7c3665dd037dd572ca35780677f..002ad2bbc76992b6acda52def147799886147693 100644 (file)
@@ -261,10 +261,8 @@ void journal_commit_transaction(journal_t *journal)
                        struct buffer_head *bh = jh2bh(jh);
 
                        jbd_lock_bh_state(bh);
-                       if (jh->b_committed_data) {
-                               kfree(jh->b_committed_data);
-                               jh->b_committed_data = NULL;
-                       }
+                       kfree(jh->b_committed_data);
+                       jh->b_committed_data = NULL;
                        jbd_unlock_bh_state(bh);
                }
                journal_refile_buffer(journal, jh);
index 103c34e4fb280978873cd811ef06d34c01bab2c2..80d7f53fd0a759dec8a019c60bb96badf7f927bb 100644 (file)
@@ -210,7 +210,7 @@ do {                                                                        \
 } while (0)
 
 /**
- * int journal_recover(journal_t *journal) - recovers a on-disk journal
+ * journal_recover - recovers a on-disk journal
  * @journal: the journal to recover
  * 
  * The primary function for recovering the log contents when mounting a
@@ -266,7 +266,7 @@ int journal_recover(journal_t *journal)
 }
 
 /**
- * int journal_skip_recovery() - Start journal and wipe exiting records 
+ * 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
index 13cb05bf60489e0005d635d66a63b47692ed72a6..429f4b263cf1198bf179af4377ff8b1c21af3d5e 100644 (file)
@@ -227,8 +227,7 @@ repeat_locked:
        spin_unlock(&transaction->t_handle_lock);
        spin_unlock(&journal->j_state_lock);
 out:
-       if (new_transaction)
-               kfree(new_transaction);
+       kfree(new_transaction);
        return ret;
 }
 
@@ -725,8 +724,7 @@ done:
        journal_cancel_revoke(handle, jh);
 
 out:
-       if (frozen_buffer)
-               kfree(frozen_buffer);
+       kfree(frozen_buffer);
 
        JBUFFER_TRACE(jh, "exit");
        return error;
@@ -905,8 +903,7 @@ repeat:
        jbd_unlock_bh_state(bh);
 out:
        journal_put_journal_head(jh);
-       if (committed_data)
-               kfree(committed_data);
+       kfree(committed_data);
        return err;
 }
 
index 27f199e94cfc8edd369775b4e962eee517dc3a14..b2e95421d932025407f758bb590d49b165a0a05a 100644 (file)
@@ -462,7 +462,7 @@ jffs_checksum_flash(struct mtd_info *mtd, loff_t start, int size, __u32 *result)
        }
 
        /* Free read buffer */
-       kfree (read_buf);
+       kfree(read_buf);
 
        /* Return result */
        D3(printk("checksum result: 0x%08x\n", sum));
@@ -1011,12 +1011,12 @@ jffs_scan_flash(struct jffs_control *c)
                                                       offset , fmc->sector_size);
 
                                                flash_safe_release(fmc->mtd);
-                                               kfree (read_buf);
+                                               kfree(read_buf);
                                                return -1; /* bad, bad, bad! */
 
                                        }
                                        flash_safe_release(fmc->mtd);
-                                       kfree (read_buf);
+                                       kfree(read_buf);
 
                                        return -EAGAIN; /* erased offending sector. Try mount one more time please. */
                                }
@@ -1112,7 +1112,7 @@ jffs_scan_flash(struct jffs_control *c)
                if (!node) {
                        if (!(node = jffs_alloc_node())) {
                                /* Free read buffer */
-                               kfree (read_buf);
+                               kfree(read_buf);
 
                                /* Release the flash device */
                                flash_safe_release(fmc->mtd);
@@ -1269,7 +1269,7 @@ jffs_scan_flash(struct jffs_control *c)
                                DJM(no_jffs_node--);
 
                                /* Free read buffer */
-                               kfree (read_buf);
+                               kfree(read_buf);
 
                                /* Release the flash device */
                                flash_safe_release(fmc->mtd);
@@ -1296,7 +1296,7 @@ jffs_scan_flash(struct jffs_control *c)
                                        flash_safe_release(fmc->flash_part);
 
                                        /* Free read buffer */
-                                       kfree (read_buf);
+                                       kfree(read_buf);
 
                                        return -ENOMEM;
                                }
@@ -1324,7 +1324,7 @@ jffs_scan_flash(struct jffs_control *c)
        jffs_build_end(fmc);
 
        /* Free read buffer */
-       kfree (read_buf);
+       kfree(read_buf);
 
        if(!num_free_space){
                printk(KERN_WARNING "jffs_scan_flash(): Did not find even a single "
@@ -1747,9 +1747,7 @@ jffs_find_child(struct jffs_file *dir, const char *name, int len)
                }
                printk("jffs_find_child(): Didn't find the file \"%s\".\n",
                       (copy ? copy : ""));
-               if (copy) {
-                       kfree(copy);
-               }
+               kfree(copy);
        });
 
        return f;
index 5b2a83599d73c6649130c161293505384e60e114..1a96903e3ef3786362d459d2089d5ee01750e45c 100644 (file)
@@ -490,7 +490,7 @@ int jffs2_do_crccheck_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *i
                up(&f->sem);
                jffs2_do_clear_inode(c, f);
        }
-       kfree (f);
+       kfree(f);
        return ret;
 }
 
@@ -742,10 +742,8 @@ void jffs2_do_clear_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f)
 
        /* For symlink inodes we us f->dents to store the target path name */
        if (S_ISLNK(OFNI_EDONI_2SFFJ(f)->i_mode)) {
-               if (f->dents) {
-                       kfree(f->dents);
-                       f->dents = NULL;
-               }
+               kfree(f->dents);
+               f->dents = NULL;
        } else {
                fds = f->dents;
 
index 316133c626b7424fc68ccfce9043c5d92c6e359d..7bc7f2d571f68f9bca429d23a41e0754ad9274f9 100644 (file)
@@ -327,8 +327,7 @@ static void jffs2_wbuf_recover(struct jffs2_sb_info *c)
                c->wbuf_ofs = ofs + towrite;
                memmove(c->wbuf, rewrite_buf + towrite, c->wbuf_len);
                /* Don't muck about with c->wbuf_inodes. False positives are harmless. */
-               if (buf)
-                       kfree(buf);
+               kfree(buf);
        } else {
                /* OK, now we're left with the dregs in whichever buffer we're using */
                if (buf) {
index 87332f30141b621b7478f3faacfac6e4c226d991..c5a33648e9fd5b6d88e50c42f9252d48f87cc57d 100644 (file)
@@ -112,8 +112,7 @@ static struct nlm_lockowner *nlm_find_lockowner(struct nlm_host *host, fl_owner_
                }
        }
        spin_unlock(&host->h_lock);
-       if (new != NULL)
-               kfree(new);
+       kfree(new);
        return res;
 }
 
index 298997f174755649a7b3ca5b72bb9e2613a53464..0f1e4530670f18567cc788b39af3ebbced8388ed 100644 (file)
@@ -301,8 +301,7 @@ fail:
        if (cache) {
                while (--m >= 0)
                        kfree(cache->c_indexes_hash[m]);
-               if (cache->c_block_hash)
-                       kfree(cache->c_block_hash);
+               kfree(cache->c_block_hash);
                kfree(cache);
        }
        return NULL;
index c5769c4fcab185ea1996e947c5b910abfd155dd5..b3f8a1966c9cafe0113370bb5843a9b91b96758f 100644 (file)
@@ -1459,7 +1459,7 @@ int may_open(struct nameidata *nd, int acc_mode, int flag)
                if (!error) {
                        DQUOT_INIT(inode);
                        
-                       error = do_truncate(dentry, 0);
+                       error = do_truncate(dentry, 0, NULL);
                }
                put_write_access(inode);
                if (error)
index 3976c177a7d0ed25b87dbf6e26014f25027a3cb7..618a327027b3a1215e6d0cfd720d7d1813e18c88 100644 (file)
@@ -149,8 +149,7 @@ int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct
                }
        }
        spin_unlock(&clp->cl_lock);
-       if (delegation != NULL)
-               kfree(delegation);
+       kfree(delegation);
        return status;
 }
 
index 24d2fbf549bda5ee2f468fd3278e1695958270ac..6391d89642144366591df7e7c0e6733b12916899 100644 (file)
@@ -1688,8 +1688,7 @@ static void nfs_kill_super(struct super_block *s)
 
        rpciod_down();          /* release rpciod */
 
-       if (server->hostname != NULL)
-               kfree(server->hostname);
+       kfree(server->hostname);
        kfree(server);
 }
 
@@ -1908,8 +1907,7 @@ nfs_copy_user_string(char *dst, struct nfs_string *src, int maxlen)
                        return ERR_PTR(-ENOMEM);
        }
        if (copy_from_user(dst, src->data, maxlen)) {
-               if (p != NULL)
-                       kfree(p);
+               kfree(p);
                return ERR_PTR(-EFAULT);
        }
        dst[maxlen] = '\0';
@@ -2000,10 +1998,8 @@ static struct super_block *nfs4_get_sb(struct file_system_type *fs_type,
 out_err:
        s = (struct super_block *)p;
 out_free:
-       if (server->mnt_path)
-               kfree(server->mnt_path);
-       if (server->hostname)
-               kfree(server->hostname);
+       kfree(server->mnt_path);
+       kfree(server->hostname);
        kfree(server);
        return s;
 }
@@ -2023,8 +2019,7 @@ static void nfs4_kill_super(struct super_block *sb)
 
        destroy_nfsv4_state(server);
 
-       if (server->hostname != NULL)
-               kfree(server->hostname);
+       kfree(server->hostname);
        kfree(server);
 }
 
index 52a26baa114c2110bd196b40ac5116a547570130..0675f3215e0a4fb7512f4950b007dfcb98420489 100644 (file)
@@ -69,10 +69,8 @@ init_nfsv4_state(struct nfs_server *server)
 void
 destroy_nfsv4_state(struct nfs_server *server)
 {
-       if (server->mnt_path) {
-               kfree(server->mnt_path);
-               server->mnt_path = NULL;
-       }
+       kfree(server->mnt_path);
+       server->mnt_path = NULL;
        if (server->nfs4_state) {
                nfs4_put_client(server->nfs4_state);
                server->nfs4_state = NULL;
@@ -311,8 +309,7 @@ struct nfs4_state_owner *nfs4_get_state_owner(struct nfs_server *server, struct
                new = NULL;
        }
        spin_unlock(&clp->cl_lock);
-       if (new)
-               kfree(new);
+       kfree(new);
        if (sp != NULL)
                return sp;
        put_rpccred(cred);
index f732541a33329fa2886ad2b56101704f62146cab..d639d172d568fac861124a4e43c8d8f946741438 100644 (file)
@@ -52,8 +52,7 @@ nfs_put_unlinkdata(struct nfs_unlinkdata *data)
 {
        if (--data->count == 0) {
                nfs_detach_unlinkdata(data);
-               if (data->name.name != NULL)
-                       kfree(data->name.name);
+               kfree(data->name.name);
                kfree(data);
        }
 }
index 057aff745506da64d5ca6b61d00f0eb41c597029..417ec02df44f33145504eabd72c940ea6efb3662 100644 (file)
@@ -190,8 +190,7 @@ static int expkey_parse(struct cache_detail *cd, char *mesg, int mlen)
  out:
        if (dom)
                auth_domain_put(dom);
-       if (buf)
-               kfree(buf);
+       kfree(buf);
        return err;
 }
 
@@ -428,8 +427,7 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen)
                path_release(&nd);
        if (dom)
                auth_domain_put(dom);
-       if (buf)
-               kfree(buf);
+       kfree(buf);
        return err;
 }
 
index e0e134d6baba0013af5918f0dd0a4f9c3405b246..9147b8524d05262bd9f28b77c0e7636854367f09 100644 (file)
@@ -366,7 +366,8 @@ nfs3svc_decode_writeargs(struct svc_rqst *rqstp, u32 *p,
        len = args->len = ntohl(*p++);
 
        hdr = (void*)p - rqstp->rq_arg.head[0].iov_base;
-       if (rqstp->rq_arg.len < len + hdr)
+       if (rqstp->rq_arg.len < hdr ||
+           rqstp->rq_arg.len - hdr < len)
                return 0;
 
        args->vec[0].iov_base = (void*)p;
index 4c4146350236be796c83072bd01e3913e344db71..dcd673186944a22f48317c3ecf52e889d1357b86 100644 (file)
@@ -151,8 +151,7 @@ static u32 *read_buf(struct nfsd4_compoundargs *argp, int nbytes)
        if (nbytes <= sizeof(argp->tmp))
                p = argp->tmp;
        else {
-               if (argp->tmpp)
-                       kfree(argp->tmpp);
+               kfree(argp->tmpp);
                p = argp->tmpp = kmalloc(nbytes, GFP_KERNEL);
                if (!p)
                        return NULL;
@@ -2476,10 +2475,8 @@ void nfsd4_release_compoundargs(struct nfsd4_compoundargs *args)
                kfree(args->ops);
                args->ops = args->iops;
        }
-       if (args->tmpp) {
-               kfree(args->tmpp);
-               args->tmpp = NULL;
-       }
+       kfree(args->tmpp);
+       args->tmpp = NULL;
        while (args->to_free) {
                struct tmpbuf *tb = args->to_free;
                args->to_free = tb->next;
index 119e4d4495b8909f41555d6f40386d4663f4207a..d852ebb538e397b83e90aa504a105dcbc50ba98f 100644 (file)
@@ -93,8 +93,7 @@ nfsd_cache_shutdown(void)
 
        cache_disabled = 1;
 
-       if (hash_list)
-               kfree (hash_list);
+       kfree (hash_list);
        hash_list = NULL;
 }
 
index 841c562991e8fdb051b12d18a3a8c88c1f528e16..a0871b3efeb7e35f1c80608ec3dd871d9e663d3f 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/seq_file.h>
 #include <linux/pagemap.h>
 #include <linux/init.h>
+#include <linux/string.h>
 
 #include <linux/nfs.h>
 #include <linux/nfsd_idmap.h>
@@ -35,6 +36,8 @@
 
 #include <asm/uaccess.h>
 
+unsigned int nfsd_versbits = ~0;
+
 /*
  *     We have a single directory with 9 nodes in it.
  */
@@ -50,8 +53,15 @@ enum {
        NFSD_List,
        NFSD_Fh,
        NFSD_Threads,
+       NFSD_Versions,
+       /*
+        * The below MUST come last.  Otherwise we leave a hole in nfsd_files[]
+        * with !CONFIG_NFSD_V4 and simple_fill_super() goes oops
+        */
+#ifdef CONFIG_NFSD_V4
        NFSD_Leasetime,
        NFSD_RecoveryDir,
+#endif
 };
 
 /*
@@ -66,8 +76,11 @@ static ssize_t write_getfd(struct file *file, char *buf, size_t size);
 static ssize_t write_getfs(struct file *file, char *buf, size_t size);
 static ssize_t write_filehandle(struct file *file, char *buf, size_t size);
 static ssize_t write_threads(struct file *file, char *buf, size_t size);
+static ssize_t write_versions(struct file *file, char *buf, size_t size);
+#ifdef CONFIG_NFSD_V4
 static ssize_t write_leasetime(struct file *file, char *buf, size_t size);
 static ssize_t write_recoverydir(struct file *file, char *buf, size_t size);
+#endif
 
 static ssize_t (*write_op[])(struct file *, char *, size_t) = {
        [NFSD_Svc] = write_svc,
@@ -79,8 +92,11 @@ static ssize_t (*write_op[])(struct file *, char *, size_t) = {
        [NFSD_Getfs] = write_getfs,
        [NFSD_Fh] = write_filehandle,
        [NFSD_Threads] = write_threads,
+       [NFSD_Versions] = write_versions,
+#ifdef CONFIG_NFSD_V4
        [NFSD_Leasetime] = write_leasetime,
        [NFSD_RecoveryDir] = write_recoverydir,
+#endif
 };
 
 static ssize_t nfsctl_transaction_write(struct file *file, const char __user *buf, size_t size, loff_t *pos)
@@ -104,9 +120,23 @@ static ssize_t nfsctl_transaction_write(struct file *file, const char __user *bu
        return rv;
 }
 
+static ssize_t nfsctl_transaction_read(struct file *file, char __user *buf, size_t size, loff_t *pos)
+{
+       if (! file->private_data) {
+               /* An attempt to read a transaction file without writing
+                * causes a 0-byte write so that the file can return
+                * state information
+                */
+               ssize_t rv = nfsctl_transaction_write(file, buf, 0, pos);
+               if (rv < 0)
+                       return rv;
+       }
+       return simple_transaction_read(file, buf, size, pos);
+}
+
 static struct file_operations transaction_ops = {
        .write          = nfsctl_transaction_write,
-       .read           = simple_transaction_read,
+       .read           = nfsctl_transaction_read,
        .release        = simple_transaction_release,
 };
 
@@ -329,6 +359,70 @@ static ssize_t write_threads(struct file *file, char *buf, size_t size)
        return strlen(buf);
 }
 
+static ssize_t write_versions(struct file *file, char *buf, size_t size)
+{
+       /*
+        * Format:
+        *   [-/+]vers [-/+]vers ...
+        */
+       char *mesg = buf;
+       char *vers, sign;
+       int len, num;
+       ssize_t tlen = 0;
+       char *sep;
+
+       if (size>0) {
+               if (nfsd_serv)
+                       return -EBUSY;
+               if (buf[size-1] != '\n')
+                       return -EINVAL;
+               buf[size-1] = 0;
+
+               vers = mesg;
+               len = qword_get(&mesg, vers, size);
+               if (len <= 0) return -EINVAL;
+               do {
+                       sign = *vers;
+                       if (sign == '+' || sign == '-')
+                               num = simple_strtol((vers+1), NULL, 0);
+                       else
+                               num = simple_strtol(vers, NULL, 0);
+                       switch(num) {
+                       case 2:
+                       case 3:
+                       case 4:
+                               if (sign != '-')
+                                       NFSCTL_VERSET(nfsd_versbits, num);
+                               else
+                                       NFSCTL_VERUNSET(nfsd_versbits, num);
+                               break;
+                       default:
+                               return -EINVAL;
+                       }
+                       vers += len + 1;
+                       tlen += len;
+               } while ((len = qword_get(&mesg, vers, size)) > 0);
+               /* If all get turned off, turn them back on, as
+                * having no versions is BAD
+                */
+               if ((nfsd_versbits & NFSCTL_VERALL)==0)
+                       nfsd_versbits = NFSCTL_VERALL;
+       }
+       /* Now write current state into reply buffer */
+       len = 0;
+       sep = "";
+       for (num=2 ; num <= 4 ; num++)
+               if (NFSCTL_VERISSET(NFSCTL_VERALL, num)) {
+                       len += sprintf(buf+len, "%s%c%d", sep,
+                                      NFSCTL_VERISSET(nfsd_versbits, num)?'+':'-',
+                                      num);
+                       sep = " ";
+               }
+       len += sprintf(buf+len, "\n");
+       return len;
+}
+
+#ifdef CONFIG_NFSD_V4
 extern time_t nfs4_leasetime(void);
 
 static ssize_t write_leasetime(struct file *file, char *buf, size_t size)
@@ -370,6 +464,7 @@ static ssize_t write_recoverydir(struct file *file, char *buf, size_t size)
        status = nfs4_reset_recoverydir(recdir);
        return strlen(buf);
 }
+#endif
 
 /*----------------------------------------------------------------------------*/
 /*
@@ -389,6 +484,7 @@ static int nfsd_fill_super(struct super_block * sb, void * data, int silent)
                [NFSD_List] = {"exports", &exports_operations, S_IRUGO},
                [NFSD_Fh] = {"filehandle", &transaction_ops, S_IWUSR|S_IRUSR},
                [NFSD_Threads] = {"threads", &transaction_ops, S_IWUSR|S_IRUSR},
+               [NFSD_Versions] = {"versions", &transaction_ops, S_IWUSR|S_IRUSR},
 #ifdef CONFIG_NFSD_V4
                [NFSD_Leasetime] = {"nfsv4leasetime", &transaction_ops, S_IWUSR|S_IRUSR},
                [NFSD_RecoveryDir] = {"nfsv4recoverydir", &transaction_ops, S_IWUSR|S_IRUSR},
index 1697539a7171777815cf6e54bd7738e3e3fdacde..89ed04696865a9595d67a2922ec33c55786862c2 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/nfsd/nfsd.h>
 #include <linux/nfsd/stats.h>
 #include <linux/nfsd/cache.h>
+#include <linux/nfsd/syscall.h>
 #include <linux/lockd/bind.h>
 #include <linux/nfsacl.h>
 
@@ -52,7 +53,7 @@
 extern struct svc_program      nfsd_program;
 static void                    nfsd(struct svc_rqst *rqstp);
 struct timeval                 nfssvc_boot;
-static struct svc_serv                 *nfsd_serv;
+       struct svc_serv                 *nfsd_serv;
 static atomic_t                        nfsd_busy;
 static unsigned long           nfsd_last_call;
 static DEFINE_SPINLOCK(nfsd_call_lock);
@@ -63,6 +64,31 @@ struct nfsd_list {
 };
 static struct list_head nfsd_list = LIST_HEAD_INIT(nfsd_list);
 
+static struct svc_version *    nfsd_version[] = {
+       [2] = &nfsd_version2,
+#if defined(CONFIG_NFSD_V3)
+       [3] = &nfsd_version3,
+#endif
+#if defined(CONFIG_NFSD_V4)
+       [4] = &nfsd_version4,
+#endif
+};
+
+#define NFSD_MINVERS           2
+#define NFSD_NRVERS            (sizeof(nfsd_version)/sizeof(nfsd_version[0]))
+static struct svc_version *nfsd_versions[NFSD_NRVERS];
+
+struct svc_program             nfsd_program = {
+       .pg_prog                = NFS_PROGRAM,          /* program number */
+       .pg_nvers               = NFSD_NRVERS,          /* nr of entries in nfsd_version */
+       .pg_vers                = nfsd_versions,        /* version table */
+       .pg_name                = "nfsd",               /* program name */
+       .pg_class               = "nfsd",               /* authentication class */
+       .pg_stats               = &nfsd_svcstats,       /* version table */
+       .pg_authenticate        = &svc_set_client,      /* export authentication */
+
+};
+
 /*
  * Maximum number of nfsd processes
  */
@@ -80,11 +106,12 @@ int
 nfsd_svc(unsigned short port, int nrservs)
 {
        int     error;
-       int     none_left;      
+       int     none_left, found_one, i;
        struct list_head *victim;
        
        lock_kernel();
-       dprintk("nfsd: creating service\n");
+       dprintk("nfsd: creating service: vers 0x%x\n",
+               nfsd_versbits);
        error = -EINVAL;
        if (nrservs <= 0)
                nrservs = 0;
@@ -99,6 +126,27 @@ nfsd_svc(unsigned short port, int nrservs)
        if (error<0)
                goto out;
        if (!nfsd_serv) {
+               /*
+                * Use the nfsd_ctlbits to define which
+                * versions that will be advertised.
+                * If nfsd_ctlbits doesn't list any version,
+                * export them all.
+                */
+               found_one = 0;
+
+               for (i = NFSD_MINVERS; i < NFSD_NRVERS; i++) {
+                       if (NFSCTL_VERISSET(nfsd_versbits, i)) {
+                               nfsd_program.pg_vers[i] = nfsd_version[i];
+                               found_one = 1;
+                       } else
+                               nfsd_program.pg_vers[i] = NULL;
+               }
+
+               if (!found_one) {
+                       for (i = NFSD_MINVERS; i < NFSD_NRVERS; i++)
+                               nfsd_program.pg_vers[i] = nfsd_version[i];
+               }
+
                atomic_set(&nfsd_busy, 0);
                error = -ENOMEM;
                nfsd_serv = svc_create(&nfsd_program, NFSD_BUFSIZE);
@@ -379,6 +427,7 @@ static struct svc_program   nfsd_acl_program = {
        .pg_name                = "nfsd",
        .pg_class               = "nfsd",
        .pg_stats               = &nfsd_acl_svcstats,
+       .pg_authenticate        = &svc_set_client,
 };
 
 static struct svc_stat nfsd_acl_svcstats = {
@@ -389,28 +438,3 @@ static struct svc_stat     nfsd_acl_svcstats = {
 #else
 #define nfsd_acl_program_p     NULL
 #endif /* defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) */
-
-extern struct svc_version nfsd_version2, nfsd_version3, nfsd_version4;
-
-static struct svc_version *    nfsd_version[] = {
-       [2] = &nfsd_version2,
-#if defined(CONFIG_NFSD_V3)
-       [3] = &nfsd_version3,
-#endif
-#if defined(CONFIG_NFSD_V4)
-       [4] = &nfsd_version4,
-#endif
-};
-
-#define NFSD_NRVERS            (sizeof(nfsd_version)/sizeof(nfsd_version[0]))
-struct svc_program             nfsd_program = {
-       .pg_next                = nfsd_acl_program_p,
-       .pg_prog                = NFS_PROGRAM,          /* program number */
-       .pg_nvers               = NFSD_NRVERS,          /* nr of entries in nfsd_version */
-       .pg_vers                = nfsd_version,         /* version table */
-       .pg_name                = "nfsd",               /* program name */
-       .pg_class               = "nfsd",               /* authentication class */
-       .pg_stats               = &nfsd_svcstats,       /* version table */
-       .pg_authenticate        = &svc_set_client,      /* export authentication */
-
-};
index 4f2cd3d2756665a1f600f8bcac96b4f2756b1ded..af7c3c3074b0075243a5850743a07ede58ebd863 100644 (file)
@@ -254,12 +254,19 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap,
 
        /* Get inode */
        err = fh_verify(rqstp, fhp, ftype, accmode);
-       if (err || !iap->ia_valid)
+       if (err)
                goto out;
 
        dentry = fhp->fh_dentry;
        inode = dentry->d_inode;
 
+       /* Ignore any mode updates on symlinks */
+       if (S_ISLNK(inode->i_mode))
+               iap->ia_valid &= ~ATTR_MODE;
+
+       if (!iap->ia_valid)
+               goto out;
+
        /* NFSv2 does not differentiate between "set-[ac]time-to-now"
         * which only requires access, and "set-[ac]time-to-X" which
         * requires ownership.
index 8d06ec911fd9df99762741ecb2ae7cf6b75ab8b0..6e8136751e9a49e1c89f47eb1957ed9f635281a7 100644 (file)
--- a/fs/open.c
+++ b/fs/open.c
@@ -194,7 +194,7 @@ out:
        return error;
 }
 
-int do_truncate(struct dentry *dentry, loff_t length)
+int do_truncate(struct dentry *dentry, loff_t length, struct file *filp)
 {
        int err;
        struct iattr newattrs;
@@ -205,6 +205,10 @@ int do_truncate(struct dentry *dentry, loff_t length)
 
        newattrs.ia_size = length;
        newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME;
+       if (filp) {
+               newattrs.ia_file = filp;
+               newattrs.ia_valid |= ATTR_FILE;
+       }
 
        down(&dentry->d_inode->i_sem);
        err = notify_change(dentry, &newattrs);
@@ -262,7 +266,7 @@ static inline long do_sys_truncate(const char __user * path, loff_t length)
        error = locks_verify_truncate(inode, NULL, length);
        if (!error) {
                DQUOT_INIT(inode);
-               error = do_truncate(nd.dentry, length);
+               error = do_truncate(nd.dentry, length, NULL);
        }
        put_write_access(inode);
 
@@ -314,7 +318,7 @@ static inline long do_sys_ftruncate(unsigned int fd, loff_t length, int small)
 
        error = locks_verify_truncate(inode, file, length);
        if (!error)
-               error = do_truncate(dentry, length);
+               error = do_truncate(dentry, length, file);
 out_putf:
        fput(file);
 out:
@@ -887,6 +891,10 @@ struct file *nameidata_to_filp(struct nameidata *nd, int flags)
        return filp;
 }
 
+/*
+ * dentry_open() will have done dput(dentry) and mntput(mnt) if it returns an
+ * error.
+ */
 struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
 {
        int error;
@@ -894,8 +902,11 @@ struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
 
        error = -ENFILE;
        f = get_empty_filp();
-       if (f == NULL)
+       if (f == NULL) {
+               dput(dentry);
+               mntput(mnt);
                return ERR_PTR(error);
+       }
 
        return __dentry_open(dentry, mnt, flags, f, NULL);
 }
index 1be11ce96b0f915f4ebc2ea2ba1deba8068eb4e5..aeb0106890e4f1db6dc903f3d5e94f3724278ab0 100644 (file)
@@ -1088,8 +1088,7 @@ static void __exit exit_openprom_fs(void)
        unregister_filesystem(&openprom_fs_type);
        free_pages ((unsigned long)nodes, alloced);
        for (i = 0; i < aliases_nodes; i++)
-               if (alias_names [i])
-                       kfree (alias_names [i]);
+               kfree (alias_names [i]);
        nodes = NULL;
 }
 
index d59dcbf2bd4a33dadaff4098cf39b24f0cb65aa1..6327bcb2d73df0d99b90dbde3a14e7958e7de330 100644 (file)
@@ -29,7 +29,7 @@
  * cyl-cyl-head-head structure
  */
 static inline int
-cchh2blk (cchh_t *ptr, struct hd_geometry *geo) {
+cchh2blk (struct vtoc_cchh *ptr, struct hd_geometry *geo) {
         return ptr->cc * geo->heads * geo->sectors +
               ptr->hh * geo->sectors;
 }
@@ -40,7 +40,7 @@ cchh2blk (cchh_t *ptr, struct hd_geometry *geo) {
  * cyl-cyl-head-head-block structure
  */
 static inline int
-cchhb2blk (cchhb_t *ptr, struct hd_geometry *geo) {
+cchhb2blk (struct vtoc_cchhb *ptr, struct hd_geometry *geo) {
         return ptr->cc * geo->heads * geo->sectors +
                ptr->hh * geo->sectors +
                ptr->b;
@@ -56,7 +56,7 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev)
        struct hd_geometry *geo;
        char type[5] = {0,};
        char name[7] = {0,};
-       volume_label_t *vlabel;
+       struct vtoc_volume_label *vlabel;
        unsigned char *data;
        Sector sect;
 
@@ -64,7 +64,8 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev)
                goto out_noinfo;
        if ((geo = kmalloc(sizeof(struct hd_geometry), GFP_KERNEL)) == NULL)
                goto out_nogeo;
-       if ((vlabel = kmalloc(sizeof(volume_label_t), GFP_KERNEL)) == NULL)
+       if ((vlabel = kmalloc(sizeof(struct vtoc_volume_label),
+                             GFP_KERNEL)) == NULL)
                goto out_novlab;
        
        if (ioctl_by_bdev(bdev, BIODASDINFO, (unsigned long)info) != 0 ||
@@ -86,7 +87,7 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev)
                strncpy(name, data + 8, 6);
        else
                strncpy(name, data + 4, 6);
-       memcpy (vlabel, data, sizeof(volume_label_t));
+       memcpy (vlabel, data, sizeof(struct vtoc_volume_label));
        put_dev_sector(sect);
 
        EBCASC(type, 4);
@@ -129,9 +130,9 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev)
                counter = 0;
                while ((data = read_dev_sector(bdev, blk*(blocksize/512),
                                               &sect)) != NULL) {
-                       format1_label_t f1;
+                       struct vtoc_format1_label f1;
 
-                       memcpy(&f1, data, sizeof(format1_label_t));
+                       memcpy(&f1, data, sizeof(struct vtoc_format1_label));
                        put_dev_sector(sect);
 
                        /* skip FMT4 / FMT5 / FMT7 labels */
index 1df7832b4e087460876251bf7b70d79566264f1a..612e04db4b939189721f35182c2dd1793804ae89 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/security.h>
 #include <linux/syscalls.h>
 #include <linux/buffer_head.h>
+#include <linux/quotaops.h>
 
 /* Check validity of generic quotactl commands */
 static int generic_quotactl_valid(struct super_block *sb, int type, int cmd, qid_t id)
index 2d85dd7415bb2a487d35f6ddc96fb52e653bef1f..a0f296d9928ad39d1044597553c36f9c75ac0b55 100644 (file)
@@ -786,8 +786,7 @@ int smb_request_recv(struct smb_sb_info *server)
                /* We should never be called with any of these states */
        case SMB_RECV_END:
        case SMB_RECV_REQUEST:
-               server->rstate = SMB_RECV_END;
-               break;
+               BUG();
        }
 
        if (result < 0) {
index 0c64bc3a0127e9c15c6f76921ea688f7eee73b6f..cdc53c4fb3813448ef6c7c0dba700b7ad38c4752 100644 (file)
@@ -45,7 +45,7 @@ static void *smb_follow_link(struct dentry *dentry, struct nameidata *nd)
                int len = smb_proc_read_link(server_from_dentry(dentry),
                                                dentry, link, PATH_MAX - 1);
                if (len < 0) {
-                       putname(link);
+                       __putname(link);
                        link = ERR_PTR(len);
                } else {
                        link[len] = 0;
@@ -59,7 +59,7 @@ static void smb_put_link(struct dentry *dentry, struct nameidata *nd, void *p)
 {
        char *s = nd_get_link(nd);
        if (!IS_ERR(s))
-               putname(s);
+               __putname(s);
 }
 
 struct inode_operations smb_link_inode_operations =
index f60155ec778010c6468b432fa60b9ebc96b98495..eed6c3132905bad2cc660e3e04e095acf1d687c4 100644 (file)
@@ -474,8 +474,6 @@ rescan:
        return NULL;
 }
 
-EXPORT_SYMBOL(user_get_super);
-
 asmlinkage long sys_ustat(unsigned dev, struct ustat __user * ubuf)
 {
         struct super_block *s;
index 0e54922daa0917ef802a73edf998f467c7b09c9d..663669810be60afbae65f2a262a657f98bfa7f64 100644 (file)
@@ -39,8 +39,7 @@ static inline struct udf_sb_info *UDF_SB(struct super_block *sb)
 {\
        if (UDF_SB(X))\
        {\
-               if (UDF_SB_PARTMAPS(X))\
-                       kfree(UDF_SB_PARTMAPS(X));\
+               kfree(UDF_SB_PARTMAPS(X));\
                UDF_SB_PARTMAPS(X) = NULL;\
        }\
 }
index f036d694ba5afe75263862b30870c4ff6794c590..54828ebcf1bacda4d1c94dc4461cd99d8264234d 100644 (file)
@@ -472,13 +472,14 @@ static int ufs_read_cylinder_structures (struct super_block *sb) {
        return 1;
 
 failed:
-       if (base) kfree (base);
+       kfree (base);
        if (sbi->s_ucg) {
                for (i = 0; i < uspi->s_ncg; i++)
-                       if (sbi->s_ucg[i]) brelse (sbi->s_ucg[i]);
+                       if (sbi->s_ucg[i])
+                               brelse (sbi->s_ucg[i]);
                kfree (sbi->s_ucg);
                for (i = 0; i < UFS_MAX_GROUP_LOADED; i++)
-                       if (sbi->s_ucpi[i]) kfree (sbi->s_ucpi[i]);
+                       kfree (sbi->s_ucpi[i]);
        }
        UFSD(("EXIT (FAILED)\n"))
        return 0;
@@ -981,9 +982,10 @@ magic_found:
 dalloc_failed:
        iput(inode);
 failed:
-       if (ubh) ubh_brelse_uspi (uspi);
-       if (uspi) kfree (uspi);
-       if (sbi) kfree(sbi);
+       if (ubh)
+               ubh_brelse_uspi (uspi);
+       kfree (uspi);
+       kfree(sbi);
        sb->s_fs_info = NULL;
        UFSD(("EXIT (FAILED)\n"))
        return -EINVAL;
index f6e00c0e114f6225d1f7af66517dd537aa0724bf..a9db225579983b4babe40ac4c47a9eef0a3250cb 100644 (file)
@@ -74,8 +74,7 @@ setxattr(struct dentry *d, char __user *name, void __user *value,
        }
 out:
        up(&d->d_inode->i_sem);
-       if (kvalue)
-               kfree(kvalue);
+       kfree(kvalue);
        return error;
 }
 
@@ -173,8 +172,7 @@ getxattr(struct dentry *d, char __user *name, void __user *value, size_t size)
                error = -E2BIG;
        }
 out:
-       if (kvalue)
-               kfree(kvalue);
+       kfree(kvalue);
        return error;
 }
 
@@ -259,8 +257,7 @@ listxattr(struct dentry *d, char __user *list, size_t size)
                error = -E2BIG;
        }
 out:
-       if (klist)
-               kfree(klist);
+       kfree(klist);
        return error;
 }
 
index 8f82c1a20dc5311e38c641bb0aa230747649545a..c64a29cdfff3446835da2e29ed3774840a551b97 100644 (file)
@@ -30,8 +30,8 @@
 #define KM_NOFS                0x0004u
 #define KM_MAYFAIL     0x0008u
 
-#define        kmem_zone       kmem_cache_s
-#define kmem_zone_t    kmem_cache_t
+#define        kmem_zone       kmem_cache
+#define kmem_zone_t    struct kmem_cache
 
 typedef unsigned long xfs_pflags_t;
 
index 8393bf374b2b59c85bd90c60440322bacd4c8426..a985cd29b6db2f5dc013d7313cf92b4f40c7b7e2 100644 (file)
@@ -17,6 +17,9 @@
 #include <asm/processor.h>     /* For TASK_SIZE */
 #include <asm/machvec.h>
 
+struct mm_struct;
+struct vm_area_struct;
+
 /* Certain architectures need to do special things when PTEs
  * within a page table are directly modified.  Thus, the following
  * hook is made available.
index d462c5e14c13e4d227c76df4099cbb904650ea53..072375c135b4a008799173b655837fb39c3d2b91 100644 (file)
@@ -67,6 +67,9 @@ struct switch_stack {
 };
 
 #ifdef __KERNEL__
+
+#define __ARCH_SYS_PTRACE      1
+
 #define user_mode(regs) (((regs)->ps & 8) != 0)
 #define instruction_pointer(regs) ((regs)->pc)
 #define profile_pc(regs) instruction_pointer(regs)
index e24465d1f40dda439795dcab869f43182ee01d7f..255b646b7fa8dbe6a586d88e4d7136ee5a12c75d 100644 (file)
@@ -9,14 +9,14 @@
  * them together into ntohl etc.
  */
 
-extern __inline__ __attribute_const__ __u32 ___arch__swab32(__u32 x)
+static inline __attribute_const__ __u32 ___arch__swab32(__u32 x)
 {
        __asm__ ("swapwb %0" : "=r" (x) : "0" (x));
   
        return(x);
 }
 
-extern __inline__ __attribute_const__ __u16 ___arch__swab16(__u16 x)
+static inline __attribute_const__ __u16 ___arch__swab16(__u16 x)
 {
        __asm__ ("swapb %0" : "=r" (x) : "0" (x));
        
index fde1d00aaa903ad4cfaf614a1a2e8e975f7e8517..633f234f336b4cd86003209f67c622e4f6c85458 100644 (file)
@@ -8,7 +8,7 @@
  * to split all of those into 16-bit components, then add.
  */
 
-extern inline unsigned int
+static inline unsigned int
 csum_tcpudp_nofold(unsigned long saddr, unsigned long daddr, unsigned short len,
                   unsigned short proto, unsigned int sum)
 {
index cfedae0d2f53dd5316e008513f57b85f795fe052..39481f6e0c3018e58a1bc06bc4627738a7753f61 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef _CRIS_ARCH_DELAY_H
 #define _CRIS_ARCH_DELAY_H
 
-extern __inline__ void __delay(int loops)
+static inline void __delay(int loops)
 {
        __asm__ __volatile__ (
                              "move.d %0,$r9\n\t"
index 8cf2d7cb22ac3bd7fe3ac0f2ab60d709635f8774..78b301ed7b126961fe4554f6a16a3d81e70596e3 100644 (file)
@@ -25,7 +25,7 @@
 
 #define MAX_HWIFS      4
 
-extern __inline__ int ide_default_irq(unsigned long base)
+static inline int ide_default_irq(unsigned long base)
 {
        /* all IDE busses share the same IRQ, number 4.
         * this has the side-effect that ide-probe.c will cluster our 4 interfaces
@@ -35,7 +35,7 @@ extern __inline__ int ide_default_irq(unsigned long base)
        return 4;
 }
 
-extern __inline__ unsigned long ide_default_io_base(int index)
+static inline unsigned long ide_default_io_base(int index)
 {
        /* we have no real I/O base address per interface, since all go through the
         * same register. but in a bitfield in that register, we have the i/f number.
@@ -54,7 +54,7 @@ extern __inline__ unsigned long ide_default_io_base(int index)
  * of the ide_default_io_base call above. ctrl_port will be 0, but that is don't care for us.
  */
 
-extern __inline__ void ide_init_hwif_ports(hw_regs_t *hw, unsigned long data_port, unsigned long ctrl_port, int *irq)
+static inline void ide_init_hwif_ports(hw_regs_t *hw, unsigned long data_port, unsigned long ctrl_port, int *irq)
 {
        int i;
 
@@ -77,7 +77,7 @@ extern __inline__ void ide_init_hwif_ports(hw_regs_t *hw, unsigned long data_por
        hw->io_ports[IDE_IRQ_OFFSET] = 0;
 }
 
-extern __inline__ void ide_init_default_hwifs(void)
+static inline void ide_init_default_hwifs(void)
 {
        hw_regs_t hw;
        int index;
index 6cc35642b8ab0d08c6182ba6256f8a642fe85299..1ac7b639b1b01670c59dca8323c5e17556b65987 100644 (file)
@@ -5,7 +5,7 @@
 
 /* read the CPU version register */
 
-extern inline unsigned long rdvr(void) { 
+static inline unsigned long rdvr(void) {
        unsigned char vr;
        __asm__ volatile ("move $vr,%0" : "=rm" (vr));
        return vr;
@@ -15,7 +15,7 @@ extern inline unsigned long rdvr(void) {
 
 /* read/write the user-mode stackpointer */
 
-extern inline unsigned long rdusp(void) {
+static inline unsigned long rdusp(void) {
        unsigned long usp;
        __asm__ __volatile__("move $usp,%0" : "=rm" (usp));
        return usp;
@@ -26,13 +26,13 @@ extern inline unsigned long rdusp(void) {
 
 /* read the current stackpointer */
 
-extern inline unsigned long rdsp(void) {
+static inline unsigned long rdsp(void) {
        unsigned long sp;
        __asm__ __volatile__("move.d $sp,%0" : "=rm" (sp));
        return sp;
 }
 
-extern inline unsigned long _get_base(char * addr)
+static inline unsigned long _get_base(char * addr)
 {
   return 0;
 }
index 357f5df0c9076c6bf21b95bfa9beeb5506f22ad5..218f4152d3e594f303ce1f9b386eb2ac5c41289e 100644 (file)
@@ -2,7 +2,7 @@
 #define _ASM_ARCH_THREAD_INFO_H
 
 /* how to get the thread information struct from C */
-extern inline struct thread_info *current_thread_info(void)
+static inline struct thread_info *current_thread_info(void)
 {
        struct thread_info *ti;
         __asm__("and.d $sp,%0; ":"=r" (ti) : "0" (~8191UL));
index ecfc553c06a5f77f818fcf45cfb1bac0f0f510a0..e48447d94faf093f380dfa2f6e944099f8d316d5 100644 (file)
@@ -22,7 +22,7 @@
 
 unsigned long get_ns_in_jiffie(void);
 
-extern inline unsigned long get_us_in_jiffie_highres(void)
+static inline unsigned long get_us_in_jiffie_highres(void)
 {
        return get_ns_in_jiffie()/1000;
 }
index 787d2e60c83c20382a6154654e119e824484dfc7..65b02d9b605af168fa619463e43b9ab0636aee76 100644 (file)
@@ -87,7 +87,7 @@
  * bytes copied                if we hit a null byte
  * (without the null byte)
  */
-extern inline long         
+static inline long
 __do_strncpy_from_user(char *dst, const char *src, long count)
 {
        long res;
@@ -602,7 +602,7 @@ __do_strncpy_from_user(char *dst, const char *src, long count)
  * or 0 for error.  Return a value greater than N if too long.
  */
 
-extern inline long
+static inline long
 strnlen_user(const char *s, long n)
 {
        long res, tmp1;
index e40a58d3b862ab01db41bbe9f9a76095e2f23d7b..147689d6b624bc806ccfe5e2603506ac7672b00a 100644 (file)
@@ -8,7 +8,7 @@
  * inverts all bits in the input.
  */
 
-extern inline unsigned long
+static inline unsigned long
 cris_swapnwbrlz(unsigned long w)
 {
        unsigned long res;
@@ -20,7 +20,7 @@ cris_swapnwbrlz(unsigned long w)
        return res;
 }
 
-extern inline unsigned long
+static inline unsigned long
 cris_swapwbrlz(unsigned long w)
 {
        unsigned long res;
@@ -36,7 +36,7 @@ cris_swapwbrlz(unsigned long w)
  * Find First Zero in word. Undefined if no zero exist, so the caller should
  * check against ~0 first.
  */
-extern inline unsigned long
+static inline unsigned long
 ffz(unsigned long w)
 {
        return cris_swapnwbrlz(w);
@@ -46,7 +46,7 @@ ffz(unsigned long w)
  * Find First Set bit in word. Undefined if no 1 exist, so the caller
  * should check against 0 first.
  */
-extern inline unsigned long
+static inline unsigned long
 __ffs(unsigned long w)
 {
        return cris_swapnwbrlz(~w);
@@ -55,7 +55,7 @@ __ffs(unsigned long w)
 /*
  * Find First Bit that is set.
  */
-extern inline unsigned long
+static inline unsigned long
 kernel_ffs(unsigned long w)
 {
        return w ? cris_swapwbrlz (w) + 1 : 0;
index 74846ee6cf99e36c62b7beda482df9c7adb91f20..6ef8fb4a35f270fd8afdc85c2348393aed269468 100644 (file)
@@ -3,14 +3,14 @@
 
 #include <asm/types.h>
 
-extern __inline__ __const__ __u32
+static inline __const__ __u32
 ___arch__swab32(__u32 x)
 {
        __asm__ __volatile__ ("swapwb %0" : "=r" (x) : "0" (x));
        return (x);
 }
 
-extern __inline__ __const__ __u16
+static inline __const__ __u16
 ___arch__swab16(__u16 x)
 {
        __asm__ __volatile__ ("swapb %0" : "=r" (x) : "0" (x));
index a1d6b2a6cc447d95201dca7479d4134ebf0cae71..97ef89efea62ca9636fffc50f09aa52d7dac8dbe 100644 (file)
@@ -9,7 +9,7 @@
  * checksum. Which means it would be necessary to split all those into
  * 16-bit components and then add.
  */
-extern inline unsigned int
+static inline unsigned int
 csum_tcpudp_nofold(unsigned long saddr, unsigned long daddr,
                   unsigned short len, unsigned short proto, unsigned int sum)
 {
index f36f7f760e891b9e1e6384e51f207b895813485d..b6e941e637de10935d0be469c4ab7346d8d7b8ef 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef _ASM_CRIS_ARCH_DELAY_H
 #define _ASM_CRIS_ARCH_DELAY_H
 
-extern __inline__ void
+static inline void
 __delay(int loops)
 {
        __asm__ __volatile__ (
index 24f5604f566ac28b780d7daa87c44532c7beae3e..6590f657500dc1c6e7b1d3cd5e6eec265471dacb 100644 (file)
@@ -26,7 +26,7 @@
 
 #define MAX_HWIFS      4
 
-extern __inline__ int ide_default_irq(unsigned long base)
+static inline int ide_default_irq(unsigned long base)
 {
        /* all IDE busses share the same IRQ,
         * this has the side-effect that ide-probe.c will cluster our 4 interfaces
@@ -36,7 +36,7 @@ extern __inline__ int ide_default_irq(unsigned long base)
        return ATA_INTR_VECT;
 }
 
-extern __inline__ unsigned long ide_default_io_base(int index)
+static inline unsigned long ide_default_io_base(int index)
 {
        reg_ata_rw_ctrl2 ctrl2 = {.sel = index};
        /* we have no real I/O base address per interface, since all go through the
index 4c80263ec634fd948bb0e7db404577ea593ea071..043c9ce5294e9192ee00e0aa75edf9eb94f4c33e 100644 (file)
@@ -35,7 +35,7 @@ extern struct crisv32_iopin crisv32_led2_red;
 extern struct crisv32_iopin crisv32_led3_green;
 extern struct crisv32_iopin crisv32_led3_red;
 
-extern inline void crisv32_io_set(struct crisv32_iopin* iopin,
+static inline void crisv32_io_set(struct crisv32_iopin* iopin,
                           int val)
 {
        if (val)
@@ -44,7 +44,7 @@ extern inline void crisv32_io_set(struct crisv32_iopin* iopin,
                *iopin->port->data &= ~iopin->bit;
 }
 
-extern inline void crisv32_io_set_dir(struct crisv32_iopin* iopin,
+static inline void crisv32_io_set_dir(struct crisv32_iopin* iopin,
                               enum crisv32_io_dir dir)
 {
        if (dir == crisv32_io_dir_in)
@@ -53,7 +53,7 @@ extern inline void crisv32_io_set_dir(struct crisv32_iopin* iopin,
                *iopin->port->oe |= iopin->bit;
 }
 
-extern inline int crisv32_io_rd(struct crisv32_iopin* iopin)
+static inline int crisv32_io_rd(struct crisv32_iopin* iopin)
 {
        return ((*iopin->port->data_in & iopin->bit) ? 1 : 0);
 }
index b9afbb95e0bb35f74e9c88e9374efd6953dd958c..a3d75d581e2f5d20942eeee48df4dde3a3737409 100644 (file)
@@ -4,7 +4,7 @@
 #include <linux/config.h>
 
 /* Read the CPU version register. */
-extern inline unsigned long rdvr(void)
+static inline unsigned long rdvr(void)
 {
        unsigned char vr;
 
@@ -15,7 +15,7 @@ extern inline unsigned long rdvr(void)
 #define cris_machine_name "crisv32"
 
 /* Read the user-mode stack pointer. */
-extern inline unsigned long rdusp(void)
+static inline unsigned long rdusp(void)
 {
        unsigned long usp;
 
@@ -24,7 +24,7 @@ extern inline unsigned long rdusp(void)
 }
 
 /* Read the current stack pointer. */
-extern inline unsigned long rdsp(void)
+static inline unsigned long rdsp(void)
 {
        unsigned long sp;
 
index a7a182307da0d2ac7c9fd9f9d0fabe07b9a2bf0e..d6936956a3c6c073fe7e47c5da9399c597d783d1 100644 (file)
@@ -2,7 +2,7 @@
 #define _ASM_CRIS_ARCH_THREAD_INFO_H
 
 /* Return a thread_info struct. */
-extern inline struct thread_info *current_thread_info(void)
+static inline struct thread_info *current_thread_info(void)
 {
        struct thread_info *ti;
 
index 4d0fd23b21e998084b3dc516adab7ce79c04afcf..5a4aa285d5fdb0c7ffa0a047263c70988979b4f0 100644 (file)
@@ -22,7 +22,7 @@
 
 extern unsigned long get_ns_in_jiffie(void);
 
-extern inline unsigned long get_us_in_jiffie_highres(void)
+static inline unsigned long get_us_in_jiffie_highres(void)
 {
        return get_ns_in_jiffie() / 1000;
 }
index 055a0bdbe835e1bb9c5533a9a53f16819055260a..6b207f1b66227e73e82b22a9712409049a465409 100644 (file)
@@ -93,7 +93,7 @@
  * bytes copied                if we hit a null byte
  * (without the null byte)
  */
-extern inline long
+static inline long
 __do_strncpy_from_user(char *dst, const char *src, long count)
 {
        long res;
@@ -695,7 +695,7 @@ __do_strncpy_from_user(char *dst, const char *src, long count)
  * or 0 for error.  Return a value greater than N if too long.
  */
 
-extern inline long
+static inline long
 strnlen_user(const char *s, long n)
 {
        long res, tmp1;
index 70605b09e8b73a324affede0a8887807275fe1c1..8c2e78304523c24da5904dc9b3d85d2988383979 100644 (file)
@@ -20,7 +20,7 @@ typedef struct { volatile int counter; } atomic_t;
 
 /* These should be written in asm but we do it in C for now. */
 
-extern __inline__ void atomic_add(int i, volatile atomic_t *v)
+static inline void atomic_add(int i, volatile atomic_t *v)
 {
        unsigned long flags;
        cris_atomic_save(v, flags);
@@ -28,7 +28,7 @@ extern __inline__ void atomic_add(int i, volatile atomic_t *v)
        cris_atomic_restore(v, flags);
 }
 
-extern __inline__ void atomic_sub(int i, volatile atomic_t *v)
+static inline void atomic_sub(int i, volatile atomic_t *v)
 {
        unsigned long flags;
        cris_atomic_save(v, flags);
@@ -36,7 +36,7 @@ extern __inline__ void atomic_sub(int i, volatile atomic_t *v)
        cris_atomic_restore(v, flags);
 }
 
-extern __inline__ int atomic_add_return(int i, volatile atomic_t *v)
+static inline int atomic_add_return(int i, volatile atomic_t *v)
 {
        unsigned long flags;
        int retval;
@@ -48,7 +48,7 @@ extern __inline__ int atomic_add_return(int i, volatile atomic_t *v)
 
 #define atomic_add_negative(a, v)      (atomic_add_return((a), (v)) < 0)
 
-extern __inline__ int atomic_sub_return(int i, volatile atomic_t *v)
+static inline int atomic_sub_return(int i, volatile atomic_t *v)
 {
        unsigned long flags;
        int retval;
@@ -58,7 +58,7 @@ extern __inline__ int atomic_sub_return(int i, volatile atomic_t *v)
        return retval;
 }
 
-extern __inline__ int atomic_sub_and_test(int i, volatile atomic_t *v)
+static inline int atomic_sub_and_test(int i, volatile atomic_t *v)
 {
        int retval;
        unsigned long flags;
@@ -68,7 +68,7 @@ extern __inline__ int atomic_sub_and_test(int i, volatile atomic_t *v)
        return retval;
 }
 
-extern __inline__ void atomic_inc(volatile atomic_t *v)
+static inline void atomic_inc(volatile atomic_t *v)
 {
        unsigned long flags;
        cris_atomic_save(v, flags);
@@ -76,7 +76,7 @@ extern __inline__ void atomic_inc(volatile atomic_t *v)
        cris_atomic_restore(v, flags);
 }
 
-extern __inline__ void atomic_dec(volatile atomic_t *v)
+static inline void atomic_dec(volatile atomic_t *v)
 {
        unsigned long flags;
        cris_atomic_save(v, flags);
@@ -84,7 +84,7 @@ extern __inline__ void atomic_dec(volatile atomic_t *v)
        cris_atomic_restore(v, flags);
 }
 
-extern __inline__ int atomic_inc_return(volatile atomic_t *v)
+static inline int atomic_inc_return(volatile atomic_t *v)
 {
        unsigned long flags;
        int retval;
@@ -94,7 +94,7 @@ extern __inline__ int atomic_inc_return(volatile atomic_t *v)
        return retval;
 }
 
-extern __inline__ int atomic_dec_return(volatile atomic_t *v)
+static inline int atomic_dec_return(volatile atomic_t *v)
 {
        unsigned long flags;
        int retval;
@@ -103,7 +103,7 @@ extern __inline__ int atomic_dec_return(volatile atomic_t *v)
        cris_atomic_restore(v, flags);
        return retval;
 }
-extern __inline__ int atomic_dec_and_test(volatile atomic_t *v)
+static inline int atomic_dec_and_test(volatile atomic_t *v)
 {
        int retval;
        unsigned long flags;
@@ -113,7 +113,7 @@ extern __inline__ int atomic_dec_and_test(volatile atomic_t *v)
        return retval;
 }
 
-extern __inline__ int atomic_inc_and_test(volatile atomic_t *v)
+static inline int atomic_inc_and_test(volatile atomic_t *v)
 {
        int retval;
        unsigned long flags;
index e3da57f97964fac5d2141ed8684c6cd9ed45a63f..1bddb3f3a289eddfa320a4519689c3081d9d1c0e 100644 (file)
@@ -89,7 +89,7 @@ struct __dummy { unsigned long a[100]; };
  * It also implies a memory barrier.
  */
 
-extern inline int test_and_set_bit(int nr, volatile unsigned long *addr)
+static inline int test_and_set_bit(int nr, volatile unsigned long *addr)
 {
        unsigned int mask, retval;
        unsigned long flags;
@@ -105,7 +105,7 @@ extern inline int test_and_set_bit(int nr, volatile unsigned long *addr)
        return retval;
 }
 
-extern inline int __test_and_set_bit(int nr, volatile unsigned long *addr)
+static inline int __test_and_set_bit(int nr, volatile unsigned long *addr)
 {
        unsigned int mask, retval;
        unsigned int *adr = (unsigned int *)addr;
@@ -132,7 +132,7 @@ extern inline int __test_and_set_bit(int nr, volatile unsigned long *addr)
  * It also implies a memory barrier.
  */
 
-extern inline int test_and_clear_bit(int nr, volatile unsigned long *addr)
+static inline int test_and_clear_bit(int nr, volatile unsigned long *addr)
 {
        unsigned int mask, retval;
        unsigned long flags;
@@ -157,7 +157,7 @@ extern inline int test_and_clear_bit(int nr, volatile unsigned long *addr)
  * but actually fail.  You must protect multiple accesses with a lock.
  */
 
-extern inline int __test_and_clear_bit(int nr, volatile unsigned long *addr)
+static inline int __test_and_clear_bit(int nr, volatile unsigned long *addr)
 {
        unsigned int mask, retval;
        unsigned int *adr = (unsigned int *)addr;
@@ -177,7 +177,7 @@ extern inline int __test_and_clear_bit(int nr, volatile unsigned long *addr)
  * It also implies a memory barrier.
  */
 
-extern inline int test_and_change_bit(int nr, volatile unsigned long *addr)
+static inline int test_and_change_bit(int nr, volatile unsigned long *addr)
 {
        unsigned int mask, retval;
        unsigned long flags;
@@ -193,7 +193,7 @@ extern inline int test_and_change_bit(int nr, volatile unsigned long *addr)
 
 /* WARNING: non atomic and it can be reordered! */
 
-extern inline int __test_and_change_bit(int nr, volatile unsigned long *addr)
+static inline int __test_and_change_bit(int nr, volatile unsigned long *addr)
 {
        unsigned int mask, retval;
        unsigned int *adr = (unsigned int *)addr;
@@ -214,7 +214,7 @@ extern inline int __test_and_change_bit(int nr, volatile unsigned long *addr)
  * This routine doesn't need to be atomic.
  */
 
-extern inline int test_bit(int nr, const volatile unsigned long *addr)
+static inline int test_bit(int nr, const volatile unsigned long *addr)
 {
        unsigned int mask;
        unsigned int *adr = (unsigned int *)addr;
@@ -258,7 +258,7 @@ extern inline int test_bit(int nr, const volatile unsigned long *addr)
  * @offset: The bitnumber to start searching at
  * @size: The maximum size to search
  */
-extern inline int find_next_zero_bit (const unsigned long * addr, int size, int offset)
+static inline int find_next_zero_bit (const unsigned long * addr, int size, int offset)
 {
        unsigned long *p = ((unsigned long *) addr) + (offset >> 5);
        unsigned long result = offset & ~31UL;
@@ -366,7 +366,7 @@ found_middle:
 #define minix_test_bit(nr,addr) test_bit(nr,addr)
 #define minix_find_first_zero_bit(addr,size) find_first_zero_bit(addr,size)
 
-extern inline int sched_find_first_bit(const unsigned long *b)
+static inline int sched_find_first_bit(const unsigned long *b)
 {
        if (unlikely(b[0]))
                return __ffs(b[0]);
index 15ca8aec5c633551af75701419917c8162006516..26a7719bbb840543250a2e4394375409c7a9b849 100644 (file)
@@ -34,7 +34,7 @@ unsigned int csum_partial_copy_nocheck(const char *src, char *dst,
  *     Fold a partial checksum into a word
  */
 
-extern inline unsigned int csum_fold(unsigned int sum)
+static inline unsigned int csum_fold(unsigned int sum)
 {
        /* the while loop is unnecessary really, it's always enough with two
           iterations */
@@ -55,7 +55,7 @@ extern unsigned int csum_partial_copy_from_user(const char *src, char *dst,
  *
  */
 
-extern inline unsigned short ip_fast_csum(unsigned char * iph,
+static inline unsigned short ip_fast_csum(unsigned char * iph,
                                          unsigned int ihl)
 {
        return csum_fold(csum_partial(iph, ihl * 4, 0));
@@ -66,7 +66,7 @@ extern inline unsigned short ip_fast_csum(unsigned char * iph,
  * returns a 16-bit checksum, already complemented
  */
 
-extern inline unsigned short int csum_tcpudp_magic(unsigned long saddr,
+static inline unsigned short int csum_tcpudp_magic(unsigned long saddr,
                                                   unsigned long daddr,
                                                   unsigned short len,
                                                   unsigned short proto,
@@ -80,7 +80,7 @@ extern inline unsigned short int csum_tcpudp_magic(unsigned long saddr,
  * in icmp.c
  */
 
-extern inline unsigned short ip_compute_csum(unsigned char * buff, int len) {
+static inline unsigned short ip_compute_csum(unsigned char * buff, int len) {
        return csum_fold (csum_partial(buff, len, 0));
 }
 
index dce69c99da39088de75bad41a8a8ca073a75bde1..5f5c0efd00be4a962b2381e02a89a264efd0e737 100644 (file)
@@ -5,7 +5,7 @@
 
 struct task_struct;
 
-extern inline struct task_struct * get_current(void)
+static inline struct task_struct * get_current(void)
 {
         return current_thread_info()->task;
 }
index efc41aad48459aedb07975fbcc623ce32f71909e..d3a39780371993eabf5503b63ffe4432256f35fb 100644 (file)
@@ -13,7 +13,7 @@
 
 extern unsigned long loops_per_usec; /* arch/cris/mm/init.c */
 
-extern __inline__ void udelay(unsigned long usecs)
+static inline void udelay(unsigned long usecs)
 {
        __delay(usecs * loops_per_usec);
 }
index 16e791b3c721978deb68c56e5ebb17d66b5dac7c..716c69bc58f89be19545b55d13a4d6d4cbe32614 100644 (file)
@@ -23,12 +23,12 @@ extern struct cris_io_operations *cris_iops;
  * Change virtual addresses to physical addresses and vv.
  */
 
-extern inline unsigned long virt_to_phys(volatile void * address)
+static inline unsigned long virt_to_phys(volatile void * address)
 {
        return __pa(address);
 }
 
-extern inline void * phys_to_virt(unsigned long address)
+static inline void * phys_to_virt(unsigned long address)
 {
        return __va(address);
 }
@@ -36,7 +36,7 @@ extern inline void * phys_to_virt(unsigned long address)
 extern void __iomem * __ioremap(unsigned long offset, unsigned long size, unsigned long flags);
 extern void __iomem * __ioremap_prot(unsigned long phys_addr, unsigned long size, pgprot_t prot);
 
-extern inline void __iomem * ioremap (unsigned long offset, unsigned long size)
+static inline void __iomem * ioremap (unsigned long offset, unsigned long size)
 {
        return __ioremap(offset, size, 0);
 }
index 4fab5c3b2e15ca4ee294346535d14456145c520e..4b338792218b045ce9593af9f5bac2329f686986 100644 (file)
@@ -8,7 +8,7 @@
 
 #include <asm/arch/irq.h>
 
-extern __inline__ int irq_canonicalize(int irq)
+static inline int irq_canonicalize(int irq)
 {  
   return irq; 
 }
index a131776edf416142874f5c2d5dcd8d6eb9b455cd..deaddfe79bbcd6527f968bc6bc3c4c1087e11440 100644 (file)
  * Allocate and free page tables.
  */
 
-extern inline pgd_t *pgd_alloc (struct mm_struct *mm)
+static inline pgd_t *pgd_alloc (struct mm_struct *mm)
 {
        return (pgd_t *)get_zeroed_page(GFP_KERNEL);
 }
 
-extern inline void pgd_free (pgd_t *pgd)
+static inline void pgd_free (pgd_t *pgd)
 {
        free_page((unsigned long)pgd);
 }
 
-extern inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address)
+static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address)
 {
        pte_t *pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO);
        return pte;
 }
 
-extern inline struct page *pte_alloc_one(struct mm_struct *mm, unsigned long address)
+static inline struct page *pte_alloc_one(struct mm_struct *mm, unsigned long address)
 {
        struct page *pte;
        pte = alloc_pages(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO, 0);
        return pte;
 }
 
-extern inline void pte_free_kernel(pte_t *pte)
+static inline void pte_free_kernel(pte_t *pte)
 {
        free_page((unsigned long)pte);
 }
 
-extern inline void pte_free(struct page *pte)
+static inline void pte_free(struct page *pte)
 {
        __free_page(pte);
 }
index a9143bed99db6908c6f63dfe32c8e00b97887058..70a832514f62ba7cda4097e5de7b49c1e73d3f0d 100644 (file)
@@ -112,44 +112,44 @@ extern unsigned long empty_zero_page;
  * Undefined behaviour if not..
  */
 
-extern inline int pte_read(pte_t pte)           { return pte_val(pte) & _PAGE_READ; }
-extern inline int pte_write(pte_t pte)          { return pte_val(pte) & _PAGE_WRITE; }
-extern inline int pte_exec(pte_t pte)           { return pte_val(pte) & _PAGE_READ; }
-extern inline int pte_dirty(pte_t pte)          { return pte_val(pte) & _PAGE_MODIFIED; }
-extern inline int pte_young(pte_t pte)          { return pte_val(pte) & _PAGE_ACCESSED; }
-extern inline int pte_file(pte_t pte)           { return pte_val(pte) & _PAGE_FILE; }
-
-extern inline pte_t pte_wrprotect(pte_t pte)
+static inline int pte_read(pte_t pte)           { return pte_val(pte) & _PAGE_READ; }
+static inline int pte_write(pte_t pte)          { return pte_val(pte) & _PAGE_WRITE; }
+static inline int pte_exec(pte_t pte)           { return pte_val(pte) & _PAGE_READ; }
+static inline int pte_dirty(pte_t pte)          { return pte_val(pte) & _PAGE_MODIFIED; }
+static inline int pte_young(pte_t pte)          { return pte_val(pte) & _PAGE_ACCESSED; }
+static inline int pte_file(pte_t pte)           { return pte_val(pte) & _PAGE_FILE; }
+
+static inline pte_t pte_wrprotect(pte_t pte)
 {
         pte_val(pte) &= ~(_PAGE_WRITE | _PAGE_SILENT_WRITE);
         return pte;
 }
 
-extern inline pte_t pte_rdprotect(pte_t pte)
+static inline pte_t pte_rdprotect(pte_t pte)
 {
         pte_val(pte) &= ~(_PAGE_READ | _PAGE_SILENT_READ);
        return pte;
 }
 
-extern inline pte_t pte_exprotect(pte_t pte)
+static inline pte_t pte_exprotect(pte_t pte)
 {
         pte_val(pte) &= ~(_PAGE_READ | _PAGE_SILENT_READ);
        return pte;
 }
 
-extern inline pte_t pte_mkclean(pte_t pte)
+static inline pte_t pte_mkclean(pte_t pte)
 {
        pte_val(pte) &= ~(_PAGE_MODIFIED | _PAGE_SILENT_WRITE); 
        return pte; 
 }
 
-extern inline pte_t pte_mkold(pte_t pte)
+static inline pte_t pte_mkold(pte_t pte)
 {
        pte_val(pte) &= ~(_PAGE_ACCESSED | _PAGE_SILENT_READ);
        return pte;
 }
 
-extern inline pte_t pte_mkwrite(pte_t pte)
+static inline pte_t pte_mkwrite(pte_t pte)
 {
         pte_val(pte) |= _PAGE_WRITE;
         if (pte_val(pte) & _PAGE_MODIFIED)
@@ -157,7 +157,7 @@ extern inline pte_t pte_mkwrite(pte_t pte)
         return pte;
 }
 
-extern inline pte_t pte_mkread(pte_t pte)
+static inline pte_t pte_mkread(pte_t pte)
 {
         pte_val(pte) |= _PAGE_READ;
         if (pte_val(pte) & _PAGE_ACCESSED)
@@ -165,7 +165,7 @@ extern inline pte_t pte_mkread(pte_t pte)
         return pte;
 }
 
-extern inline pte_t pte_mkexec(pte_t pte)
+static inline pte_t pte_mkexec(pte_t pte)
 {
         pte_val(pte) |= _PAGE_READ;
         if (pte_val(pte) & _PAGE_ACCESSED)
@@ -173,7 +173,7 @@ extern inline pte_t pte_mkexec(pte_t pte)
         return pte;
 }
 
-extern inline pte_t pte_mkdirty(pte_t pte)
+static inline pte_t pte_mkdirty(pte_t pte)
 {
         pte_val(pte) |= _PAGE_MODIFIED;
         if (pte_val(pte) & _PAGE_WRITE)
@@ -181,7 +181,7 @@ extern inline pte_t pte_mkdirty(pte_t pte)
         return pte;
 }
 
-extern inline pte_t pte_mkyoung(pte_t pte)
+static inline pte_t pte_mkyoung(pte_t pte)
 {
         pte_val(pte) |= _PAGE_ACCESSED;
         if (pte_val(pte) & _PAGE_READ)
@@ -205,7 +205,7 @@ extern inline pte_t pte_mkyoung(pte_t pte)
  * addresses (the 0xc0xxxxxx's) goes as void *'s.
  */
 
-extern inline pte_t __mk_pte(void * page, pgprot_t pgprot)
+static inline pte_t __mk_pte(void * page, pgprot_t pgprot)
 {
        pte_t pte;
        /* the PTE needs a physical address */
@@ -223,7 +223,7 @@ extern inline pte_t __mk_pte(void * page, pgprot_t pgprot)
         __pte;                                                          \
 })
 
-extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
+static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
 { pte_val(pte) = (pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot); return pte; }
 
 
@@ -232,7 +232,7 @@ extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
  * pte_pagenr refers to the page-number counted starting from the virtual DRAM start
  */
 
-extern inline unsigned long __pte_page(pte_t pte)
+static inline unsigned long __pte_page(pte_t pte)
 {
        /* the PTE contains a physical address */
        return (unsigned long)__va(pte_val(pte) & PAGE_MASK);
@@ -250,7 +250,7 @@ extern inline unsigned long __pte_page(pte_t pte)
  * don't need the __pa and __va transformations.
  */
 
-extern inline void pmd_set(pmd_t * pmdp, pte_t * ptep)
+static inline void pmd_set(pmd_t * pmdp, pte_t * ptep)
 { pmd_val(*pmdp) = _PAGE_TABLE | (unsigned long) ptep; }
 
 #define pmd_page(pmd)          (pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT))
@@ -260,7 +260,7 @@ extern inline void pmd_set(pmd_t * pmdp, pte_t * ptep)
 #define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
 
 /* to find an entry in a page-table-directory */
-extern inline pgd_t * pgd_offset(struct mm_struct * mm, unsigned long address)
+static inline pgd_t * pgd_offset(struct mm_struct * mm, unsigned long address)
 {
        return mm->pgd + pgd_index(address);
 }
@@ -296,7 +296,7 @@ extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; /* defined in head.S */
  * 
  * Actually I am not sure on what this could be used for.
  */
-extern inline void update_mmu_cache(struct vm_area_struct * vma,
+static inline void update_mmu_cache(struct vm_area_struct * vma,
        unsigned long address, pte_t pte)
 {
 }
index 0dc218117bd83df881c93c51942e75d8a49e11a3..dce41009eeb086a17811c7e1095709672ddedac4 100644 (file)
@@ -16,6 +16,8 @@
 #include <asm/ptrace.h>
 #include <asm/arch/processor.h>
 
+struct task_struct;
+
 /* This decides where the kernel will search for a free chunk of vm
  * space during mmap's.
  */
@@ -45,7 +47,7 @@
 
 #define current_regs() user_regs(current->thread_info)
 
-extern inline void prepare_to_copy(struct task_struct *tsk)
+static inline void prepare_to_copy(struct task_struct *tsk)
 {
 }
 
@@ -58,7 +60,7 @@ unsigned long get_wchan(struct task_struct *p);
 extern unsigned long thread_saved_pc(struct task_struct *tsk);
 
 /* Free all resources held by a thread. */
-extern inline void release_thread(struct task_struct *dead_task)
+static inline void release_thread(struct task_struct *dead_task)
 {
         /* Nothing needs to be done.  */
 }
index 39faf69bcf766523a7ad34e019b9ce63e40de2c5..53f548b791c18ebb8456c1b593a0f38b95e557cb 100644 (file)
@@ -18,8 +18,6 @@
  * CRIS semaphores, implemented in C-only so far. 
  */
 
-int printk(const char *fmt, ...);
-
 struct semaphore {
        atomic_t count;
        atomic_t waking;
@@ -39,17 +37,17 @@ struct semaphore {
 #define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1)
 #define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name,0)
 
-extern inline void sema_init(struct semaphore *sem, int val)
+static inline void sema_init(struct semaphore *sem, int val)
 {
        *sem = (struct semaphore)__SEMAPHORE_INITIALIZER((*sem),val);
 }
 
-extern inline void init_MUTEX (struct semaphore *sem)
+static inline void init_MUTEX (struct semaphore *sem)
 {
         sema_init(sem, 1);
 }
 
-extern inline void init_MUTEX_LOCKED (struct semaphore *sem)
+static inline void init_MUTEX_LOCKED (struct semaphore *sem)
 {
         sema_init(sem, 0);
 }
@@ -61,7 +59,7 @@ extern void __up(struct semaphore * sem);
 
 /* notice - we probably can do cli/sti here instead of saving */
 
-extern inline void down(struct semaphore * sem)
+static inline void down(struct semaphore * sem)
 {
        unsigned long flags;
        int failed;
@@ -83,7 +81,7 @@ extern inline void down(struct semaphore * sem)
  * returns negative for signalled and zero for semaphore acquired.
  */
 
-extern inline int down_interruptible(struct semaphore * sem)
+static inline int down_interruptible(struct semaphore * sem)
 {
        unsigned long flags;
        int failed;
@@ -99,7 +97,7 @@ extern inline int down_interruptible(struct semaphore * sem)
        return(failed);
 }
 
-extern inline int down_trylock(struct semaphore * sem)
+static inline int down_trylock(struct semaphore * sem)
 {
        unsigned long flags;
        int failed;
@@ -119,7 +117,7 @@ extern inline int down_trylock(struct semaphore * sem)
  * The default case (no contention) will result in NO
  * jumps for both down() and up().
  */
-extern inline void up(struct semaphore * sem)
+static inline void up(struct semaphore * sem)
 {  
        unsigned long flags;
        int wakeup;
index e06739806d4e4928e1c55094196899e7cacfe158..d48670107a85ffe05c0e1257a94678f6f3389e6f 100644 (file)
@@ -41,7 +41,7 @@ extern struct task_struct *resume(struct task_struct *prev, struct task_struct *
 void disable_hlt(void);
 void enable_hlt(void);
 
-extern inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size)
+static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size)
 {
   /* since Etrax doesn't have any atomic xchg instructions, we need to disable
      irq's (if enabled) and do it with move.d's */
index 3fb069a3771761314edc9de8d1a08ffe9f55d367..b92e0e80fe86fdfcd2cbe2f42b8036d9492e63c2 100644 (file)
@@ -16,7 +16,7 @@
 
 typedef unsigned long long cycles_t;
 
-extern inline cycles_t get_cycles(void)
+static inline cycles_t get_cycles(void)
 {
         return 0;
 }
index 6ed7d9ae90db5497d03cb2e31e17e3e2dc38c7e7..c52238005b5592539be59892b8ef61a4bf1a3380 100644 (file)
@@ -39,14 +39,14 @@ static inline void flush_tlb_range(struct vm_area_struct * vma, unsigned long st
        flush_tlb_mm(vma->vm_mm);
 }
 
-extern inline void flush_tlb_pgtables(struct mm_struct *mm,
+static inline void flush_tlb_pgtables(struct mm_struct *mm,
                                       unsigned long start, unsigned long end)
 {
         /* CRIS does not keep any page table caches in TLB */
 }
 
 
-extern inline void flush_tlb(void) 
+static inline void flush_tlb(void)
 {
        flush_tlb_mm(current->mm);
 }
index 7d50086eb5ea08a6de01e4f4f4f7735a2ec4eee0..69d48a2dc8e13ee15fa7c493fbe89eadc9bbaac9 100644 (file)
@@ -213,7 +213,7 @@ extern unsigned long __copy_user(void *to, const void *from, unsigned long n);
 extern unsigned long __copy_user_zeroing(void *to, const void *from, unsigned long n);
 extern unsigned long __do_clear_user(void *to, unsigned long n);
 
-extern inline unsigned long
+static inline unsigned long
 __generic_copy_to_user(void __user *to, const void *from, unsigned long n)
 {
        if (access_ok(VERIFY_WRITE, to, n))
@@ -221,7 +221,7 @@ __generic_copy_to_user(void __user *to, const void *from, unsigned long n)
        return n;
 }
 
-extern inline unsigned long
+static inline unsigned long
 __generic_copy_from_user(void *to, const void __user *from, unsigned long n)
 {
        if (access_ok(VERIFY_READ, from, n))
@@ -229,7 +229,7 @@ __generic_copy_from_user(void *to, const void __user *from, unsigned long n)
        return n;
 }
 
-extern inline unsigned long
+static inline unsigned long
 __generic_clear_user(void __user *to, unsigned long n)
 {
        if (access_ok(VERIFY_WRITE, to, n))
@@ -237,13 +237,13 @@ __generic_clear_user(void __user *to, unsigned long n)
        return n;
 }
 
-extern inline long
+static inline long
 __strncpy_from_user(char *dst, const char __user *src, long count)
 {
        return __do_strncpy_from_user(dst, src, count);
 }
 
-extern inline long
+static inline long
 strncpy_from_user(char *dst, const char __user *src, long count)
 {
        long res = -EFAULT;
@@ -256,7 +256,7 @@ strncpy_from_user(char *dst, const char __user *src, long count)
 /* Note that if these expand awfully if made into switch constructs, so
    don't do that.  */
 
-extern inline unsigned long
+static inline unsigned long
 __constant_copy_from_user(void *to, const void __user *from, unsigned long n)
 {
        unsigned long ret = 0;
@@ -306,7 +306,7 @@ __constant_copy_from_user(void *to, const void __user *from, unsigned long n)
 
 /* Ditto, don't make a switch out of this.  */
 
-extern inline unsigned long
+static inline unsigned long
 __constant_copy_to_user(void __user *to, const void *from, unsigned long n)
 {
        unsigned long ret = 0;
@@ -356,7 +356,7 @@ __constant_copy_to_user(void __user *to, const void *from, unsigned long n)
 
 /* No switch, please.  */
 
-extern inline unsigned long
+static inline unsigned long
 __constant_clear_user(void __user *to, unsigned long n)
 {
        unsigned long ret = 0;
@@ -406,19 +406,19 @@ __constant_clear_user(void __user *to, unsigned long n)
  * used in fast paths and have only a small space overhead.
  */
 
-extern inline unsigned long
+static inline unsigned long
 __generic_copy_from_user_nocheck(void *to, const void *from, unsigned long n)
 {
        return __copy_user_zeroing(to,from,n);
 }
 
-extern inline unsigned long
+static inline unsigned long
 __generic_copy_to_user_nocheck(void *to, const void *from, unsigned long n)
 {
        return __copy_user(to,from,n);
 }
 
-extern inline unsigned long
+static inline unsigned long
 __generic_clear_user_nocheck(void *to, unsigned long n)
 {
        return __do_clear_user(to,n);
index 156a34bfc583b853b1d2970171602e592665c972..2627bbdf8a1144e78c5a85584f86a152640ddb43 100644 (file)
  * some others too.
  */
 #define __NR__exit __NR_exit
-extern inline _syscall0(pid_t,setsid)
-extern inline _syscall3(int,write,int,fd,const char *,buf,off_t,count)
-extern inline _syscall3(int,read,int,fd,char *,buf,off_t,count)
-extern inline _syscall3(off_t,lseek,int,fd,off_t,offset,int,count)
-extern inline _syscall1(int,dup,int,fd)
-extern inline _syscall3(int,execve,const char *,file,char **,argv,char **,envp)
-extern inline _syscall3(int,open,const char *,file,int,flag,int,mode)
-extern inline _syscall1(int,close,int,fd)
+static inline _syscall0(pid_t,setsid)
+static inline _syscall3(int,write,int,fd,const char *,buf,off_t,count)
+static inline _syscall3(int,read,int,fd,char *,buf,off_t,count)
+static inline _syscall3(off_t,lseek,int,fd,off_t,offset,int,count)
+static inline _syscall1(int,dup,int,fd)
+static inline _syscall3(int,execve,const char *,file,char **,argv,char **,envp)
+static inline _syscall3(int,open,const char *,file,int,flag,int,mode)
+static inline _syscall1(int,close,int,fd)
 
 struct pt_regs;
 asmlinkage long sys_mmap2(
@@ -382,8 +382,8 @@ asmlinkage long sys_rt_sigaction(int sig,
 #ifdef __KERNEL__
 #define _exit kernel_syscall_exit
 #endif
-extern inline _syscall1(int,_exit,int,exitcode)
-extern inline _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options)
+static inline _syscall1(int,_exit,int,exitcode)
+static inline _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options)
 #endif
 
 
index b247e99dff49a830ee3af8d3e833d80e6087acde..844666377dcbfc45db86c4b33d5c9ec431fb4907 100644 (file)
@@ -26,6 +26,8 @@
 #include <linux/slab.h>
 #include <linux/list.h>
 #include <linux/spinlock.h>
+struct mm_struct;
+struct vm_area_struct;
 #endif
 
 #ifndef __ASSEMBLY__
index 7dca30a26c536305e6ad75dde33c9a9d35801b68..358e4d309ceb179776f2a7036dabce02cdfad1d2 100644 (file)
@@ -128,6 +128,7 @@ do {                                                                        \
 #endif
 
 #ifndef __HAVE_ARCH_PTEP_SET_WRPROTECT
+struct mm_struct;
 static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long address, pte_t *ptep)
 {
        pte_t old_pte = *ptep;
index a9c55490fb8238e78584176bdb6002a6bd38432e..094d4917c1a9a908b9416eba618aa24217112e7a 100644 (file)
                VMLINUX_SYMBOL(__end_pci_fixups_enable) = .;            \
        }                                                               \
                                                                        \
+       /* RapidIO route ops */                                         \
+       .rio_route        : AT(ADDR(.rio_route) - LOAD_OFFSET) {        \
+               VMLINUX_SYMBOL(__start_rio_route_ops) = .;              \
+               *(.rio_route_ops)                                       \
+               VMLINUX_SYMBOL(__end_rio_route_ops) = .;                \
+       }                                                               \
+                                                                       \
        /* Kernel symbol table: Normal symbols */                       \
        __ksymtab         : AT(ADDR(__ksymtab) - LOAD_OFFSET) {         \
                VMLINUX_SYMBOL(__start___ksymtab) = .;                  \
index fa11117d3cfac32de2b2e6b3694c8d65f56b5ac5..4153d80e4d2b86535a6e55a6e72a30ba7b5b5699 100644 (file)
@@ -119,6 +119,8 @@ typedef struct user_fxsr_struct elf_fpxregset_t;
  */
 #define elf_read_implies_exec(ex, executable_stack)    (executable_stack != EXSTACK_DISABLE_X)
 
+struct task_struct;
+
 extern int dump_task_regs (struct task_struct *, elf_gregset_t *);
 extern int dump_task_fpu (struct task_struct *, elf_fpregset_t *);
 extern int dump_task_extended_fpu (struct task_struct *, struct user_fxsr_struct *);
index 8b6d3a90cd78942f1a48bf1e0625f6df22e77e53..ca916a892877edaddd26d048f74a33352dc6cd8f 100644 (file)
@@ -49,6 +49,23 @@ struct arch_specific_insn {
        kprobe_opcode_t insn[MAX_INSN_SIZE];
 };
 
+struct prev_kprobe {
+       struct kprobe *kp;
+       unsigned long status;
+       unsigned long old_eflags;
+       unsigned long saved_eflags;
+};
+
+/* per-cpu kprobe control block */
+struct kprobe_ctlblk {
+       unsigned long kprobe_status;
+       unsigned long kprobe_old_eflags;
+       unsigned long kprobe_saved_eflags;
+       long *jprobe_saved_esp;
+       struct pt_regs jprobe_saved_regs;
+       kprobe_opcode_t jprobes_stack[MAX_STACK_SIZE];
+       struct prev_kprobe prev_kprobe;
+};
 
 /* trap3/1 are intr gates for kprobes.  So, restore the status of IF,
  * if necessary, before executing the original int3/1 (trap) handler.
index 03f3c8ac6383a4d7f874e12869b56f7ba45f1414..088a945bf26bdb5ef02f8b5a0397e32ee3955214 100644 (file)
@@ -25,6 +25,9 @@
 #include <linux/list.h>
 #include <linux/spinlock.h>
 
+struct mm_struct;
+struct vm_area_struct;
+
 /*
  * ZERO_PAGE is a global shared page that is always zero: used
  * for zero-mapped memory areas etc..
index 0a4ec764377ca1aa0db8c607a35e9ddfd586d297..8c02b0318703b4c9cf8d68e665949215f97455d6 100644 (file)
@@ -718,4 +718,10 @@ extern void mtrr_bp_init(void);
 #define mtrr_bp_init() do {} while (0)
 #endif
 
+#ifdef CONFIG_X86_MCE
+extern void mcheck_init(struct cpuinfo_x86 *c);
+#else
+#define mcheck_init(c) do {} while(0)
+#endif
+
 #endif /* __ASM_I386_PROCESSOR_H */
index 6347c9845642658031649d9eada3de509c888455..df67d40801de9ac9dc2041145927c251e7e5c7c5 100644 (file)
@@ -48,12 +48,7 @@ dma_set_mask (struct device *dev, u64 mask)
        return 0;
 }
 
-static inline int
-dma_get_cache_alignment (void)
-{
-       extern int ia64_max_cacheline_size;
-       return ia64_max_cacheline_size;
-}
+extern int dma_get_cache_alignment(void);
 
 static inline void
 dma_cache_sync (void *vaddr, size_t size, enum dma_data_direction dir)
index 573a3574a24fe86ebcd4ecb5be7800c3057b4df5..592abb000e29bc9260257a5f9fb806eae367a21d 100644 (file)
@@ -26,6 +26,7 @@
  */
 #include <linux/types.h>
 #include <linux/ptrace.h>
+#include <linux/percpu.h>
 #include <asm/break.h>
 
 #define MAX_INSN_SIZE   16
@@ -62,6 +63,18 @@ typedef struct _bundle {
        } quad1;
 } __attribute__((__aligned__(16)))  bundle_t;
 
+struct prev_kprobe {
+       struct kprobe *kp;
+       unsigned long status;
+};
+
+/* per-cpu kprobe control block */
+struct kprobe_ctlblk {
+       unsigned long kprobe_status;
+       struct pt_regs jprobe_saved_regs;
+       struct prev_kprobe prev_kprobe;
+};
+
 #define JPROBE_ENTRY(pentry)   (kprobe_opcode_t *)pentry
 
 #define ARCH_SUPPORTS_KRETPROBES
index 21e32a06bc82c110e4870358b0d5e913a588ae1a..c34ba80c1c31fcdd80c94cf7ec32981348f3c609 100644 (file)
 
 # ifndef __ASSEMBLY__
 
+#include <linux/sched.h>       /* for mm_struct */
 #include <asm/bitops.h>
 #include <asm/cacheflush.h>
 #include <asm/mmu_context.h>
index a79d1a7ecc77e758c1e187facf736b1e39441fbb..2c703d6e0c8630aa234039d0ebdca4d9ce04dc09 100644 (file)
@@ -229,6 +229,9 @@ struct switch_stack {
 };
 
 #ifdef __KERNEL__
+
+#define __ARCH_SYS_PTRACE      1
+
 /*
  * We use the ia64_psr(regs)->ri to determine which of the three
  * instructions in bundle (16 bytes) took the sample. Generate
index 1cd5fd4a5b2cea4813f9e58e13db466b114baa4d..75740debcd01e0c46842c6aee002e0d28fb216b7 100644 (file)
@@ -27,6 +27,9 @@
 #include <asm/bitops.h>
 #include <asm/page.h>
 
+struct mm_struct;
+struct vm_area_struct;
+
 extern pgd_t swapper_pg_dir[1024];
 extern void paging_init(void);
 
index 976417126b2d96812c2824a431bc9e256f702b30..55cd7ecfde4370c6f34c1e88bef4df48e18b6643 100644 (file)
@@ -145,6 +145,9 @@ struct pt_regs {
 #define PTRACE_O_TRACESYSGOOD  0x00000001
 
 #ifdef __KERNEL__
+
+#define __ARCH_SYS_PTRACE      1
+
 #if defined(CONFIG_ISA_M32R2) || defined(CONFIG_CHIP_VDEC2)
 #define user_mode(regs) ((M32R_PSW_BPM & (regs)->psw) != 0)
 #elif defined(CONFIG_ISA_M32R)
index 026bbc9565b428b4270ae0d759268ab0a4f36fd0..49925e91e89ce341b40a0f98eb863e6a767949e4 100644 (file)
@@ -25,7 +25,7 @@
 #define copy_from_user_page(vma, page, vaddr, dst, src, len) \
        memcpy(dst, src, len)
 
-extern inline void __flush_cache_all(void)
+static inline void __flush_cache_all(void)
 {
 #ifdef CONFIG_M5407
        /*
@@ -64,7 +64,7 @@ extern inline void __flush_cache_all(void)
                "nop\n\t"
                : : : "d0" );
 #endif /* CONFIG_M5272 */
-#if CONFIG_M5249
+#ifdef CONFIG_M5249
        __asm__ __volatile__ (
                "movel  #0xa1000200, %%d0\n\t"
                "movec  %%d0, %%CACR\n\t"
index 208ccd969e4bd39ce9af1d39efc464a9c20dcab3..a08fa9b958dab2cc122a5ca5e755454c5bd34495 100644 (file)
@@ -2,7 +2,6 @@
 #define _M68K_IRQ_H_
 
 #include <linux/config.h>
-#include <linux/interrupt.h>
 #include <asm/ptrace.h>
 
 #ifdef CONFIG_COLDFIRE
@@ -82,36 +81,6 @@ extern void (*mach_disable_irq)(unsigned int);
 
 #endif /* CONFIG_M68360 */
 
-/*
- * This structure is used to chain together the ISRs for a particular
- * interrupt source (if it supports chaining).
- */
-typedef struct irq_node {
-       irqreturn_t     (*handler)(int, void *, struct pt_regs *);
-       unsigned long   flags;
-       void            *dev_id;
-       const char      *devname;
-       struct irq_node *next;
-} irq_node_t;
-
-/*
- * This structure has only 4 elements for speed reasons
- */
-typedef struct irq_handler {
-       irqreturn_t     (*handler)(int, void *, struct pt_regs *);
-       unsigned long   flags;
-       void            *dev_id;
-       const char      *devname;
-} irq_handler_t;
-
-/* count of spurious interrupts */
-extern volatile unsigned int num_spurious;
-
-/*
- * This function returns a new irq_node_t
- */
-extern irq_node_t *new_irq_node(void);
-
 /*
  * Some drivers want these entry points
  */
diff --git a/include/asm-m68knommu/irqnode.h b/include/asm-m68knommu/irqnode.h
new file mode 100644 (file)
index 0000000..a2503df
--- /dev/null
@@ -0,0 +1,36 @@
+#ifndef _M68K_IRQNODE_H_
+#define _M68K_IRQNODE_H_
+
+#include <linux/interrupt.h>
+
+/*
+ * This structure is used to chain together the ISRs for a particular
+ * interrupt source (if it supports chaining).
+ */
+typedef struct irq_node {
+       irqreturn_t     (*handler)(int, void *, struct pt_regs *);
+       unsigned long   flags;
+       void            *dev_id;
+       const char      *devname;
+       struct irq_node *next;
+} irq_node_t;
+
+/*
+ * This structure has only 4 elements for speed reasons
+ */
+typedef struct irq_handler {
+       irqreturn_t     (*handler)(int, void *, struct pt_regs *);
+       unsigned long   flags;
+       void            *dev_id;
+       const char      *devname;
+} irq_handler_t;
+
+/* count of spurious interrupts */
+extern volatile unsigned int num_spurious;
+
+/*
+ * This function returns a new irq_node_t
+ */
+extern irq_node_t *new_irq_node(void);
+
+#endif /* _M68K_IRQNODE_H_ */
index 7420f12742bb92c5d6d41068d8b2f1e8f772e51b..d2c9a25f8459cab60a6a3e86438ab7c5ad43f2fc 100644 (file)
@@ -275,6 +275,8 @@ do {                                                                        \
 
 #endif /* CONFIG_64BIT */
 
+struct task_struct;
+
 extern void dump_regs(elf_greg_t *, struct pt_regs *regs);
 extern int dump_task_regs (struct task_struct *, elf_gregset_t *);
 extern int dump_task_fpu(struct task_struct *, elf_fpregset_t *);
index 34facd9965034d354eb72ea91bc71586759083f6..702a28fa7a3489d01c2ff986c7dfd0adefebe0bc 100644 (file)
@@ -19,6 +19,9 @@
 #include <asm/io.h>
 #include <asm/pgtable-bits.h>
 
+struct mm_struct;
+struct vm_area_struct;
+
 #define PAGE_NONE      __pgprot(_PAGE_PRESENT | _CACHE_CACHABLE_NONCOHERENT)
 #define PAGE_SHARED    __pgprot(_PAGE_PRESENT | _PAGE_READ | _PAGE_WRITE | \
                        PAGE_CACHABLE_DEFAULT)
index c28fb6f48c6c482471cc9e7df01a8a12e56fb1b5..b4554711c3e739d126be89721006cf6f3375540a 100644 (file)
@@ -12,6 +12,7 @@
  */
 
 #include <linux/spinlock.h>
+#include <linux/mm.h>          /* for vm_area_struct */
 #include <asm/processor.h>
 #include <asm/cache.h>
 #include <asm/bitops.h>
@@ -418,7 +419,6 @@ extern void paging_init (void);
 
 #define PG_dcache_dirty         PG_arch_1
 
-struct vm_area_struct; /* forward declaration (include/linux/mm.h) */
 extern void update_mmu_cache(struct vm_area_struct *, unsigned long, pte_t);
 
 /* Encode and de-code a swap entry */
@@ -464,6 +464,7 @@ static inline int ptep_test_and_clear_dirty(struct vm_area_struct *vma, unsigned
 
 extern spinlock_t pa_dbit_lock;
 
+struct mm_struct;
 static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
 {
        pte_t old_pte;
index d140577d0a05b4cd4ff62becef0de5677b810876..feac3458d71f693a9a31b31f263f5b0106978fc8 100644 (file)
@@ -1,11 +1,13 @@
 #ifndef _ASM_POWERPC_ELF_H
 #define _ASM_POWERPC_ELF_H
 
+#include <linux/sched.h>       /* for task_struct */
 #include <asm/types.h>
 #include <asm/ptrace.h>
 #include <asm/cputable.h>
 #include <asm/auxvec.h>
 #include <asm/page.h>
+#include <asm/string.h>
 
 /* PowerPC relocations defined by the ABIs */
 #define R_PPC_NONE             0
index b2f09f17fbe03fbdea816ccd0aec77ce3e7651cf..6cd0a3bfa28033a67dd6da3997aff32c6e46127a 100644 (file)
@@ -27,6 +27,7 @@
  */
 #include <linux/types.h>
 #include <linux/ptrace.h>
+#include <linux/percpu.h>
 
 struct pt_regs;
 
@@ -53,6 +54,20 @@ struct arch_specific_insn {
        kprobe_opcode_t *insn;
 };
 
+struct prev_kprobe {
+       struct kprobe *kp;
+       unsigned long status;
+       unsigned long saved_msr;
+};
+
+/* per-cpu kprobe control block */
+struct kprobe_ctlblk {
+       unsigned long kprobe_status;
+       unsigned long kprobe_saved_msr;
+       struct pt_regs jprobe_saved_regs;
+       struct prev_kprobe prev_kprobe;
+};
+
 #ifdef CONFIG_KPROBES
 extern int kprobe_exceptions_notify(struct notifier_block *self,
                                    unsigned long val, void *data);
index e5374be86aefb90a39e608ef09ed002eab7decfe..f835066fb3cad431ff7a259df2b0f4a25c2b5e6e 100644 (file)
 /* Lowest TLB slot consumed by the default pinned TLBs */
 #define PPC44x_LOW_SLOT                63
 
-/* LS 32-bits of UART0 physical address location for early serial text debug */
+/*
+ * Least significant 32-bits and extended real page number (ERPN) of
+ * UART0 physical address location for early serial text debug
+ */
 #if defined(CONFIG_440SP)
+#define UART0_PHYS_ERPN                1
+#define UART0_PHYS_IO_BASE     0xf0000200
+#elif defined(CONFIG_440SPE)
+#define UART0_PHYS_ERPN                4
 #define UART0_PHYS_IO_BASE     0xf0000200
 #elif defined(CONFIG_440EP)
 #define UART0_PHYS_IO_BASE     0xe0000000
 #else
+#define UART0_PHYS_ERPN                1
 #define UART0_PHYS_IO_BASE     0x40000200
 #endif
 
 #define        PPC44x_PCICFG_PAGE      0x0000000900000000ULL
 #define        PPC44x_PCIIO_PAGE       PPC44x_PCICFG_PAGE
 #define        PPC44x_PCIMEM_PAGE      0x0000000a00000000ULL
+#elif defined(CONFIG_440SPE)
+#define        PPC44x_IO_PAGE          0x0000000400000000ULL
+#define        PPC44x_PCICFG_PAGE      0x0000000c00000000ULL
+#define        PPC44x_PCIIO_PAGE       PPC44x_PCICFG_PAGE
+#define        PPC44x_PCIMEM_PAGE      0x0000000d00000000ULL
 #elif defined(CONFIG_440EP)
 #define PPC44x_IO_PAGE         0x0000000000000000ULL
 #define PPC44x_PCICFG_PAGE     0x0000000000000000ULL
@@ -71,7 +84,7 @@
 /*
  * 36-bit trap ranges
  */
-#if defined(CONFIG_440SP)
+#if defined(CONFIG_440SP) || defined(CONFIG_440SPE)
 #define PPC44x_IO_LO           0xf0000000UL
 #define PPC44x_IO_HI           0xf0000fffUL
 #define PPC44x_PCI0CFG_LO      0x0ec00000UL
  */
 
 
-/* CPRs (440GX and 440SP) */
+/* CPRs (440GX and 440SP/440SPe) */
 #define DCRN_CPR_CONFIG_ADDR   0xc
 #define DCRN_CPR_CONFIG_DATA   0xd
 
        mtdcr(DCRN_CPR_CONFIG_ADDR, offset); \
        mtdcr(DCRN_CPR_CONFIG_DATA, data);})
 
-/* SDRs (440GX and 440SP) */
+/* SDRs (440GX and 440SP/440SPe) */
 #define DCRN_SDR_CONFIG_ADDR   0xe
 #define DCRN_SDR_CONFIG_DATA   0xf
 #define DCRN_SDR_PFC0          0x4100
        mtdcr(DCRN_SDR_CONFIG_ADDR, offset); \
        mtdcr(DCRN_SDR_CONFIG_DATA,data);})
 
-/* DMA (excluding 440SP) */
+/* DMA (excluding 440SP/440SPe) */
 #define DCRN_DMA0_BASE         0x100
 #define DCRN_DMA1_BASE         0x108
 #define DCRN_DMA2_BASE         0x110
 /* UIC */
 #define DCRN_UIC0_BASE 0xc0
 #define DCRN_UIC1_BASE 0xd0
-#define DCRN_UIC2_BASE 0x210
-#define DCRN_UICB_BASE 0x200
 #define UIC0           DCRN_UIC0_BASE
 #define UIC1           DCRN_UIC1_BASE
+
+#ifdef CONFIG_440SPE
+#define DCRN_UIC2_BASE 0xe0
+#define DCRN_UIC3_BASE 0xf0
+#define UIC2           DCRN_UIC2_BASE
+#define UIC3           DCRN_UIC3_BASE
+#else
+#define DCRN_UIC2_BASE 0x210
+#define DCRN_UICB_BASE 0x200
 #define UIC2           DCRN_UIC2_BASE
 #define UICB           DCRN_UICB_BASE
+#endif
 
 #define DCRN_UIC_SR(base)       (base + 0x0)
 #define DCRN_UIC_ER(base)       (base + 0x2)
 
 #define UIC0_UIC1NC            0x00000002
 
+#ifdef CONFIG_440SPE
+#define UIC0_UIC1NC      0x00000002
+#define UIC0_UIC2NC      0x00200000
+#define UIC0_UIC3NC      0x00008000
+#endif
+
 #define UICB_UIC0NC            0x40000000
 #define UICB_UIC1NC            0x10000000
 #define UICB_UIC2NC            0x04000000
 #define MALOBISR_CH0           0x80000000      /* EOB channel 1 bit */
 #define MALOBISR_CH2           0x40000000      /* EOB channel 2 bit */
 
+#if defined(CONFIG_440SP) || defined(CONFIG_440SPE)
+/* 440SP/440SPe PLB Arbiter DCRs */
+#define DCRN_PLB_REVID        0x080            /* PLB Revision ID */
+#define DCRN_PLB_CCR          0x088            /* PLB Crossbar Control */
+
+#define DCRN_PLB0_ACR         0x081            /* PLB Arbiter Control */
+#define DCRN_PLB0_BESRL               0x082            /* PLB Error Status */
+#define DCRN_PLB0_BESRH               0x083            /* PLB Error Status */
+#define DCRN_PLB0_BEARL               0x084            /* PLB Error Address Low */
+#define DCRN_PLB0_BEARH               0x085            /* PLB Error Address High */
+
+#define DCRN_PLB1_ACR          0x089           /* PLB Arbiter Control */
+#define DCRN_PLB1_BESRL                0x08a           /* PLB Error Status */
+#define DCRN_PLB1_BESRH                0x08b           /* PLB Error Status */
+#define DCRN_PLB1_BEARL                0x08c           /* PLB Error Address Low */
+#define DCRN_PLB1_BEARH                0x08d           /* PLB Error Address High */
+#else
 /* 440GP/GX PLB Arbiter DCRs */
 #define DCRN_PLB0_REVID                0x082           /* PLB Arbiter Revision ID */
 #define DCRN_PLB0_ACR          0x083           /* PLB Arbiter Control */
 #define DCRN_PLB0_BEARL                0x086           /* PLB Error Address Low */
 #define DCRN_PLB0_BEAR         DCRN_PLB0_BEARL /* 40x compatibility */
 #define DCRN_PLB0_BEARH                0x087           /* PLB Error Address High */
+#endif
 
 /* 440GP/GX PLB to OPB bridge DCRs */
 #define DCRN_POB0_BESR0                0x090
 #define PPC44x_MEM_SIZE_1G             0x40000000
 #define PPC44x_MEM_SIZE_2G             0x80000000
 
-/* 440SP memory controller DCRs */
+/* 440SP/440SPe memory controller DCRs */
 #define DCRN_MQ0_BS0BAS                        0x40
-#define DCRN_MQ0_BS1BAS                        0x41
+#if defined(CONFIG_440SP)
+#define MQ0_NUM_BANKS                  2
+#elif defined(CONFIG_440SPE)
+#define MQ0_NUM_BANKS                  4
+#endif
 
 #define MQ0_CONFIG_SIZE_MASK           0x0000fff0
 #define MQ0_CONFIG_SIZE_8M             0x0000ffc0
 #define MQ0_CONFIG_SIZE_512M           0x0000f000
 #define MQ0_CONFIG_SIZE_1G             0x0000e000
 #define MQ0_CONFIG_SIZE_2G             0x0000c000
+#define MQ0_CONFIG_SIZE_4G             0x00008000
 
-/* Internal SRAM Controller 440GX/440SP */
+/* Internal SRAM Controller 440GX/440SP/440SPe */
 #define DCRN_SRAM0_BASE                0x000
 
 #define DCRN_SRAM0_SB0CR       (DCRN_SRAM0_BASE + 0x020)
 #define DCRN_SRAM0_DPC         (DCRN_SRAM0_BASE + 0x02a)
 #define  SRAM_DPC_ENABLE       0x80000000
 
-/* L2 Cache Controller 440GX/440SP */
+/* L2 Cache Controller 440GX/440SP/440SPe */
 #define DCRN_L2C0_CFG          0x030
 #define  L2C_CFG_L2M           0x80000000
 #define  L2C_CFG_ICU           0x40000000
 #define IIC_CLOCK              50
 
 #undef NR_UICS
-#ifdef CONFIG_440GX
+#if defined(CONFIG_440GX)
 #define NR_UICS 3
+#elif defined(CONFIG_440SPE)
+#define NR_UICS 4
 #else
 #define NR_UICS 2
 #endif
index e992369cb8e9b476fd64306bbc92a846a5bb074f..6c28ae7807f4fe20add48c793a0d84397e61bf50 100644 (file)
@@ -97,6 +97,10 @@ void ppc4xx_init(unsigned long r3, unsigned long r4, unsigned long r5,
 #include <platforms/4xx/luan.h>
 #endif
 
+#if defined(CONFIG_YUCCA)
+#include <platforms/4xx/yucca.h>
+#endif
+
 #if defined(CONFIG_OCOTEA)
 #include <platforms/4xx/ocotea.h>
 #endif
index 6f10a25bd628c18cc2f4bd1462d79c9f61936a86..9c21de1ff4ed109805142f9d23dd45dfcdff5f6a 100644 (file)
@@ -131,9 +131,22 @@ static inline void ibm_ocp_set_emac(int start, int end)
        /* Copy MAC addresses to EMAC additions */
        for (i=start; i<=end; i++) {
                def = ocp_get_one_device(OCP_VENDOR_IBM, OCP_FUNC_EMAC, i);
-               memcpy(((struct ocp_func_emac_data *)def->additions)->mac_addr,
-                               &__res.bi_enetaddr[i],
-                               6);
+               if (i == 0)
+                       memcpy(((struct ocp_func_emac_data *)def->additions)->mac_addr,
+                              __res.bi_enetaddr, 6);
+#if defined(CONFIG_405EP) || defined(CONFIG_44x)
+               else if (i == 1)
+                       memcpy(((struct ocp_func_emac_data *)def->additions)->mac_addr,
+                              __res.bi_enet1addr, 6);
+#endif
+#if defined(CONFIG_440GX)
+               else if (i == 2)
+                       memcpy(((struct ocp_func_emac_data *)def->additions)->mac_addr,
+                              __res.bi_enet2addr, 6);
+               else if (i == 3)
+                       memcpy(((struct ocp_func_emac_data *)def->additions)->mac_addr,
+                              __res.bi_enet3addr, 6);
+#endif
        }
 }
 #endif
index b28a713ba862e48754afc3d409060d50153ad1a2..6d1c39e8a6afef09a47c503b7bd734aa0e9acf28 100644 (file)
@@ -12,6 +12,7 @@
 #include <asm/processor.h>             /* For TASK_SIZE */
 #include <asm/mmu.h>
 #include <asm/page.h>
+struct mm_struct;
 
 extern unsigned long va_to_phys(unsigned long address);
 extern pte_t *va_to_pte(unsigned long address);
index fe24e4520208bdfd31b58baf507295231ac24185..6b7b63f71daae2d41c125b9b84ba92404b172b44 100644 (file)
@@ -73,8 +73,8 @@ typedef struct bd_info {
 #if defined(CONFIG_HYMOD)
        hymod_conf_t    bi_hymod_conf;  /* hymod configuration information */
 #endif
-#if defined(CONFIG_EVB64260) || defined(CONFIG_44x) || defined(CONFIG_85xx) ||\
-       defined(CONFIG_83xx)
+#if defined(CONFIG_EVB64260) || defined(CONFIG_405EP) || defined(CONFIG_44x) || \
+       defined(CONFIG_85xx) || defined(CONFIG_83xx)
        /* second onboard ethernet port */
        unsigned char   bi_enet1addr[6];
 #endif
@@ -96,5 +96,7 @@ typedef struct bd_info {
 #endif
 } bd_t;
 
+#define bi_tbfreq      bi_intfreq
+
 #endif /* __ASSEMBLY__ */
 #endif /* __ASM_PPCBOOT_H__ */
diff --git a/include/asm-ppc/rio.h b/include/asm-ppc/rio.h
new file mode 100644 (file)
index 0000000..0018bf8
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ * RapidIO architecture support
+ *
+ * Copyright 2005 MontaVista Software, Inc.
+ * Matt Porter <mporter@kernel.crashing.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.
+ */
+
+#ifndef ASM_PPC_RIO_H
+#define ASM_PPC_RIO_H
+
+extern void platform_rio_init(void);
+
+#endif                         /* ASM_PPC_RIO_H */
index c883a274855878c20602cf246d45993f218ebffe..e9590c06ad9276541a191ec1f3a3057452c7bde9 100644 (file)
@@ -23,6 +23,9 @@
 #define PMD_SIZE       (1UL << PMD_SHIFT)
 #define PMD_MASK       (~(PMD_SIZE-1))
 
+/* With 4k base page size, hugepage PTEs go at the PMD level */
+#define MIN_HUGEPTE_SHIFT      PMD_SHIFT
+
 /* PUD_SHIFT determines what a third-level page table entry can map */
 #define PUD_SHIFT      (PMD_SHIFT + PMD_INDEX_SIZE)
 #define PUD_SIZE       (1UL << PUD_SHIFT)
index c5f437c86b3c7a67b264edea5b9de83dedf9001c..154f1840ece4d0c49e403177b8262640e91048a6 100644 (file)
@@ -14,6 +14,9 @@
 #define PTRS_PER_PMD   (1 << PMD_INDEX_SIZE)
 #define PTRS_PER_PGD   (1 << PGD_INDEX_SIZE)
 
+/* With 4k base page size, hugepage PTEs go at the PMD level */
+#define MIN_HUGEPTE_SHIFT      PAGE_SHIFT
+
 /* PMD_SHIFT determines what a second-level page table entry can map */
 #define PMD_SHIFT      (PAGE_SHIFT + PTE_INDEX_SIZE)
 #define PMD_SIZE       (1UL << PMD_SHIFT)
index fde93ec36abc5550e91724357ef1137debd4cbe6..a9783ba7fe9898f87291bc59168a7452b656b24d 100644 (file)
@@ -13,6 +13,7 @@
 #include <asm/mmu.h>
 #include <asm/page.h>
 #include <asm/tlbflush.h>
+struct mm_struct;
 #endif /* __ASSEMBLY__ */
 
 #ifdef CONFIG_PPC_64K_PAGES
index 8651524217fde5108f6e5ded6ba1f4c4e5100f2c..b07c578b22ea677d55f9bf147d8791a18c75a20e 100644 (file)
@@ -518,8 +518,8 @@ static inline int __test_bit(unsigned long nr, const volatile unsigned long *ptr
 
 static inline int 
 __constant_test_bit(unsigned long nr, const volatile unsigned long *addr) {
-    return (((volatile char *) addr)
-           [(nr^(__BITOPS_WORDSIZE-8))>>3] & (1<<(nr&7)));
+    return ((((volatile char *) addr)
+           [(nr^(__BITOPS_WORDSIZE-8))>>3] & (1<<(nr&7)))) != 0;
 }
 
 #define test_bit(nr,addr) \
index 3b8bd46832a14c9a746dab57d2e7f370ad250e60..372d51cccd5306a46494744898132a4929551c19 100644 (file)
@@ -96,6 +96,7 @@
  * ELF register definitions..
  */
 
+#include <linux/sched.h>       /* for task_struct */
 #include <asm/ptrace.h>
 #include <asm/user.h>
 #include <asm/system.h>                /* for save_access_regs */
index df94f89038cc3ab5f93d3f6db8df742b1f24c720..9be741bb1496fd831601559936d51708127990da 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/threads.h>
 
 struct vm_area_struct; /* forward declaration (include/linux/mm.h) */
+struct mm_struct;
 
 extern pgd_t swapper_pg_dir[] __attribute__ ((aligned (4096)));
 extern void paging_init(void);
index fc7c96edc697c5922f0377811b3531cc0d161cdb..a949cc077cc72fcfc5b371e4acd54c7bde23621b 100644 (file)
@@ -468,6 +468,8 @@ struct user_regs_struct
 };
 
 #ifdef __KERNEL__
+#define __ARCH_SYS_PTRACE      1
+
 #define user_mode(regs) (((regs)->psw.mask & PSW_MASK_PSTATE) != 0)
 #define instruction_pointer(regs) ((regs)->psw.addr & PSW_ADDR_INSN)
 #define profile_pc(regs) instruction_pointer(regs)
index 38a5cf8ab9e3e5cc69f162f1b8af363f886b7046..10a619da4761cddd316266891b26c5f69b86cb43 100644 (file)
@@ -200,21 +200,37 @@ extern int __put_user_bad(void) __attribute__((noreturn));
 
 #define __get_user(x, ptr)                                     \
 ({                                                             \
-       __typeof__(*(ptr)) __x;                                 \
        int __gu_err;                                           \
         __chk_user_ptr(ptr);                                    \
        switch (sizeof(*(ptr))) {                               \
-       case 1:                                                 \
-       case 2:                                                 \
-       case 4:                                                 \
-       case 8:                                                 \
+       case 1: {                                               \
+               unsigned char __x;                              \
+               __get_user_asm(__x, ptr, __gu_err);             \
+               (x) = (__typeof__(*(ptr))) __x;                 \
+               break;                                          \
+       };                                                      \
+       case 2: {                                               \
+               unsigned short __x;                             \
+               __get_user_asm(__x, ptr, __gu_err);             \
+               (x) = (__typeof__(*(ptr))) __x;                 \
+               break;                                          \
+       };                                                      \
+       case 4: {                                               \
+               unsigned int __x;                               \
+               __get_user_asm(__x, ptr, __gu_err);             \
+               (x) = (__typeof__(*(ptr))) __x;                 \
+               break;                                          \
+       };                                                      \
+       case 8: {                                               \
+               unsigned long long __x;                         \
                __get_user_asm(__x, ptr, __gu_err);             \
+               (x) = (__typeof__(*(ptr))) __x;                 \
                break;                                          \
+       };                                                      \
        default:                                                \
                __get_user_bad();                               \
                break;                                          \
        }                                                       \
-       (x) = __x;                                              \
        __gu_err;                                               \
 })
 
index a14e34e80b8811904318552778981d2f0d25a070..41d369f38b0e163fdded72953014c785dd458fad 100644 (file)
-#ifndef __KERNEL__
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <errno.h>
-#include <ctype.h>
-#include <time.h>
-#include <fcntl.h>
-#include <unistd.h>
+/*
+ * include/asm-s390/vtoc.h
+ *
+ * This file contains volume label definitions for DASD devices.
+ *
+ * (C) Copyright IBM Corp. 2005
+ *
+ * Author(s): Volker Sameske <sameske@de.ibm.com>
+ *
+ */
+
+#ifndef _ASM_S390_VTOC_H
+#define _ASM_S390_VTOC_H
 
-#include <sys/stat.h>
-#include <sys/ioctl.h>
-
-#include <linux/fs.h>
 #include <linux/types.h>
-#include <linux/hdreg.h>
-#include <asm/dasd.h>
-#endif
-
-
-#define LINE_LENGTH 80
-#define VTOC_START_CC 0x0
-#define VTOC_START_HH 0x1
-#define FIRST_USABLE_CYL 1
-#define FIRST_USABLE_TRK 2
-
-#define DASD_3380_TYPE 13148
-#define DASD_3390_TYPE 13200
-#define DASD_9345_TYPE 37701
-
-#define DASD_3380_VALUE 0xbb60
-#define DASD_3390_VALUE 0xe5a2
-#define DASD_9345_VALUE 0xbc98
-
-#define VOLSER_LENGTH 6
-#define BIG_DISK_SIZE 0x10000
-
-#define VTOC_ERROR "VTOC error:"
-
 
-typedef struct ttr 
+struct vtoc_ttr
 {
-        __u16 tt;
-        __u8  r;
-} __attribute__ ((packed)) ttr_t;
+       __u16 tt;
+       __u8 r;
+} __attribute__ ((packed));
 
-typedef struct cchhb 
+struct vtoc_cchhb
 {
-        __u16 cc;
-        __u16 hh;
-        __u8 b;
-} __attribute__ ((packed)) cchhb_t;
+       __u16 cc;
+       __u16 hh;
+       __u8 b;
+} __attribute__ ((packed));
 
-typedef struct cchh 
+struct vtoc_cchh
 {
-        __u16 cc;
-        __u16 hh;
-} __attribute__ ((packed)) cchh_t;
+       __u16 cc;
+       __u16 hh;
+} __attribute__ ((packed));
 
-typedef struct labeldate 
+struct vtoc_labeldate
 {
-        __u8  year;
-        __u16 day;
-} __attribute__ ((packed)) labeldate_t;
+       __u8 year;
+       __u16 day;
+} __attribute__ ((packed));
 
-
-typedef struct volume_label 
+struct vtoc_volume_label
 {
-        char volkey[4];         /* volume key = volume label                 */
-       char vollbl[4];         /* volume label                              */
-       char volid[6];          /* volume identifier                         */
-       __u8 security;          /* security byte                             */
-       cchhb_t vtoc;           /* VTOC address                              */
-       char res1[5];           /* reserved                                  */
-        char cisize[4];                /* CI-size for FBA,...                       */
-                                /* ...blanks for CKD                         */
-       char blkperci[4];       /* no of blocks per CI (FBA), blanks for CKD */
-       char labperci[4];       /* no of labels per CI (FBA), blanks for CKD */
-       char res2[4];           /* reserved                                  */
-       char lvtoc[14];         /* owner code for LVTOC                      */
-       char res3[29];          /* reserved                                  */
-} __attribute__ ((packed)) volume_label_t;
-
-
-typedef struct extent 
+       char volkey[4];         /* volume key = volume label */
+       char vollbl[4];         /* volume label */
+       char volid[6];          /* volume identifier */
+       __u8 security;          /* security byte */
+       struct vtoc_cchhb vtoc; /* VTOC address */
+       char res1[5];           /* reserved */
+       char cisize[4];         /* CI-size for FBA,... */
+                               /* ...blanks for CKD */
+       char blkperci[4];       /* no of blocks per CI (FBA), blanks for CKD */
+       char labperci[4];       /* no of labels per CI (FBA), blanks for CKD */
+       char res2[4];           /* reserved */
+       char lvtoc[14];         /* owner code for LVTOC */
+       char res3[29];          /* reserved */
+} __attribute__ ((packed));
+
+struct vtoc_extent
 {
-        __u8  typeind;          /* extent type indicator                     */
-        __u8  seqno;            /* extent sequence number                    */
-        cchh_t llimit;          /* starting point of this extent             */
-        cchh_t ulimit;          /* ending point of this extent               */
-} __attribute__ ((packed)) extent_t;
-
+       __u8 typeind;                   /* extent type indicator */
+       __u8 seqno;                     /* extent sequence number */
+       struct vtoc_cchh llimit;        /* starting point of this extent */
+       struct vtoc_cchh ulimit;        /* ending point of this extent */
+} __attribute__ ((packed));
 
-typedef struct dev_const 
+struct vtoc_dev_const
 {
-        __u16 DS4DSCYL;           /* number of logical cyls                  */
-        __u16 DS4DSTRK;           /* number of tracks in a logical cylinder  */
-        __u16 DS4DEVTK;           /* device track length                     */
-        __u8  DS4DEVI;            /* non-last keyed record overhead          */
-        __u8  DS4DEVL;            /* last keyed record overhead              */
-        __u8  DS4DEVK;            /* non-keyed record overhead differential  */
-        __u8  DS4DEVFG;           /* flag byte                               */
-        __u16 DS4DEVTL;           /* device tolerance                        */
-        __u8  DS4DEVDT;           /* number of DSCB's per track              */
-        __u8  DS4DEVDB;           /* number of directory blocks per track    */
-} __attribute__ ((packed)) dev_const_t;
-
-
-typedef struct format1_label 
+       __u16 DS4DSCYL; /* number of logical cyls */
+       __u16 DS4DSTRK; /* number of tracks in a logical cylinder */
+       __u16 DS4DEVTK; /* device track length */
+       __u8 DS4DEVI;   /* non-last keyed record overhead */
+       __u8 DS4DEVL;   /* last keyed record overhead */
+       __u8 DS4DEVK;   /* non-keyed record overhead differential */
+       __u8 DS4DEVFG;  /* flag byte */
+       __u16 DS4DEVTL; /* device tolerance */
+       __u8 DS4DEVDT;  /* number of DSCB's per track */
+       __u8 DS4DEVDB;  /* number of directory blocks per track */
+} __attribute__ ((packed));
+
+struct vtoc_format1_label
 {
-       char  DS1DSNAM[44];       /* data set name                           */
-       __u8  DS1FMTID;           /* format identifier                       */
-       char  DS1DSSN[6];         /* data set serial number                  */
-       __u16 DS1VOLSQ;           /* volume sequence number                  */
-       labeldate_t DS1CREDT;     /* creation date: ydd                      */
-       labeldate_t DS1EXPDT;     /* expiration date                         */
-       __u8  DS1NOEPV;           /* number of extents on volume             */
-        __u8  DS1NOBDB;           /* no. of bytes used in last direction blk */
-       __u8  DS1FLAG1;           /* flag 1                                  */
-       char  DS1SYSCD[13];       /* system code                             */
-       labeldate_t DS1REFD;      /* date last referenced                    */
-        __u8  DS1SMSFG;           /* system managed storage indicators       */
-        __u8  DS1SCXTF;           /* sec. space extension flag byte          */
-        __u16 DS1SCXTV;           /* secondary space extension value         */
-        __u8  DS1DSRG1;           /* data set organisation byte 1            */
-        __u8  DS1DSRG2;           /* data set organisation byte 2            */
-       __u8  DS1RECFM;           /* record format                           */
-       __u8  DS1OPTCD;           /* option code                             */
-       __u16 DS1BLKL;            /* block length                            */
-       __u16 DS1LRECL;           /* record length                           */
-       __u8  DS1KEYL;            /* key length                              */
-       __u16 DS1RKP;             /* relative key position                   */
-       __u8  DS1DSIND;           /* data set indicators                     */
-        __u8  DS1SCAL1;           /* secondary allocation flag byte          */
-       char DS1SCAL3[3];         /* secondary allocation quantity           */
-       ttr_t DS1LSTAR;           /* last used track and block on track      */
-       __u16 DS1TRBAL;           /* space remaining on last used track      */
-        __u16 res1;               /* reserved                                */
-       extent_t DS1EXT1;         /* first extent description                */
-       extent_t DS1EXT2;         /* second extent description               */
-       extent_t DS1EXT3;         /* third extent description                */
-       cchhb_t DS1PTRDS;         /* possible pointer to f2 or f3 DSCB       */
-} __attribute__ ((packed)) format1_label_t;
-
-
-typedef struct format4_label 
+       char DS1DSNAM[44];      /* data set name */
+       __u8 DS1FMTID;          /* format identifier */
+       char DS1DSSN[6];        /* data set serial number */
+       __u16 DS1VOLSQ;         /* volume sequence number */
+       struct vtoc_labeldate DS1CREDT; /* creation date: ydd */
+       struct vtoc_labeldate DS1EXPDT; /* expiration date */
+       __u8 DS1NOEPV;          /* number of extents on volume */
+       __u8 DS1NOBDB;          /* no. of bytes used in last direction blk */
+       __u8 DS1FLAG1;          /* flag 1 */
+       char DS1SYSCD[13];      /* system code */
+       struct vtoc_labeldate DS1REFD; /* date last referenced  */
+       __u8 DS1SMSFG;          /* system managed storage indicators */
+       __u8 DS1SCXTF;          /* sec. space extension flag byte */
+       __u16 DS1SCXTV;         /* secondary space extension value */
+       __u8 DS1DSRG1;          /* data set organisation byte 1 */
+       __u8 DS1DSRG2;          /* data set organisation byte 2 */
+       __u8 DS1RECFM;          /* record format */
+       __u8 DS1OPTCD;          /* option code */
+       __u16 DS1BLKL;          /* block length */
+       __u16 DS1LRECL;         /* record length */
+       __u8 DS1KEYL;           /* key length */
+       __u16 DS1RKP;           /* relative key position */
+       __u8 DS1DSIND;          /* data set indicators */
+       __u8 DS1SCAL1;          /* secondary allocation flag byte */
+       char DS1SCAL3[3];       /* secondary allocation quantity */
+       struct vtoc_ttr DS1LSTAR; /* last used track and block on track */
+       __u16 DS1TRBAL;         /* space remaining on last used track */
+       __u16 res1;             /* reserved */
+       struct vtoc_extent DS1EXT1; /* first extent description */
+       struct vtoc_extent DS1EXT2; /* second extent description */
+       struct vtoc_extent DS1EXT3; /* third extent description */
+       struct vtoc_cchhb DS1PTRDS; /* possible pointer to f2 or f3 DSCB */
+} __attribute__ ((packed));
+
+struct vtoc_format4_label
 {
-       char  DS4KEYCD[44];       /* key code for VTOC labels: 44 times 0x04 */
-        __u8  DS4IDFMT;           /* format identifier                       */
-       cchhb_t DS4HPCHR;         /* highest address of a format 1 DSCB      */
-        __u16 DS4DSREC;           /* number of available DSCB's              */
-        cchh_t DS4HCCHH;          /* CCHH of next available alternate track  */
-        __u16 DS4NOATK;           /* number of remaining alternate tracks    */
-        __u8  DS4VTOCI;           /* VTOC indicators                         */
-        __u8  DS4NOEXT;           /* number of extents in VTOC               */
-        __u8  DS4SMSFG;           /* system managed storage indicators       */
-        __u8  DS4DEVAC;           /* number of alternate cylinders. 
-                                     Subtract from first two bytes of 
-                                     DS4DEVSZ to get number of usable
-                                    cylinders. can be zero. valid
-                                    only if DS4DEVAV on.                    */
-        dev_const_t DS4DEVCT;     /* device constants                        */
-        char DS4AMTIM[8];         /* VSAM time stamp                         */
-        char DS4AMCAT[3];         /* VSAM catalog indicator                  */
-        char DS4R2TIM[8];         /* VSAM volume/catalog match time stamp    */
-        char res1[5];             /* reserved                                */
-        char DS4F6PTR[5];         /* pointer to first format 6 DSCB          */
-        extent_t DS4VTOCE;        /* VTOC extent description                 */
-        char res2[10];            /* reserved                                */
-        __u8 DS4EFLVL;            /* extended free-space management level    */
-        cchhb_t DS4EFPTR;         /* pointer to extended free-space info     */
-        char res3[9];             /* reserved                                */
-} __attribute__ ((packed)) format4_label_t;
-
-
-typedef struct ds5ext 
+       char DS4KEYCD[44];      /* key code for VTOC labels: 44 times 0x04 */
+       __u8 DS4IDFMT;          /* format identifier */
+       struct vtoc_cchhb DS4HPCHR; /* highest address of a format 1 DSCB */
+       __u16 DS4DSREC;         /* number of available DSCB's */
+       struct vtoc_cchh DS4HCCHH; /* CCHH of next available alternate track */
+       __u16 DS4NOATK;         /* number of remaining alternate tracks */
+       __u8 DS4VTOCI;          /* VTOC indicators */
+       __u8 DS4NOEXT;          /* number of extents in VTOC */
+       __u8 DS4SMSFG;          /* system managed storage indicators */
+       __u8 DS4DEVAC;          /* number of alternate cylinders.
+                                * Subtract from first two bytes of
+                                * DS4DEVSZ to get number of usable
+                                * cylinders. can be zero. valid
+                                * only if DS4DEVAV on. */
+       struct vtoc_dev_const DS4DEVCT; /* device constants */
+       char DS4AMTIM[8];       /* VSAM time stamp */
+       char DS4AMCAT[3];       /* VSAM catalog indicator */
+       char DS4R2TIM[8];       /* VSAM volume/catalog match time stamp */
+       char res1[5];           /* reserved */
+       char DS4F6PTR[5];       /* pointer to first format 6 DSCB */
+       struct vtoc_extent DS4VTOCE; /* VTOC extent description */
+       char res2[10];          /* reserved */
+       __u8 DS4EFLVL;          /* extended free-space management level */
+       struct vtoc_cchhb DS4EFPTR; /* pointer to extended free-space info */
+       char res3[9];           /* reserved */
+} __attribute__ ((packed));
+
+struct vtoc_ds5ext
 {
-       __u16 t;                  /* RTA of the first track of free extent   */
-       __u16 fc;                 /* number of whole cylinders in free ext.  */
-       __u8  ft;                 /* number of remaining free tracks         */
-} __attribute__ ((packed)) ds5ext_t;
-
+       __u16 t;        /* RTA of the first track of free extent */
+       __u16 fc;       /* number of whole cylinders in free ext. */
+       __u8 ft;        /* number of remaining free tracks */
+} __attribute__ ((packed));
 
-typedef struct format5_label 
+struct vtoc_format5_label
 {
-       char DS5KEYID[4];         /* key identifier                          */
-       ds5ext_t DS5AVEXT;        /* first available (free-space) extent.    */
-       ds5ext_t DS5EXTAV[7];     /* seven available extents                 */
-       __u8 DS5FMTID;            /* format identifier                       */
-       ds5ext_t DS5MAVET[18];    /* eighteen available extents              */
-       cchhb_t DS5PTRDS;         /* pointer to next format5 DSCB            */
-} __attribute__ ((packed)) format5_label_t;
-
-
-typedef struct ds7ext 
+       char DS5KEYID[4];       /* key identifier */
+       struct vtoc_ds5ext DS5AVEXT; /* first available (free-space) extent. */
+       struct vtoc_ds5ext DS5EXTAV[7]; /* seven available extents */
+       __u8 DS5FMTID;          /* format identifier */
+       struct vtoc_ds5ext DS5MAVET[18]; /* eighteen available extents */
+       struct vtoc_cchhb DS5PTRDS; /* pointer to next format5 DSCB */
+} __attribute__ ((packed));
+
+struct vtoc_ds7ext
 {
-       __u32 a;                  /* starting RTA value                      */
-       __u32 b;                  /* ending RTA value + 1                    */
-} __attribute__ ((packed)) ds7ext_t;
+       __u32 a; /* starting RTA value */
+       __u32 b; /* ending RTA value + 1 */
+} __attribute__ ((packed));
 
-
-typedef struct format7_label 
+struct vtoc_format7_label
 {
-       char DS7KEYID[4];         /* key identifier                          */
-       ds7ext_t DS7EXTNT[5];     /* space for 5 extent descriptions         */
-       __u8 DS7FMTID;            /* format identifier                       */
-       ds7ext_t DS7ADEXT[11];    /* space for 11 extent descriptions        */
-       char res1[2];             /* reserved                                */
-       cchhb_t DS7PTRDS;         /* pointer to next FMT7 DSCB               */
-} __attribute__ ((packed)) format7_label_t;
-
-
-char * vtoc_ebcdic_enc (
-        unsigned char source[LINE_LENGTH],
-        unsigned char target[LINE_LENGTH],
-       int l);
-char * vtoc_ebcdic_dec (
-        unsigned char source[LINE_LENGTH],
-       unsigned char target[LINE_LENGTH],
-       int l);
-void vtoc_set_extent (
-        extent_t * ext,
-        __u8 typeind,
-        __u8 seqno,
-        cchh_t * lower,
-        cchh_t * upper);
-void vtoc_set_cchh (
-        cchh_t * addr,
-       __u16 cc,
-       __u16 hh);
-void vtoc_set_cchhb (
-        cchhb_t * addr,
-        __u16 cc,
-        __u16 hh,
-        __u8 b);
-void vtoc_set_date (
-        labeldate_t * d,
-        __u8 year,
-        __u16 day);
-
-void vtoc_volume_label_init (
-       volume_label_t *vlabel);
-
-int vtoc_read_volume_label (
-        char * device,
-        unsigned long vlabel_start,
-        volume_label_t * vlabel);
-
-int vtoc_write_volume_label (
-        char *device,
-        unsigned long vlabel_start,
-        volume_label_t *vlabel);
-
-void vtoc_volume_label_set_volser (
-       volume_label_t *vlabel,
-       char *volser);
-
-char *vtoc_volume_label_get_volser (
-       volume_label_t *vlabel,
-       char *volser);
-
-void vtoc_volume_label_set_key (
-        volume_label_t *vlabel,
-        char *key);     
-
-void vtoc_volume_label_set_label (
-       volume_label_t *vlabel,
-       char *lbl);
-
-char *vtoc_volume_label_get_label (
-       volume_label_t *vlabel,
-       char *lbl);
-
-void vtoc_read_label (
-        char *device,
-        unsigned long position,
-        format1_label_t *f1,
-        format4_label_t *f4,
-        format5_label_t *f5,
-        format7_label_t *f7);
-
-void vtoc_write_label (
-        char *device,
-        unsigned long position,
-        format1_label_t *f1,
-       format4_label_t *f4,
-       format5_label_t *f5,
-       format7_label_t *f7);
-
-
-void vtoc_init_format1_label (
-        char *volid,
-        unsigned int blksize,
-        extent_t *part_extent,
-        format1_label_t *f1);
-
-
-void vtoc_init_format4_label (
-        format4_label_t *f4lbl,
-       unsigned int usable_partitions,
-       unsigned int cylinders,
-       unsigned int tracks,
-       unsigned int blocks,
-       unsigned int blksize,
-       __u16 dev_type);
-
-void vtoc_update_format4_label (
-       format4_label_t *f4,
-       cchhb_t *highest_f1,
-       __u16 unused_update);
-
-
-void vtoc_init_format5_label (
-       format5_label_t *f5);
-
-void vtoc_update_format5_label_add (
-       format5_label_t *f5,
-       int verbose,
-       int cyl,
-       int trk,
-       __u16 a, 
-       __u16 b, 
-       __u8 c);
-void vtoc_update_format5_label_del (
-       format5_label_t *f5,
-       int verbose,
-       int cyl,
-       int trk,
-       __u16 a, 
-       __u16 b, 
-       __u8 c);
-
-
-void vtoc_init_format7_label (
-       format7_label_t *f7);
-
-void vtoc_update_format7_label_add (
-       format7_label_t *f7,
-       int verbose,
-       __u32 a, 
-       __u32 b);
-
-void vtoc_update_format7_label_del (
-       format7_label_t *f7, 
-       int verbose,
-       __u32 a, 
-       __u32 b);
-
-
-void vtoc_set_freespace(
-       format4_label_t *f4,
-       format5_label_t *f5,
-       format7_label_t *f7,
-       char ch,
-       int verbose,
-       __u32 start,
-       __u32 stop,
-       int cyl,
-       int trk);
-
-
-
-
-
-
-
-
-
-
-
-
+       char DS7KEYID[4];       /* key identifier */
+       struct vtoc_ds7ext DS7EXTNT[5]; /* space for 5 extent descriptions */
+       __u8 DS7FMTID;          /* format identifier */
+       struct vtoc_ds7ext DS7ADEXT[11]; /* space for 11 extent descriptions */
+       char res1[2];           /* reserved */
+       struct vtoc_cchhb DS7PTRDS; /* pointer to next FMT7 DSCB */
+} __attribute__ ((packed));
+
+#endif /* _ASM_S390_VTOC_H */
index 8fe00a1981ce757fcf1ed899cb570331bd59b3d8..1b63dfeea4f2b3e165a4689e80c130a46b6eb1c0 100644 (file)
@@ -111,6 +111,7 @@ typedef struct user_fpu_struct elf_fpregset_t;
 
 #ifdef __KERNEL__
 #define SET_PERSONALITY(ex, ibcs2) set_personality(PER_LINUX_32BIT)
+struct task_struct;
 extern int dump_task_regs (struct task_struct *, elf_gregset_t *);
 extern int dump_task_fpu (struct task_struct *, elf_fpregset_t *);
 
diff --git a/include/asm-sh/mmzone.h b/include/asm-sh/mmzone.h
deleted file mode 100644 (file)
index 0e74066..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- *  linux/include/asm-sh/mmzone.h
- *
- * 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.
- */
-#ifndef __ASM_SH_MMZONE_H
-#define __ASM_SH_MMZONE_H
-
-#include <linux/config.h>
-
-#ifdef CONFIG_DISCONTIGMEM
-
-/* Currently, just for HP690 */
-#define PHYSADDR_TO_NID(phys)  ((((phys) - __MEMORY_START) >= 0x01000000)?1:0)
-
-extern pg_data_t discontig_page_data[MAX_NUMNODES];
-extern bootmem_data_t discontig_node_bdata[MAX_NUMNODES];
-
-/*
- * Following are macros that each numa implmentation must define.
- */
-
-/*
- * Given a kernel address, find the home node of the underlying memory.
- */
-#define KVADDR_TO_NID(kaddr)   PHYSADDR_TO_NID(__pa(kaddr))
-
-/*
- * Return a pointer to the node data for node n.
- */
-#define NODE_DATA(nid)         (&discontig_page_data[nid])
-
-/*
- * NODE_MEM_MAP gives the kaddr for the mem_map of the node.
- */
-#define NODE_MEM_MAP(nid)      (NODE_DATA(nid)->node_mem_map)
-
-#define phys_to_page(phys)                                             \
-({ unsigned int node = PHYSADDR_TO_NID(phys);                          \
-   NODE_MEM_MAP(node)                                                  \
-     + (((phys) - NODE_DATA(node)->node_start_paddr) >> PAGE_SHIFT); })
-
-static inline int is_valid_page(struct page *page)
-{
-       unsigned int i;
-
-       for (i = 0; i < MAX_NUMNODES; i++) {
-               if (page >= NODE_MEM_MAP(i) &&
-                   page < NODE_MEM_MAP(i) + NODE_DATA(i)->node_size)
-                       return 1;
-       }
-       return 0;
-}
-
-#define VALID_PAGE(page)       is_valid_page(page)
-#define page_to_phys(page)     PHYSADDR(page_address(page))
-
-#endif /* CONFIG_DISCONTIGMEM */
-#endif
index 324e6cc5ecf71c90d66fa90fe459e944791f6c86..972c3f655b2a01030f78fc720056264361f1af88 100644 (file)
@@ -93,11 +93,6 @@ typedef struct { unsigned long pgprot; } pgprot_t;
 
 #define __MEMORY_START         CONFIG_MEMORY_START
 #define __MEMORY_SIZE          CONFIG_MEMORY_SIZE
-#ifdef CONFIG_DISCONTIGMEM
-/* Just for HP690, for now.. */
-#define __MEMORY_START_2ND     (__MEMORY_START+0x02000000)
-#define __MEMORY_SIZE_2ND      0x001000000 /* 16MB */
-#endif
 
 #define PAGE_OFFSET            (0x80000000UL)
 #define __pa(x)                        ((unsigned long)(x)-PAGE_OFFSET)
@@ -105,10 +100,8 @@ typedef struct { unsigned long pgprot; } pgprot_t;
 
 #define MAP_NR(addr)           (((unsigned long)(addr)-PAGE_OFFSET) >> PAGE_SHIFT)
 
-#ifndef CONFIG_DISCONTIGMEM
 #define phys_to_page(phys)     (mem_map + (((phys)-__MEMORY_START) >> PAGE_SHIFT))
 #define page_to_phys(page)     (((page - mem_map) << PAGE_SHIFT) + __MEMORY_START)
-#endif
 
 /* PFN start number, because of __MEMORY_START */
 #define PFN_START              (__MEMORY_START >> PAGE_SHIFT)
index aef8ae43de1367de335ee4b698ae76f5a040f33a..bb0efb31a8cbeb230a60ab4386b3c4d122b8f099 100644 (file)
@@ -196,7 +196,9 @@ static inline pte_t pte_mkexec(pte_t pte)   { set_pte(&pte, __pte(pte_val(pte) | _
 static inline pte_t pte_mkdirty(pte_t pte)     { set_pte(&pte, __pte(pte_val(pte) | _PAGE_DIRTY)); return pte; }
 static inline pte_t pte_mkyoung(pte_t pte)     { set_pte(&pte, __pte(pte_val(pte) | _PAGE_ACCESSED)); return pte; }
 static inline pte_t pte_mkwrite(pte_t pte)     { set_pte(&pte, __pte(pte_val(pte) | _PAGE_RW)); return pte; }
+#ifdef CONFIG_HUGETLB_PAGE
 static inline pte_t pte_mkhuge(pte_t pte)      { set_pte(&pte, __pte(pte_val(pte) | _PAGE_SZHUGE)); return pte; }
+#endif
 
 /*
  * Macro and implementation to make a page protection as uncachable.
@@ -282,6 +284,8 @@ typedef pte_t *pte_addr_t;
 #define GET_IOSPACE(pfn)               0
 #define GET_PFN(pfn)                   (pfn)
 
+struct mm_struct;
+
 /*
  * No page table caches to initialise
  */
index 51b05818e4ebc9cfc848f2992782e43cc0990f6d..a1906a772df9b66594bb39da22866e0097317d11 100644 (file)
@@ -24,6 +24,8 @@
 #include <linux/threads.h>
 #include <linux/config.h>
 
+struct vm_area_struct;
+
 extern void paging_init(void);
 
 /* We provide our own get_unmapped_area to avoid cache synonym issue */
index a8ecb2d6977aadcb20bd40a652403a2f3f7fde07..714497099a423ae54d35a2d0e6d0985a219d043c 100644 (file)
@@ -60,6 +60,9 @@ struct sparc_stackf {
 #define STACKFRAME_SZ sizeof(struct sparc_stackf)
 
 #ifdef __KERNEL__
+
+#define __ARCH_SYS_PTRACE      1
+
 #define user_mode(regs) (!((regs)->psr & PSR_PS))
 #define instruction_pointer(regs) ((regs)->pc)
 unsigned long profile_pc(struct pt_regs *);
index a8d326a598f0215994f1d0b2bf7cfb56cb355b17..7ba845320f5c05d0d9450d89cbf2dacf72b72819 100644 (file)
@@ -3,6 +3,7 @@
 
 #include <linux/config.h>
 #include <linux/types.h>
+#include <linux/percpu.h>
 
 typedef u32 kprobe_opcode_t;
 
@@ -18,6 +19,25 @@ struct arch_specific_insn {
        kprobe_opcode_t insn[MAX_INSN_SIZE];
 };
 
+struct prev_kprobe {
+       struct kprobe *kp;
+       unsigned int status;
+       unsigned long orig_tnpc;
+       unsigned long orig_tstate_pil;
+};
+
+/* per-cpu kprobe control block */
+struct kprobe_ctlblk {
+       unsigned long kprobe_status;
+       unsigned long kprobe_orig_tnpc;
+       unsigned long kprobe_orig_tstate_pil;
+       long *jprobe_saved_esp;
+       struct pt_regs jprobe_saved_regs;
+       struct pt_regs *jprobe_saved_regs_location;
+       struct sparc_stackf jprobe_saved_stack;
+       struct prev_kprobe prev_kprobe;
+};
+
 #ifdef CONFIG_KPROBES
 extern int kprobe_exceptions_notify(struct notifier_block *self,
                                    unsigned long val, void *data);
index 6194f771e9fc738536b0165a2ee7f6b99e625b34..7eba90c6c7535394859269ea5610f31650a3b247 100644 (file)
@@ -94,6 +94,9 @@ struct sparc_trapf {
 #define STACKFRAME32_SZ        sizeof(struct sparc_stackf32)
 
 #ifdef __KERNEL__
+
+#define __ARCH_SYS_PTRACE      1
+
 #define force_successful_syscall_return()          \
 do {   current_thread_info()->syscall_noerror = 1; \
 } while (0)
diff --git a/include/asm-um/ldt-i386.h b/include/asm-um/ldt-i386.h
new file mode 100644 (file)
index 0000000..b426629
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2004 Fujitsu Siemens Computers GmbH
+ * Licensed under the GPL
+ *
+ * Author: Bodo Stroesser <bstroesser@fujitsu-siemens.com>
+ */
+
+#ifndef __ASM_LDT_I386_H
+#define __ASM_LDT_I386_H
+
+#include "asm/semaphore.h"
+#include "asm/arch/ldt.h"
+
+struct mmu_context_skas;
+extern void ldt_host_info(void);
+extern long init_new_ldt(struct mmu_context_skas * to_mm,
+                        struct mmu_context_skas * from_mm);
+extern void free_ldt(struct mmu_context_skas * mm);
+
+#define LDT_PAGES_MAX \
+       ((LDT_ENTRIES * LDT_ENTRY_SIZE)/PAGE_SIZE)
+#define LDT_ENTRIES_PER_PAGE \
+       (PAGE_SIZE/LDT_ENTRY_SIZE)
+#define LDT_DIRECT_ENTRIES \
+       ((LDT_PAGES_MAX*sizeof(void *))/LDT_ENTRY_SIZE)
+
+struct ldt_entry {
+       __u32 a;
+       __u32 b;
+};
+
+typedef struct uml_ldt {
+       int entry_count;
+       struct semaphore semaphore;
+       union {
+               struct ldt_entry * pages[LDT_PAGES_MAX];
+               struct ldt_entry entries[LDT_DIRECT_ENTRIES];
+       };
+} uml_ldt_t;
+
+/*
+ * macros stolen from include/asm-i386/desc.h
+ */
+#define LDT_entry_a(info) \
+       ((((info)->base_addr & 0x0000ffff) << 16) | ((info)->limit & 0x0ffff))
+
+#define LDT_entry_b(info) \
+       (((info)->base_addr & 0xff000000) | \
+       (((info)->base_addr & 0x00ff0000) >> 16) | \
+       ((info)->limit & 0xf0000) | \
+       (((info)->read_exec_only ^ 1) << 9) | \
+       ((info)->contents << 10) | \
+       (((info)->seg_not_present ^ 1) << 15) | \
+       ((info)->seg_32bit << 22) | \
+       ((info)->limit_in_pages << 23) | \
+       ((info)->useable << 20) | \
+       0x7000)
+
+#define LDT_empty(info) (\
+       (info)->base_addr       == 0    && \
+       (info)->limit           == 0    && \
+       (info)->contents        == 0    && \
+       (info)->read_exec_only  == 1    && \
+       (info)->seg_32bit       == 0    && \
+       (info)->limit_in_pages  == 0    && \
+       (info)->seg_not_present == 1    && \
+       (info)->useable         == 0    )
+
+#endif
index e908439d338aef6c881ea0f4d2e9e5476136295d..4466ff6de0fde32afdd449c7f10959563ecaef4d 100644 (file)
@@ -1,3 +1,72 @@
+/*
+ * Copyright (C) 2004 Fujitsu Siemens Computers GmbH
+ * Licensed under the GPL
+ *
+ * Author: Bodo Stroesser <bstroesser@fujitsu-siemens.com>
+ */
+
+#ifndef __ASM_LDT_I386_H
+#define __ASM_LDT_I386_H
+
+#include "asm/semaphore.h"
+#include "asm/arch/ldt.h"
+
+struct mmu_context_skas;
+extern void ldt_host_info(void);
+extern long init_new_ldt(struct mmu_context_skas * to_mm,
+                        struct mmu_context_skas * from_mm);
+extern void free_ldt(struct mmu_context_skas * mm);
+
+#define LDT_PAGES_MAX \
+       ((LDT_ENTRIES * LDT_ENTRY_SIZE)/PAGE_SIZE)
+#define LDT_ENTRIES_PER_PAGE \
+       (PAGE_SIZE/LDT_ENTRY_SIZE)
+#define LDT_DIRECT_ENTRIES \
+       ((LDT_PAGES_MAX*sizeof(void *))/LDT_ENTRY_SIZE)
+
+struct ldt_entry {
+       __u32 a;
+       __u32 b;
+};
+
+typedef struct uml_ldt {
+       int entry_count;
+       struct semaphore semaphore;
+       union {
+               struct ldt_entry * pages[LDT_PAGES_MAX];
+               struct ldt_entry entries[LDT_DIRECT_ENTRIES];
+       };
+} uml_ldt_t;
+
+/*
+ * macros stolen from include/asm-i386/desc.h
+ */
+#define LDT_entry_a(info) \
+       ((((info)->base_addr & 0x0000ffff) << 16) | ((info)->limit & 0x0ffff))
+
+#define LDT_entry_b(info) \
+       (((info)->base_addr & 0xff000000) | \
+       (((info)->base_addr & 0x00ff0000) >> 16) | \
+       ((info)->limit & 0xf0000) | \
+       (((info)->read_exec_only ^ 1) << 9) | \
+       ((info)->contents << 10) | \
+       (((info)->seg_not_present ^ 1) << 15) | \
+       ((info)->seg_32bit << 22) | \
+       ((info)->limit_in_pages << 23) | \
+       ((info)->useable << 20) | \
+       0x7000)
+
+#define LDT_empty(info) (\
+       (info)->base_addr       == 0    && \
+       (info)->limit           == 0    && \
+       (info)->contents        == 0    && \
+       (info)->read_exec_only  == 1    && \
+       (info)->seg_32bit       == 0    && \
+       (info)->limit_in_pages  == 0    && \
+       (info)->seg_not_present == 1    && \
+       (info)->useable         == 0    )
+
+#endif
 #ifndef __UM_LDT_H
 #define __UM_LDT_H
 
index 2edb4f1f789cdb96e0208da409622db6f1eaa70b..9a0e48eb542e019d5e259f3972550649bb1e46a8 100644 (file)
@@ -29,7 +29,8 @@ static inline void activate_mm(struct mm_struct *old, struct mm_struct *new)
         * possible.
         */
        if (old != new && (current->flags & PF_BORROWED_MM))
-               force_flush_all();
+               CHOOSE_MODE(force_flush_all(),
+                           switch_mm_skas(&new->context.skas.id));
 }
 
 static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, 
index 8284aa7363f21ff7c75fb4377a297b34ba2fb2b6..395268a8c0dec1787fca9f39d29eab8df1d51797 100644 (file)
@@ -31,7 +31,7 @@ typedef struct { int counter; } atomic_t;
 #define atomic_read(v)         ((v)->counter)
 #define atomic_set(v,i)                (((v)->counter) = (i))
 
-extern __inline__ int atomic_add_return (int i, volatile atomic_t *v)
+static inline int atomic_add_return (int i, volatile atomic_t *v)
 {
        unsigned long flags;
        int res;
index 0e5c2f210872b75165f4d622d63b2656352ec40f..b91e799763fdf4f3896b20abb17563323f717b76 100644 (file)
@@ -30,7 +30,7 @@
  * ffz = Find First Zero in word. Undefined if no zero exists,
  * so code should check against ~0UL first..
  */
-extern __inline__ unsigned long ffz (unsigned long word)
+static inline unsigned long ffz (unsigned long word)
 {
        unsigned long result = 0;
 
@@ -135,7 +135,7 @@ extern __inline__ unsigned long ffz (unsigned long word)
                             "m" (*((const char *)(addr) + ((nr) >> 3))));    \
      __test_bit_res;                                                         \
   })
-extern __inline__ int __test_bit (int nr, const void *addr)
+static inline int __test_bit (int nr, const void *addr)
 {
        int res;
        __asm__ __volatile__ ("tst1 %1, [%2]; setf nz, %0"
@@ -157,7 +157,7 @@ extern __inline__ int __test_bit (int nr, const void *addr)
 #define find_first_zero_bit(addr, size) \
   find_next_zero_bit ((addr), (size), 0)
 
-extern __inline__ int find_next_zero_bit(const void *addr, int size, int offset)
+static inline int find_next_zero_bit(const void *addr, int size, int offset)
 {
        unsigned long *p = ((unsigned long *) addr) + (offset >> 5);
        unsigned long result = offset & ~31UL;
index 1ce65d48a7c5acb22df5c52690d6eafee2571154..6d028e6b2354cf7cf3f0fcc11be735c09039d07c 100644 (file)
@@ -16,7 +16,7 @@
 
 #include <asm/param.h>
 
-extern __inline__ void __delay(unsigned long loops)
+static inline void __delay(unsigned long loops)
 {
        if (loops)
                __asm__ __volatile__ ("1: add -1, %0; bnz 1b"
@@ -33,7 +33,7 @@ extern __inline__ void __delay(unsigned long loops)
 
 extern unsigned long loops_per_jiffy;
 
-extern __inline__ void udelay(unsigned long usecs)
+static inline void udelay(unsigned long usecs)
 {
        register unsigned long full_loops, part_loops;
 
index 4bdc98edb9f854b01018bd8fe259ed0f1f6caf6e..a8aab4342712a77a7e1f2ac49ae8b536fb270d40 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef __V850_HW_IRQ_H__
 #define __V850_HW_IRQ_H__
 
-extern inline void hw_resend_irq (struct hw_interrupt_type *h, unsigned int i)
+static inline void hw_resend_irq (struct hw_interrupt_type *h, unsigned int i)
 {
 }
 
index d41f925f5182508117482d4d1ce0ccfbaa41c289..98f929427d3dcfde6e8a825ba0f7620f3743511d 100644 (file)
@@ -59,7 +59,7 @@ struct thread_struct {
 
 
 /* Do necessary setup to start up a newly executed thread.  */
-extern inline void start_thread (struct pt_regs *regs,
+static inline void start_thread (struct pt_regs *regs,
                                 unsigned long pc, unsigned long usp)
 {
        regs->pc = pc;
@@ -68,7 +68,7 @@ extern inline void start_thread (struct pt_regs *regs,
 }
 
 /* Free all resources held by a thread. */
-extern inline void release_thread (struct task_struct *dead_task)
+static inline void release_thread (struct task_struct *dead_task)
 {
 }
 
index df6cdecf6c1f12522bb3f49ff30ba20ae9811309..735baaf3a16e8fe7478f8307a10be49f1c6a7a09 100644 (file)
@@ -24,7 +24,7 @@ struct semaphore {
 #define DECLARE_MUTEX(name)            __DECLARE_SEMAPHORE_GENERIC (name,1)
 #define DECLARE_MUTEX_LOCKED(name)     __DECLARE_SEMAPHORE_GENERIC (name,0)
 
-extern inline void sema_init (struct semaphore *sem, int val)
+static inline void sema_init (struct semaphore *sem, int val)
 {
        *sem = (struct semaphore)__SEMAPHORE_INITIALIZER((*sem),val);
 }
@@ -52,14 +52,14 @@ extern int  __down_interruptible (struct semaphore * sem);
 extern int  __down_trylock (struct semaphore * sem);
 extern void __up (struct semaphore * sem);
 
-extern inline void down (struct semaphore * sem)
+static inline void down (struct semaphore * sem)
 {
        might_sleep();
        if (atomic_dec_return (&sem->count) < 0)
                __down (sem);
 }
 
-extern inline int down_interruptible (struct semaphore * sem)
+static inline int down_interruptible (struct semaphore * sem)
 {
        int ret = 0;
        might_sleep();
@@ -68,7 +68,7 @@ extern inline int down_interruptible (struct semaphore * sem)
        return ret;
 }
 
-extern inline int down_trylock (struct semaphore *sem)
+static inline int down_trylock (struct semaphore *sem)
 {
        int ret = 0;
        if (atomic_dec_return (&sem->count) < 0)
@@ -76,7 +76,7 @@ extern inline int down_trylock (struct semaphore *sem)
        return ret;
 }
 
-extern inline void up (struct semaphore * sem)
+static inline void up (struct semaphore * sem)
 {
        if (atomic_inc_return (&sem->count) <= 0)
                __up (sem);
index 20f4c738c04efea475020764849ce8d1009488fa..107decbd6e6cfc038a1729a77154f97ed5f65204 100644 (file)
@@ -81,7 +81,7 @@ static inline int irqs_disabled (void)
   ((__typeof__ (*(ptr)))__xchg ((unsigned long)(with), (ptr), sizeof (*(ptr))))
 #define tas(ptr) (xchg ((ptr), 1))
 
-extern inline unsigned long __xchg (unsigned long with,
+static inline unsigned long __xchg (unsigned long with,
                                    __volatile__ void *ptr, int size)
 {
        unsigned long tmp, flags;
index 501e4498172c02e274ece2eb57a10126f1a5a47a..5f2f85f636ea74bc0fe019ef51c53e978ac9a348 100644 (file)
@@ -56,12 +56,12 @@ static inline void flush_tlb_range(struct vm_area_struct *vma,
        BUG ();
 }
 
-extern inline void flush_tlb_kernel_page(unsigned long addr)
+static inline void flush_tlb_kernel_page(unsigned long addr)
 {
        BUG ();
 }
 
-extern inline void flush_tlb_pgtables(struct mm_struct *mm,
+static inline void flush_tlb_pgtables(struct mm_struct *mm,
                                      unsigned long start, unsigned long end)
 {
        BUG ();
index 188b28597cf1f680a96f271fa7e3244ffdc74831..64563c409bb2219f2fcb24fa06e5f540a1aa0c59 100644 (file)
@@ -14,7 +14,7 @@
 #define VERIFY_READ    0
 #define VERIFY_WRITE   1
 
-extern inline int access_ok (int type, const void *addr, unsigned long size)
+static inline int access_ok (int type, const void *addr, unsigned long size)
 {
        /* XXX I guess we should check against real ram bounds at least, and
           possibly make sure ADDR is not within the kernel.
index 65e38362142b8bcdd9ae7d5a14b13abfd3e2287a..e30b18653a94bf8cde19b2573888692d1d46d55a 100644 (file)
@@ -82,19 +82,19 @@ extern int __bug_unaligned_x(void *ptr);
        })
 
 
-extern inline void __put_unaligned_2(__u32 __v, register __u8 *__p)
+static inline void __put_unaligned_2(__u32 __v, register __u8 *__p)
 {
        *__p++ = __v;
        *__p++ = __v >> 8;
 }
 
-extern inline void __put_unaligned_4(__u32 __v, register __u8 *__p)
+static inline void __put_unaligned_4(__u32 __v, register __u8 *__p)
 {
        __put_unaligned_2(__v >> 16, __p + 2);
        __put_unaligned_2(__v, __p);
 }
 
-extern inline void __put_unaligned_8(const unsigned long long __v, register __u8 *__p)
+static inline void __put_unaligned_8(const unsigned long long __v, register __u8 *__p)
 {
        /*
         * tradeoff: 8 bytes of stack for all unaligned puts (2
index a60a35e792226248cbbcc4e4e44ff266b7e5a04a..43862cd6a569d7a20886325f1a19a53a51782925 100644 (file)
@@ -149,6 +149,8 @@ extern void set_personality_64bit(void);
  */
 #define elf_read_implies_exec(ex, executable_stack)    (executable_stack != EXSTACK_DISABLE_X)
 
+struct task_struct;
+
 extern int dump_task_regs (struct task_struct *, elf_gregset_t *);
 extern int dump_task_fpu (struct task_struct *, elf_fpregset_t *);
 
index 6d6d883fdf6d0f2862d3a41771f15ba09ed04c5a..4dd7a7e148d450d6ba93c347c655cc8975ac8230 100644 (file)
@@ -25,6 +25,7 @@
  */
 #include <linux/types.h>
 #include <linux/ptrace.h>
+#include <linux/percpu.h>
 
 struct pt_regs;
 
@@ -48,6 +49,24 @@ struct arch_specific_insn {
        kprobe_opcode_t *insn;
 };
 
+struct prev_kprobe {
+       struct kprobe *kp;
+       unsigned long status;
+       unsigned long old_rflags;
+       unsigned long saved_rflags;
+};
+
+/* per-cpu kprobe control block */
+struct kprobe_ctlblk {
+       unsigned long kprobe_status;
+       unsigned long kprobe_old_rflags;
+       unsigned long kprobe_saved_rflags;
+       long *jprobe_saved_rsp;
+       struct pt_regs jprobe_saved_regs;
+       kprobe_opcode_t jprobes_stack[MAX_STACK_SIZE];
+       struct prev_kprobe prev_kprobe;
+};
+
 /* trap3/1 are intr gates for kprobes.  So, restore the status of IF,
  * if necessary, before executing the original int3/1 (trap) handler.
  */
index 7a07196a72022f56ebef52ace38ec35d88be7c9e..7309fffeec9a04fe0b45abd0b7a39060a9abe19d 100644 (file)
@@ -105,6 +105,8 @@ static inline void pgd_clear (pgd_t * pgd)
 
 #define ptep_get_and_clear(mm,addr,xp) __pte(xchg(&(xp)->pte, 0))
 
+struct mm_struct;
+
 static inline pte_t ptep_get_and_clear_full(struct mm_struct *mm, unsigned long addr, pte_t *ptep, int full)
 {
        pte_t pte;
index 64f1f53874fe4b65c875182220f1395bc4b01f82..de0667453b2ecb28ef6f6cac3b70a31af29b4282 100644 (file)
@@ -209,6 +209,8 @@ extern void xtensa_elf_core_copy_regs (xtensa_gregset_t *, struct pt_regs *);
 
 #define SET_PERSONALITY(ex, ibcs2) set_personality(PER_LINUX_32BIT)
 
+struct task_struct;
+
 extern void do_copy_regs (xtensa_gregset_t*, struct pt_regs*,
                          struct task_struct*);
 extern void do_restore_regs (xtensa_gregset_t*, struct pt_regs*,
index 987e3b802313561d837b7f43f1e53133db0d0656..7b15afb70c5678b624c55a2a85c715b0e67d241e 100644 (file)
@@ -278,6 +278,8 @@ static inline void update_pte(pte_t *ptep, pte_t pteval)
 #endif
 }
 
+struct mm_struct;
+
 static inline void
 set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pteval)
 {
@@ -294,6 +296,7 @@ set_pmd(pmd_t *pmdp, pmd_t pmdval)
 #endif
 }
 
+struct vm_area_struct;
 
 static inline int
 ptep_test_and_clear_young(struct vm_area_struct *vma, unsigned long addr,
index 2a10e193b92972504e12c68199cc5691cd084a04..f10c3487cd4c5cb26b18d2e92df574395c349594 100644 (file)
@@ -38,6 +38,7 @@ struct semaphore {
 static inline void sema_init (struct semaphore *sem, int val)
 {
        atomic_set(&sem->count, val);
+       sem->sleepers = 0;
        init_waitqueue_head(&sem->wait);
 }
 
index 0decf66117c16c995a35ab8017440dc73368972c..403d71dcb7c818beb2b43101af33d6133f6d5622 100644 (file)
@@ -183,6 +183,7 @@ struct kioctx {
        struct list_head        active_reqs;    /* used for cancellation */
        struct list_head        run_list;       /* used for kicked reqs */
 
+       /* sys_io_setup currently limits this to an unsigned int */
        unsigned                max_reqs;
 
        struct aio_ring_info    ring_info;
@@ -234,7 +235,7 @@ static inline struct kiocb *list_kiocb(struct list_head *h)
 }
 
 /* for sysctl: */
-extern atomic_t aio_nr;
-extern unsigned aio_max_nr;
+extern unsigned long aio_nr;
+extern unsigned long aio_max_nr;
 
 #endif /* __LINUX__AIO_H */
diff --git a/include/linux/cn_proc.h b/include/linux/cn_proc.h
new file mode 100644 (file)
index 0000000..70ab563
--- /dev/null
@@ -0,0 +1,127 @@
+/*
+ * cn_proc.h - process events connector
+ *
+ * Copyright (C) Matt Helsley, IBM Corp. 2005
+ * Based on cn_fork.h by Nguyen Anh Quynh and Guillaume Thouvenin
+ * Original copyright notice follows:
+ * Copyright (C) 2005 Nguyen Anh Quynh <aquynh@gmail.com>
+ * Copyright (C) 2005 Guillaume Thouvenin <guillaume.thouvenin@bull.net>
+ *
+ * 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
+ */
+
+#ifndef CN_PROC_H
+#define CN_PROC_H
+
+#include <linux/types.h>
+#include <linux/connector.h>
+
+/*
+ * Userspace sends this enum to register with the kernel that it is listening
+ * for events on the connector.
+ */
+enum proc_cn_mcast_op {
+       PROC_CN_MCAST_LISTEN = 1,
+       PROC_CN_MCAST_IGNORE = 2
+};
+
+/*
+ * From the user's point of view, the process
+ * ID is the thread group ID and thread ID is the internal
+ * kernel "pid". So, fields are assigned as follow:
+ *
+ *  In user space     -  In  kernel space
+ *
+ * parent process ID  =  parent->tgid
+ * parent thread  ID  =  parent->pid
+ * child  process ID  =  child->tgid
+ * child  thread  ID  =  child->pid
+ */
+
+struct proc_event {
+       enum what {
+               /* Use successive bits so the enums can be used to record
+                * sets of events as well
+                */
+               PROC_EVENT_NONE = 0x00000000,
+               PROC_EVENT_FORK = 0x00000001,
+               PROC_EVENT_EXEC = 0x00000002,
+               PROC_EVENT_UID  = 0x00000004,
+               PROC_EVENT_GID  = 0x00000040,
+               /* "next" should be 0x00000400 */
+               /* "last" is the last process event: exit */
+               PROC_EVENT_EXIT = 0x80000000
+       } what;
+       __u32 cpu;
+       union { /* must be last field of proc_event struct */
+               struct {
+                       __u32 err;
+               } ack;
+
+               struct fork_proc_event {
+                       pid_t parent_pid;
+                       pid_t parent_tgid;
+                       pid_t child_pid;
+                       pid_t child_tgid;
+               } fork;
+
+               struct exec_proc_event {
+                       pid_t process_pid;
+                       pid_t process_tgid;
+               } exec;
+
+               struct id_proc_event {
+                       pid_t process_pid;
+                       pid_t process_tgid;
+                       union {
+                               uid_t ruid; /* current->uid */
+                               gid_t rgid; /* current->gid */
+                       } r;
+                       union {
+                               uid_t euid;
+                               gid_t egid;
+                       } e;
+               } id;
+
+               struct exit_proc_event {
+                       pid_t process_pid;
+                       pid_t process_tgid;
+                       __u32 exit_code, exit_signal;
+               } exit;
+       } event_data;
+};
+
+#ifdef __KERNEL__
+#ifdef CONFIG_PROC_EVENTS
+void proc_fork_connector(struct task_struct *task);
+void proc_exec_connector(struct task_struct *task);
+void proc_id_connector(struct task_struct *task, int which_id);
+void proc_exit_connector(struct task_struct *task);
+#else
+static inline void proc_fork_connector(struct task_struct *task)
+{}
+
+static inline void proc_exec_connector(struct task_struct *task)
+{}
+
+static inline void proc_id_connector(struct task_struct *task,
+                                    int which_id)
+{}
+
+static inline void proc_exit_connector(struct task_struct *task)
+{}
+#endif /* CONFIG_PROC_EVENTS */
+#endif /* __KERNEL__ */
+#endif /* CN_PROC_H */
index 95952cc1f525b509b365191738911c2d992d19ac..c5769c6585f4cf9c623b8e086ba830310cff3256 100644 (file)
 #define CN_IDX_CONNECTOR               0xffffffff
 #define CN_VAL_CONNECTOR               0xffffffff
 
+/*
+ * Process Events connector unique ids -- used for message routing
+ */
+#define CN_IDX_PROC                    0x1
+#define CN_VAL_PROC                    0x1
+
 #define CN_NETLINK_USERS               1
 
 /*
index 725be90ef55ecb1c239707c8d98297f8ad0087dd..f8e5587a0f92178cf3bd1604f4b4c7cc27cd3f68 100644 (file)
@@ -9,6 +9,8 @@
  * to achieve effects such as fast scrolling by changing the origin.
  */
 
+#include <linux/vt.h>
+
 struct vt_struct;
 
 #define NPAR 16
index c698055266d062b09fa7e19b447144c67fd82c22..e7ff98e395f620c5b17625683176bf9d85ab8fdb 100644 (file)
@@ -810,7 +810,6 @@ struct fb_info {
 extern int fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var); 
 extern int fb_pan_display(struct fb_info *info, struct fb_var_screeninfo *var); 
 extern int fb_blank(struct fb_info *info, int blank);
-extern int soft_cursor(struct fb_info *info, struct fb_cursor *cursor);
 extern void cfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect); 
 extern void cfb_copyarea(struct fb_info *info, const struct fb_copyarea *area); 
 extern void cfb_imageblit(struct fb_info *info, const struct fb_image *image);
@@ -898,11 +897,13 @@ extern struct fb_videomode *fb_match_mode(struct fb_var_screeninfo *var,
                                          struct list_head *head);
 extern struct fb_videomode *fb_find_best_mode(struct fb_var_screeninfo *var,
                                              struct list_head *head);
-extern struct fb_videomode *fb_find_nearest_mode(struct fb_var_screeninfo *var,
+extern struct fb_videomode *fb_find_nearest_mode(struct fb_videomode *mode,
                                                 struct list_head *head);
 extern void fb_destroy_modelist(struct list_head *head);
 extern void fb_videomode_to_modelist(struct fb_videomode *modedb, int num,
                                     struct list_head *head);
+extern struct fb_videomode *fb_find_best_display(struct fb_monspecs *specs,
+                                                struct list_head *head);
 
 /* drivers/video/fbcmap.c */
 extern int fb_alloc_cmap(struct fb_cmap *cmap, int len, int transp);
index f5bbd4c508b3da00b3af27dc20f2178996cc9496..d3b1a15d5f21b378731bd2fca44edd2be5d3dc5d 100644 (file)
@@ -59,9 +59,9 @@ extern void FASTCALL(set_close_on_exec(unsigned int fd, int flag));
 extern void put_filp(struct file *);
 extern int get_unused_fd(void);
 extern void FASTCALL(put_unused_fd(unsigned int fd));
-struct kmem_cache_s;
-extern void filp_ctor(void * objp, struct kmem_cache_s *cachep, unsigned long cflags);
-extern void filp_dtor(void * objp, struct kmem_cache_s *cachep, unsigned long dflags);
+struct kmem_cache;
+extern void filp_ctor(void * objp, struct kmem_cache *cachep, unsigned long cflags);
+extern void filp_dtor(void * objp, struct kmem_cache *cachep, unsigned long dflags);
 
 extern struct file ** alloc_fd_array(int);
 extern void free_fd_array(struct file **, int);
index 53b129f07f6f294a896ce4bcc62133641f79d9ef..8aac48c37f3db1c7ef6fa00383e1a41a987d44d2 100644 (file)
@@ -31,6 +31,7 @@ struct font_desc {
 #define SUN12x22_IDX   7
 #define ACORN8x8_IDX   8
 #define        MINI4x6_IDX     9
+#define        RL_IDX  10
 
 extern const struct font_desc  font_vga_8x8,
                        font_vga_8x16,
@@ -41,6 +42,7 @@ extern const struct font_desc font_vga_8x8,
                        font_sun_8x16,
                        font_sun_12x22,
                        font_acorn_8x8,
+                       font_rl,
                        font_mini_4x6;
 
 /* Find a font with a specific name */
index 6d6226732c93ba96e5edf946e2c934f3e23b390b..9a593ef262ef183807bb094a0fc494e399b6aacb 100644 (file)
@@ -264,6 +264,7 @@ typedef void (dio_iodone_t)(struct kiocb *iocb, loff_t offset,
 #define ATTR_ATTR_FLAG 1024
 #define ATTR_KILL_SUID 2048
 #define ATTR_KILL_SGID 4096
+#define ATTR_FILE      8192
 
 /*
  * This is the Inode Attributes structure, used for notify_change().  It
@@ -283,6 +284,13 @@ struct iattr {
        struct timespec ia_atime;
        struct timespec ia_mtime;
        struct timespec ia_ctime;
+
+       /*
+        * Not an attribute, but an auxilary info for filesystems wanting to
+        * implement an ftruncate() like method.  NOTE: filesystem should
+        * check for (ia_valid & ATTR_FILE), and not for (ia_file != NULL).
+        */
+       struct file     *ia_file;
 };
 
 /*
@@ -1088,6 +1096,8 @@ int sync_inode(struct inode *inode, struct writeback_control *wbc);
  * @get_name:       find the name for a given inode in a given directory
  * @get_parent:     find the parent of a given directory
  * @get_dentry:     find a dentry for the inode given a file handle sub-fragment
+ * @find_exported_dentry:
+ *     set by the exporting module to a standard helper function.
  *
  * Description:
  *    The export_operations structure provides a means for nfsd to communicate
@@ -1288,7 +1298,7 @@ static inline int break_lease(struct inode *inode, unsigned int mode)
 
 /* fs/open.c */
 
-extern int do_truncate(struct dentry *, loff_t start);
+extern int do_truncate(struct dentry *, loff_t start, struct file *filp);
 extern long do_sys_open(const char __user *filename, int flags, int mode);
 extern struct file *filp_open(const char *, int, int);
 extern struct file * dentry_open(struct dentry *, struct vfsmount *, int);
index f98854c2abd7a9dffa35a5e091d954e81c34cfb0..b76b558b03d481376c6a41d75d42786a2dae168e 100644 (file)
@@ -14,7 +14,7 @@
 #define FUSE_KERNEL_VERSION 7
 
 /** Minor version number of this interface */
-#define FUSE_KERNEL_MINOR_VERSION 2
+#define FUSE_KERNEL_MINOR_VERSION 3
 
 /** The node ID of the root inode */
 #define FUSE_ROOT_ID 1
@@ -61,6 +61,7 @@ struct fuse_kstatfs {
 #define FATTR_SIZE     (1 << 3)
 #define FATTR_ATIME    (1 << 4)
 #define FATTR_MTIME    (1 << 5)
+#define FATTR_FH       (1 << 6)
 
 /**
  * Flags returned by the OPEN request
@@ -99,7 +100,9 @@ enum fuse_opcode {
        FUSE_OPENDIR       = 27,
        FUSE_READDIR       = 28,
        FUSE_RELEASEDIR    = 29,
-       FUSE_FSYNCDIR      = 30
+       FUSE_FSYNCDIR      = 30,
+       FUSE_ACCESS        = 34,
+       FUSE_CREATE        = 35
 };
 
 /* Conservative buffer size for the client */
@@ -152,12 +155,25 @@ struct fuse_link_in {
 struct fuse_setattr_in {
        __u32   valid;
        __u32   padding;
-       struct fuse_attr attr;
+       __u64   fh;
+       __u64   size;
+       __u64   unused1;
+       __u64   atime;
+       __u64   mtime;
+       __u64   unused2;
+       __u32   atimensec;
+       __u32   mtimensec;
+       __u32   unused3;
+       __u32   mode;
+       __u32   unused4;
+       __u32   uid;
+       __u32   gid;
+       __u32   unused5;
 };
 
 struct fuse_open_in {
        __u32   flags;
-       __u32   padding;
+       __u32   mode;
 };
 
 struct fuse_open_out {
@@ -222,6 +238,11 @@ struct fuse_getxattr_out {
        __u32   padding;
 };
 
+struct fuse_access_in {
+       __u32   mask;
+       __u32   padding;
+};
+
 struct fuse_init_in_out {
        __u32   major;
        __u32   minor;
index 18d010bee635dafc4156b54234c1c89db14737e1..cd6bd001ba4edbc68dfc5b52f08ef3bb832c785e 100644 (file)
@@ -94,7 +94,7 @@ extern struct resource iomem_resource;
 extern int request_resource(struct resource *root, struct resource *new);
 extern struct resource * ____request_resource(struct resource *root, struct resource *new);
 extern int release_resource(struct resource *new);
-extern int insert_resource(struct resource *parent, struct resource *new);
+extern __deprecated_for_modules int insert_resource(struct resource *parent, struct resource *new);
 extern int allocate_resource(struct resource *root, struct resource *new,
                             unsigned long size,
                             unsigned long min, unsigned long max,
index 938d55b813a5f600050fcc557331195b036fa12c..d6276e60b3bf3672343046f49c63d0af3e2b9987 100644 (file)
@@ -256,10 +256,7 @@ struct ipmi_recv_msg
 };
 
 /* Allocate and free the receive message. */
-static inline void ipmi_free_recv_msg(struct ipmi_recv_msg *msg)
-{
-       msg->done(msg);
-}
+void ipmi_free_recv_msg(struct ipmi_recv_msg *msg);
 
 struct ipmi_user_hndl
 {
index 69681c3b1f05f8fac09efb8ad5334c60b65686c0..c516382fbec2fa5fb5871937ba0bab6de48d4dfd 100644 (file)
@@ -10,6 +10,7 @@
  */
 
 #include <linux/config.h>
+#include <asm/smp.h>           /* cpu_online_map */
 
 #if !defined(CONFIG_ARCH_S390)
 
index be197eb900777167fedecdce824be0c2275a78d5..aa56172c6fed9533136aab5f98a43a2912bf19eb 100644 (file)
@@ -611,6 +611,9 @@ struct transaction_s
  * @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 journal_commit_transaction
+ * @j_wbufsize: maximum number of buffer_heads allowed in j_wbuf, the
+ *     number that will fit in j_blocksize
  * @j_private: An opaque pointer to fs-private information.
  */
 
index f1925ccc9fe1696496cdad0f9f2bcf583bf2eb5c..b1e407a4fbda1ec9b101c5e0bd2c3c4378b7bb5b 100644 (file)
@@ -168,7 +168,7 @@ static inline void console_verbose(void)
 
 extern void bust_spinlocks(int yes);
 extern int oops_in_progress;           /* If set, an oops, panic(), BUG() or die() is in progress */
-extern int panic_timeout;
+extern __deprecated_for_modules int panic_timeout;
 extern int panic_on_oops;
 extern int tainted;
 extern const char *print_tainted(void);
@@ -266,7 +266,6 @@ extern void dump_stack(void);
 
 /**
  * container_of - cast a member of a structure out to the containing structure
- *
  * @ptr:       the pointer to the member.
  * @type:      the type of the container struct this is embedded in.
  * @member:    the name of the member within the struct.
index dba27749b428368f159a91666797c218bfd60521..a484572c302e10fd43a81aa3cdffd9c2be6eb07b 100644 (file)
@@ -6,6 +6,7 @@
 #include <linux/smp.h>
 #include <linux/threads.h>
 #include <linux/percpu.h>
+#include <linux/cpumask.h>
 #include <asm/cputime.h>
 
 /*
@@ -43,11 +44,10 @@ extern unsigned long long nr_context_switches(void);
  */
 static inline int kstat_irqs(int irq)
 {
-       int i, sum=0;
+       int cpu, sum = 0;
 
-       for (i = 0; i < NR_CPUS; i++)
-               if (cpu_possible(i))
-                       sum += kstat_cpu(i).irqs[irq];
+       for_each_cpu(cpu)
+               sum += kstat_cpu(cpu).irqs[irq];
 
        return sum;
 }
index e30afdca79174f9a01b0b538dca138f62bf697f2..e373c4a9de53601a3f6e85bf1623a2b1d896f36c 100644 (file)
@@ -33,6 +33,9 @@
 #include <linux/list.h>
 #include <linux/notifier.h>
 #include <linux/smp.h>
+#include <linux/percpu.h>
+#include <linux/spinlock.h>
+#include <linux/rcupdate.h>
 
 #include <asm/kprobes.h>
 
@@ -106,6 +109,9 @@ struct jprobe {
        kprobe_opcode_t *entry; /* probe handling code to jump to */
 };
 
+DECLARE_PER_CPU(struct kprobe *, current_kprobe);
+DECLARE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
+
 #ifdef ARCH_SUPPORTS_KRETPROBES
 extern void arch_prepare_kretprobe(struct kretprobe *rp, struct pt_regs *regs);
 #else /* ARCH_SUPPORTS_KRETPROBES */
@@ -142,17 +148,7 @@ struct kretprobe_instance {
 };
 
 #ifdef CONFIG_KPROBES
-/* Locks kprobe: irq must be disabled */
-void lock_kprobes(void);
-void unlock_kprobes(void);
-
-/* kprobe running now on this CPU? */
-static inline int kprobe_running(void)
-{
-       extern unsigned int kprobe_cpu;
-       return kprobe_cpu == smp_processor_id();
-}
-
+extern spinlock_t kretprobe_lock;
 extern int arch_prepare_kprobe(struct kprobe *p);
 extern void arch_copy_kprobe(struct kprobe *p);
 extern void arch_arm_kprobe(struct kprobe *p);
@@ -163,10 +159,26 @@ extern void show_registers(struct pt_regs *regs);
 extern kprobe_opcode_t *get_insn_slot(void);
 extern void free_insn_slot(kprobe_opcode_t *slot);
 
-/* Get the kprobe at this addr (if any).  Must have called lock_kprobes */
+/* Get the kprobe at this addr (if any) - called with preemption disabled */
 struct kprobe *get_kprobe(void *addr);
 struct hlist_head * kretprobe_inst_table_head(struct task_struct *tsk);
 
+/* kprobe_running() will just return the current_kprobe on this CPU */
+static inline struct kprobe *kprobe_running(void)
+{
+       return (__get_cpu_var(current_kprobe));
+}
+
+static inline void reset_current_kprobe(void)
+{
+       __get_cpu_var(current_kprobe) = NULL;
+}
+
+static inline struct kprobe_ctlblk *get_kprobe_ctlblk(void)
+{
+       return (&__get_cpu_var(kprobe_ctlblk));
+}
+
 int register_kprobe(struct kprobe *p);
 void unregister_kprobe(struct kprobe *p);
 int setjmp_pre_handler(struct kprobe *, struct pt_regs *);
@@ -183,9 +195,9 @@ void add_rp_inst(struct kretprobe_instance *ri);
 void kprobe_flush_task(struct task_struct *tk);
 void recycle_rp_inst(struct kretprobe_instance *ri);
 #else /* CONFIG_KPROBES */
-static inline int kprobe_running(void)
+static inline struct kprobe *kprobe_running(void)
 {
-       return 0;
+       return NULL;
 }
 static inline int register_kprobe(struct kprobe *p)
 {
index 084971f333fe30e7ffc312258d5cfb47afe6d1b8..fbfca73355a3a6791a3f2afb20fa41823c5f6fc6 100644 (file)
@@ -601,7 +601,7 @@ static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h)
  * or hlist_del_rcu(), running on this same list.
  * However, it is perfectly legal to run concurrently with
  * the _rcu list-traversal primitives, such as
- * hlist_for_each_rcu(), used to prevent memory-consistency
+ * hlist_for_each_entry_rcu(), used to prevent memory-consistency
  * problems on Alpha CPUs.  Regardless of the type of CPU, the
  * list-traversal primitive must be guarded by rcu_read_lock().
  */
@@ -650,7 +650,7 @@ static inline void hlist_add_after(struct hlist_node *n,
  * or hlist_del_rcu(), running on this same list.
  * However, it is perfectly legal to run concurrently with
  * the _rcu list-traversal primitives, such as
- * hlist_for_each_rcu(), used to prevent memory-consistency
+ * hlist_for_each_entry_rcu(), used to prevent memory-consistency
  * problems on Alpha CPUs.
  */
 static inline void hlist_add_before_rcu(struct hlist_node *n,
@@ -675,7 +675,7 @@ static inline void hlist_add_before_rcu(struct hlist_node *n,
  * or hlist_del_rcu(), running on this same list.
  * However, it is perfectly legal to run concurrently with
  * the _rcu list-traversal primitives, such as
- * hlist_for_each_rcu(), used to prevent memory-consistency
+ * hlist_for_each_entry_rcu(), used to prevent memory-consistency
  * problems on Alpha CPUs.
  */
 static inline void hlist_add_after_rcu(struct hlist_node *prev,
@@ -699,11 +699,6 @@ static inline void hlist_add_after_rcu(struct hlist_node *prev,
        for (pos = (head)->first; pos && ({ n = pos->next; 1; }); \
             pos = n)
 
-#define hlist_for_each_rcu(pos, head) \
-       for ((pos) = (head)->first; \
-               rcu_dereference((pos)) && ({ prefetch((pos)->next); 1; }); \
-               (pos) = (pos)->next)
-
 /**
  * hlist_for_each_entry        - iterate over list of given type
  * @tpos:      the type * to use as a loop counter.
@@ -756,7 +751,7 @@ static inline void hlist_add_after_rcu(struct hlist_node *prev,
 
 /**
  * hlist_for_each_entry_rcu - iterate over rcu list of given type
- * @pos:       the type * to use as a loop counter.
+ * @tpos:      the type * to use as a loop counter.
  * @pos:       the &struct hlist_node to use as a loop counter.
  * @head:      the head for your list.
  * @member:    the name of the hlist_node within the struct.
index 0def328ab5cfbae5fc44a769f8bc30f5257a5b85..9a424383e6c60064fdb76ae8b0c7895351da69a0 100644 (file)
@@ -54,6 +54,9 @@ struct memory_block {
  */
 #define        MEM_MAPPING_INVALID     (1<<3)
 
+struct notifier_block;
+struct mem_section;
+
 #ifndef CONFIG_MEMORY_HOTPLUG
 static inline int memory_dev_init(void)
 {
index 5c1fb0a2e806bb4d13bd7b716c022bad64f59523..7b115feca4df23064dfd3ee80a66a9e638b0dcbd 100644 (file)
@@ -932,13 +932,13 @@ int write_one_page(struct page *page, int wait);
                                         * turning readahead off */
 
 int do_page_cache_readahead(struct address_space *mapping, struct file *filp,
-                       unsigned long offset, unsigned long nr_to_read);
+                       pgoff_t offset, unsigned long nr_to_read);
 int force_page_cache_readahead(struct address_space *mapping, struct file *filp,
-                       unsigned long offset, unsigned long nr_to_read);
-unsigned long  page_cache_readahead(struct address_space *mapping,
+                       pgoff_t offset, unsigned long nr_to_read);
+unsigned long page_cache_readahead(struct address_space *mapping,
                          struct file_ra_state *ra,
                          struct file *filp,
-                         unsigned long offset,
+                         pgoff_t offset,
                          unsigned long size);
 void handle_ra_miss(struct address_space *mapping, 
                    struct file_ra_state *ra, pgoff_t offset);
index 4e981585a89a349f9444ffdbfe9588cbf66d1671..d6a41e6577f61a3b2729247af897532ab3b44ea3 100644 (file)
@@ -71,6 +71,7 @@ typedef enum {
  * @SOCK_RAW: raw socket
  * @SOCK_RDM: reliably-delivered message
  * @SOCK_SEQPACKET: sequential packet socket
+ * @SOCK_DCCP: Datagram Congestion Control Protocol socket
  * @SOCK_PACKET: linux specific way of getting packets at the dev level.
  *               For writing rarp and other similar things on the user level.
  *
index 6d5a24f3fc6d902aad24b9c532d15dec3a863da1..51c231a1e5a669457ef5a4aef34207ad74a78b37 100644 (file)
@@ -60,7 +60,7 @@ typedef int (*nfsd_dirop_t)(struct inode *, struct dentry *, int, int);
 extern struct svc_program      nfsd_program;
 extern struct svc_version      nfsd_version2, nfsd_version3,
                                nfsd_version4;
-
+extern struct svc_serv         *nfsd_serv;
 /*
  * Function prototypes.
  */
index e65c9db6d13f975952850a04e73dab753f0e8097..781efbf94ed359c47b4a9db04aa6d0632a3da787 100644 (file)
 #define NFSCTL_GETFD           7       /* get an fh by path (used by mountd) */
 #define        NFSCTL_GETFS            8       /* get an fh by path with max FH len */
 
+/*
+ * Macros used to set version
+ */
+#define NFSCTL_VERSET(_cltbits, _v)   ((_cltbits) |=  (1 << (_v)))
+#define NFSCTL_VERUNSET(_cltbits, _v) ((_cltbits) &= ~(1 << (_v)))
+#define NFSCTL_VERISSET(_cltbits, _v) ((_cltbits) & (1 << (_v)))
+
+#if defined(CONFIG_NFSD_V4)
+#define        NFSCTL_VERALL   (0x1c /* 0b011100 */)
+#elif defined(CONFIG_NFSD_V3)
+#define        NFSCTL_VERALL   (0x0c /* 0b001100 */)
+#else
+#define        NFSCTL_VERALL   (0x04 /* 0b000100 */)
+#endif
+
 /* SVC */
 struct nfsctl_svc {
        unsigned short          svc_port;
@@ -120,6 +135,8 @@ extern int          exp_delclient(struct nfsctl_client *ncp);
 extern int             exp_export(struct nfsctl_export *nxp);
 extern int             exp_unexport(struct nfsctl_export *nxp);
 
+extern unsigned int nfsd_versbits;
+
 #endif /* __KERNEL__ */
 
 #endif /* NFSD_SYSCALL_H */
index 21e18ce7ca63bc047b9a31be8da1700621326c15..3c2a71b43bacc38a33ad9b8ab3efa4aaf61d8190 100644 (file)
@@ -42,7 +42,7 @@ struct nfsd3_writeargs {
        __u64                   offset;
        __u32                   count;
        int                     stable;
-       int                     len;
+       __u32                   len;
        struct kvec             vec[RPCSVC_MAXPAGES];
        int                     vlen;
 };
index 8cadfdeef67494bc4b615b96ac25c054597287b0..9a96f05883935a32955b216fcc3184bf162b0a85 100644 (file)
 #define PCI_DEVICE_ID_MATROX_MIL       0x0519
 #define PCI_DEVICE_ID_MATROX_MYS       0x051A
 #define PCI_DEVICE_ID_MATROX_MIL_2     0x051b
+#define PCI_DEVICE_ID_MATROX_MYS_AGP   0x051e
 #define PCI_DEVICE_ID_MATROX_MIL_2_AGP 0x051f
 #define PCI_DEVICE_ID_MATROX_MGA_IMP   0x0d10
 #define PCI_DEVICE_ID_MATROX_G100_MM   0x1000
index aadbac29103cfc7601291e8fc0415f46d6cafc85..584d57cb393a1e1cc7339e11b7d747882016b85c 100644 (file)
@@ -353,7 +353,6 @@ struct pnp_protocol {
 int pnp_register_protocol(struct pnp_protocol *protocol);
 void pnp_unregister_protocol(struct pnp_protocol *protocol);
 int pnp_add_device(struct pnp_dev *dev);
-void pnp_remove_device(struct pnp_dev *dev);
 int pnp_device_attach(struct pnp_dev *pnp_dev);
 void pnp_device_detach(struct pnp_dev *pnp_dev);
 extern struct list_head pnp_global;
@@ -399,7 +398,6 @@ static inline int pnp_register_protocol(struct pnp_protocol *protocol) { return
 static inline void pnp_unregister_protocol(struct pnp_protocol *protocol) { }
 static inline int pnp_init_device(struct pnp_dev *dev) { return -ENODEV; }
 static inline int pnp_add_device(struct pnp_dev *dev) { return -ENODEV; }
-static inline void pnp_remove_device(struct pnp_dev *dev) { }
 static inline int pnp_device_attach(struct pnp_dev *pnp_dev) { return -ENODEV; }
 static inline void pnp_device_detach(struct pnp_dev *pnp_dev) { ; }
 
index dc6f3647bfbc01cfcfca8192d631b12d4c9bdd80..b2b3dba1298d1fef7f1b4e4ecfba22fe142c88d2 100644 (file)
@@ -78,6 +78,8 @@
 #include <linux/compiler.h>            /* For unlikely.  */
 #include <linux/sched.h>               /* For struct task_struct.  */
 
+
+extern long arch_ptrace(struct task_struct *child, long request, long addr, long data);
 extern int ptrace_readdata(struct task_struct *tsk, unsigned long src, char __user *dst, int len);
 extern int ptrace_writedata(struct task_struct *tsk, char __user *src, unsigned long dst, int len);
 extern int ptrace_attach(struct task_struct *tsk);
index d211507ab24611b32a6edc8b6ff716505fc9d864..4f34d3d60f2ed6485d450bd4ca06cbea450e6997 100644 (file)
@@ -198,38 +198,38 @@ static __inline__ int DQUOT_OFF(struct super_block *sb)
 #define DQUOT_SYNC(sb)                         do { } while(0)
 #define DQUOT_OFF(sb)                          do { } while(0)
 #define DQUOT_TRANSFER(inode, iattr)           (0)
-extern __inline__ int DQUOT_PREALLOC_SPACE_NODIRTY(struct inode *inode, qsize_t nr)
+static inline int DQUOT_PREALLOC_SPACE_NODIRTY(struct inode *inode, qsize_t nr)
 {
        inode_add_bytes(inode, nr);
        return 0;
 }
 
-extern __inline__ int DQUOT_PREALLOC_SPACE(struct inode *inode, qsize_t nr)
+static inline int DQUOT_PREALLOC_SPACE(struct inode *inode, qsize_t nr)
 {
        DQUOT_PREALLOC_SPACE_NODIRTY(inode, nr);
        mark_inode_dirty(inode);
        return 0;
 }
 
-extern __inline__ int DQUOT_ALLOC_SPACE_NODIRTY(struct inode *inode, qsize_t nr)
+static inline int DQUOT_ALLOC_SPACE_NODIRTY(struct inode *inode, qsize_t nr)
 {
        inode_add_bytes(inode, nr);
        return 0;
 }
 
-extern __inline__ int DQUOT_ALLOC_SPACE(struct inode *inode, qsize_t nr)
+static inline int DQUOT_ALLOC_SPACE(struct inode *inode, qsize_t nr)
 {
        DQUOT_ALLOC_SPACE_NODIRTY(inode, nr);
        mark_inode_dirty(inode);
        return 0;
 }
 
-extern __inline__ void DQUOT_FREE_SPACE_NODIRTY(struct inode *inode, qsize_t nr)
+static inline void DQUOT_FREE_SPACE_NODIRTY(struct inode *inode, qsize_t nr)
 {
        inode_sub_bytes(inode, nr);
 }
 
-extern __inline__ void DQUOT_FREE_SPACE(struct inode *inode, qsize_t nr)
+static inline void DQUOT_FREE_SPACE(struct inode *inode, qsize_t nr)
 {
        DQUOT_FREE_SPACE_NODIRTY(inode, nr);
        mark_inode_dirty(inode);
index 9f0f9281f42a01628adbdb80f317172486eca583..36e5d269612fec7ce193f2edee5fd816af353650 100644 (file)
@@ -46,6 +46,7 @@ do {                                                                  \
 
 int radix_tree_insert(struct radix_tree_root *, unsigned long, void *);
 void *radix_tree_lookup(struct radix_tree_root *, unsigned long);
+void **radix_tree_lookup_slot(struct radix_tree_root *, unsigned long);
 void *radix_tree_delete(struct radix_tree_root *, unsigned long);
 unsigned int
 radix_tree_gang_lookup(struct radix_tree_root *root, void **results,
diff --git a/include/linux/rio.h b/include/linux/rio.h
new file mode 100644 (file)
index 0000000..c7e907f
--- /dev/null
@@ -0,0 +1,325 @@
+/*
+ * RapidIO interconnect services
+ * (RapidIO Interconnect Specification, http://www.rapidio.org)
+ *
+ * Copyright 2005 MontaVista Software, Inc.
+ * Matt Porter <mporter@kernel.crashing.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.
+ */
+
+#ifndef LINUX_RIO_H
+#define LINUX_RIO_H
+
+#ifdef __KERNEL__
+
+#include <linux/types.h>
+#include <linux/config.h>
+#include <linux/ioport.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/device.h>
+#include <linux/rio_regs.h>
+
+#define RIO_ANY_DESTID         0xff
+#define RIO_NO_HOPCOUNT                -1
+
+#define RIO_MAX_MPORT_RESOURCES        16
+#define RIO_MAX_DEV_RESOURCES  16
+
+#define RIO_GLOBAL_TABLE       0xff    /* Indicates access of a switch's
+                                          global routing table if it
+                                          has multiple (or per port)
+                                          tables */
+
+#define RIO_INVALID_ROUTE      0xff    /* Indicates that a route table
+                                          entry is invalid (no route
+                                          exists for the device ID) */
+
+#ifdef CONFIG_RAPIDIO_8_BIT_TRANSPORT
+#define RIO_MAX_ROUTE_ENTRIES  (1 << 8)
+#else
+#define RIO_MAX_ROUTE_ENTRIES  (1 << 16)
+#endif
+
+#define RIO_MAX_MBOX           4
+#define RIO_MAX_MSG_SIZE       0x1000
+
+/*
+ * Error values that may be returned by RIO functions.
+ */
+#define RIO_SUCCESSFUL                 0x00
+#define RIO_BAD_SIZE                   0x81
+
+/*
+ * For RIO devices, the region numbers are assigned this way:
+ *
+ *     0       RapidIO outbound doorbells
+ *      1-15   RapidIO memory regions
+ *
+ * For RIO master ports, the region number are assigned this way:
+ *
+ *     0       RapidIO inbound doorbells
+ *     1       RapidIO inbound mailboxes
+ *     1       RapidIO outbound mailboxes
+ */
+#define RIO_DOORBELL_RESOURCE  0
+#define RIO_INB_MBOX_RESOURCE  1
+#define RIO_OUTB_MBOX_RESOURCE 2
+
+extern struct bus_type rio_bus_type;
+extern struct list_head rio_devices;   /* list of all devices */
+
+struct rio_mport;
+
+/**
+ * struct rio_dev - RIO device info
+ * @global_list: Node in list of all RIO devices
+ * @net_list: Node in list of RIO devices in a network
+ * @net: Network this device is a part of
+ * @did: Device ID
+ * @vid: Vendor ID
+ * @device_rev: Device revision
+ * @asm_did: Assembly device ID
+ * @asm_vid: Assembly vendor ID
+ * @asm_rev: Assembly revision
+ * @efptr: Extended feature pointer
+ * @pef: Processing element features
+ * @swpinfo: Switch port info
+ * @src_ops: Source operation capabilities
+ * @dst_ops: Destination operation capabilities
+ * @dma_mask: Mask of bits of RIO address this device implements
+ * @rswitch: Pointer to &struct rio_switch if valid for this device
+ * @driver: Driver claiming this device
+ * @dev: Device model device
+ * @riores: RIO resources this device owns
+ * @destid: Network destination ID
+ */
+struct rio_dev {
+       struct list_head global_list;   /* node in list of all RIO devices */
+       struct list_head net_list;      /* node in per net list */
+       struct rio_net *net;    /* RIO net this device resides in */
+       u16 did;
+       u16 vid;
+       u32 device_rev;
+       u16 asm_did;
+       u16 asm_vid;
+       u16 asm_rev;
+       u16 efptr;
+       u32 pef;
+       u32 swpinfo;            /* Only used for switches */
+       u32 src_ops;
+       u32 dst_ops;
+       u64 dma_mask;
+       struct rio_switch *rswitch;     /* RIO switch info */
+       struct rio_driver *driver;      /* RIO driver claiming this device */
+       struct device dev;      /* LDM device structure */
+       struct resource riores[RIO_MAX_DEV_RESOURCES];
+       u16 destid;
+};
+
+#define rio_dev_g(n) list_entry(n, struct rio_dev, global_list)
+#define rio_dev_f(n) list_entry(n, struct rio_dev, net_list)
+#define        to_rio_dev(n) container_of(n, struct rio_dev, dev)
+
+/**
+ * struct rio_msg - RIO message event
+ * @res: Mailbox resource
+ * @mcback: Message event callback
+ */
+struct rio_msg {
+       struct resource *res;
+       void (*mcback) (struct rio_mport * mport, void *dev_id, int mbox, int slot);
+};
+
+/**
+ * struct rio_dbell - RIO doorbell event
+ * @node: Node in list of doorbell events
+ * @res: Doorbell resource
+ * @dinb: Doorbell event callback
+ * @dev_id: Device specific pointer to pass on event
+ */
+struct rio_dbell {
+       struct list_head node;
+       struct resource *res;
+       void (*dinb) (struct rio_mport *mport, void *dev_id, u16 src, u16 dst, u16 info);
+       void *dev_id;
+};
+
+/**
+ * struct rio_mport - RIO master port info
+ * @dbells: List of doorbell events
+ * @node: Node in global list of master ports
+ * @nnode: Node in network list of master ports
+ * @iores: I/O mem resource that this master port interface owns
+ * @riores: RIO resources that this master port interfaces owns
+ * @inb_msg: RIO inbound message event descriptors
+ * @outb_msg: RIO outbound message event descriptors
+ * @host_deviceid: Host device ID associated with this master port
+ * @ops: configuration space functions
+ * @id: Port ID, unique among all ports
+ * @index: Port index, unique among all port interfaces of the same type
+ * @name: Port name string
+ */
+struct rio_mport {
+       struct list_head dbells;        /* list of doorbell events */
+       struct list_head node;  /* node in global list of ports */
+       struct list_head nnode; /* node in net list of ports */
+       struct resource iores;
+       struct resource riores[RIO_MAX_MPORT_RESOURCES];
+       struct rio_msg inb_msg[RIO_MAX_MBOX];
+       struct rio_msg outb_msg[RIO_MAX_MBOX];
+       int host_deviceid;      /* Host device ID */
+       struct rio_ops *ops;    /* maintenance transaction functions */
+       unsigned char id;       /* port ID, unique among all ports */
+       unsigned char index;    /* port index, unique among all port
+                                  interfaces of the same type */
+       unsigned char name[40];
+};
+
+/**
+ * struct rio_net - RIO network info
+ * @node: Node in global list of RIO networks
+ * @devices: List of devices in this network
+ * @mports: List of master ports accessing this network
+ * @hport: Default port for accessing this network
+ * @id: RIO network ID
+ */
+struct rio_net {
+       struct list_head node;  /* node in list of networks */
+       struct list_head devices;       /* list of devices in this net */
+       struct list_head mports;        /* list of ports accessing net */
+       struct rio_mport *hport;        /* primary port for accessing net */
+       unsigned char id;       /* RIO network ID */
+};
+
+/**
+ * struct rio_switch - RIO switch info
+ * @node: Node in global list of switches
+ * @switchid: Switch ID that is unique across a network
+ * @hopcount: Hopcount to this switch
+ * @destid: Associated destid in the path
+ * @route_table: Copy of switch routing table
+ * @add_entry: Callback for switch-specific route add function
+ * @get_entry: Callback for switch-specific route get function
+ */
+struct rio_switch {
+       struct list_head node;
+       u16 switchid;
+       u16 hopcount;
+       u16 destid;
+       u8 route_table[RIO_MAX_ROUTE_ENTRIES];
+       int (*add_entry) (struct rio_mport * mport, u16 destid, u8 hopcount,
+                         u16 table, u16 route_destid, u8 route_port);
+       int (*get_entry) (struct rio_mport * mport, u16 destid, u8 hopcount,
+                         u16 table, u16 route_destid, u8 * route_port);
+};
+
+/* Low-level architecture-dependent routines */
+
+/**
+ * struct rio_ops - Low-level RIO configuration space operations
+ * @lcread: Callback to perform local (master port) read of config space.
+ * @lcwrite: Callback to perform local (master port) write of config space.
+ * @cread: Callback to perform network read of config space.
+ * @cwrite: Callback to perform network write of config space.
+ * @dsend: Callback to send a doorbell message.
+ */
+struct rio_ops {
+       int (*lcread) (int index, u32 offset, int len, u32 * data);
+       int (*lcwrite) (int index, u32 offset, int len, u32 data);
+       int (*cread) (int index, u16 destid, u8 hopcount, u32 offset, int len,
+                     u32 * data);
+       int (*cwrite) (int index, u16 destid, u8 hopcount, u32 offset, int len,
+                      u32 data);
+       int (*dsend) (int index, u16 destid, u16 data);
+};
+
+#define RIO_RESOURCE_MEM       0x00000100
+#define RIO_RESOURCE_DOORBELL  0x00000200
+#define RIO_RESOURCE_MAILBOX   0x00000400
+
+#define RIO_RESOURCE_CACHEABLE 0x00010000
+#define RIO_RESOURCE_PCI       0x00020000
+
+#define RIO_RESOURCE_BUSY      0x80000000
+
+/**
+ * struct rio_driver - RIO driver info
+ * @node: Node in list of drivers
+ * @name: RIO driver name
+ * @id_table: RIO device ids to be associated with this driver
+ * @probe: RIO device inserted
+ * @remove: RIO device removed
+ * @suspend: RIO device suspended
+ * @resume: RIO device awakened
+ * @enable_wake: RIO device enable wake event
+ * @driver: LDM driver struct
+ *
+ * Provides info on a RIO device driver for insertion/removal and
+ * power management purposes.
+ */
+struct rio_driver {
+       struct list_head node;
+       char *name;
+       const struct rio_device_id *id_table;
+       int (*probe) (struct rio_dev * dev, const struct rio_device_id * id);
+       void (*remove) (struct rio_dev * dev);
+       int (*suspend) (struct rio_dev * dev, u32 state);
+       int (*resume) (struct rio_dev * dev);
+       int (*enable_wake) (struct rio_dev * dev, u32 state, int enable);
+       struct device_driver driver;
+};
+
+#define        to_rio_driver(drv) container_of(drv,struct rio_driver, driver)
+
+/**
+ * struct rio_device_id - RIO device identifier
+ * @did: RIO device ID
+ * @vid: RIO vendor ID
+ * @asm_did: RIO assembly device ID
+ * @asm_vid: RIO assembly vendor ID
+ *
+ * Identifies a RIO device based on both the device/vendor IDs and
+ * the assembly device/vendor IDs.
+ */
+struct rio_device_id {
+       u16 did, vid;
+       u16 asm_did, asm_vid;
+};
+
+/**
+ * struct rio_route_ops - Per-switch route operations
+ * @vid: RIO vendor ID
+ * @did: RIO device ID
+ * @add_hook: Callback that adds a route entry
+ * @get_hook: Callback that gets a route entry
+ *
+ * Defines the operations that are necessary to manipulate the route
+ * tables for a particular RIO switch device.
+ */
+struct rio_route_ops {
+       u16 vid, did;
+       int (*add_hook) (struct rio_mport * mport, u16 destid, u8 hopcount,
+                        u16 table, u16 route_destid, u8 route_port);
+       int (*get_hook) (struct rio_mport * mport, u16 destid, u8 hopcount,
+                        u16 table, u16 route_destid, u8 * route_port);
+};
+
+/* Architecture and hardware-specific functions */
+extern int rio_init_mports(void);
+extern void rio_register_mport(struct rio_mport *);
+extern int rio_hw_add_outb_message(struct rio_mport *, struct rio_dev *, int,
+                                  void *, size_t);
+extern int rio_hw_add_inb_buffer(struct rio_mport *, int, void *);
+extern void *rio_hw_get_inb_message(struct rio_mport *, int);
+extern int rio_open_inb_mbox(struct rio_mport *, void *, int, int);
+extern void rio_close_inb_mbox(struct rio_mport *, int);
+extern int rio_open_outb_mbox(struct rio_mport *, void *, int, int);
+extern void rio_close_outb_mbox(struct rio_mport *, int);
+
+#endif                         /* __KERNEL__ */
+#endif                         /* LINUX_RIO_H */
diff --git a/include/linux/rio_drv.h b/include/linux/rio_drv.h
new file mode 100644 (file)
index 0000000..3bd7cce
--- /dev/null
@@ -0,0 +1,469 @@
+/*
+ * RapidIO driver services
+ *
+ * Copyright 2005 MontaVista Software, Inc.
+ * Matt Porter <mporter@kernel.crashing.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.
+ */
+
+#ifndef LINUX_RIO_DRV_H
+#define LINUX_RIO_DRV_H
+
+#ifdef __KERNEL__
+
+#include <linux/types.h>
+#include <linux/config.h>
+#include <linux/ioport.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/device.h>
+#include <linux/rio.h>
+
+extern int __rio_local_read_config_32(struct rio_mport *port, u32 offset,
+                                     u32 * data);
+extern int __rio_local_write_config_32(struct rio_mport *port, u32 offset,
+                                      u32 data);
+extern int __rio_local_read_config_16(struct rio_mport *port, u32 offset,
+                                     u16 * data);
+extern int __rio_local_write_config_16(struct rio_mport *port, u32 offset,
+                                      u16 data);
+extern int __rio_local_read_config_8(struct rio_mport *port, u32 offset,
+                                    u8 * data);
+extern int __rio_local_write_config_8(struct rio_mport *port, u32 offset,
+                                     u8 data);
+
+extern int rio_mport_read_config_32(struct rio_mport *port, u16 destid,
+                                   u8 hopcount, u32 offset, u32 * data);
+extern int rio_mport_write_config_32(struct rio_mport *port, u16 destid,
+                                    u8 hopcount, u32 offset, u32 data);
+extern int rio_mport_read_config_16(struct rio_mport *port, u16 destid,
+                                   u8 hopcount, u32 offset, u16 * data);
+extern int rio_mport_write_config_16(struct rio_mport *port, u16 destid,
+                                    u8 hopcount, u32 offset, u16 data);
+extern int rio_mport_read_config_8(struct rio_mport *port, u16 destid,
+                                  u8 hopcount, u32 offset, u8 * data);
+extern int rio_mport_write_config_8(struct rio_mport *port, u16 destid,
+                                   u8 hopcount, u32 offset, u8 data);
+
+/**
+ * rio_local_read_config_32 - Read 32 bits from local configuration space
+ * @port: Master port
+ * @offset: Offset into local configuration space
+ * @data: Pointer to read data into
+ *
+ * Reads 32 bits of data from the specified offset within the local
+ * device's configuration space.
+ */
+static inline int rio_local_read_config_32(struct rio_mport *port, u32 offset,
+                                          u32 * data)
+{
+       return __rio_local_read_config_32(port, offset, data);
+}
+
+/**
+ * rio_local_write_config_32 - Write 32 bits to local configuration space
+ * @port: Master port
+ * @offset: Offset into local configuration space
+ * @data: Data to be written
+ *
+ * Writes 32 bits of data to the specified offset within the local
+ * device's configuration space.
+ */
+static inline int rio_local_write_config_32(struct rio_mport *port, u32 offset,
+                                           u32 data)
+{
+       return __rio_local_write_config_32(port, offset, data);
+}
+
+/**
+ * rio_local_read_config_16 - Read 16 bits from local configuration space
+ * @port: Master port
+ * @offset: Offset into local configuration space
+ * @data: Pointer to read data into
+ *
+ * Reads 16 bits of data from the specified offset within the local
+ * device's configuration space.
+ */
+static inline int rio_local_read_config_16(struct rio_mport *port, u32 offset,
+                                          u16 * data)
+{
+       return __rio_local_read_config_16(port, offset, data);
+}
+
+/**
+ * rio_local_write_config_16 - Write 16 bits to local configuration space
+ * @port: Master port
+ * @offset: Offset into local configuration space
+ * @data: Data to be written
+ *
+ * Writes 16 bits of data to the specified offset within the local
+ * device's configuration space.
+ */
+
+static inline int rio_local_write_config_16(struct rio_mport *port, u32 offset,
+                                           u16 data)
+{
+       return __rio_local_write_config_16(port, offset, data);
+}
+
+/**
+ * rio_local_read_config_8 - Read 8 bits from local configuration space
+ * @port: Master port
+ * @offset: Offset into local configuration space
+ * @data: Pointer to read data into
+ *
+ * Reads 8 bits of data from the specified offset within the local
+ * device's configuration space.
+ */
+static inline int rio_local_read_config_8(struct rio_mport *port, u32 offset,
+                                         u8 * data)
+{
+       return __rio_local_read_config_8(port, offset, data);
+}
+
+/**
+ * rio_local_write_config_8 - Write 8 bits to local configuration space
+ * @port: Master port
+ * @offset: Offset into local configuration space
+ * @data: Data to be written
+ *
+ * Writes 8 bits of data to the specified offset within the local
+ * device's configuration space.
+ */
+static inline int rio_local_write_config_8(struct rio_mport *port, u32 offset,
+                                          u8 data)
+{
+       return __rio_local_write_config_8(port, offset, data);
+}
+
+/**
+ * rio_read_config_32 - Read 32 bits from configuration space
+ * @rdev: RIO device
+ * @offset: Offset into device configuration space
+ * @data: Pointer to read data into
+ *
+ * Reads 32 bits of data from the specified offset within the
+ * RIO device's configuration space.
+ */
+static inline int rio_read_config_32(struct rio_dev *rdev, u32 offset,
+                                    u32 * data)
+{
+       u8 hopcount = 0xff;
+       u16 destid = rdev->destid;
+
+       if (rdev->rswitch) {
+               destid = rdev->rswitch->destid;
+               hopcount = rdev->rswitch->hopcount;
+       }
+
+       return rio_mport_read_config_32(rdev->net->hport, destid, hopcount,
+                                       offset, data);
+};
+
+/**
+ * rio_write_config_32 - Write 32 bits to configuration space
+ * @rdev: RIO device
+ * @offset: Offset into device configuration space
+ * @data: Data to be written
+ *
+ * Writes 32 bits of data to the specified offset within the
+ * RIO device's configuration space.
+ */
+static inline int rio_write_config_32(struct rio_dev *rdev, u32 offset,
+                                     u32 data)
+{
+       u8 hopcount = 0xff;
+       u16 destid = rdev->destid;
+
+       if (rdev->rswitch) {
+               destid = rdev->rswitch->destid;
+               hopcount = rdev->rswitch->hopcount;
+       }
+
+       return rio_mport_write_config_32(rdev->net->hport, destid, hopcount,
+                                        offset, data);
+};
+
+/**
+ * rio_read_config_16 - Read 16 bits from configuration space
+ * @rdev: RIO device
+ * @offset: Offset into device configuration space
+ * @data: Pointer to read data into
+ *
+ * Reads 16 bits of data from the specified offset within the
+ * RIO device's configuration space.
+ */
+static inline int rio_read_config_16(struct rio_dev *rdev, u32 offset,
+                                    u16 * data)
+{
+       u8 hopcount = 0xff;
+       u16 destid = rdev->destid;
+
+       if (rdev->rswitch) {
+               destid = rdev->rswitch->destid;
+               hopcount = rdev->rswitch->hopcount;
+       }
+
+       return rio_mport_read_config_16(rdev->net->hport, destid, hopcount,
+                                       offset, data);
+};
+
+/**
+ * rio_write_config_16 - Write 16 bits to configuration space
+ * @rdev: RIO device
+ * @offset: Offset into device configuration space
+ * @data: Data to be written
+ *
+ * Writes 16 bits of data to the specified offset within the
+ * RIO device's configuration space.
+ */
+static inline int rio_write_config_16(struct rio_dev *rdev, u32 offset,
+                                     u16 data)
+{
+       u8 hopcount = 0xff;
+       u16 destid = rdev->destid;
+
+       if (rdev->rswitch) {
+               destid = rdev->rswitch->destid;
+               hopcount = rdev->rswitch->hopcount;
+       }
+
+       return rio_mport_write_config_16(rdev->net->hport, destid, hopcount,
+                                        offset, data);
+};
+
+/**
+ * rio_read_config_8 - Read 8 bits from configuration space
+ * @rdev: RIO device
+ * @offset: Offset into device configuration space
+ * @data: Pointer to read data into
+ *
+ * Reads 8 bits of data from the specified offset within the
+ * RIO device's configuration space.
+ */
+static inline int rio_read_config_8(struct rio_dev *rdev, u32 offset, u8 * data)
+{
+       u8 hopcount = 0xff;
+       u16 destid = rdev->destid;
+
+       if (rdev->rswitch) {
+               destid = rdev->rswitch->destid;
+               hopcount = rdev->rswitch->hopcount;
+       }
+
+       return rio_mport_read_config_8(rdev->net->hport, destid, hopcount,
+                                      offset, data);
+};
+
+/**
+ * rio_write_config_8 - Write 8 bits to configuration space
+ * @rdev: RIO device
+ * @offset: Offset into device configuration space
+ * @data: Data to be written
+ *
+ * Writes 8 bits of data to the specified offset within the
+ * RIO device's configuration space.
+ */
+static inline int rio_write_config_8(struct rio_dev *rdev, u32 offset, u8 data)
+{
+       u8 hopcount = 0xff;
+       u16 destid = rdev->destid;
+
+       if (rdev->rswitch) {
+               destid = rdev->rswitch->destid;
+               hopcount = rdev->rswitch->hopcount;
+       }
+
+       return rio_mport_write_config_8(rdev->net->hport, destid, hopcount,
+                                       offset, data);
+};
+
+extern int rio_mport_send_doorbell(struct rio_mport *mport, u16 destid,
+                                  u16 data);
+
+/**
+ * rio_send_doorbell - Send a doorbell message to a device
+ * @rdev: RIO device
+ * @data: Doorbell message data
+ *
+ * Send a doorbell message to a RIO device. The doorbell message
+ * has a 16-bit info field provided by the @data argument.
+ */
+static inline int rio_send_doorbell(struct rio_dev *rdev, u16 data)
+{
+       return rio_mport_send_doorbell(rdev->net->hport, rdev->destid, data);
+};
+
+/**
+ * rio_init_mbox_res - Initialize a RIO mailbox resource
+ * @res: resource struct
+ * @start: start of mailbox range
+ * @end: end of mailbox range
+ *
+ * This function is used to initialize the fields of a resource
+ * for use as a mailbox resource.  It initializes a range of
+ * mailboxes using the start and end arguments.
+ */
+static inline void rio_init_mbox_res(struct resource *res, int start, int end)
+{
+       memset(res, 0, sizeof(struct resource));
+       res->start = start;
+       res->end = end;
+       res->flags = RIO_RESOURCE_MAILBOX;
+}
+
+/**
+ * rio_init_dbell_res - Initialize a RIO doorbell resource
+ * @res: resource struct
+ * @start: start of doorbell range
+ * @end: end of doorbell range
+ *
+ * This function is used to initialize the fields of a resource
+ * for use as a doorbell resource.  It initializes a range of
+ * doorbell messages using the start and end arguments.
+ */
+static inline void rio_init_dbell_res(struct resource *res, u16 start, u16 end)
+{
+       memset(res, 0, sizeof(struct resource));
+       res->start = start;
+       res->end = end;
+       res->flags = RIO_RESOURCE_DOORBELL;
+}
+
+/**
+ * RIO_DEVICE - macro used to describe a specific RIO device
+ * @vid: the 16 bit RIO vendor ID
+ * @did: the 16 bit RIO device ID
+ *
+ * This macro is used to create a struct rio_device_id that matches a
+ * specific device.  The assembly vendor and assembly device fields
+ * will be set to %RIO_ANY_ID.
+ */
+#define RIO_DEVICE(dev,ven) \
+       .did = (dev), .vid = (ven), \
+       .asm_did = RIO_ANY_ID, .asm_vid = RIO_ANY_ID
+
+/* Mailbox management */
+extern int rio_request_outb_mbox(struct rio_mport *, void *, int, int,
+                                void (*)(struct rio_mport *, void *,int, int));
+extern int rio_release_outb_mbox(struct rio_mport *, int);
+
+/**
+ * rio_add_outb_message - Add RIO message to an outbound mailbox queue
+ * @mport: RIO master port containing the outbound queue
+ * @rdev: RIO device the message is be sent to
+ * @mbox: The outbound mailbox queue
+ * @buffer: Pointer to the message buffer
+ * @len: Length of the message buffer
+ *
+ * Adds a RIO message buffer to an outbound mailbox queue for
+ * transmission. Returns 0 on success.
+ */
+static inline int rio_add_outb_message(struct rio_mport *mport,
+                                      struct rio_dev *rdev, int mbox,
+                                      void *buffer, size_t len)
+{
+       return rio_hw_add_outb_message(mport, rdev, mbox, buffer, len);
+}
+
+extern int rio_request_inb_mbox(struct rio_mport *, void *, int, int,
+                               void (*)(struct rio_mport *, void *, int, int));
+extern int rio_release_inb_mbox(struct rio_mport *, int);
+
+/**
+ * rio_add_inb_buffer - Add buffer to an inbound mailbox queue
+ * @mport: Master port containing the inbound mailbox
+ * @mbox: The inbound mailbox number
+ * @buffer: Pointer to the message buffer
+ *
+ * Adds a buffer to an inbound mailbox queue for reception. Returns
+ * 0 on success.
+ */
+static inline int rio_add_inb_buffer(struct rio_mport *mport, int mbox,
+                                    void *buffer)
+{
+       return rio_hw_add_inb_buffer(mport, mbox, buffer);
+}
+
+/**
+ * rio_get_inb_message - Get A RIO message from an inbound mailbox queue
+ * @mport: Master port containing the inbound mailbox
+ * @mbox: The inbound mailbox number
+ * @buffer: Pointer to the message buffer
+ *
+ * Get a RIO message from an inbound mailbox queue. Returns 0 on success.
+ */
+static inline void *rio_get_inb_message(struct rio_mport *mport, int mbox)
+{
+       return rio_hw_get_inb_message(mport, mbox);
+}
+
+/* Doorbell management */
+extern int rio_request_inb_dbell(struct rio_mport *, void *, u16, u16,
+                                void (*)(struct rio_mport *, void *, u16, u16, u16));
+extern int rio_release_inb_dbell(struct rio_mport *, u16, u16);
+extern struct resource *rio_request_outb_dbell(struct rio_dev *, u16, u16);
+extern int rio_release_outb_dbell(struct rio_dev *, struct resource *);
+
+/* Memory region management */
+int rio_claim_resource(struct rio_dev *, int);
+int rio_request_regions(struct rio_dev *, char *);
+void rio_release_regions(struct rio_dev *);
+int rio_request_region(struct rio_dev *, int, char *);
+void rio_release_region(struct rio_dev *, int);
+
+/* LDM support */
+int rio_register_driver(struct rio_driver *);
+void rio_unregister_driver(struct rio_driver *);
+struct rio_dev *rio_dev_get(struct rio_dev *);
+void rio_dev_put(struct rio_dev *);
+
+/**
+ * rio_name - Get the unique RIO device identifier
+ * @rdev: RIO device
+ *
+ * Get the unique RIO device identifier. Returns the device
+ * identifier string.
+ */
+static inline char *rio_name(struct rio_dev *rdev)
+{
+       return rdev->dev.bus_id;
+}
+
+/**
+ * rio_get_drvdata - Get RIO driver specific data
+ * @rdev: RIO device
+ *
+ * Get RIO driver specific data. Returns a pointer to the
+ * driver specific data.
+ */
+static inline void *rio_get_drvdata(struct rio_dev *rdev)
+{
+       return dev_get_drvdata(&rdev->dev);
+}
+
+/**
+ * rio_set_drvdata - Set RIO driver specific data
+ * @rdev: RIO device
+ * @data: Pointer to driver specific data
+ *
+ * Set RIO driver specific data. device struct driver data pointer
+ * is set to the @data argument.
+ */
+static inline void rio_set_drvdata(struct rio_dev *rdev, void *data)
+{
+       dev_set_drvdata(&rdev->dev, data);
+}
+
+/* Misc driver helpers */
+extern u16 rio_local_get_device_id(struct rio_mport *port);
+extern struct rio_dev *rio_get_device(u16 vid, u16 did, struct rio_dev *from);
+extern struct rio_dev *rio_get_asm(u16 vid, u16 did, u16 asm_vid, u16 asm_did,
+                                  struct rio_dev *from);
+
+#endif                         /* __KERNEL__ */
+#endif                         /* LINUX_RIO_DRV_H */
diff --git a/include/linux/rio_ids.h b/include/linux/rio_ids.h
new file mode 100644 (file)
index 0000000..919d4e0
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * RapidIO devices
+ *
+ * Copyright 2005 MontaVista Software, Inc.
+ * Matt Porter <mporter@kernel.crashing.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.
+ */
+
+#ifndef LINUX_RIO_IDS_H
+#define LINUX_RIO_IDS_H
+
+#define RIO_ANY_ID                     0xffff
+
+#define RIO_VID_FREESCALE              0x0002
+#define RIO_DID_MPC8560                        0x0003
+
+#define RIO_VID_TUNDRA                 0x000d
+#define RIO_DID_TSI500                 0x0500
+
+#endif                         /* LINUX_RIO_IDS_H */
diff --git a/include/linux/rio_regs.h b/include/linux/rio_regs.h
new file mode 100644 (file)
index 0000000..326540f
--- /dev/null
@@ -0,0 +1,215 @@
+/*
+ * RapidIO register definitions
+ *
+ * Copyright 2005 MontaVista Software, Inc.
+ * Matt Porter <mporter@kernel.crashing.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.
+ */
+
+#ifndef LINUX_RIO_REGS_H
+#define LINUX_RIO_REGS_H
+
+/*
+ * In RapidIO, each device has a 2MB configuration space that is
+ * accessed via maintenance transactions.  Portions of configuration
+ * space are standardized and/or reserved.
+ */
+#define RIO_DEV_ID_CAR         0x00    /* [I] Device Identity CAR */
+#define RIO_DEV_INFO_CAR       0x04    /* [I] Device Information CAR */
+#define RIO_ASM_ID_CAR         0x08    /* [I] Assembly Identity CAR */
+#define  RIO_ASM_ID_MASK               0xffff0000      /* [I] Asm ID Mask */
+#define  RIO_ASM_VEN_ID_MASK           0x0000ffff      /* [I] Asm Vend Mask */
+
+#define RIO_ASM_INFO_CAR       0x0c    /* [I] Assembly Information CAR */
+#define  RIO_ASM_REV_MASK              0xffff0000      /* [I] Asm Rev Mask */
+#define  RIO_EXT_FTR_PTR_MASK          0x0000ffff      /* [I] EF_PTR Mask */
+
+#define RIO_PEF_CAR            0x10    /* [I] Processing Element Features CAR */
+#define  RIO_PEF_BRIDGE                        0x80000000      /* [I] Bridge */
+#define  RIO_PEF_MEMORY                        0x40000000      /* [I] MMIO */
+#define  RIO_PEF_PROCESSOR             0x20000000      /* [I] Processor */
+#define  RIO_PEF_SWITCH                        0x10000000      /* [I] Switch */
+#define  RIO_PEF_INB_MBOX              0x00f00000      /* [II] Mailboxes */
+#define  RIO_PEF_INB_MBOX0             0x00800000      /* [II] Mailbox 0 */
+#define  RIO_PEF_INB_MBOX1             0x00400000      /* [II] Mailbox 1 */
+#define  RIO_PEF_INB_MBOX2             0x00200000      /* [II] Mailbox 2 */
+#define  RIO_PEF_INB_MBOX3             0x00100000      /* [II] Mailbox 3 */
+#define  RIO_PEF_INB_DOORBELL          0x00080000      /* [II] Doorbells */
+#define  RIO_PEF_CTLS                  0x00000010      /* [III] CTLS */
+#define  RIO_PEF_EXT_FEATURES          0x00000008      /* [I] EFT_PTR valid */
+#define  RIO_PEF_ADDR_66               0x00000004      /* [I] 66 bits */
+#define  RIO_PEF_ADDR_50               0x00000002      /* [I] 50 bits */
+#define  RIO_PEF_ADDR_34               0x00000001      /* [I] 34 bits */
+
+#define RIO_SWP_INFO_CAR       0x14    /* [I] Switch Port Information CAR */
+#define  RIO_SWP_INFO_PORT_TOTAL_MASK  0x0000ff00      /* [I] Total number of ports */
+#define  RIO_SWP_INFO_PORT_NUM_MASK    0x000000ff      /* [I] Maintenance transaction port number */
+#define  RIO_GET_TOTAL_PORTS(x)                ((x & RIO_SWP_INFO_PORT_TOTAL_MASK) >> 8)
+
+#define RIO_SRC_OPS_CAR                0x18    /* [I] Source Operations CAR */
+#define  RIO_SRC_OPS_READ              0x00008000      /* [I] Read op */
+#define  RIO_SRC_OPS_WRITE             0x00004000      /* [I] Write op */
+#define  RIO_SRC_OPS_STREAM_WRITE      0x00002000      /* [I] Str-write op */
+#define  RIO_SRC_OPS_WRITE_RESPONSE    0x00001000      /* [I] Write/resp op */
+#define  RIO_SRC_OPS_DATA_MSG          0x00000800      /* [II] Data msg op */
+#define  RIO_SRC_OPS_DOORBELL          0x00000400      /* [II] Doorbell op */
+#define  RIO_SRC_OPS_ATOMIC_TST_SWP    0x00000100      /* [I] Atomic TAS op */
+#define  RIO_SRC_OPS_ATOMIC_INC                0x00000080      /* [I] Atomic inc op */
+#define  RIO_SRC_OPS_ATOMIC_DEC                0x00000040      /* [I] Atomic dec op */
+#define  RIO_SRC_OPS_ATOMIC_SET                0x00000020      /* [I] Atomic set op */
+#define  RIO_SRC_OPS_ATOMIC_CLR                0x00000010      /* [I] Atomic clr op */
+#define  RIO_SRC_OPS_PORT_WRITE                0x00000004      /* [I] Port-write op */
+
+#define RIO_DST_OPS_CAR                0x1c    /* Destination Operations CAR */
+#define  RIO_DST_OPS_READ              0x00008000      /* [I] Read op */
+#define  RIO_DST_OPS_WRITE             0x00004000      /* [I] Write op */
+#define  RIO_DST_OPS_STREAM_WRITE      0x00002000      /* [I] Str-write op */
+#define  RIO_DST_OPS_WRITE_RESPONSE    0x00001000      /* [I] Write/resp op */
+#define  RIO_DST_OPS_DATA_MSG          0x00000800      /* [II] Data msg op */
+#define  RIO_DST_OPS_DOORBELL          0x00000400      /* [II] Doorbell op */
+#define  RIO_DST_OPS_ATOMIC_TST_SWP    0x00000100      /* [I] Atomic TAS op */
+#define  RIO_DST_OPS_ATOMIC_INC                0x00000080      /* [I] Atomic inc op */
+#define  RIO_DST_OPS_ATOMIC_DEC                0x00000040      /* [I] Atomic dec op */
+#define  RIO_DST_OPS_ATOMIC_SET                0x00000020      /* [I] Atomic set op */
+#define  RIO_DST_OPS_ATOMIC_CLR                0x00000010      /* [I] Atomic clr op */
+#define  RIO_DST_OPS_PORT_WRITE                0x00000004      /* [I] Port-write op */
+
+#define  RIO_OPS_READ                  0x00008000      /* [I] Read op */
+#define  RIO_OPS_WRITE                 0x00004000      /* [I] Write op */
+#define  RIO_OPS_STREAM_WRITE          0x00002000      /* [I] Str-write op */
+#define  RIO_OPS_WRITE_RESPONSE                0x00001000      /* [I] Write/resp op */
+#define  RIO_OPS_DATA_MSG              0x00000800      /* [II] Data msg op */
+#define  RIO_OPS_DOORBELL              0x00000400      /* [II] Doorbell op */
+#define  RIO_OPS_ATOMIC_TST_SWP                0x00000100      /* [I] Atomic TAS op */
+#define  RIO_OPS_ATOMIC_INC            0x00000080      /* [I] Atomic inc op */
+#define  RIO_OPS_ATOMIC_DEC            0x00000040      /* [I] Atomic dec op */
+#define  RIO_OPS_ATOMIC_SET            0x00000020      /* [I] Atomic set op */
+#define  RIO_OPS_ATOMIC_CLR            0x00000010      /* [I] Atomic clr op */
+#define  RIO_OPS_PORT_WRITE            0x00000004      /* [I] Port-write op */
+
+                                       /* 0x20-0x3c *//* Reserved */
+
+#define RIO_MBOX_CSR           0x40    /* [II] Mailbox CSR */
+#define  RIO_MBOX0_AVAIL               0x80000000      /* [II] Mbox 0 avail */
+#define  RIO_MBOX0_FULL                        0x40000000      /* [II] Mbox 0 full */
+#define  RIO_MBOX0_EMPTY               0x20000000      /* [II] Mbox 0 empty */
+#define  RIO_MBOX0_BUSY                        0x10000000      /* [II] Mbox 0 busy */
+#define  RIO_MBOX0_FAIL                        0x08000000      /* [II] Mbox 0 fail */
+#define  RIO_MBOX0_ERROR               0x04000000      /* [II] Mbox 0 error */
+#define  RIO_MBOX1_AVAIL               0x00800000      /* [II] Mbox 1 avail */
+#define  RIO_MBOX1_FULL                        0x00200000      /* [II] Mbox 1 full */
+#define  RIO_MBOX1_EMPTY               0x00200000      /* [II] Mbox 1 empty */
+#define  RIO_MBOX1_BUSY                        0x00100000      /* [II] Mbox 1 busy */
+#define  RIO_MBOX1_FAIL                        0x00080000      /* [II] Mbox 1 fail */
+#define  RIO_MBOX1_ERROR               0x00040000      /* [II] Mbox 1 error */
+#define  RIO_MBOX2_AVAIL               0x00008000      /* [II] Mbox 2 avail */
+#define  RIO_MBOX2_FULL                        0x00004000      /* [II] Mbox 2 full */
+#define  RIO_MBOX2_EMPTY               0x00002000      /* [II] Mbox 2 empty */
+#define  RIO_MBOX2_BUSY                        0x00001000      /* [II] Mbox 2 busy */
+#define  RIO_MBOX2_FAIL                        0x00000800      /* [II] Mbox 2 fail */
+#define  RIO_MBOX2_ERROR               0x00000400      /* [II] Mbox 2 error */
+#define  RIO_MBOX3_AVAIL               0x00000080      /* [II] Mbox 3 avail */
+#define  RIO_MBOX3_FULL                        0x00000040      /* [II] Mbox 3 full */
+#define  RIO_MBOX3_EMPTY               0x00000020      /* [II] Mbox 3 empty */
+#define  RIO_MBOX3_BUSY                        0x00000010      /* [II] Mbox 3 busy */
+#define  RIO_MBOX3_FAIL                        0x00000008      /* [II] Mbox 3 fail */
+#define  RIO_MBOX3_ERROR               0x00000004      /* [II] Mbox 3 error */
+
+#define RIO_WRITE_PORT_CSR     0x44    /* [I] Write Port CSR */
+#define RIO_DOORBELL_CSR       0x44    /* [II] Doorbell CSR */
+#define  RIO_DOORBELL_AVAIL            0x80000000      /* [II] Doorbell avail */
+#define  RIO_DOORBELL_FULL             0x40000000      /* [II] Doorbell full */
+#define  RIO_DOORBELL_EMPTY            0x20000000      /* [II] Doorbell empty */
+#define  RIO_DOORBELL_BUSY             0x10000000      /* [II] Doorbell busy */
+#define  RIO_DOORBELL_FAILED           0x08000000      /* [II] Doorbell failed */
+#define  RIO_DOORBELL_ERROR            0x04000000      /* [II] Doorbell error */
+#define  RIO_WRITE_PORT_AVAILABLE      0x00000080      /* [I] Write Port Available */
+#define  RIO_WRITE_PORT_FULL           0x00000040      /* [I] Write Port Full */
+#define  RIO_WRITE_PORT_EMPTY          0x00000020      /* [I] Write Port Empty */
+#define  RIO_WRITE_PORT_BUSY           0x00000010      /* [I] Write Port Busy */
+#define  RIO_WRITE_PORT_FAILED         0x00000008      /* [I] Write Port Failed */
+#define  RIO_WRITE_PORT_ERROR          0x00000004      /* [I] Write Port Error */
+
+                                       /* 0x48 *//* Reserved */
+
+#define RIO_PELL_CTRL_CSR      0x4c    /* [I] PE Logical Layer Control CSR */
+#define   RIO_PELL_ADDR_66             0x00000004      /* [I] 66-bit addr */
+#define   RIO_PELL_ADDR_50             0x00000002      /* [I] 50-bit addr */
+#define   RIO_PELL_ADDR_34             0x00000001      /* [I] 34-bit addr */
+
+                                       /* 0x50-0x54 *//* Reserved */
+
+#define RIO_LCSH_BA            0x58    /* [I] LCS High Base Address */
+#define RIO_LCSL_BA            0x5c    /* [I] LCS Base Address */
+
+#define RIO_DID_CSR            0x60    /* [III] Base Device ID CSR */
+
+                                       /* 0x64 *//* Reserved */
+
+#define RIO_HOST_DID_LOCK_CSR  0x68    /* [III] Host Base Device ID Lock CSR */
+#define RIO_COMPONENT_TAG_CSR  0x6c    /* [III] Component Tag CSR */
+
+                                       /* 0x70-0xf8 *//* Reserved */
+                                       /* 0x100-0xfff8 *//* [I] Extended Features Space */
+                                       /* 0x10000-0xfffff8 *//* [I] Implementation-defined Space */
+
+/*
+ * Extended Features Space is a configuration space area where
+ * functionality is mapped into extended feature blocks via a
+ * singly linked list of extended feature pointers (EFT_PTR).
+ *
+ * Each extended feature block can be identified/located in
+ * Extended Features Space by walking the extended feature
+ * list starting with the Extended Feature Pointer located
+ * in the Assembly Information CAR.
+ *
+ * Extended Feature Blocks (EFBs) are identified with an assigned
+ * EFB ID. Extended feature block offsets in the definitions are
+ * relative to the offset of the EFB within the  Extended Features
+ * Space.
+ */
+
+/* Helper macros to parse the Extended Feature Block header */
+#define RIO_EFB_PTR_MASK       0xffff0000
+#define RIO_EFB_ID_MASK                0x0000ffff
+#define RIO_GET_BLOCK_PTR(x)   ((x & RIO_EFB_PTR_MASK) >> 16)
+#define RIO_GET_BLOCK_ID(x)    (x & RIO_EFB_ID_MASK)
+
+/* Extended Feature Block IDs */
+#define RIO_EFB_PAR_EP_ID      0x0001  /* [IV] LP/LVDS EP Devices */
+#define RIO_EFB_PAR_EP_REC_ID  0x0002  /* [IV] LP/LVDS EP Recovery Devices */
+#define RIO_EFB_PAR_EP_FREE_ID 0x0003  /* [IV] LP/LVDS EP Free Devices */
+#define RIO_EFB_SER_EP_ID      0x0004  /* [VI] LP/Serial EP Devices */
+#define RIO_EFB_SER_EP_REC_ID  0x0005  /* [VI] LP/Serial EP Recovery Devices */
+#define RIO_EFB_SER_EP_FREE_ID 0x0006  /* [VI] LP/Serial EP Free Devices */
+
+/*
+ * Physical 8/16 LP-LVDS
+ * ID=0x0001, Generic End Point Devices
+ * ID=0x0002, Generic End Point Devices, software assisted recovery option
+ * ID=0x0003, Generic End Point Free Devices
+ *
+ * Physical LP-Serial
+ * ID=0x0004, Generic End Point Devices
+ * ID=0x0005, Generic End Point Devices, software assisted recovery option
+ * ID=0x0006, Generic End Point Free Devices
+ */
+#define RIO_PORT_MNT_HEADER            0x0000
+#define RIO_PORT_REQ_CTL_CSR           0x0020
+#define RIO_PORT_RSP_CTL_CSR           0x0024  /* 0x0001/0x0002 */
+#define RIO_PORT_GEN_CTL_CSR           0x003c
+#define  RIO_PORT_GEN_HOST             0x80000000
+#define  RIO_PORT_GEN_MASTER           0x40000000
+#define  RIO_PORT_GEN_DISCOVERED       0x20000000
+#define RIO_PORT_N_MNT_REQ_CSR(x)      (0x0040 + x*0x20)       /* 0x0002 */
+#define RIO_PORT_N_MNT_RSP_CSR(x)      (0x0044 + x*0x20)       /* 0x0002 */
+#define RIO_PORT_N_ACK_STS_CSR(x)      (0x0048 + x*0x20)       /* 0x0002 */
+#define RIO_PORT_N_ERR_STS_CSR(x)      (0x58 + x*0x20)
+#define PORT_N_ERR_STS_PORT_OK 0x00000002
+#define RIO_PORT_N_CTL_CSR(x)          (0x5c + x*0x20)
+
+#endif                         /* LINUX_RIO_REGS_H */
index 106f9757339a54aeffc52a440129b5827040c8c1..3c1f1120fe8846de2ef1f9a3ec2d4cf47171f8b0 100644 (file)
@@ -79,6 +79,8 @@ struct  seminfo {
 
 #ifdef __KERNEL__
 
+struct task_struct;
+
 /* One semaphore structure for each semaphore in the system. */
 struct sem {
        int     semval;         /* current value */
index 80113a1f60bc83447184c6cc55b89eafa7eebd10..a2c896ad0befa6819dbae3e1ffd47b1679597346 100644 (file)
@@ -92,6 +92,7 @@ struct shmid_kernel /* private to the kernel */
 #define        SHM_DEST        01000   /* segment will be destroyed on last detach */
 #define SHM_LOCKED      02000   /* segment will not be swapped */
 #define SHM_HUGETLB     04000   /* segment will use huge TLB pages */
+#define SHM_NORESERVE   010000  /* don't check for reservations */
 
 #ifdef CONFIG_SYSVIPC
 long do_shmat(int shmid, char __user *shmaddr, int shmflg, unsigned long *addr);
index 09b9aa60063dda9d56d062f9e44e2042df72f744..d1ea4051b99618b1f12a6a31291353cd9cf3ce69 100644 (file)
@@ -9,7 +9,7 @@
 
 #if    defined(__KERNEL__)
 
-typedef struct kmem_cache_s kmem_cache_t;
+typedef struct kmem_cache kmem_cache_t;
 
 #include       <linux/config.h>        /* kmalloc_sizes.h needs CONFIG_ options */
 #include       <linux/gfp.h>
index 5af8800e0ce328a05aa7cbaeaa0b604ba28b00ab..e4086ec8b952a3a87b5f16bd654df3c70a05066a 100644 (file)
@@ -171,7 +171,8 @@ xdr_argsize_check(struct svc_rqst *rqstp, u32 *p)
 {
        char *cp = (char *)p;
        struct kvec *vec = &rqstp->rq_arg.head[0];
-       return cp - (char*)vec->iov_base <= vec->iov_len;
+       return cp >= (char*)vec->iov_base
+               && cp <= (char*)vec->iov_base + vec->iov_len;
 }
 
 static inline int
index c906c5a0aaefadb6f93f53f45ce25f9b3ff62d2f..17ea468fa3621a9246a2e5717a99c94ca0b01ddc 100644 (file)
@@ -19,7 +19,7 @@
  */
 #define SUPERHYWAY_DEVICE_ID_SH5_DMAC  0x0183
 
-struct vcr_info {
+struct superhyway_vcr_info {
        u8      perr_flags;     /* P-port Error flags */
        u8      merr_flags;     /* Module Error flags */
        u16     mod_vers;       /* Module Version */
@@ -28,6 +28,17 @@ struct vcr_info {
        u8      top_mb;         /* Top Memory block */
 };
 
+struct superhyway_ops {
+       int (*read_vcr)(unsigned long base, struct superhyway_vcr_info *vcr);
+       int (*write_vcr)(unsigned long base, struct superhyway_vcr_info vcr);
+};
+
+struct superhyway_bus {
+       struct superhyway_ops *ops;
+};
+
+extern struct superhyway_bus superhyway_channels[];
+
 struct superhyway_device_id {
        unsigned int id;
        unsigned long driver_data;
@@ -55,9 +66,11 @@ struct superhyway_device {
 
        struct superhyway_device_id id;
        struct superhyway_driver *drv;
+       struct superhyway_bus *bus;
 
-       struct resource resource;
-       struct vcr_info vcr;
+       int num_resources;
+       struct resource *resource;
+       struct superhyway_vcr_info vcr;
 };
 
 #define to_superhyway_device(d)        container_of((d), struct superhyway_device, dev)
@@ -65,12 +78,27 @@ struct superhyway_device {
 #define superhyway_get_drvdata(d)      dev_get_drvdata(&(d)->dev)
 #define superhyway_set_drvdata(d,p)    dev_set_drvdata(&(d)->dev, (p))
 
-extern int superhyway_scan_bus(void);
+static inline int
+superhyway_read_vcr(struct superhyway_device *dev, unsigned long base,
+                   struct superhyway_vcr_info *vcr)
+{
+       return dev->bus->ops->read_vcr(base, vcr);
+}
+
+static inline int
+superhyway_write_vcr(struct superhyway_device *dev, unsigned long base,
+                    struct superhyway_vcr_info vcr)
+{
+       return dev->bus->ops->write_vcr(base, vcr);
+}
+
+extern int superhyway_scan_bus(struct superhyway_bus *);
 
 /* drivers/sh/superhyway/superhyway.c */
 int superhyway_register_driver(struct superhyway_driver *);
 void superhyway_unregister_driver(struct superhyway_driver *);
-int superhyway_add_device(unsigned int, unsigned long, unsigned long long);
+int superhyway_add_device(unsigned long base, struct superhyway_device *, struct superhyway_bus *);
+int superhyway_add_devices(struct superhyway_bus *bus, struct superhyway_device **devices, int nr_devices);
 
 /* drivers/sh/superhyway/superhyway-sysfs.c */
 extern struct device_attribute superhyway_dev_attrs[];
index d38c9fecdc368450d00a4e5602944b0288a2c64b..d28518236b62fea581606ee74c76607743153aad 100644 (file)
@@ -54,6 +54,7 @@ struct __wait_queue_head {
 };
 typedef struct __wait_queue_head wait_queue_head_t;
 
+struct task_struct;
 
 /*
  * Macros for declaration and initialisaton of the datatypes
index b58c651d31ae23a36c58a1de3005e6b5d46a2662..587d836d80d9d07f075259d3efe73917413f8010 100644 (file)
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -212,8 +212,16 @@ static int newseg (key_t key, int shmflg, size_t size)
                file = hugetlb_zero_setup(size);
                shp->mlock_user = current->user;
        } else {
+               int acctflag = VM_ACCOUNT;
+               /*
+                * Do not allow no accounting for OVERCOMMIT_NEVER, even
+                * if it's asked for.
+                */
+               if  ((shmflg & SHM_NORESERVE) &&
+                               sysctl_overcommit_memory != OVERCOMMIT_NEVER)
+                       acctflag = 0;
                sprintf (name, "SYSV%08x", key);
-               file = shmem_file_setup(name, size, VM_ACCOUNT);
+               file = shmem_file_setup(name, size, acctflag);
        }
        error = PTR_ERR(file);
        if (IS_ERR(file))
index 10e836d0d89e86fb36de703364a0afdeb0f21c7e..23f1cec150c106dd7e0aa17e34699679c70e02dc 100644 (file)
@@ -410,7 +410,8 @@ void ipc_rcu_getref(void *ptr)
 }
 
 /**
- *     ipc_schedule_free       - free ipc + rcu space
+ * ipc_schedule_free - free ipc + rcu space
+ * @head: RCU callback structure for queued work
  * 
  * Since RCU callback function is called in bh,
  * we need to defer the vfree to schedule_work
@@ -427,10 +428,10 @@ static void ipc_schedule_free(struct rcu_head *head)
 }
 
 /**
- *     ipc_immediate_free      - free ipc + rcu space
- *
- *     Free from the RCU callback context
+ * ipc_immediate_free - free ipc + rcu space
+ * @head: RCU callback structure that contains pointer to be freed
  *
+ * Free from the RCU callback context
  */
 static void ipc_immediate_free(struct rcu_head *head)
 {
index 537394b25e8d9a6d1e108ae0f78cbb3fab317769..452a1d1161782130204c934542aa2cb7f5f44b25 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/cpuset.h>
 #include <linux/syscalls.h>
 #include <linux/signal.h>
+#include <linux/cn_proc.h>
 
 #include <asm/uaccess.h>
 #include <asm/unistd.h>
@@ -863,6 +864,7 @@ fastcall NORET_TYPE void do_exit(long code)
                module_put(tsk->binfmt->module);
 
        tsk->exit_code = code;
+       proc_exit_connector(tsk);
        exit_notify(tsk);
 #ifdef CONFIG_NUMA
        mpol_free(tsk->mempolicy);
index 8a069612eac39e285afc9bc9314311e5980ef536..efac2c58ec7d7eb4889b962af69b372b669640f1 100644 (file)
@@ -42,6 +42,7 @@
 #include <linux/profile.h>
 #include <linux/rmap.h>
 #include <linux/acct.h>
+#include <linux/cn_proc.h>
 
 #include <asm/pgtable.h>
 #include <asm/pgalloc.h>
@@ -1143,6 +1144,7 @@ static task_t *copy_process(unsigned long clone_flags,
                        __get_cpu_var(process_counts)++;
        }
 
+       proc_fork_connector(p);
        if (!current->signal->tty && p->signal->tty)
                p->signal->tty = NULL;
 
index 3b4d5ad44cc6eb182a6bece56d2574436762fe56..aca8d10704f675cbdf35267d49bb984669c49f44 100644 (file)
@@ -365,6 +365,11 @@ retry:
                if (bh1 != bh2)
                        spin_unlock(&bh2->lock);
 
+               if (unlikely(op_ret != -EFAULT)) {
+                       ret = op_ret;
+                       goto out;
+               }
+
                /* futex_atomic_op_inuser needs to both read and write
                 * *(int __user *)uaddr2, but we can't modify it
                 * non-atomically.  Therefore, if get_user below is not
index 1cfdb08ddf2054f6f219d28c78b97828e2f8b447..3bd7226d15fa10b5c4d6183506cff3368d4b7dfd 100644 (file)
@@ -24,6 +24,7 @@ cpumask_t __cacheline_aligned pending_irq_cpumask[NR_IRQS];
 
 /**
  *     synchronize_irq - wait for pending IRQ handlers (on other CPUs)
+ *     @irq: interrupt number to wait for
  *
  *     This function waits for any pending IRQ handlers for this interrupt
  *     to complete before returning. If you use this function while
index ce4915dd683a3f35b120a31e1b1a356beb2fb94c..5beda378cc7518b353dc5f0551c636d8dd81b02a 100644 (file)
@@ -32,7 +32,6 @@
  *             <prasanna@in.ibm.com> added function-return probes.
  */
 #include <linux/kprobes.h>
-#include <linux/spinlock.h>
 #include <linux/hash.h>
 #include <linux/init.h>
 #include <linux/slab.h>
@@ -49,9 +48,9 @@
 static struct hlist_head kprobe_table[KPROBE_TABLE_SIZE];
 static struct hlist_head kretprobe_inst_table[KPROBE_TABLE_SIZE];
 
-unsigned int kprobe_cpu = NR_CPUS;
-static DEFINE_SPINLOCK(kprobe_lock);
-static struct kprobe *curr_kprobe;
+static DEFINE_SPINLOCK(kprobe_lock);   /* Protects kprobe_table */
+DEFINE_SPINLOCK(kretprobe_lock);       /* Protects kretprobe_inst_table */
+static DEFINE_PER_CPU(struct kprobe *, kprobe_instance) = NULL;
 
 /*
  * kprobe->ainsn.insn points to the copy of the instruction to be
@@ -153,50 +152,31 @@ void __kprobes free_insn_slot(kprobe_opcode_t *slot)
        }
 }
 
-/* Locks kprobe: irqs must be disabled */
-void __kprobes lock_kprobes(void)
+/* We have preemption disabled.. so it is safe to use __ versions */
+static inline void set_kprobe_instance(struct kprobe *kp)
 {
-       unsigned long flags = 0;
-
-       /* Avoiding local interrupts to happen right after we take the kprobe_lock
-        * and before we get a chance to update kprobe_cpu, this to prevent
-        * deadlock when we have a kprobe on ISR routine and a kprobe on task
-        * routine
-        */
-       local_irq_save(flags);
-
-       spin_lock(&kprobe_lock);
-       kprobe_cpu = smp_processor_id();
-
-       local_irq_restore(flags);
+       __get_cpu_var(kprobe_instance) = kp;
 }
 
-void __kprobes unlock_kprobes(void)
+static inline void reset_kprobe_instance(void)
 {
-       unsigned long flags = 0;
-
-       /* Avoiding local interrupts to happen right after we update
-        * kprobe_cpu and before we get a a chance to release kprobe_lock,
-        * this to prevent deadlock when we have a kprobe on ISR routine and
-        * a kprobe on task routine
-        */
-       local_irq_save(flags);
-
-       kprobe_cpu = NR_CPUS;
-       spin_unlock(&kprobe_lock);
-
-       local_irq_restore(flags);
+       __get_cpu_var(kprobe_instance) = NULL;
 }
 
-/* You have to be holding the kprobe_lock */
+/*
+ * This routine is called either:
+ *     - under the kprobe_lock spinlock - during kprobe_[un]register()
+ *                             OR
+ *     - with preemption disabled - from arch/xxx/kernel/kprobes.c
+ */
 struct kprobe __kprobes *get_kprobe(void *addr)
 {
        struct hlist_head *head;
        struct hlist_node *node;
+       struct kprobe *p;
 
        head = &kprobe_table[hash_ptr(addr, KPROBE_HASH_BITS)];
-       hlist_for_each(node, head) {
-               struct kprobe *p = hlist_entry(node, struct kprobe, hlist);
+       hlist_for_each_entry_rcu(p, node, head, hlist) {
                if (p->addr == addr)
                        return p;
        }
@@ -211,13 +191,13 @@ static int __kprobes aggr_pre_handler(struct kprobe *p, struct pt_regs *regs)
 {
        struct kprobe *kp;
 
-       list_for_each_entry(kp, &p->list, list) {
+       list_for_each_entry_rcu(kp, &p->list, list) {
                if (kp->pre_handler) {
-                       curr_kprobe = kp;
+                       set_kprobe_instance(kp);
                        if (kp->pre_handler(kp, regs))
                                return 1;
                }
-               curr_kprobe = NULL;
+               reset_kprobe_instance();
        }
        return 0;
 }
@@ -227,11 +207,11 @@ static void __kprobes aggr_post_handler(struct kprobe *p, struct pt_regs *regs,
 {
        struct kprobe *kp;
 
-       list_for_each_entry(kp, &p->list, list) {
+       list_for_each_entry_rcu(kp, &p->list, list) {
                if (kp->post_handler) {
-                       curr_kprobe = kp;
+                       set_kprobe_instance(kp);
                        kp->post_handler(kp, regs, flags);
-                       curr_kprobe = NULL;
+                       reset_kprobe_instance();
                }
        }
        return;
@@ -240,12 +220,14 @@ static void __kprobes aggr_post_handler(struct kprobe *p, struct pt_regs *regs,
 static int __kprobes aggr_fault_handler(struct kprobe *p, struct pt_regs *regs,
                                        int trapnr)
 {
+       struct kprobe *cur = __get_cpu_var(kprobe_instance);
+
        /*
         * if we faulted "during" the execution of a user specified
         * probe handler, invoke just that probe's fault handler
         */
-       if (curr_kprobe && curr_kprobe->fault_handler) {
-               if (curr_kprobe->fault_handler(curr_kprobe, regs, trapnr))
+       if (cur && cur->fault_handler) {
+               if (cur->fault_handler(cur, regs, trapnr))
                        return 1;
        }
        return 0;
@@ -253,17 +235,18 @@ static int __kprobes aggr_fault_handler(struct kprobe *p, struct pt_regs *regs,
 
 static int __kprobes aggr_break_handler(struct kprobe *p, struct pt_regs *regs)
 {
-       struct kprobe *kp = curr_kprobe;
-       if (curr_kprobe && kp->break_handler) {
-               if (kp->break_handler(kp, regs)) {
-                       curr_kprobe = NULL;
-                       return 1;
-               }
+       struct kprobe *cur = __get_cpu_var(kprobe_instance);
+       int ret = 0;
+
+       if (cur && cur->break_handler) {
+               if (cur->break_handler(cur, regs))
+                       ret = 1;
        }
-       curr_kprobe = NULL;
-       return 0;
+       reset_kprobe_instance();
+       return ret;
 }
 
+/* Called with kretprobe_lock held */
 struct kretprobe_instance __kprobes *get_free_rp_inst(struct kretprobe *rp)
 {
        struct hlist_node *node;
@@ -273,6 +256,7 @@ struct kretprobe_instance __kprobes *get_free_rp_inst(struct kretprobe *rp)
        return NULL;
 }
 
+/* Called with kretprobe_lock held */
 static struct kretprobe_instance __kprobes *get_used_rp_inst(struct kretprobe
                                                              *rp)
 {
@@ -283,6 +267,7 @@ static struct kretprobe_instance __kprobes *get_used_rp_inst(struct kretprobe
        return NULL;
 }
 
+/* Called with kretprobe_lock held */
 void __kprobes add_rp_inst(struct kretprobe_instance *ri)
 {
        /*
@@ -301,6 +286,7 @@ void __kprobes add_rp_inst(struct kretprobe_instance *ri)
        hlist_add_head(&ri->uflist, &ri->rp->used_instances);
 }
 
+/* Called with kretprobe_lock held */
 void __kprobes recycle_rp_inst(struct kretprobe_instance *ri)
 {
        /* remove rp inst off the rprobe_inst_table */
@@ -334,13 +320,13 @@ void __kprobes kprobe_flush_task(struct task_struct *tk)
        struct hlist_node *node, *tmp;
        unsigned long flags = 0;
 
-       spin_lock_irqsave(&kprobe_lock, flags);
+       spin_lock_irqsave(&kretprobe_lock, flags);
         head = kretprobe_inst_table_head(current);
         hlist_for_each_entry_safe(ri, node, tmp, head, hlist) {
                 if (ri->task == tk)
                         recycle_rp_inst(ri);
         }
-       spin_unlock_irqrestore(&kprobe_lock, flags);
+       spin_unlock_irqrestore(&kretprobe_lock, flags);
 }
 
 /*
@@ -351,9 +337,12 @@ static int __kprobes pre_handler_kretprobe(struct kprobe *p,
                                           struct pt_regs *regs)
 {
        struct kretprobe *rp = container_of(p, struct kretprobe, kp);
+       unsigned long flags = 0;
 
        /*TODO: consider to only swap the RA after the last pre_handler fired */
+       spin_lock_irqsave(&kretprobe_lock, flags);
        arch_prepare_kretprobe(rp, regs);
+       spin_unlock_irqrestore(&kretprobe_lock, flags);
        return 0;
 }
 
@@ -384,13 +373,13 @@ static int __kprobes add_new_kprobe(struct kprobe *old_p, struct kprobe *p)
         struct kprobe *kp;
 
        if (p->break_handler) {
-               list_for_each_entry(kp, &old_p->list, list) {
+               list_for_each_entry_rcu(kp, &old_p->list, list) {
                        if (kp->break_handler)
                                return -EEXIST;
                }
-               list_add_tail(&p->list, &old_p->list);
+               list_add_tail_rcu(&p->list, &old_p->list);
        } else
-               list_add(&p->list, &old_p->list);
+               list_add_rcu(&p->list, &old_p->list);
        return 0;
 }
 
@@ -408,18 +397,18 @@ static inline void add_aggr_kprobe(struct kprobe *ap, struct kprobe *p)
        ap->break_handler = aggr_break_handler;
 
        INIT_LIST_HEAD(&ap->list);
-       list_add(&p->list, &ap->list);
+       list_add_rcu(&p->list, &ap->list);
 
        INIT_HLIST_NODE(&ap->hlist);
-       hlist_del(&p->hlist);
-       hlist_add_head(&ap->hlist,
+       hlist_del_rcu(&p->hlist);
+       hlist_add_head_rcu(&ap->hlist,
                &kprobe_table[hash_ptr(ap->addr, KPROBE_HASH_BITS)]);
 }
 
 /*
  * This is the second or subsequent kprobe at the address - handle
  * the intricacies
- * TODO: Move kcalloc outside the spinlock
+ * TODO: Move kcalloc outside the spin_lock
  */
 static int __kprobes register_aggr_kprobe(struct kprobe *old_p,
                                          struct kprobe *p)
@@ -445,7 +434,7 @@ static int __kprobes register_aggr_kprobe(struct kprobe *old_p,
 static inline void cleanup_kprobe(struct kprobe *p, unsigned long flags)
 {
        arch_disarm_kprobe(p);
-       hlist_del(&p->hlist);
+       hlist_del_rcu(&p->hlist);
        spin_unlock_irqrestore(&kprobe_lock, flags);
        arch_remove_kprobe(p);
 }
@@ -453,11 +442,10 @@ static inline void cleanup_kprobe(struct kprobe *p, unsigned long flags)
 static inline void cleanup_aggr_kprobe(struct kprobe *old_p,
                struct kprobe *p, unsigned long flags)
 {
-       list_del(&p->list);
-       if (list_empty(&old_p->list)) {
+       list_del_rcu(&p->list);
+       if (list_empty(&old_p->list))
                cleanup_kprobe(old_p, flags);
-               kfree(old_p);
-       } else
+       else
                spin_unlock_irqrestore(&kprobe_lock, flags);
 }
 
@@ -480,9 +468,9 @@ int __kprobes register_kprobe(struct kprobe *p)
        if ((ret = arch_prepare_kprobe(p)) != 0)
                goto rm_kprobe;
 
+       p->nmissed = 0;
        spin_lock_irqsave(&kprobe_lock, flags);
        old_p = get_kprobe(p->addr);
-       p->nmissed = 0;
        if (old_p) {
                ret = register_aggr_kprobe(old_p, p);
                goto out;
@@ -490,7 +478,7 @@ int __kprobes register_kprobe(struct kprobe *p)
 
        arch_copy_kprobe(p);
        INIT_HLIST_NODE(&p->hlist);
-       hlist_add_head(&p->hlist,
+       hlist_add_head_rcu(&p->hlist,
                       &kprobe_table[hash_ptr(p->addr, KPROBE_HASH_BITS)]);
 
        arch_arm_kprobe(p);
@@ -511,10 +499,16 @@ void __kprobes unregister_kprobe(struct kprobe *p)
        spin_lock_irqsave(&kprobe_lock, flags);
        old_p = get_kprobe(p->addr);
        if (old_p) {
+               /* cleanup_*_kprobe() does the spin_unlock_irqrestore */
                if (old_p->pre_handler == aggr_pre_handler)
                        cleanup_aggr_kprobe(old_p, p, flags);
                else
                        cleanup_kprobe(p, flags);
+
+               synchronize_sched();
+               if (old_p->pre_handler == aggr_pre_handler &&
+                               list_empty(&old_p->list))
+                       kfree(old_p);
        } else
                spin_unlock_irqrestore(&kprobe_lock, flags);
 }
@@ -591,13 +585,13 @@ void __kprobes unregister_kretprobe(struct kretprobe *rp)
 
        unregister_kprobe(&rp->kp);
        /* No race here */
-       spin_lock_irqsave(&kprobe_lock, flags);
+       spin_lock_irqsave(&kretprobe_lock, flags);
        free_rp_inst(rp);
        while ((ri = get_used_rp_inst(rp)) != NULL) {
                ri->rp = NULL;
                hlist_del(&ri->uflist);
        }
-       spin_unlock_irqrestore(&kprobe_lock, flags);
+       spin_unlock_irqrestore(&kretprobe_lock, flags);
 }
 
 static int __init init_kprobes(void)
index ff5c500ab625202ef8401998bc0a71cac53424aa..2ea929d51ad08dc49e515d02bce7414c6cfdddbe 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/stop_machine.h>
 #include <linux/device.h>
 #include <linux/string.h>
+#include <linux/sched.h>
 #include <asm/uaccess.h>
 #include <asm/semaphore.h>
 #include <asm/cacheflush.h>
index 91a8942649413f48916196f4aed68deed9a1ae2b..84af54c39e1b0c31ff32854b45cbb15a512a4ba5 100644 (file)
@@ -497,7 +497,7 @@ static void process_timer_rebalance(struct task_struct *p,
                left = cputime_div(cputime_sub(expires.cpu, val.cpu),
                                   nthreads);
                do {
-                       if (!unlikely(t->flags & PF_EXITING)) {
+                       if (likely(!(t->flags & PF_EXITING))) {
                                ticks = cputime_add(prof_ticks(t), left);
                                if (cputime_eq(t->it_prof_expires,
                                               cputime_zero) ||
@@ -512,7 +512,7 @@ static void process_timer_rebalance(struct task_struct *p,
                left = cputime_div(cputime_sub(expires.cpu, val.cpu),
                                   nthreads);
                do {
-                       if (!unlikely(t->flags & PF_EXITING)) {
+                       if (likely(!(t->flags & PF_EXITING))) {
                                ticks = cputime_add(virt_ticks(t), left);
                                if (cputime_eq(t->it_virt_expires,
                                               cputime_zero) ||
@@ -527,7 +527,7 @@ static void process_timer_rebalance(struct task_struct *p,
                nsleft = expires.sched - val.sched;
                do_div(nsleft, nthreads);
                do {
-                       if (!unlikely(t->flags & PF_EXITING)) {
+                       if (likely(!(t->flags & PF_EXITING))) {
                                ns = t->sched_time + nsleft;
                                if (t->it_sched_expires == 0 ||
                                    t->it_sched_expires > ns) {
index 42a6287043983e93a67d54d5168c56df62a2e51c..723f5179883e57d054d13bbb53bf2854b70e1b00 100644 (file)
@@ -168,9 +168,8 @@ static unsigned count_data_pages(void)
 {
        struct zone *zone;
        unsigned long zone_pfn;
-       unsigned n;
+       unsigned int n = 0;
 
-       n = 0;
        for_each_zone (zone) {
                if (is_highmem(zone))
                        continue;
@@ -250,10 +249,10 @@ static inline void fill_pb_page(struct pbe *pbpage)
  *     of memory pages allocated with alloc_pagedir()
  */
 
-void create_pbe_list(struct pbe *pblist, unsigned nr_pages)
+void create_pbe_list(struct pbe *pblist, unsigned int nr_pages)
 {
        struct pbe *pbpage, *p;
-       unsigned num = PBES_PER_PAGE;
+       unsigned int num = PBES_PER_PAGE;
 
        for_each_pb_page (pbpage, pblist) {
                if (num >= nr_pages)
@@ -293,9 +292,9 @@ static void *alloc_image_page(void)
  *     On each page we set up a list of struct_pbe elements.
  */
 
-struct pbe *alloc_pagedir(unsigned nr_pages)
+struct pbe *alloc_pagedir(unsigned int nr_pages)
 {
-       unsigned num;
+       unsigned int num;
        struct pbe *pblist, *pbe;
 
        if (!nr_pages)
@@ -329,7 +328,7 @@ void swsusp_free(void)
        for_each_zone(zone) {
                for (zone_pfn = 0; zone_pfn < zone->spanned_pages; ++zone_pfn)
                        if (pfn_valid(zone_pfn + zone->zone_start_pfn)) {
-                               struct page * page;
+                               struct page *page;
                                page = pfn_to_page(zone_pfn + zone->zone_start_pfn);
                                if (PageNosave(page) && PageNosaveFree(page)) {
                                        ClearPageNosave(page);
@@ -348,7 +347,7 @@ void swsusp_free(void)
  *     free pages.
  */
 
-static int enough_free_mem(unsigned nr_pages)
+static int enough_free_mem(unsigned int nr_pages)
 {
        pr_debug("swsusp: available memory: %u pages\n", nr_free_pages());
        return nr_free_pages() > (nr_pages + PAGES_FOR_IO +
@@ -356,7 +355,7 @@ static int enough_free_mem(unsigned nr_pages)
 }
 
 
-static struct pbe *swsusp_alloc(unsigned nr_pages)
+static struct pbe *swsusp_alloc(unsigned int nr_pages)
 {
        struct pbe *pblist, *p;
 
@@ -380,7 +379,7 @@ static struct pbe *swsusp_alloc(unsigned nr_pages)
 
 asmlinkage int swsusp_save(void)
 {
-       unsigned nr_pages;
+       unsigned int nr_pages;
 
        pr_debug("swsusp: critical section: \n");
        if (save_highmem()) {
index 12db1d2ad61f89e5667f21f339b2bd9c3fd3969f..e1ab28b9b2176fe14c364fb00485e9d0c2067900 100644 (file)
@@ -85,18 +85,11 @@ unsigned int nr_copy_pages __nosavedata = 0;
 /* Suspend pagedir is allocated before final copy, therefore it
    must be freed after resume
 
-   Warning: this is evil. There are actually two pagedirs at time of
-   resume. One is "pagedir_save", which is empty frame allocated at
-   time of suspend, that must be freed. Second is "pagedir_nosave",
-   allocated at time of resume, that travels through memory not to
-   collide with anything.
-
    Warning: this is even more evil than it seems. Pagedirs this file
    talks about are completely different from page directories used by
    MMU hardware.
  */
 suspend_pagedir_t *pagedir_nosave __nosavedata = NULL;
-suspend_pagedir_t *pagedir_save;
 
 #define SWSUSP_SIG     "S1SUSPEND"
 
@@ -122,8 +115,8 @@ static struct swsusp_info swsusp_info;
 static unsigned short swapfile_used[MAX_SWAPFILES];
 static unsigned short root_swap;
 
-static int write_page(unsigned long addr, swp_entry_t * loc);
-static int bio_read_page(pgoff_t page_off, void * page);
+static int write_page(unsigned long addr, swp_entry_t *loc);
+static int bio_read_page(pgoff_t page_off, void *page);
 
 static u8 key_iv[MAXKEY+MAXIV];
 
@@ -355,7 +348,7 @@ static void lock_swapdevices(void)
  *     This is a partial improvement, since we will at least return other
  *     errors, though we need to eventually fix the damn code.
  */
-static int write_page(unsigned long addr, swp_entry_t * loc)
+static int write_page(unsigned long addr, swp_entry_t *loc)
 {
        swp_entry_t entry;
        int error = 0;
@@ -383,9 +376,9 @@ static int write_page(unsigned long addr, swp_entry_t * loc)
 static void data_free(void)
 {
        swp_entry_t entry;
-       struct pbe * p;
+       struct pbe *p;
 
-       for_each_pbe(p, pagedir_nosave) {
+       for_each_pbe (p, pagedir_nosave) {
                entry = p->swap_address;
                if (entry.val)
                        swap_free(entry);
@@ -492,8 +485,8 @@ static void free_pagedir_entries(void)
 static int write_pagedir(void)
 {
        int error = 0;
-       unsigned n = 0;
-       struct pbe * pbe;
+       unsigned int n = 0;
+       struct pbe *pbe;
 
        printk( "Writing pagedir...");
        for_each_pb_page (pbe, pagedir_nosave) {
@@ -543,7 +536,7 @@ static int write_suspend_image(void)
  *     We should only consider resume_device.
  */
 
-int enough_swap(unsigned nr_pages)
+int enough_swap(unsigned int nr_pages)
 {
        struct sysinfo i;
 
@@ -694,7 +687,7 @@ static int check_pagedir(struct pbe *pblist)
  *     restore from the loaded pages later.  We relocate them here.
  */
 
-static struct pbe * swsusp_pagedir_relocate(struct pbe *pblist)
+static struct pbe *swsusp_pagedir_relocate(struct pbe *pblist)
 {
        struct zone *zone;
        unsigned long zone_pfn;
@@ -770,7 +763,7 @@ static struct pbe * swsusp_pagedir_relocate(struct pbe *pblist)
 
 static atomic_t io_done = ATOMIC_INIT(0);
 
-static int end_io(struct bio * bio, unsigned int num, int err)
+static int end_io(struct bio *bio, unsigned int num, int err)
 {
        if (!test_bit(BIO_UPTODATE, &bio->bi_flags))
                panic("I/O error reading memory image");
@@ -778,7 +771,7 @@ static int end_io(struct bio * bio, unsigned int num, int err)
        return 0;
 }
 
-static struct block_device * resume_bdev;
+static struct block_device *resume_bdev;
 
 /**
  *     submit - submit BIO request.
@@ -791,10 +784,10 @@ static struct block_device * resume_bdev;
  *     Then submit it and wait.
  */
 
-static int submit(int rw, pgoff_t page_off, void * page)
+static int submit(int rw, pgoff_t page_off, void *page)
 {
        int error = 0;
-       struct bio * bio;
+       struct bio *bio;
 
        bio = bio_alloc(GFP_ATOMIC, 1);
        if (!bio)
@@ -823,12 +816,12 @@ static int submit(int rw, pgoff_t page_off, void * page)
        return error;
 }
 
-static int bio_read_page(pgoff_t page_off, void * page)
+static int bio_read_page(pgoff_t page_off, void *page)
 {
        return submit(READ, page_off, page);
 }
 
-static int bio_write_page(pgoff_t page_off, void * page)
+static int bio_write_page(pgoff_t page_off, void *page)
 {
        return submit(WRITE, page_off, page);
 }
@@ -838,7 +831,7 @@ static int bio_write_page(pgoff_t page_off, void * page)
  * I really don't think that it's foolproof but more than nothing..
  */
 
-static const char * sanity_check(void)
+static const char *sanity_check(void)
 {
        dump_info();
        if (swsusp_info.version_code != LINUX_VERSION_CODE)
@@ -864,7 +857,7 @@ static const char * sanity_check(void)
 
 static int check_header(void)
 {
-       const char * reason = NULL;
+       const char *reason = NULL;
        int error;
 
        if ((error = bio_read_page(swp_offset(swsusp_header.swsusp_info), &swsusp_info)))
@@ -912,7 +905,7 @@ static int check_sig(void)
 
 static int data_read(struct pbe *pblist)
 {
-       struct pbe * p;
+       struct pbe *p;
        int error = 0;
        int i = 0;
        int mod = swsusp_info.image_pages / 100;
@@ -950,7 +943,7 @@ static int data_read(struct pbe *pblist)
 static int read_pagedir(struct pbe *pblist)
 {
        struct pbe *pbpage, *p;
-       unsigned i = 0;
+       unsigned int i = 0;
        int error;
 
        if (!pblist)
index 3cb9708209bcb94a9d30a4c807f760ae485bf0c4..e9be027bc9300d03322a7ecf5681bdb2dec69f4b 100644 (file)
@@ -806,7 +806,6 @@ void console_unblank(void)
                        c->unblank();
        release_console_sem();
 }
-EXPORT_SYMBOL(console_unblank);
 
 /*
  * Return the console tty driver structure and its associated index
index 863eee8bff4763d949489d17bdfd9cef33cbca6c..5b8dd98a230e442c1ec46adc968acb60dfdb74ae 100644 (file)
@@ -406,3 +406,85 @@ int ptrace_request(struct task_struct *child, long request,
 
        return ret;
 }
+
+#ifndef __ARCH_SYS_PTRACE
+static int ptrace_get_task_struct(long request, long pid,
+               struct task_struct **childp)
+{
+       struct task_struct *child;
+       int ret;
+
+       /*
+        * Callers use child == NULL as an indication to exit early even
+        * when the return value is 0, so make sure it is non-NULL here.
+        */
+       *childp = NULL;
+
+       if (request == PTRACE_TRACEME) {
+               /*
+                * Are we already being traced?
+                */
+               if (current->ptrace & PT_PTRACED)
+                       return -EPERM;
+               ret = security_ptrace(current->parent, current);
+               if (ret)
+                       return -EPERM;
+               /*
+                * Set the ptrace bit in the process ptrace flags.
+                */
+               current->ptrace |= PT_PTRACED;
+               return 0;
+       }
+
+       /*
+        * You may not mess with init
+        */
+       if (pid == 1)
+               return -EPERM;
+
+       ret = -ESRCH;
+       read_lock(&tasklist_lock);
+       child = find_task_by_pid(pid);
+       if (child)
+               get_task_struct(child);
+       read_unlock(&tasklist_lock);
+       if (!child)
+               return -ESRCH;
+
+       *childp = child;
+       return 0;
+}
+
+asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
+{
+       struct task_struct *child;
+       long ret;
+
+       /*
+        * This lock_kernel fixes a subtle race with suid exec
+        */
+       lock_kernel();
+       ret = ptrace_get_task_struct(request, pid, &child);
+       if (!child)
+               goto out;
+
+       if (request == PTRACE_ATTACH) {
+               ret = ptrace_attach(child);
+               goto out;
+       }
+
+       ret = ptrace_check_attach(child, request == PTRACE_KILL);
+       if (ret < 0)
+               goto out_put_task_struct;
+
+       ret = arch_ptrace(child, request, addr, data);
+       if (ret < 0)
+               goto out_put_task_struct;
+
+ out_put_task_struct:
+       put_task_struct(child);
+ out:
+       unlock_kernel();
+       return ret;
+}
+#endif /* __ARCH_SYS_PTRACE */
index b4f4eb6135372d258d51ded475ff68c5517c2614..3ce26954be1284e4f74abf0c5ca602f6d46dbef0 100644 (file)
@@ -3563,8 +3563,6 @@ int idle_cpu(int cpu)
        return cpu_curr(cpu) == cpu_rq(cpu)->idle;
 }
 
-EXPORT_SYMBOL_GPL(idle_cpu);
-
 /**
  * idle_task - return the idle task for a given cpu.
  * @cpu: the processor in question.
@@ -4680,7 +4678,8 @@ static int migration_call(struct notifier_block *nfb, unsigned long action,
 #ifdef CONFIG_HOTPLUG_CPU
        case CPU_UP_CANCELED:
                /* Unbind it from offline cpu so it can run.  Fall thru. */
-               kthread_bind(cpu_rq(cpu)->migration_thread,smp_processor_id());
+               kthread_bind(cpu_rq(cpu)->migration_thread,
+                            any_online_cpu(cpu_online_map));
                kthread_stop(cpu_rq(cpu)->migration_thread);
                cpu_rq(cpu)->migration_thread = NULL;
                break;
index f766b2fc48be8cd54cc254c91660ec414603a2c5..ad3295cdded55032f248bf53dc6b908c56702581 100644 (file)
@@ -470,7 +470,8 @@ static int __devinit cpu_callback(struct notifier_block *nfb,
 #ifdef CONFIG_HOTPLUG_CPU
        case CPU_UP_CANCELED:
                /* Unbind so it can run.  Fall thru. */
-               kthread_bind(per_cpu(ksoftirqd, hotcpu), smp_processor_id());
+               kthread_bind(per_cpu(ksoftirqd, hotcpu),
+                            any_online_cpu(cpu_online_map));
        case CPU_DEAD:
                p = per_cpu(ksoftirqd, hotcpu);
                per_cpu(ksoftirqd, hotcpu) = NULL;
index 75976209cea7dbf44549b2bfca079142accb45a4..a2dcceb9437d61561caf1f85b0099cd4cd9e262d 100644 (file)
@@ -123,7 +123,8 @@ cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu)
 #ifdef CONFIG_HOTPLUG_CPU
        case CPU_UP_CANCELED:
                /* Unbind so it can run.  Fall thru. */
-               kthread_bind(per_cpu(watchdog_task, hotcpu), smp_processor_id());
+               kthread_bind(per_cpu(watchdog_task, hotcpu),
+                            any_online_cpu(cpu_online_map));
        case CPU_DEAD:
                p = per_cpu(watchdog_task, hotcpu);
                per_cpu(watchdog_task, hotcpu) = NULL;
index 2fa1ed18123cb8c84f241d4a19e1ed9b2727574e..c43b3e22bbda5b215515ca54c1f359e5a776c896 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/suspend.h>
 #include <linux/tty.h>
 #include <linux/signal.h>
+#include <linux/cn_proc.h>
 
 #include <linux/compat.h>
 #include <linux/syscalls.h>
@@ -375,18 +376,21 @@ void emergency_restart(void)
 }
 EXPORT_SYMBOL_GPL(emergency_restart);
 
-/**
- *     kernel_restart - reboot the system
- *
- *     Shutdown everything and perform a clean reboot.
- *     This is not safe to call in interrupt context.
- */
 void kernel_restart_prepare(char *cmd)
 {
        notifier_call_chain(&reboot_notifier_list, SYS_RESTART, cmd);
        system_state = SYSTEM_RESTART;
        device_shutdown();
 }
+
+/**
+ *     kernel_restart - reboot the system
+ *     @cmd: pointer to buffer containing command to execute for restart
+ *             or %NULL
+ *
+ *     Shutdown everything and perform a clean reboot.
+ *     This is not safe to call in interrupt context.
+ */
 void kernel_restart(char *cmd)
 {
        kernel_restart_prepare(cmd);
@@ -623,6 +627,7 @@ asmlinkage long sys_setregid(gid_t rgid, gid_t egid)
        current->egid = new_egid;
        current->gid = new_rgid;
        key_fsgid_changed(current);
+       proc_id_connector(current, PROC_EVENT_GID);
        return 0;
 }
 
@@ -662,6 +667,7 @@ asmlinkage long sys_setgid(gid_t gid)
                return -EPERM;
 
        key_fsgid_changed(current);
+       proc_id_connector(current, PROC_EVENT_GID);
        return 0;
 }
   
@@ -751,6 +757,7 @@ asmlinkage long sys_setreuid(uid_t ruid, uid_t euid)
        current->fsuid = current->euid;
 
        key_fsuid_changed(current);
+       proc_id_connector(current, PROC_EVENT_UID);
 
        return security_task_post_setuid(old_ruid, old_euid, old_suid, LSM_SETID_RE);
 }
@@ -798,6 +805,7 @@ asmlinkage long sys_setuid(uid_t uid)
        current->suid = new_suid;
 
        key_fsuid_changed(current);
+       proc_id_connector(current, PROC_EVENT_UID);
 
        return security_task_post_setuid(old_ruid, old_euid, old_suid, LSM_SETID_ID);
 }
@@ -846,6 +854,7 @@ asmlinkage long sys_setresuid(uid_t ruid, uid_t euid, uid_t suid)
                current->suid = suid;
 
        key_fsuid_changed(current);
+       proc_id_connector(current, PROC_EVENT_UID);
 
        return security_task_post_setuid(old_ruid, old_euid, old_suid, LSM_SETID_RES);
 }
@@ -898,6 +907,7 @@ asmlinkage long sys_setresgid(gid_t rgid, gid_t egid, gid_t sgid)
                current->sgid = sgid;
 
        key_fsgid_changed(current);
+       proc_id_connector(current, PROC_EVENT_GID);
        return 0;
 }
 
@@ -940,6 +950,7 @@ asmlinkage long sys_setfsuid(uid_t uid)
        }
 
        key_fsuid_changed(current);
+       proc_id_connector(current, PROC_EVENT_UID);
 
        security_task_post_setuid(old_fsuid, (uid_t)-1, (uid_t)-1, LSM_SETID_FS);
 
@@ -968,6 +979,7 @@ asmlinkage long sys_setfsgid(gid_t gid)
                }
                current->fsgid = gid;
                key_fsgid_changed(current);
+               proc_id_connector(current, PROC_EVENT_GID);
        }
        return old_fsgid;
 }
@@ -1485,8 +1497,6 @@ EXPORT_SYMBOL(in_egroup_p);
 
 DECLARE_RWSEM(uts_sem);
 
-EXPORT_SYMBOL(uts_sem);
-
 asmlinkage long sys_newuname(struct new_utsname __user * name)
 {
        int errno = 0;
index 8e56e2495542be41fa688aa7a15604cb2e3e6897..c4f35f96884df814c665d0287eba465033d9eabe 100644 (file)
@@ -952,7 +952,7 @@ static ctl_table fs_table[] = {
                .data           = &aio_nr,
                .maxlen         = sizeof(aio_nr),
                .mode           = 0444,
-               .proc_handler   = &proc_dointvec,
+               .proc_handler   = &proc_doulongvec_minmax,
        },
        {
                .ctl_name       = FS_AIO_MAX_NR,
@@ -960,7 +960,7 @@ static ctl_table fs_table[] = {
                .data           = &aio_max_nr,
                .maxlen         = sizeof(aio_max_nr),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec,
+               .proc_handler   = &proc_doulongvec_minmax,
        },
 #ifdef CONFIG_INOTIFY
        {
@@ -1997,6 +1997,7 @@ int proc_dointvec_jiffies(ctl_table *table, int write, struct file *filp,
  * @filp: the file structure
  * @buffer: the user buffer
  * @lenp: the size of the user buffer
+ * @ppos: pointer to the file position
  *
  * Reads/writes up to table->maxlen/sizeof(unsigned int) integer
  * values from/to the user buffer, treated as an ASCII string. 
index 7cee222231bc46843d7d5b68acbb82f375c1af71..42df83d7fad21d7176efdfef13282ef693f3c6ba 100644 (file)
@@ -524,7 +524,7 @@ static int __devinit workqueue_cpu_callback(struct notifier_block *nfb,
                list_for_each_entry(wq, &workqueues, list) {
                        /* Unbind so it can run. */
                        kthread_bind(per_cpu_ptr(wq->cpu_wq, hotcpu)->thread,
-                                    smp_processor_id());
+                                    any_online_cpu(cpu_online_map));
                        cleanup_workqueue_thread(wq, hotcpu);
                }
                break;
index d1c057e71b683db7328f1c8ef619e93866e486cf..88511c3805ad77fc9515b7a75bdc52e09a6393df 100644 (file)
@@ -281,35 +281,60 @@ int radix_tree_insert(struct radix_tree_root *root,
 }
 EXPORT_SYMBOL(radix_tree_insert);
 
-/**
- *     radix_tree_lookup    -    perform lookup operation on a radix tree
- *     @root:          radix tree root
- *     @index:         index key
- *
- *     Lookup the item at the position @index in the radix tree @root.
- */
-void *radix_tree_lookup(struct radix_tree_root *root, unsigned long index)
+static inline void **__lookup_slot(struct radix_tree_root *root,
+                                  unsigned long index)
 {
        unsigned int height, shift;
-       struct radix_tree_node *slot;
+       struct radix_tree_node **slot;
 
        height = root->height;
        if (index > radix_tree_maxindex(height))
                return NULL;
 
        shift = (height-1) * RADIX_TREE_MAP_SHIFT;
-       slot = root->rnode;
+       slot = &root->rnode;
 
        while (height > 0) {
-               if (slot == NULL)
+               if (*slot == NULL)
                        return NULL;
 
-               slot = slot->slots[(index >> shift) & RADIX_TREE_MAP_MASK];
+               slot = (struct radix_tree_node **)
+                       ((*slot)->slots +
+                               ((index >> shift) & RADIX_TREE_MAP_MASK));
                shift -= RADIX_TREE_MAP_SHIFT;
                height--;
        }
 
-       return slot;
+       return (void **)slot;
+}
+
+/**
+ *     radix_tree_lookup_slot    -    lookup a slot in a radix tree
+ *     @root:          radix tree root
+ *     @index:         index key
+ *
+ *     Lookup the slot corresponding to the position @index in the radix tree
+ *     @root. This is useful for update-if-exists operations.
+ */
+void **radix_tree_lookup_slot(struct radix_tree_root *root, unsigned long index)
+{
+       return __lookup_slot(root, index);
+}
+EXPORT_SYMBOL(radix_tree_lookup_slot);
+
+/**
+ *     radix_tree_lookup    -    perform lookup operation on a radix tree
+ *     @root:          radix tree root
+ *     @index:         index key
+ *
+ *     Lookup the item at the position @index in the radix tree @root.
+ */
+void *radix_tree_lookup(struct radix_tree_root *root, unsigned long index)
+{
+       void **slot;
+
+       slot = __lookup_slot(root, index);
+       return slot != NULL ? *slot : NULL;
 }
 EXPORT_SYMBOL(radix_tree_lookup);
 
index 1a4473fcb2ca0d2ea163301ba49d740d78310e8b..ae9ce6b73e8a8351d1a5533349f141bbb5492e3a 100644 (file)
@@ -126,9 +126,11 @@ comment "Memory hotplug is currently incompatible with Software Suspend"
 # Default to 4 for wider testing, though 8 might be more appropriate.
 # ARM's adjust_pte (unused if VIPT) depends on mm-wide page_table_lock.
 # PA-RISC's debug spinlock_t is too large for the 32-bit struct page.
+# ARM26 and SPARC32 and PPC64 may use one page for multiple page tables.
 #
 config SPLIT_PTLOCK_CPUS
        int
        default "4096" if ARM && !CPU_CACHE_VIPT
        default "4096" if PARISC && DEBUG_SPINLOCK && !64BIT
+       default "4096" if ARM26 || SPARC32 || PPC64
        default "4"
index 9a565808da3fac6cad64e7412aa2d12f1a75eb70..728e9bda12ea9971c1cf0212184b1ca2c2d94020 100644 (file)
@@ -237,7 +237,6 @@ unsigned long hugetlb_total_pages(void)
 {
        return nr_huge_pages * (HPAGE_SIZE / PAGE_SIZE);
 }
-EXPORT_SYMBOL(hugetlb_total_pages);
 
 /*
  * We cannot handle pagefaults against hugetlb pages at all.  They cause
index 320dda1778c3b3489aea3a44e12251f939e75e3c..6c997b159600b89b6d6cb4b5a4059e8adf3b0e92 100644 (file)
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -155,10 +155,6 @@ int __vm_enough_memory(long pages, int cap_sys_admin)
        return -ENOMEM;
 }
 
-EXPORT_SYMBOL(sysctl_overcommit_memory);
-EXPORT_SYMBOL(sysctl_overcommit_ratio);
-EXPORT_SYMBOL(sysctl_max_map_count);
-EXPORT_SYMBOL(vm_committed_space);
 EXPORT_SYMBOL(__vm_enough_memory);
 
 /*
index d1e076a487cbe3eff161ca2f2472186977f30e41..6deb6ab3d6ada1a27cfcbc65303fa1403d498ac0 100644 (file)
@@ -44,10 +44,6 @@ int sysctl_max_map_count = DEFAULT_MAX_MAP_COUNT;
 int heap_stack_gap = 0;
 
 EXPORT_SYMBOL(mem_map);
-EXPORT_SYMBOL(sysctl_max_map_count);
-EXPORT_SYMBOL(sysctl_overcommit_memory);
-EXPORT_SYMBOL(sysctl_overcommit_ratio);
-EXPORT_SYMBOL(vm_committed_space);
 EXPORT_SYMBOL(__vm_enough_memory);
 
 /* list of shareable VMAs */
index 0166ea15c9ee8d61f08ddc6e100de841e59205c7..74138c9a22b982a9a74fb4076e41826a0d56c3b5 100644 (file)
@@ -750,7 +750,6 @@ int clear_page_dirty_for_io(struct page *page)
        }
        return TestClearPageDirty(page);
 }
-EXPORT_SYMBOL(clear_page_dirty_for_io);
 
 int test_clear_page_writeback(struct page *page)
 {
index 2dbdd98426fd46f9270d45acb081b7554df1740d..ff81b5c65511df6a1604f486ba6fae44553cb8e4 100644 (file)
@@ -64,7 +64,6 @@ long nr_swap_pages;
 int sysctl_lowmem_reserve_ratio[MAX_NR_ZONES-1] = { 256, 32 };
 
 EXPORT_SYMBOL(totalram_pages);
-EXPORT_SYMBOL(nr_swap_pages);
 
 /*
  * Used by page_zone() to look up the address of the struct zone whose
index d0b50034e245a0095c7d359388b59676af0bdb59..72e7adbb87c7dd1e08cc1eb2851bdb96300d7e02 100644 (file)
@@ -254,7 +254,7 @@ out:
  */
 static int
 __do_page_cache_readahead(struct address_space *mapping, struct file *filp,
-                       unsigned long offset, unsigned long nr_to_read)
+                       pgoff_t offset, unsigned long nr_to_read)
 {
        struct inode *inode = mapping->host;
        struct page *page;
@@ -274,7 +274,7 @@ __do_page_cache_readahead(struct address_space *mapping, struct file *filp,
         */
        read_lock_irq(&mapping->tree_lock);
        for (page_idx = 0; page_idx < nr_to_read; page_idx++) {
-               unsigned long page_offset = offset + page_idx;
+               pgoff_t page_offset = offset + page_idx;
                
                if (page_offset > end_index)
                        break;
@@ -311,7 +311,7 @@ out:
  * memory at once.
  */
 int force_page_cache_readahead(struct address_space *mapping, struct file *filp,
-               unsigned long offset, unsigned long nr_to_read)
+               pgoff_t offset, unsigned long nr_to_read)
 {
        int ret = 0;
 
@@ -368,7 +368,7 @@ static inline int check_ra_success(struct file_ra_state *ra,
  * request queues.
  */
 int do_page_cache_readahead(struct address_space *mapping, struct file *filp,
-                       unsigned long offset, unsigned long nr_to_read)
+                       pgoff_t offset, unsigned long nr_to_read)
 {
        if (bdi_read_congested(mapping->backing_dev_info))
                return -1;
@@ -385,7 +385,7 @@ int do_page_cache_readahead(struct address_space *mapping, struct file *filp,
  */
 static int
 blockable_page_cache_readahead(struct address_space *mapping, struct file *filp,
-                       unsigned long offset, unsigned long nr_to_read,
+                       pgoff_t offset, unsigned long nr_to_read,
                        struct file_ra_state *ra, int block)
 {
        int actual;
@@ -430,14 +430,27 @@ static int make_ahead_window(struct address_space *mapping, struct file *filp,
        return ret;
 }
 
-/*
- * page_cache_readahead is the main function.  If performs the adaptive
+/**
+ * page_cache_readahead - generic adaptive readahead
+ * @mapping: address_space which holds the pagecache and I/O vectors
+ * @ra: file_ra_state which holds the readahead state
+ * @filp: passed on to ->readpage() and ->readpages()
+ * @offset: start offset into @mapping, in PAGE_CACHE_SIZE units
+ * @req_size: hint: total size of the read which the caller is performing in
+ *            PAGE_CACHE_SIZE units
+ *
+ * page_cache_readahead() is the main function.  If performs the adaptive
  * readahead window size management and submits the readahead I/O.
+ *
+ * Note that @filp is purely used for passing on to the ->readpage[s]()
+ * handler: it may refer to a different file from @mapping (so we may not use
+ * @filp->f_mapping or @filp->f_dentry->d_inode here).
+ * Also, @ra may not be equal to &@filp->f_ra.
+ *
  */
 unsigned long
 page_cache_readahead(struct address_space *mapping, struct file_ra_state *ra,
-                    struct file *filp, unsigned long offset,
-                    unsigned long req_size)
+                    struct file *filp, pgoff_t offset, unsigned long req_size)
 {
        unsigned long max, newsize;
        int sequential;
index 22bfb0b2ac8b441d479bbfe16028fa7e0db132e8..e291f5e1afbb3acd9d53ad3646527e2f06c3169f 100644 (file)
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -368,7 +368,7 @@ static inline void kmem_list3_init(struct kmem_list3 *parent)
  * manages a cache.
  */
        
-struct kmem_cache_s {
+struct kmem_cache {
 /* 1) per-cpu data, touched during every alloc/free */
        struct array_cache      *array[NR_CPUS];
        unsigned int            batchcount;
@@ -1502,6 +1502,7 @@ kmem_cache_create (const char *name, size_t size, size_t align,
 {
        size_t left_over, slab_size, ralign;
        kmem_cache_t *cachep = NULL;
+       struct list_head *p;
 
        /*
         * Sanity checks... these are all serious usage bugs.
@@ -1516,6 +1517,35 @@ kmem_cache_create (const char *name, size_t size, size_t align,
                        BUG();
                }
 
+       down(&cache_chain_sem);
+
+       list_for_each(p, &cache_chain) {
+               kmem_cache_t *pc = list_entry(p, kmem_cache_t, next);
+               mm_segment_t old_fs = get_fs();
+               char tmp;
+               int res;
+
+               /*
+                * This happens when the module gets unloaded and doesn't
+                * destroy its slab cache and no-one else reuses the vmalloc
+                * area of the module.  Print a warning.
+                */
+               set_fs(KERNEL_DS);
+               res = __get_user(tmp, pc->name);
+               set_fs(old_fs);
+               if (res) {
+                       printk("SLAB: cache with size %d has lost its name\n",
+                                       pc->objsize);
+                       continue;
+               }
+
+               if (!strcmp(pc->name,name)) {
+                       printk("kmem_cache_create: duplicate cache %s\n", name);
+                       dump_stack();
+                       goto oops;
+               }
+       }
+
 #if DEBUG
        WARN_ON(strchr(name, ' '));     /* It confuses parsers */
        if ((flags & SLAB_DEBUG_INITIAL) && !ctor) {
@@ -1592,7 +1622,7 @@ kmem_cache_create (const char *name, size_t size, size_t align,
        /* Get cache's description obj. */
        cachep = (kmem_cache_t *) kmem_cache_alloc(&cache_cache, SLAB_KERNEL);
        if (!cachep)
-               goto opps;
+               goto oops;
        memset(cachep, 0, sizeof(kmem_cache_t));
 
 #if DEBUG
@@ -1686,7 +1716,7 @@ next:
                printk("kmem_cache_create: couldn't create cache %s.\n", name);
                kmem_cache_free(&cache_cache, cachep);
                cachep = NULL;
-               goto opps;
+               goto oops;
        }
        slab_size = ALIGN(cachep->num*sizeof(kmem_bufctl_t)
                                + sizeof(struct slab), align);
@@ -1781,43 +1811,14 @@ next:
                cachep->limit = BOOT_CPUCACHE_ENTRIES;
        } 
 
-       /* Need the semaphore to access the chain. */
-       down(&cache_chain_sem);
-       {
-               struct list_head *p;
-               mm_segment_t old_fs;
-
-               old_fs = get_fs();
-               set_fs(KERNEL_DS);
-               list_for_each(p, &cache_chain) {
-                       kmem_cache_t *pc = list_entry(p, kmem_cache_t, next);
-                       char tmp;
-                       /* This happens when the module gets unloaded and doesn't
-                          destroy its slab cache and noone else reuses the vmalloc
-                          area of the module. Print a warning. */
-                       if (__get_user(tmp,pc->name)) { 
-                               printk("SLAB: cache with size %d has lost its name\n", 
-                                       pc->objsize); 
-                               continue; 
-                       }       
-                       if (!strcmp(pc->name,name)) { 
-                               printk("kmem_cache_create: duplicate cache %s\n",name); 
-                               up(&cache_chain_sem); 
-                               unlock_cpu_hotplug();
-                               BUG(); 
-                       }       
-               }
-               set_fs(old_fs);
-       }
-
        /* cache setup completed, link it into the list */
        list_add(&cachep->next, &cache_chain);
-       up(&cache_chain_sem);
        unlock_cpu_hotplug();
-opps:
+oops:
        if (!cachep && (flags & SLAB_PANIC))
                panic("kmem_cache_create(): failed to create slab `%s'\n",
                        name);
+       up(&cache_chain_sem);
        return cachep;
 }
 EXPORT_SYMBOL(kmem_cache_create);
@@ -3262,6 +3263,7 @@ static void drain_array_locked(kmem_cache_t *cachep,
 
 /**
  * cache_reap - Reclaim memory from caches.
+ * @unused: unused parameter
  *
  * Called from workqueue/eventd every few seconds.
  * Purpose:
@@ -3278,7 +3280,7 @@ static void cache_reap(void *unused)
 
        if (down_trylock(&cache_chain_sem)) {
                /* Give up. Setup the next iteration. */
-               schedule_delayed_work(&__get_cpu_var(reap_work), REAPTIMEOUT_CPUC + smp_processor_id());
+               schedule_delayed_work(&__get_cpu_var(reap_work), REAPTIMEOUT_CPUC);
                return;
        }
 
@@ -3347,7 +3349,7 @@ next:
        up(&cache_chain_sem);
        drain_remote_pages();
        /* Setup the next iteration */
-       schedule_delayed_work(&__get_cpu_var(reap_work), REAPTIMEOUT_CPUC + smp_processor_id());
+       schedule_delayed_work(&__get_cpu_var(reap_work), REAPTIMEOUT_CPUC);
 }
 
 #ifdef CONFIG_PROC_FS
index 154ae13d8b7e33bd9f5d929b2c7e4c16ab38590c..d09cf7f03e767e57e500ac5f6dd4c35c72c5f9a4 100644 (file)
--- a/mm/swap.c
+++ b/mm/swap.c
@@ -413,7 +413,6 @@ void vm_acct_memory(long pages)
        }
        preempt_enable();
 }
-EXPORT_SYMBOL(vm_acct_memory);
 
 #ifdef CONFIG_HOTPLUG_CPU
 static void lru_drain_cache(unsigned int cpu)
index dfd9a46755b84f7ffdcc97e6526d9a0665062b6c..0df9a57b1de84bca534a9f6cc0c32d1ddefb939a 100644 (file)
@@ -40,7 +40,6 @@ struct address_space swapper_space = {
        .i_mmap_nonlinear = LIST_HEAD_INIT(swapper_space.i_mmap_nonlinear),
        .backing_dev_info = &swap_backing_dev_info,
 };
-EXPORT_SYMBOL(swapper_space);
 
 #define INC_CACHE_INFO(x)      do { swap_cache_info.x++; } while (0)
 
index 8970c0b74194f45f2bce26592399e9db40f2947b..edafeace301f01879e04d31c9bf9e5c01a4484e9 100644 (file)
@@ -36,8 +36,6 @@ unsigned int nr_swapfiles;
 long total_swap_pages;
 static int swap_overflow;
 
-EXPORT_SYMBOL(total_swap_pages);
-
 static const char Bad_file[] = "Bad swap file entry ";
 static const char Unused_file[] = "Unused swap file entry ";
 static const char Bad_offset[] = "Bad swap offset entry ";
index 54a90e83cb318aa32e2f8ee6adc28960ee1da32c..729eb3eec75fd7043b8b8a74e6b748b9390b0f6d 100644 (file)
@@ -457,7 +457,7 @@ void *__vmalloc_area(struct vm_struct *area, gfp_t gfp_mask, pgprot_t prot)
  *     @size:          allocation size
  *     @gfp_mask:      flags for the page level allocator
  *     @prot:          protection mask for the allocated pages
- *     @node           node to use for allocation or -1
+ *     @node:          node to use for allocation or -1
  *
  *     Allocate enough pages to cover @size from the page level
  *     allocator with @gfp_mask flags.  Map them into contiguous
@@ -507,7 +507,7 @@ EXPORT_SYMBOL(vmalloc);
  *     vmalloc_node  -  allocate memory on a specific node
  *
  *     @size:          allocation size
- *     @node;          numa node
+ *     @node:          numa node
  *
  *     Allocate enough pages to cover @size from the page level
  *     allocator and map them into contiguous kernel virtual space.
index e9bd91265f70854654e0624fd0a3120b299d82fe..5a220b2bb376f4669ecf4d267d1fa261d0b5b847 100644 (file)
@@ -313,6 +313,11 @@ svc_process(struct svc_serv *serv, struct svc_rqst *rqstp)
        rqstp->rq_proc = proc = ntohl(svc_getu32(argv));        /* procedure number */
 
        progp = serv->sv_program;
+
+       for (progp = serv->sv_program; progp; progp = progp->pg_next)
+               if (prog == progp->pg_prog)
+                       break;
+
        /*
         * Decode auth data, and add verifier to reply buffer.
         * We do this before anything else in order to get a decent
@@ -320,7 +325,7 @@ svc_process(struct svc_serv *serv, struct svc_rqst *rqstp)
         */
        auth_res = svc_authenticate(rqstp, &auth_stat);
        /* Also give the program a chance to reject this call: */
-       if (auth_res == SVC_OK) {
+       if (auth_res == SVC_OK && progp) {
                auth_stat = rpc_autherr_badcred;
                auth_res = progp->pg_authenticate(rqstp);
        }
@@ -340,10 +345,7 @@ svc_process(struct svc_serv *serv, struct svc_rqst *rqstp)
        case SVC_COMPLETE:
                goto sendit;
        }
-               
-       for (progp = serv->sv_program; progp; progp = progp->pg_next)
-               if (prog == progp->pg_prog)
-                       break;
+
        if (progp == NULL)
                goto err_bad_prog;
 
index 455aeabd95dd59a441566e2de9e2f80f1961fa26..c65c435c4923b52de56e8d024d773a53a01848d2 100644 (file)
@@ -118,7 +118,7 @@ clean-files := lkc_defs.h qconf.moc .tmp_qtcheck \
 
 # Needed for systems without gettext
 KBUILD_HAVE_NLS := $(shell \
-     if echo "\#include <libint.h>" | $(HOSTCC) $(HOSTCFLAGS) -E - > /dev/null 2>&1 ; \
+     if echo "\#include <libintl.h>" | $(HOSTCC) $(HOSTCFLAGS) -E - > /dev/null 2>&1 ; \
      then echo yes ; \
      else echo no ; fi)
 ifeq ($(KBUILD_HAVE_NLS),no)
index ccde17aff6167848388ce263c4fddec30c8131e5..01bcfecb7eae755d28189419736361d42a41bc26 100644 (file)
@@ -115,8 +115,7 @@ struct key_user *key_user_lookup(uid_t uid)
  found:
        atomic_inc(&user->usage);
        spin_unlock(&key_user_lock);
-       if (candidate)
-               kfree(candidate);
+       kfree(candidate);
  out:
        return user;
 
index e1cc4dd7901221352185e71daeffe1f3f779e325..c7a0ab1cfda35aacd868504c3033417c58c9e9e7 100644 (file)
@@ -434,8 +434,8 @@ ascend:
                if (sp >= KEYRING_SEARCH_MAX_DEPTH)
                        continue;
 
-               if (!key_task_permission(make_key_ref(key, possessed),
-                                        context, KEY_SEARCH) < 0)
+               if (key_task_permission(make_key_ref(key, possessed),
+                                       context, KEY_SEARCH) < 0)
                        continue;
 
                /* stack the current position */
@@ -621,8 +621,8 @@ struct key *find_keyring_by_name(const char *name, key_serial_t bound)
                        if (strcmp(keyring->description, name) != 0)
                                continue;
 
-                       if (!key_permission(make_key_ref(keyring, 0),
-                                           KEY_SEARCH) < 0)
+                       if (key_permission(make_key_ref(keyring, 0),
+                                          KEY_SEARCH) < 0)
                                continue;
 
                        /* found a potential candidate, but we still need to
index 2f5f539875f2d0e60b780b407deef7fb64aeecdb..0ac311dc8371ecd540168f200c535ae4a6f7ac12 100644 (file)
@@ -632,22 +632,22 @@ void policydb_destroy(struct policydb *p)
        cond_policydb_destroy(p);
 
        for (tr = p->role_tr; tr; tr = tr->next) {
-               if (ltr) kfree(ltr);
+               kfree(ltr);
                ltr = tr;
        }
-       if (ltr) kfree(ltr);
+       kfree(ltr);
 
        for (ra = p->role_allow; ra; ra = ra -> next) {
-               if (lra) kfree(lra);
+               kfree(lra);
                lra = ra;
        }
-       if (lra) kfree(lra);
+       kfree(lra);
 
        for (rt = p->range_tr; rt; rt = rt -> next) {
-               if (lrt) kfree(lrt);
+               kfree(lrt);
                lrt = rt;
        }
-       if (lrt) kfree(lrt);
+       kfree(lrt);
 
        if (p->type_attr_map) {
                for (i = 0; i < p->p_types.nprim; i++)
index 45edfd767e4e7b1edcc4cb14ad18a36961f6c5e6..5d008798c31018bdc1a0af6976476acce59347a9 100644 (file)
@@ -19,7 +19,6 @@ EXPORT_SYMBOL(sequencer_timer);
 EXPORT_SYMBOL(sound_timer_init);
 EXPORT_SYMBOL(sound_timer_interrupt);
 EXPORT_SYMBOL(sound_timer_syncinterval);
-EXPORT_SYMBOL(reprogram_timer);
 
 /* Tuning */