]> git.karo-electronics.de Git - linux-beck.git/commitdiff
Merge branch 'perf-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorLinus Torvalds <torvalds@linux-foundation.org>
Sat, 5 Dec 2009 23:30:21 +0000 (15:30 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 5 Dec 2009 23:30:21 +0000 (15:30 -0800)
* 'perf-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: (470 commits)
  x86: Fix comments of register/stack access functions
  perf tools: Replace %m with %a in sscanf
  hw-breakpoints: Keep track of user disabled breakpoints
  tracing/syscalls: Make syscall events print callbacks static
  tracing: Add DEFINE_EVENT(), DEFINE_SINGLE_EVENT() support to docbook
  perf: Don't free perf_mmap_data until work has been done
  perf_event: Fix compile error
  perf tools: Fix _GNU_SOURCE macro related strndup() build error
  trace_syscalls: Remove unused syscall_name_to_nr()
  trace_syscalls: Simplify syscall profile
  trace_syscalls: Remove duplicate init_enter_##sname()
  trace_syscalls: Add syscall_nr field to struct syscall_metadata
  trace_syscalls: Remove enter_id exit_id
  trace_syscalls: Set event_enter_##sname->data to its metadata
  trace_syscalls: Remove unused event_syscall_enter and event_syscall_exit
  perf_event: Initialize data.period in perf_swevent_hrtimer()
  perf probe: Simplify event naming
  perf probe: Add --list option for listing current probe events
  perf probe: Add argv_split() from lib/argv_split.c
  perf probe: Move probe event utility functions to probe-event.c
  ...

739 files changed:
.gitignore
Documentation/RCU/trace.txt
Documentation/RCU/whatisRCU.txt
Documentation/dontdiff
Documentation/fb/framebuffer.txt
Documentation/filesystems/caching/fscache.txt
Documentation/filesystems/caching/netfs-api.txt
Documentation/filesystems/ocfs2.txt
Documentation/kernel-parameters.txt
Documentation/pcmcia/driver-changes.txt
Documentation/slow-work.txt
Documentation/vm/page-types.c
MAINTAINERS
Makefile
arch/alpha/boot/tools/objstrip.c
arch/alpha/include/asm/fcntl.h
arch/alpha/include/asm/thread_info.h
arch/alpha/kernel/core_marvel.c
arch/alpha/kernel/core_titan.c
arch/alpha/kernel/irq.c
arch/alpha/kernel/irq_alpha.c
arch/alpha/kernel/irq_i8259.c
arch/alpha/kernel/irq_pyxis.c
arch/alpha/kernel/irq_srm.c
arch/alpha/kernel/sys_alcor.c
arch/alpha/kernel/sys_cabriolet.c
arch/alpha/kernel/sys_dp264.c
arch/alpha/kernel/sys_eb64p.c
arch/alpha/kernel/sys_eiger.c
arch/alpha/kernel/sys_jensen.c
arch/alpha/kernel/sys_marvel.c
arch/alpha/kernel/sys_mikasa.c
arch/alpha/kernel/sys_noritake.c
arch/alpha/kernel/sys_rawhide.c
arch/alpha/kernel/sys_ruffian.c
arch/alpha/kernel/sys_rx164.c
arch/alpha/kernel/sys_sable.c
arch/alpha/kernel/sys_takara.c
arch/alpha/kernel/sys_titan.c
arch/alpha/kernel/sys_wildfire.c
arch/arm/include/asm/kmap_types.h
arch/arm/kernel/signal.c
arch/arm/mach-at91/Kconfig
arch/arm/mach-at91/board-sam9g20ek-2slot-mmc.c
arch/arm/mach-kirkwood/common.c
arch/arm/mach-kirkwood/include/mach/bridge-regs.h
arch/arm/mach-mmp/include/mach/mfp-pxa910.h
arch/arm/mach-omap2/board-zoom2.c
arch/arm/mach-omap2/clock34xx.c
arch/arm/mach-omap2/clock34xx.h
arch/arm/mach-omap2/gpmc.c
arch/arm/mach-pxa/colibri-pxa320.c
arch/arm/mach-pxa/cpufreq-pxa2xx.c
arch/arm/mach-pxa/cpufreq-pxa3xx.c
arch/arm/mach-pxa/hx4700.c
arch/arm/mach-pxa/include/mach/entry-macro.S
arch/arm/mach-pxa/spitz.c
arch/arm/mach-u300/core.c
arch/arm/plat-omap/gpio.c
arch/arm/plat-pxa/include/plat/mfp.h
arch/arm/plat-pxa/mfp.c
arch/arm/tools/mach-types
arch/avr32/include/asm/bug.h
arch/blackfin/kernel/bfin_dma_5xx.c
arch/blackfin/kernel/cplb-mpu/cplbinit.c
arch/blackfin/kernel/process.c
arch/blackfin/kernel/ptrace.c
arch/blackfin/mach-bf518/include/mach/anomaly.h
arch/blackfin/mach-bf527/include/mach/anomaly.h
arch/blackfin/mach-bf533/include/mach/anomaly.h
arch/blackfin/mach-bf537/include/mach/anomaly.h
arch/blackfin/mach-bf538/include/mach/anomaly.h
arch/blackfin/mach-bf548/include/mach/anomaly.h
arch/blackfin/mach-bf561/atomic.S
arch/blackfin/mach-bf561/include/mach/anomaly.h
arch/blackfin/mach-common/arch_checks.c
arch/blackfin/mach-common/smp.c
arch/ia64/include/asm/swiotlb.h
arch/ia64/kernel/pci-swiotlb.c
arch/mips/Kconfig
arch/mips/bcm47xx/prom.c
arch/mips/configs/rbtx49xx_defconfig
arch/mips/include/asm/bug.h
arch/mips/include/asm/dma-mapping.h
arch/mips/include/asm/mman.h
arch/mips/include/asm/system.h
arch/mips/kernel/cevt-smtc.c
arch/mips/kernel/syscall.c
arch/mips/math-emu/cp1emu.c
arch/mips/mm/dma-default.c
arch/mips/mti-malta/malta-memory.c
arch/mips/rb532/devices.c
arch/mips/rb532/prom.c
arch/mips/txx9/generic/setup.c
arch/parisc/include/asm/fcntl.h
arch/parisc/kernel/unwind.c
arch/parisc/kernel/vmlinux.lds.S
arch/powerpc/boot/addRamDisk.c
arch/powerpc/include/asm/kmap_types.h
arch/powerpc/kernel/setup_32.c
arch/powerpc/kernel/setup_64.c
arch/s390/Kconfig
arch/s390/include/asm/bug.h
arch/s390/include/asm/spinlock.h
arch/s390/kernel/early.c
arch/s390/kernel/entry.S
arch/s390/kernel/entry64.S
arch/sh/kernel/cpu/irq/imask.c
arch/sh/kernel/cpu/irq/intc-sh5.c
arch/sparc/boot/btfixupprep.c
arch/sparc/boot/piggyback_32.c
arch/sparc/boot/piggyback_64.c
arch/sparc/mm/init_64.h
arch/x86/include/asm/amd_iommu.h
arch/x86/include/asm/amd_iommu_proto.h [new file with mode: 0644]
arch/x86/include/asm/amd_iommu_types.h
arch/x86/include/asm/bug.h
arch/x86/include/asm/calgary.h
arch/x86/include/asm/device.h
arch/x86/include/asm/dma-mapping.h
arch/x86/include/asm/gart.h
arch/x86/include/asm/iommu.h
arch/x86/include/asm/swiotlb.h
arch/x86/include/asm/x86_init.h
arch/x86/kernel/acpi/processor.c
arch/x86/kernel/amd_iommu.c
arch/x86/kernel/amd_iommu_init.c
arch/x86/kernel/aperture_64.c
arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
arch/x86/kernel/cpu/cpufreq/longhaul.c
arch/x86/kernel/cpu/cpufreq/powernow-k8.c
arch/x86/kernel/cpu/cpufreq/speedstep-ich.c
arch/x86/kernel/crash.c
arch/x86/kernel/pci-calgary_64.c
arch/x86/kernel/pci-dma.c
arch/x86/kernel/pci-gart_64.c
arch/x86/kernel/pci-nommu.c
arch/x86/kernel/pci-swiotlb.c
arch/x86/kernel/reboot.c
arch/x86/kernel/x86_init.c
crypto/async_tx/Kconfig
crypto/async_tx/async_pq.c
crypto/async_tx/async_xor.c
crypto/gcm.c
drivers/acpi/acpica/acpredef.h
drivers/acpi/blacklist.c
drivers/acpi/sleep.c
drivers/ata/pata_pcmcia.c
drivers/ata/sata_fsl.c
drivers/base/power/runtime.c
drivers/block/aoe/aoecmd.c
drivers/block/cciss.c
drivers/bluetooth/bluecard_cs.c
drivers/bluetooth/bt3c_cs.c
drivers/bluetooth/btuart_cs.c
drivers/bluetooth/btusb.c
drivers/bluetooth/dtl1_cs.c
drivers/char/agp/Kconfig
drivers/char/agp/intel-agp.c
drivers/char/keyboard.c
drivers/char/pcmcia/cm4000_cs.c
drivers/char/pcmcia/cm4040_cs.c
drivers/char/pcmcia/ipwireless/hardware.c
drivers/char/pcmcia/ipwireless/main.c
drivers/char/pcmcia/synclink_cs.c
drivers/char/tpm/tpm.c
drivers/char/tpm/tpm_tis.c
drivers/char/tty_port.c
drivers/char/vt_ioctl.c
drivers/cpufreq/cpufreq.c
drivers/cpufreq/cpufreq_conservative.c
drivers/cpufreq/cpufreq_ondemand.c
drivers/crypto/padlock-aes.c
drivers/dma/Kconfig
drivers/dma/dmaengine.c
drivers/dma/ioat/dca.c
drivers/dma/ioat/dma.h
drivers/dma/ioat/dma_v2.c
drivers/dma/ioat/dma_v3.c
drivers/dma/ioat/hw.h
drivers/dma/ioat/registers.h
drivers/dma/shdma.c
drivers/firewire/ohci.c
drivers/gpio/langwell_gpio.c
drivers/gpu/drm/Kconfig
drivers/gpu/drm/drm_edid.c
drivers/gpu/drm/drm_fb_helper.c
drivers/gpu/drm/drm_gem.c
drivers/gpu/drm/drm_mm.c
drivers/gpu/drm/i915/i915_debugfs.c
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/i915_irq.c
drivers/gpu/drm/i915/i915_suspend.c
drivers/gpu/drm/i915/intel_crt.c
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_hdmi.c
drivers/gpu/drm/radeon/atom.c
drivers/gpu/drm/radeon/mkregtable.c
drivers/gpu/drm/radeon/radeon.h
drivers/gpu/drm/radeon/radeon_agp.c
drivers/gpu/drm/radeon/radeon_connectors.c
drivers/gpu/drm/radeon/radeon_device.c
drivers/gpu/drm/radeon/rv515.c
drivers/hwmon/adt7475.c
drivers/hwmon/s3c-hwmon.c
drivers/i2c/busses/i2c-pnx.c
drivers/i2c/chips/tsl2550.c
drivers/i2c/i2c-core.c
drivers/ide/ide-cs.c
drivers/ide/ide-ioctls.c
drivers/ieee802154/fakehard.c
drivers/input/ff-core.c
drivers/input/ff-memless.c
drivers/input/input.c
drivers/input/keyboard/atkbd.c
drivers/input/mouse/lifebook.c
drivers/input/mouse/psmouse-base.c
drivers/input/serio/i8042-x86ia64io.h
drivers/isdn/hardware/avm/avm_cs.c
drivers/isdn/hardware/mISDN/hfcmulti.c
drivers/isdn/hisax/avma1_cs.c
drivers/isdn/hisax/elsa_cs.c
drivers/isdn/hisax/sedlbauer_cs.c
drivers/isdn/hisax/teles_cs.c
drivers/isdn/i4l/isdn_ppp.c
drivers/leds/leds-gpio.c
drivers/md/md.c
drivers/md/raid1.c
drivers/md/raid5.c
drivers/media/common/ir-functions.c
drivers/media/dvb/dvb-core/dvb_frontend.c
drivers/media/dvb/dvb-usb/cxusb.c
drivers/media/dvb/siano/Kconfig
drivers/media/radio/radio-gemtek-pci.c
drivers/media/video/davinci/vpif_display.c
drivers/media/video/em28xx/em28xx-cards.c
drivers/media/video/mx1_camera.c
drivers/media/video/mx3_camera.c
drivers/media/video/sh_mobile_ceu_camera.c
drivers/media/video/soc_camera.c
drivers/media/video/videobuf-dma-contig.c
drivers/mfd/wm831x-core.c
drivers/misc/eeprom/at24.c
drivers/mmc/host/pxamci.c
drivers/mtd/maps/pcmciamtd.c
drivers/mtd/maps/sa1100-flash.c
drivers/net/Kconfig
drivers/net/arm/ep93xx_eth.c
drivers/net/au1000_eth.c
drivers/net/b44.c
drivers/net/can/Kconfig
drivers/net/can/dev.c
drivers/net/can/sja1000/Kconfig [new file with mode: 0644]
drivers/net/can/usb/Kconfig [new file with mode: 0644]
drivers/net/can/usb/Makefile
drivers/net/cxgb3/sge.c
drivers/net/davinci_emac.c
drivers/net/e100.c
drivers/net/e1000e/e1000.h
drivers/net/e1000e/ethtool.c
drivers/net/e1000e/ich8lan.c
drivers/net/e1000e/netdev.c
drivers/net/e1000e/phy.c
drivers/net/forcedeth.c
drivers/net/ibm_newemac/emac.h
drivers/net/ixgbe/ixgbe_main.c
drivers/net/ks8851_mll.c
drivers/net/macvlan.c
drivers/net/netxen/netxen_nic.h
drivers/net/netxen/netxen_nic_hdr.h
drivers/net/netxen/netxen_nic_hw.c
drivers/net/netxen/netxen_nic_init.c
drivers/net/netxen/netxen_nic_main.c
drivers/net/pcmcia/3c574_cs.c
drivers/net/pcmcia/3c589_cs.c
drivers/net/pcmcia/axnet_cs.c
drivers/net/pcmcia/com20020_cs.c
drivers/net/pcmcia/fmvj18x_cs.c
drivers/net/pcmcia/ibmtr_cs.c
drivers/net/pcmcia/nmclan_cs.c
drivers/net/pcmcia/pcnet_cs.c
drivers/net/pcmcia/smc91c92_cs.c
drivers/net/pcmcia/xirc2ps_cs.c
drivers/net/phy/mdio-gpio.c
drivers/net/ppp_generic.c
drivers/net/r6040.c
drivers/net/r8169.c
drivers/net/s2io.c
drivers/net/smc91x.c
drivers/net/smsc911x.c
drivers/net/smsc9420.c
drivers/net/stmmac/stmmac_main.c
drivers/net/stmmac/stmmac_timer.c
drivers/net/stmmac/stmmac_timer.h
drivers/net/sungem.c
drivers/net/usb/hso.c
drivers/net/veth.c
drivers/net/wan/cosa.c
drivers/net/wireless/airo_cs.c
drivers/net/wireless/ath/ath5k/base.c
drivers/net/wireless/ath/ath5k/led.c
drivers/net/wireless/ath/ath9k/main.c
drivers/net/wireless/atmel_cs.c
drivers/net/wireless/b43/main.c
drivers/net/wireless/b43/pcmcia.c
drivers/net/wireless/hostap/hostap_cs.c
drivers/net/wireless/ipw2x00/ipw2100.c
drivers/net/wireless/ipw2x00/ipw2200.c
drivers/net/wireless/ipw2x00/libipw.h
drivers/net/wireless/ipw2x00/libipw_module.c
drivers/net/wireless/iwlwifi/iwl-1000.c
drivers/net/wireless/iwlwifi/iwl-6000.c
drivers/net/wireless/iwlwifi/iwl-agn-rs.c
drivers/net/wireless/iwlwifi/iwl-agn.c
drivers/net/wireless/iwlwifi/iwl-core.h
drivers/net/wireless/iwlwifi/iwl-tx.c
drivers/net/wireless/libertas/ethtool.c
drivers/net/wireless/libertas/if_cs.c
drivers/net/wireless/netwave_cs.c
drivers/net/wireless/orinoco/orinoco_cs.c
drivers/net/wireless/orinoco/spectrum_cs.c
drivers/net/wireless/p54/p54usb.c
drivers/net/wireless/ray_cs.c
drivers/net/wireless/rtl818x/rtl8187_rfkill.c
drivers/net/wireless/wavelan_cs.c
drivers/net/wireless/wl3501_cs.c
drivers/parport/parport_cs.c
drivers/pci/dmar.c
drivers/pci/intel-iommu.c
drivers/pcmcia/Kconfig
drivers/pcmcia/Makefile
drivers/pcmcia/cardbus.c
drivers/pcmcia/cirrus.h
drivers/pcmcia/cistpl.c
drivers/pcmcia/cs.c
drivers/pcmcia/cs_internal.h
drivers/pcmcia/ds.c
drivers/pcmcia/i82365.c
drivers/pcmcia/m32r_cfc.c
drivers/pcmcia/m32r_pcc.c
drivers/pcmcia/m8xx_pcmcia.c
drivers/pcmcia/o2micro.h
drivers/pcmcia/pcmcia_ioctl.c
drivers/pcmcia/pcmcia_resource.c
drivers/pcmcia/pd6729.c
drivers/pcmcia/pd6729.h
drivers/pcmcia/pxa2xx_base.c
drivers/pcmcia/pxa2xx_base.h
drivers/pcmcia/pxa2xx_cm_x255.c
drivers/pcmcia/pxa2xx_cm_x270.c
drivers/pcmcia/pxa2xx_e740.c
drivers/pcmcia/pxa2xx_lubbock.c
drivers/pcmcia/pxa2xx_mainstone.c
drivers/pcmcia/pxa2xx_palmld.c
drivers/pcmcia/pxa2xx_palmtx.c
drivers/pcmcia/pxa2xx_sharpsl.c
drivers/pcmcia/pxa2xx_trizeps4.c
drivers/pcmcia/pxa2xx_viper.c
drivers/pcmcia/rsrc_mgr.c
drivers/pcmcia/sa1100_assabet.c
drivers/pcmcia/sa1100_badge4.c
drivers/pcmcia/sa1100_cerf.c
drivers/pcmcia/sa1100_generic.c
drivers/pcmcia/sa1100_h3600.c
drivers/pcmcia/sa1100_jornada720.c
drivers/pcmcia/sa1100_neponset.c
drivers/pcmcia/sa1100_shannon.c
drivers/pcmcia/sa1100_simpad.c
drivers/pcmcia/sa1111_generic.c
drivers/pcmcia/sa1111_generic.h
drivers/pcmcia/sa11xx_base.c
drivers/pcmcia/sa11xx_base.h
drivers/pcmcia/soc_common.c
drivers/pcmcia/soc_common.h
drivers/pcmcia/tcic.c
drivers/pcmcia/topic.h
drivers/platform/x86/acerhdf.c
drivers/platform/x86/thinkpad_acpi.c
drivers/regulator/core.c
drivers/regulator/fixed.c
drivers/regulator/wm831x-isink.c
drivers/regulator/wm831x-ldo.c
drivers/rtc/rtc-coh901331.c
drivers/rtc/rtc-pcf50633.c
drivers/rtc/rtc-x1205.c
drivers/s390/char/monreader.c
drivers/s390/char/sclp_quiesce.c
drivers/scsi/bfa/bfad_fwimg.c
drivers/scsi/bfa/bfad_im.c
drivers/scsi/gdth.c
drivers/scsi/hosts.c
drivers/scsi/ipr.c
drivers/scsi/ipr.h
drivers/scsi/libsas/sas_expander.c
drivers/scsi/pcmcia/aha152x_stub.c
drivers/scsi/pcmcia/fdomain_stub.c
drivers/scsi/pcmcia/nsp_cs.c
drivers/scsi/pcmcia/qlogic_stub.c
drivers/scsi/pcmcia/sym53c500_cs.c
drivers/scsi/pmcraid.c
drivers/scsi/scsi_scan.c
drivers/scsi/scsi_sysfs.c
drivers/scsi/scsi_transport_fc.c
drivers/scsi/sd_dif.c
drivers/serial/bcm63xx_uart.c
drivers/serial/of_serial.c
drivers/serial/serial_cs.c
drivers/serial/suncore.c
drivers/serial/suncore.h
drivers/serial/sunhv.c
drivers/serial/sunsab.c
drivers/serial/sunsu.c
drivers/serial/sunzilog.c
drivers/spi/spi_stmp.c
drivers/spi/spi_txx9.c
drivers/ssb/pcmcia.c
drivers/ssb/scan.c
drivers/staging/comedi/drivers/cb_das16_cs.c
drivers/staging/comedi/drivers/das08_cs.c
drivers/staging/comedi/drivers/ni_daq_700.c
drivers/staging/comedi/drivers/ni_daq_dio24.c
drivers/staging/comedi/drivers/ni_labpc_cs.c
drivers/staging/comedi/drivers/ni_mio_cs.c
drivers/staging/comedi/drivers/quatech_daqp_cs.c
drivers/staging/go7007/s2250-board.c
drivers/staging/go7007/s2250-loader.h [new file with mode: 0644]
drivers/staging/hv/BlkVsc.c
drivers/staging/hv/Channel.c
drivers/staging/hv/ChannelMgmt.c
drivers/staging/hv/NetVsc.c
drivers/staging/hv/NetVsc.h
drivers/staging/hv/StorVsc.c
drivers/staging/hv/blkvsc_drv.c
drivers/staging/hv/netvsc_drv.c
drivers/staging/octeon/ethernet-mdio.c
drivers/staging/octeon/ethernet-spi.c
drivers/staging/octeon/ethernet.c
drivers/staging/rtl8187se/TODO
drivers/staging/rtl8192su/TODO
drivers/staging/vt6655/TODO
drivers/staging/vt6656/TODO
drivers/telephony/ixj_pcmcia.c
drivers/uio/uio_pdrv_genirq.c
drivers/usb/class/cdc-acm.c
drivers/usb/core/hub.c
drivers/usb/gadget/amd5536udc.c
drivers/usb/host/ehci-hcd.c
drivers/usb/host/ehci-pci.c
drivers/usb/host/ehci-q.c
drivers/usb/host/ehci-sched.c
drivers/usb/host/ehci.h
drivers/usb/host/ohci-hcd.c
drivers/usb/host/ohci-pci.c
drivers/usb/host/ohci-q.c
drivers/usb/host/ohci.h
drivers/usb/host/sl811_cs.c
drivers/usb/host/xhci-mem.c
drivers/usb/host/xhci-ring.c
drivers/usb/mon/mon_bin.c
drivers/usb/musb/cppi_dma.c
drivers/usb/musb/musb_core.c
drivers/usb/musb/musb_gadget.c
drivers/usb/musb/musb_gadget_ep0.c
drivers/usb/musb/musb_host.c
drivers/usb/serial/cp210x.c
drivers/usb/serial/ftdi_sio.c
drivers/usb/serial/option.c
drivers/video/backlight/corgi_lcd.c
drivers/video/backlight/lcd.c
drivers/video/da8xx-fb.c
drivers/video/gbefb.c
drivers/watchdog/pnx4008_wdt.c
drivers/watchdog/rc32434_wdt.c
fs/9p/cache.c
fs/afs/file.c
fs/cachefiles/interface.c
fs/cachefiles/namei.c
fs/cachefiles/rdwr.c
fs/cifs/CHANGES
fs/cifs/cifsfs.c
fs/cifs/dir.c
fs/cifs/misc.c
fs/exec.c
fs/fcntl.c
fs/file_table.c
fs/fscache/Kconfig
fs/fscache/Makefile
fs/fscache/cache.c
fs/fscache/cookie.c
fs/fscache/internal.h
fs/fscache/main.c
fs/fscache/object-list.c [new file with mode: 0644]
fs/fscache/object.c
fs/fscache/operation.c
fs/fscache/page.c
fs/fscache/proc.c
fs/fscache/stats.c
fs/fuse/dir.c
fs/gfs2/Kconfig
fs/gfs2/acl.c
fs/gfs2/acl.h
fs/gfs2/aops.c
fs/gfs2/dir.c
fs/gfs2/glock.c
fs/gfs2/glock.h
fs/gfs2/glops.c
fs/gfs2/incore.h
fs/gfs2/inode.c
fs/gfs2/log.c
fs/gfs2/lops.c
fs/gfs2/main.c
fs/gfs2/ops_fstype.c
fs/gfs2/quota.c
fs/gfs2/quota.h
fs/gfs2/recovery.c
fs/gfs2/rgrp.c
fs/gfs2/super.c
fs/gfs2/super.h
fs/gfs2/sys.c
fs/gfs2/xattr.c
fs/gfs2/xattr.h
fs/inode.c
fs/jffs2/read.c
fs/namespace.c
fs/nfs/fscache.c
fs/nfs/nfs4proc.c
fs/nfsd/nfs3xdr.c
fs/nilfs2/cpfile.c
fs/nilfs2/inode.c
fs/nilfs2/ioctl.c
fs/ocfs2/file.c
fs/ocfs2/ocfs2.h
fs/ocfs2/refcounttree.c
fs/ocfs2/super.c
fs/ocfs2/uptodate.c
fs/open.c
fs/proc/array.c
fs/quota/Kconfig
fs/quota/dquot.c
fs/quota/quota.c
fs/xattr_acl.c
fs/xfs/xfs_log_recover.c
fs/xfs/xfs_trans_ail.c
include/asm-generic/fcntl.h
include/linux/Kbuild
include/linux/bootmem.h
include/linux/capability.h
include/linux/compiler-gcc.h
include/linux/compiler-gcc4.h
include/linux/compiler.h
include/linux/dmar.h
include/linux/fscache-cache.h
include/linux/fscache.h
include/linux/gfs2_ondisk.h
include/linux/hardirq.h
include/linux/i2c-pnx.h
include/linux/init_task.h
include/linux/input.h
include/linux/interrupt.h
include/linux/irqflags.h
include/linux/isdn_ppp.h
include/linux/kernel.h
include/linux/lsm_audit.h
include/linux/mfd/wm831x/regulator.h
include/linux/net.h
include/linux/nilfs2_fs.h
include/linux/pci_ids.h
include/linux/posix_acl.h
include/linux/quota.h
include/linux/ratelimit.h
include/linux/rcupdate.h
include/linux/rcutiny.h [new file with mode: 0644]
include/linux/rcutree.h
include/linux/sched.h
include/linux/securebits.h
include/linux/security.h
include/linux/slow-work.h
include/linux/smp.h
include/linux/spinlock.h
include/linux/spinlock_api_smp.h
include/linux/srcu.h
include/linux/suspend.h
include/linux/swiotlb.h
include/linux/tpm.h
include/linux/vt.h
include/net/mac80211.h
include/net/sctp/structs.h
include/pcmcia/cs.h
include/pcmcia/cs_types.h
include/pcmcia/ds.h
include/pcmcia/ss.h
include/scsi/scsi_device.h
include/scsi/scsi_host.h
include/trace/events/syscalls.h
include/trace/ftrace.h
include/trace/power.h [deleted file]
init/Kconfig
init/main.c
kernel/Kconfig.locks [new file with mode: 0644]
kernel/Makefile
kernel/capability.c
kernel/hung_task.c
kernel/irq/chip.c
kernel/irq/proc.c
kernel/irq/spurious.c
kernel/kmod.c
kernel/kprobes.c
kernel/module.c
kernel/mutex.c
kernel/printk.c
kernel/rcupdate.c
kernel/rcutiny.c [new file with mode: 0644]
kernel/rcutorture.c
kernel/rcutree.c
kernel/rcutree.h
kernel/rcutree_plugin.h
kernel/rcutree_trace.c
kernel/sched.c
kernel/signal.c
kernel/slow-work-debugfs.c [new file with mode: 0644]
kernel/slow-work.c
kernel/slow-work.h [new file with mode: 0644]
kernel/smp.c
kernel/softirq.c
kernel/spinlock.c
kernel/srcu.c
kernel/sysctl.c
kernel/trace/ftrace.c
kernel/trace/ring_buffer.c
kernel/trace/ring_buffer_benchmark.c
kernel/trace/trace.c
kernel/trace/trace_clock.c
kernel/trace/trace_export.c
kernel/workqueue.c
lib/Kconfig.debug
lib/radix-tree.c
lib/ratelimit.c
lib/string.c
lib/swiotlb.c
mm/Kconfig
mm/backing-dev.c
mm/bootmem.c
mm/memory_hotplug.c
mm/mmap.c
mm/percpu.c
net/8021q/vlan.c
net/bluetooth/hci_conn.c
net/bluetooth/l2cap.c
net/core/dev.c
net/core/pktgen.c
net/core/skbuff.c
net/core/sysctl_net_core.c
net/core/utils.c
net/ipv4/ip_fragment.c
net/ipv4/ipmr.c
net/ipv4/tcp.c
net/mac80211/agg-rx.c
net/mac80211/agg-tx.c
net/mac80211/ht.c
net/mac80211/ieee80211_i.h
net/mac80211/util.c
net/netfilter/nf_log.c
net/netfilter/xt_limit.c
net/netfilter/xt_osf.c
net/rfkill/core.c
net/sctp/associola.c
net/sctp/outqueue.c
net/sctp/sm_sideeffect.c
net/sctp/sm_statefuns.c
net/sctp/socket.c
net/sctp/transport.c
net/sunrpc/addr.c
scripts/dtc/data.c
scripts/dtc/dtc-lexer.l
scripts/dtc/dtc-lexer.lex.c_shipped
scripts/dtc/libfdt/fdt_ro.c
scripts/dtc/treesource.c
scripts/genksyms/keywords.c_shipped
scripts/genksyms/keywords.gperf
scripts/kconfig/Makefile
scripts/kconfig/lex.zconf.c_shipped
scripts/kconfig/streamline_config.pl
scripts/kconfig/zconf.gperf
scripts/kconfig/zconf.hash.c_shipped
scripts/kconfig/zconf.l
scripts/kconfig/zconf.tab.c_shipped
scripts/kconfig/zconf.y
scripts/recordmcount.pl
scripts/selinux/Makefile
scripts/selinux/genheaders/.gitignore [new file with mode: 0644]
scripts/selinux/genheaders/Makefile [new file with mode: 0644]
scripts/selinux/genheaders/genheaders.c [new file with mode: 0644]
scripts/selinux/mdp/mdp.c
security/Kconfig
security/Makefile
security/capability.c
security/commoncap.c
security/integrity/ima/Kconfig
security/integrity/ima/ima_iint.c
security/lsm_audit.c
security/min_addr.c
security/root_plug.c [deleted file]
security/security.c
security/selinux/.gitignore [new file with mode: 0644]
security/selinux/Makefile
security/selinux/avc.c
security/selinux/hooks.c
security/selinux/include/av_inherit.h [deleted file]
security/selinux/include/av_perm_to_string.h [deleted file]
security/selinux/include/av_permissions.h [deleted file]
security/selinux/include/avc_ss.h
security/selinux/include/class_to_string.h [deleted file]
security/selinux/include/classmap.h [new file with mode: 0644]
security/selinux/include/common_perm_to_string.h [deleted file]
security/selinux/include/flask.h [deleted file]
security/selinux/include/security.h
security/selinux/selinuxfs.c
security/selinux/ss/Makefile
security/selinux/ss/mls.c
security/selinux/ss/policydb.c
security/selinux/ss/policydb.h
security/selinux/ss/services.c
security/tomoyo/common.c
security/tomoyo/common.h
security/tomoyo/realpath.c
sound/arm/aaci.c
sound/oss/hex2hex.c
sound/pci/hda/patch_nvhdmi.c
sound/pci/hda/patch_realtek.c
sound/pci/hda/patch_sigmatel.c
sound/pci/ice1712/ice1712.h
sound/pci/ice1712/prodigy_hifi.c
sound/pcmcia/pdaudiocf/pdaudiocf.c
sound/pcmcia/vx/vxpocket.c
sound/soc/codecs/tlv320aic23.c
sound/soc/omap/omap3evm.c
sound/soc/omap/omap3pandora.c
sound/soc/soc-dapm.c
sound/usb/usbmixer.c

index b93fb7eff94286c7a15d475fa581dac32a89b0db..946c7ec5c922ff5bb02726144178f56f57c3378d 100644 (file)
@@ -25,6 +25,7 @@
 *.elf
 *.bin
 *.gz
+*.bz2
 *.lzma
 *.patch
 *.gcno
index 187bbf10c92332fa184706b25825c6d2a2761ae4..8608fd85e921844ab33406c7f7d32ae7ea6c7d18 100644 (file)
 CONFIG_RCU_TRACE debugfs Files and Formats
 
 
-The rcupreempt and rcutree implementations of RCU provide debugfs trace
-output that summarizes counters and state.  This information is useful for
-debugging RCU itself, and can sometimes also help to debug abuses of RCU.
-Note that the rcuclassic implementation of RCU does not provide debugfs
-trace output.
-
-The following sections describe the debugfs files and formats for
-preemptable RCU (rcupreempt) and hierarchical RCU (rcutree).
-
-
-Preemptable RCU debugfs Files and Formats
-
-This implementation of RCU provides three debugfs files under the
-top-level directory RCU: rcu/rcuctrs (which displays the per-CPU
-counters used by preemptable RCU) rcu/rcugp (which displays grace-period
-counters), and rcu/rcustats (which internal counters for debugging RCU).
-
-The output of "cat rcu/rcuctrs" looks as follows:
-
-CPU last cur F M
-  0    5  -5 0 0
-  1   -1   0 0 0
-  2    0   1 0 0
-  3    0   1 0 0
-  4    0   1 0 0
-  5    0   1 0 0
-  6    0   2 0 0
-  7    0  -1 0 0
-  8    0   1 0 0
-ggp = 26226, state = waitzero
-
-The per-CPU fields are as follows:
-
-o      "CPU" gives the CPU number.  Offline CPUs are not displayed.
-
-o      "last" gives the value of the counter that is being decremented
-       for the current grace period phase.  In the example above,
-       the counters sum to 4, indicating that there are still four
-       RCU read-side critical sections still running that started
-       before the last counter flip.
-
-o      "cur" gives the value of the counter that is currently being
-       both incremented (by rcu_read_lock()) and decremented (by
-       rcu_read_unlock()).  In the example above, the counters sum to
-       1, indicating that there is only one RCU read-side critical section
-       still running that started after the last counter flip.
-
-o      "F" indicates whether RCU is waiting for this CPU to acknowledge
-       a counter flip.  In the above example, RCU is not waiting on any,
-       which is consistent with the state being "waitzero" rather than
-       "waitack".
-
-o      "M" indicates whether RCU is waiting for this CPU to execute a
-       memory barrier.  In the above example, RCU is not waiting on any,
-       which is consistent with the state being "waitzero" rather than
-       "waitmb".
-
-o      "ggp" is the global grace-period counter.
-
-o      "state" is the RCU state, which can be one of the following:
-
-       o       "idle": there is no grace period in progress.
-
-       o       "waitack": RCU just incremented the global grace-period
-               counter, which has the effect of reversing the roles of
-               the "last" and "cur" counters above, and is waiting for
-               all the CPUs to acknowledge the flip.  Once the flip has
-               been acknowledged, CPUs will no longer be incrementing
-               what are now the "last" counters, so that their sum will
-               decrease monotonically down to zero.
-
-       o       "waitzero": RCU is waiting for the sum of the "last" counters
-               to decrease to zero.
-
-       o       "waitmb": RCU is waiting for each CPU to execute a memory
-               barrier, which ensures that instructions from a given CPU's
-               last RCU read-side critical section cannot be reordered
-               with instructions following the memory-barrier instruction.
-
-The output of "cat rcu/rcugp" looks as follows:
-
-oldggp=48870  newggp=48873
-
-Note that reading from this file provokes a synchronize_rcu().  The
-"oldggp" value is that of "ggp" from rcu/rcuctrs above, taken before
-executing the synchronize_rcu(), and the "newggp" value is also the
-"ggp" value, but taken after the synchronize_rcu() command returns.
-
-
-The output of "cat rcu/rcugp" looks as follows:
-
-na=1337955 nl=40 wa=1337915 wl=44 da=1337871 dl=0 dr=1337871 di=1337871
-1=50989 e1=6138 i1=49722 ie1=82 g1=49640 a1=315203 ae1=265563 a2=49640
-z1=1401244 ze1=1351605 z2=49639 m1=5661253 me1=5611614 m2=49639
-
-These are counters tracking internal preemptable-RCU events, however,
-some of them may be useful for debugging algorithms using RCU.  In
-particular, the "nl", "wl", and "dl" values track the number of RCU
-callbacks in various states.  The fields are as follows:
-
-o      "na" is the total number of RCU callbacks that have been enqueued
-       since boot.
-
-o      "nl" is the number of RCU callbacks waiting for the previous
-       grace period to end so that they can start waiting on the next
-       grace period.
-
-o      "wa" is the total number of RCU callbacks that have started waiting
-       for a grace period since boot.  "na" should be roughly equal to
-       "nl" plus "wa".
-
-o      "wl" is the number of RCU callbacks currently waiting for their
-       grace period to end.
-
-o      "da" is the total number of RCU callbacks whose grace periods
-       have completed since boot.  "wa" should be roughly equal to
-       "wl" plus "da".
-
-o      "dr" is the total number of RCU callbacks that have been removed
-       from the list of callbacks ready to invoke.  "dr" should be roughly
-       equal to "da".
-
-o      "di" is the total number of RCU callbacks that have been invoked
-       since boot.  "di" should be roughly equal to "da", though some
-       early versions of preemptable RCU had a bug so that only the
-       last CPU's count of invocations was displayed, rather than the
-       sum of all CPU's counts.
-
-o      "1" is the number of calls to rcu_try_flip().  This should be
-       roughly equal to the sum of "e1", "i1", "a1", "z1", and "m1"
-       described below.  In other words, the number of times that
-       the state machine is visited should be equal to the sum of the
-       number of times that each state is visited plus the number of
-       times that the state-machine lock acquisition failed.
-
-o      "e1" is the number of times that rcu_try_flip() was unable to
-       acquire the fliplock.
-
-o      "i1" is the number of calls to rcu_try_flip_idle().
-
-o      "ie1" is the number of times rcu_try_flip_idle() exited early
-       due to the calling CPU having no work for RCU.
-
-o      "g1" is the number of times that rcu_try_flip_idle() decided
-       to start a new grace period.  "i1" should be roughly equal to
-       "ie1" plus "g1".
-
-o      "a1" is the number of calls to rcu_try_flip_waitack().
-
-o      "ae1" is the number of times that rcu_try_flip_waitack() found
-       that at least one CPU had not yet acknowledge the new grace period
-       (AKA "counter flip").
-
-o      "a2" is the number of time rcu_try_flip_waitack() found that
-       all CPUs had acknowledged.  "a1" should be roughly equal to
-       "ae1" plus "a2".  (This particular output was collected on
-       a 128-CPU machine, hence the smaller-than-usual fraction of
-       calls to rcu_try_flip_waitack() finding all CPUs having already
-       acknowledged.)
-
-o      "z1" is the number of calls to rcu_try_flip_waitzero().
-
-o      "ze1" is the number of times that rcu_try_flip_waitzero() found
-       that not all of the old RCU read-side critical sections had
-       completed.
-
-o      "z2" is the number of times that rcu_try_flip_waitzero() finds
-       the sum of the counters equal to zero, in other words, that
-       all of the old RCU read-side critical sections had completed.
-       The value of "z1" should be roughly equal to "ze1" plus
-       "z2".
-
-o      "m1" is the number of calls to rcu_try_flip_waitmb().
-
-o      "me1" is the number of times that rcu_try_flip_waitmb() finds
-       that at least one CPU has not yet executed a memory barrier.
-
-o      "m2" is the number of times that rcu_try_flip_waitmb() finds that
-       all CPUs have executed a memory barrier.
+The rcutree implementation of RCU provides debugfs trace output that
+summarizes counters and state.  This information is useful for debugging
+RCU itself, and can sometimes also help to debug abuses of RCU.
+The following sections describe the debugfs files and formats.
 
 
 Hierarchical RCU debugfs Files and Formats
@@ -210,9 +35,10 @@ rcu_bh:
   6 c=-275 g=-275 pq=1 pqc=-275 qp=0 dt=859/1 dn=0 df=15 of=0 ri=0 ql=0 b=10
   7 c=-275 g=-275 pq=1 pqc=-275 qp=0 dt=3761/1 dn=0 df=15 of=0 ri=0 ql=0 b=10
 
-The first section lists the rcu_data structures for rcu, the second for
-rcu_bh.  Each section has one line per CPU, or eight for this 8-CPU system.
-The fields are as follows:
+The first section lists the rcu_data structures for rcu_sched, the second
+for rcu_bh.  Note that CONFIG_TREE_PREEMPT_RCU kernels will have an
+additional section for rcu_preempt.  Each section has one line per CPU,
+or eight for this 8-CPU system.  The fields are as follows:
 
 o      The number at the beginning of each line is the CPU number.
        CPUs numbers followed by an exclamation mark are offline,
@@ -223,9 +49,9 @@ o    The number at the beginning of each line is the CPU number.
 
 o      "c" is the count of grace periods that this CPU believes have
        completed.  CPUs in dynticks idle mode may lag quite a ways
-       behind, for example, CPU 4 under "rcu" above, which has slept
-       through the past 25 RCU grace periods.  It is not unusual to
-       see CPUs lagging by thousands of grace periods.
+       behind, for example, CPU 4 under "rcu_sched" above, which has
+       slept through the past 25 RCU grace periods.  It is not unusual
+       to see CPUs lagging by thousands of grace periods.
 
 o      "g" is the count of grace periods that this CPU believes have
        started.  Again, CPUs in dynticks idle mode may lag behind.
@@ -308,8 +134,10 @@ The output of "cat rcu/rcugp" looks as follows:
 rcu_sched: completed=33062  gpnum=33063
 rcu_bh: completed=464  gpnum=464
 
-Again, this output is for both "rcu" and "rcu_bh".  The fields are
-taken from the rcu_state structure, and are as follows:
+Again, this output is for both "rcu_sched" and "rcu_bh".  Note that
+kernels built with CONFIG_TREE_PREEMPT_RCU will have an additional
+"rcu_preempt" line.  The fields are taken from the rcu_state structure,
+and are as follows:
 
 o      "completed" is the number of grace periods that have completed.
        It is comparable to the "c" field from rcu/rcudata in that a
@@ -324,23 +152,24 @@ o "gpnum" is the number of grace periods that have started.  It is
        If these two fields are equal (as they are for "rcu_bh" above),
        then there is no grace period in progress, in other words, RCU
        is idle.  On the other hand, if the two fields differ (as they
-       do for "rcu" above), then an RCU grace period is in progress.
+       do for "rcu_sched" above), then an RCU grace period is in progress.
 
 
 The output of "cat rcu/rcuhier" looks as follows, with very long lines:
 
-c=6902 g=6903 s=2 jfq=3 j=72c7 nfqs=13142/nfqsng=0(13142) fqlh=6
-1/1 0:127 ^0    
-3/3 0:35 ^0    0/0 36:71 ^1    0/0 72:107 ^2    0/0 108:127 ^3    
-3/3f 0:5 ^0    2/3 6:11 ^1    0/0 12:17 ^2    0/0 18:23 ^3    0/0 24:29 ^4    0/0 30:35 ^5    0/0 36:41 ^0    0/0 42:47 ^1    0/0 48:53 ^2    0/0 54:59 ^3    0/0 60:65 ^4    0/0 66:71 ^5    0/0 72:77 ^0    0/0 78:83 ^1    0/0 84:89 ^2    0/0 90:95 ^3    0/0 96:101 ^4    0/0 102:107 ^5    0/0 108:113 ^0    0/0 114:119 ^1    0/0 120:125 ^2    0/0 126:127 ^3    
+c=6902 g=6903 s=2 jfq=3 j=72c7 nfqs=13142/nfqsng=0(13142) fqlh=6 oqlen=0
+1/1 .>. 0:127 ^0    
+3/3 .>. 0:35 ^0    0/0 .>. 36:71 ^1    0/0 .>. 72:107 ^2    0/0 .>. 108:127 ^3    
+3/3f .>. 0:5 ^0    2/3 .>. 6:11 ^1    0/0 .>. 12:17 ^2    0/0 .>. 18:23 ^3    0/0 .>. 24:29 ^4    0/0 .>. 30:35 ^5    0/0 .>. 36:41 ^0    0/0 .>. 42:47 ^1    0/0 .>. 48:53 ^2    0/0 .>. 54:59 ^3    0/0 .>. 60:65 ^4    0/0 .>. 66:71 ^5    0/0 .>. 72:77 ^0    0/0 .>. 78:83 ^1    0/0 .>. 84:89 ^2    0/0 .>. 90:95 ^3    0/0 .>. 96:101 ^4    0/0 .>. 102:107 ^5    0/0 .>. 108:113 ^0    0/0 .>. 114:119 ^1    0/0 .>. 120:125 ^2    0/0 .>. 126:127 ^3    
 rcu_bh:
-c=-226 g=-226 s=1 jfq=-5701 j=72c7 nfqs=88/nfqsng=0(88) fqlh=0
-0/1 0:127 ^0    
-0/3 0:35 ^0    0/0 36:71 ^1    0/0 72:107 ^2    0/0 108:127 ^3    
-0/3f 0:5 ^0    0/3 6:11 ^1    0/0 12:17 ^2    0/0 18:23 ^3    0/0 24:29 ^4    0/0 30:35 ^5    0/0 36:41 ^0    0/0 42:47 ^1    0/0 48:53 ^2    0/0 54:59 ^3    0/0 60:65 ^4    0/0 66:71 ^5    0/0 72:77 ^0    0/0 78:83 ^1    0/0 84:89 ^2    0/0 90:95 ^3    0/0 96:101 ^4    0/0 102:107 ^5    0/0 108:113 ^0    0/0 114:119 ^1    0/0 120:125 ^2    0/0 126:127 ^3
+c=-226 g=-226 s=1 jfq=-5701 j=72c7 nfqs=88/nfqsng=0(88) fqlh=0 oqlen=0
+0/1 .>. 0:127 ^0    
+0/3 .>. 0:35 ^0    0/0 .>. 36:71 ^1    0/0 .>. 72:107 ^2    0/0 .>. 108:127 ^3    
+0/3f .>. 0:5 ^0    0/3 .>. 6:11 ^1    0/0 .>. 12:17 ^2    0/0 .>. 18:23 ^3    0/0 .>. 24:29 ^4    0/0 .>. 30:35 ^5    0/0 .>. 36:41 ^0    0/0 .>. 42:47 ^1    0/0 .>. 48:53 ^2    0/0 .>. 54:59 ^3    0/0 .>. 60:65 ^4    0/0 .>. 66:71 ^5    0/0 .>. 72:77 ^0    0/0 .>. 78:83 ^1    0/0 .>. 84:89 ^2    0/0 .>. 90:95 ^3    0/0 .>. 96:101 ^4    0/0 .>. 102:107 ^5    0/0 .>. 108:113 ^0    0/0 .>. 114:119 ^1    0/0 .>. 120:125 ^2    0/0 .>. 126:127 ^3
 
-This is once again split into "rcu" and "rcu_bh" portions.  The fields are
-as follows:
+This is once again split into "rcu_sched" and "rcu_bh" portions,
+and CONFIG_TREE_PREEMPT_RCU kernels will again have an additional
+"rcu_preempt" section.  The fields are as follows:
 
 o      "c" is exactly the same as "completed" under rcu/rcugp.
 
@@ -372,6 +201,11 @@ o  "fqlh" is the number of calls to force_quiescent_state() that
        exited immediately (without even being counted in nfqs above)
        due to contention on ->fqslock.
 
+o      "oqlen" is the number of callbacks on the "orphan" callback
+       list.  RCU callbacks are placed on this list by CPUs going
+       offline, and are "adopted" either by the CPU helping the outgoing
+       CPU or by the next rcu_barrier*() call, whichever comes first.
+
 o      Each element of the form "1/1 0:127 ^0" represents one struct
        rcu_node.  Each line represents one level of the hierarchy, from
        root to leaves.  It is best to think of the rcu_data structures
@@ -379,7 +213,7 @@ o   Each element of the form "1/1 0:127 ^0" represents one struct
        might be either one, two, or three levels of rcu_node structures,
        depending on the relationship between CONFIG_RCU_FANOUT and
        CONFIG_NR_CPUS.
-       
+
        o       The numbers separated by the "/" are the qsmask followed
                by the qsmaskinit.  The qsmask will have one bit
                set for each entity in the next lower level that
@@ -389,10 +223,19 @@ o Each element of the form "1/1 0:127 ^0" represents one struct
                The value of qsmaskinit is assigned to that of qsmask
                at the beginning of each grace period.
 
-               For example, for "rcu", the qsmask of the first entry
-               of the lowest level is 0x14, meaning that we are still
-               waiting for CPUs 2 and 4 to check in for the current
-               grace period.
+               For example, for "rcu_sched", the qsmask of the first
+               entry of the lowest level is 0x14, meaning that we
+               are still waiting for CPUs 2 and 4 to check in for the
+               current grace period.
+
+       o       The characters separated by the ">" indicate the state
+               of the blocked-tasks lists.  A "T" preceding the ">"
+               indicates that at least one task blocked in an RCU
+               read-side critical section blocks the current grace
+               period, while a "." preceding the ">" indicates otherwise.
+               The character following the ">" indicates similarly for
+               the next grace period.  A "T" should appear in this
+               field only for rcu-preempt.
 
        o       The numbers separated by the ":" are the range of CPUs
                served by this struct rcu_node.  This can be helpful
@@ -431,8 +274,9 @@ rcu_bh:
   6 np=120834 qsp=9902 cbr=0 cng=0 gpc=6 gps=3 nf=2 nn=110921
   7 np=144888 qsp=26336 cbr=0 cng=0 gpc=8 gps=2 nf=0 nn=118542
 
-As always, this is once again split into "rcu" and "rcu_bh" portions.
-The fields are as follows:
+As always, this is once again split into "rcu_sched" and "rcu_bh"
+portions, with CONFIG_TREE_PREEMPT_RCU kernels having an additional
+"rcu_preempt" section.  The fields are as follows:
 
 o      "np" is the number of times that __rcu_pending() has been invoked
        for the corresponding flavor of RCU.
index e41a7fecf0d3c33354aef84985cb564619ab6c77..d542ca243b80d52afcc0ce9a32e7e5faa20a0920 100644 (file)
@@ -830,7 +830,7 @@ sched:      Critical sections       Grace period            Barrier
 SRCU:  Critical sections       Grace period            Barrier
 
        srcu_read_lock          synchronize_srcu        N/A
-       srcu_read_unlock
+       srcu_read_unlock        synchronize_srcu_expedited
 
 SRCU:  Initialization/cleanup
        init_srcu_struct
index e1efc400bed66095629a46c2229b5bf863434315..e151b2a36267c17fdb7da317e309bea3de408a4b 100644 (file)
@@ -65,6 +65,7 @@ aicdb.h*
 asm-offsets.h
 asm_offsets.h
 autoconf.h*
+av_permissions.h
 bbootsect
 bin2c
 binkernel.spec
@@ -95,12 +96,14 @@ docproc
 elf2ecoff
 elfconfig.h*
 fixdep
+flask.h
 fore200e_mkfirm
 fore200e_pca_fw.c*
 gconf
 gen-devlist
 gen_crc32table
 gen_init_cpio
+genheaders
 genksyms
 *_gray256.c
 ihex2fw
index b3e3a035683993edc8391cefd11ea3ef6be9eb08..fe79e3c8847dc334f479050bb0bc6af5711f868a 100644 (file)
@@ -312,10 +312,8 @@ and to the following documentation:
 8. Mailing list
 ---------------
 
-There are several frame buffer device related mailing lists at SourceForge:
-  - linux-fbdev-announce@lists.sourceforge.net, for announcements,
-  - linux-fbdev-user@lists.sourceforge.net, for generic user support,
-  - linux-fbdev-devel@lists.sourceforge.net, for project developers.
+There is a frame buffer device related mailing list at kernel.org:
+linux-fbdev@vger.kernel.org.
 
 Point your web browser to http://sourceforge.net/projects/linux-fbdev/ for
 subscription information and archive browsing.
index 9e94b9491d89c7bc246865d1b4580d8533fa7549..a91e2e2095b09fcebca6f456fe7e1fe36263006d 100644 (file)
@@ -235,6 +235,7 @@ proc files.
                neg=N   Number of negative lookups made
                pos=N   Number of positive lookups made
                crt=N   Number of objects created by lookup
+               tmo=N   Number of lookups timed out and requeued
        Updates n=N     Number of update cookie requests seen
                nul=N   Number of upd reqs given a NULL parent
                run=N   Number of upd reqs granted CPU time
@@ -250,8 +251,10 @@ proc files.
                ok=N    Number of successful alloc reqs
                wt=N    Number of alloc reqs that waited on lookup completion
                nbf=N   Number of alloc reqs rejected -ENOBUFS
+               int=N   Number of alloc reqs aborted -ERESTARTSYS
                ops=N   Number of alloc reqs submitted
                owt=N   Number of alloc reqs waited for CPU time
+               abt=N   Number of alloc reqs aborted due to object death
        Retrvls n=N     Number of retrieval (read) requests seen
                ok=N    Number of successful retr reqs
                wt=N    Number of retr reqs that waited on lookup completion
@@ -261,6 +264,7 @@ proc files.
                oom=N   Number of retr reqs failed -ENOMEM
                ops=N   Number of retr reqs submitted
                owt=N   Number of retr reqs waited for CPU time
+               abt=N   Number of retr reqs aborted due to object death
        Stores  n=N     Number of storage (write) requests seen
                ok=N    Number of successful store reqs
                agn=N   Number of store reqs on a page already pending storage
@@ -268,12 +272,37 @@ proc files.
                oom=N   Number of store reqs failed -ENOMEM
                ops=N   Number of store reqs submitted
                run=N   Number of store reqs granted CPU time
+               pgs=N   Number of pages given store req processing time
+               rxd=N   Number of store reqs deleted from tracking tree
+               olm=N   Number of store reqs over store limit
+       VmScan  nos=N   Number of release reqs against pages with no pending store
+               gon=N   Number of release reqs against pages stored by time lock granted
+               bsy=N   Number of release reqs ignored due to in-progress store
+               can=N   Number of page stores cancelled due to release req
        Ops     pend=N  Number of times async ops added to pending queues
                run=N   Number of times async ops given CPU time
                enq=N   Number of times async ops queued for processing
+               can=N   Number of async ops cancelled
+               rej=N   Number of async ops rejected due to object lookup/create failure
                dfr=N   Number of async ops queued for deferred release
                rel=N   Number of async ops released
                gc=N    Number of deferred-release async ops garbage collected
+       CacheOp alo=N   Number of in-progress alloc_object() cache ops
+               luo=N   Number of in-progress lookup_object() cache ops
+               luc=N   Number of in-progress lookup_complete() cache ops
+               gro=N   Number of in-progress grab_object() cache ops
+               upo=N   Number of in-progress update_object() cache ops
+               dro=N   Number of in-progress drop_object() cache ops
+               pto=N   Number of in-progress put_object() cache ops
+               syn=N   Number of in-progress sync_cache() cache ops
+               atc=N   Number of in-progress attr_changed() cache ops
+               rap=N   Number of in-progress read_or_alloc_page() cache ops
+               ras=N   Number of in-progress read_or_alloc_pages() cache ops
+               alp=N   Number of in-progress allocate_page() cache ops
+               als=N   Number of in-progress allocate_pages() cache ops
+               wrp=N   Number of in-progress write_page() cache ops
+               ucp=N   Number of in-progress uncache_page() cache ops
+               dsp=N   Number of in-progress dissociate_pages() cache ops
 
 
  (*) /proc/fs/fscache/histogram
@@ -299,6 +328,87 @@ proc files.
      jiffy range covered, and the SECS field the equivalent number of seconds.
 
 
+===========
+OBJECT LIST
+===========
+
+If CONFIG_FSCACHE_OBJECT_LIST is enabled, the FS-Cache facility will maintain a
+list of all the objects currently allocated and allow them to be viewed
+through:
+
+       /proc/fs/fscache/objects
+
+This will look something like:
+
+       [root@andromeda ~]# head /proc/fs/fscache/objects
+       OBJECT   PARENT   STAT CHLDN OPS OOP IPR EX READS EM EV F S | NETFS_COOKIE_DEF TY FL NETFS_DATA       OBJECT_KEY, AUX_DATA
+       ======== ======== ==== ===== === === === == ===== == == = = | ================ == == ================ ================
+          17e4b        2 ACTV     0   0   0   0  0     0 7b  4 0 8 | NFS.fh           DT  0 ffff88001dd82820 010006017edcf8bbc93b43298fdfbe71e50b57b13a172c0117f38472, e567634700000000000000000000000063f2404a000000000000000000000000c9030000000000000000000063f2404a
+          1693a        2 ACTV     0   0   0   0  0     0 7b  4 0 8 | NFS.fh           DT  0 ffff88002db23380 010006017edcf8bbc93b43298fdfbe71e50b57b1e0162c01a2df0ea6, 420ebc4a000000000000000000000000420ebc4a0000000000000000000000000e1801000000000000000000420ebc4a
+
+where the first set of columns before the '|' describe the object:
+
+       COLUMN  DESCRIPTION
+       ======= ===============================================================
+       OBJECT  Object debugging ID (appears as OBJ%x in some debug messages)
+       PARENT  Debugging ID of parent object
+       STAT    Object state
+       CHLDN   Number of child objects of this object
+       OPS     Number of outstanding operations on this object
+       OOP     Number of outstanding child object management operations
+       IPR
+       EX      Number of outstanding exclusive operations
+       READS   Number of outstanding read operations
+       EM      Object's event mask
+       EV      Events raised on this object
+       F       Object flags
+       S       Object slow-work work item flags
+
+and the second set of columns describe the object's cookie, if present:
+
+       COLUMN          DESCRIPTION
+       =============== =======================================================
+       NETFS_COOKIE_DEF Name of netfs cookie definition
+       TY              Cookie type (IX - index, DT - data, hex - special)
+       FL              Cookie flags
+       NETFS_DATA      Netfs private data stored in the cookie
+       OBJECT_KEY      Object key      } 1 column, with separating comma
+       AUX_DATA        Object aux data } presence may be configured
+
+The data shown may be filtered by attaching the a key to an appropriate keyring
+before viewing the file.  Something like:
+
+               keyctl add user fscache:objlist <restrictions> @s
+
+where <restrictions> are a selection of the following letters:
+
+       K       Show hexdump of object key (don't show if not given)
+       A       Show hexdump of object aux data (don't show if not given)
+
+and the following paired letters:
+
+       C       Show objects that have a cookie
+       c       Show objects that don't have a cookie
+       B       Show objects that are busy
+       b       Show objects that aren't busy
+       W       Show objects that have pending writes
+       w       Show objects that don't have pending writes
+       R       Show objects that have outstanding reads
+       r       Show objects that don't have outstanding reads
+       S       Show objects that have slow work queued
+       s       Show objects that don't have slow work queued
+
+If neither side of a letter pair is given, then both are implied.  For example:
+
+       keyctl add user fscache:objlist KB @s
+
+shows objects that are busy, and lists their object keys, but does not dump
+their auxiliary data.  It also implies "CcWwRrSs", but as 'B' is given, 'b' is
+not implied.
+
+By default all objects and all fields will be shown.
+
+
 =========
 DEBUGGING
 =========
index 2666b1ed5e9e6515cdda71c878f846438167a0b1..1902c57b72ef7e103a07856dd520aef772c1e684 100644 (file)
@@ -641,7 +641,7 @@ data file must be retired (see the relinquish cookie function below).
 
 Furthermore, note that this does not cancel the asynchronous read or write
 operation started by the read/alloc and write functions, so the page
-invalidation and release functions must use:
+invalidation functions must use:
 
        bool fscache_check_page_write(struct fscache_cookie *cookie,
                                      struct page *page);
@@ -654,6 +654,25 @@ to see if a page is being written to the cache, and:
 to wait for it to finish if it is.
 
 
+When releasepage() is being implemented, a special FS-Cache function exists to
+manage the heuristics of coping with vmscan trying to eject pages, which may
+conflict with the cache trying to write pages to the cache (which may itself
+need to allocate memory):
+
+       bool fscache_maybe_release_page(struct fscache_cookie *cookie,
+                                       struct page *page,
+                                       gfp_t gfp);
+
+This takes the netfs cookie, and the page and gfp arguments as supplied to
+releasepage().  It will return false if the page cannot be released yet for
+some reason and if it returns true, the page has been uncached and can now be
+released.
+
+To make a page available for release, this function may wait for an outstanding
+storage request to complete, or it may attempt to cancel the storage request -
+in which case the page will not be stored in the cache this time.
+
+
 ==========================
 INDEX AND DATA FILE UPDATE
 ==========================
index c2a0871280a02eeaa6c027300207881b4a8825cf..c58b9f5ba002a4bdfb8b0ef2aefb30d08160bf53 100644 (file)
@@ -20,15 +20,16 @@ Lots of code taken from ext3 and other projects.
 Authors in alphabetical order:
 Joel Becker   <joel.becker@oracle.com>
 Zach Brown    <zach.brown@oracle.com>
-Mark Fasheh   <mark.fasheh@oracle.com>
+Mark Fasheh   <mfasheh@suse.com>
 Kurt Hackel   <kurt.hackel@oracle.com>
+Tao Ma        <tao.ma@oracle.com>
 Sunil Mushran <sunil.mushran@oracle.com>
 Manish Singh  <manish.singh@oracle.com>
+Tiger Yang    <tiger.yang@oracle.com>
 
 Caveats
 =======
 Features which OCFS2 does not support yet:
-       - quotas
        - Directory change notification (F_NOTIFY)
        - Distributed Caching (F_SETLEASE/F_GETLEASE/break_lease)
 
@@ -70,7 +71,6 @@ commit=nrsec  (*)     Ocfs2 can be told to sync all its data and metadata
                        performance.
 localalloc=8(*)                Allows custom localalloc size in MB. If the value is too
                        large, the fs will silently revert it to the default.
-                       Localalloc is not enabled for local mounts.
 localflocks            This disables cluster aware flock.
 inode64                        Indicates that Ocfs2 is allowed to create inodes at
                        any location in the filesystem, including those which
index c8d1b2be28eff182b699571a18143497db246fcb..51138b3dc8cc7cac2e5f01907b84d23e957df304 100644 (file)
@@ -85,7 +85,6 @@ parameter is applicable:
        PPT     Parallel port support is enabled.
        PS2     Appropriate PS/2 support is enabled.
        RAM     RAM disk support is enabled.
-       ROOTPLUG The example Root Plug LSM is enabled.
        S390    S390 architecture is enabled.
        SCSI    Appropriate SCSI support is enabled.
                        A lot of drivers has their options described inside of
@@ -2039,8 +2038,15 @@ and is between 256 and 4096 characters. It is defined in the file
 
        print-fatal-signals=
                        [KNL] debug: print fatal signals
-                       print-fatal-signals=1: print segfault info to
-                       the kernel console.
+
+                       If enabled, warn about various signal handling
+                       related application anomalies: too many signals,
+                       too many POSIX.1 timers, fatal signals causing a
+                       coredump - etc.
+
+                       If you hit the warning due to signal overflow,
+                       you might want to try "ulimit -i unlimited".
+
                        default: off.
 
        printk.time=    Show timing data prefixed to each printk message line
@@ -2171,15 +2177,6 @@ and is between 256 and 4096 characters. It is defined in the file
                        Useful for devices that are detected asynchronously
                        (e.g. USB and MMC devices).
 
-       root_plug.vendor_id=
-                       [ROOTPLUG] Override the default vendor ID
-
-       root_plug.product_id=
-                       [ROOTPLUG] Override the default product ID
-
-       root_plug.debug=
-                       [ROOTPLUG] Enable debugging output
-
        rw              [KNL] Mount root device read-write on boot
 
        S               [KNL] Run init in single mode
index 059934363cafaf18a15ebff592e167f8c84ee539..446f43b309dfea887937c8059634cc1b8f7642d8 100644 (file)
@@ -1,5 +1,17 @@
 This file details changes in 2.6 which affect PCMCIA card driver authors:
 
+* no cs_error / CS_CHECK / CONFIG_PCMCIA_DEBUG (as of 2.6.33)
+   Instead of the cs_error() callback or the CS_CHECK() macro, please use
+   Linux-style checking of return values, and -- if necessary -- debug
+   messages using "dev_dbg()" or "pr_debug()".
+
+* New CIS tuple access (as of 2.6.33)
+   Instead of pcmcia_get_{first,next}_tuple(), pcmcia_get_tuple_data() and
+   pcmcia_parse_tuple(), a driver shall use "pcmcia_get_tuple()" if it is
+   only interested in one (raw) tuple, or "pcmcia_loop_tuple()" if it is
+   interested in all tuples of one type. To decode the MAC from CISTPL_FUNCE,
+   a new helper "pcmcia_get_mac_from_cis()" was added.
+
 * New configuration loop helper (as of 2.6.28)
    By calling pcmcia_loop_config(), a driver can iterate over all available
    configuration options. During a driver's probe() phase, one doesn't need
index ebc50f808ea4b6774992ff340a4de9c5492c8135..9dbf4470c7e16df9530591cfdc7fbf401ff23a2f 100644 (file)
@@ -41,6 +41,13 @@ expand files, provided the time taken to do so isn't too long.
 Operations of both types may sleep during execution, thus tying up the thread
 loaned to it.
 
+A further class of work item is available, based on the slow work item class:
+
+ (*) Delayed slow work items.
+
+These are slow work items that have a timer to defer queueing of the item for
+a while.
+
 
 THREAD-TO-CLASS ALLOCATION
 --------------------------
@@ -64,9 +71,11 @@ USING SLOW WORK ITEMS
 Firstly, a module or subsystem wanting to make use of slow work items must
 register its interest:
 
-        int ret = slow_work_register_user();
+        int ret = slow_work_register_user(struct module *module);
 
-This will return 0 if successful, or a -ve error upon failure.
+This will return 0 if successful, or a -ve error upon failure.  The module
+pointer should be the module interested in using this facility (almost
+certainly THIS_MODULE).
 
 
 Slow work items may then be set up by:
@@ -91,6 +100,10 @@ Slow work items may then be set up by:
 
        slow_work_init(&myitem, &myitem_ops);
 
+     or:
+
+       delayed_slow_work_init(&myitem, &myitem_ops);
+
      or:
 
        vslow_work_init(&myitem, &myitem_ops);
@@ -102,15 +115,92 @@ A suitably set up work item can then be enqueued for processing:
        int ret = slow_work_enqueue(&myitem);
 
 This will return a -ve error if the thread pool is unable to gain a reference
-on the item, 0 otherwise.
+on the item, 0 otherwise, or (for delayed work):
+
+       int ret = delayed_slow_work_enqueue(&myitem, my_jiffy_delay);
 
 
 The items are reference counted, so there ought to be no need for a flush
-operation.  When all a module's slow work items have been processed, and the
+operation.  But as the reference counting is optional, means to cancel
+existing work items are also included:
+
+       cancel_slow_work(&myitem);
+       cancel_delayed_slow_work(&myitem);
+
+can be used to cancel pending work.  The above cancel function waits for
+existing work to have been executed (or prevent execution of them, depending
+on timing).
+
+
+When all a module's slow work items have been processed, and the
 module has no further interest in the facility, it should unregister its
 interest:
 
-       slow_work_unregister_user();
+       slow_work_unregister_user(struct module *module);
+
+The module pointer is used to wait for all outstanding work items for that
+module before completing the unregistration.  This prevents the put_ref() code
+from being taken away before it completes.  module should almost certainly be
+THIS_MODULE.
+
+
+================
+HELPER FUNCTIONS
+================
+
+The slow-work facility provides a function by which it can be determined
+whether or not an item is queued for later execution:
+
+       bool queued = slow_work_is_queued(struct slow_work *work);
+
+If it returns false, then the item is not on the queue (it may be executing
+with a requeue pending).  This can be used to work out whether an item on which
+another depends is on the queue, thus allowing a dependent item to be queued
+after it.
+
+If the above shows an item on which another depends not to be queued, then the
+owner of the dependent item might need to wait.  However, to avoid locking up
+the threads unnecessarily be sleeping in them, it can make sense under some
+circumstances to return the work item to the queue, thus deferring it until
+some other items have had a chance to make use of the yielded thread.
+
+To yield a thread and defer an item, the work function should simply enqueue
+the work item again and return.  However, this doesn't work if there's nothing
+actually on the queue, as the thread just vacated will jump straight back into
+the item's work function, thus busy waiting on a CPU.
+
+Instead, the item should use the thread to wait for the dependency to go away,
+but rather than using schedule() or schedule_timeout() to sleep, it should use
+the following function:
+
+       bool requeue = slow_work_sleep_till_thread_needed(
+                       struct slow_work *work,
+                       signed long *_timeout);
+
+This will add a second wait and then sleep, such that it will be woken up if
+either something appears on the queue that could usefully make use of the
+thread - and behind which this item can be queued, or if the event the caller
+set up to wait for happens.  True will be returned if something else appeared
+on the queue and this work function should perhaps return, of false if
+something else woke it up.  The timeout is as for schedule_timeout().
+
+For example:
+
+       wq = bit_waitqueue(&my_flags, MY_BIT);
+       init_wait(&wait);
+       requeue = false;
+       do {
+               prepare_to_wait(wq, &wait, TASK_UNINTERRUPTIBLE);
+               if (!test_bit(MY_BIT, &my_flags))
+                       break;
+               requeue = slow_work_sleep_till_thread_needed(&my_work,
+                                                            &timeout);
+       } while (timeout > 0 && !requeue);
+       finish_wait(wq, &wait);
+       if (!test_bit(MY_BIT, &my_flags)
+               goto do_my_thing;
+       if (requeue)
+               return; // to slow_work
 
 
 ===============
@@ -118,7 +208,8 @@ ITEM OPERATIONS
 ===============
 
 Each work item requires a table of operations of type struct slow_work_ops.
-All members are required:
+Only ->execute() is required; the getting and putting of a reference and the
+describing of an item are all optional.
 
  (*) Get a reference on an item:
 
@@ -148,6 +239,16 @@ All members are required:
      This should perform the work required of the item.  It may sleep, it may
      perform disk I/O and it may wait for locks.
 
+ (*) View an item through /proc:
+
+       void (*desc)(struct slow_work *work, struct seq_file *m);
+
+     If supplied, this should print to 'm' a small string describing the work
+     the item is to do.  This should be no more than about 40 characters, and
+     shouldn't include a newline character.
+
+     See the 'Viewing executing and queued items' section below.
+
 
 ==================
 POOL CONFIGURATION
@@ -172,3 +273,50 @@ The slow-work thread pool has a number of configurables:
      is bounded to between 1 and one fewer than the number of active threads.
      This ensures there is always at least one thread that can process very
      slow work items, and always at least one thread that won't.
+
+
+==================================
+VIEWING EXECUTING AND QUEUED ITEMS
+==================================
+
+If CONFIG_SLOW_WORK_DEBUG is enabled, a debugfs file is made available:
+
+       /sys/kernel/debug/slow_work/runqueue
+
+through which the list of work items being executed and the queues of items to
+be executed may be viewed.  The owner of a work item is given the chance to
+add some information of its own.
+
+The contents look something like the following:
+
+    THR PID   ITEM ADDR        FL MARK  DESC
+    === ===== ================ == ===== ==========
+      0  3005 ffff880023f52348  a 952ms FSC: OBJ17d3: LOOK
+      1  3006 ffff880024e33668  2 160ms FSC: OBJ17e5 OP60d3b: Write1/Store fl=2
+      2  3165 ffff8800296dd180  a 424ms FSC: OBJ17e4: LOOK
+      3  4089 ffff8800262c8d78  a 212ms FSC: OBJ17ea: CRTN
+      4  4090 ffff88002792bed8  2 388ms FSC: OBJ17e8 OP60d36: Write1/Store fl=2
+      5  4092 ffff88002a0ef308  2 388ms FSC: OBJ17e7 OP60d2e: Write1/Store fl=2
+      6  4094 ffff88002abaf4b8  2 132ms FSC: OBJ17e2 OP60d4e: Write1/Store fl=2
+      7  4095 ffff88002bb188e0  a 388ms FSC: OBJ17e9: CRTN
+    vsq     - ffff880023d99668  1 308ms FSC: OBJ17e0 OP60f91: Write1/EnQ fl=2
+    vsq     - ffff8800295d1740  1 212ms FSC: OBJ16be OP4d4b6: Write1/EnQ fl=2
+    vsq     - ffff880025ba3308  1 160ms FSC: OBJ179a OP58dec: Write1/EnQ fl=2
+    vsq     - ffff880024ec83e0  1 160ms FSC: OBJ17ae OP599f2: Write1/EnQ fl=2
+    vsq     - ffff880026618e00  1 160ms FSC: OBJ17e6 OP60d33: Write1/EnQ fl=2
+    vsq     - ffff880025a2a4b8  1 132ms FSC: OBJ16a2 OP4d583: Write1/EnQ fl=2
+    vsq     - ffff880023cbe6d8  9 212ms FSC: OBJ17eb: LOOK
+    vsq     - ffff880024d37590  9 212ms FSC: OBJ17ec: LOOK
+    vsq     - ffff880027746cb0  9 212ms FSC: OBJ17ed: LOOK
+    vsq     - ffff880024d37ae8  9 212ms FSC: OBJ17ee: LOOK
+    vsq     - ffff880024d37cb0  9 212ms FSC: OBJ17ef: LOOK
+    vsq     - ffff880025036550  9 212ms FSC: OBJ17f0: LOOK
+    vsq     - ffff8800250368e0  9 212ms FSC: OBJ17f1: LOOK
+    vsq     - ffff880025036aa8  9 212ms FSC: OBJ17f2: LOOK
+
+In the 'THR' column, executing items show the thread they're occupying and
+queued threads indicate which queue they're on.  'PID' shows the process ID of
+a slow-work thread that's executing something.  'FL' shows the work item flags.
+'MARK' indicates how long since an item was queued or began executing.  Lastly,
+the 'DESC' column permits the owner of an item to give some information.
+
index 3ec4f2a2258537a80b77f1ca341b1df03ded6ae8..4793c6aac73343e580a98de57b1b014c87165a08 100644 (file)
@@ -218,7 +218,7 @@ static void fatal(const char *x, ...)
        exit(EXIT_FAILURE);
 }
 
-int checked_open(const char *pathname, int flags)
+static int checked_open(const char *pathname, int flags)
 {
        int fd = open(pathname, flags);
 
index 81d68d5b7eea0c172c6fce0cd5bd4abcd32ac75a..4f96ac81089c545e9f2346bc53c2dc65ae9c9315 100644 (file)
@@ -512,10 +512,32 @@ W:        http://www.arm.linux.org.uk/
 S:     Maintained
 F:     arch/arm/
 
+ARM PRIMECELL AACI PL041 DRIVER
+M:     Russell King <linux@arm.linux.org.uk>
+S:     Maintained
+F:     sound/arm/aaci.*
+
+ARM PRIMECELL CLCD PL110 DRIVER
+M:     Russell King <linux@arm.linux.org.uk>
+S:     Maintained
+F:     drivers/video/amba-clcd.*
+
+ARM PRIMECELL KMI PL050 DRIVER
+M:     Russell King <linux@arm.linux.org.uk>
+S:     Maintained
+F:     drivers/input/serio/ambakmi.*
+F:     include/linux/amba/kmi.h
+
 ARM PRIMECELL MMCI PL180/1 DRIVER
 S:     Orphan
 F:     drivers/mmc/host/mmci.*
 
+ARM PRIMECELL BUS SUPPORT
+M:     Russell King <linux@arm.linux.org.uk>
+S:     Maintained
+F:     drivers/amba/
+F:     include/linux/amba/bus.h
+
 ARM/ADI ROADRUNNER MACHINE SUPPORT
 M:     Lennert Buytenhek <kernel@wantstofly.org>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
@@ -1027,7 +1049,7 @@ F:        drivers/serial/atmel_serial.c
 
 ATMEL LCDFB DRIVER
 M:     Nicolas Ferre <nicolas.ferre@atmel.com>
-L:     linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers)
+L:     linux-fbdev@vger.kernel.org
 S:     Maintained
 F:     drivers/video/atmel_lcdfb.c
 F:     include/video/atmel_lcdc.h
@@ -2113,7 +2135,7 @@ F:        drivers/net/wan/dlci.c
 F:     drivers/net/wan/sdla.c
 
 FRAMEBUFFER LAYER
-L:     linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers)
+L:     linux-fbdev@vger.kernel.org
 W:     http://linux-fbdev.sourceforge.net/
 S:     Orphan
 F:     Documentation/fb/
@@ -2136,7 +2158,7 @@ F:        drivers/i2c/busses/i2c-cpm.c
 
 FREESCALE IMX / MXC FRAMEBUFFER DRIVER
 M:     Sascha Hauer <kernel@pengutronix.de>
-L:     linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers)
+L:     linux-fbdev@vger.kernel.org
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:     Maintained
 F:     arch/arm/plat-mxc/include/mach/imxfb.h
@@ -2312,6 +2334,13 @@ T:       git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
 S:     Maintained
 F:     drivers/media/video/gspca/finepix.c
 
+GSPCA GL860 SUBDRIVER
+M:     Olivier Lorin <o.lorin@laposte.net>
+L:     linux-media@vger.kernel.org
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
+S:     Maintained
+F:     drivers/media/video/gspca/gl860/
+
 GSPCA M5602 SUBDRIVER
 M:     Erik Andren <erik.andren@gmail.com>
 L:     linux-media@vger.kernel.org
@@ -2533,8 +2562,7 @@ S:        Maintained
 F:     Documentation/i2c/
 F:     drivers/i2c/
 F:     include/linux/i2c.h
-F:     include/linux/i2c-dev.h
-F:     include/linux/i2c-id.h
+F:     include/linux/i2c-*.h
 
 I2C-TINY-USB DRIVER
 M:     Till Harbaum <till@harbaum.org>
@@ -2635,7 +2663,7 @@ S:        Supported
 F:     security/integrity/ima/
 
 IMS TWINTURBO FRAMEBUFFER DRIVER
-L:     linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers)
+L:     linux-fbdev@vger.kernel.org
 S:     Orphan
 F:     drivers/video/imsttfb.c
 
@@ -2670,14 +2698,14 @@ F:      drivers/input/
 
 INTEL FRAMEBUFFER DRIVER (excluding 810 and 815)
 M:     Sylvain Meyer <sylvain.meyer@worldonline.fr>
-L:     linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers)
+L:     linux-fbdev@vger.kernel.org
 S:     Maintained
 F:     Documentation/fb/intelfb.txt
 F:     drivers/video/intelfb/
 
 INTEL 810/815 FRAMEBUFFER DRIVER
 M:     Antonino Daplas <adaplas@gmail.com>
-L:     linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers)
+L:     linux-fbdev@vger.kernel.org
 S:     Maintained
 F:     drivers/video/i810/
 
@@ -2987,11 +3015,8 @@ S:       Maintained
 F:     fs/autofs4/
 
 KERNEL BUILD
-M:     Sam Ravnborg <sam@ravnborg.org>
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/sam/kbuild-next.git
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/sam/kbuild-fixes.git
 L:     linux-kbuild@vger.kernel.org
-S:     Maintained
+S:     Orphan
 F:     Documentation/kbuild/
 F:     Makefile
 F:     scripts/Makefile.*
@@ -3084,9 +3109,13 @@ F:       kernel/kgdb.c
 
 KMEMCHECK
 M:     Vegard Nossum <vegardno@ifi.uio.no>
-P      Pekka Enberg
-M:     penberg@cs.helsinki.fi
+M:     Pekka Enberg <penberg@cs.helsinki.fi>
 S:     Maintained
+F:     Documentation/kmemcheck.txt
+F:     arch/x86/include/asm/kmemcheck.h
+F:     arch/x86/mm/kmemcheck/
+F:     include/linux/kmemcheck.h
+F:     mm/kmemcheck.c
 
 KMEMLEAK
 M:     Catalin Marinas <catalin.marinas@arm.com>
@@ -3387,7 +3416,7 @@ S:        Supported
 
 MATROX FRAMEBUFFER DRIVER
 M:     Petr Vandrovec <vandrove@vc.cvut.cz>
-L:     linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers)
+L:     linux-fbdev@vger.kernel.org
 S:     Maintained
 F:     drivers/video/matrox/matroxfb_*
 F:     include/linux/matroxfb.h
@@ -3774,7 +3803,7 @@ F:        fs/ntfs/
 
 NVIDIA (rivafb and nvidiafb) FRAMEBUFFER DRIVER
 M:     Antonino Daplas <adaplas@gmail.com>
-L:     linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers)
+L:     linux-fbdev@vger.kernel.org
 S:     Maintained
 F:     drivers/video/riva/
 F:     drivers/video/nvidia/
@@ -3809,7 +3838,7 @@ F:        sound/soc/omap/
 
 OMAP FRAMEBUFFER SUPPORT
 M:     Imre Deak <imre.deak@nokia.com>
-L:     linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers)
+L:     linux-fbdev@vger.kernel.org
 L:     linux-omap@vger.kernel.org
 S:     Maintained
 F:     drivers/video/omap/
@@ -4315,19 +4344,21 @@ F:      include/linux/qnxtypes.h
 
 RADEON FRAMEBUFFER DISPLAY DRIVER
 M:     Benjamin Herrenschmidt <benh@kernel.crashing.org>
-L:     linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers)
+L:     linux-fbdev@vger.kernel.org
 S:     Maintained
 F:     drivers/video/aty/radeon*
 F:     include/linux/radeonfb.h
 
 RAGE128 FRAMEBUFFER DISPLAY DRIVER
 M:     Paul Mackerras <paulus@samba.org>
-L:     linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers)
+L:     linux-fbdev@vger.kernel.org
 S:     Maintained
 F:     drivers/video/aty/aty128fb.c
 
 RALINK RT2X00 WIRELESS LAN DRIVER
 P:     rt2x00 project
+M:     Ivo van Doorn <IvDoorn@gmail.com>
+M:     Gertjan van Wingerde <gwingerde@gmail.com>
 L:     linux-wireless@vger.kernel.org
 L:     users@rt2x00.serialmonkey.com (moderated for non-subscribers)
 W:     http://rt2x00.serialmonkey.com/
@@ -4415,7 +4446,7 @@ RFKILL
 M:     Johannes Berg <johannes@sipsolutions.net>
 L:     linux-wireless@vger.kernel.org
 S:     Maintained
-F      Documentation/rfkill.txt
+F:     Documentation/rfkill.txt
 F:     net/rfkill/
 
 RISCOM8 DRIVER
@@ -4459,7 +4490,7 @@ F:        drivers/net/wireless/rtl818x/rtl8187*
 
 S3 SAVAGE FRAMEBUFFER DRIVER
 M:     Antonino Daplas <adaplas@gmail.com>
-L:     linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers)
+L:     linux-fbdev@vger.kernel.org
 S:     Maintained
 F:     drivers/video/savage/
 
@@ -5622,7 +5653,7 @@ S:        Maintained
 
 UVESAFB DRIVER
 M:     Michal Januszewski <spock@gentoo.org>
-L:     linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers)
+L:     linux-fbdev@vger.kernel.org
 W:     http://dev.gentoo.org/~spock/projects/uvesafb/
 S:     Maintained
 F:     Documentation/fb/uvesafb.txt
@@ -5655,7 +5686,7 @@ F:        drivers/mmc/host/via-sdmmc.c
 VIA UNICHROME(PRO)/CHROME9 FRAMEBUFFER DRIVER
 M:     Joseph Chan <JosephChan@via.com.tw>
 M:     Scott Fang <ScottFang@viatech.com.cn>
-L:     linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers)
+L:     linux-fbdev@vger.kernel.org
 S:     Maintained
 F:     drivers/video/via/
 
index 8278361281588a802accd4d1e8a94cb0e34de851..33d4732a6c4a319c4479933c826dd37be489684b 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 6
 SUBLEVEL = 32
-EXTRAVERSION = -rc7
+EXTRAVERSION =
 NAME = Man-Eating Seals of Antiquity
 
 # *DOCUMENTATION*
@@ -221,7 +221,7 @@ CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \
 
 HOSTCC       = gcc
 HOSTCXX      = g++
-HOSTCFLAGS   = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer
+HOSTCFLAGS   = -Wall -Wmissing-prototypes -Wstrict-prototypes -O2 -fomit-frame-pointer
 HOSTCXXFLAGS = -O2
 
 # Decide whether to build built-in, modular, or both.
@@ -379,6 +379,7 @@ export RCS_TAR_IGNORE := --exclude SCCS --exclude BitKeeper --exclude .svn --exc
 PHONY += scripts_basic
 scripts_basic:
        $(Q)$(MAKE) $(build)=scripts/basic
+       $(Q)rm -f .tmp_quiet_recordmcount
 
 # To avoid any implicit rule to kick in, define an empty command.
 scripts/basic/%: scripts_basic ;
index 9d0727d18aeeb82f6a1920f0ba3fc2bb1775e5cc..367d53d031fc04d51af471273a0256a5a08432c7 100644 (file)
@@ -35,7 +35,7 @@
 const char * prog_name;
 
 
-void
+static void
 usage (void)
 {
     fprintf(stderr,
index 73126e4dd639416df233d0ca5f134049b2fd6f70..25da0017ec87fb2dd675257d7d16a68cc5f89aff 100644 (file)
@@ -26,8 +26,6 @@
 #define F_GETOWN       6       /*  for sockets. */
 #define F_SETSIG       10      /*  for sockets. */
 #define F_GETSIG       11      /*  for sockets. */
-#define F_SETOWN_EX    15
-#define F_GETOWN_EX    16
 
 /* for posix fcntl() and lockf() */
 #define F_RDLCK                1
index 815680b585ed2d15e766384b1401dd67f5e138d9..b3e888638bb7c819547cba13e5ec48724d596cd1 100644 (file)
@@ -61,21 +61,24 @@ register struct thread_info *__current_thread_info __asm__("$8");
 /*
  * Thread information flags:
  * - these are process state flags and used from assembly
- * - pending work-to-be-done flags come first to fit in and immediate operand.
+ * - pending work-to-be-done flags come first and must be assigned to be
+ *   within bits 0 to 7 to fit in and immediate operand.
+ * - ALPHA_UAC_SHIFT below must be kept consistent with the unaligned
+ *   control flags.
  *
  * TIF_SYSCALL_TRACE is known to be 0 via blbs.
  */
 #define TIF_SYSCALL_TRACE      0       /* syscall trace active */
-#define TIF_SIGPENDING         1       /* signal pending */
-#define TIF_NEED_RESCHED       2       /* rescheduling necessary */
-#define TIF_POLLING_NRFLAG     3       /* poll_idle is polling NEED_RESCHED */
-#define TIF_DIE_IF_KERNEL      4       /* dik recursion lock */
-#define TIF_UAC_NOPRINT                5       /* see sysinfo.h */
-#define TIF_UAC_NOFIX          6
-#define TIF_UAC_SIGBUS         7
-#define TIF_MEMDIE             8
-#define TIF_RESTORE_SIGMASK    9       /* restore signal mask in do_signal */
-#define TIF_NOTIFY_RESUME      10      /* callback before returning to user */
+#define TIF_NOTIFY_RESUME      1       /* callback before returning to user */
+#define TIF_SIGPENDING         2       /* signal pending */
+#define TIF_NEED_RESCHED       3       /* rescheduling necessary */
+#define TIF_POLLING_NRFLAG     8       /* poll_idle is polling NEED_RESCHED */
+#define TIF_DIE_IF_KERNEL      9       /* dik recursion lock */
+#define TIF_UAC_NOPRINT                10      /* see sysinfo.h */
+#define TIF_UAC_NOFIX          11
+#define TIF_UAC_SIGBUS         12
+#define TIF_MEMDIE             13
+#define TIF_RESTORE_SIGMASK    14      /* restore signal mask in do_signal */
 #define TIF_FREEZE             16      /* is freezing for suspend */
 
 #define _TIF_SYSCALL_TRACE     (1<<TIF_SYSCALL_TRACE)
@@ -94,7 +97,7 @@ register struct thread_info *__current_thread_info __asm__("$8");
 #define _TIF_ALLWORK_MASK      (_TIF_WORK_MASK         \
                                 | _TIF_SYSCALL_TRACE)
 
-#define ALPHA_UAC_SHIFT                6
+#define ALPHA_UAC_SHIFT                10
 #define ALPHA_UAC_MASK         (1 << TIF_UAC_NOPRINT | 1 << TIF_UAC_NOFIX | \
                                 1 << TIF_UAC_SIGBUS)
 
index 8e059e58b0acd6eba4aace468da92dd0090e5008..53dd2f1a53aabd25f188053e2e78fb9510d45d75 100644 (file)
@@ -1103,6 +1103,8 @@ marvel_agp_info(void)
         * Allocate the info structure.
         */
        agp = kmalloc(sizeof(*agp), GFP_KERNEL);
+       if (!agp)
+               return NULL;
 
        /*
         * Fill it in.
index 76686497b1e210992fcf0ee51fd86ed800e5dd14..219bf271c0ba2e5f2d668af707df57fbbd00ccfd 100644 (file)
@@ -757,6 +757,8 @@ titan_agp_info(void)
         * Allocate the info structure.
         */
        agp = kmalloc(sizeof(*agp), GFP_KERNEL);
+       if (!agp)
+               return NULL;
 
        /*
         * Fill it in.
index cc783466142754b97475522de5fd39aaa5b85f37..c0de072b8305bab3c507b96f92da2536aab9667c 100644 (file)
@@ -92,7 +92,7 @@ show_interrupts(struct seq_file *p, void *v)
                for_each_online_cpu(j)
                        seq_printf(p, "%10u ", kstat_irqs_cpu(irq, j));
 #endif
-               seq_printf(p, " %14s", irq_desc[irq].chip->typename);
+               seq_printf(p, " %14s", irq_desc[irq].chip->name);
                seq_printf(p, "  %c%s",
                        (action->flags & IRQF_DISABLED)?'+':' ',
                        action->name);
index 38c805dfc5445dd02ba8683d6c538d9daf4c8822..cfde865b78e05f9c02c89d174887e38ef12590b2 100644 (file)
@@ -228,7 +228,7 @@ struct irqaction timer_irqaction = {
 };
 
 static struct irq_chip rtc_irq_type = {
-       .typename       = "RTC",
+       .name           = "RTC",
        .startup        = rtc_startup,
        .shutdown       = rtc_enable_disable,
        .enable         = rtc_enable_disable,
index 50bfec9b588ffbc8ba4d08a47c532bf5f0de7299..83a9ac2808908cf49e2014bf1960e4cdb95afc95 100644 (file)
@@ -84,7 +84,7 @@ i8259a_end_irq(unsigned int irq)
 }
 
 struct irq_chip i8259a_irq_type = {
-       .typename       = "XT-PIC",
+       .name           = "XT-PIC",
        .startup        = i8259a_startup_irq,
        .shutdown       = i8259a_disable_irq,
        .enable         = i8259a_enable_irq,
index 69199a76ec4a41f6d165f66a56738a5b048340bd..989ce46a0cf3392e22d57f36fe23c8ab1752d5d6 100644 (file)
@@ -71,7 +71,7 @@ pyxis_mask_and_ack_irq(unsigned int irq)
 }
 
 static struct irq_chip pyxis_irq_type = {
-       .typename       = "PYXIS",
+       .name           = "PYXIS",
        .startup        = pyxis_startup_irq,
        .shutdown       = pyxis_disable_irq,
        .enable         = pyxis_enable_irq,
index 85229369a1f8bfa31e7e326f1e0bc42020550a75..d63e93e1e8bf885295a26e4ec154c836a96c3d64 100644 (file)
@@ -49,7 +49,7 @@ srm_end_irq(unsigned int irq)
 
 /* Handle interrupts from the SRM, assuming no additional weirdness.  */
 static struct irq_chip srm_irq_type = {
-       .typename       = "SRM",
+       .name           = "SRM",
        .startup        = srm_startup_irq,
        .shutdown       = srm_disable_irq,
        .enable         = srm_enable_irq,
index 382035ef7394666e20f7a4b9c821f2f71051e800..20a30b8b96559e888223d16e60dec6bad9347297 100644 (file)
@@ -90,7 +90,7 @@ alcor_end_irq(unsigned int irq)
 }
 
 static struct irq_chip alcor_irq_type = {
-       .typename       = "ALCOR",
+       .name           = "ALCOR",
        .startup        = alcor_startup_irq,
        .shutdown       = alcor_disable_irq,
        .enable         = alcor_enable_irq,
index ed349436732ba2ded473fc8c65776b422cb77b09..affd0f3f25df09b147c4a1e06146ff2f57e550ce 100644 (file)
@@ -72,7 +72,7 @@ cabriolet_end_irq(unsigned int irq)
 }
 
 static struct irq_chip cabriolet_irq_type = {
-       .typename       = "CABRIOLET",
+       .name           = "CABRIOLET",
        .startup        = cabriolet_startup_irq,
        .shutdown       = cabriolet_disable_irq,
        .enable         = cabriolet_enable_irq,
index 46e70ece5176ec1372e26dc09072759b26de5c43..d64e1e497e76a1edd304d4036f3f1d7a5a41c83a 100644 (file)
@@ -199,7 +199,7 @@ clipper_set_affinity(unsigned int irq, const struct cpumask *affinity)
 }
 
 static struct irq_chip dp264_irq_type = {
-       .typename       = "DP264",
+       .name           = "DP264",
        .startup        = dp264_startup_irq,
        .shutdown       = dp264_disable_irq,
        .enable         = dp264_enable_irq,
@@ -210,7 +210,7 @@ static struct irq_chip dp264_irq_type = {
 };
 
 static struct irq_chip clipper_irq_type = {
-       .typename       = "CLIPPER",
+       .name           = "CLIPPER",
        .startup        = clipper_startup_irq,
        .shutdown       = clipper_disable_irq,
        .enable         = clipper_enable_irq,
index 660c23ef661f686bfbb7c6e2fe382ad3eb8b3478..df2090ce5e7f622b4bececed8ee38cfc0e2b558b 100644 (file)
@@ -70,7 +70,7 @@ eb64p_end_irq(unsigned int irq)
 }
 
 static struct irq_chip eb64p_irq_type = {
-       .typename       = "EB64P",
+       .name           = "EB64P",
        .startup        = eb64p_startup_irq,
        .shutdown       = eb64p_disable_irq,
        .enable         = eb64p_enable_irq,
index b99ea488d8446139d4fabdaa53dbeeedf51446eb..3ca1dbcf404477deb345277541df0b93f9776957 100644 (file)
@@ -81,7 +81,7 @@ eiger_end_irq(unsigned int irq)
 }
 
 static struct irq_chip eiger_irq_type = {
-       .typename       = "EIGER",
+       .name           = "EIGER",
        .startup        = eiger_startup_irq,
        .shutdown       = eiger_disable_irq,
        .enable         = eiger_enable_irq,
index ef0b83a070accb165129291fb58b2bfa19f748e7..7a7ae36fff913d22448687188c4c56536f2b96ae 100644 (file)
@@ -119,7 +119,7 @@ jensen_local_end(unsigned int irq)
 }
 
 static struct irq_chip jensen_local_irq_type = {
-       .typename       = "LOCAL",
+       .name           = "LOCAL",
        .startup        = jensen_local_startup,
        .shutdown       = jensen_local_shutdown,
        .enable         = jensen_local_enable,
index bbfc4f20ca72a2ed9f6e0ac2c3172fc81f8c33d1..0bb3b5c4f69377c3d146237ef50786ee78b56aae 100644 (file)
@@ -170,7 +170,7 @@ marvel_irq_noop_return(unsigned int irq)
 }
 
 static struct irq_chip marvel_legacy_irq_type = {
-       .typename       = "LEGACY",
+       .name           = "LEGACY",
        .startup        = marvel_irq_noop_return,
        .shutdown       = marvel_irq_noop,
        .enable         = marvel_irq_noop,
@@ -180,7 +180,7 @@ static struct irq_chip marvel_legacy_irq_type = {
 };
 
 static struct irq_chip io7_lsi_irq_type = {
-       .typename       = "LSI",
+       .name           = "LSI",
        .startup        = io7_startup_irq,
        .shutdown       = io7_disable_irq,
        .enable         = io7_enable_irq,
@@ -190,7 +190,7 @@ static struct irq_chip io7_lsi_irq_type = {
 };
 
 static struct irq_chip io7_msi_irq_type = {
-       .typename       = "MSI",
+       .name           = "MSI",
        .startup        = io7_startup_irq,
        .shutdown       = io7_disable_irq,
        .enable         = io7_enable_irq,
index 4e366641a08ed20c4f6cba1755f2e9082216a5df..ee88651698110e335dbe644c51ce47601ea3e5f2 100644 (file)
@@ -69,7 +69,7 @@ mikasa_end_irq(unsigned int irq)
 }
 
 static struct irq_chip mikasa_irq_type = {
-       .typename       = "MIKASA",
+       .name           = "MIKASA",
        .startup        = mikasa_startup_irq,
        .shutdown       = mikasa_disable_irq,
        .enable         = mikasa_enable_irq,
index 35753a173bac3073305d8c8a18156d5e7b90840a..86503fe73a8804444d52098d51bb1cd5b787aa85 100644 (file)
@@ -74,7 +74,7 @@ noritake_end_irq(unsigned int irq)
 }
 
 static struct irq_chip noritake_irq_type = {
-       .typename       = "NORITAKE",
+       .name           = "NORITAKE",
        .startup        = noritake_startup_irq,
        .shutdown       = noritake_disable_irq,
        .enable         = noritake_enable_irq,
index f3aec7e085c8c6f0a0165a7f47af0fe076312377..26c322bf89ee195a81863c8a4b42418991c6513f 100644 (file)
@@ -136,7 +136,7 @@ rawhide_end_irq(unsigned int irq)
 }
 
 static struct irq_chip rawhide_irq_type = {
-       .typename       = "RAWHIDE",
+       .name           = "RAWHIDE",
        .startup        = rawhide_startup_irq,
        .shutdown       = rawhide_disable_irq,
        .enable         = rawhide_enable_irq,
index d9f9cfeb9931354cee9d6df304877941ef13ecea..8de1046fe91e7f635decef2e2b08aa8d003977ca 100644 (file)
@@ -66,7 +66,7 @@ ruffian_init_irq(void)
        common_init_isa_dma();
 }
 
-#define RUFFIAN_LATCH  ((PIT_TICK_RATE + HZ / 2) / HZ)
+#define RUFFIAN_LATCH  DIV_ROUND_CLOSEST(PIT_TICK_RATE, HZ)
 
 static void __init
 ruffian_init_rtc(void)
index fc9246373452896439e58c01c8c595a1771c7d63..be161129eab996b0225adc4c73bd1d33ac55e794 100644 (file)
@@ -73,7 +73,7 @@ rx164_end_irq(unsigned int irq)
 }
 
 static struct irq_chip rx164_irq_type = {
-       .typename       = "RX164",
+       .name           = "RX164",
        .startup        = rx164_startup_irq,
        .shutdown       = rx164_disable_irq,
        .enable         = rx164_enable_irq,
index 426eb6906d0192a96872aa5697d2a0fc3bcb57a8..b2abe27a23cff2ad2164f9827efb938e395ce84f 100644 (file)
@@ -502,7 +502,7 @@ sable_lynx_mask_and_ack_irq(unsigned int irq)
 }
 
 static struct irq_chip sable_lynx_irq_type = {
-       .typename       = "SABLE/LYNX",
+       .name           = "SABLE/LYNX",
        .startup        = sable_lynx_startup_irq,
        .shutdown       = sable_lynx_disable_irq,
        .enable         = sable_lynx_enable_irq,
index 830318c21661dba4f36b2443e90686a7e4689d5b..230464885b5cbe1a7683a2c76acdf1e46fbb9bac 100644 (file)
@@ -75,7 +75,7 @@ takara_end_irq(unsigned int irq)
 }
 
 static struct irq_chip takara_irq_type = {
-       .typename       = "TAKARA",
+       .name           = "TAKARA",
        .startup        = takara_startup_irq,
        .shutdown       = takara_disable_irq,
        .enable         = takara_enable_irq,
index 88978fc60f835061b35746d8623b6713606a559b..288053342c83b5e951df1e4a68eb81ba2bd3ad62 100644 (file)
@@ -195,7 +195,7 @@ init_titan_irqs(struct irq_chip * ops, int imin, int imax)
 }
 
 static struct irq_chip titan_irq_type = {
-       .typename       = "TITAN",
+       .name          = "TITAN",
        .startup        = titan_startup_irq,
        .shutdown       = titan_disable_irq,
        .enable         = titan_enable_irq,
index e91b4c3838a8d3e5f21f4e5aa01d7135014fbe14..62fd972e18efcd42156fc3734ce15a2f1edc5819 100644 (file)
@@ -158,7 +158,7 @@ wildfire_end_irq(unsigned int irq)
 }
 
 static struct irq_chip wildfire_irq_type = {
-       .typename       = "WILDFIRE",
+       .name           = "WILDFIRE",
        .startup        = wildfire_startup_irq,
        .shutdown       = wildfire_disable_irq,
        .enable         = wildfire_enable_irq,
index d16ec97ec9a9948fbb7de727164a006bfe6eeae7..c019949a5189dc725a937006eb8445c18d0ad2ef 100644 (file)
@@ -22,4 +22,10 @@ enum km_type {
        KM_TYPE_NR
 };
 
+#ifdef CONFIG_DEBUG_HIGHMEM
+#define KM_NMI         (-1)
+#define KM_NMI_PTE     (-1)
+#define KM_IRQ_PTE     (-1)
+#endif
+
 #endif
index 2a573d4fea24a7ab12873282ad5c805a4c0e8de1..e7714f367eb83aa0a4b0224e5129ec94c87c3391 100644 (file)
@@ -662,8 +662,12 @@ static void do_signal(struct pt_regs *regs, int syscall)
                                regs->ARM_sp -= 4;
                                usp = (u32 __user *)regs->ARM_sp;
 
-                               put_user(regs->ARM_pc, usp);
-                               regs->ARM_pc = KERN_RESTART_CODE;
+                               if (put_user(regs->ARM_pc, usp) == 0) {
+                                       regs->ARM_pc = KERN_RESTART_CODE;
+                               } else {
+                                       regs->ARM_sp += 4;
+                                       force_sigsegv(0, current);
+                               }
 #endif
                        }
                }
index e35d54d43e709d52a3d025165c17cee01da8fc69..2fd88437348b58d3f5bff57c1a429650f321ecca 100644 (file)
@@ -289,13 +289,6 @@ config MACH_NEOCORE926
        help
          Select this if you are using the Adeneo Neocore 926 board.
 
-config MACH_AT91SAM9G20EK_2MMC
-       bool "Atmel AT91SAM9G20-EK Evaluation Kit modified for 2 MMC Slots"
-       depends on ARCH_AT91SAM9G20
-       help
-         Select this if you are using an Atmel AT91SAM9G20-EK Evaluation Kit
-         Rev A or B modified for 2 MMC Slots.
-
 endif
 
 # ----------------------------------------------------------
@@ -322,7 +315,16 @@ config MACH_AT91SAM9G20EK
        bool "Atmel AT91SAM9G20-EK Evaluation Kit"
        depends on ARCH_AT91SAM9G20
        help
-         Select this if you are using Atmel's AT91SAM9G20-EK Evaluation Kit.
+         Select this if you are using Atmel's AT91SAM9G20-EK Evaluation Kit
+         that embeds only one SD/MMC slot.
+
+config MACH_AT91SAM9G20EK_2MMC
+       bool "Atmel AT91SAM9G20-EK Evaluation Kit with 2 SD/MMC Slots"
+       depends on ARCH_AT91SAM9G20
+       help
+         Select this if you are using an Atmel AT91SAM9G20-EK Evaluation Kit
+         with 2 SD/MMC Slots. This is the case for AT91SAM9G20-EK rev. C and
+         onwards.
 
 config MACH_CPU9G20
        bool "Eukrea CPU9G20 board"
@@ -392,7 +394,7 @@ config MTD_AT91_DATAFLASH_CARD
 
 config MTD_NAND_ATMEL_BUSWIDTH_16
        bool "Enable 16-bit data bus interface to NAND flash"
-       depends on (MACH_AT91SAM9260EK || MACH_AT91SAM9261EK || MACH_AT91SAM9G10EK || MACH_AT91SAM9263EK || MACH_AT91SAM9G20EK || MACH_AT91SAM9G45EKES || MACH_AT91CAP9ADK)
+       depends on (MACH_AT91SAM9260EK || MACH_AT91SAM9261EK || MACH_AT91SAM9G10EK || MACH_AT91SAM9263EK || MACH_AT91SAM9G20EK || MACH_AT91SAM9G20EK_2MMC || MACH_AT91SAM9G45EKES || MACH_AT91CAP9ADK)
        help
          On AT91SAM926x boards both types of NAND flash can be present
          (8 and 16 bit data bus width).
index a28e53faf71d5248138eca588915045391678aec..a4102d72cc9b1c8e9d323f432fb5873b2144cc44 100644 (file)
@@ -90,7 +90,7 @@ static struct at91_udc_data __initdata ek_udc_data = {
  * SPI devices.
  */
 static struct spi_board_info ek_spi_devices[] = {
-#if !defined(CONFIG_MMC_ATMELMCI)
+#if !(defined(CONFIG_MMC_ATMELMCI) || defined(CONFIG_MMC_AT91))
        {       /* DataFlash chip */
                .modalias       = "mtd_dataflash",
                .chip_select    = 1,
@@ -113,7 +113,7 @@ static struct spi_board_info ek_spi_devices[] = {
  * MACB Ethernet device
  */
 static struct at91_eth_data __initdata ek_macb_data = {
-       .phy_irq_pin    = AT91_PIN_PC12,
+       .phy_irq_pin    = AT91_PIN_PB0,
        .is_rmii        = 1,
 };
 
@@ -194,24 +194,27 @@ static void __init ek_add_device_nand(void)
 
 /*
  * MCI (SD/MMC)
- * det_pin and wp_pin are not connected
+ * wp_pin is not connected
  */
 #if defined(CONFIG_MMC_ATMELMCI) || defined(CONFIG_MMC_ATMELMCI_MODULE)
 static struct mci_platform_data __initdata ek_mmc_data = {
        .slot[0] = {
                .bus_width      = 4,
-               .detect_pin     = -ENODEV,
+               .detect_pin     = AT91_PIN_PC2,
                .wp_pin         = -ENODEV,
        },
        .slot[1] = {
                .bus_width      = 4,
-               .detect_pin     = -ENODEV,
+               .detect_pin     = AT91_PIN_PC9,
                .wp_pin         = -ENODEV,
        },
 
 };
 #else
-static struct amci_platform_data __initdata ek_mmc_data = {
+static struct at91_mmc_data __initdata ek_mmc_data = {
+       .slot_b         = 1,    /* Only one slot so use slot B */
+       .wire4          = 1,
+       .det_pin        = AT91_PIN_PC9,
 };
 #endif
 
@@ -221,13 +224,13 @@ static struct amci_platform_data __initdata ek_mmc_data = {
 static struct gpio_led ek_leds[] = {
        {       /* "bottom" led, green, userled1 to be defined */
                .name                   = "ds5",
-               .gpio                   = AT91_PIN_PB12,
+               .gpio                   = AT91_PIN_PB8,
                .active_low             = 1,
                .default_trigger        = "none",
        },
        {       /* "power" led, yellow */
                .name                   = "ds1",
-               .gpio                   = AT91_PIN_PB13,
+               .gpio                   = AT91_PIN_PB9,
                .default_trigger        = "heartbeat",
        }
 };
@@ -254,7 +257,11 @@ static void __init ek_board_init(void)
        /* Ethernet */
        at91_add_device_eth(&ek_macb_data);
        /* MMC */
+#if defined(CONFIG_MMC_ATMELMCI) || defined(CONFIG_MMC_ATMELMCI_MODULE)
        at91_add_device_mci(0, &ek_mmc_data);
+#else
+       at91_add_device_mmc(0, &ek_mmc_data);
+#endif
        /* I2C */
        at91_add_device_i2c(ek_i2c_devices, ARRAY_SIZE(ek_i2c_devices));
        /* LEDs */
index 7177c4aa63421e22e5f57afcadf00e60a98a79fe..242dd077534336269804795d30c4afb04fe1739b 100644 (file)
@@ -915,6 +915,14 @@ void __init kirkwood_init(void)
        kirkwood_uart0_data[0].uartclk = kirkwood_tclk;
        kirkwood_uart1_data[0].uartclk = kirkwood_tclk;
 
+       /*
+        * Disable propagation of mbus errors to the CPU local bus,
+        * as this causes mbus errors (which can occur for example
+        * for PCI aborts) to throw CPU aborts, which we're not set
+        * up to deal with.
+        */
+       writel(readl(CPU_CONFIG) & ~CPU_CONFIG_ERROR_PROP, CPU_CONFIG);
+
        kirkwood_setup_cpu_mbus();
 
 #ifdef CONFIG_CACHE_FEROCEON_L2
index 9e80d9232c831e315783509b71a837de115b92b9..418f5017c50e1d916468ebc99e5b958a706d98f6 100644 (file)
@@ -13,6 +13,9 @@
 
 #include <mach/kirkwood.h>
 
+#define CPU_CONFIG             (BRIDGE_VIRT_BASE | 0x0100)
+#define CPU_CONFIG_ERROR_PROP  0x00000004
+
 #define CPU_CONTROL            (BRIDGE_VIRT_BASE | 0x0104)
 #define CPU_RESET              0x00000002
 
index bf1189ff9a34bd62fad9f8ab2c90c04e4703671b..7e8a80f25ddcfca47ce8817ad4f0eeeca3f6ed87 100644 (file)
 #define MMC1_WP_MMC1_WP                MFP_CFG_DRV(MMC1_WP, AF0, MEDIUM)
 
 /* PWM */
-#define GPIO27 PWM3 AF2                MFP_CFG(GPIO27, AF2)
+#define GPIO27_PWM3_AF2                MFP_CFG(GPIO27, AF2)
 #define GPIO51_PWM2_OUT                MFP_CFG(GPIO51, AF2)
 #define GPIO117_PWM1_OUT       MFP_CFG(GPIO117, AF2)
 #define GPIO118_PWM2_OUT       MFP_CFG(GPIO118, AF2)
index ea00486a5e5314b5e5255a7c3aa9d4a9af306960..51e0b3ba5f3a3c0110e2a70868ebd6970a01738e 100644 (file)
 /* Zoom2 has Qwerty keyboard*/
 static int board_keymap[] = {
        KEY(0, 0, KEY_E),
-       KEY(1, 0, KEY_R),
-       KEY(2, 0, KEY_T),
-       KEY(3, 0, KEY_HOME),
-       KEY(6, 0, KEY_I),
-       KEY(7, 0, KEY_LEFTSHIFT),
-       KEY(0, 1, KEY_D),
+       KEY(0, 1, KEY_R),
+       KEY(0, 2, KEY_T),
+       KEY(0, 3, KEY_HOME),
+       KEY(0, 6, KEY_I),
+       KEY(0, 7, KEY_LEFTSHIFT),
+       KEY(1, 0, KEY_D),
        KEY(1, 1, KEY_F),
-       KEY(2, 1, KEY_G),
-       KEY(3, 1, KEY_SEND),
-       KEY(6, 1, KEY_K),
-       KEY(7, 1, KEY_ENTER),
-       KEY(0, 2, KEY_X),
-       KEY(1, 2, KEY_C),
+       KEY(1, 2, KEY_G),
+       KEY(1, 3, KEY_SEND),
+       KEY(1, 6, KEY_K),
+       KEY(1, 7, KEY_ENTER),
+       KEY(2, 0, KEY_X),
+       KEY(2, 1, KEY_C),
        KEY(2, 2, KEY_V),
-       KEY(3, 2, KEY_END),
-       KEY(6, 2, KEY_DOT),
-       KEY(7, 2, KEY_CAPSLOCK),
-       KEY(0, 3, KEY_Z),
-       KEY(1, 3, KEY_KPPLUS),
-       KEY(2, 3, KEY_B),
+       KEY(2, 3, KEY_END),
+       KEY(2, 6, KEY_DOT),
+       KEY(2, 7, KEY_CAPSLOCK),
+       KEY(3, 0, KEY_Z),
+       KEY(3, 1, KEY_KPPLUS),
+       KEY(3, 2, KEY_B),
        KEY(3, 3, KEY_F1),
-       KEY(6, 3, KEY_O),
-       KEY(7, 3, KEY_SPACE),
-       KEY(0, 4, KEY_W),
-       KEY(1, 4, KEY_Y),
-       KEY(2, 4, KEY_U),
-       KEY(3, 4, KEY_F2),
+       KEY(3, 6, KEY_O),
+       KEY(3, 7, KEY_SPACE),
+       KEY(4, 0, KEY_W),
+       KEY(4, 1, KEY_Y),
+       KEY(4, 2, KEY_U),
+       KEY(4, 3, KEY_F2),
        KEY(4, 4, KEY_VOLUMEUP),
-       KEY(6, 4, KEY_L),
-       KEY(7, 4, KEY_LEFT),
-       KEY(0, 5, KEY_S),
-       KEY(1, 5, KEY_H),
-       KEY(2, 5, KEY_J),
-       KEY(3, 5, KEY_F3),
+       KEY(4, 6, KEY_L),
+       KEY(4, 7, KEY_LEFT),
+       KEY(5, 0, KEY_S),
+       KEY(5, 1, KEY_H),
+       KEY(5, 2, KEY_J),
+       KEY(5, 3, KEY_F3),
        KEY(5, 5, KEY_VOLUMEDOWN),
-       KEY(6, 5, KEY_M),
-       KEY(4, 5, KEY_ENTER),
-       KEY(7, 5, KEY_RIGHT),
-       KEY(0, 6, KEY_Q),
-       KEY(1, 6, KEY_A),
-       KEY(2, 6, KEY_N),
-       KEY(3, 6, KEY_BACKSPACE),
+       KEY(5, 6, KEY_M),
+       KEY(5, 7, KEY_ENTER),
+       KEY(6, 0, KEY_Q),
+       KEY(6, 1, KEY_A),
+       KEY(6, 2, KEY_N),
+       KEY(6, 3, KEY_BACKSPACE),
        KEY(6, 6, KEY_P),
-       KEY(7, 6, KEY_UP),
        KEY(6, 7, KEY_SELECT),
-       KEY(7, 7, KEY_DOWN),
-       KEY(0, 7, KEY_PROG1),   /*MACRO 1 <User defined> */
-       KEY(1, 7, KEY_PROG2),   /*MACRO 2 <User defined> */
-       KEY(2, 7, KEY_PROG3),   /*MACRO 3 <User defined> */
-       KEY(3, 7, KEY_PROG4),   /*MACRO 4 <User defined> */
-       0
+       KEY(7, 0, KEY_PROG1),   /*MACRO 1 <User defined> */
+       KEY(7, 1, KEY_PROG2),   /*MACRO 2 <User defined> */
+       KEY(7, 2, KEY_PROG3),   /*MACRO 3 <User defined> */
+       KEY(7, 3, KEY_PROG4),   /*MACRO 4 <User defined> */
+       KEY(7, 5, KEY_RIGHT),
+       KEY(7, 6, KEY_UP),
+       KEY(7, 7, KEY_DOWN)
 };
 
 static struct matrix_keymap_data board_map_data = {
index 489556eecbd1189a7a61638deec0f33d3aff59ad..7c5c00df3c70c36bb2a96b39ef015688e3599cb8 100644 (file)
@@ -473,7 +473,7 @@ static u16 _omap3_dpll_compute_freqsel(struct clk *clk, u8 n)
        unsigned long fint;
        u16 f = 0;
 
-       fint = clk->dpll_data->clk_ref->rate / (n + 1);
+       fint = clk->dpll_data->clk_ref->rate / n;
 
        pr_debug("clock: fint is %lu\n", fint);
 
index c8119781e00aff7f0be0e7965dbd14878edcb55a..9565c05bebd259d050afc597e7578294403470c7 100644 (file)
@@ -489,9 +489,9 @@ static struct clk core_ck = {
 static struct clk dpll3_m2x2_ck = {
        .name           = "dpll3_m2x2_ck",
        .ops            = &clkops_null,
-       .parent         = &dpll3_x2_ck,
+       .parent         = &dpll3_m2_ck,
        .clkdm_name     = "dpll3_clkdm",
-       .recalc         = &followparent_recalc,
+       .recalc         = &omap3_clkoutx2_recalc,
 };
 
 /* The PWRDN bit is apparently only available on 3430ES2 and above */
index f8657568b1baff51eeb6b950de4b35b6088d47c7..f3c992e29651c1c0520a28eb551717537ea82a93 100644 (file)
@@ -378,7 +378,7 @@ EXPORT_SYMBOL(gpmc_cs_request);
 void gpmc_cs_free(int cs)
 {
        spin_lock(&gpmc_mem_lock);
-       if (cs >= GPMC_CS_NUM || !gpmc_cs_reserved(cs)) {
+       if (cs >= GPMC_CS_NUM || cs < 0 || !gpmc_cs_reserved(cs)) {
                printk(KERN_ERR "Trying to free non-reserved GPMC CS%d\n", cs);
                BUG();
                spin_unlock(&gpmc_mem_lock);
index 494572825c7da49bf3a665adaf1b8574b9dbe9ef..ec0e14b96682a9b6117ff70420803d280d63a120 100644 (file)
@@ -27,6 +27,7 @@
 #include <mach/colibri.h>
 #include <mach/pxafb.h>
 #include <mach/ohci.h>
+#include <mach/audio.h>
 
 #include "generic.h"
 #include "devices.h"
@@ -145,7 +146,8 @@ static void __init colibri_pxa320_init_lcd(void)
 static inline void colibri_pxa320_init_lcd(void) {}
 #endif
 
-#if defined(SND_AC97_CODEC) || defined(SND_AC97_CODEC_MODULE)
+#if    defined(CONFIG_SND_AC97_CODEC) || \
+       defined(CONFIG_SND_AC97_CODEC_MODULE)
 static mfp_cfg_t colibri_pxa320_ac97_pin_config[] __initdata = {
        GPIO34_AC97_SYSCLK,
        GPIO35_AC97_SDATA_IN_0,
index 983cc8c2008190db5e686f65a69f2a47bd2fd5cc..9e4d9816726ad5d75c0657f9a32d0b36c0ec3aa7 100644 (file)
@@ -447,6 +447,7 @@ static __init int pxa_cpufreq_init(struct cpufreq_policy *policy)
                pxa27x_freq_table[i].frequency = freq;
                pxa27x_freq_table[i].index = i;
        }
+       pxa27x_freq_table[i].index = i;
        pxa27x_freq_table[i].frequency = CPUFREQ_TABLE_END;
 
        /*
index 67f34a8d8e60ee58c7f9257fd4812d9dd827dc34..149cdd9aee4d51d23977d769d1a3d041897f12ee 100644 (file)
@@ -102,7 +102,7 @@ static int setup_freqs_table(struct cpufreq_policy *policy,
                table[i].index = i;
                table[i].frequency = freqs[i].cpufreq_mhz * 1000;
        }
-       table[num].frequency = i;
+       table[num].index = i;
        table[num].frequency = CPUFREQ_TABLE_END;
 
        pxa3xx_freqs = freqs;
index abff9e1327492b42254a455c1f57dcbb0604df57..83bd3c6e3884594c2beac41e777220080865339c 100644 (file)
@@ -604,7 +604,7 @@ static struct platform_device gpio_vbus = {
 static const struct ads7846_platform_data tsc2046_info = {
        .model            = 7846,
        .vref_delay_usecs = 100,
-       .pressure_max     = 512,
+       .pressure_max     = 1024,
        .debounce_max     = 10,
        .debounce_tol     = 3,
        .debounce_rep     = 1,
index 241880608ac64d3293c8d1e2e190572589f7878d..a73bc86a3c263d238e2a7b7a82d297748857b9ce 100644 (file)
@@ -46,5 +46,6 @@
                beq     1001f
                bic     \irqstat, \irqstat, #0x80000000
                mov     \irqnr, \irqstat, lsr #16
+               add     \irqnr, \irqnr, #(PXA_IRQ(0))
 1001:
                .endm
index 3da45d05174398d0b2767f5efc0ab8efa0d6691d..d98023f55503881c3d7e177b1112686f0ef8b5c0 100644 (file)
@@ -802,10 +802,12 @@ static void __init spitz_init(void)
 {
        spitz_ficp_platform_data.gpio_pwdown = SPITZ_GPIO_IR_ON;
 
+#ifdef CONFIG_MACH_BORZOI
        if (machine_is_borzoi()) {
                sharpsl_nand_platform_data.badblock_pattern = &sharpsl_akita_bbt;
                sharpsl_nand_platform_data.ecc_layout = &akita_oobinfo;
        }
+#endif
 
        platform_scoop_config = &spitz_pcmcia_config;
 
index be60d6deee8b018c883cc547eae53f4e6d2b2a66..653e25be3dd82df532b4b3a508fb45e393b00876 100644 (file)
@@ -408,7 +408,7 @@ static struct platform_device keypad_device = {
 };
 
 static struct platform_device rtc_device = {
-       .name = "rtc0",
+       .name = "rtc-coh901331",
        .id = -1,
        .num_resources = ARRAY_SIZE(rtc_resources),
        .resource = rtc_resources,
index 71ebd7fcfea158afa5d0f6eb14b4d9202f79be5a..7c345b757df12d17014416116ce07a39d663c634 100644 (file)
@@ -373,7 +373,7 @@ static inline int gpio_valid(int gpio)
 
 static int check_gpio(int gpio)
 {
-       if (unlikely(gpio_valid(gpio)) < 0) {
+       if (unlikely(gpio_valid(gpio) < 0)) {
                printk(KERN_ERR "omap-gpio: invalid GPIO %d\n", gpio);
                dump_stack();
                return -1;
index 22086e696e8e38f00ea8a28f68b7e618abee6b33..857a6839071cd57a36688cd4498cda34c172d927 100644 (file)
@@ -16,7 +16,7 @@
 #ifndef __ASM_PLAT_MFP_H
 #define __ASM_PLAT_MFP_H
 
-#define mfp_to_gpio(m) ((m) % 128)
+#define mfp_to_gpio(m) ((m) % 256)
 
 /* list of all the configurable MFP pins */
 enum {
index 9405d0379c850da2b39651a30ee228fb91113685..be58f9fe65b0db082b4b1c8af428dd6cca682a39 100644 (file)
@@ -207,7 +207,7 @@ unsigned long mfp_read(int mfp)
 {
        unsigned long val, flags;
 
-       BUG_ON(mfp >= MFP_PIN_MAX);
+       BUG_ON(mfp < 0 || mfp >= MFP_PIN_MAX);
 
        spin_lock_irqsave(&mfp_spin_lock, flags);
        val = mfpr_readl(mfp_table[mfp].mfpr_off);
@@ -220,7 +220,7 @@ void mfp_write(int mfp, unsigned long val)
 {
        unsigned long flags;
 
-       BUG_ON(mfp >= MFP_PIN_MAX);
+       BUG_ON(mfp < 0 || mfp >= MFP_PIN_MAX);
 
        spin_lock_irqsave(&mfp_spin_lock, flags);
        mfpr_writel(mfp_table[mfp].mfpr_off, val);
index 94be7bb6cb9a9f345721053ea491b6353b431191..07b976da617418d32b6c0a7d2d84a4ffeb7a5ace 100644 (file)
@@ -12,7 +12,7 @@
 #
 #   http://www.arm.linux.org.uk/developer/machines/?action=new
 #
-# Last update: Fri Sep 18 21:42:00 2009
+# Last update: Wed Nov 25 22:14:58 2009
 #
 # machine_is_xxx       CONFIG_xxxx             MACH_TYPE_xxx           number
 #
@@ -928,7 +928,7 @@ palmt5                      MACH_PALMT5             PALMT5                  917
 palmtc                 MACH_PALMTC             PALMTC                  918
 omap_apollon           MACH_OMAP_APOLLON       OMAP_APOLLON            919
 mxc30030evb            MACH_MXC30030EVB        MXC30030EVB             920
-rea_2d                 MACH_REA_2D             REA_2D                  921
+rea_cpu2               MACH_REA_2D             REA_2D                  921
 eti3e524               MACH_TI3E524            TI3E524                 922
 ateb9200               MACH_ATEB9200           ATEB9200                923
 auckland               MACH_AUCKLAND           AUCKLAND                924
@@ -2421,3 +2421,118 @@ liberty                 MACH_LIBERTY            LIBERTY                 2434
 mh355                  MACH_MH355              MH355                   2435
 pc7802                 MACH_PC7802             PC7802                  2436
 gnet_sgc               MACH_GNET_SGC           GNET_SGC                2437
+einstein15             MACH_EINSTEIN15         EINSTEIN15              2438
+cmpd                   MACH_CMPD               CMPD                    2439
+davinci_hase1          MACH_DAVINCI_HASE1      DAVINCI_HASE1           2440
+lgeincitephone         MACH_LGEINCITEPHONE     LGEINCITEPHONE          2441
+ea313x                 MACH_EA313X             EA313X                  2442
+fwbd_39064             MACH_FWBD_39064         FWBD_39064              2443
+fwbd_390128            MACH_FWBD_390128        FWBD_390128             2444
+pelco_moe              MACH_PELCO_MOE          PELCO_MOE               2445
+minimix27              MACH_MINIMIX27          MINIMIX27               2446
+omap3_thunder          MACH_OMAP3_THUNDER      OMAP3_THUNDER           2447
+passionc               MACH_PASSIONC           PASSIONC                2448
+mx27amata              MACH_MX27AMATA          MX27AMATA               2449
+bgat1                  MACH_BGAT1              BGAT1                   2450
+buzz                   MACH_BUZZ               BUZZ                    2451
+mb9g20                 MACH_MB9G20             MB9G20                  2452
+yushan                 MACH_YUSHAN             YUSHAN                  2453
+lizard                 MACH_LIZARD             LIZARD                  2454
+omap3polycom           MACH_OMAP3POLYCOM       OMAP3POLYCOM            2455
+smdkv210               MACH_SMDKV210           SMDKV210                2456
+bravo                  MACH_BRAVO              BRAVO                   2457
+siogentoo1             MACH_SIOGENTOO1         SIOGENTOO1              2458
+siogentoo2             MACH_SIOGENTOO2         SIOGENTOO2              2459
+sm3k                   MACH_SM3K               SM3K                    2460
+acer_tempo_f900                MACH_ACER_TEMPO_F900    ACER_TEMPO_F900         2461
+sst61vc010_dev         MACH_SST61VC010_DEV     SST61VC010_DEV          2462
+glittertind            MACH_GLITTERTIND        GLITTERTIND             2463
+omap_zoom3             MACH_OMAP_ZOOM3         OMAP_ZOOM3              2464
+omap_3630sdp           MACH_OMAP_3630SDP       OMAP_3630SDP            2465
+cybook2440             MACH_CYBOOK2440         CYBOOK2440              2466
+torino_s               MACH_TORINO_S           TORINO_S                2467
+havana                 MACH_HAVANA             HAVANA                  2468
+beaumont_11            MACH_BEAUMONT_11        BEAUMONT_11             2469
+vanguard               MACH_VANGUARD           VANGUARD                2470
+s5pc110_draco          MACH_S5PC110_DRACO      S5PC110_DRACO           2471
+cartesio_two           MACH_CARTESIO_TWO       CARTESIO_TWO            2472
+aster                  MACH_ASTER              ASTER                   2473
+voguesv210             MACH_VOGUESV210         VOGUESV210              2474
+acm500x                        MACH_ACM500X            ACM500X                 2475
+km9260                 MACH_KM9260             KM9260                  2476
+nideflexg1             MACH_NIDEFLEXG1         NIDEFLEXG1              2477
+ctera_plug_io          MACH_CTERA_PLUG_IO      CTERA_PLUG_IO           2478
+smartq7                        MACH_SMARTQ7            SMARTQ7                 2479
+at91sam9g10ek2         MACH_AT91SAM9G10EK2     AT91SAM9G10EK2          2480
+asusp527               MACH_ASUSP527           ASUSP527                2481
+at91sam9g20mpm2                MACH_AT91SAM9G20MPM2    AT91SAM9G20MPM2         2482
+topasa900              MACH_TOPASA900          TOPASA900               2483
+electrum_100           MACH_ELECTRUM_100       ELECTRUM_100            2484
+mx51grb                        MACH_MX51GRB            MX51GRB                 2485
+xea300                 MACH_XEA300             XEA300                  2486
+htcstartrek            MACH_HTCSTARTREK        HTCSTARTREK             2487
+lima                   MACH_LIMA               LIMA                    2488
+csb740                 MACH_CSB740             CSB740                  2489
+usb_s8815              MACH_USB_S8815          USB_S8815               2490
+watson_efm_plugin      MACH_WATSON_EFM_PLUGIN  WATSON_EFM_PLUGIN       2491
+milkyway               MACH_MILKYWAY           MILKYWAY                2492
+g4evm                  MACH_G4EVM              G4EVM                   2493
+picomod6               MACH_PICOMOD6           PICOMOD6                2494
+omapl138_hawkboard     MACH_OMAPL138_HAWKBOARD OMAPL138_HAWKBOARD      2495
+ip6000                 MACH_IP6000             IP6000                  2496
+ip6010                 MACH_IP6010             IP6010                  2497
+utm400                 MACH_UTM400             UTM400                  2498
+omap3_zybex            MACH_OMAP3_ZYBEX        OMAP3_ZYBEX             2499
+wireless_space         MACH_WIRELESS_SPACE     WIRELESS_SPACE          2500
+sx560                  MACH_SX560              SX560                   2501
+ts41x                  MACH_TS41X              TS41X                   2502
+elphel10373            MACH_ELPHEL10373        ELPHEL10373             2503
+rhobot                 MACH_RHOBOT             RHOBOT                  2504
+mx51_refresh           MACH_MX51_REFRESH       MX51_REFRESH            2505
+ls9260                 MACH_LS9260             LS9260                  2506
+shank                  MACH_SHANK              SHANK                   2507
+qsd8x50_st1            MACH_QSD8X50_ST1        QSD8X50_ST1             2508
+at91sam9m10ekes                MACH_AT91SAM9M10EKES    AT91SAM9M10EKES         2509
+hiram                  MACH_HIRAM              HIRAM                   2510
+phy3250                        MACH_PHY3250            PHY3250                 2511
+ea3250                 MACH_EA3250             EA3250                  2512
+fdi3250                        MACH_FDI3250            FDI3250                 2513
+whitestone             MACH_WHITESTONE         WHITESTONE              2514
+at91sam9263nit         MACH_AT91SAM9263NIT     AT91SAM9263NIT          2515
+ccmx51                 MACH_CCMX51             CCMX51                  2516
+ccmx51js               MACH_CCMX51JS           CCMX51JS                2517
+ccwmx51                        MACH_CCWMX51            CCWMX51                 2518
+ccwmx51js              MACH_CCWMX51JS          CCWMX51JS               2519
+mini6410               MACH_MINI6410           MINI6410                2520
+tiny6410               MACH_TINY6410           TINY6410                2521
+nano6410               MACH_NANO6410           NANO6410                2522
+at572d940hfnldb                MACH_AT572D940HFNLDB    AT572D940HFNLDB         2523
+htcleo                 MACH_HTCLEO             HTCLEO                  2524
+avp13                  MACH_AVP13              AVP13                   2525
+xxsvideod              MACH_XXSVIDEOD          XXSVIDEOD               2526
+vpnext                 MACH_VPNEXT             VPNEXT                  2527
+swarco_itc3            MACH_SWARCO_ITC3        SWARCO_ITC3             2528
+tx51                   MACH_TX51               TX51                    2529
+dolby_cat1021          MACH_DOLBY_CAT1021      DOLBY_CAT1021           2530
+mx28evk                        MACH_MX28EVK            MX28EVK                 2531
+phoenix260             MACH_PHOENIX260         PHOENIX260              2532
+uvaca_stork            MACH_UVACA_STORK        UVACA_STORK             2533
+smartq5                        MACH_SMARTQ5            SMARTQ5                 2534
+all3078                        MACH_ALL3078            ALL3078                 2535
+ctera_2bay_ds          MACH_CTERA_2BAY_DS      CTERA_2BAY_DS           2536
+siogentoo3             MACH_SIOGENTOO3         SIOGENTOO3              2537
+epb5000                        MACH_EPB5000            EPB5000                 2538
+hy9263                 MACH_HY9263             HY9263                  2539
+acer_tempo_m900                MACH_ACER_TEMPO_M900    ACER_TEMPO_M900         2540
+acer_tempo_dx650       MACH_ACER_TEMPO_DX900   ACER_TEMPO_DX900        2541
+acer_tempo_x960                MACH_ACER_TEMPO_X960    ACER_TEMPO_X960         2542
+acer_eten_v900         MACH_ACER_ETEN_V900     ACER_ETEN_V900          2543
+acer_eten_x900         MACH_ACER_ETEN_X900     ACER_ETEN_X900          2544
+bonnell                        MACH_BONNELL            BONNELL                 2545
+oht_mx27               MACH_OHT_MX27           OHT_MX27                2546
+htcquartz              MACH_HTCQUARTZ          HTCQUARTZ               2547
+davinci_dm6467tevm     MACH_DAVINCI_DM6467TEVM DAVINCI_DM6467TEVM      2548
+c3ax03                 MACH_C3AX03             C3AX03                  2549
+mxt_td60               MACH_MXT_TD60           MXT_TD60                2550
+esyx                   MACH_ESYX               ESYX                    2551
+bulldog                        MACH_BULLDOG            BULLDOG                 2553
index 331d45bab18f3b13e4eaf4faa4aaf6433883f924..2aa373cc61b58e7f7c4807837a60a0c687269f27 100644 (file)
@@ -52,7 +52,7 @@
 #define BUG()                                                          \
        do {                                                            \
                _BUG_OR_WARN(0);                                        \
-               for (;;);                                               \
+               unreachable();                                          \
        } while (0)
 
 #define WARN_ON(condition)                                                     \
index 1f170216d2f9b35f475db4a7fa37d9c2064a9fe3..3946aff4f4148b6133f31429fbbe9facb40b35c0 100644 (file)
@@ -225,8 +225,13 @@ int blackfin_dma_suspend(void)
 void blackfin_dma_resume(void)
 {
        int i;
-       for (i = 0; i < MAX_DMA_SUSPEND_CHANNELS; ++i)
-               dma_ch[i].regs->peripheral_map = dma_ch[i].saved_peripheral_map;
+
+       for (i = 0; i < MAX_DMA_CHANNELS; ++i) {
+               dma_ch[i].regs->cfg = 0;
+
+               if (i < MAX_DMA_SUSPEND_CHANNELS)
+                       dma_ch[i].regs->peripheral_map = dma_ch[i].saved_peripheral_map;
+       }
 }
 #endif
 
index f7b9cdce823977a58e944999f6cbb35b1d0e0bbd..b52c1f8c4bc0e9451ab2def134dfc7e095e45185 100644 (file)
@@ -38,7 +38,7 @@ void __init generate_cplb_tables_cpu(unsigned int cpu)
 
 #ifdef CONFIG_BFIN_EXTMEM_DCACHEABLE
        d_cache = CPLB_L1_CHBL;
-#ifdef CONFIG_BFIN_EXTMEM_WRITETROUGH
+#ifdef CONFIG_BFIN_EXTMEM_WRITETHROUGH
        d_cache |= CPLB_L1_AOW | CPLB_WT;
 #endif
 #endif
index 430ae39456e8e1b5cbe9c2c5c6396ff921699722..5cc7e2e9e4156f202bd9bc10f7c58cfa72e0bdbf 100644 (file)
@@ -151,7 +151,7 @@ void start_thread(struct pt_regs *regs, unsigned long new_ip, unsigned long new_
        regs->pc = new_ip;
        if (current->mm)
                regs->p5 = current->mm->start_data;
-#ifdef CONFIG_SMP
+#ifndef CONFIG_SMP
        task_thread_info(current)->l1_task_info.stack_start =
                (void *)current->mm->context.stack_start;
        task_thread_info(current)->l1_task_info.lowest_sp = (void *)new_sp;
index 0982b5d5af100ab70f3aee3efbd780eb234175b2..56b0ba12175f2d6922068c4284fa9a0487a75acd 100644 (file)
@@ -315,7 +315,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
                        case BFIN_MEM_ACCESS_CORE:
                        case BFIN_MEM_ACCESS_CORE_ONLY:
                                copied = access_process_vm(child, addr, &data,
-                                                          to_copy, 0);
+                                                          to_copy, 1);
                                if (copied)
                                        break;
 
index e9c65390edd1852bdf4b691542e34e3687a29a95..2829dd0400f18b405953e2ff61e2996d3c4c7115 100644 (file)
@@ -1,9 +1,13 @@
 /*
- * File: include/asm-blackfin/mach-bf518/anomaly.h
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ * DO NOT EDIT THIS FILE
+ * This file is under version control at
+ *   svn://sources.blackfin.uclinux.org/toolchain/trunk/proc-defs/header-frags/
+ * and can be replaced with that version at any time
+ * DO NOT EDIT THIS FILE
  *
- * Copyright (C) 2004-2009 Analog Devices Inc.
- * Licensed under the GPL-2 or later.
+ * Copyright 2004-2009 Analog Devices Inc.
+ * Licensed under the ADI BSD license.
+ *   https://docs.blackfin.uclinux.org/doku.php?id=adi_bsd
  */
 
 /* This file should be up to date with:
 #define ANOMALY_05000461 (1)
 /* Synchronization Problem at Startup May Cause SPORT Transmit Channels to Misalign */
 #define ANOMALY_05000462 (1)
+/* Interrupted 32-Bit SPORT Data Register Access Results In Underflow */
+#define ANOMALY_05000473 (1)
+/* TESTSET Instruction Cannot Be Interrupted */
+#define ANOMALY_05000477 (1)
 
 /* Anomalies that don't exist on this proc */
 #define ANOMALY_05000099 (0)
 #define ANOMALY_05000450 (0)
 #define ANOMALY_05000465 (0)
 #define ANOMALY_05000467 (0)
+#define ANOMALY_05000474 (0)
+#define ANOMALY_05000475 (0)
 
 #endif
index 3f9052687fa8065c871d00e268c34c45f85a7f31..02040df8ec80be9ef3b08e1525b76aa22507a717 100644 (file)
@@ -1,14 +1,18 @@
 /*
- * File: include/asm-blackfin/mach-bf527/anomaly.h
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ * DO NOT EDIT THIS FILE
+ * This file is under version control at
+ *   svn://sources.blackfin.uclinux.org/toolchain/trunk/proc-defs/header-frags/
+ * and can be replaced with that version at any time
+ * DO NOT EDIT THIS FILE
  *
- * Copyright (C) 2004-2009 Analog Devices Inc.
- * Licensed under the GPL-2 or later.
+ * Copyright 2004-2009 Analog Devices Inc.
+ * Licensed under the ADI BSD license.
+ *   https://docs.blackfin.uclinux.org/doku.php?id=adi_bsd
  */
 
 /* This file should be up to date with:
  *  - Revision D, 08/14/2009; ADSP-BF526 Blackfin Processor Anomaly List
- *  - Revision F, 03/03/2009; ADSP-BF527 Blackfin Processor Anomaly List
+ *  - Revision G, 08/25/2009; ADSP-BF527 Blackfin Processor Anomaly List
  */
 
 #ifndef _MACH_ANOMALY_H_
 #define ANOMALY_05000467 (1)
 /* PLL Latches Incorrect Settings During Reset */
 #define ANOMALY_05000469 (1)
+/* Interrupted 32-Bit SPORT Data Register Access Results In Underflow */
+#define ANOMALY_05000473 (1)
+/* TESTSET Instruction Cannot Be Interrupted */
+#define ANOMALY_05000477 (1)
 
 /* Anomalies that don't exist on this proc */
 #define ANOMALY_05000099 (0)
 #define ANOMALY_05000412 (0)
 #define ANOMALY_05000447 (0)
 #define ANOMALY_05000448 (0)
+#define ANOMALY_05000474 (0)
+#define ANOMALY_05000475 (0)
 
 #endif
index cd83db2fb1a17fdc99e3cba7a7423005430afc80..9b3f7a27714d3d8964619e61626d366d6eef7a05 100644 (file)
@@ -1,9 +1,13 @@
 /*
- * File: include/asm-blackfin/mach-bf533/anomaly.h
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ * DO NOT EDIT THIS FILE
+ * This file is under version control at
+ *   svn://sources.blackfin.uclinux.org/toolchain/trunk/proc-defs/header-frags/
+ * and can be replaced with that version at any time
+ * DO NOT EDIT THIS FILE
  *
- * Copyright (C) 2004-2009 Analog Devices Inc.
- * Licensed under the GPL-2 or later.
+ * Copyright 2004-2009 Analog Devices Inc.
+ * Licensed under the ADI BSD license.
+ *   https://docs.blackfin.uclinux.org/doku.php?id=adi_bsd
  */
 
 /* This file should be up to date with:
 #define ANOMALY_05000443 (1)
 /* False Hardware Error when RETI Points to Invalid Memory */
 #define ANOMALY_05000461 (1)
+/* Interrupted 32-Bit SPORT Data Register Access Results In Underflow */
+#define ANOMALY_05000473 (1)
+/* TESTSET Instruction Cannot Be Interrupted */
+#define ANOMALY_05000477 (1)
 
 /* These anomalies have been "phased" out of analog.com anomaly sheets and are
  * here to show running on older silicon just isn't feasible.
 #define ANOMALY_05000450 (0)
 #define ANOMALY_05000465 (0)
 #define ANOMALY_05000467 (0)
+#define ANOMALY_05000474 (0)
+#define ANOMALY_05000475 (0)
 
 #endif
index f091ad2d8ea8dd23001bd598027e34aeb97b3598..d2c427bc6656e8fa0c6be3234c644d1fa8288aa6 100644 (file)
@@ -1,9 +1,13 @@
 /*
- * File: include/asm-blackfin/mach-bf537/anomaly.h
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ * DO NOT EDIT THIS FILE
+ * This file is under version control at
+ *   svn://sources.blackfin.uclinux.org/toolchain/trunk/proc-defs/header-frags/
+ * and can be replaced with that version at any time
+ * DO NOT EDIT THIS FILE
  *
- * Copyright (C) 2004-2009 Analog Devices Inc.
- * Licensed under the GPL-2 or later.
+ * Copyright 2004-2009 Analog Devices Inc.
+ * Licensed under the ADI BSD license.
+ *   https://docs.blackfin.uclinux.org/doku.php?id=adi_bsd
  */
 
 /* This file should be up to date with:
 #define ANOMALY_05000443 (1)
 /* False Hardware Error when RETI Points to Invalid Memory */
 #define ANOMALY_05000461 (1)
+/* Interrupted 32-Bit SPORT Data Register Access Results In Underflow */
+#define ANOMALY_05000473 (1)
+/* TESTSET Instruction Cannot Be Interrupted */
+#define ANOMALY_05000477 (1)
 
 /* Anomalies that don't exist on this proc */
 #define ANOMALY_05000099 (0)
 #define ANOMALY_05000450 (0)
 #define ANOMALY_05000465 (0)
 #define ANOMALY_05000467 (0)
+#define ANOMALY_05000474 (0)
+#define ANOMALY_05000475 (0)
 
 #endif
index 26b76083e14c084fb2cd48622573ffeb70566b29..d882b7e6f59bcf443e00270ef01cd7788b821aa1 100644 (file)
@@ -1,9 +1,13 @@
 /*
- * File: include/asm-blackfin/mach-bf538/anomaly.h
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ * DO NOT EDIT THIS FILE
+ * This file is under version control at
+ *   svn://sources.blackfin.uclinux.org/toolchain/trunk/proc-defs/header-frags/
+ * and can be replaced with that version at any time
+ * DO NOT EDIT THIS FILE
  *
- * Copyright (C) 2004-2009 Analog Devices Inc.
- * Licensed under the GPL-2 or later.
+ * Copyright 2004-2009 Analog Devices Inc.
+ * Licensed under the ADI BSD license.
+ *   https://docs.blackfin.uclinux.org/doku.php?id=adi_bsd
  */
 
 /* This file should be up to date with:
 #define ANOMALY_05000443 (1)
 /* False Hardware Error when RETI Points to Invalid Memory */
 #define ANOMALY_05000461 (1)
+/* Interrupted 32-Bit SPORT Data Register Access Results In Underflow */
+#define ANOMALY_05000473 (1)
+/* TESTSET Instruction Cannot Be Interrupted */
+#define ANOMALY_05000477 (1)
 
 /* Anomalies that don't exist on this proc */
 #define ANOMALY_05000099 (0)
 #define ANOMALY_05000450 (0)
 #define ANOMALY_05000465 (0)
 #define ANOMALY_05000467 (0)
+#define ANOMALY_05000474 (0)
+#define ANOMALY_05000475 (0)
 
 #endif
index 52b116ae522a57fc153515055ed7389ac784d18f..7d08c7524498a6f0e4645ba106925c7f3cf292eb 100644 (file)
@@ -1,9 +1,13 @@
 /*
- * File: include/asm-blackfin/mach-bf548/anomaly.h
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ * DO NOT EDIT THIS FILE
+ * This file is under version control at
+ *   svn://sources.blackfin.uclinux.org/toolchain/trunk/proc-defs/header-frags/
+ * and can be replaced with that version at any time
+ * DO NOT EDIT THIS FILE
  *
- * Copyright (C) 2004-2009 Analog Devices Inc.
- * Licensed under the GPL-2 or later.
+ * Copyright 2004-2009 Analog Devices Inc.
+ * Licensed under the ADI BSD license.
+ *   https://docs.blackfin.uclinux.org/doku.php?id=adi_bsd
  */
 
 /* This file should be up to date with:
@@ -24,6 +28,8 @@
 #define ANOMALY_05000119 (1)
 /* Rx.H Cannot Be Used to Access 16-bit System MMR Registers */
 #define ANOMALY_05000122 (1)
+/* Data Corruption with Cached External Memory and Non-Cached On-Chip L2 Memory */
+#define ANOMALY_05000220 (1)
 /* False Hardware Error from an Access in the Shadow of a Conditional Branch */
 #define ANOMALY_05000245 (1)
 /* Sensitivity To Noise with Slow Input Edge Rates on External SPORT TX and RX Clocks */
 #define ANOMALY_05000466 (1)
 /* Possible RX data corruption when control & data EP FIFOs are accessed via the core */
 #define ANOMALY_05000467 (1)
+/* Interrupted 32-Bit SPORT Data Register Access Results In Underflow */
+#define ANOMALY_05000473 (1)
+/* Access to DDR-SDRAM causes system hang under certain PLL/VR settings */
+#define ANOMALY_05000474 (1)
+/* Core Hang With L2/L3 Configured in Writeback Cache Mode */
+#define ANOMALY_05000475 (1)
+/* TESTSET Instruction Cannot Be Interrupted */
+#define ANOMALY_05000477 (1)
 
 /* Anomalies that don't exist on this proc */
 #define ANOMALY_05000099 (0)
 #define ANOMALY_05000198 (0)
 #define ANOMALY_05000202 (0)
 #define ANOMALY_05000215 (0)
-#define ANOMALY_05000220 (0)
 #define ANOMALY_05000227 (0)
 #define ANOMALY_05000230 (0)
 #define ANOMALY_05000231 (0)
index 0261a5e751b35189d79f5684ff227f6552145ff3..f99f174b129f694609710faf9fe653f01f76b503 100644 (file)
        \reg\().h = _corelock;
 .endm
 
+.macro safe_testset addr:req, scratch:req
+#if ANOMALY_05000477
+       cli \scratch;
+       testset (\addr);
+       sti \scratch;
+#else
+       testset (\addr);
+#endif
+.endm
+
 /*
  * r0 = address of atomic data to flush and invalidate (32bit).
  *
@@ -33,7 +43,7 @@ ENTRY(_get_core_lock)
        cli r0;
        coreslot_loadaddr p0;
 .Lretry_corelock:
-       testset (p0);
+       safe_testset p0, r2;
        if cc jump .Ldone_corelock;
        SSYNC(r2);
        jump .Lretry_corelock
@@ -56,7 +66,7 @@ ENTRY(_get_core_lock_noflush)
        cli r0;
        coreslot_loadaddr p0;
 .Lretry_corelock_noflush:
-       testset (p0);
+       safe_testset p0, r2;
        if cc jump .Ldone_corelock_noflush;
        SSYNC(r2);
        jump .Lretry_corelock_noflush
index 70da495c96652e1c407d8ecb49e5607b389cec6a..5ddc981e9937b2d11d24a4efdb17217e24b4f18a 100644 (file)
@@ -1,9 +1,13 @@
 /*
- * File: include/asm-blackfin/mach-bf561/anomaly.h
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ * DO NOT EDIT THIS FILE
+ * This file is under version control at
+ *   svn://sources.blackfin.uclinux.org/toolchain/trunk/proc-defs/header-frags/
+ * and can be replaced with that version at any time
+ * DO NOT EDIT THIS FILE
  *
- * Copyright (C) 2004-2009 Analog Devices Inc.
- * Licensed under the GPL-2 or later.
+ * Copyright 2004-2009 Analog Devices Inc.
+ * Licensed under the ADI BSD license.
+ *   https://docs.blackfin.uclinux.org/doku.php?id=adi_bsd
  */
 
 /* This file should be up to date with:
 /* Disabling Peripherals with DMA Running May Cause DMA System Instability */
 #define ANOMALY_05000278 (__SILICON_REVISION__ < 5)
 /* False Hardware Error Exception when ISR Context Is Not Restored */
-#define ANOMALY_05000281 (__SILICON_REVISION__ < 5)
+/* Temporarily walk around for bug 5423 till this issue is confirmed by
+ * official anomaly document. It looks 05000281 still exists on bf561
+ * v0.5.
+ */
+#define ANOMALY_05000281 (__SILICON_REVISION__ <= 5)
 /* System MMR Write Is Stalled Indefinitely when Killed in a Particular Stage */
 #define ANOMALY_05000283 (1)
 /* Reads Will Receive Incorrect Data under Certain Conditions */
 #define ANOMALY_05000443 (1)
 /* False Hardware Error when RETI Points to Invalid Memory */
 #define ANOMALY_05000461 (1)
+/* Interrupted 32-Bit SPORT Data Register Access Results In Underflow */
+#define ANOMALY_05000473 (1)
+/* Core Hang With L2/L3 Configured in Writeback Cache Mode */
+#define ANOMALY_05000475 (__SILICON_REVISION__ < 4)
+/* TESTSET Instruction Cannot Be Interrupted */
+#define ANOMALY_05000477 (1)
 
 /* Anomalies that don't exist on this proc */
 #define ANOMALY_05000119 (0)
 #define ANOMALY_05000450 (0)
 #define ANOMALY_05000465 (0)
 #define ANOMALY_05000467 (0)
+#define ANOMALY_05000474 (0)
 
 #endif
index 9dbafcdcf4791e3ba7eb8522cf1b6de911c05b0a..f2ca211a76a09a4497b0b18714cac2df2e0fb8a5 100644 (file)
@@ -57,3 +57,8 @@
         (!defined(CONFIG_BFIN_EXTMEM_DCACHEABLE) && defined(CONFIG_BFIN_L2_WRITEBACK)))
 # error You are exposing Anomaly 220 in this config, either config L2 as Write Through, or make External Memory WB.
 #endif
+
+#if ANOMALY_05000475 && \
+       (defined(CONFIG_BFIN_EXTMEM_WRITEBACK) || defined(CONFIG_BFIN_L2_WRITEBACK))
+# error "Anomaly 475 does not allow you to use Write Back cache with L2 or External Memory"
+#endif
index d98585f3237d5114f9d054e386c64898a13ce08a..d92b168c83281cdd89326875e80ca75afe890c80 100644 (file)
@@ -276,10 +276,9 @@ void smp_send_reschedule(int cpu)
        if (cpu_is_offline(cpu))
                return;
 
-       msg = kmalloc(sizeof(*msg), GFP_ATOMIC);
+       msg = kzalloc(sizeof(*msg), GFP_ATOMIC);
        if (!msg)
                return;
-       memset(msg, 0, sizeof(msg));
        INIT_LIST_HEAD(&msg->list);
        msg->type = BFIN_IPI_RESCHEDULE;
 
@@ -305,10 +304,9 @@ void smp_send_stop(void)
        if (cpus_empty(callmap))
                return;
 
-       msg = kmalloc(sizeof(*msg), GFP_ATOMIC);
+       msg = kzalloc(sizeof(*msg), GFP_ATOMIC);
        if (!msg)
                return;
-       memset(msg, 0, sizeof(msg));
        INIT_LIST_HEAD(&msg->list);
        msg->type = BFIN_IPI_CPU_STOP;
 
index dcbaea7ce12868436a39d4f2bd31a406a6d3a704..f0acde68aaea5c3dd685b853f542647393bbbd6b 100644 (file)
@@ -4,8 +4,6 @@
 #include <linux/dma-mapping.h>
 #include <linux/swiotlb.h>
 
-extern int swiotlb_force;
-
 #ifdef CONFIG_SWIOTLB
 extern int swiotlb;
 extern void pci_swiotlb_init(void);
index 285aae8431c6278d08c6ff862a18fdf66b2e52bf..53292abf846c453b45c2f3e3afcd57ca0e9a6308 100644 (file)
@@ -41,7 +41,7 @@ struct dma_map_ops swiotlb_dma_ops = {
 void __init swiotlb_dma_init(void)
 {
        dma_ops = &swiotlb_dma_ops;
-       swiotlb_init();
+       swiotlb_init(1);
 }
 
 void __init pci_swiotlb_init(void)
@@ -51,7 +51,7 @@ void __init pci_swiotlb_init(void)
                swiotlb = 1;
                printk(KERN_INFO "PCI-DMA: Re-initialize machine vector.\n");
                machvec_init("dig");
-               swiotlb_init();
+               swiotlb_init(1);
                dma_ops = &swiotlb_dma_ops;
 #else
                panic("Unable to find Intel IOMMU");
index 03bd56a2fb6e5f02a265111ecbc84bf161d13f41..fd7620f025fab0ab25bcd9bca3e3dbf00b78161d 100644 (file)
@@ -1,6 +1,7 @@
 config MIPS
        bool
        default y
+       select HAVE_GENERIC_DMA_COHERENT
        select HAVE_IDE
        select HAVE_OPROFILE
        select HAVE_ARCH_KGDB
@@ -357,7 +358,14 @@ config SGI_IP22
        select SWAP_IO_SPACE
        select SYS_HAS_CPU_R4X00
        select SYS_HAS_CPU_R5000
-       select SYS_HAS_EARLY_PRINTK
+       #
+       # Disable EARLY_PRINTK for now since it leads to overwritten prom
+       # memory during early boot on some machines.
+       #
+       # See http://www.linux-mips.org/cgi-bin/mesg.cgi?a=linux-mips&i=20091119164009.GA15038%40deprecation.cyrius.com
+       # for a more details discussion
+       #
+       # select SYS_HAS_EARLY_PRINTK
        select SYS_SUPPORTS_32BIT_KERNEL
        select SYS_SUPPORTS_64BIT_KERNEL
        select SYS_SUPPORTS_BIG_ENDIAN
@@ -409,7 +417,14 @@ config SGI_IP28
        select SGI_HAS_ZILOG
        select SWAP_IO_SPACE
        select SYS_HAS_CPU_R10000
-       select SYS_HAS_EARLY_PRINTK
+       #
+       # Disable EARLY_PRINTK for now since it leads to overwritten prom
+       # memory during early boot on some machines.
+       #
+       # See http://www.linux-mips.org/cgi-bin/mesg.cgi?a=linux-mips&i=20091119164009.GA15038%40deprecation.cyrius.com
+       # for a more details discussion
+       #
+       # select SYS_HAS_EARLY_PRINTK
        select SYS_SUPPORTS_64BIT_KERNEL
        select SYS_SUPPORTS_BIG_ENDIAN
       help
@@ -1438,6 +1453,7 @@ choice
 
 config PAGE_SIZE_4KB
        bool "4kB"
+       depends on !CPU_LOONGSON2
        help
         This option select the standard 4kB Linux page size.  On some
         R3000-family processors this is the only available page size.  Using
@@ -1762,7 +1778,7 @@ config SYS_SUPPORTS_SMARTMIPS
 
 config ARCH_FLATMEM_ENABLE
        def_bool y
-       depends on !NUMA
+       depends on !NUMA && !CPU_LOONGSON2
 
 config ARCH_DISCONTIGMEM_ENABLE
        bool
index 079e33d527834803e85efec766411ab76f0b2653..fb284c3b2cff4082626f425f54a700798b9f2da5 100644 (file)
@@ -100,7 +100,7 @@ static __init void prom_init_console(void)
 
 static __init void prom_init_cmdline(void)
 {
-       char buf[CL_SIZE];
+       static char buf[CL_SIZE] __initdata;
 
        /* Get the kernel command line from CFE */
        if (cfe_getenv("LINUX_CMDLINE", buf, CL_SIZE) >= 0) {
index c69813b8488cd6fc52d50d9b569db508a40254e7..6c6a19aebe1fa21338df29e7d6566b3e0adaea23 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc7
-# Wed Mar  4 23:08:06 2009
+# Linux kernel version: 2.6.32-rc6
+# Sun Nov  8 22:59:47 2009
 #
 CONFIG_MIPS=y
 
@@ -9,16 +9,18 @@ CONFIG_MIPS=y
 # Machine selection
 #
 # CONFIG_MACH_ALCHEMY is not set
+# CONFIG_AR7 is not set
 # CONFIG_BASLER_EXCITE is not set
 # CONFIG_BCM47XX is not set
+# CONFIG_BCM63XX is not set
 # CONFIG_MIPS_COBALT is not set
 # CONFIG_MACH_DECSTATION is not set
 # CONFIG_MACH_JAZZ is not set
 # CONFIG_LASAT is not set
-# CONFIG_LEMOTE_FULONG is not set
+# CONFIG_MACH_LOONGSON is not set
 # CONFIG_MIPS_MALTA is not set
 # CONFIG_MIPS_SIM is not set
-# CONFIG_MACH_EMMA is not set
+# CONFIG_NEC_MARKEINS is not set
 # CONFIG_MACH_VR41XX is not set
 # CONFIG_NXP_STB220 is not set
 # CONFIG_NXP_STB225 is not set
@@ -45,6 +47,7 @@ CONFIG_MACH_TX49XX=y
 # CONFIG_WR_PPMC is not set
 # CONFIG_CAVIUM_OCTEON_SIMULATOR is not set
 # CONFIG_CAVIUM_OCTEON_REFERENCE_BOARD is not set
+# CONFIG_ALCHEMY_GPIO_INDIRECT is not set
 CONFIG_MACH_TXX9=y
 CONFIG_TOSHIBA_RBTX4927=y
 CONFIG_TOSHIBA_RBTX4938=y
@@ -86,7 +89,6 @@ CONFIG_DMA_NONCOHERENT=y
 CONFIG_DMA_NEED_PCI_MAP_STATE=y
 CONFIG_EARLY_PRINTK=y
 CONFIG_SYS_HAS_EARLY_PRINTK=y
-# CONFIG_HOTPLUG_CPU is not set
 # CONFIG_NO_IOPORT is not set
 CONFIG_GENERIC_GPIO=y
 CONFIG_CPU_BIG_ENDIAN=y
@@ -101,7 +103,7 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
 #
 # CPU selection
 #
-# CONFIG_CPU_LOONGSON2 is not set
+# CONFIG_CPU_LOONGSON2E is not set
 # CONFIG_CPU_MIPS32_R1 is not set
 # CONFIG_CPU_MIPS32_R2 is not set
 # CONFIG_CPU_MIPS64_R1 is not set
@@ -137,6 +139,7 @@ CONFIG_32BIT=y
 CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_8KB is not set
 # CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_32KB is not set
 # CONFIG_PAGE_SIZE_64KB is not set
 CONFIG_CPU_HAS_PREFETCH=y
 CONFIG_MIPS_MT_DISABLED=y
@@ -154,7 +157,10 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
 # CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=0
 CONFIG_VIRT_TO_BUS=y
-CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
 CONFIG_TICK_ONESHOT=y
 CONFIG_NO_HZ=y
 CONFIG_HIGH_RES_TIMERS=y
@@ -175,6 +181,7 @@ CONFIG_PREEMPT_NONE=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_STACKTRACE_SUPPORT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
 
 #
 # General setup
@@ -194,11 +201,12 @@ CONFIG_SYSVIPC_SYSCTL=y
 #
 # RCU Subsystem
 #
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
 # CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
@@ -209,8 +217,12 @@ CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
@@ -220,25 +232,35 @@ CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
 # CONFIG_PCSPKR_PLATFORM is not set
-CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
-# CONFIG_FUTEX is not set
-CONFIG_ANON_INODES=y
+CONFIG_FUTEX=y
 # CONFIG_EPOLL is not set
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_AIO=y
+
+#
+# Kernel Performance Events And Counters
+#
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_PCI_QUIRKS=y
+CONFIG_COMPAT_BRK=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
 # CONFIG_PROFILING is not set
 CONFIG_HAVE_OPROFILE=y
-# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
 CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
 CONFIG_BASE_SMALL=0
 CONFIG_MODULES=y
 # CONFIG_MODULE_FORCE_LOAD is not set
@@ -246,8 +268,8 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_BLOCK=y
-# CONFIG_LBD is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LBDAF is not set
+# CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
 #
@@ -274,6 +296,7 @@ CONFIG_PCI_DOMAINS=y
 # CONFIG_ARCH_SUPPORTS_MSI is not set
 # CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
 CONFIG_MMU=y
 
 #
@@ -288,6 +311,7 @@ CONFIG_TRAD_SIGNALS=y
 #
 # Power management options
 #
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
 # CONFIG_PM is not set
 CONFIG_NET=y
@@ -295,7 +319,6 @@ CONFIG_NET=y
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -311,6 +334,7 @@ CONFIG_IP_PNP=y
 # CONFIG_NET_IPIP is not set
 # CONFIG_NET_IPGRE is not set
 # CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
 # CONFIG_SYN_COOKIES is not set
 # CONFIG_INET_AH is not set
 # CONFIG_INET_ESP is not set
@@ -336,6 +360,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_LLC2 is not set
 # CONFIG_IPX is not set
 # CONFIG_ATALK is not set
+# CONFIG_PHONET is not set
 # CONFIG_NET_SCHED is not set
 # CONFIG_DCB is not set
 
@@ -347,7 +372,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_CAN is not set
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
-# CONFIG_PHONET is not set
 # CONFIG_WIRELESS is not set
 # CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
@@ -365,9 +389,9 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 # CONFIG_CONNECTOR is not set
 CONFIG_MTD=y
 # CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_CONCAT is not set
 CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_TESTS is not set
 # CONFIG_MTD_REDBOOT_PARTS is not set
 CONFIG_MTD_CMDLINE_PARTS=y
 # CONFIG_MTD_AR7_PARTS is not set
@@ -376,9 +400,9 @@ CONFIG_MTD_CMDLINE_PARTS=y
 # User Modules And Translation Layers
 #
 CONFIG_MTD_CHAR=y
-# CONFIG_MTD_BLKDEVS is not set
-# CONFIG_MTD_BLOCK is not set
-# CONFIG_MTD_BLOCK_RO is not set
+CONFIG_MTD_BLKDEVS=m
+CONFIG_MTD_BLOCK=m
+CONFIG_MTD_BLOCK_RO=m
 # CONFIG_FTL is not set
 # CONFIG_NFTL is not set
 # CONFIG_INFTL is not set
@@ -414,16 +438,20 @@ CONFIG_MTD_CFI_UTIL=y
 #
 # Mapping drivers for chip access
 #
-# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+CONFIG_MTD_COMPLEX_MAPPINGS=y
 CONFIG_MTD_PHYSMAP=y
 # CONFIG_MTD_PHYSMAP_COMPAT is not set
+# CONFIG_MTD_PCI is not set
+# CONFIG_MTD_GPIO_ADDR is not set
 # CONFIG_MTD_INTEL_VR_NOR is not set
+CONFIG_MTD_RBTX4939=y
 # CONFIG_MTD_PLATRAM is not set
 
 #
 # Self-contained MTD device drivers
 #
 # CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SST25L is not set
 # CONFIG_MTD_SLRAM is not set
 # CONFIG_MTD_PHRAM is not set
 # CONFIG_MTD_MTDRAM is not set
@@ -435,7 +463,15 @@ CONFIG_MTD_PHYSMAP=y
 # CONFIG_MTD_DOC2000 is not set
 # CONFIG_MTD_DOC2001 is not set
 # CONFIG_MTD_DOC2001PLUS is not set
-# CONFIG_MTD_NAND is not set
+CONFIG_MTD_NAND=m
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_NAND_ECC_SMC is not set
+# CONFIG_MTD_NAND_MUSEUM_IDS is not set
+CONFIG_MTD_NAND_IDS=m
+# CONFIG_MTD_NAND_CAFE is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+CONFIG_MTD_NAND_TXX9NDFMC=m
 # CONFIG_MTD_ONENAND is not set
 
 #
@@ -471,6 +507,7 @@ CONFIG_IDE=y
 #
 # Please see Documentation/ide/ide.txt for help/info on IDE drives
 #
+CONFIG_IDE_XFER_MODE=y
 CONFIG_IDE_TIMINGS=y
 # CONFIG_BLK_DEV_IDE_SATA is not set
 CONFIG_IDE_GD=y
@@ -534,8 +571,13 @@ CONFIG_BLK_DEV_IDEDMA=y
 #
 
 #
-# A new alternative FireWire stack is available with EXPERIMENTAL=y
+# You can enable one or both FireWire driver stacks.
 #
+
+#
+# See the help texts for more information.
+#
+# CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
 # CONFIG_I2O is not set
 CONFIG_NETDEVICES=y
@@ -574,6 +616,8 @@ CONFIG_MII=y
 # CONFIG_NET_VENDOR_3COM is not set
 CONFIG_SMC91X=y
 # CONFIG_DM9000 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_DNET is not set
 # CONFIG_NET_TULIP is not set
 # CONFIG_HP100 is not set
 CONFIG_NE2000=y
@@ -602,18 +646,15 @@ CONFIG_TC35815=y
 # CONFIG_SMSC9420 is not set
 # CONFIG_SUNDANCE is not set
 # CONFIG_TLAN is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851 is not set
+# CONFIG_KS8851_MLL is not set
 # CONFIG_VIA_RHINE is not set
 # CONFIG_ATL2 is not set
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
 # CONFIG_TR is not set
-
-#
-# Wireless LAN
-#
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
+# CONFIG_WLAN is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -653,6 +694,7 @@ CONFIG_DEVKMEM=y
 #
 # Non-8250 serial port support
 #
+# CONFIG_SERIAL_MAX3100 is not set
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_SERIAL_TXX9=y
@@ -666,7 +708,9 @@ CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_IPMI_HANDLER is not set
-# CONFIG_HW_RANDOM is not set
+CONFIG_HW_RANDOM=m
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
+CONFIG_HW_RANDOM_TX4939=m
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
 # CONFIG_RAW_DRIVER is not set
@@ -686,6 +730,10 @@ CONFIG_SPI_TXX9=y
 # SPI Protocol Masters
 #
 # CONFIG_SPI_TLE62X0 is not set
+
+#
+# PPS support
+#
 CONFIG_ARCH_REQUIRE_GPIOLIB=y
 CONFIG_GPIOLIB=y
 
@@ -701,17 +749,22 @@ CONFIG_GPIOLIB=y
 # PCI GPIO expanders:
 #
 # CONFIG_GPIO_BT8XX is not set
+# CONFIG_GPIO_LANGWELL is not set
 
 #
 # SPI GPIO expanders:
 #
 # CONFIG_GPIO_MAX7301 is not set
 # CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_GPIO_MC33880 is not set
+
+#
+# AC97 GPIO expanders:
+#
 # CONFIG_W1 is not set
 # CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
 # CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
 CONFIG_WATCHDOG=y
 # CONFIG_WATCHDOG_NOWAYOUT is not set
 
@@ -740,28 +793,17 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_UCB1400_CORE is not set
 # CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_MC13783 is not set
+# CONFIG_EZX_PCAP is not set
 # CONFIG_REGULATOR is not set
-
-#
-# Multimedia devices
-#
-
-#
-# Multimedia core support
-#
-# CONFIG_VIDEO_DEV is not set
-# CONFIG_DVB_CORE is not set
-# CONFIG_VIDEO_MEDIA is not set
-
-#
-# Multimedia drivers
-#
-# CONFIG_DAB is not set
+# CONFIG_MEDIA_SUPPORT is not set
 
 #
 # Graphics support
 #
+# CONFIG_VGA_ARB is not set
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 # CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -772,7 +814,42 @@ CONFIG_SSB_POSSIBLE=y
 # Display device support
 #
 # CONFIG_DISPLAY_SUPPORT is not set
-# CONFIG_SOUND is not set
+CONFIG_SOUND=m
+# CONFIG_SOUND_OSS_CORE is not set
+CONFIG_SND=m
+CONFIG_SND_TIMER=m
+CONFIG_SND_PCM=m
+# CONFIG_SND_SEQUENCER is not set
+# CONFIG_SND_MIXER_OSS is not set
+# CONFIG_SND_PCM_OSS is not set
+# CONFIG_SND_HRTIMER is not set
+# CONFIG_SND_DYNAMIC_MINORS is not set
+# CONFIG_SND_SUPPORT_OLD_API is not set
+# CONFIG_SND_VERBOSE_PROCFS is not set
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+CONFIG_SND_VMASTER=y
+# CONFIG_SND_RAWMIDI_SEQ is not set
+# CONFIG_SND_OPL3_LIB_SEQ is not set
+# CONFIG_SND_OPL4_LIB_SEQ is not set
+# CONFIG_SND_SBAWE_SEQ is not set
+# CONFIG_SND_EMU10K1_SEQ is not set
+CONFIG_SND_AC97_CODEC=m
+# CONFIG_SND_DRIVERS is not set
+# CONFIG_SND_PCI is not set
+# CONFIG_SND_SPI is not set
+# CONFIG_SND_MIPS is not set
+CONFIG_SND_SOC=m
+CONFIG_SND_SOC_AC97_BUS=y
+CONFIG_SND_SOC_TXX9ACLC=m
+CONFIG_HAS_TXX9_ACLC=y
+CONFIG_SND_SOC_TXX9ACLC_AC97=m
+CONFIG_SND_SOC_TXX9ACLC_GENERIC=m
+CONFIG_SND_SOC_I2C_AND_SPI=m
+# CONFIG_SND_SOC_ALL_CODECS is not set
+CONFIG_SND_SOC_AC97_CODEC=m
+# CONFIG_SOUND_PRIME is not set
+CONFIG_AC97_BUS=m
 # CONFIG_USB_SUPPORT is not set
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
@@ -783,6 +860,8 @@ CONFIG_LEDS_CLASS=y
 # LED drivers
 #
 CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_GPIO_PLATFORM=y
+# CONFIG_LEDS_DAC124S085 is not set
 
 #
 # LED Triggers
@@ -792,7 +871,12 @@ CONFIG_LEDS_TRIGGERS=y
 CONFIG_LEDS_TRIGGER_IDE_DISK=y
 CONFIG_LEDS_TRIGGER_HEARTBEAT=y
 # CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
+# CONFIG_LEDS_TRIGGER_GPIO is not set
 # CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set
+
+#
+# iptables trigger is under Netfilter config (LED target)
+#
 # CONFIG_ACCESSIBILITY is not set
 # CONFIG_INFINIBAND is not set
 CONFIG_RTC_LIB=y
@@ -820,6 +904,7 @@ CONFIG_RTC_INTF_DEV_UIE_EMUL=y
 # CONFIG_RTC_DRV_R9701 is not set
 CONFIG_RTC_DRV_RS5C348=y
 # CONFIG_RTC_DRV_DS3234 is not set
+# CONFIG_RTC_DRV_PCF2123 is not set
 
 #
 # Platform RTC drivers
@@ -840,8 +925,26 @@ CONFIG_RTC_DRV_DS1742=y
 # on-CPU RTC drivers
 #
 CONFIG_RTC_DRV_TX4939=y
-# CONFIG_DMADEVICES is not set
+CONFIG_DMADEVICES=y
+
+#
+# DMA Devices
+#
+CONFIG_TXX9_DMAC=m
+CONFIG_DMA_ENGINE=y
+
+#
+# DMA Clients
+#
+# CONFIG_NET_DMA is not set
+# CONFIG_ASYNC_TX_DMA is not set
+# CONFIG_DMATEST is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
 # CONFIG_STAGING is not set
 
 #
@@ -853,9 +956,10 @@ CONFIG_RTC_DRV_TX4939=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 CONFIG_FS_POSIX_ACL=y
-CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_OCFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
 # CONFIG_DNOTIFY is not set
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -865,6 +969,10 @@ CONFIG_INOTIFY_USER=y
 # CONFIG_FUSE_FS is not set
 CONFIG_GENERIC_ACL=y
 
+#
+# Caches
+#
+
 #
 # CD-ROM/DVD Filesystems
 #
@@ -890,7 +998,27 @@ CONFIG_TMPFS=y
 CONFIG_TMPFS_POSIX_ACL=y
 # CONFIG_HUGETLB_PAGE is not set
 # CONFIG_CONFIGFS_FS is not set
-# CONFIG_MISC_FILESYSTEMS is not set
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_HFSPLUS_FS is not set
+CONFIG_JFFS2_FS=m
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+# CONFIG_JFFS2_LZO is not set
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
 CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
@@ -922,6 +1050,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
 CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_FRAME_WARN=1024
 # CONFIG_MAGIC_SYSRQ is not set
+CONFIG_STRIP_ASM_SYMS=y
 # CONFIG_UNUSED_SYMBOLS is not set
 CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
@@ -929,11 +1058,9 @@ CONFIG_DEBUG_FS=y
 # CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
-
-#
-# Tracers
-#
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_DYNAMIC_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 CONFIG_CMDLINE=""
@@ -946,6 +1073,7 @@ CONFIG_CMDLINE=""
 # CONFIG_SECURITYFS is not set
 # CONFIG_SECURITY_FILE_CAPABILITIES is not set
 # CONFIG_CRYPTO is not set
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
@@ -959,6 +1087,10 @@ CONFIG_GENERIC_FIND_LAST_BIT=y
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=m
+CONFIG_DECOMPRESS_GZIP=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
index 6cf29c26e873788a78221ab517dc97cc6ae5386c..540c98a810d1bce2639e65f09610651ee3fb8aff 100644 (file)
@@ -11,9 +11,7 @@
 static inline void __noreturn BUG(void)
 {
        __asm__ __volatile__("break %0" : : "i" (BRK_BUG));
-       /* Fool GCC into thinking the function doesn't return. */
-       while (1)
-               ;
+       unreachable();
 }
 
 #define HAVE_ARCH_BUG
index d16afddb09a9ff23bc461d99e34f0657e56a58af..664ba53dc32a79fed9b7ed433e88a8b3a56e5d45 100644 (file)
@@ -3,6 +3,7 @@
 
 #include <asm/scatterlist.h>
 #include <asm/cache.h>
+#include <asm-generic/dma-coherent.h>
 
 void *dma_alloc_noncoherent(struct device *dev, size_t size,
                           dma_addr_t *dma_handle, gfp_t flag);
@@ -73,14 +74,4 @@ extern int dma_is_consistent(struct device *dev, dma_addr_t dma_addr);
 extern void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
               enum dma_data_direction direction);
 
-#if 0
-#define ARCH_HAS_DMA_DECLARE_COHERENT_MEMORY
-
-extern int dma_declare_coherent_memory(struct device *dev, dma_addr_t bus_addr,
-       dma_addr_t device_addr, size_t size, int flags);
-extern void dma_release_declared_memory(struct device *dev);
-extern void * dma_mark_declared_memory_occupied(struct device *dev,
-       dma_addr_t device_addr, size_t size);
-#endif
-
 #endif /* _ASM_DMA_MAPPING_H */
index a2250f390a292626e9fde6db8ab3edee41e9ea18..c892bfb3e2c1d74eca5a902194e71b46f3e87635 100644 (file)
@@ -75,6 +75,7 @@
 
 #define MADV_MERGEABLE   12            /* KSM may merge identical pages */
 #define MADV_UNMERGEABLE 13            /* KSM may not merge identical pages */
+#define MADV_HWPOISON    100           /* poison a page for testing */
 
 /* compatibility flags */
 #define MAP_FILE       0
index fcf5f98d90ccf6227906449d24b2cfb016a6e1ae..83b5509e09e8cf99a6bd966ee991ce0234806566 100644 (file)
@@ -12,6 +12,7 @@
 #ifndef _ASM_SYSTEM_H
 #define _ASM_SYSTEM_H
 
+#include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/irqflags.h>
 
@@ -193,10 +194,6 @@ extern __u64 __xchg_u64_unsupported_on_32bit_kernels(volatile __u64 * m, __u64 v
 #define __xchg_u64 __xchg_u64_unsupported_on_32bit_kernels
 #endif
 
-/* This function doesn't exist, so you'll get a linker error
-   if something tries to do an invalid xchg().  */
-extern void __xchg_called_with_bad_pointer(void);
-
 static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size)
 {
        switch (size) {
@@ -205,11 +202,17 @@ static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int siz
        case 8:
                return __xchg_u64(ptr, x);
        }
-       __xchg_called_with_bad_pointer();
+
        return x;
 }
 
-#define xchg(ptr, x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x), (ptr), sizeof(*(ptr))))
+#define xchg(ptr, x)                                                   \
+({                                                                     \
+       BUILD_BUG_ON(sizeof(*(ptr)) & ~0xc);                            \
+                                                                       \
+       ((__typeof__(*(ptr)))                                           \
+               __xchg((unsigned long)(x), (ptr), sizeof(*(ptr))));     \
+})
 
 extern void set_handler(unsigned long offset, void *addr, unsigned long len);
 extern void set_uncached_handler(unsigned long offset, void *addr, unsigned long len);
index 98bd7de7577811e13c4a04379025f8c6e026a24d..b102e4f1630eaa8e021b4c61b0b959f646f2bb81 100644 (file)
@@ -173,11 +173,12 @@ void smtc_distribute_timer(int vpe)
        unsigned int mtflags;
        int cpu;
        struct clock_event_device *cd;
-       unsigned long nextstamp = 0L;
+       unsigned long nextstamp;
        unsigned long reference;
 
 
 repeat:
+       nextstamp = 0L;
        for_each_online_cpu(cpu) {
            /*
             * Find virtual CPUs within the current VPE who have
index 3fe1fcfa2e7301825427c8f44faf80efc2969ed2..fe0d7980560368056e187dcc9f852b3218a08951 100644 (file)
@@ -306,6 +306,7 @@ static inline int mips_atomic_set(struct pt_regs *regs,
 
        if (cpu_has_llsc && R10000_LLSC_WAR) {
                __asm__ __volatile__ (
+               "       .set    mips3                                   \n"
                "       li      %[err], 0                               \n"
                "1:     ll      %[old], (%[addr])                       \n"
                "       move    %[tmp], %[new]                          \n"
@@ -320,6 +321,7 @@ static inline int mips_atomic_set(struct pt_regs *regs,
                "       "STR(PTR)"      1b, 4b                          \n"
                "       "STR(PTR)"      2b, 4b                          \n"
                "       .previous                                       \n"
+               "       .set    mips0                                   \n"
                : [old] "=&r" (old),
                  [err] "=&r" (err),
                  [tmp] "=&r" (tmp)
@@ -329,6 +331,7 @@ static inline int mips_atomic_set(struct pt_regs *regs,
                : "memory");
        } else if (cpu_has_llsc) {
                __asm__ __volatile__ (
+               "       .set    mips3                                   \n"
                "       li      %[err], 0                               \n"
                "1:     ll      %[old], (%[addr])                       \n"
                "       move    %[tmp], %[new]                          \n"
@@ -347,6 +350,7 @@ static inline int mips_atomic_set(struct pt_regs *regs,
                "       "STR(PTR)"      1b, 5b                          \n"
                "       "STR(PTR)"      2b, 5b                          \n"
                "       .previous                                       \n"
+               "       .set    mips0                                   \n"
                : [old] "=&r" (old),
                  [err] "=&r" (err),
                  [tmp] "=&r" (tmp)
index 890f77927d628b0c203c92c7712415a9c52a819f..454b53924490c58ed383f047f84f68e8be117afe 100644 (file)
@@ -163,33 +163,34 @@ static int isBranchInstr(mips_instruction * i)
 
 /*
  * In the Linux kernel, we support selection of FPR format on the
- * basis of the Status.FR bit.  This does imply that, if a full 32
- * FPRs are desired, there needs to be a flip-flop that can be written
- * to one at that bit position.  In any case, O32 MIPS ABI uses
- * only the even FPRs (Status.FR = 0).
+ * basis of the Status.FR bit.  If an FPU is not present, the FR bit
+ * is hardwired to zero, which would imply a 32-bit FPU even for
+ * 64-bit CPUs.  For 64-bit kernels with no FPU we use TIF_32BIT_REGS
+ * as a proxy for the FR bit so that a 64-bit FPU is emulated.  In any
+ * case, for a 32-bit kernel which uses the O32 MIPS ABI, only the
+ * even FPRs are used (Status.FR = 0).
  */
-
-#define CP0_STATUS_FR_SUPPORT
-
-#ifdef CP0_STATUS_FR_SUPPORT
-#define FR_BIT ST0_FR
+static inline int cop1_64bit(struct pt_regs *xcp)
+{
+       if (cpu_has_fpu)
+               return xcp->cp0_status & ST0_FR;
+#ifdef CONFIG_64BIT
+       return !test_thread_flag(TIF_32BIT_REGS);
 #else
-#define FR_BIT 0
+       return 0;
 #endif
+}
+
+#define SIFROMREG(si, x) ((si) = cop1_64bit(xcp) || !(x & 1) ? \
+                       (int)ctx->fpr[x] : (int)(ctx->fpr[x & ~1] >> 32))
 
-#define SIFROMREG(si, x) ((si) = \
-                       (xcp->cp0_status & FR_BIT) || !(x & 1) ? \
-                       (int)ctx->fpr[x] : \
-                       (int)(ctx->fpr[x & ~1] >> 32 ))
-#define SITOREG(si, x) (ctx->fpr[x & ~((xcp->cp0_status & FR_BIT) == 0)] = \
-                       (xcp->cp0_status & FR_BIT) || !(x & 1) ? \
+#define SITOREG(si, x) (ctx->fpr[x & ~(cop1_64bit(xcp) == 0)] = \
+                       cop1_64bit(xcp) || !(x & 1) ? \
                        ctx->fpr[x & ~1] >> 32 << 32 | (u32)(si) : \
                        ctx->fpr[x & ~1] << 32 >> 32 | (u64)(si) << 32)
 
-#define DIFROMREG(di, x) ((di) = \
-                       ctx->fpr[x & ~((xcp->cp0_status & FR_BIT) == 0)])
-#define DITOREG(di, x) (ctx->fpr[x & ~((xcp->cp0_status & FR_BIT) == 0)] \
-                       = (di))
+#define DIFROMREG(di, x) ((di) = ctx->fpr[x & ~(cop1_64bit(xcp) == 0)])
+#define DITOREG(di, x) (ctx->fpr[x & ~(cop1_64bit(xcp) == 0)] = (di))
 
 #define SPFROMREG(sp, x) SIFROMREG((sp).bits, x)
 #define SPTOREG(sp, x) SITOREG((sp).bits, x)
index 7e48e76148aa73aea2de549fb3e9439d16fb6f82..9367e33fbd1822d92f55302a38fb872982e2fb7d 100644 (file)
@@ -90,6 +90,9 @@ void *dma_alloc_coherent(struct device *dev, size_t size,
 {
        void *ret;
 
+       if (dma_alloc_from_coherent(dev, size, dma_handle, &ret))
+               return ret;
+
        gfp = massage_gfp_flags(dev, gfp);
 
        ret = (void *) __get_free_pages(gfp, get_order(size));
@@ -122,6 +125,10 @@ void dma_free_coherent(struct device *dev, size_t size, void *vaddr,
        dma_addr_t dma_handle)
 {
        unsigned long addr = (unsigned long) vaddr;
+       int order = get_order(size);
+
+       if (dma_release_from_coherent(dev, order, vaddr))
+               return;
 
        plat_unmap_dma_mem(dev, dma_handle, size, DMA_BIDIRECTIONAL);
 
index 61888ff72c87ce7bb56c3ea6c269f9a8a801ce8d..9035c64bc5ed4e27b0661231507de7346848a07f 100644 (file)
@@ -54,7 +54,8 @@ static struct prom_pmemblock * __init prom_getmdesc(void)
 {
        char *memsize_str;
        unsigned int memsize;
-       char cmdline[CL_SIZE], *ptr;
+       char *ptr;
+       static char cmdline[CL_SIZE] __initdata;
 
        /* otherwise look in the environment */
        memsize_str = prom_getenv("memsize");
index 9f40e1ff9b4fe4c71b1827d83972419b2fb4dc81..041fc1afc3f4bf20e9ee7def1dd9de4310010f0b 100644 (file)
@@ -110,7 +110,6 @@ static struct korina_device korina_dev0_data = {
 static struct platform_device korina_dev0 = {
        .id = -1,
        .name = "korina",
-       .dev.driver_data = &korina_dev0_data,
        .resource = korina_dev0_res,
        .num_resources = ARRAY_SIZE(korina_dev0_res),
 };
@@ -332,6 +331,8 @@ static int __init plat_setup_devices(void)
        /* set the uart clock to the current cpu frequency */
        rb532_uart_res[0].uartclk = idt_cpu_freq;
 
+       dev_set_drvdata(&korina_dev0.dev, &korina_dev0_data);
+
        return platform_add_devices(rb532_devs, ARRAY_SIZE(rb532_devs));
 }
 
index 46ca24dbcc2d0ea035fe104c46cc03ab7684c2aa..ad5bd10979740673806c5e8b4620dcd6310e039d 100644 (file)
@@ -69,7 +69,7 @@ static inline unsigned long tag2ul(char *arg, const char *tag)
 
 void __init prom_setup_cmdline(void)
 {
-       char cmd_line[CL_SIZE];
+       static char cmd_line[CL_SIZE] __initdata;
        char *cp, *board;
        int prom_argc;
        char **prom_argv, **prom_envp;
index e10184c1b3e14cebd667166503fc67297087b257..d66802edebb2f7ea85d5004ac2791905a93ad57c 100644 (file)
@@ -160,7 +160,7 @@ static void __init prom_init_cmdline(void)
        int argc;
        int *argv32;
        int i;                  /* Always ignore the "-c" at argv[0] */
-       char builtin[CL_SIZE];
+       static char builtin[CL_SIZE] __initdata;
 
        if (fw_arg0 >= CKSEG0 || fw_arg1 < CKSEG0) {
                /*
@@ -315,7 +315,7 @@ static inline void txx9_cache_fixup(void)
 
 static void __init preprocess_cmdline(void)
 {
-       char cmdline[CL_SIZE];
+       static char cmdline[CL_SIZE] __initdata;
        char *s;
 
        strcpy(cmdline, arcs_cmdline);
index 5f39d5597cedea76f43c3470bcb9998c9dd07b12..1e1c824764ee1f0202c9012090e06f532eb75e42 100644 (file)
@@ -28,8 +28,6 @@
 #define F_SETOWN       12      /*  for sockets. */
 #define F_SETSIG       13      /*  for sockets. */
 #define F_GETSIG       14      /*  for sockets. */
-#define F_GETOWN_EX    15
-#define F_SETOWN_EX    16
 
 /* for posix fcntl() and lockf() */
 #define F_RDLCK                01
index 69dad5a850a8392f5f520dd164f4dda9a4d5445a..a36799e85693d7b30d7a9acf1f2703709ad77bcb 100644 (file)
@@ -28,7 +28,7 @@
 #define dbg(x...)
 #endif
 
-#define KERNEL_START (KERNEL_BINARY_TEXT_START - 0x1000)
+#define KERNEL_START (KERNEL_BINARY_TEXT_START)
 
 extern struct unwind_table_entry __start___unwind[];
 extern struct unwind_table_entry __stop___unwind[];
index fda4baa059b5002a99f64fdb832cf134b20756ee..9dab4a4e09f7af86d5dbe6a5a8e129393d619a42 100644 (file)
@@ -78,9 +78,6 @@ SECTIONS
         */
        . = ALIGN(PAGE_SIZE);
        data_start = .;
-       EXCEPTION_TABLE(16)
-
-       NOTES
 
        /* unwind info */
        .PARISC.unwind : {
@@ -89,6 +86,9 @@ SECTIONS
                __stop___unwind = .;
        }
 
+       EXCEPTION_TABLE(16)
+       NOTES
+
        /* Data */
        RW_DATA_SECTION(L1_CACHE_BYTES, PAGE_SIZE, THREAD_SIZE)
 
index c02a99952be7cdfa4f2c2b4061c6af58d8a2403f..893f446cbd22a15c9108d9e244a2ad148344d2db 100644 (file)
@@ -58,7 +58,7 @@ static int check_elf64(void *p, int size, struct addr_range *r)
 
        return 64;
 }
-void get4k(FILE *file, char *buf )
+static void get4k(FILE *file, char *buf )
 {
        unsigned j;
        unsigned num = fread(buf, 1, 4096, file);
@@ -66,12 +66,12 @@ void get4k(FILE *file, char *buf )
                buf[j] = 0;
 }
 
-void put4k(FILE *file, char *buf )
+static void put4k(FILE *file, char *buf )
 {
        fwrite(buf, 1, 4096, file);
 }
 
-void death(const char *msg, FILE *fdesc, const char *fname) 
+static void death(const char *msg, FILE *fdesc, const char *fname)
 {
        fprintf(stderr, msg);
        fclose(fdesc);
index b6bac6f61c16d60465b17da5cc77ba81e059ec5e..916369575c976991d449dfcd2b4c196c4bd8e7f1 100644 (file)
@@ -29,5 +29,16 @@ enum km_type {
        KM_TYPE_NR
 };
 
+/*
+ * This is a temporary build fix that (so they say on lkml....) should no longer
+ * be required after 2.6.33, because of changes planned to the kmap code.
+ * Let's try to remove this cruft then.
+ */
+#ifdef CONFIG_DEBUG_HIGHMEM
+#define KM_NMI         (-1)
+#define KM_NMI_PTE     (-1)
+#define KM_IRQ_PTE     (-1)
+#endif
+
 #endif /* __KERNEL__ */
 #endif /* _ASM_POWERPC_KMAP_TYPES_H */
index 53bcf3d792db1e16bce7066389fa29e7451602a7..b152de3e64d45a3646356b438ae9e7fedd088e4f 100644 (file)
@@ -345,7 +345,7 @@ void __init setup_arch(char **cmdline_p)
 
 #ifdef CONFIG_SWIOTLB
        if (ppc_swiotlb_enable)
-               swiotlb_init();
+               swiotlb_init(1);
 #endif
 
        paging_init();
index 04f638d82fb3cd3ff5387bfe62f395144e4f7c82..df2c9e932b3714b8ef060ac204757157429a3029 100644 (file)
@@ -550,7 +550,7 @@ void __init setup_arch(char **cmdline_p)
 
 #ifdef CONFIG_SWIOTLB
        if (ppc_swiotlb_enable)
-               swiotlb_init();
+               swiotlb_init(1);
 #endif
 
        paging_init();
index 43c0acad7160e55eef1bc719c39111a3cdf97a14..16c673096a226ee3bb0b671d6869faae4f9ee3ab 100644 (file)
@@ -95,6 +95,34 @@ config S390
        select HAVE_ARCH_TRACEHOOK
        select INIT_ALL_POSSIBLE
        select HAVE_PERF_EVENTS
+       select ARCH_INLINE_SPIN_TRYLOCK
+       select ARCH_INLINE_SPIN_TRYLOCK_BH
+       select ARCH_INLINE_SPIN_LOCK
+       select ARCH_INLINE_SPIN_LOCK_BH
+       select ARCH_INLINE_SPIN_LOCK_IRQ
+       select ARCH_INLINE_SPIN_LOCK_IRQSAVE
+       select ARCH_INLINE_SPIN_UNLOCK
+       select ARCH_INLINE_SPIN_UNLOCK_BH
+       select ARCH_INLINE_SPIN_UNLOCK_IRQ
+       select ARCH_INLINE_SPIN_UNLOCK_IRQRESTORE
+       select ARCH_INLINE_READ_TRYLOCK
+       select ARCH_INLINE_READ_LOCK
+       select ARCH_INLINE_READ_LOCK_BH
+       select ARCH_INLINE_READ_LOCK_IRQ
+       select ARCH_INLINE_READ_LOCK_IRQSAVE
+       select ARCH_INLINE_READ_UNLOCK
+       select ARCH_INLINE_READ_UNLOCK_BH
+       select ARCH_INLINE_READ_UNLOCK_IRQ
+       select ARCH_INLINE_READ_UNLOCK_IRQRESTORE
+       select ARCH_INLINE_WRITE_TRYLOCK
+       select ARCH_INLINE_WRITE_LOCK
+       select ARCH_INLINE_WRITE_LOCK_BH
+       select ARCH_INLINE_WRITE_LOCK_IRQ
+       select ARCH_INLINE_WRITE_LOCK_IRQSAVE
+       select ARCH_INLINE_WRITE_UNLOCK
+       select ARCH_INLINE_WRITE_UNLOCK_BH
+       select ARCH_INLINE_WRITE_UNLOCK_IRQ
+       select ARCH_INLINE_WRITE_UNLOCK_IRQRESTORE
 
 config SCHED_OMIT_FRAME_POINTER
        bool
index 7efd0abe88871dc494e26adc1ef5b31b7edffcb4..efb74fd5156e8f14590e012260dc6f568b627d3f 100644 (file)
@@ -49,7 +49,7 @@
 
 #define BUG() do {                                     \
        __EMIT_BUG(0);                                  \
-       for (;;);                                       \
+       unreachable();                                  \
 } while (0)
 
 #define WARN_ON(x) ({                                  \
index 41ce6861174eea7e2b15579e7d80b1ef34e9432a..c9af0d19c7ab7b4fc726528797be910ef7d7c0f3 100644 (file)
@@ -191,33 +191,4 @@ static inline int __raw_write_trylock(raw_rwlock_t *rw)
 #define _raw_read_relax(lock)  cpu_relax()
 #define _raw_write_relax(lock) cpu_relax()
 
-#define __always_inline__spin_lock
-#define __always_inline__read_lock
-#define __always_inline__write_lock
-#define __always_inline__spin_lock_bh
-#define __always_inline__read_lock_bh
-#define __always_inline__write_lock_bh
-#define __always_inline__spin_lock_irq
-#define __always_inline__read_lock_irq
-#define __always_inline__write_lock_irq
-#define __always_inline__spin_lock_irqsave
-#define __always_inline__read_lock_irqsave
-#define __always_inline__write_lock_irqsave
-#define __always_inline__spin_trylock
-#define __always_inline__read_trylock
-#define __always_inline__write_trylock
-#define __always_inline__spin_trylock_bh
-#define __always_inline__spin_unlock
-#define __always_inline__read_unlock
-#define __always_inline__write_unlock
-#define __always_inline__spin_unlock_bh
-#define __always_inline__read_unlock_bh
-#define __always_inline__write_unlock_bh
-#define __always_inline__spin_unlock_irq
-#define __always_inline__read_unlock_irq
-#define __always_inline__write_unlock_irq
-#define __always_inline__spin_unlock_irqrestore
-#define __always_inline__read_unlock_irqrestore
-#define __always_inline__write_unlock_irqrestore
-
 #endif /* __ASM_SPINLOCK_H */
index bf8b4ae7ff2d6450ac6fee0f7133e2fddc24b702..e49e9e0c69fd88278eaa707271c18466d23f70ad 100644 (file)
@@ -55,6 +55,7 @@ static void __init reset_tod_clock(void)
                disabled_wait(0);
 
        sched_clock_base_cc = TOD_UNIX_EPOCH;
+       S390_lowcore.last_update_clock = sched_clock_base_cc;
 }
 
 #ifdef CONFIG_SHARED_KERNEL
@@ -167,6 +168,14 @@ static noinline __init void create_kernel_nss(void)
                return;
        }
 
+       /* re-initialize cputime accounting. */
+       sched_clock_base_cc = get_clock();
+       S390_lowcore.last_update_clock = sched_clock_base_cc;
+       S390_lowcore.last_update_timer = 0x7fffffffffffffffULL;
+       S390_lowcore.user_timer = 0;
+       S390_lowcore.system_timer = 0;
+       asm volatile("SPT 0(%0)" : : "a" (&S390_lowcore.last_update_timer));
+
        /* re-setup boot command line with new ipl vm parms */
        ipl_update_parameters();
        setup_boot_command_line();
index f43d2ee544645a4de9eb679f9dbe095d555dfe77..48215d15762b2d3d6a3be7eaf6fe509a45268567 100644 (file)
@@ -565,10 +565,10 @@ pgm_svcper:
        lh      %r7,0x8a                # get svc number from lowcore
        l       %r9,__LC_THREAD_INFO    # load pointer to thread_info struct
        TRACE_IRQS_OFF
-       l       %r1,__TI_task(%r9)
-       mvc     __THREAD_per+__PER_atmid(2,%r1),__LC_PER_ATMID
-       mvc     __THREAD_per+__PER_address(4,%r1),__LC_PER_ADDRESS
-       mvc     __THREAD_per+__PER_access_id(1,%r1),__LC_PER_ACCESS_ID
+       l       %r8,__TI_task(%r9)
+       mvc     __THREAD_per+__PER_atmid(2,%r8),__LC_PER_ATMID
+       mvc     __THREAD_per+__PER_address(4,%r8),__LC_PER_ADDRESS
+       mvc     __THREAD_per+__PER_access_id(1,%r8),__LC_PER_ACCESS_ID
        oi      __TI_flags+3(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP
        TRACE_IRQS_ON
        stosm   __SF_EMPTY(%r15),0x03   # reenable interrupts
index a6f7b20df61687a6445de264a17bc7e0ec44bb96..9aff1d449b6e83c2be03275ad46cf6f3e3599a7c 100644 (file)
@@ -543,10 +543,10 @@ pgm_svcper:
        mvc     __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
        llgh    %r7,__LC_SVC_INT_CODE   # get svc number from lowcore
        lg      %r9,__LC_THREAD_INFO    # load pointer to thread_info struct
-       lg      %r1,__TI_task(%r9)
-       mvc     __THREAD_per+__PER_atmid(2,%r1),__LC_PER_ATMID
-       mvc     __THREAD_per+__PER_address(8,%r1),__LC_PER_ADDRESS
-       mvc     __THREAD_per+__PER_access_id(1,%r1),__LC_PER_ACCESS_ID
+       lg      %r8,__TI_task(%r9)
+       mvc     __THREAD_per+__PER_atmid(2,%r8),__LC_PER_ATMID
+       mvc     __THREAD_per+__PER_address(8,%r8),__LC_PER_ADDRESS
+       mvc     __THREAD_per+__PER_access_id(1,%r8),__LC_PER_ACCESS_ID
        oi      __TI_flags+7(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP
        TRACE_IRQS_ON
        stosm   __SF_EMPTY(%r15),0x03   # reenable interrupts
index 6b5d191eec3a98079ce6605a84f71472f89a309e..a351ed84eec5932c3e9f6ea0d7bcfff2c95c2f35 100644 (file)
@@ -68,7 +68,7 @@ static void unmask_imask_irq(unsigned int irq)
 }
 
 static struct irq_chip imask_irq_chip = {
-       .typename       = "SR.IMASK",
+       .name           = "SR.IMASK",
        .mask           = mask_imask_irq,
        .unmask         = unmask_imask_irq,
        .mask_ack       = mask_imask_irq,
index 6c092f1f55579e7d67641f4504bad9f71f5ee9e2..06e7e2959b542e9b862566d4f078e18953ff964b 100644 (file)
@@ -85,7 +85,7 @@ static void mask_and_ack_intc(unsigned int);
 static void end_intc_irq(unsigned int irq);
 
 static struct irq_chip intc_irq_type = {
-       .typename = "INTC",
+       .name = "INTC",
        .startup = startup_intc_irq,
        .shutdown = shutdown_intc_irq,
        .enable = enable_intc_irq,
index 52a4208fe4f01e6d3eb6a55a4e83613bdefa707a..bbf91b9c3d39fc0bc770eed6fb629001a6f7c630 100644 (file)
@@ -61,14 +61,14 @@ unsigned long lastfoffset = -1;
 unsigned long lastfrelno;
 btfixup *lastf;
 
-void fatal(void) __attribute__((noreturn));
-void fatal(void)
+static void fatal(void) __attribute__((noreturn));
+static void fatal(void)
 {
        fprintf(stderr, "Malformed output from objdump\n%s\n", buffer);
        exit(1);
 }
 
-btfixup *find(int type, char *name)
+static btfixup *find(int type, char *name)
 {
        int i;
        for (i = 0; i < last; i++) {
@@ -88,7 +88,7 @@ btfixup *find(int type, char *name)
        return array + last - 1;
 }
 
-void set_mode (char *buffer)
+static void set_mode (char *buffer)
 {
        for (mode = 0;; mode++)
                if (buffer[mode] < '0' || buffer[mode] > '9')
index e8dc9adfcd61db8a05ae092407b53a01f2efac2b..ac944aec7301769805199c8b3b7f83dbeae8a968 100644 (file)
  * as PROM looks for a.out image only.
  */
 
-unsigned short ld2(char *p)
+static unsigned short ld2(char *p)
 {
        return (p[0] << 8) | p[1];
 }
 
-unsigned int ld4(char *p)
+static unsigned int ld4(char *p)
 {
        return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
 }
 
-void st4(char *p, unsigned int x)
+static void st4(char *p, unsigned int x)
 {
        p[0] = x >> 24;
        p[1] = x >> 16;
@@ -53,7 +53,7 @@ void st4(char *p, unsigned int x)
        p[3] = x;
 }
 
-void usage(void)
+static void usage(void)
 {
        /* fs_img.gz is an image of initial ramdisk. */
        fprintf(stderr, "Usage: piggyback vmlinux.aout System.map fs_img.gz\n");
@@ -61,7 +61,7 @@ void usage(void)
        exit(1);
 }
 
-void die(char *str)
+static void die(char *str)
 {
        perror (str);
        exit(1);
index c63fd1b6bdd4f036617c7740619db05dbe6d8e7d..a26a686cb5aa04022196188264f1a77e20df2745 100644 (file)
@@ -32,7 +32,7 @@
 /* Note: run this on an a.out kernel (use elftoaout for it), as PROM looks for a.out image onlly
    usage: piggyback vmlinux System.map tail, where tail is gzipped fs of the initial ramdisk */
 
-void die(char *str)
+static void die(char *str)
 {
        perror (str);
        exit(1);
index c2f772dbd556ffaa5a75430500fbedb9cde3d3fd..77d1b313e3441e9b616dffeed881b7cf5bfcc541 100644 (file)
@@ -45,7 +45,7 @@ extern void free_initmem(void);
 #define VMEMMAP_ALIGN(x)       (((x)+VMEMMAP_CHUNK-1UL)&VMEMMAP_CHUNK_MASK)
 
 #define VMEMMAP_SIZE   ((((1UL << MAX_PHYSADDR_BITS) >> PAGE_SHIFT) * \
-                         sizeof(struct page *)) >> VMEMMAP_CHUNK_SHIFT)
+                         sizeof(struct page)) >> VMEMMAP_CHUNK_SHIFT)
 extern unsigned long vmemmap_table[VMEMMAP_SIZE];
 #endif
 
index 4b180897e6b510f0970118fb42f346054554e0d3..5af2982133b5435b492372c447eef8c849b0eac4 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2007-2008 Advanced Micro Devices, Inc.
+ * Copyright (C) 2007-2009 Advanced Micro Devices, Inc.
  * Author: Joerg Roedel <joerg.roedel@amd.com>
  *         Leo Duran <leo.duran@amd.com>
  *
 #include <linux/irqreturn.h>
 
 #ifdef CONFIG_AMD_IOMMU
-extern int amd_iommu_init(void);
-extern int amd_iommu_init_dma_ops(void);
-extern int amd_iommu_init_passthrough(void);
+
 extern void amd_iommu_detect(void);
-extern irqreturn_t amd_iommu_int_handler(int irq, void *data);
-extern void amd_iommu_flush_all_domains(void);
-extern void amd_iommu_flush_all_devices(void);
-extern void amd_iommu_shutdown(void);
-extern void amd_iommu_apply_erratum_63(u16 devid);
+
 #else
-static inline int amd_iommu_init(void) { return -ENODEV; }
+
 static inline void amd_iommu_detect(void) { }
-static inline void amd_iommu_shutdown(void) { }
+
 #endif
 
 #endif /* _ASM_X86_AMD_IOMMU_H */
diff --git a/arch/x86/include/asm/amd_iommu_proto.h b/arch/x86/include/asm/amd_iommu_proto.h
new file mode 100644 (file)
index 0000000..84786fb
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2009 Advanced Micro Devices, Inc.
+ * Author: Joerg Roedel <joerg.roedel@amd.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public 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 _ASM_X86_AMD_IOMMU_PROTO_H
+#define _ASM_X86_AMD_IOMMU_PROTO_H
+
+struct amd_iommu;
+
+extern int amd_iommu_init_dma_ops(void);
+extern int amd_iommu_init_passthrough(void);
+extern irqreturn_t amd_iommu_int_handler(int irq, void *data);
+extern void amd_iommu_flush_all_domains(void);
+extern void amd_iommu_flush_all_devices(void);
+extern void amd_iommu_apply_erratum_63(u16 devid);
+extern void amd_iommu_reset_cmd_buffer(struct amd_iommu *iommu);
+
+#ifndef CONFIG_AMD_IOMMU_STATS
+
+static inline void amd_iommu_stats_init(void) { }
+
+#endif /* !CONFIG_AMD_IOMMU_STATS */
+
+#endif /* _ASM_X86_AMD_IOMMU_PROTO_H  */
index 2a2cc7a78a81b6b06d460dfee51ad8e9093eb808..ba19ad4c47d03010f9d371bb80fe94e13676cf5a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2007-2008 Advanced Micro Devices, Inc.
+ * Copyright (C) 2007-2009 Advanced Micro Devices, Inc.
  * Author: Joerg Roedel <joerg.roedel@amd.com>
  *         Leo Duran <leo.duran@amd.com>
  *
 #include <linux/list.h>
 #include <linux/spinlock.h>
 
+/*
+ * Maximum number of IOMMUs supported
+ */
+#define MAX_IOMMUS     32
+
 /*
  * some size calculation constants
  */
@@ -206,6 +211,9 @@ extern bool amd_iommu_dump;
                        printk(KERN_INFO "AMD-Vi: " format, ## arg);    \
        } while(0);
 
+/* global flag if IOMMUs cache non-present entries */
+extern bool amd_iommu_np_cache;
+
 /*
  * Make iterating over all IOMMUs easier
  */
@@ -226,6 +234,8 @@ extern bool amd_iommu_dump;
  * independent of their use.
  */
 struct protection_domain {
+       struct list_head list;  /* for list of all protection domains */
+       struct list_head dev_list; /* List of all devices in this domain */
        spinlock_t lock;        /* mostly used to lock the page table*/
        u16 id;                 /* the domain id written to the device table */
        int mode;               /* paging mode (0-6 levels) */
@@ -233,7 +243,20 @@ struct protection_domain {
        unsigned long flags;    /* flags to find out type of domain */
        bool updated;           /* complete domain flush required */
        unsigned dev_cnt;       /* devices assigned to this domain */
+       unsigned dev_iommu[MAX_IOMMUS]; /* per-IOMMU reference count */
        void *priv;             /* private data */
+
+};
+
+/*
+ * This struct contains device specific data for the IOMMU
+ */
+struct iommu_dev_data {
+       struct list_head list;            /* For domain->dev_list */
+       struct device *dev;               /* Device this data belong to */
+       struct device *alias;             /* The Alias Device */
+       struct protection_domain *domain; /* Domain the device is bound to */
+       atomic_t bind;                    /* Domain attach reverent count */
 };
 
 /*
@@ -291,6 +314,9 @@ struct dma_ops_domain {
 struct amd_iommu {
        struct list_head list;
 
+       /* Index within the IOMMU array */
+       int index;
+
        /* locks the accesses to the hardware */
        spinlock_t lock;
 
@@ -356,6 +382,21 @@ struct amd_iommu {
  */
 extern struct list_head amd_iommu_list;
 
+/*
+ * Array with pointers to each IOMMU struct
+ * The indices are referenced in the protection domains
+ */
+extern struct amd_iommu *amd_iommus[MAX_IOMMUS];
+
+/* Number of IOMMUs present in the system */
+extern int amd_iommus_present;
+
+/*
+ * Declarations for the global list of all protection domains
+ */
+extern spinlock_t amd_iommu_pd_lock;
+extern struct list_head amd_iommu_pd_list;
+
 /*
  * Structure defining one entry in the device table
  */
@@ -416,15 +457,9 @@ extern unsigned amd_iommu_aperture_order;
 /* largest PCI device id we expect translation requests for */
 extern u16 amd_iommu_last_bdf;
 
-/* data structures for protection domain handling */
-extern struct protection_domain **amd_iommu_pd_table;
-
 /* allocation bitmap for domain ids */
 extern unsigned long *amd_iommu_pd_alloc_bitmap;
 
-/* will be 1 if device isolation is enabled */
-extern bool amd_iommu_isolate;
-
 /*
  * If true, the addresses will be flushed on unmap time, not when
  * they are reused
@@ -462,11 +497,6 @@ struct __iommu_counter {
 #define ADD_STATS_COUNTER(name, x)
 #define SUB_STATS_COUNTER(name, x)
 
-static inline void amd_iommu_stats_init(void) { }
-
 #endif /* CONFIG_AMD_IOMMU_STATS */
 
-/* some function prototypes */
-extern void amd_iommu_reset_cmd_buffer(struct amd_iommu *iommu);
-
 #endif /* _ASM_X86_AMD_IOMMU_TYPES_H */
index d9cf1cd156d24b5cebe5a8ed41292b6300e8c9c2..f654d1bb17fb6cf3f0199dd820bd2da2f8b52901 100644 (file)
@@ -22,14 +22,14 @@ do {                                                                \
                     ".popsection"                              \
                     : : "i" (__FILE__), "i" (__LINE__),        \
                     "i" (sizeof(struct bug_entry)));           \
-       for (;;) ;                                              \
+       unreachable();                                          \
 } while (0)
 
 #else
 #define BUG()                                                  \
 do {                                                           \
        asm volatile("ud2");                                    \
-       for (;;) ;                                              \
+       unreachable();                                          \
 } while (0)
 #endif
 
index b03bedb62aa7f43ab8bc8f75168206dfbb5dd721..0918654305af5975bdef505fe7c3003cbc49ef73 100644 (file)
@@ -62,10 +62,8 @@ struct cal_chipset_ops {
 extern int use_calgary;
 
 #ifdef CONFIG_CALGARY_IOMMU
-extern int calgary_iommu_init(void);
 extern void detect_calgary(void);
 #else
-static inline int calgary_iommu_init(void) { return 1; }
 static inline void detect_calgary(void) { return; }
 #endif
 
index cee34e9ca45bc9b74aaba7203a340c0922996277..029f230ab637f2ab8fddb835f506edc9abc0f28d 100644 (file)
@@ -8,7 +8,7 @@ struct dev_archdata {
 #ifdef CONFIG_X86_64
 struct dma_map_ops *dma_ops;
 #endif
-#ifdef CONFIG_DMAR
+#if defined(CONFIG_DMAR) || defined(CONFIG_AMD_IOMMU)
        void *iommu; /* hook for IOMMU specific extension */
 #endif
 };
index 6a25d5d4283640f6a2ec76add7581a4bfd47e610..0f6c02f3b7d4f26126a590e3df2408c2af6c5d8c 100644 (file)
@@ -20,7 +20,8 @@
 # define ISA_DMA_BIT_MASK DMA_BIT_MASK(32)
 #endif
 
-extern dma_addr_t bad_dma_address;
+#define DMA_ERROR_CODE 0
+
 extern int iommu_merge;
 extern struct device x86_dma_fallback_dev;
 extern int panic_on_overflow;
@@ -48,7 +49,7 @@ static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
        if (ops->mapping_error)
                return ops->mapping_error(dev, dma_addr);
 
-       return (dma_addr == bad_dma_address);
+       return (dma_addr == DMA_ERROR_CODE);
 }
 
 #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
index 6cfdafa409d8f436d106e4fb9f1e19374d913d55..4ac5b0f33fc1017b3760eb01b1a4ed7f7155dbce 100644 (file)
@@ -35,8 +35,7 @@ extern int gart_iommu_aperture_allowed;
 extern int gart_iommu_aperture_disabled;
 
 extern void early_gart_iommu_check(void);
-extern void gart_iommu_init(void);
-extern void gart_iommu_shutdown(void);
+extern int gart_iommu_init(void);
 extern void __init gart_parse_options(char *);
 extern void gart_iommu_hole_init(void);
 
@@ -48,12 +47,6 @@ extern void gart_iommu_hole_init(void);
 static inline void early_gart_iommu_check(void)
 {
 }
-static inline void gart_iommu_init(void)
-{
-}
-static inline void gart_iommu_shutdown(void)
-{
-}
 static inline void gart_parse_options(char *options)
 {
 }
index fd6d21bbee6cc34c2cbb709b269ee1811bb2b108..345c99cef15262dda6415b5eff3d2140c37bafcc 100644 (file)
@@ -1,8 +1,6 @@
 #ifndef _ASM_X86_IOMMU_H
 #define _ASM_X86_IOMMU_H
 
-extern void pci_iommu_shutdown(void);
-extern void no_iommu_init(void);
 extern struct dma_map_ops nommu_dma_ops;
 extern int force_iommu, no_iommu;
 extern int iommu_detected;
index b9e4e20174fbb0c9519848f1f542b2bb3e9c2a89..87ffcb12a1b87c91b3ad9fd6f459b97ad222aa5c 100644 (file)
@@ -3,17 +3,14 @@
 
 #include <linux/swiotlb.h>
 
-/* SWIOTLB interface */
-
-extern int swiotlb_force;
-
 #ifdef CONFIG_SWIOTLB
 extern int swiotlb;
-extern void pci_swiotlb_init(void);
+extern int pci_swiotlb_init(void);
 #else
 #define swiotlb 0
-static inline void pci_swiotlb_init(void)
+static inline int pci_swiotlb_init(void)
 {
+       return 0;
 }
 #endif
 
index 2c756fd4ab0ead09c83970ea588ad865a42c1708..d8e71459f025a3c4c08225d148e67bbb895f851a 100644 (file)
@@ -90,6 +90,14 @@ struct x86_init_timers {
        void (*timer_init)(void);
 };
 
+/**
+ * struct x86_init_iommu - platform specific iommu setup
+ * @iommu_init:                        platform specific iommu setup
+ */
+struct x86_init_iommu {
+       int (*iommu_init)(void);
+};
+
 /**
  * struct x86_init_ops - functions for platform specific setup
  *
@@ -101,6 +109,7 @@ struct x86_init_ops {
        struct x86_init_oem             oem;
        struct x86_init_paging          paging;
        struct x86_init_timers          timers;
+       struct x86_init_iommu           iommu;
 };
 
 /**
@@ -121,6 +130,7 @@ struct x86_platform_ops {
        unsigned long (*calibrate_tsc)(void);
        unsigned long (*get_wallclock)(void);
        int (*set_wallclock)(unsigned long nowtime);
+       void (*iommu_shutdown)(void);
 };
 
 extern struct x86_init_ops x86_init;
index d296f4a195c916d8d454c144396ecc1f71af91d2..d85d1b2432baec47b65d81191353c0ab6b490aec 100644 (file)
@@ -79,7 +79,8 @@ void arch_acpi_processor_init_pdc(struct acpi_processor *pr)
        struct cpuinfo_x86 *c = &cpu_data(pr->id);
 
        pr->pdc = NULL;
-       if (c->x86_vendor == X86_VENDOR_INTEL)
+       if (c->x86_vendor == X86_VENDOR_INTEL ||
+           c->x86_vendor == X86_VENDOR_CENTAUR)
                init_intel_pdc(pr, c);
 
        return;
index 0285521e0a991d09dbf3fd01e85489f068083d3f..32fb09102a1356af2597d1cafd924bbc8e2ee941 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2007-2008 Advanced Micro Devices, Inc.
+ * Copyright (C) 2007-2009 Advanced Micro Devices, Inc.
  * Author: Joerg Roedel <joerg.roedel@amd.com>
  *         Leo Duran <leo.duran@amd.com>
  *
@@ -28,6 +28,7 @@
 #include <asm/proto.h>
 #include <asm/iommu.h>
 #include <asm/gart.h>
+#include <asm/amd_iommu_proto.h>
 #include <asm/amd_iommu_types.h>
 #include <asm/amd_iommu.h>
 
@@ -56,20 +57,115 @@ struct iommu_cmd {
        u32 data[4];
 };
 
-static int dma_ops_unity_map(struct dma_ops_domain *dma_dom,
-                            struct unity_map_entry *e);
-static struct dma_ops_domain *find_protection_domain(u16 devid);
-static u64 *alloc_pte(struct protection_domain *domain,
-                     unsigned long address, int end_lvl,
-                     u64 **pte_page, gfp_t gfp);
-static void dma_ops_reserve_addresses(struct dma_ops_domain *dom,
-                                     unsigned long start_page,
-                                     unsigned int pages);
 static void reset_iommu_command_buffer(struct amd_iommu *iommu);
-static u64 *fetch_pte(struct protection_domain *domain,
-                     unsigned long address, int map_size);
 static void update_domain(struct protection_domain *domain);
 
+/****************************************************************************
+ *
+ * Helper functions
+ *
+ ****************************************************************************/
+
+static inline u16 get_device_id(struct device *dev)
+{
+       struct pci_dev *pdev = to_pci_dev(dev);
+
+       return calc_devid(pdev->bus->number, pdev->devfn);
+}
+
+static struct iommu_dev_data *get_dev_data(struct device *dev)
+{
+       return dev->archdata.iommu;
+}
+
+/*
+ * In this function the list of preallocated protection domains is traversed to
+ * find the domain for a specific device
+ */
+static struct dma_ops_domain *find_protection_domain(u16 devid)
+{
+       struct dma_ops_domain *entry, *ret = NULL;
+       unsigned long flags;
+       u16 alias = amd_iommu_alias_table[devid];
+
+       if (list_empty(&iommu_pd_list))
+               return NULL;
+
+       spin_lock_irqsave(&iommu_pd_list_lock, flags);
+
+       list_for_each_entry(entry, &iommu_pd_list, list) {
+               if (entry->target_dev == devid ||
+                   entry->target_dev == alias) {
+                       ret = entry;
+                       break;
+               }
+       }
+
+       spin_unlock_irqrestore(&iommu_pd_list_lock, flags);
+
+       return ret;
+}
+
+/*
+ * This function checks if the driver got a valid device from the caller to
+ * avoid dereferencing invalid pointers.
+ */
+static bool check_device(struct device *dev)
+{
+       u16 devid;
+
+       if (!dev || !dev->dma_mask)
+               return false;
+
+       /* No device or no PCI device */
+       if (!dev || dev->bus != &pci_bus_type)
+               return false;
+
+       devid = get_device_id(dev);
+
+       /* Out of our scope? */
+       if (devid > amd_iommu_last_bdf)
+               return false;
+
+       if (amd_iommu_rlookup_table[devid] == NULL)
+               return false;
+
+       return true;
+}
+
+static int iommu_init_device(struct device *dev)
+{
+       struct iommu_dev_data *dev_data;
+       struct pci_dev *pdev;
+       u16 devid, alias;
+
+       if (dev->archdata.iommu)
+               return 0;
+
+       dev_data = kzalloc(sizeof(*dev_data), GFP_KERNEL);
+       if (!dev_data)
+               return -ENOMEM;
+
+       dev_data->dev = dev;
+
+       devid = get_device_id(dev);
+       alias = amd_iommu_alias_table[devid];
+       pdev = pci_get_bus_and_slot(PCI_BUS(alias), alias & 0xff);
+       if (pdev)
+               dev_data->alias = &pdev->dev;
+
+       atomic_set(&dev_data->bind, 0);
+
+       dev->archdata.iommu = dev_data;
+
+
+       return 0;
+}
+
+static void iommu_uninit_device(struct device *dev)
+{
+       kfree(dev->archdata.iommu);
+}
 #ifdef CONFIG_AMD_IOMMU_STATS
 
 /*
@@ -90,7 +186,6 @@ DECLARE_STATS_COUNTER(alloced_io_mem);
 DECLARE_STATS_COUNTER(total_map_requests);
 
 static struct dentry *stats_dir;
-static struct dentry *de_isolate;
 static struct dentry *de_fflush;
 
 static void amd_iommu_stats_add(struct __iommu_counter *cnt)
@@ -108,9 +203,6 @@ static void amd_iommu_stats_init(void)
        if (stats_dir == NULL)
                return;
 
-       de_isolate = debugfs_create_bool("isolation", 0444, stats_dir,
-                                        (u32 *)&amd_iommu_isolate);
-
        de_fflush  = debugfs_create_bool("fullflush", 0444, stats_dir,
                                         (u32 *)&amd_iommu_unmap_flush);
 
@@ -130,12 +222,6 @@ static void amd_iommu_stats_init(void)
 
 #endif
 
-/* returns !0 if the IOMMU is caching non-present entries in its TLB */
-static int iommu_has_npcache(struct amd_iommu *iommu)
-{
-       return iommu->cap & (1UL << IOMMU_CAP_NPCACHE);
-}
-
 /****************************************************************************
  *
  * Interrupt handling functions
@@ -199,6 +285,7 @@ static void iommu_print_event(struct amd_iommu *iommu, void *__evt)
                break;
        case EVENT_TYPE_ILL_CMD:
                printk("ILLEGAL_COMMAND_ERROR address=0x%016llx]\n", address);
+               iommu->reset_in_progress = true;
                reset_iommu_command_buffer(iommu);
                dump_command(address);
                break;
@@ -321,11 +408,8 @@ static void __iommu_wait_for_completion(struct amd_iommu *iommu)
        status &= ~MMIO_STATUS_COM_WAIT_INT_MASK;
        writel(status, iommu->mmio_base + MMIO_STATUS_OFFSET);
 
-       if (unlikely(i == EXIT_LOOP_COUNT)) {
-               spin_unlock(&iommu->lock);
-               reset_iommu_command_buffer(iommu);
-               spin_lock(&iommu->lock);
-       }
+       if (unlikely(i == EXIT_LOOP_COUNT))
+               iommu->reset_in_progress = true;
 }
 
 /*
@@ -372,26 +456,46 @@ static int iommu_completion_wait(struct amd_iommu *iommu)
 out:
        spin_unlock_irqrestore(&iommu->lock, flags);
 
+       if (iommu->reset_in_progress)
+               reset_iommu_command_buffer(iommu);
+
        return 0;
 }
 
+static void iommu_flush_complete(struct protection_domain *domain)
+{
+       int i;
+
+       for (i = 0; i < amd_iommus_present; ++i) {
+               if (!domain->dev_iommu[i])
+                       continue;
+
+               /*
+                * Devices of this domain are behind this IOMMU
+                * We need to wait for completion of all commands.
+                */
+               iommu_completion_wait(amd_iommus[i]);
+       }
+}
+
 /*
  * Command send function for invalidating a device table entry
  */
-static int iommu_queue_inv_dev_entry(struct amd_iommu *iommu, u16 devid)
+static int iommu_flush_device(struct device *dev)
 {
+       struct amd_iommu *iommu;
        struct iommu_cmd cmd;
-       int ret;
+       u16 devid;
 
-       BUG_ON(iommu == NULL);
+       devid = get_device_id(dev);
+       iommu = amd_iommu_rlookup_table[devid];
 
+       /* Build command */
        memset(&cmd, 0, sizeof(cmd));
        CMD_SET_TYPE(&cmd, CMD_INV_DEV_ENTRY);
        cmd.data[0] = devid;
 
-       ret = iommu_queue_command(iommu, &cmd);
-
-       return ret;
+       return iommu_queue_command(iommu, &cmd);
 }
 
 static void __iommu_build_inv_iommu_pages(struct iommu_cmd *cmd, u64 address,
@@ -430,11 +534,11 @@ static int iommu_queue_inv_iommu_pages(struct amd_iommu *iommu,
  * It invalidates a single PTE if the range to flush is within a single
  * page. Otherwise it flushes the whole TLB of the IOMMU.
  */
-static int iommu_flush_pages(struct amd_iommu *iommu, u16 domid,
-               u64 address, size_t size)
+static void __iommu_flush_pages(struct protection_domain *domain,
+                               u64 address, size_t size, int pde)
 {
-       int s = 0;
-       unsigned pages = iommu_num_pages(address, size, PAGE_SIZE);
+       int s = 0, i;
+       unsigned long pages = iommu_num_pages(address, size, PAGE_SIZE);
 
        address &= PAGE_MASK;
 
@@ -447,142 +551,212 @@ static int iommu_flush_pages(struct amd_iommu *iommu, u16 domid,
                s = 1;
        }
 
-       iommu_queue_inv_iommu_pages(iommu, address, domid, 0, s);
 
-       return 0;
+       for (i = 0; i < amd_iommus_present; ++i) {
+               if (!domain->dev_iommu[i])
+                       continue;
+
+               /*
+                * Devices of this domain are behind this IOMMU
+                * We need a TLB flush
+                */
+               iommu_queue_inv_iommu_pages(amd_iommus[i], address,
+                                           domain->id, pde, s);
+       }
+
+       return;
 }
 
-/* Flush the whole IO/TLB for a given protection domain */
-static void iommu_flush_tlb(struct amd_iommu *iommu, u16 domid)
+static void iommu_flush_pages(struct protection_domain *domain,
+                            u64 address, size_t size)
 {
-       u64 address = CMD_INV_IOMMU_ALL_PAGES_ADDRESS;
-
-       INC_STATS_COUNTER(domain_flush_single);
+       __iommu_flush_pages(domain, address, size, 0);
+}
 
-       iommu_queue_inv_iommu_pages(iommu, address, domid, 0, 1);
+/* Flush the whole IO/TLB for a given protection domain */
+static void iommu_flush_tlb(struct protection_domain *domain)
+{
+       __iommu_flush_pages(domain, 0, CMD_INV_IOMMU_ALL_PAGES_ADDRESS, 0);
 }
 
 /* Flush the whole IO/TLB for a given protection domain - including PDE */
-static void iommu_flush_tlb_pde(struct amd_iommu *iommu, u16 domid)
+static void iommu_flush_tlb_pde(struct protection_domain *domain)
 {
-       u64 address = CMD_INV_IOMMU_ALL_PAGES_ADDRESS;
-
-       INC_STATS_COUNTER(domain_flush_single);
-
-       iommu_queue_inv_iommu_pages(iommu, address, domid, 1, 1);
+       __iommu_flush_pages(domain, 0, CMD_INV_IOMMU_ALL_PAGES_ADDRESS, 1);
 }
 
+
 /*
- * This function flushes one domain on one IOMMU
+ * This function flushes the DTEs for all devices in domain
  */
-static void flush_domain_on_iommu(struct amd_iommu *iommu, u16 domid)
+static void iommu_flush_domain_devices(struct protection_domain *domain)
 {
-       struct iommu_cmd cmd;
+       struct iommu_dev_data *dev_data;
        unsigned long flags;
 
-       __iommu_build_inv_iommu_pages(&cmd, CMD_INV_IOMMU_ALL_PAGES_ADDRESS,
-                                     domid, 1, 1);
+       spin_lock_irqsave(&domain->lock, flags);
 
-       spin_lock_irqsave(&iommu->lock, flags);
-       __iommu_queue_command(iommu, &cmd);
-       __iommu_completion_wait(iommu);
-       __iommu_wait_for_completion(iommu);
-       spin_unlock_irqrestore(&iommu->lock, flags);
+       list_for_each_entry(dev_data, &domain->dev_list, list)
+               iommu_flush_device(dev_data->dev);
+
+       spin_unlock_irqrestore(&domain->lock, flags);
 }
 
-static void flush_all_domains_on_iommu(struct amd_iommu *iommu)
+static void iommu_flush_all_domain_devices(void)
 {
-       int i;
+       struct protection_domain *domain;
+       unsigned long flags;
 
-       for (i = 1; i < MAX_DOMAIN_ID; ++i) {
-               if (!test_bit(i, amd_iommu_pd_alloc_bitmap))
-                       continue;
-               flush_domain_on_iommu(iommu, i);
+       spin_lock_irqsave(&amd_iommu_pd_lock, flags);
+
+       list_for_each_entry(domain, &amd_iommu_pd_list, list) {
+               iommu_flush_domain_devices(domain);
+               iommu_flush_complete(domain);
        }
 
+       spin_unlock_irqrestore(&amd_iommu_pd_lock, flags);
+}
+
+void amd_iommu_flush_all_devices(void)
+{
+       iommu_flush_all_domain_devices();
 }
 
 /*
- * This function is used to flush the IO/TLB for a given protection domain
- * on every IOMMU in the system
+ * This function uses heavy locking and may disable irqs for some time. But
+ * this is no issue because it is only called during resume.
  */
-static void iommu_flush_domain(u16 domid)
+void amd_iommu_flush_all_domains(void)
 {
-       struct amd_iommu *iommu;
+       struct protection_domain *domain;
+       unsigned long flags;
 
-       INC_STATS_COUNTER(domain_flush_all);
+       spin_lock_irqsave(&amd_iommu_pd_lock, flags);
 
-       for_each_iommu(iommu)
-               flush_domain_on_iommu(iommu, domid);
+       list_for_each_entry(domain, &amd_iommu_pd_list, list) {
+               spin_lock(&domain->lock);
+               iommu_flush_tlb_pde(domain);
+               iommu_flush_complete(domain);
+               spin_unlock(&domain->lock);
+       }
+
+       spin_unlock_irqrestore(&amd_iommu_pd_lock, flags);
 }
 
-void amd_iommu_flush_all_domains(void)
+static void reset_iommu_command_buffer(struct amd_iommu *iommu)
 {
-       struct amd_iommu *iommu;
+       pr_err("AMD-Vi: Resetting IOMMU command buffer\n");
 
-       for_each_iommu(iommu)
-               flush_all_domains_on_iommu(iommu);
+       if (iommu->reset_in_progress)
+               panic("AMD-Vi: ILLEGAL_COMMAND_ERROR while resetting command buffer\n");
+
+       amd_iommu_reset_cmd_buffer(iommu);
+       amd_iommu_flush_all_devices();
+       amd_iommu_flush_all_domains();
+
+       iommu->reset_in_progress = false;
 }
 
-static void flush_all_devices_for_iommu(struct amd_iommu *iommu)
+/****************************************************************************
+ *
+ * The functions below are used the create the page table mappings for
+ * unity mapped regions.
+ *
+ ****************************************************************************/
+
+/*
+ * This function is used to add another level to an IO page table. Adding
+ * another level increases the size of the address space by 9 bits to a size up
+ * to 64 bits.
+ */
+static bool increase_address_space(struct protection_domain *domain,
+                                  gfp_t gfp)
 {
-       int i;
+       u64 *pte;
 
-       for (i = 0; i <= amd_iommu_last_bdf; ++i) {
-               if (iommu != amd_iommu_rlookup_table[i])
-                       continue;
+       if (domain->mode == PAGE_MODE_6_LEVEL)
+               /* address space already 64 bit large */
+               return false;
 
-               iommu_queue_inv_dev_entry(iommu, i);
-               iommu_completion_wait(iommu);
-       }
+       pte = (void *)get_zeroed_page(gfp);
+       if (!pte)
+               return false;
+
+       *pte             = PM_LEVEL_PDE(domain->mode,
+                                       virt_to_phys(domain->pt_root));
+       domain->pt_root  = pte;
+       domain->mode    += 1;
+       domain->updated  = true;
+
+       return true;
 }
 
-static void flush_devices_by_domain(struct protection_domain *domain)
+static u64 *alloc_pte(struct protection_domain *domain,
+                     unsigned long address,
+                     int end_lvl,
+                     u64 **pte_page,
+                     gfp_t gfp)
 {
-       struct amd_iommu *iommu;
-       int i;
+       u64 *pte, *page;
+       int level;
 
-       for (i = 0; i <= amd_iommu_last_bdf; ++i) {
-               if ((domain == NULL && amd_iommu_pd_table[i] == NULL) ||
-                   (amd_iommu_pd_table[i] != domain))
-                       continue;
+       while (address > PM_LEVEL_SIZE(domain->mode))
+               increase_address_space(domain, gfp);
 
-               iommu = amd_iommu_rlookup_table[i];
-               if (!iommu)
-                       continue;
+       level =  domain->mode - 1;
+       pte   = &domain->pt_root[PM_LEVEL_INDEX(level, address)];
+
+       while (level > end_lvl) {
+               if (!IOMMU_PTE_PRESENT(*pte)) {
+                       page = (u64 *)get_zeroed_page(gfp);
+                       if (!page)
+                               return NULL;
+                       *pte = PM_LEVEL_PDE(level, virt_to_phys(page));
+               }
+
+               level -= 1;
 
-               iommu_queue_inv_dev_entry(iommu, i);
-               iommu_completion_wait(iommu);
+               pte = IOMMU_PTE_PAGE(*pte);
+
+               if (pte_page && level == end_lvl)
+                       *pte_page = pte;
+
+               pte = &pte[PM_LEVEL_INDEX(level, address)];
        }
+
+       return pte;
 }
 
-static void reset_iommu_command_buffer(struct amd_iommu *iommu)
+/*
+ * This function checks if there is a PTE for a given dma address. If
+ * there is one, it returns the pointer to it.
+ */
+static u64 *fetch_pte(struct protection_domain *domain,
+                     unsigned long address, int map_size)
 {
-       pr_err("AMD-Vi: Resetting IOMMU command buffer\n");
+       int level;
+       u64 *pte;
 
-       if (iommu->reset_in_progress)
-               panic("AMD-Vi: ILLEGAL_COMMAND_ERROR while resetting command buffer\n");
+       level =  domain->mode - 1;
+       pte   = &domain->pt_root[PM_LEVEL_INDEX(level, address)];
 
-       iommu->reset_in_progress = true;
+       while (level > map_size) {
+               if (!IOMMU_PTE_PRESENT(*pte))
+                       return NULL;
 
-       amd_iommu_reset_cmd_buffer(iommu);
-       flush_all_devices_for_iommu(iommu);
-       flush_all_domains_on_iommu(iommu);
+               level -= 1;
 
-       iommu->reset_in_progress = false;
-}
+               pte = IOMMU_PTE_PAGE(*pte);
+               pte = &pte[PM_LEVEL_INDEX(level, address)];
 
-void amd_iommu_flush_all_devices(void)
-{
-       flush_devices_by_domain(NULL);
-}
+               if ((PM_PTE_LEVEL(*pte) == 0) && level != map_size) {
+                       pte = NULL;
+                       break;
+               }
+       }
 
-/****************************************************************************
- *
- * The functions below are used the create the page table mappings for
- * unity mapped regions.
- *
- ****************************************************************************/
+       return pte;
+}
 
 /*
  * Generic mapping functions. It maps a physical address into a DMA
@@ -653,28 +827,6 @@ static int iommu_for_unity_map(struct amd_iommu *iommu,
        return 0;
 }
 
-/*
- * Init the unity mappings for a specific IOMMU in the system
- *
- * Basically iterates over all unity mapping entries and applies them to
- * the default domain DMA of that IOMMU if necessary.
- */
-static int iommu_init_unity_mappings(struct amd_iommu *iommu)
-{
-       struct unity_map_entry *entry;
-       int ret;
-
-       list_for_each_entry(entry, &amd_iommu_unity_map, list) {
-               if (!iommu_for_unity_map(iommu, entry))
-                       continue;
-               ret = dma_ops_unity_map(iommu->default_dom, entry);
-               if (ret)
-                       return ret;
-       }
-
-       return 0;
-}
-
 /*
  * This function actually applies the mapping to the page table of the
  * dma_ops domain.
@@ -703,6 +855,28 @@ static int dma_ops_unity_map(struct dma_ops_domain *dma_dom,
        return 0;
 }
 
+/*
+ * Init the unity mappings for a specific IOMMU in the system
+ *
+ * Basically iterates over all unity mapping entries and applies them to
+ * the default domain DMA of that IOMMU if necessary.
+ */
+static int iommu_init_unity_mappings(struct amd_iommu *iommu)
+{
+       struct unity_map_entry *entry;
+       int ret;
+
+       list_for_each_entry(entry, &amd_iommu_unity_map, list) {
+               if (!iommu_for_unity_map(iommu, entry))
+                       continue;
+               ret = dma_ops_unity_map(iommu->default_dom, entry);
+               if (ret)
+                       return ret;
+       }
+
+       return 0;
+}
+
 /*
  * Inits the unity mappings required for a specific device
  */
@@ -740,34 +914,23 @@ static int init_unity_mappings_for_device(struct dma_ops_domain *dma_dom,
  */
 
 /*
- * This function checks if there is a PTE for a given dma address. If
- * there is one, it returns the pointer to it.
+ * Used to reserve address ranges in the aperture (e.g. for exclusion
+ * ranges.
  */
-static u64 *fetch_pte(struct protection_domain *domain,
-                     unsigned long address, int map_size)
+static void dma_ops_reserve_addresses(struct dma_ops_domain *dom,
+                                     unsigned long start_page,
+                                     unsigned int pages)
 {
-       int level;
-       u64 *pte;
-
-       level =  domain->mode - 1;
-       pte   = &domain->pt_root[PM_LEVEL_INDEX(level, address)];
-
-       while (level > map_size) {
-               if (!IOMMU_PTE_PRESENT(*pte))
-                       return NULL;
-
-               level -= 1;
+       unsigned int i, last_page = dom->aperture_size >> PAGE_SHIFT;
 
-               pte = IOMMU_PTE_PAGE(*pte);
-               pte = &pte[PM_LEVEL_INDEX(level, address)];
+       if (start_page + pages > last_page)
+               pages = last_page - start_page;
 
-               if ((PM_PTE_LEVEL(*pte) == 0) && level != map_size) {
-                       pte = NULL;
-                       break;
-               }
+       for (i = start_page; i < start_page + pages; ++i) {
+               int index = i / APERTURE_RANGE_PAGES;
+               int page  = i % APERTURE_RANGE_PAGES;
+               __set_bit(page, dom->aperture[index]->bitmap);
        }
-
-       return pte;
 }
 
 /*
@@ -775,11 +938,11 @@ static u64 *fetch_pte(struct protection_domain *domain,
  * aperture in case of dma_ops domain allocation or address allocation
  * failure.
  */
-static int alloc_new_range(struct amd_iommu *iommu,
-                          struct dma_ops_domain *dma_dom,
+static int alloc_new_range(struct dma_ops_domain *dma_dom,
                           bool populate, gfp_t gfp)
 {
        int index = dma_dom->aperture_size >> APERTURE_RANGE_SHIFT;
+       struct amd_iommu *iommu;
        int i;
 
 #ifdef CONFIG_IOMMU_STRESS
@@ -819,14 +982,17 @@ static int alloc_new_range(struct amd_iommu *iommu,
        dma_dom->aperture_size += APERTURE_RANGE_SIZE;
 
        /* Intialize the exclusion range if necessary */
-       if (iommu->exclusion_start &&
-           iommu->exclusion_start >= dma_dom->aperture[index]->offset &&
-           iommu->exclusion_start < dma_dom->aperture_size) {
-               unsigned long startpage = iommu->exclusion_start >> PAGE_SHIFT;
-               int pages = iommu_num_pages(iommu->exclusion_start,
-                                           iommu->exclusion_length,
-                                           PAGE_SIZE);
-               dma_ops_reserve_addresses(dma_dom, startpage, pages);
+       for_each_iommu(iommu) {
+               if (iommu->exclusion_start &&
+                   iommu->exclusion_start >= dma_dom->aperture[index]->offset
+                   && iommu->exclusion_start < dma_dom->aperture_size) {
+                       unsigned long startpage;
+                       int pages = iommu_num_pages(iommu->exclusion_start,
+                                                   iommu->exclusion_length,
+                                                   PAGE_SIZE);
+                       startpage = iommu->exclusion_start >> PAGE_SHIFT;
+                       dma_ops_reserve_addresses(dma_dom, startpage, pages);
+               }
        }
 
        /*
@@ -928,7 +1094,7 @@ static unsigned long dma_ops_alloc_addresses(struct device *dev,
        }
 
        if (unlikely(address == -1))
-               address = bad_dma_address;
+               address = DMA_ERROR_CODE;
 
        WARN_ON((address + (PAGE_SIZE*pages)) > dom->aperture_size);
 
@@ -973,6 +1139,31 @@ static void dma_ops_free_addresses(struct dma_ops_domain *dom,
  *
  ****************************************************************************/
 
+/*
+ * This function adds a protection domain to the global protection domain list
+ */
+static void add_domain_to_list(struct protection_domain *domain)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&amd_iommu_pd_lock, flags);
+       list_add(&domain->list, &amd_iommu_pd_list);
+       spin_unlock_irqrestore(&amd_iommu_pd_lock, flags);
+}
+
+/*
+ * This function removes a protection domain to the global
+ * protection domain list
+ */
+static void del_domain_from_list(struct protection_domain *domain)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&amd_iommu_pd_lock, flags);
+       list_del(&domain->list);
+       spin_unlock_irqrestore(&amd_iommu_pd_lock, flags);
+}
+
 static u16 domain_id_alloc(void)
 {
        unsigned long flags;
@@ -1000,26 +1191,6 @@ static void domain_id_free(int id)
        write_unlock_irqrestore(&amd_iommu_devtable_lock, flags);
 }
 
-/*
- * Used to reserve address ranges in the aperture (e.g. for exclusion
- * ranges.
- */
-static void dma_ops_reserve_addresses(struct dma_ops_domain *dom,
-                                     unsigned long start_page,
-                                     unsigned int pages)
-{
-       unsigned int i, last_page = dom->aperture_size >> PAGE_SHIFT;
-
-       if (start_page + pages > last_page)
-               pages = last_page - start_page;
-
-       for (i = start_page; i < start_page + pages; ++i) {
-               int index = i / APERTURE_RANGE_PAGES;
-               int page  = i % APERTURE_RANGE_PAGES;
-               __set_bit(page, dom->aperture[index]->bitmap);
-       }
-}
-
 static void free_pagetable(struct protection_domain *domain)
 {
        int i, j;
@@ -1061,6 +1232,8 @@ static void dma_ops_domain_free(struct dma_ops_domain *dom)
        if (!dom)
                return;
 
+       del_domain_from_list(&dom->domain);
+
        free_pagetable(&dom->domain);
 
        for (i = 0; i < APERTURE_MAX_RANGES; ++i) {
@@ -1078,7 +1251,7 @@ static void dma_ops_domain_free(struct dma_ops_domain *dom)
  * It also intializes the page table and the address allocator data
  * structures required for the dma_ops interface
  */
-static struct dma_ops_domain *dma_ops_domain_alloc(struct amd_iommu *iommu)
+static struct dma_ops_domain *dma_ops_domain_alloc(void)
 {
        struct dma_ops_domain *dma_dom;
 
@@ -1091,6 +1264,7 @@ static struct dma_ops_domain *dma_ops_domain_alloc(struct amd_iommu *iommu)
        dma_dom->domain.id = domain_id_alloc();
        if (dma_dom->domain.id == 0)
                goto free_dma_dom;
+       INIT_LIST_HEAD(&dma_dom->domain.dev_list);
        dma_dom->domain.mode = PAGE_MODE_2_LEVEL;
        dma_dom->domain.pt_root = (void *)get_zeroed_page(GFP_KERNEL);
        dma_dom->domain.flags = PD_DMA_OPS_MASK;
@@ -1101,7 +1275,9 @@ static struct dma_ops_domain *dma_ops_domain_alloc(struct amd_iommu *iommu)
        dma_dom->need_flush = false;
        dma_dom->target_dev = 0xffff;
 
-       if (alloc_new_range(iommu, dma_dom, true, GFP_KERNEL))
+       add_domain_to_list(&dma_dom->domain);
+
+       if (alloc_new_range(dma_dom, true, GFP_KERNEL))
                goto free_dma_dom;
 
        /*
@@ -1129,22 +1305,6 @@ static bool dma_ops_domain(struct protection_domain *domain)
        return domain->flags & PD_DMA_OPS_MASK;
 }
 
-/*
- * Find out the protection domain structure for a given PCI device. This
- * will give us the pointer to the page table root for example.
- */
-static struct protection_domain *domain_for_device(u16 devid)
-{
-       struct protection_domain *dom;
-       unsigned long flags;
-
-       read_lock_irqsave(&amd_iommu_devtable_lock, flags);
-       dom = amd_iommu_pd_table[devid];
-       read_unlock_irqrestore(&amd_iommu_devtable_lock, flags);
-
-       return dom;
-}
-
 static void set_dte_entry(u16 devid, struct protection_domain *domain)
 {
        u64 pte_root = virt_to_phys(domain->pt_root);
@@ -1156,42 +1316,123 @@ static void set_dte_entry(u16 devid, struct protection_domain *domain)
        amd_iommu_dev_table[devid].data[2] = domain->id;
        amd_iommu_dev_table[devid].data[1] = upper_32_bits(pte_root);
        amd_iommu_dev_table[devid].data[0] = lower_32_bits(pte_root);
+}
+
+static void clear_dte_entry(u16 devid)
+{
+       /* remove entry from the device table seen by the hardware */
+       amd_iommu_dev_table[devid].data[0] = IOMMU_PTE_P | IOMMU_PTE_TV;
+       amd_iommu_dev_table[devid].data[1] = 0;
+       amd_iommu_dev_table[devid].data[2] = 0;
+
+       amd_iommu_apply_erratum_63(devid);
+}
+
+static void do_attach(struct device *dev, struct protection_domain *domain)
+{
+       struct iommu_dev_data *dev_data;
+       struct amd_iommu *iommu;
+       u16 devid;
 
-       amd_iommu_pd_table[devid] = domain;
+       devid    = get_device_id(dev);
+       iommu    = amd_iommu_rlookup_table[devid];
+       dev_data = get_dev_data(dev);
+
+       /* Update data structures */
+       dev_data->domain = domain;
+       list_add(&dev_data->list, &domain->dev_list);
+       set_dte_entry(devid, domain);
+
+       /* Do reference counting */
+       domain->dev_iommu[iommu->index] += 1;
+       domain->dev_cnt                 += 1;
+
+       /* Flush the DTE entry */
+       iommu_flush_device(dev);
+}
+
+static void do_detach(struct device *dev)
+{
+       struct iommu_dev_data *dev_data;
+       struct amd_iommu *iommu;
+       u16 devid;
+
+       devid    = get_device_id(dev);
+       iommu    = amd_iommu_rlookup_table[devid];
+       dev_data = get_dev_data(dev);
+
+       /* decrease reference counters */
+       dev_data->domain->dev_iommu[iommu->index] -= 1;
+       dev_data->domain->dev_cnt                 -= 1;
+
+       /* Update data structures */
+       dev_data->domain = NULL;
+       list_del(&dev_data->list);
+       clear_dte_entry(devid);
+
+       /* Flush the DTE entry */
+       iommu_flush_device(dev);
 }
 
 /*
  * If a device is not yet associated with a domain, this function does
  * assigns it visible for the hardware
  */
-static void __attach_device(struct amd_iommu *iommu,
-                           struct protection_domain *domain,
-                           u16 devid)
+static int __attach_device(struct device *dev,
+                          struct protection_domain *domain)
 {
+       struct iommu_dev_data *dev_data, *alias_data;
+
+       dev_data   = get_dev_data(dev);
+       alias_data = get_dev_data(dev_data->alias);
+
+       if (!alias_data)
+               return -EINVAL;
+
        /* lock domain */
        spin_lock(&domain->lock);
 
-       /* update DTE entry */
-       set_dte_entry(devid, domain);
+       /* Some sanity checks */
+       if (alias_data->domain != NULL &&
+           alias_data->domain != domain)
+               return -EBUSY;
+
+       if (dev_data->domain != NULL &&
+           dev_data->domain != domain)
+               return -EBUSY;
+
+       /* Do real assignment */
+       if (dev_data->alias != dev) {
+               alias_data = get_dev_data(dev_data->alias);
+               if (alias_data->domain == NULL)
+                       do_attach(dev_data->alias, domain);
+
+               atomic_inc(&alias_data->bind);
+       }
+
+       if (dev_data->domain == NULL)
+               do_attach(dev, domain);
 
-       domain->dev_cnt += 1;
+       atomic_inc(&dev_data->bind);
 
        /* ready */
        spin_unlock(&domain->lock);
+
+       return 0;
 }
 
 /*
  * If a device is not yet associated with a domain, this function does
  * assigns it visible for the hardware
  */
-static void attach_device(struct amd_iommu *iommu,
-                         struct protection_domain *domain,
-                         u16 devid)
+static int attach_device(struct device *dev,
+                        struct protection_domain *domain)
 {
        unsigned long flags;
+       int ret;
 
        write_lock_irqsave(&amd_iommu_devtable_lock, flags);
-       __attach_device(iommu, domain, devid);
+       ret = __attach_device(dev, domain);
        write_unlock_irqrestore(&amd_iommu_devtable_lock, flags);
 
        /*
@@ -1199,98 +1440,125 @@ static void attach_device(struct amd_iommu *iommu,
         * left the caches in the IOMMU dirty. So we have to flush
         * here to evict all dirty stuff.
         */
-       iommu_queue_inv_dev_entry(iommu, devid);
-       iommu_flush_tlb_pde(iommu, domain->id);
+       iommu_flush_tlb_pde(domain);
+
+       return ret;
 }
 
 /*
  * Removes a device from a protection domain (unlocked)
  */
-static void __detach_device(struct protection_domain *domain, u16 devid)
+static void __detach_device(struct device *dev)
 {
+       struct iommu_dev_data *dev_data = get_dev_data(dev);
+       struct iommu_dev_data *alias_data;
+       unsigned long flags;
 
-       /* lock domain */
-       spin_lock(&domain->lock);
-
-       /* remove domain from the lookup table */
-       amd_iommu_pd_table[devid] = NULL;
+       BUG_ON(!dev_data->domain);
 
-       /* remove entry from the device table seen by the hardware */
-       amd_iommu_dev_table[devid].data[0] = IOMMU_PTE_P | IOMMU_PTE_TV;
-       amd_iommu_dev_table[devid].data[1] = 0;
-       amd_iommu_dev_table[devid].data[2] = 0;
+       spin_lock_irqsave(&dev_data->domain->lock, flags);
 
-       amd_iommu_apply_erratum_63(devid);
+       if (dev_data->alias != dev) {
+               alias_data = get_dev_data(dev_data->alias);
+               if (atomic_dec_and_test(&alias_data->bind))
+                       do_detach(dev_data->alias);
+       }
 
-       /* decrease reference counter */
-       domain->dev_cnt -= 1;
+       if (atomic_dec_and_test(&dev_data->bind))
+               do_detach(dev);
 
-       /* ready */
-       spin_unlock(&domain->lock);
+       spin_unlock_irqrestore(&dev_data->domain->lock, flags);
 
        /*
         * If we run in passthrough mode the device must be assigned to the
         * passthrough domain if it is detached from any other domain
         */
-       if (iommu_pass_through) {
-               struct amd_iommu *iommu = amd_iommu_rlookup_table[devid];
-               __attach_device(iommu, pt_domain, devid);
-       }
+       if (iommu_pass_through && dev_data->domain == NULL)
+               __attach_device(dev, pt_domain);
 }
 
 /*
  * Removes a device from a protection domain (with devtable_lock held)
  */
-static void detach_device(struct protection_domain *domain, u16 devid)
+static void detach_device(struct device *dev)
 {
        unsigned long flags;
 
        /* lock device table */
        write_lock_irqsave(&amd_iommu_devtable_lock, flags);
-       __detach_device(domain, devid);
+       __detach_device(dev);
        write_unlock_irqrestore(&amd_iommu_devtable_lock, flags);
 }
 
+/*
+ * Find out the protection domain structure for a given PCI device. This
+ * will give us the pointer to the page table root for example.
+ */
+static struct protection_domain *domain_for_device(struct device *dev)
+{
+       struct protection_domain *dom;
+       struct iommu_dev_data *dev_data, *alias_data;
+       unsigned long flags;
+       u16 devid, alias;
+
+       devid      = get_device_id(dev);
+       alias      = amd_iommu_alias_table[devid];
+       dev_data   = get_dev_data(dev);
+       alias_data = get_dev_data(dev_data->alias);
+       if (!alias_data)
+               return NULL;
+
+       read_lock_irqsave(&amd_iommu_devtable_lock, flags);
+       dom = dev_data->domain;
+       if (dom == NULL &&
+           alias_data->domain != NULL) {
+               __attach_device(dev, alias_data->domain);
+               dom = alias_data->domain;
+       }
+
+       read_unlock_irqrestore(&amd_iommu_devtable_lock, flags);
+
+       return dom;
+}
+
 static int device_change_notifier(struct notifier_block *nb,
                                  unsigned long action, void *data)
 {
        struct device *dev = data;
-       struct pci_dev *pdev = to_pci_dev(dev);
-       u16 devid = calc_devid(pdev->bus->number, pdev->devfn);
+       u16 devid;
        struct protection_domain *domain;
        struct dma_ops_domain *dma_domain;
        struct amd_iommu *iommu;
        unsigned long flags;
 
-       if (devid > amd_iommu_last_bdf)
-               goto out;
-
-       devid = amd_iommu_alias_table[devid];
-
-       iommu = amd_iommu_rlookup_table[devid];
-       if (iommu == NULL)
-               goto out;
-
-       domain = domain_for_device(devid);
+       if (!check_device(dev))
+               return 0;
 
-       if (domain && !dma_ops_domain(domain))
-               WARN_ONCE(1, "AMD IOMMU WARNING: device %s already bound "
-                         "to a non-dma-ops domain\n", dev_name(dev));
+       devid  = get_device_id(dev);
+       iommu  = amd_iommu_rlookup_table[devid];
 
        switch (action) {
        case BUS_NOTIFY_UNBOUND_DRIVER:
+
+               domain = domain_for_device(dev);
+
                if (!domain)
                        goto out;
                if (iommu_pass_through)
                        break;
-               detach_device(domain, devid);
+               detach_device(dev);
                break;
        case BUS_NOTIFY_ADD_DEVICE:
+
+               iommu_init_device(dev);
+
+               domain = domain_for_device(dev);
+
                /* allocate a protection domain if a device is added */
                dma_domain = find_protection_domain(devid);
                if (dma_domain)
                        goto out;
-               dma_domain = dma_ops_domain_alloc(iommu);
+               dma_domain = dma_ops_domain_alloc();
                if (!dma_domain)
                        goto out;
                dma_domain->target_dev = devid;
@@ -1300,11 +1568,15 @@ static int device_change_notifier(struct notifier_block *nb,
                spin_unlock_irqrestore(&iommu_pd_list_lock, flags);
 
                break;
+       case BUS_NOTIFY_DEL_DEVICE:
+
+               iommu_uninit_device(dev);
+
        default:
                goto out;
        }
 
-       iommu_queue_inv_dev_entry(iommu, devid);
+       iommu_flush_device(dev);
        iommu_completion_wait(iommu);
 
 out:
@@ -1321,44 +1593,6 @@ static struct notifier_block device_nb = {
  *
  *****************************************************************************/
 
-/*
- * This function checks if the driver got a valid device from the caller to
- * avoid dereferencing invalid pointers.
- */
-static bool check_device(struct device *dev)
-{
-       if (!dev || !dev->dma_mask)
-               return false;
-
-       return true;
-}
-
-/*
- * In this function the list of preallocated protection domains is traversed to
- * find the domain for a specific device
- */
-static struct dma_ops_domain *find_protection_domain(u16 devid)
-{
-       struct dma_ops_domain *entry, *ret = NULL;
-       unsigned long flags;
-
-       if (list_empty(&iommu_pd_list))
-               return NULL;
-
-       spin_lock_irqsave(&iommu_pd_list_lock, flags);
-
-       list_for_each_entry(entry, &iommu_pd_list, list) {
-               if (entry->target_dev == devid) {
-                       ret = entry;
-                       break;
-               }
-       }
-
-       spin_unlock_irqrestore(&iommu_pd_list_lock, flags);
-
-       return ret;
-}
-
 /*
  * In the dma_ops path we only have the struct device. This function
  * finds the corresponding IOMMU, the protection domain and the
@@ -1366,62 +1600,40 @@ static struct dma_ops_domain *find_protection_domain(u16 devid)
  * If the device is not yet associated with a domain this is also done
  * in this function.
  */
-static int get_device_resources(struct device *dev,
-                               struct amd_iommu **iommu,
-                               struct protection_domain **domain,
-                               u16 *bdf)
+static struct protection_domain *get_domain(struct device *dev)
 {
+       struct protection_domain *domain;
        struct dma_ops_domain *dma_dom;
-       struct pci_dev *pcidev;
-       u16 _bdf;
-
-       *iommu = NULL;
-       *domain = NULL;
-       *bdf = 0xffff;
-
-       if (dev->bus != &pci_bus_type)
-               return 0;
-
-       pcidev = to_pci_dev(dev);
-       _bdf = calc_devid(pcidev->bus->number, pcidev->devfn);
+       u16 devid = get_device_id(dev);
 
-       /* device not translated by any IOMMU in the system? */
-       if (_bdf > amd_iommu_last_bdf)
-               return 0;
+       if (!check_device(dev))
+               return ERR_PTR(-EINVAL);
 
-       *bdf = amd_iommu_alias_table[_bdf];
+       domain = domain_for_device(dev);
+       if (domain != NULL && !dma_ops_domain(domain))
+               return ERR_PTR(-EBUSY);
 
-       *iommu = amd_iommu_rlookup_table[*bdf];
-       if (*iommu == NULL)
-               return 0;
-       *domain = domain_for_device(*bdf);
-       if (*domain == NULL) {
-               dma_dom = find_protection_domain(*bdf);
-               if (!dma_dom)
-                       dma_dom = (*iommu)->default_dom;
-               *domain = &dma_dom->domain;
-               attach_device(*iommu, *domain, *bdf);
-               DUMP_printk("Using protection domain %d for device %s\n",
-                           (*domain)->id, dev_name(dev));
-       }
+       if (domain != NULL)
+               return domain;
 
-       if (domain_for_device(_bdf) == NULL)
-               attach_device(*iommu, *domain, _bdf);
+       /* Device not bount yet - bind it */
+       dma_dom = find_protection_domain(devid);
+       if (!dma_dom)
+               dma_dom = amd_iommu_rlookup_table[devid]->default_dom;
+       attach_device(dev, &dma_dom->domain);
+       DUMP_printk("Using protection domain %d for device %s\n",
+                   dma_dom->domain.id, dev_name(dev));
 
-       return 1;
+       return &dma_dom->domain;
 }
 
 static void update_device_table(struct protection_domain *domain)
 {
-       unsigned long flags;
-       int i;
+       struct iommu_dev_data *dev_data;
 
-       for (i = 0; i <= amd_iommu_last_bdf; ++i) {
-               if (amd_iommu_pd_table[i] != domain)
-                       continue;
-               write_lock_irqsave(&amd_iommu_devtable_lock, flags);
-               set_dte_entry(i, domain);
-               write_unlock_irqrestore(&amd_iommu_devtable_lock, flags);
+       list_for_each_entry(dev_data, &domain->dev_list, list) {
+               u16 devid = get_device_id(dev_data->dev);
+               set_dte_entry(devid, domain);
        }
 }
 
@@ -1431,75 +1643,12 @@ static void update_domain(struct protection_domain *domain)
                return;
 
        update_device_table(domain);
-       flush_devices_by_domain(domain);
-       iommu_flush_domain(domain->id);
+       iommu_flush_domain_devices(domain);
+       iommu_flush_tlb_pde(domain);
 
        domain->updated = false;
 }
 
-/*
- * This function is used to add another level to an IO page table. Adding
- * another level increases the size of the address space by 9 bits to a size up
- * to 64 bits.
- */
-static bool increase_address_space(struct protection_domain *domain,
-                                  gfp_t gfp)
-{
-       u64 *pte;
-
-       if (domain->mode == PAGE_MODE_6_LEVEL)
-               /* address space already 64 bit large */
-               return false;
-
-       pte = (void *)get_zeroed_page(gfp);
-       if (!pte)
-               return false;
-
-       *pte             = PM_LEVEL_PDE(domain->mode,
-                                       virt_to_phys(domain->pt_root));
-       domain->pt_root  = pte;
-       domain->mode    += 1;
-       domain->updated  = true;
-
-       return true;
-}
-
-static u64 *alloc_pte(struct protection_domain *domain,
-                     unsigned long address,
-                     int end_lvl,
-                     u64 **pte_page,
-                     gfp_t gfp)
-{
-       u64 *pte, *page;
-       int level;
-
-       while (address > PM_LEVEL_SIZE(domain->mode))
-               increase_address_space(domain, gfp);
-
-       level =  domain->mode - 1;
-       pte   = &domain->pt_root[PM_LEVEL_INDEX(level, address)];
-
-       while (level > end_lvl) {
-               if (!IOMMU_PTE_PRESENT(*pte)) {
-                       page = (u64 *)get_zeroed_page(gfp);
-                       if (!page)
-                               return NULL;
-                       *pte = PM_LEVEL_PDE(level, virt_to_phys(page));
-               }
-
-               level -= 1;
-
-               pte = IOMMU_PTE_PAGE(*pte);
-
-               if (pte_page && level == end_lvl)
-                       *pte_page = pte;
-
-               pte = &pte[PM_LEVEL_INDEX(level, address)];
-       }
-
-       return pte;
-}
-
 /*
  * This function fetches the PTE for a given address in the aperture
  */
@@ -1530,8 +1679,7 @@ static u64* dma_ops_get_pte(struct dma_ops_domain *dom,
  * This is the generic map function. It maps one 4kb page at paddr to
  * the given address in the DMA address space for the domain.
  */
-static dma_addr_t dma_ops_domain_map(struct amd_iommu *iommu,
-                                    struct dma_ops_domain *dom,
+static dma_addr_t dma_ops_domain_map(struct dma_ops_domain *dom,
                                     unsigned long address,
                                     phys_addr_t paddr,
                                     int direction)
@@ -1544,7 +1692,7 @@ static dma_addr_t dma_ops_domain_map(struct amd_iommu *iommu,
 
        pte  = dma_ops_get_pte(dom, address);
        if (!pte)
-               return bad_dma_address;
+               return DMA_ERROR_CODE;
 
        __pte = paddr | IOMMU_PTE_P | IOMMU_PTE_FC;
 
@@ -1565,8 +1713,7 @@ static dma_addr_t dma_ops_domain_map(struct amd_iommu *iommu,
 /*
  * The generic unmapping function for on page in the DMA address space.
  */
-static void dma_ops_domain_unmap(struct amd_iommu *iommu,
-                                struct dma_ops_domain *dom,
+static void dma_ops_domain_unmap(struct dma_ops_domain *dom,
                                 unsigned long address)
 {
        struct aperture_range *aperture;
@@ -1597,7 +1744,6 @@ static void dma_ops_domain_unmap(struct amd_iommu *iommu,
  * Must be called with the domain lock held.
  */
 static dma_addr_t __map_single(struct device *dev,
-                              struct amd_iommu *iommu,
                               struct dma_ops_domain *dma_dom,
                               phys_addr_t paddr,
                               size_t size,
@@ -1625,7 +1771,7 @@ static dma_addr_t __map_single(struct device *dev,
 retry:
        address = dma_ops_alloc_addresses(dev, dma_dom, pages, align_mask,
                                          dma_mask);
-       if (unlikely(address == bad_dma_address)) {
+       if (unlikely(address == DMA_ERROR_CODE)) {
                /*
                 * setting next_address here will let the address
                 * allocator only scan the new allocated range in the
@@ -1633,7 +1779,7 @@ retry:
                 */
                dma_dom->next_address = dma_dom->aperture_size;
 
-               if (alloc_new_range(iommu, dma_dom, false, GFP_ATOMIC))
+               if (alloc_new_range(dma_dom, false, GFP_ATOMIC))
                        goto out;
 
                /*
@@ -1645,8 +1791,8 @@ retry:
 
        start = address;
        for (i = 0; i < pages; ++i) {
-               ret = dma_ops_domain_map(iommu, dma_dom, start, paddr, dir);
-               if (ret == bad_dma_address)
+               ret = dma_ops_domain_map(dma_dom, start, paddr, dir);
+               if (ret == DMA_ERROR_CODE)
                        goto out_unmap;
 
                paddr += PAGE_SIZE;
@@ -1657,10 +1803,10 @@ retry:
        ADD_STATS_COUNTER(alloced_io_mem, size);
 
        if (unlikely(dma_dom->need_flush && !amd_iommu_unmap_flush)) {
-               iommu_flush_tlb(iommu, dma_dom->domain.id);
+               iommu_flush_tlb(&dma_dom->domain);
                dma_dom->need_flush = false;
-       } else if (unlikely(iommu_has_npcache(iommu)))
-               iommu_flush_pages(iommu, dma_dom->domain.id, address, size);
+       } else if (unlikely(amd_iommu_np_cache))
+               iommu_flush_pages(&dma_dom->domain, address, size);
 
 out:
        return address;
@@ -1669,20 +1815,19 @@ out_unmap:
 
        for (--i; i >= 0; --i) {
                start -= PAGE_SIZE;
-               dma_ops_domain_unmap(iommu, dma_dom, start);
+               dma_ops_domain_unmap(dma_dom, start);
        }
 
        dma_ops_free_addresses(dma_dom, address, pages);
 
-       return bad_dma_address;
+       return DMA_ERROR_CODE;
 }
 
 /*
  * Does the reverse of the __map_single function. Must be called with
  * the domain lock held too
  */
-static void __unmap_single(struct amd_iommu *iommu,
-                          struct dma_ops_domain *dma_dom,
+static void __unmap_single(struct dma_ops_domain *dma_dom,
                           dma_addr_t dma_addr,
                           size_t size,
                           int dir)
@@ -1690,7 +1835,7 @@ static void __unmap_single(struct amd_iommu *iommu,
        dma_addr_t i, start;
        unsigned int pages;
 
-       if ((dma_addr == bad_dma_address) ||
+       if ((dma_addr == DMA_ERROR_CODE) ||
            (dma_addr + size > dma_dom->aperture_size))
                return;
 
@@ -1699,7 +1844,7 @@ static void __unmap_single(struct amd_iommu *iommu,
        start = dma_addr;
 
        for (i = 0; i < pages; ++i) {
-               dma_ops_domain_unmap(iommu, dma_dom, start);
+               dma_ops_domain_unmap(dma_dom, start);
                start += PAGE_SIZE;
        }
 
@@ -1708,7 +1853,7 @@ static void __unmap_single(struct amd_iommu *iommu,
        dma_ops_free_addresses(dma_dom, dma_addr, pages);
 
        if (amd_iommu_unmap_flush || dma_dom->need_flush) {
-               iommu_flush_pages(iommu, dma_dom->domain.id, dma_addr, size);
+               iommu_flush_pages(&dma_dom->domain, dma_addr, size);
                dma_dom->need_flush = false;
        }
 }
@@ -1722,36 +1867,29 @@ static dma_addr_t map_page(struct device *dev, struct page *page,
                           struct dma_attrs *attrs)
 {
        unsigned long flags;
-       struct amd_iommu *iommu;
        struct protection_domain *domain;
-       u16 devid;
        dma_addr_t addr;
        u64 dma_mask;
        phys_addr_t paddr = page_to_phys(page) + offset;
 
        INC_STATS_COUNTER(cnt_map_single);
 
-       if (!check_device(dev))
-               return bad_dma_address;
-
-       dma_mask = *dev->dma_mask;
-
-       get_device_resources(dev, &iommu, &domain, &devid);
-
-       if (iommu == NULL || domain == NULL)
-               /* device not handled by any AMD IOMMU */
+       domain = get_domain(dev);
+       if (PTR_ERR(domain) == -EINVAL)
                return (dma_addr_t)paddr;
+       else if (IS_ERR(domain))
+               return DMA_ERROR_CODE;
 
-       if (!dma_ops_domain(domain))
-               return bad_dma_address;
+       dma_mask = *dev->dma_mask;
 
        spin_lock_irqsave(&domain->lock, flags);
-       addr = __map_single(dev, iommu, domain->priv, paddr, size, dir, false,
+
+       addr = __map_single(dev, domain->priv, paddr, size, dir, false,
                            dma_mask);
-       if (addr == bad_dma_address)
+       if (addr == DMA_ERROR_CODE)
                goto out;
 
-       iommu_completion_wait(iommu);
+       iommu_flush_complete(domain);
 
 out:
        spin_unlock_irqrestore(&domain->lock, flags);
@@ -1766,25 +1904,19 @@ static void unmap_page(struct device *dev, dma_addr_t dma_addr, size_t size,
                       enum dma_data_direction dir, struct dma_attrs *attrs)
 {
        unsigned long flags;
-       struct amd_iommu *iommu;
        struct protection_domain *domain;
-       u16 devid;
 
        INC_STATS_COUNTER(cnt_unmap_single);
 
-       if (!check_device(dev) ||
-           !get_device_resources(dev, &iommu, &domain, &devid))
-               /* device not handled by any AMD IOMMU */
-               return;
-
-       if (!dma_ops_domain(domain))
+       domain = get_domain(dev);
+       if (IS_ERR(domain))
                return;
 
        spin_lock_irqsave(&domain->lock, flags);
 
-       __unmap_single(iommu, domain->priv, dma_addr, size, dir);
+       __unmap_single(domain->priv, dma_addr, size, dir);
 
-       iommu_completion_wait(iommu);
+       iommu_flush_complete(domain);
 
        spin_unlock_irqrestore(&domain->lock, flags);
 }
@@ -1816,9 +1948,7 @@ static int map_sg(struct device *dev, struct scatterlist *sglist,
                  struct dma_attrs *attrs)
 {
        unsigned long flags;
-       struct amd_iommu *iommu;
        struct protection_domain *domain;
-       u16 devid;
        int i;
        struct scatterlist *s;
        phys_addr_t paddr;
@@ -1827,25 +1957,20 @@ static int map_sg(struct device *dev, struct scatterlist *sglist,
 
        INC_STATS_COUNTER(cnt_map_sg);
 
-       if (!check_device(dev))
+       domain = get_domain(dev);
+       if (PTR_ERR(domain) == -EINVAL)
+               return map_sg_no_iommu(dev, sglist, nelems, dir);
+       else if (IS_ERR(domain))
                return 0;
 
        dma_mask = *dev->dma_mask;
 
-       get_device_resources(dev, &iommu, &domain, &devid);
-
-       if (!iommu || !domain)
-               return map_sg_no_iommu(dev, sglist, nelems, dir);
-
-       if (!dma_ops_domain(domain))
-               return 0;
-
        spin_lock_irqsave(&domain->lock, flags);
 
        for_each_sg(sglist, s, nelems, i) {
                paddr = sg_phys(s);
 
-               s->dma_address = __map_single(dev, iommu, domain->priv,
+               s->dma_address = __map_single(dev, domain->priv,
                                              paddr, s->length, dir, false,
                                              dma_mask);
 
@@ -1856,7 +1981,7 @@ static int map_sg(struct device *dev, struct scatterlist *sglist,
                        goto unmap;
        }
 
-       iommu_completion_wait(iommu);
+       iommu_flush_complete(domain);
 
 out:
        spin_unlock_irqrestore(&domain->lock, flags);
@@ -1865,7 +1990,7 @@ out:
 unmap:
        for_each_sg(sglist, s, mapped_elems, i) {
                if (s->dma_address)
-                       __unmap_single(iommu, domain->priv, s->dma_address,
+                       __unmap_single(domain->priv, s->dma_address,
                                       s->dma_length, dir);
                s->dma_address = s->dma_length = 0;
        }
@@ -1884,30 +2009,25 @@ static void unmap_sg(struct device *dev, struct scatterlist *sglist,
                     struct dma_attrs *attrs)
 {
        unsigned long flags;
-       struct amd_iommu *iommu;
        struct protection_domain *domain;
        struct scatterlist *s;
-       u16 devid;
        int i;
 
        INC_STATS_COUNTER(cnt_unmap_sg);
 
-       if (!check_device(dev) ||
-           !get_device_resources(dev, &iommu, &domain, &devid))
-               return;
-
-       if (!dma_ops_domain(domain))
+       domain = get_domain(dev);
+       if (IS_ERR(domain))
                return;
 
        spin_lock_irqsave(&domain->lock, flags);
 
        for_each_sg(sglist, s, nelems, i) {
-               __unmap_single(iommu, domain->priv, s->dma_address,
+               __unmap_single(domain->priv, s->dma_address,
                               s->dma_length, dir);
                s->dma_address = s->dma_length = 0;
        }
 
-       iommu_completion_wait(iommu);
+       iommu_flush_complete(domain);
 
        spin_unlock_irqrestore(&domain->lock, flags);
 }
@@ -1920,49 +2040,44 @@ static void *alloc_coherent(struct device *dev, size_t size,
 {
        unsigned long flags;
        void *virt_addr;
-       struct amd_iommu *iommu;
        struct protection_domain *domain;
-       u16 devid;
        phys_addr_t paddr;
        u64 dma_mask = dev->coherent_dma_mask;
 
        INC_STATS_COUNTER(cnt_alloc_coherent);
 
-       if (!check_device(dev))
+       domain = get_domain(dev);
+       if (PTR_ERR(domain) == -EINVAL) {
+               virt_addr = (void *)__get_free_pages(flag, get_order(size));
+               *dma_addr = __pa(virt_addr);
+               return virt_addr;
+       } else if (IS_ERR(domain))
                return NULL;
 
-       if (!get_device_resources(dev, &iommu, &domain, &devid))
-               flag &= ~(__GFP_DMA | __GFP_HIGHMEM | __GFP_DMA32);
+       dma_mask  = dev->coherent_dma_mask;
+       flag     &= ~(__GFP_DMA | __GFP_HIGHMEM | __GFP_DMA32);
+       flag     |= __GFP_ZERO;
 
-       flag |= __GFP_ZERO;
        virt_addr = (void *)__get_free_pages(flag, get_order(size));
        if (!virt_addr)
                return NULL;
 
        paddr = virt_to_phys(virt_addr);
 
-       if (!iommu || !domain) {
-               *dma_addr = (dma_addr_t)paddr;
-               return virt_addr;
-       }
-
-       if (!dma_ops_domain(domain))
-               goto out_free;
-
        if (!dma_mask)
                dma_mask = *dev->dma_mask;
 
        spin_lock_irqsave(&domain->lock, flags);
 
-       *dma_addr = __map_single(dev, iommu, domain->priv, paddr,
+       *dma_addr = __map_single(dev, domain->priv, paddr,
                                 size, DMA_BIDIRECTIONAL, true, dma_mask);
 
-       if (*dma_addr == bad_dma_address) {
+       if (*dma_addr == DMA_ERROR_CODE) {
                spin_unlock_irqrestore(&domain->lock, flags);
                goto out_free;
        }
 
-       iommu_completion_wait(iommu);
+       iommu_flush_complete(domain);
 
        spin_unlock_irqrestore(&domain->lock, flags);
 
@@ -1982,28 +2097,19 @@ static void free_coherent(struct device *dev, size_t size,
                          void *virt_addr, dma_addr_t dma_addr)
 {
        unsigned long flags;
-       struct amd_iommu *iommu;
        struct protection_domain *domain;
-       u16 devid;
 
        INC_STATS_COUNTER(cnt_free_coherent);
 
-       if (!check_device(dev))
-               return;
-
-       get_device_resources(dev, &iommu, &domain, &devid);
-
-       if (!iommu || !domain)
-               goto free_mem;
-
-       if (!dma_ops_domain(domain))
+       domain = get_domain(dev);
+       if (IS_ERR(domain))
                goto free_mem;
 
        spin_lock_irqsave(&domain->lock, flags);
 
-       __unmap_single(iommu, domain->priv, dma_addr, size, DMA_BIDIRECTIONAL);
+       __unmap_single(domain->priv, dma_addr, size, DMA_BIDIRECTIONAL);
 
-       iommu_completion_wait(iommu);
+       iommu_flush_complete(domain);
 
        spin_unlock_irqrestore(&domain->lock, flags);
 
@@ -2017,22 +2123,7 @@ free_mem:
  */
 static int amd_iommu_dma_supported(struct device *dev, u64 mask)
 {
-       u16 bdf;
-       struct pci_dev *pcidev;
-
-       /* No device or no PCI device */
-       if (!dev || dev->bus != &pci_bus_type)
-               return 0;
-
-       pcidev = to_pci_dev(dev);
-
-       bdf = calc_devid(pcidev->bus->number, pcidev->devfn);
-
-       /* Out of our scope? */
-       if (bdf > amd_iommu_last_bdf)
-               return 0;
-
-       return 1;
+       return check_device(dev);
 }
 
 /*
@@ -2046,25 +2137,30 @@ static void prealloc_protection_domains(void)
 {
        struct pci_dev *dev = NULL;
        struct dma_ops_domain *dma_dom;
-       struct amd_iommu *iommu;
        u16 devid;
 
        while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
-               devid = calc_devid(dev->bus->number, dev->devfn);
-               if (devid > amd_iommu_last_bdf)
-                       continue;
-               devid = amd_iommu_alias_table[devid];
-               if (domain_for_device(devid))
+
+               /* Do we handle this device? */
+               if (!check_device(&dev->dev))
                        continue;
-               iommu = amd_iommu_rlookup_table[devid];
-               if (!iommu)
+
+               iommu_init_device(&dev->dev);
+
+               /* Is there already any domain for it? */
+               if (domain_for_device(&dev->dev))
                        continue;
-               dma_dom = dma_ops_domain_alloc(iommu);
+
+               devid = get_device_id(&dev->dev);
+
+               dma_dom = dma_ops_domain_alloc();
                if (!dma_dom)
                        continue;
                init_unity_mappings_for_device(dma_dom, devid);
                dma_dom->target_dev = devid;
 
+               attach_device(&dev->dev, &dma_dom->domain);
+
                list_add_tail(&dma_dom->list, &iommu_pd_list);
        }
 }
@@ -2093,7 +2189,7 @@ int __init amd_iommu_init_dma_ops(void)
         * protection domain will be assigned to the default one.
         */
        for_each_iommu(iommu) {
-               iommu->default_dom = dma_ops_domain_alloc(iommu);
+               iommu->default_dom = dma_ops_domain_alloc();
                if (iommu->default_dom == NULL)
                        return -ENOMEM;
                iommu->default_dom->domain.flags |= PD_DEFAULT_MASK;
@@ -2103,15 +2199,12 @@ int __init amd_iommu_init_dma_ops(void)
        }
 
        /*
-        * If device isolation is enabled, pre-allocate the protection
-        * domains for each device.
+        * Pre-allocate the protection domains for each device.
         */
-       if (amd_iommu_isolate)
-               prealloc_protection_domains();
+       prealloc_protection_domains();
 
        iommu_detected = 1;
-       force_iommu = 1;
-       bad_dma_address = 0;
+       swiotlb = 0;
 #ifdef CONFIG_GART_IOMMU
        gart_iommu_aperture_disabled = 1;
        gart_iommu_aperture = 0;
@@ -2150,14 +2243,17 @@ free_domains:
 
 static void cleanup_domain(struct protection_domain *domain)
 {
+       struct iommu_dev_data *dev_data, *next;
        unsigned long flags;
-       u16 devid;
 
        write_lock_irqsave(&amd_iommu_devtable_lock, flags);
 
-       for (devid = 0; devid <= amd_iommu_last_bdf; ++devid)
-               if (amd_iommu_pd_table[devid] == domain)
-                       __detach_device(domain, devid);
+       list_for_each_entry_safe(dev_data, next, &domain->dev_list, list) {
+               struct device *dev = dev_data->dev;
+
+               do_detach(dev);
+               atomic_set(&dev_data->bind, 0);
+       }
 
        write_unlock_irqrestore(&amd_iommu_devtable_lock, flags);
 }
@@ -2167,6 +2263,8 @@ static void protection_domain_free(struct protection_domain *domain)
        if (!domain)
                return;
 
+       del_domain_from_list(domain);
+
        if (domain->id)
                domain_id_free(domain->id);
 
@@ -2185,6 +2283,9 @@ static struct protection_domain *protection_domain_alloc(void)
        domain->id = domain_id_alloc();
        if (!domain->id)
                goto out_err;
+       INIT_LIST_HEAD(&domain->dev_list);
+
+       add_domain_to_list(domain);
 
        return domain;
 
@@ -2241,26 +2342,23 @@ static void amd_iommu_domain_destroy(struct iommu_domain *dom)
 static void amd_iommu_detach_device(struct iommu_domain *dom,
                                    struct device *dev)
 {
-       struct protection_domain *domain = dom->priv;
+       struct iommu_dev_data *dev_data = dev->archdata.iommu;
        struct amd_iommu *iommu;
-       struct pci_dev *pdev;
        u16 devid;
 
-       if (dev->bus != &pci_bus_type)
+       if (!check_device(dev))
                return;
 
-       pdev = to_pci_dev(dev);
-
-       devid = calc_devid(pdev->bus->number, pdev->devfn);
+       devid = get_device_id(dev);
 
-       if (devid > 0)
-               detach_device(domain, devid);
+       if (dev_data->domain != NULL)
+               detach_device(dev);
 
        iommu = amd_iommu_rlookup_table[devid];
        if (!iommu)
                return;
 
-       iommu_queue_inv_dev_entry(iommu, devid);
+       iommu_flush_device(dev);
        iommu_completion_wait(iommu);
 }
 
@@ -2268,35 +2366,30 @@ static int amd_iommu_attach_device(struct iommu_domain *dom,
                                   struct device *dev)
 {
        struct protection_domain *domain = dom->priv;
-       struct protection_domain *old_domain;
+       struct iommu_dev_data *dev_data;
        struct amd_iommu *iommu;
-       struct pci_dev *pdev;
+       int ret;
        u16 devid;
 
-       if (dev->bus != &pci_bus_type)
+       if (!check_device(dev))
                return -EINVAL;
 
-       pdev = to_pci_dev(dev);
-
-       devid = calc_devid(pdev->bus->number, pdev->devfn);
+       dev_data = dev->archdata.iommu;
 
-       if (devid >= amd_iommu_last_bdf ||
-                       devid != amd_iommu_alias_table[devid])
-               return -EINVAL;
+       devid = get_device_id(dev);
 
        iommu = amd_iommu_rlookup_table[devid];
        if (!iommu)
                return -EINVAL;
 
-       old_domain = domain_for_device(devid);
-       if (old_domain)
-               detach_device(old_domain, devid);
+       if (dev_data->domain)
+               detach_device(dev);
 
-       attach_device(iommu, domain, devid);
+       ret = attach_device(dev, domain);
 
        iommu_completion_wait(iommu);
 
-       return 0;
+       return ret;
 }
 
 static int amd_iommu_map_range(struct iommu_domain *dom,
@@ -2342,7 +2435,7 @@ static void amd_iommu_unmap_range(struct iommu_domain *dom,
                iova  += PAGE_SIZE;
        }
 
-       iommu_flush_domain(domain->id);
+       iommu_flush_tlb_pde(domain);
 }
 
 static phys_addr_t amd_iommu_iova_to_phys(struct iommu_domain *dom,
@@ -2393,8 +2486,9 @@ static struct iommu_ops amd_iommu_ops = {
 
 int __init amd_iommu_init_passthrough(void)
 {
+       struct amd_iommu *iommu;
        struct pci_dev *dev = NULL;
-       u16 devid, devid2;
+       u16 devid;
 
        /* allocate passthroug domain */
        pt_domain = protection_domain_alloc();
@@ -2404,20 +2498,17 @@ int __init amd_iommu_init_passthrough(void)
        pt_domain->mode |= PAGE_MODE_NONE;
 
        while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
-               struct amd_iommu *iommu;
 
-               devid = calc_devid(dev->bus->number, dev->devfn);
-               if (devid > amd_iommu_last_bdf)
+               if (!check_device(&dev->dev))
                        continue;
 
-               devid2 = amd_iommu_alias_table[devid];
+               devid = get_device_id(&dev->dev);
 
-               iommu = amd_iommu_rlookup_table[devid2];
+               iommu = amd_iommu_rlookup_table[devid];
                if (!iommu)
                        continue;
 
-               __attach_device(iommu, pt_domain, devid);
-               __attach_device(iommu, pt_domain, devid2);
+               attach_device(&dev->dev, pt_domain);
        }
 
        pr_info("AMD-Vi: Initialized for Passthrough Mode\n");
index c20001e4f5562cf6199c546cbd9fa4f307dab122..7ffc39965233ce570a7b734f12636ce05e403d1e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2007-2008 Advanced Micro Devices, Inc.
+ * Copyright (C) 2007-2009 Advanced Micro Devices, Inc.
  * Author: Joerg Roedel <joerg.roedel@amd.com>
  *         Leo Duran <leo.duran@amd.com>
  *
 #include <linux/interrupt.h>
 #include <linux/msi.h>
 #include <asm/pci-direct.h>
+#include <asm/amd_iommu_proto.h>
 #include <asm/amd_iommu_types.h>
 #include <asm/amd_iommu.h>
 #include <asm/iommu.h>
 #include <asm/gart.h>
+#include <asm/x86_init.h>
 
 /*
  * definitions for the ACPI scanning code
@@ -123,18 +125,24 @@ u16 amd_iommu_last_bdf;                   /* largest PCI device id we have
                                           to handle */
 LIST_HEAD(amd_iommu_unity_map);                /* a list of required unity mappings
                                           we find in ACPI */
-#ifdef CONFIG_IOMMU_STRESS
-bool amd_iommu_isolate = false;
-#else
-bool amd_iommu_isolate = true;         /* if true, device isolation is
-                                          enabled */
-#endif
-
 bool amd_iommu_unmap_flush;            /* if true, flush on every unmap */
 
 LIST_HEAD(amd_iommu_list);             /* list of all AMD IOMMUs in the
                                           system */
 
+/* Array to assign indices to IOMMUs*/
+struct amd_iommu *amd_iommus[MAX_IOMMUS];
+int amd_iommus_present;
+
+/* IOMMUs have a non-present cache? */
+bool amd_iommu_np_cache __read_mostly;
+
+/*
+ * List of protection domains - used during resume
+ */
+LIST_HEAD(amd_iommu_pd_list);
+spinlock_t amd_iommu_pd_lock;
+
 /*
  * Pointer to the device table which is shared by all AMD IOMMUs
  * it is indexed by the PCI device id or the HT unit id and contains
@@ -156,12 +164,6 @@ u16 *amd_iommu_alias_table;
  */
 struct amd_iommu **amd_iommu_rlookup_table;
 
-/*
- * The pd table (protection domain table) is used to find the protection domain
- * data structure a device belongs to. Indexed with the PCI device id too.
- */
-struct protection_domain **amd_iommu_pd_table;
-
 /*
  * AMD IOMMU allows up to 2^16 differend protection domains. This is a bitmap
  * to know which ones are already in use.
@@ -838,7 +840,18 @@ static void __init free_iommu_all(void)
 static int __init init_iommu_one(struct amd_iommu *iommu, struct ivhd_header *h)
 {
        spin_lock_init(&iommu->lock);
+
+       /* Add IOMMU to internal data structures */
        list_add_tail(&iommu->list, &amd_iommu_list);
+       iommu->index             = amd_iommus_present++;
+
+       if (unlikely(iommu->index >= MAX_IOMMUS)) {
+               WARN(1, "AMD-Vi: System has more IOMMUs than supported by this driver\n");
+               return -ENOSYS;
+       }
+
+       /* Index is fine - add IOMMU to the array */
+       amd_iommus[iommu->index] = iommu;
 
        /*
         * Copy data from ACPI table entry to the iommu struct
@@ -868,6 +881,9 @@ static int __init init_iommu_one(struct amd_iommu *iommu, struct ivhd_header *h)
        init_iommu_from_acpi(iommu, h);
        init_iommu_devices(iommu);
 
+       if (iommu->cap & (1UL << IOMMU_CAP_NPCACHE))
+               amd_iommu_np_cache = true;
+
        return pci_enable_device(iommu->dev);
 }
 
@@ -925,7 +941,7 @@ static int __init init_iommu_all(struct acpi_table_header *table)
  *
  ****************************************************************************/
 
-static int __init iommu_setup_msi(struct amd_iommu *iommu)
+static int iommu_setup_msi(struct amd_iommu *iommu)
 {
        int r;
 
@@ -1176,19 +1192,10 @@ static struct sys_device device_amd_iommu = {
  * functions. Finally it prints some information about AMD IOMMUs and
  * the driver state and enables the hardware.
  */
-int __init amd_iommu_init(void)
+static int __init amd_iommu_init(void)
 {
        int i, ret = 0;
 
-
-       if (no_iommu) {
-               printk(KERN_INFO "AMD-Vi disabled by kernel command line\n");
-               return 0;
-       }
-
-       if (!amd_iommu_detected)
-               return -ENODEV;
-
        /*
         * First parse ACPI tables to find the largest Bus/Dev/Func
         * we need to handle. Upon this information the shared data
@@ -1225,15 +1232,6 @@ int __init amd_iommu_init(void)
        if (amd_iommu_rlookup_table == NULL)
                goto free;
 
-       /*
-        * Protection Domain table - maps devices to protection domains
-        * This table has the same size as the rlookup_table
-        */
-       amd_iommu_pd_table = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO,
-                                    get_order(rlookup_table_size));
-       if (amd_iommu_pd_table == NULL)
-               goto free;
-
        amd_iommu_pd_alloc_bitmap = (void *)__get_free_pages(
                                            GFP_KERNEL | __GFP_ZERO,
                                            get_order(MAX_DOMAIN_ID/8));
@@ -1255,6 +1253,8 @@ int __init amd_iommu_init(void)
         */
        amd_iommu_pd_alloc_bitmap[0] = 1;
 
+       spin_lock_init(&amd_iommu_pd_lock);
+
        /*
         * now the data structures are allocated and basically initialized
         * start the real acpi table scan
@@ -1286,17 +1286,12 @@ int __init amd_iommu_init(void)
        if (iommu_pass_through)
                goto out;
 
-       printk(KERN_INFO "AMD-Vi: device isolation ");
-       if (amd_iommu_isolate)
-               printk("enabled\n");
-       else
-               printk("disabled\n");
-
        if (amd_iommu_unmap_flush)
                printk(KERN_INFO "AMD-Vi: IO/TLB flush on unmap enabled\n");
        else
                printk(KERN_INFO "AMD-Vi: Lazy IO/TLB flushing enabled\n");
 
+       x86_platform.iommu_shutdown = disable_iommus;
 out:
        return ret;
 
@@ -1304,9 +1299,6 @@ free:
        free_pages((unsigned long)amd_iommu_pd_alloc_bitmap,
                   get_order(MAX_DOMAIN_ID/8));
 
-       free_pages((unsigned long)amd_iommu_pd_table,
-                  get_order(rlookup_table_size));
-
        free_pages((unsigned long)amd_iommu_rlookup_table,
                   get_order(rlookup_table_size));
 
@@ -1323,11 +1315,6 @@ free:
        goto out;
 }
 
-void amd_iommu_shutdown(void)
-{
-       disable_iommus();
-}
-
 /****************************************************************************
  *
  * Early detect code. This code runs at IOMMU detection time in the DMA
@@ -1342,16 +1329,13 @@ static int __init early_amd_iommu_detect(struct acpi_table_header *table)
 
 void __init amd_iommu_detect(void)
 {
-       if (swiotlb || no_iommu || (iommu_detected && !gart_iommu_aperture))
+       if (no_iommu || (iommu_detected && !gart_iommu_aperture))
                return;
 
        if (acpi_table_parse("IVRS", early_amd_iommu_detect) == 0) {
                iommu_detected = 1;
                amd_iommu_detected = 1;
-#ifdef CONFIG_GART_IOMMU
-               gart_iommu_aperture_disabled = 1;
-               gart_iommu_aperture = 0;
-#endif
+               x86_init.iommu.iommu_init = amd_iommu_init;
        }
 }
 
@@ -1372,10 +1356,6 @@ static int __init parse_amd_iommu_dump(char *str)
 static int __init parse_amd_iommu_options(char *str)
 {
        for (; *str; ++str) {
-               if (strncmp(str, "isolate", 7) == 0)
-                       amd_iommu_isolate = true;
-               if (strncmp(str, "share", 5) == 0)
-                       amd_iommu_isolate = false;
                if (strncmp(str, "fullflush", 9) == 0)
                        amd_iommu_unmap_flush = true;
        }
index 128111d8ffe0de7ffcdaf0891221ff37d0ae61f8..e0dfb6856aa297ef9349dc36c3b5cef93b5abbf0 100644 (file)
@@ -28,6 +28,7 @@
 #include <asm/pci-direct.h>
 #include <asm/dma.h>
 #include <asm/k8.h>
+#include <asm/x86_init.h>
 
 int gart_iommu_aperture;
 int gart_iommu_aperture_disabled __initdata;
@@ -400,6 +401,7 @@ void __init gart_iommu_hole_init(void)
 
                        iommu_detected = 1;
                        gart_iommu_aperture = 1;
+                       x86_init.iommu.iommu_init = gart_iommu_init;
 
                        aper_order = (read_pci_config(bus, slot, 3, AMD64_GARTAPERTURECTL) >> 1) & 7;
                        aper_size = (32 * 1024 * 1024) << aper_order;
@@ -456,7 +458,7 @@ out:
 
        if (aper_alloc) {
                /* Got the aperture from the AGP bridge */
-       } else if (swiotlb && !valid_agp) {
+       } else if (!valid_agp) {
                /* Do nothing */
        } else if ((!no_iommu && max_pfn > MAX_DMA32_PFN) ||
                   force_iommu ||
index 7d5c3b0ea8dad3a69eaf24d9b99d7eb3a2bacfd2..8b581d3905cb47214af854582e24a379fac444f3 100644 (file)
@@ -526,15 +526,21 @@ static const struct dmi_system_id sw_any_bug_dmi_table[] = {
 
 static int acpi_cpufreq_blacklist(struct cpuinfo_x86 *c)
 {
-       /* http://www.intel.com/Assets/PDF/specupdate/314554.pdf
+       /* Intel Xeon Processor 7100 Series Specification Update
+        * http://www.intel.com/Assets/PDF/specupdate/314554.pdf
         * AL30: A Machine Check Exception (MCE) Occurring during an
         * Enhanced Intel SpeedStep Technology Ratio Change May Cause
-        * Both Processor Cores to Lock Up when HT is enabled*/
+        * Both Processor Cores to Lock Up*/
        if (c->x86_vendor == X86_VENDOR_INTEL) {
                if ((c->x86 == 15) &&
                    (c->x86_model == 6) &&
-                   (c->x86_mask == 8) && smt_capable())
+                   (c->x86_mask == 8)) {
+                       printk(KERN_INFO "acpi-cpufreq: Intel(R) "
+                           "Xeon(R) 7100 Errata AL30, processors may "
+                           "lock up on frequency changes: disabling "
+                           "acpi-cpufreq.\n");
                        return -ENODEV;
+                   }
                }
        return 0;
 }
@@ -549,13 +555,18 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy)
        unsigned int result = 0;
        struct cpuinfo_x86 *c = &cpu_data(policy->cpu);
        struct acpi_processor_performance *perf;
+#ifdef CONFIG_SMP
+       static int blacklisted;
+#endif
 
        dprintk("acpi_cpufreq_cpu_init\n");
 
 #ifdef CONFIG_SMP
-       result = acpi_cpufreq_blacklist(c);
-       if (result)
-               return result;
+       if (blacklisted)
+               return blacklisted;
+       blacklisted = acpi_cpufreq_blacklist(c);
+       if (blacklisted)
+               return blacklisted;
 #endif
 
        data = kzalloc(sizeof(struct acpi_cpufreq_data), GFP_KERNEL);
index ce2ed3e4aad96a200fe0280dea4d66a4b2fb9268..cabd2fa3fc931e0e20f6f368b6378705d040e602 100644 (file)
@@ -813,7 +813,7 @@ static int __init longhaul_cpu_init(struct cpufreq_policy *policy)
                        memcpy(eblcr, samuel2_eblcr, sizeof(samuel2_eblcr));
                        break;
                case 1 ... 15:
-                       longhaul_version = TYPE_LONGHAUL_V1;
+                       longhaul_version = TYPE_LONGHAUL_V2;
                        if (c->x86_mask < 8) {
                                cpu_model = CPU_SAMUEL2;
                                cpuname = "C3 'Samuel 2' [C5B]";
index 6394aa5c7985b17ea0c18a9d9ae6859cd7b66585..3f12dabeab525d2de56321c6dc1a1a6817d8db7a 100644 (file)
@@ -1022,7 +1022,7 @@ static int get_transition_latency(struct powernow_k8_data *data)
                 * set it to 1 to avoid problems in the future.
                 * For all others it's a BIOS bug.
                 */
-               if (!boot_cpu_data.x86 == 0x11)
+               if (boot_cpu_data.x86 != 0x11)
                        printk(KERN_ERR FW_WARN PFX "Invalid zero transition "
                                "latency\n");
                max_latency = 1;
index 6911e91fb4f67dc5344342f83e273b39a74106bf..3ae5a7a3a500dc2ddf392ba730736ade952057d7 100644 (file)
@@ -232,28 +232,23 @@ static unsigned int speedstep_detect_chipset(void)
        return 0;
 }
 
-struct get_freq_data {
-       unsigned int speed;
-       unsigned int processor;
-};
-
-static void get_freq_data(void *_data)
+static void get_freq_data(void *_speed)
 {
-       struct get_freq_data *data = _data;
+       unsigned int *speed = _speed;
 
-       data->speed = speedstep_get_frequency(data->processor);
+       *speed = speedstep_get_frequency(speedstep_processor);
 }
 
 static unsigned int speedstep_get(unsigned int cpu)
 {
-       struct get_freq_data data = { .processor = cpu };
+       unsigned int speed;
 
        /* You're supposed to ensure CPU is online. */
-       if (smp_call_function_single(cpu, get_freq_data, &data, 1) != 0)
+       if (smp_call_function_single(cpu, get_freq_data, &speed, 1) != 0)
                BUG();
 
-       dprintk("detected %u kHz as current frequency\n", data.speed);
-       return data.speed;
+       dprintk("detected %u kHz as current frequency\n", speed);
+       return speed;
 }
 
 /**
index 5e409dc298a479d3f72e9a65990edb5fedc514da..a4849c10a77e0b7016574e26b332910dcf2955a6 100644 (file)
@@ -27,8 +27,7 @@
 #include <asm/cpu.h>
 #include <asm/reboot.h>
 #include <asm/virtext.h>
-#include <asm/iommu.h>
-
+#include <asm/x86_init.h>
 
 #if defined(CONFIG_SMP) && defined(CONFIG_X86_LOCAL_APIC)
 
@@ -106,7 +105,7 @@ void native_machine_crash_shutdown(struct pt_regs *regs)
 #endif
 
 #ifdef CONFIG_X86_64
-       pci_iommu_shutdown();
+       x86_platform.iommu_shutdown();
 #endif
 
        crash_save_cpu(regs, safe_smp_processor_id());
index 971a3bec47a8644fdd3cbbcebb833a0ad2cc3044..c563e4c8ff395efe92522c80212a237968897b4a 100644 (file)
@@ -46,6 +46,7 @@
 #include <asm/dma.h>
 #include <asm/rio.h>
 #include <asm/bios_ebda.h>
+#include <asm/x86_init.h>
 
 #ifdef CONFIG_CALGARY_IOMMU_ENABLED_BY_DEFAULT
 int use_calgary __read_mostly = 1;
@@ -244,7 +245,7 @@ static unsigned long iommu_range_alloc(struct device *dev,
                        if (panic_on_overflow)
                                panic("Calgary: fix the allocator.\n");
                        else
-                               return bad_dma_address;
+                               return DMA_ERROR_CODE;
                }
        }
 
@@ -260,12 +261,15 @@ static dma_addr_t iommu_alloc(struct device *dev, struct iommu_table *tbl,
                              void *vaddr, unsigned int npages, int direction)
 {
        unsigned long entry;
-       dma_addr_t ret = bad_dma_address;
+       dma_addr_t ret;
 
        entry = iommu_range_alloc(dev, tbl, npages);
 
-       if (unlikely(entry == bad_dma_address))
-               goto error;
+       if (unlikely(entry == DMA_ERROR_CODE)) {
+               printk(KERN_WARNING "Calgary: failed to allocate %u pages in "
+                      "iommu %p\n", npages, tbl);
+               return DMA_ERROR_CODE;
+       }
 
        /* set the return dma address */
        ret = (entry << PAGE_SHIFT) | ((unsigned long)vaddr & ~PAGE_MASK);
@@ -273,13 +277,7 @@ static dma_addr_t iommu_alloc(struct device *dev, struct iommu_table *tbl,
        /* put the TCEs in the HW table */
        tce_build(tbl, entry, npages, (unsigned long)vaddr & PAGE_MASK,
                  direction);
-
        return ret;
-
-error:
-       printk(KERN_WARNING "Calgary: failed to allocate %u pages in "
-              "iommu %p\n", npages, tbl);
-       return bad_dma_address;
 }
 
 static void iommu_free(struct iommu_table *tbl, dma_addr_t dma_addr,
@@ -290,8 +288,8 @@ static void iommu_free(struct iommu_table *tbl, dma_addr_t dma_addr,
        unsigned long flags;
 
        /* were we called with bad_dma_address? */
-       badend = bad_dma_address + (EMERGENCY_PAGES * PAGE_SIZE);
-       if (unlikely((dma_addr >= bad_dma_address) && (dma_addr < badend))) {
+       badend = DMA_ERROR_CODE + (EMERGENCY_PAGES * PAGE_SIZE);
+       if (unlikely((dma_addr >= DMA_ERROR_CODE) && (dma_addr < badend))) {
                WARN(1, KERN_ERR "Calgary: driver tried unmapping bad DMA "
                       "address 0x%Lx\n", dma_addr);
                return;
@@ -318,13 +316,15 @@ static inline struct iommu_table *find_iommu_table(struct device *dev)
 
        pdev = to_pci_dev(dev);
 
+       /* search up the device tree for an iommu */
        pbus = pdev->bus;
-
-       /* is the device behind a bridge? Look for the root bus */
-       while (pbus->parent)
+       do {
+               tbl = pci_iommu(pbus);
+               if (tbl && tbl->it_busno == pbus->number)
+                       break;
+               tbl = NULL;
                pbus = pbus->parent;
-
-       tbl = pci_iommu(pbus);
+       } while (pbus);
 
        BUG_ON(tbl && (tbl->it_busno != pbus->number));
 
@@ -373,7 +373,7 @@ static int calgary_map_sg(struct device *dev, struct scatterlist *sg,
                npages = iommu_num_pages(vaddr, s->length, PAGE_SIZE);
 
                entry = iommu_range_alloc(dev, tbl, npages);
-               if (entry == bad_dma_address) {
+               if (entry == DMA_ERROR_CODE) {
                        /* makes sure unmap knows to stop */
                        s->dma_length = 0;
                        goto error;
@@ -391,7 +391,7 @@ static int calgary_map_sg(struct device *dev, struct scatterlist *sg,
 error:
        calgary_unmap_sg(dev, sg, nelems, dir, NULL);
        for_each_sg(sg, s, nelems, i) {
-               sg->dma_address = bad_dma_address;
+               sg->dma_address = DMA_ERROR_CODE;
                sg->dma_length = 0;
        }
        return 0;
@@ -446,7 +446,7 @@ static void* calgary_alloc_coherent(struct device *dev, size_t size,
 
        /* set up tces to cover the allocated range */
        mapping = iommu_alloc(dev, tbl, ret, npages, DMA_BIDIRECTIONAL);
-       if (mapping == bad_dma_address)
+       if (mapping == DMA_ERROR_CODE)
                goto free;
        *dma_handle = mapping;
        return ret;
@@ -727,7 +727,7 @@ static void __init calgary_reserve_regions(struct pci_dev *dev)
        struct iommu_table *tbl = pci_iommu(dev->bus);
 
        /* reserve EMERGENCY_PAGES from bad_dma_address and up */
-       iommu_range_reserve(tbl, bad_dma_address, EMERGENCY_PAGES);
+       iommu_range_reserve(tbl, DMA_ERROR_CODE, EMERGENCY_PAGES);
 
        /* avoid the BIOS/VGA first 640KB-1MB region */
        /* for CalIOC2 - avoid the entire first MB */
@@ -1344,6 +1344,23 @@ static void __init get_tce_space_from_tar(void)
        return;
 }
 
+static int __init calgary_iommu_init(void)
+{
+       int ret;
+
+       /* ok, we're trying to use Calgary - let's roll */
+       printk(KERN_INFO "PCI-DMA: Using Calgary IOMMU\n");
+
+       ret = calgary_init();
+       if (ret) {
+               printk(KERN_ERR "PCI-DMA: Calgary init failed %d, "
+                      "falling back to no_iommu\n", ret);
+               return ret;
+       }
+
+       return 0;
+}
+
 void __init detect_calgary(void)
 {
        int bus;
@@ -1357,7 +1374,7 @@ void __init detect_calgary(void)
         * if the user specified iommu=off or iommu=soft or we found
         * another HW IOMMU already, bail out.
         */
-       if (swiotlb || no_iommu || iommu_detected)
+       if (no_iommu || iommu_detected)
                return;
 
        if (!use_calgary)
@@ -1442,9 +1459,7 @@ void __init detect_calgary(void)
                printk(KERN_INFO "PCI-DMA: Calgary TCE table spec is %d\n",
                       specified_table_size);
 
-               /* swiotlb for devices that aren't behind the Calgary. */
-               if (max_pfn > MAX_DMA32_PFN)
-                       swiotlb = 1;
+               x86_init.iommu.iommu_init = calgary_iommu_init;
        }
        return;
 
@@ -1457,35 +1472,6 @@ cleanup:
        }
 }
 
-int __init calgary_iommu_init(void)
-{
-       int ret;
-
-       if (no_iommu || (swiotlb && !calgary_detected))
-               return -ENODEV;
-
-       if (!calgary_detected)
-               return -ENODEV;
-
-       /* ok, we're trying to use Calgary - let's roll */
-       printk(KERN_INFO "PCI-DMA: Using Calgary IOMMU\n");
-
-       ret = calgary_init();
-       if (ret) {
-               printk(KERN_ERR "PCI-DMA: Calgary init failed %d, "
-                      "falling back to no_iommu\n", ret);
-               return ret;
-       }
-
-       force_iommu = 1;
-       bad_dma_address = 0x0;
-       /* dma_ops is set to swiotlb or nommu */
-       if (!dma_ops)
-               dma_ops = &nommu_dma_ops;
-
-       return 0;
-}
-
 static int __init calgary_parse_options(char *p)
 {
        unsigned int bridge;
index a6e804d16c35a4053b5ba16323887007ef25c30d..afcc58b69c7c8579c11f08405621b85919f88663 100644 (file)
 #include <asm/gart.h>
 #include <asm/calgary.h>
 #include <asm/amd_iommu.h>
+#include <asm/x86_init.h>
 
 static int forbid_dac __read_mostly;
 
-struct dma_map_ops *dma_ops;
+struct dma_map_ops *dma_ops = &nommu_dma_ops;
 EXPORT_SYMBOL(dma_ops);
 
 static int iommu_sac_force __read_mostly;
@@ -42,9 +43,6 @@ int iommu_detected __read_mostly = 0;
  */
 int iommu_pass_through __read_mostly;
 
-dma_addr_t bad_dma_address __read_mostly = 0;
-EXPORT_SYMBOL(bad_dma_address);
-
 /* Dummy device used for NULL arguments (normally ISA). */
 struct device x86_dma_fallback_dev = {
        .init_name = "fallback device",
@@ -126,20 +124,17 @@ void __init pci_iommu_alloc(void)
        /* free the range so iommu could get some range less than 4G */
        dma32_free_bootmem();
 #endif
+       if (pci_swiotlb_init())
+               return;
 
-       /*
-        * The order of these functions is important for
-        * fall-back/fail-over reasons
-        */
        gart_iommu_hole_init();
 
        detect_calgary();
 
        detect_intel_iommu();
 
+       /* needs to be called after gart_iommu_hole_init */
        amd_iommu_detect();
-
-       pci_swiotlb_init();
 }
 
 void *dma_generic_alloc_coherent(struct device *dev, size_t size,
@@ -214,7 +209,7 @@ static __init int iommu_setup(char *p)
                if (!strncmp(p, "allowdac", 8))
                        forbid_dac = 0;
                if (!strncmp(p, "nodac", 5))
-                       forbid_dac = -1;
+                       forbid_dac = 1;
                if (!strncmp(p, "usedac", 6)) {
                        forbid_dac = -1;
                        return 1;
@@ -289,25 +284,17 @@ static int __init pci_iommu_init(void)
 #ifdef CONFIG_PCI
        dma_debug_add_bus(&pci_bus_type);
 #endif
+       x86_init.iommu.iommu_init();
 
-       calgary_iommu_init();
-
-       intel_iommu_init();
+       if (swiotlb) {
+               printk(KERN_INFO "PCI-DMA: "
+                      "Using software bounce buffering for IO (SWIOTLB)\n");
+               swiotlb_print_info();
+       } else
+               swiotlb_free();
 
-       amd_iommu_init();
-
-       gart_iommu_init();
-
-       no_iommu_init();
        return 0;
 }
-
-void pci_iommu_shutdown(void)
-{
-       gart_iommu_shutdown();
-
-       amd_iommu_shutdown();
-}
 /* Must execute after PCI subsystem */
 rootfs_initcall(pci_iommu_init);
 
index a7f1b64f86e0476321c82dc44d3fe7dd20758927..e6a0d402f1714dec4aff2e160b0eff255ea5307b 100644 (file)
@@ -39,6 +39,7 @@
 #include <asm/swiotlb.h>
 #include <asm/dma.h>
 #include <asm/k8.h>
+#include <asm/x86_init.h>
 
 static unsigned long iommu_bus_base;   /* GART remapping area (physical) */
 static unsigned long iommu_size;       /* size of remapping area bytes */
@@ -46,6 +47,8 @@ static unsigned long iommu_pages;     /* .. and in pages */
 
 static u32 *iommu_gatt_base;           /* Remapping table */
 
+static dma_addr_t bad_dma_addr;
+
 /*
  * If this is disabled the IOMMU will use an optimized flushing strategy
  * of only flushing when an mapping is reused. With it true the GART is
@@ -92,7 +95,7 @@ static unsigned long alloc_iommu(struct device *dev, int size,
 
        base_index = ALIGN(iommu_bus_base & dma_get_seg_boundary(dev),
                           PAGE_SIZE) >> PAGE_SHIFT;
-       boundary_size = ALIGN((unsigned long long)dma_get_seg_boundary(dev) + 1,
+       boundary_size = ALIGN((u64)dma_get_seg_boundary(dev) + 1,
                              PAGE_SIZE) >> PAGE_SHIFT;
 
        spin_lock_irqsave(&iommu_bitmap_lock, flags);
@@ -216,7 +219,7 @@ static dma_addr_t dma_map_area(struct device *dev, dma_addr_t phys_mem,
                if (panic_on_overflow)
                        panic("dma_map_area overflow %lu bytes\n", size);
                iommu_full(dev, size, dir);
-               return bad_dma_address;
+               return bad_dma_addr;
        }
 
        for (i = 0; i < npages; i++) {
@@ -294,7 +297,7 @@ static int dma_map_sg_nonforce(struct device *dev, struct scatterlist *sg,
        int i;
 
 #ifdef CONFIG_IOMMU_DEBUG
-       printk(KERN_DEBUG "dma_map_sg overflow\n");
+       pr_debug("dma_map_sg overflow\n");
 #endif
 
        for_each_sg(sg, s, nents, i) {
@@ -302,7 +305,7 @@ static int dma_map_sg_nonforce(struct device *dev, struct scatterlist *sg,
 
                if (nonforced_iommu(dev, addr, s->length)) {
                        addr = dma_map_area(dev, addr, s->length, dir, 0);
-                       if (addr == bad_dma_address) {
+                       if (addr == bad_dma_addr) {
                                if (i > 0)
                                        gart_unmap_sg(dev, sg, i, dir, NULL);
                                nents = 0;
@@ -389,12 +392,14 @@ static int gart_map_sg(struct device *dev, struct scatterlist *sg, int nents,
        if (!dev)
                dev = &x86_dma_fallback_dev;
 
-       out = 0;
-       start = 0;
-       start_sg = sgmap = sg;
-       seg_size = 0;
-       max_seg_size = dma_get_max_seg_size(dev);
-       ps = NULL; /* shut up gcc */
+       out             = 0;
+       start           = 0;
+       start_sg        = sg;
+       sgmap           = sg;
+       seg_size        = 0;
+       max_seg_size    = dma_get_max_seg_size(dev);
+       ps              = NULL; /* shut up gcc */
+
        for_each_sg(sg, s, nents, i) {
                dma_addr_t addr = sg_phys(s);
 
@@ -417,11 +422,12 @@ static int gart_map_sg(struct device *dev, struct scatterlist *sg, int nents,
                                                 sgmap, pages, need) < 0)
                                        goto error;
                                out++;
-                               seg_size = 0;
-                               sgmap = sg_next(sgmap);
-                               pages = 0;
-                               start = i;
-                               start_sg = s;
+
+                               seg_size        = 0;
+                               sgmap           = sg_next(sgmap);
+                               pages           = 0;
+                               start           = i;
+                               start_sg        = s;
                        }
                }
 
@@ -455,7 +461,7 @@ error:
 
        iommu_full(dev, pages << PAGE_SHIFT, dir);
        for_each_sg(sg, s, nents, i)
-               s->dma_address = bad_dma_address;
+               s->dma_address = bad_dma_addr;
        return 0;
 }
 
@@ -479,7 +485,7 @@ gart_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_addr,
                                     DMA_BIDIRECTIONAL, align_mask);
 
                flush_gart();
-               if (paddr != bad_dma_address) {
+               if (paddr != bad_dma_addr) {
                        *dma_addr = paddr;
                        return page_address(page);
                }
@@ -499,6 +505,11 @@ gart_free_coherent(struct device *dev, size_t size, void *vaddr,
        free_pages((unsigned long)vaddr, get_order(size));
 }
 
+static int gart_mapping_error(struct device *dev, dma_addr_t dma_addr)
+{
+       return (dma_addr == bad_dma_addr);
+}
+
 static int no_agp;
 
 static __init unsigned long check_iommu_size(unsigned long aper, u64 aper_size)
@@ -515,7 +526,7 @@ static __init unsigned long check_iommu_size(unsigned long aper, u64 aper_size)
        iommu_size -= round_up(a, PMD_PAGE_SIZE) - a;
 
        if (iommu_size < 64*1024*1024) {
-               printk(KERN_WARNING
+               pr_warning(
                        "PCI-DMA: Warning: Small IOMMU %luMB."
                        " Consider increasing the AGP aperture in BIOS\n",
                                iommu_size >> 20);
@@ -570,28 +581,32 @@ void set_up_gart_resume(u32 aper_order, u32 aper_alloc)
        aperture_alloc = aper_alloc;
 }
 
-static int gart_resume(struct sys_device *dev)
+static void gart_fixup_northbridges(struct sys_device *dev)
 {
-       printk(KERN_INFO "PCI-DMA: Resuming GART IOMMU\n");
+       int i;
 
-       if (fix_up_north_bridges) {
-               int i;
+       if (!fix_up_north_bridges)
+               return;
 
-               printk(KERN_INFO "PCI-DMA: Restoring GART aperture settings\n");
+       pr_info("PCI-DMA: Restoring GART aperture settings\n");
 
-               for (i = 0; i < num_k8_northbridges; i++) {
-                       struct pci_dev *dev = k8_northbridges[i];
+       for (i = 0; i < num_k8_northbridges; i++) {
+               struct pci_dev *dev = k8_northbridges[i];
 
-                       /*
-                        * Don't enable translations just yet.  That is the next
-                        * step.  Restore the pre-suspend aperture settings.
-                        */
-                       pci_write_config_dword(dev, AMD64_GARTAPERTURECTL,
-                                               aperture_order << 1);
-                       pci_write_config_dword(dev, AMD64_GARTAPERTUREBASE,
-                                               aperture_alloc >> 25);
-               }
+               /*
+                * Don't enable translations just yet.  That is the next
+                * step.  Restore the pre-suspend aperture settings.
+                */
+               pci_write_config_dword(dev, AMD64_GARTAPERTURECTL, aperture_order << 1);
+               pci_write_config_dword(dev, AMD64_GARTAPERTUREBASE, aperture_alloc >> 25);
        }
+}
+
+static int gart_resume(struct sys_device *dev)
+{
+       pr_info("PCI-DMA: Resuming GART IOMMU\n");
+
+       gart_fixup_northbridges(dev);
 
        enable_gart_translations();
 
@@ -604,15 +619,14 @@ static int gart_suspend(struct sys_device *dev, pm_message_t state)
 }
 
 static struct sysdev_class gart_sysdev_class = {
-       .name = "gart",
-       .suspend = gart_suspend,
-       .resume = gart_resume,
+       .name           = "gart",
+       .suspend        = gart_suspend,
+       .resume         = gart_resume,
 
 };
 
 static struct sys_device device_gart = {
-       .id     = 0,
-       .cls    = &gart_sysdev_class,
+       .cls            = &gart_sysdev_class,
 };
 
 /*
@@ -627,7 +641,8 @@ static __init int init_k8_gatt(struct agp_kern_info *info)
        void *gatt;
        int i, error;
 
-       printk(KERN_INFO "PCI-DMA: Disabling AGP.\n");
+       pr_info("PCI-DMA: Disabling AGP.\n");
+
        aper_size = aper_base = info->aper_size = 0;
        dev = NULL;
        for (i = 0; i < num_k8_northbridges; i++) {
@@ -645,6 +660,7 @@ static __init int init_k8_gatt(struct agp_kern_info *info)
        }
        if (!aper_base)
                goto nommu;
+
        info->aper_base = aper_base;
        info->aper_size = aper_size >> 20;
 
@@ -667,14 +683,14 @@ static __init int init_k8_gatt(struct agp_kern_info *info)
 
        flush_gart();
 
-       printk(KERN_INFO "PCI-DMA: aperture base @ %x size %u KB\n",
+       pr_info("PCI-DMA: aperture base @ %x size %u KB\n",
               aper_base, aper_size>>10);
 
        return 0;
 
  nommu:
        /* Should not happen anymore */
-       printk(KERN_WARNING "PCI-DMA: More than 4GB of RAM and no IOMMU\n"
+       pr_warning("PCI-DMA: More than 4GB of RAM and no IOMMU\n"
               "falling back to iommu=soft.\n");
        return -1;
 }
@@ -686,14 +702,15 @@ static struct dma_map_ops gart_dma_ops = {
        .unmap_page                     = gart_unmap_page,
        .alloc_coherent                 = gart_alloc_coherent,
        .free_coherent                  = gart_free_coherent,
+       .mapping_error                  = gart_mapping_error,
 };
 
-void gart_iommu_shutdown(void)
+static void gart_iommu_shutdown(void)
 {
        struct pci_dev *dev;
        int i;
 
-       if (no_agp && (dma_ops != &gart_dma_ops))
+       if (no_agp)
                return;
 
        for (i = 0; i < num_k8_northbridges; i++) {
@@ -708,7 +725,7 @@ void gart_iommu_shutdown(void)
        }
 }
 
-void __init gart_iommu_init(void)
+int __init gart_iommu_init(void)
 {
        struct agp_kern_info info;
        unsigned long iommu_start;
@@ -718,7 +735,7 @@ void __init gart_iommu_init(void)
        long i;
 
        if (cache_k8_northbridges() < 0 || num_k8_northbridges == 0)
-               return;
+               return 0;
 
 #ifndef CONFIG_AGP_AMD64
        no_agp = 1;
@@ -730,35 +747,28 @@ void __init gart_iommu_init(void)
                (agp_copy_info(agp_bridge, &info) < 0);
 #endif
 
-       if (swiotlb)
-               return;
-
-       /* Did we detect a different HW IOMMU? */
-       if (iommu_detected && !gart_iommu_aperture)
-               return;
-
        if (no_iommu ||
            (!force_iommu && max_pfn <= MAX_DMA32_PFN) ||
            !gart_iommu_aperture ||
            (no_agp && init_k8_gatt(&info) < 0)) {
                if (max_pfn > MAX_DMA32_PFN) {
-                       printk(KERN_WARNING "More than 4GB of memory "
-                              "but GART IOMMU not available.\n");
-                       printk(KERN_WARNING "falling back to iommu=soft.\n");
+                       pr_warning("More than 4GB of memory but GART IOMMU not available.\n");
+                       pr_warning("falling back to iommu=soft.\n");
                }
-               return;
+               return 0;
        }
 
        /* need to map that range */
-       aper_size = info.aper_size << 20;
-       aper_base = info.aper_base;
-       end_pfn = (aper_base>>PAGE_SHIFT) + (aper_size>>PAGE_SHIFT);
+       aper_size       = info.aper_size << 20;
+       aper_base       = info.aper_base;
+       end_pfn         = (aper_base>>PAGE_SHIFT) + (aper_size>>PAGE_SHIFT);
+
        if (end_pfn > max_low_pfn_mapped) {
                start_pfn = (aper_base>>PAGE_SHIFT);
                init_memory_mapping(start_pfn<<PAGE_SHIFT, end_pfn<<PAGE_SHIFT);
        }
 
-       printk(KERN_INFO "PCI-DMA: using GART IOMMU.\n");
+       pr_info("PCI-DMA: using GART IOMMU.\n");
        iommu_size = check_iommu_size(info.aper_base, aper_size);
        iommu_pages = iommu_size >> PAGE_SHIFT;
 
@@ -773,8 +783,7 @@ void __init gart_iommu_init(void)
 
                ret = dma_debug_resize_entries(iommu_pages);
                if (ret)
-                       printk(KERN_DEBUG
-                              "PCI-DMA: Cannot trace all the entries\n");
+                       pr_debug("PCI-DMA: Cannot trace all the entries\n");
        }
 #endif
 
@@ -784,15 +793,14 @@ void __init gart_iommu_init(void)
         */
        iommu_area_reserve(iommu_gart_bitmap, 0, EMERGENCY_PAGES);
 
-       agp_memory_reserved = iommu_size;
-       printk(KERN_INFO
-              "PCI-DMA: Reserving %luMB of IOMMU area in the AGP aperture\n",
+       pr_info("PCI-DMA: Reserving %luMB of IOMMU area in the AGP aperture\n",
               iommu_size >> 20);
 
-       iommu_start = aper_size - iommu_size;
-       iommu_bus_base = info.aper_base + iommu_start;
-       bad_dma_address = iommu_bus_base;
-       iommu_gatt_base = agp_gatt_table + (iommu_start>>PAGE_SHIFT);
+       agp_memory_reserved     = iommu_size;
+       iommu_start             = aper_size - iommu_size;
+       iommu_bus_base          = info.aper_base + iommu_start;
+       bad_dma_addr            = iommu_bus_base;
+       iommu_gatt_base         = agp_gatt_table + (iommu_start>>PAGE_SHIFT);
 
        /*
         * Unmap the IOMMU part of the GART. The alias of the page is
@@ -814,7 +822,7 @@ void __init gart_iommu_init(void)
         * the pages as Not-Present:
         */
        wbinvd();
-       
+
        /*
         * Now all caches are flushed and we can safely enable
         * GART hardware.  Doing it early leaves the possibility
@@ -838,6 +846,10 @@ void __init gart_iommu_init(void)
 
        flush_gart();
        dma_ops = &gart_dma_ops;
+       x86_platform.iommu_shutdown = gart_iommu_shutdown;
+       swiotlb = 0;
+
+       return 0;
 }
 
 void __init gart_parse_options(char *p)
@@ -856,7 +868,7 @@ void __init gart_parse_options(char *p)
 #endif
        if (isdigit(*p) && get_option(&p, &arg))
                iommu_size = arg;
-       if (!strncmp(p, "fullflush", 8))
+       if (!strncmp(p, "fullflush", 9))
                iommu_fullflush = 1;
        if (!strncmp(p, "nofullflush", 11))
                iommu_fullflush = 0;
index a3933d4330cd31f1ec4c6797f5e892279d9d6c7f..22be12b60a8ff2b12678e5198379d19260de9ce4 100644 (file)
@@ -33,7 +33,7 @@ static dma_addr_t nommu_map_page(struct device *dev, struct page *page,
        dma_addr_t bus = page_to_phys(page) + offset;
        WARN_ON(size == 0);
        if (!check_addr("map_single", dev, bus, size))
-               return bad_dma_address;
+               return DMA_ERROR_CODE;
        flush_write_buffers();
        return bus;
 }
@@ -103,12 +103,3 @@ struct dma_map_ops nommu_dma_ops = {
        .sync_sg_for_device     = nommu_sync_sg_for_device,
        .is_phys                = 1,
 };
-
-void __init no_iommu_init(void)
-{
-       if (dma_ops)
-               return;
-
-       force_iommu = 0; /* no HW IOMMU */
-       dma_ops = &nommu_dma_ops;
-}
index aaa6b7839f1e3541e2a36bb67c770bf343075de7..e3c0a66b9e7785a1eee6637d9ddedef18fb7bf48 100644 (file)
@@ -42,18 +42,28 @@ static struct dma_map_ops swiotlb_dma_ops = {
        .dma_supported = NULL,
 };
 
-void __init pci_swiotlb_init(void)
+/*
+ * pci_swiotlb_init - initialize swiotlb if necessary
+ *
+ * This returns non-zero if we are forced to use swiotlb (by the boot
+ * option).
+ */
+int __init pci_swiotlb_init(void)
 {
+       int use_swiotlb = swiotlb | swiotlb_force;
+
        /* don't initialize swiotlb if iommu=off (no_iommu=1) */
 #ifdef CONFIG_X86_64
-       if ((!iommu_detected && !no_iommu && max_pfn > MAX_DMA32_PFN))
+       if (!no_iommu && max_pfn > MAX_DMA32_PFN)
                swiotlb = 1;
 #endif
        if (swiotlb_force)
                swiotlb = 1;
+
        if (swiotlb) {
-               printk(KERN_INFO "PCI-DMA: Using software bounce buffering for IO (SWIOTLB)\n");
-               swiotlb_init();
+               swiotlb_init(0);
                dma_ops = &swiotlb_dma_ops;
        }
+
+       return use_swiotlb;
 }
index f93078746e0014815daada2b3437164a660e5ca6..2b97fc5b124e42b13029c6293147682a3e6d1272 100644 (file)
@@ -23,7 +23,7 @@
 # include <linux/ctype.h>
 # include <linux/mc146818rtc.h>
 #else
-# include <asm/iommu.h>
+# include <asm/x86_init.h>
 #endif
 
 /*
@@ -622,7 +622,7 @@ void native_machine_shutdown(void)
 #endif
 
 #ifdef CONFIG_X86_64
-       pci_iommu_shutdown();
+       x86_platform.iommu_shutdown();
 #endif
 }
 
index 4449a4a2c2ed7398768509b13f1e8a95213d38e3..d11c5ff7c65ede5f752449c630200cda0620fce2 100644 (file)
 #include <asm/time.h>
 #include <asm/irq.h>
 #include <asm/tsc.h>
+#include <asm/iommu.h>
 
 void __cpuinit x86_init_noop(void) { }
 void __init x86_init_uint_noop(unsigned int unused) { }
 void __init x86_init_pgd_noop(pgd_t *unused) { }
+int __init iommu_init_noop(void) { return 0; }
+void iommu_shutdown_noop(void) { }
 
 /*
  * The platform setup functions are preset with the default functions
@@ -62,6 +65,10 @@ struct x86_init_ops x86_init __initdata = {
                .tsc_pre_init           = x86_init_noop,
                .timer_init             = hpet_time_init,
        },
+
+       .iommu = {
+               .iommu_init             = iommu_init_noop,
+       },
 };
 
 struct x86_cpuinit_ops x86_cpuinit __cpuinitdata = {
@@ -72,4 +79,5 @@ struct x86_platform_ops x86_platform = {
        .calibrate_tsc                  = native_calibrate_tsc,
        .get_wallclock                  = mach_get_cmos_time,
        .set_wallclock                  = mach_set_rtc_mmss,
+       .iommu_shutdown                 = iommu_shutdown_noop,
 };
index e5aeb2b79e6f956998b8bd0b2bc3bc882ab5067c..e28e276ac611d9d9bd25011b1cefc200456d6242 100644 (file)
@@ -23,3 +23,8 @@ config ASYNC_RAID6_RECOV
        select ASYNC_CORE
        select ASYNC_PQ
 
+config ASYNC_TX_DISABLE_PQ_VAL_DMA
+       bool
+
+config ASYNC_TX_DISABLE_XOR_VAL_DMA
+       bool
index 6b5cc4fba59f0a52e9b20689ed029cbb65b6209a..ec87f53d50595f0c545df398932799d5d2054c0d 100644 (file)
@@ -240,6 +240,16 @@ async_gen_syndrome(struct page **blocks, unsigned int offset, int disks,
 }
 EXPORT_SYMBOL_GPL(async_gen_syndrome);
 
+static inline struct dma_chan *
+pq_val_chan(struct async_submit_ctl *submit, struct page **blocks, int disks, size_t len)
+{
+       #ifdef CONFIG_ASYNC_TX_DISABLE_PQ_VAL_DMA
+       return NULL;
+       #endif
+       return async_tx_find_channel(submit, DMA_PQ_VAL, NULL, 0,  blocks,
+                                    disks, len);
+}
+
 /**
  * async_syndrome_val - asynchronously validate a raid6 syndrome
  * @blocks: source blocks from idx 0..disks-3, P @ disks-2 and Q @ disks-1
@@ -260,9 +270,7 @@ async_syndrome_val(struct page **blocks, unsigned int offset, int disks,
                   size_t len, enum sum_check_flags *pqres, struct page *spare,
                   struct async_submit_ctl *submit)
 {
-       struct dma_chan *chan = async_tx_find_channel(submit, DMA_PQ_VAL,
-                                                     NULL, 0,  blocks, disks,
-                                                     len);
+       struct dma_chan *chan = pq_val_chan(submit, blocks, disks, len);
        struct dma_device *device = chan ? chan->device : NULL;
        struct dma_async_tx_descriptor *tx;
        unsigned char coefs[disks-2];
index 79182dcb91b797760579482176cb652c495263a8..079ae8ca590bf869fdeb475a1bf4bea7a563831e 100644 (file)
@@ -234,6 +234,17 @@ static int page_is_zero(struct page *p, unsigned int offset, size_t len)
                memcmp(a, a + 4, len - 4) == 0);
 }
 
+static inline struct dma_chan *
+xor_val_chan(struct async_submit_ctl *submit, struct page *dest,
+                struct page **src_list, int src_cnt, size_t len)
+{
+       #ifdef CONFIG_ASYNC_TX_DISABLE_XOR_VAL_DMA
+       return NULL;
+       #endif
+       return async_tx_find_channel(submit, DMA_XOR_VAL, &dest, 1, src_list,
+                                    src_cnt, len);
+}
+
 /**
  * async_xor_val - attempt a xor parity check with a dma engine.
  * @dest: destination page used if the xor is performed synchronously
@@ -255,9 +266,7 @@ async_xor_val(struct page *dest, struct page **src_list, unsigned int offset,
              int src_cnt, size_t len, enum sum_check_flags *result,
              struct async_submit_ctl *submit)
 {
-       struct dma_chan *chan = async_tx_find_channel(submit, DMA_XOR_VAL,
-                                                     &dest, 1, src_list,
-                                                     src_cnt, len);
+       struct dma_chan *chan = xor_val_chan(submit, dest, src_list, src_cnt, len);
        struct dma_device *device = chan ? chan->device : NULL;
        struct dma_async_tx_descriptor *tx = NULL;
        dma_addr_t *dma_src = NULL;
index 5fc3292483efb19cdbf45b18e877015229fb30db..c6547130624ce73cd4e41088f260f40b391dd940 100644 (file)
@@ -40,7 +40,7 @@ struct crypto_rfc4106_ctx {
 struct crypto_gcm_ghash_ctx {
        unsigned int cryptlen;
        struct scatterlist *src;
-       crypto_completion_t complete;
+       void (*complete)(struct aead_request *req, int err);
 };
 
 struct crypto_gcm_req_priv_ctx {
@@ -267,23 +267,26 @@ static int gcm_hash_final(struct aead_request *req,
        return crypto_ahash_final(ahreq);
 }
 
-static void gcm_hash_final_done(struct crypto_async_request *areq,
-                               int err)
+static void __gcm_hash_final_done(struct aead_request *req, int err)
 {
-       struct aead_request *req = areq->data;
        struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req);
        struct crypto_gcm_ghash_ctx *gctx = &pctx->ghash_ctx;
 
        if (!err)
                crypto_xor(pctx->auth_tag, pctx->iauth_tag, 16);
 
-       gctx->complete(areq, err);
+       gctx->complete(req, err);
 }
 
-static void gcm_hash_len_done(struct crypto_async_request *areq,
-                             int err)
+static void gcm_hash_final_done(struct crypto_async_request *areq, int err)
 {
        struct aead_request *req = areq->data;
+
+       __gcm_hash_final_done(req, err);
+}
+
+static void __gcm_hash_len_done(struct aead_request *req, int err)
+{
        struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req);
 
        if (!err) {
@@ -292,13 +295,18 @@ static void gcm_hash_len_done(struct crypto_async_request *areq,
                        return;
        }
 
-       gcm_hash_final_done(areq, err);
+       __gcm_hash_final_done(req, err);
 }
 
-static void gcm_hash_crypt_remain_done(struct crypto_async_request *areq,
-                                      int err)
+static void gcm_hash_len_done(struct crypto_async_request *areq, int err)
 {
        struct aead_request *req = areq->data;
+
+       __gcm_hash_len_done(req, err);
+}
+
+static void __gcm_hash_crypt_remain_done(struct aead_request *req, int err)
+{
        struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req);
 
        if (!err) {
@@ -307,13 +315,19 @@ static void gcm_hash_crypt_remain_done(struct crypto_async_request *areq,
                        return;
        }
 
-       gcm_hash_len_done(areq, err);
+       __gcm_hash_len_done(req, err);
 }
 
-static void gcm_hash_crypt_done(struct crypto_async_request *areq,
-                               int err)
+static void gcm_hash_crypt_remain_done(struct crypto_async_request *areq,
+                                      int err)
 {
        struct aead_request *req = areq->data;
+
+       __gcm_hash_crypt_remain_done(req, err);
+}
+
+static void __gcm_hash_crypt_done(struct aead_request *req, int err)
+{
        struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req);
        struct crypto_gcm_ghash_ctx *gctx = &pctx->ghash_ctx;
        unsigned int remain;
@@ -327,13 +341,18 @@ static void gcm_hash_crypt_done(struct crypto_async_request *areq,
                        return;
        }
 
-       gcm_hash_crypt_remain_done(areq, err);
+       __gcm_hash_crypt_remain_done(req, err);
 }
 
-static void gcm_hash_assoc_remain_done(struct crypto_async_request *areq,
-                                          int err)
+static void gcm_hash_crypt_done(struct crypto_async_request *areq, int err)
 {
        struct aead_request *req = areq->data;
+
+       __gcm_hash_crypt_done(req, err);
+}
+
+static void __gcm_hash_assoc_remain_done(struct aead_request *req, int err)
+{
        struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req);
        struct crypto_gcm_ghash_ctx *gctx = &pctx->ghash_ctx;
        crypto_completion_t complete;
@@ -350,15 +369,21 @@ static void gcm_hash_assoc_remain_done(struct crypto_async_request *areq,
        }
 
        if (remain)
-               gcm_hash_crypt_done(areq, err);
+               __gcm_hash_crypt_done(req, err);
        else
-               gcm_hash_crypt_remain_done(areq, err);
+               __gcm_hash_crypt_remain_done(req, err);
 }
 
-static void gcm_hash_assoc_done(struct crypto_async_request *areq,
-                               int err)
+static void gcm_hash_assoc_remain_done(struct crypto_async_request *areq,
+                                      int err)
 {
        struct aead_request *req = areq->data;
+
+       __gcm_hash_assoc_remain_done(req, err);
+}
+
+static void __gcm_hash_assoc_done(struct aead_request *req, int err)
+{
        struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req);
        unsigned int remain;
 
@@ -371,13 +396,18 @@ static void gcm_hash_assoc_done(struct crypto_async_request *areq,
                        return;
        }
 
-       gcm_hash_assoc_remain_done(areq, err);
+       __gcm_hash_assoc_remain_done(req, err);
 }
 
-static void gcm_hash_init_done(struct crypto_async_request *areq,
-                              int err)
+static void gcm_hash_assoc_done(struct crypto_async_request *areq, int err)
 {
        struct aead_request *req = areq->data;
+
+       __gcm_hash_assoc_done(req, err);
+}
+
+static void __gcm_hash_init_done(struct aead_request *req, int err)
+{
        struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req);
        crypto_completion_t complete;
        unsigned int remain = 0;
@@ -393,9 +423,16 @@ static void gcm_hash_init_done(struct crypto_async_request *areq,
        }
 
        if (remain)
-               gcm_hash_assoc_done(areq, err);
+               __gcm_hash_assoc_done(req, err);
        else
-               gcm_hash_assoc_remain_done(areq, err);
+               __gcm_hash_assoc_remain_done(req, err);
+}
+
+static void gcm_hash_init_done(struct crypto_async_request *areq, int err)
+{
+       struct aead_request *req = areq->data;
+
+       __gcm_hash_init_done(req, err);
 }
 
 static int gcm_hash(struct aead_request *req,
@@ -457,10 +494,8 @@ static void gcm_enc_copy_hash(struct aead_request *req,
                                 crypto_aead_authsize(aead), 1);
 }
 
-static void gcm_enc_hash_done(struct crypto_async_request *areq,
-                                    int err)
+static void gcm_enc_hash_done(struct aead_request *req, int err)
 {
-       struct aead_request *req = areq->data;
        struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req);
 
        if (!err)
@@ -469,8 +504,7 @@ static void gcm_enc_hash_done(struct crypto_async_request *areq,
        aead_request_complete(req, err);
 }
 
-static void gcm_encrypt_done(struct crypto_async_request *areq,
-                                    int err)
+static void gcm_encrypt_done(struct crypto_async_request *areq, int err)
 {
        struct aead_request *req = areq->data;
        struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req);
@@ -479,9 +513,13 @@ static void gcm_encrypt_done(struct crypto_async_request *areq,
                err = gcm_hash(req, pctx);
                if (err == -EINPROGRESS || err == -EBUSY)
                        return;
+               else if (!err) {
+                       crypto_xor(pctx->auth_tag, pctx->iauth_tag, 16);
+                       gcm_enc_copy_hash(req, pctx);
+               }
        }
 
-       gcm_enc_hash_done(areq, err);
+       aead_request_complete(req, err);
 }
 
 static int crypto_gcm_encrypt(struct aead_request *req)
@@ -538,9 +576,8 @@ static void gcm_decrypt_done(struct crypto_async_request *areq, int err)
        aead_request_complete(req, err);
 }
 
-static void gcm_dec_hash_done(struct crypto_async_request *areq, int err)
+static void gcm_dec_hash_done(struct aead_request *req, int err)
 {
-       struct aead_request *req = areq->data;
        struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req);
        struct ablkcipher_request *abreq = &pctx->u.abreq;
        struct crypto_gcm_ghash_ctx *gctx = &pctx->ghash_ctx;
@@ -552,9 +589,11 @@ static void gcm_dec_hash_done(struct crypto_async_request *areq, int err)
                err = crypto_ablkcipher_decrypt(abreq);
                if (err == -EINPROGRESS || err == -EBUSY)
                        return;
+               else if (!err)
+                       err = crypto_gcm_verify(req, pctx);
        }
 
-       gcm_decrypt_done(areq, err);
+       aead_request_complete(req, err);
 }
 
 static int crypto_gcm_decrypt(struct aead_request *req)
index cd80d1dd195093fc726bc9253a8f1423dc79d4a2..57bdaf6ffab1b43e1f91dfb35c04bdc8422db7fe 100644 (file)
@@ -203,8 +203,9 @@ static const union acpi_predefined_info predefined_names[] =
        {{"_BCT", 1, ACPI_RTYPE_INTEGER}},
        {{"_BDN", 0, ACPI_RTYPE_INTEGER}},
        {{"_BFS", 1, 0}},
-       {{"_BIF", 0, ACPI_RTYPE_PACKAGE}}, /* Fixed-length (9 Int),(4 Str) */
-                         {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 9, ACPI_RTYPE_STRING}, 4,0}},
+       {{"_BIF", 0, ACPI_RTYPE_PACKAGE} }, /* Fixed-length (9 Int),(4 Str/Buf) */
+                         {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 9,
+                            ACPI_RTYPE_STRING | ACPI_RTYPE_BUFFER}, 4, 0} },
 
        {{"_BIX", 0, ACPI_RTYPE_PACKAGE}},      /* Fixed-length (16 Int),(4 Str) */
        {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 16, ACPI_RTYPE_STRING}, 4,
index e56b2a7b53db2dcc4735287edaeb10a7c54a3d56..23e5a0519af552d27ddcb9f8c14aa38062b434ea 100644 (file)
@@ -224,6 +224,7 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = {
         * _OSI(Linux) helps sound
         * DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad R61"),
         * DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T61"),
+        * T400, T500
         * _OSI(Linux) has Linux specific hooks
         * DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad X61"),
         * _OSI(Linux) is a NOP:
@@ -254,6 +255,22 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = {
                     DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad X61"),
                },
        },
+       {
+       .callback = dmi_enable_osi_linux,
+       .ident = "Lenovo ThinkPad T400",
+       .matches = {
+                    DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+                    DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T400"),
+               },
+       },
+       {
+       .callback = dmi_enable_osi_linux,
+       .ident = "Lenovo ThinkPad T500",
+       .matches = {
+                    DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+                    DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T500"),
+               },
+       },
        {}
 };
 
index 4cc1b8116e76acd7b8edfbfca294d3e4f64bbc64..5f2c379ab7bfba1903158f5c3f94cf37631a6c44 100644 (file)
@@ -430,6 +430,14 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = {
        },
        {
        .callback = init_set_sci_en_on_resume,
+       .ident = "Hewlett-Packard Compaq Presario C700 Notebook PC",
+       .matches = {
+               DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
+               DMI_MATCH(DMI_PRODUCT_NAME, "Compaq Presario C700 Notebook PC"),
+               },
+       },
+       {
+       .callback = init_set_sci_en_on_resume,
        .ident = "Hewlett-Packard Compaq Presario CQ40 Notebook PC",
        .matches = {
                DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
index dc99e26f8e5ba8c5d1a5635de6816d2a868a44bb..1b392c9e853134ebe5180b61c88e6451252e198d 100644 (file)
@@ -177,9 +177,6 @@ static struct ata_port_operations pcmcia_8bit_port_ops = {
        .drain_fifo     = pcmcia_8bit_drain_fifo,
 };
 
-#define CS_CHECK(fn, ret) \
-do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
-
 
 struct pcmcia_config_check {
        unsigned long ctl_base;
@@ -252,7 +249,7 @@ static int pcmcia_init_one(struct pcmcia_device *pdev)
        struct ata_port *ap;
        struct ata_pcmcia_info *info;
        struct pcmcia_config_check *stk = NULL;
-       int last_ret = 0, last_fn = 0, is_kme = 0, ret = -ENOMEM, p;
+       int is_kme = 0, ret = -ENOMEM, p;
        unsigned long io_base, ctl_base;
        void __iomem *io_addr, *ctl_addr;
        int n_ports = 1;
@@ -271,7 +268,6 @@ static int pcmcia_init_one(struct pcmcia_device *pdev)
        pdev->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
        pdev->io.IOAddrLines = 3;
        pdev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
-       pdev->irq.IRQInfo1 = IRQ_LEVEL_ID;
        pdev->conf.Attributes = CONF_ENABLE_IRQ;
        pdev->conf.IntType = INT_MEMORY_AND_IO;
 
@@ -296,8 +292,13 @@ static int pcmcia_init_one(struct pcmcia_device *pdev)
        }
        io_base = pdev->io.BasePort1;
        ctl_base = stk->ctl_base;
-       CS_CHECK(RequestIRQ, pcmcia_request_irq(pdev, &pdev->irq));
-       CS_CHECK(RequestConfiguration, pcmcia_request_configuration(pdev, &pdev->conf));
+       ret = pcmcia_request_irq(pdev, &pdev->irq);
+       if (ret)
+               goto failed;
+
+       ret = pcmcia_request_configuration(pdev, &pdev->conf);
+       if (ret)
+               goto failed;
 
        /* iomap */
        ret = -ENOMEM;
@@ -351,8 +352,6 @@ static int pcmcia_init_one(struct pcmcia_device *pdev)
        kfree(stk);
        return 0;
 
-cs_failed:
-       cs_error(pdev, last_fn, last_ret);
 failed:
        kfree(stk);
        info->ndev = 0;
index d344db42a00251cb4b1206672ad6c453927d7463..172b57e6543fca8a9d0750ae37ad3d7d258762f8 100644 (file)
@@ -707,34 +707,17 @@ static unsigned int sata_fsl_dev_classify(struct ata_port *ap)
        return ata_dev_classify(&tf);
 }
 
-static int sata_fsl_prereset(struct ata_link *link, unsigned long deadline)
-{
-       /* FIXME: Never skip softreset, sata_fsl_softreset() is
-        * combination of soft and hard resets.  sata_fsl_softreset()
-        * needs to be splitted into soft and hard resets.
-        */
-       return 0;
-}
-
-static int sata_fsl_softreset(struct ata_link *link, unsigned int *class,
+static int sata_fsl_hardreset(struct ata_link *link, unsigned int *class,
                                        unsigned long deadline)
 {
        struct ata_port *ap = link->ap;
-       struct sata_fsl_port_priv *pp = ap->private_data;
        struct sata_fsl_host_priv *host_priv = ap->host->private_data;
        void __iomem *hcr_base = host_priv->hcr_base;
-       int pmp = sata_srst_pmp(link);
        u32 temp;
-       struct ata_taskfile tf;
-       u8 *cfis;
-       u32 Serror;
        int i = 0;
        unsigned long start_jiffies;
 
-       DPRINTK("in xx_softreset\n");
-
-       if (pmp != SATA_PMP_CTRL_PORT)
-               goto issue_srst;
+       DPRINTK("in xx_hardreset\n");
 
 try_offline_again:
        /*
@@ -749,7 +732,7 @@ try_offline_again:
 
        if (temp & ONLINE) {
                ata_port_printk(ap, KERN_ERR,
-                               "Softreset failed, not off-lined %d\n", i);
+                               "Hardreset failed, not off-lined %d\n", i);
 
                /*
                 * Try to offline controller atleast twice
@@ -761,7 +744,7 @@ try_offline_again:
                        goto try_offline_again;
        }
 
-       DPRINTK("softreset, controller off-lined\n");
+       DPRINTK("hardreset, controller off-lined\n");
        VPRINTK("HStatus = 0x%x\n", ioread32(hcr_base + HSTATUS));
        VPRINTK("HControl = 0x%x\n", ioread32(hcr_base + HCONTROL));
 
@@ -786,11 +769,11 @@ try_offline_again:
 
        if (!(temp & ONLINE)) {
                ata_port_printk(ap, KERN_ERR,
-                               "Softreset failed, not on-lined\n");
+                               "Hardreset failed, not on-lined\n");
                goto err;
        }
 
-       DPRINTK("softreset, controller off-lined & on-lined\n");
+       DPRINTK("hardreset, controller off-lined & on-lined\n");
        VPRINTK("HStatus = 0x%x\n", ioread32(hcr_base + HSTATUS));
        VPRINTK("HControl = 0x%x\n", ioread32(hcr_base + HCONTROL));
 
@@ -806,7 +789,7 @@ try_offline_again:
                                "No Device OR PHYRDY change,Hstatus = 0x%x\n",
                                ioread32(hcr_base + HSTATUS));
                *class = ATA_DEV_NONE;
-               goto out;
+               return 0;
        }
 
        /*
@@ -819,11 +802,44 @@ try_offline_again:
        if ((temp & 0xFF) != 0x18) {
                ata_port_printk(ap, KERN_WARNING, "No Signature Update\n");
                *class = ATA_DEV_NONE;
-               goto out;
+               goto do_followup_srst;
        } else {
                ata_port_printk(ap, KERN_INFO,
                                "Signature Update detected @ %d msecs\n",
                                jiffies_to_msecs(jiffies - start_jiffies));
+               *class = sata_fsl_dev_classify(ap);
+               return 0;
+       }
+
+do_followup_srst:
+       /*
+        * request libATA to perform follow-up softreset
+        */
+       return -EAGAIN;
+
+err:
+       return -EIO;
+}
+
+static int sata_fsl_softreset(struct ata_link *link, unsigned int *class,
+                                       unsigned long deadline)
+{
+       struct ata_port *ap = link->ap;
+       struct sata_fsl_port_priv *pp = ap->private_data;
+       struct sata_fsl_host_priv *host_priv = ap->host->private_data;
+       void __iomem *hcr_base = host_priv->hcr_base;
+       int pmp = sata_srst_pmp(link);
+       u32 temp;
+       struct ata_taskfile tf;
+       u8 *cfis;
+       u32 Serror;
+
+       DPRINTK("in xx_softreset\n");
+
+       if (ata_link_offline(link)) {
+               DPRINTK("PHY reports no device\n");
+               *class = ATA_DEV_NONE;
+               return 0;
        }
 
        /*
@@ -834,7 +850,6 @@ try_offline_again:
         * reached here, we can send a command to the target device
         */
 
-issue_srst:
        DPRINTK("Sending SRST/device reset\n");
 
        ata_tf_init(link->device, &tf);
@@ -860,6 +875,8 @@ issue_srst:
                ioread32(CA + hcr_base), ioread32(CC + hcr_base));
 
        iowrite32(0xFFFF, CC + hcr_base);
+       if (pmp != SATA_PMP_CTRL_PORT)
+               iowrite32(pmp, CQPMP + hcr_base);
        iowrite32(1, CQ + hcr_base);
 
        temp = ata_wait_register(CQ + hcr_base, 0x1, 0x1, 1, 5000);
@@ -926,7 +943,6 @@ issue_srst:
                VPRINTK("cereg = 0x%x\n", ioread32(hcr_base + CE));
        }
 
-out:
        return 0;
 
 err:
@@ -988,18 +1004,6 @@ static void sata_fsl_error_intr(struct ata_port *ap)
                ehi->err_mask |= AC_ERR_ATA_BUS;
                ehi->action |= ATA_EH_SOFTRESET;
 
-               /*
-                * Ignore serror in case of fatal errors as we always want
-                * to do a soft-reset of the FSL SATA controller. Analyzing
-                * serror may cause libata to schedule a hard-reset action,
-                * and hard-reset currently does not do controller
-                * offline/online, causing command timeouts and leads to an
-                * un-recoverable state, hence make libATA ignore
-                * autopsy in case of fatal errors.
-                */
-
-               ehi->flags |= ATA_EHI_NO_AUTOPSY;
-
                freeze = 1;
        }
 
@@ -1267,8 +1271,8 @@ static struct ata_port_operations sata_fsl_ops = {
 
        .freeze = sata_fsl_freeze,
        .thaw = sata_fsl_thaw,
-       .prereset = sata_fsl_prereset,
        .softreset = sata_fsl_softreset,
+       .hardreset = sata_fsl_hardreset,
        .pmp_softreset = sata_fsl_softreset,
        .error_handler = sata_fsl_error_handler,
        .post_internal_cmd = sata_fsl_post_internal_cmd,
index a770498a74ece95daa7f2eade9434e0e7518e095..846d89e3d12294d423af8a38ff57373d0b6f4505 100644 (file)
@@ -328,11 +328,11 @@ int __pm_runtime_resume(struct device *dev, bool from_wq)
                 * necessary.
                 */
                parent = dev->parent;
-               spin_unlock_irq(&dev->power.lock);
+               spin_unlock(&dev->power.lock);
 
                pm_runtime_get_noresume(parent);
 
-               spin_lock_irq(&parent->power.lock);
+               spin_lock(&parent->power.lock);
                /*
                 * We can resume if the parent's run-time PM is disabled or it
                 * is set to ignore children.
@@ -343,9 +343,9 @@ int __pm_runtime_resume(struct device *dev, bool from_wq)
                        if (parent->power.runtime_status != RPM_ACTIVE)
                                retval = -EBUSY;
                }
-               spin_unlock_irq(&parent->power.lock);
+               spin_unlock(&parent->power.lock);
 
-               spin_lock_irq(&dev->power.lock);
+               spin_lock(&dev->power.lock);
                if (retval)
                        goto out;
                goto repeat;
@@ -777,7 +777,7 @@ int __pm_runtime_set_status(struct device *dev, unsigned int status)
        }
 
        if (parent) {
-               spin_lock_irq(&parent->power.lock);
+               spin_lock(&parent->power.lock);
 
                /*
                 * It is invalid to put an active child under a parent that is
@@ -793,7 +793,7 @@ int __pm_runtime_set_status(struct device *dev, unsigned int status)
                                atomic_inc(&parent->power.child_count);
                }
 
-               spin_unlock_irq(&parent->power.lock);
+               spin_unlock(&parent->power.lock);
 
                if (error)
                        goto out;
index 965ece2c7e4da6040454443395adb89240eaa475..13bb69d2abb3307d8cb95c9f21e04e0c7b2e9ae8 100644 (file)
@@ -735,6 +735,21 @@ diskstats(struct gendisk *disk, struct bio *bio, ulong duration, sector_t sector
        part_stat_unlock();
 }
 
+/*
+ * Ensure we don't create aliases in VI caches
+ */
+static inline void
+killalias(struct bio *bio)
+{
+       struct bio_vec *bv;
+       int i;
+
+       if (bio_data_dir(bio) == READ)
+               __bio_for_each_segment(bv, bio, i, 0) {
+                       flush_dcache_page(bv->bv_page);
+               }
+}
+
 void
 aoecmd_ata_rsp(struct sk_buff *skb)
 {
@@ -853,8 +868,12 @@ aoecmd_ata_rsp(struct sk_buff *skb)
 
        if (buf && --buf->nframesout == 0 && buf->resid == 0) {
                diskstats(d->gd, buf->bio, jiffies - buf->stime, buf->sector);
-               n = (buf->flags & BUFFL_FAIL) ? -EIO : 0;
-               bio_endio(buf->bio, n);
+               if (buf->flags & BUFFL_FAIL)
+                       bio_endio(buf->bio, -EIO);
+               else {
+                       killalias(buf->bio);
+                       bio_endio(buf->bio, 0);
+               }
                mempool_free(buf, d->bufpool);
        }
 
index 6399e5090df4d59175063ae1b158f7b77e8a41e3..92b126394fa1f1f9605bd5227242fbd9d01c691b 100644 (file)
@@ -482,7 +482,7 @@ static ssize_t host_store_rescan(struct device *dev,
 
        return count;
 }
-DEVICE_ATTR(rescan, S_IWUSR, NULL, host_store_rescan);
+static DEVICE_ATTR(rescan, S_IWUSR, NULL, host_store_rescan);
 
 static ssize_t dev_show_unique_id(struct device *dev,
                                 struct device_attribute *attr,
@@ -512,7 +512,7 @@ static ssize_t dev_show_unique_id(struct device *dev,
                                sn[8], sn[9], sn[10], sn[11],
                                sn[12], sn[13], sn[14], sn[15]);
 }
-DEVICE_ATTR(unique_id, S_IRUGO, dev_show_unique_id, NULL);
+static DEVICE_ATTR(unique_id, S_IRUGO, dev_show_unique_id, NULL);
 
 static ssize_t dev_show_vendor(struct device *dev,
                               struct device_attribute *attr,
@@ -536,7 +536,7 @@ static ssize_t dev_show_vendor(struct device *dev,
        else
                return snprintf(buf, sizeof(vendor) + 1, "%s\n", drv->vendor);
 }
-DEVICE_ATTR(vendor, S_IRUGO, dev_show_vendor, NULL);
+static DEVICE_ATTR(vendor, S_IRUGO, dev_show_vendor, NULL);
 
 static ssize_t dev_show_model(struct device *dev,
                              struct device_attribute *attr,
@@ -560,7 +560,7 @@ static ssize_t dev_show_model(struct device *dev,
        else
                return snprintf(buf, sizeof(model) + 1, "%s\n", drv->model);
 }
-DEVICE_ATTR(model, S_IRUGO, dev_show_model, NULL);
+static DEVICE_ATTR(model, S_IRUGO, dev_show_model, NULL);
 
 static ssize_t dev_show_rev(struct device *dev,
                            struct device_attribute *attr,
@@ -584,7 +584,7 @@ static ssize_t dev_show_rev(struct device *dev,
        else
                return snprintf(buf, sizeof(rev) + 1, "%s\n", drv->rev);
 }
-DEVICE_ATTR(rev, S_IRUGO, dev_show_rev, NULL);
+static DEVICE_ATTR(rev, S_IRUGO, dev_show_rev, NULL);
 
 static ssize_t cciss_show_lunid(struct device *dev,
                                struct device_attribute *attr, char *buf)
@@ -609,7 +609,7 @@ static ssize_t cciss_show_lunid(struct device *dev,
                lunid[0], lunid[1], lunid[2], lunid[3],
                lunid[4], lunid[5], lunid[6], lunid[7]);
 }
-DEVICE_ATTR(lunid, S_IRUGO, cciss_show_lunid, NULL);
+static DEVICE_ATTR(lunid, S_IRUGO, cciss_show_lunid, NULL);
 
 static ssize_t cciss_show_raid_level(struct device *dev,
                                     struct device_attribute *attr, char *buf)
@@ -632,7 +632,7 @@ static ssize_t cciss_show_raid_level(struct device *dev,
        return snprintf(buf, strlen(raid_label[raid]) + 7, "RAID %s\n",
                        raid_label[raid]);
 }
-DEVICE_ATTR(raid_level, S_IRUGO, cciss_show_raid_level, NULL);
+static DEVICE_ATTR(raid_level, S_IRUGO, cciss_show_raid_level, NULL);
 
 static ssize_t cciss_show_usage_count(struct device *dev,
                                      struct device_attribute *attr, char *buf)
@@ -651,7 +651,7 @@ static ssize_t cciss_show_usage_count(struct device *dev,
        spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
        return snprintf(buf, 20, "%d\n", count);
 }
-DEVICE_ATTR(usage_count, S_IRUGO, cciss_show_usage_count, NULL);
+static DEVICE_ATTR(usage_count, S_IRUGO, cciss_show_usage_count, NULL);
 
 static struct attribute *cciss_host_attrs[] = {
        &dev_attr_rescan.attr,
index b0e569ba730d0e7ef1d8fafdcfee3ff20ab1a456..2acdc605cb4b670beefb8b0bf0ef326ff9c123e5 100644 (file)
@@ -867,11 +867,9 @@ static int bluecard_probe(struct pcmcia_device *link)
 
        link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
        link->io.NumPorts1 = 8;
-       link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
-       link->irq.IRQInfo1 = IRQ_LEVEL_ID;
+       link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
 
        link->irq.Handler = bluecard_interrupt;
-       link->irq.Instance = info;
 
        link->conf.Attributes = CONF_ENABLE_IRQ;
        link->conf.IntType = INT_MEMORY_AND_IO;
@@ -905,22 +903,16 @@ static int bluecard_config(struct pcmcia_device *link)
                        break;
        }
 
-       if (i != 0) {
-               cs_error(link, RequestIO, i);
+       if (i != 0)
                goto failed;
-       }
 
        i = pcmcia_request_irq(link, &link->irq);
-       if (i != 0) {
-               cs_error(link, RequestIRQ, i);
+       if (i != 0)
                link->irq.AssignedIRQ = 0;
-       }
 
        i = pcmcia_request_configuration(link, &link->conf);
-       if (i != 0) {
-               cs_error(link, RequestConfiguration, i);
+       if (i != 0)
                goto failed;
-       }
 
        if (bluecard_open(info) != 0)
                goto failed;
index d58e22b9f06a46b2b6a082703f822519f0b815b7..d814a2755ccbe756310261698fd41d3740fc2ced 100644 (file)
@@ -659,11 +659,9 @@ static int bt3c_probe(struct pcmcia_device *link)
 
        link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
        link->io.NumPorts1 = 8;
-       link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
-       link->irq.IRQInfo1 = IRQ_LEVEL_ID;
+       link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
 
        link->irq.Handler = bt3c_interrupt;
-       link->irq.Instance = info;
 
        link->conf.Attributes = CONF_ENABLE_IRQ;
        link->conf.IntType = INT_MEMORY_AND_IO;
@@ -740,21 +738,16 @@ static int bt3c_config(struct pcmcia_device *link)
                goto found_port;
 
        BT_ERR("No usable port range found");
-       cs_error(link, RequestIO, -ENODEV);
        goto failed;
 
 found_port:
        i = pcmcia_request_irq(link, &link->irq);
-       if (i != 0) {
-               cs_error(link, RequestIRQ, i);
+       if (i != 0)
                link->irq.AssignedIRQ = 0;
-       }
 
        i = pcmcia_request_configuration(link, &link->conf);
-       if (i != 0) {
-               cs_error(link, RequestConfiguration, i);
+       if (i != 0)
                goto failed;
-       }
 
        if (bt3c_open(info) != 0)
                goto failed;
index efd689a062eb231dcd95c58af780822d0f00c479..d339464dc15e7f06602e58c988e74961377447b9 100644 (file)
@@ -588,11 +588,9 @@ static int btuart_probe(struct pcmcia_device *link)
 
        link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
        link->io.NumPorts1 = 8;
-       link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
-       link->irq.IRQInfo1 = IRQ_LEVEL_ID;
+       link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
 
        link->irq.Handler = btuart_interrupt;
-       link->irq.Instance = info;
 
        link->conf.Attributes = CONF_ENABLE_IRQ;
        link->conf.IntType = INT_MEMORY_AND_IO;
@@ -669,21 +667,16 @@ static int btuart_config(struct pcmcia_device *link)
                goto found_port;
 
        BT_ERR("No usable port range found");
-       cs_error(link, RequestIO, -ENODEV);
        goto failed;
 
 found_port:
        i = pcmcia_request_irq(link, &link->irq);
-       if (i != 0) {
-               cs_error(link, RequestIRQ, i);
+       if (i != 0)
                link->irq.AssignedIRQ = 0;
-       }
 
        i = pcmcia_request_configuration(link, &link->conf);
-       if (i != 0) {
-               cs_error(link, RequestConfiguration, i);
+       if (i != 0)
                goto failed;
-       }
 
        if (btuart_open(info) != 0)
                goto failed;
index 2fb38027f3bb8773da3d380c8322cbb947c2ea57..44bc8bbabf5474948d59eb8ce15cff6bef11b819 100644 (file)
@@ -600,11 +600,13 @@ static int btusb_close(struct hci_dev *hdev)
        btusb_stop_traffic(data);
        err = usb_autopm_get_interface(data->intf);
        if (err < 0)
-               return 0;
+               goto failed;
 
        data->intf->needs_remote_wakeup = 0;
        usb_autopm_put_interface(data->intf);
 
+failed:
+       usb_scuttle_anchored_urbs(&data->deferred);
        return 0;
 }
 
index b881a9cd8741d78cb3c24adfb3f868cb604c294d..4f02a6f3c980b246c1f9f9843d79e51da7cf2af1 100644 (file)
@@ -573,11 +573,9 @@ static int dtl1_probe(struct pcmcia_device *link)
 
        link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
        link->io.NumPorts1 = 8;
-       link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
-       link->irq.IRQInfo1 = IRQ_LEVEL_ID;
+       link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
 
        link->irq.Handler = dtl1_interrupt;
-       link->irq.Instance = info;
 
        link->conf.Attributes = CONF_ENABLE_IRQ;
        link->conf.IntType = INT_MEMORY_AND_IO;
@@ -622,16 +620,12 @@ static int dtl1_config(struct pcmcia_device *link)
                goto failed;
 
        i = pcmcia_request_irq(link, &link->irq);
-       if (i != 0) {
-               cs_error(link, RequestIRQ, i);
+       if (i != 0)
                link->irq.AssignedIRQ = 0;
-       }
 
        i = pcmcia_request_configuration(link, &link->conf);
-       if (i != 0) {
-               cs_error(link, RequestConfiguration, i);
+       if (i != 0)
                goto failed;
-       }
 
        if (dtl1_open(info) != 0)
                goto failed;
index ccb1fa89de2976e99bcb5d7bb94094f989e3b974..2fb3a480f6b07e1fdd41c2e2bf9fd02ad06ab4d5 100644 (file)
@@ -56,9 +56,8 @@ config AGP_AMD
          X on AMD Irongate, 761, and 762 chipsets.
 
 config AGP_AMD64
-       tristate "AMD Opteron/Athlon64 on-CPU GART support" if !GART_IOMMU
+       tristate "AMD Opteron/Athlon64 on-CPU GART support"
        depends on AGP && X86
-       default y if GART_IOMMU
        help
          This option gives you AGP support for the GLX component of
          X using the on-CPU northbridge of the AMD Athlon64/Opteron CPUs.
index 4068467ce7b93bcd8e82e1174603b089b868c6b9..3cb56a049e249eed3eac9abb7d0e0c012fae067c 100644 (file)
@@ -62,6 +62,7 @@
 #define PCI_DEVICE_ID_INTEL_IGDNG_D_IG     0x0042
 #define PCI_DEVICE_ID_INTEL_IGDNG_M_HB     0x0044
 #define PCI_DEVICE_ID_INTEL_IGDNG_MA_HB            0x0062
+#define PCI_DEVICE_ID_INTEL_IGDNG_MC2_HB    0x006a
 #define PCI_DEVICE_ID_INTEL_IGDNG_M_IG     0x0046
 
 /* cover 915 and 945 variants */
@@ -96,7 +97,8 @@
                agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_B43_HB || \
                agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDNG_D_HB || \
                agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDNG_M_HB || \
-               agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDNG_MA_HB)
+               agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDNG_MA_HB || \
+               agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDNG_MC2_HB)
 
 extern int agp_memory_reserved;
 
@@ -1161,12 +1163,6 @@ static int intel_i915_configure(void)
 
        intel_i9xx_setup_flush();
 
-#ifdef USE_PCI_DMA_API 
-       if (pci_set_dma_mask(intel_private.pcidev, DMA_BIT_MASK(36)))
-               dev_err(&intel_private.pcidev->dev,
-                       "set gfx device dma mask 36bit failed!\n");
-#endif
-
        return 0;
 }
 
@@ -1364,6 +1360,7 @@ static void intel_i965_get_gtt_range(int *gtt_offset, int *gtt_size)
        case PCI_DEVICE_ID_INTEL_IGDNG_D_HB:
        case PCI_DEVICE_ID_INTEL_IGDNG_M_HB:
        case PCI_DEVICE_ID_INTEL_IGDNG_MA_HB:
+       case PCI_DEVICE_ID_INTEL_IGDNG_MC2_HB:
                *gtt_offset = *gtt_size = MB(2);
                break;
        default:
@@ -2365,6 +2362,8 @@ static const struct intel_driver_description {
            "IGDNG/M", NULL, &intel_i965_driver },
        { PCI_DEVICE_ID_INTEL_IGDNG_MA_HB, PCI_DEVICE_ID_INTEL_IGDNG_M_IG, 0,
            "IGDNG/MA", NULL, &intel_i965_driver },
+       { PCI_DEVICE_ID_INTEL_IGDNG_MC2_HB, PCI_DEVICE_ID_INTEL_IGDNG_M_IG, 0,
+           "IGDNG/MC2", NULL, &intel_i965_driver },
        { 0, 0, 0, NULL, NULL, NULL }
 };
 
@@ -2456,6 +2455,11 @@ static int __devinit agp_intel_probe(struct pci_dev *pdev,
                                &bridge->mode);
        }
 
+       if (bridge->driver->mask_memory == intel_i965_mask_memory)
+               if (pci_set_dma_mask(intel_private.pcidev, DMA_BIT_MASK(36)))
+                       dev_err(&intel_private.pcidev->dev,
+                               "set gfx device dma mask 36bit failed!\n");
+
        pci_set_drvdata(pdev, bridge);
        return agp_add_bridge(bridge);
 }
@@ -2561,6 +2565,7 @@ static struct pci_device_id agp_intel_pci_table[] = {
        ID(PCI_DEVICE_ID_INTEL_IGDNG_D_HB),
        ID(PCI_DEVICE_ID_INTEL_IGDNG_M_HB),
        ID(PCI_DEVICE_ID_INTEL_IGDNG_MA_HB),
+       ID(PCI_DEVICE_ID_INTEL_IGDNG_MC2_HB),
        { }
 };
 
index 737be953cc589c5a75750ad47cb89726598ef3a9..950837cf9e9c3881718d161e4185c6fc1194b9cb 100644 (file)
@@ -1249,7 +1249,7 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw)
 
        if (keycode >= NR_KEYS)
                if (keycode >= KEY_BRL_DOT1 && keycode <= KEY_BRL_DOT8)
-                       keysym = K(KT_BRL, keycode - KEY_BRL_DOT1 + 1);
+                       keysym = U(K(KT_BRL, keycode - KEY_BRL_DOT1 + 1));
                else
                        return;
        else
index c250a31efa537c1f15ab8466b20bcc779ba214f3..2db4c0a29b052540ba988e05a5c217804c3d5aed 100644 (file)
@@ -23,8 +23,6 @@
   * All rights reserved. Licensed under dual BSD/GPL license.
   */
 
-/* #define PCMCIA_DEBUG 6 */
-
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/slab.h>
 
 /* #define ATR_CSUM */
 
-#ifdef PCMCIA_DEBUG
-#define reader_to_dev(x)       (&handle_to_dev(x->p_dev))
-static int pc_debug = PCMCIA_DEBUG;
-module_param(pc_debug, int, 0600);
-#define DEBUGP(n, rdr, x, args...) do {                                \
-       if (pc_debug >= (n))                                            \
-               dev_printk(KERN_DEBUG, reader_to_dev(rdr), "%s:" x,     \
-                          __func__ , ## args);                 \
+#define reader_to_dev(x)       (&x->p_dev->dev)
+
+/* n (debug level) is ignored */
+/* additional debug output may be enabled by re-compiling with
+ * CM4000_DEBUG set */
+/* #define CM4000_DEBUG */
+#define DEBUGP(n, rdr, x, args...) do {                \
+               dev_dbg(reader_to_dev(rdr), "%s:" x,    \
+                          __func__ , ## args);         \
        } while (0)
-#else
-#define DEBUGP(n, rdr, x, args...)
-#endif
+
 static char *version = "cm4000_cs.c v2.4.0gm6 - All bugs added by Harald Welte";
 
 #define        T_1SEC          (HZ)
@@ -174,14 +171,13 @@ static unsigned char fi_di_table[10][14] = {
 /* 9 */ {0x09,0x19,0x29,0x39,0x49,0x59,0x69,0x11,0x11,0x99,0xA9,0xB9,0xC9,0xD9}
 };
 
-#ifndef PCMCIA_DEBUG
+#ifndef CM4000_DEBUG
 #define        xoutb   outb
 #define        xinb    inb
 #else
 static inline void xoutb(unsigned char val, unsigned short port)
 {
-       if (pc_debug >= 7)
-               printk(KERN_DEBUG "outb(val=%.2x,port=%.4x)\n", val, port);
+       pr_debug("outb(val=%.2x,port=%.4x)\n", val, port);
        outb(val, port);
 }
 static inline unsigned char xinb(unsigned short port)
@@ -189,8 +185,7 @@ static inline unsigned char xinb(unsigned short port)
        unsigned char val;
 
        val = inb(port);
-       if (pc_debug >= 7)
-               printk(KERN_DEBUG "%.2x=inb(%.4x)\n", val, port);
+       pr_debug("%.2x=inb(%.4x)\n", val, port);
 
        return val;
 }
@@ -514,12 +509,10 @@ static int set_protocol(struct cm4000_dev *dev, struct ptsreq *ptsreq)
        for (i = 0; i < 4; i++) {
                xoutb(i, REG_BUF_ADDR(iobase));
                xoutb(dev->pts[i], REG_BUF_DATA(iobase));       /* buf data */
-#ifdef PCMCIA_DEBUG
-               if (pc_debug >= 5)
-                       printk("0x%.2x ", dev->pts[i]);
+#ifdef CM4000_DEBUG
+               pr_debug("0x%.2x ", dev->pts[i]);
        }
-       if (pc_debug >= 5)
-               printk("\n");
+       pr_debug("\n");
 #else
        }
 #endif
@@ -579,14 +572,13 @@ static int set_protocol(struct cm4000_dev *dev, struct ptsreq *ptsreq)
                pts_reply[i] = inb(REG_BUF_DATA(iobase));
        }
 
-#ifdef PCMCIA_DEBUG
+#ifdef CM4000_DEBUG
        DEBUGP(2, dev, "PTSreply: ");
        for (i = 0; i < num_bytes_read; i++) {
-               if (pc_debug >= 5)
-                       printk("0x%.2x ", pts_reply[i]);
+               pr_debug("0x%.2x ", pts_reply[i]);
        }
-       printk("\n");
-#endif /* PCMCIA_DEBUG */
+       pr_debug("\n");
+#endif /* CM4000_DEBUG */
 
        DEBUGP(5, dev, "Clear Tactive in Flags1\n");
        xoutb(0x20, REG_FLAGS1(iobase));
@@ -655,7 +647,7 @@ static void terminate_monitor(struct cm4000_dev *dev)
 
        DEBUGP(5, dev, "Delete timer\n");
        del_timer_sync(&dev->timer);
-#ifdef PCMCIA_DEBUG
+#ifdef CM4000_DEBUG
        dev->monitor_running = 0;
 #endif
 
@@ -898,7 +890,7 @@ static void monitor_card(unsigned long p)
                                DEBUGP(4, dev, "ATR checksum (0x%.2x, should "
                                       "be zero) failed\n", dev->atr_csum);
                        }
-#ifdef PCMCIA_DEBUG
+#ifdef CM4000_DEBUG
                        else if (test_bit(IS_BAD_LENGTH, &dev->flags)) {
                                DEBUGP(4, dev, "ATR length error\n");
                        } else {
@@ -1415,7 +1407,7 @@ static long cmm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
        int size;
        int rc;
        void __user *argp = (void __user *)arg;
-#ifdef PCMCIA_DEBUG
+#ifdef CM4000_DEBUG
        char *ioctl_names[CM_IOC_MAXNR + 1] = {
                [_IOC_NR(CM_IOCGSTATUS)] "CM_IOCGSTATUS",
                [_IOC_NR(CM_IOCGATR)] "CM_IOCGATR",
@@ -1423,9 +1415,9 @@ static long cmm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
                [_IOC_NR(CM_IOCSPTS)] "CM_IOCSPTS",
                [_IOC_NR(CM_IOSDBGLVL)] "CM4000_DBGLVL",
        };
-#endif
        DEBUGP(3, dev, "cmm_ioctl(device=%d.%d) %s\n", imajor(inode),
               iminor(inode), ioctl_names[_IOC_NR(cmd)]);
+#endif
 
        lock_kernel();
        rc = -ENODEV;
@@ -1523,7 +1515,7 @@ static long cmm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
                }
        case CM_IOCARDOFF:
 
-#ifdef PCMCIA_DEBUG
+#ifdef CM4000_DEBUG
                DEBUGP(4, dev, "... in CM_IOCARDOFF\n");
                if (dev->flags0 & 0x01) {
                        DEBUGP(4, dev, "    Card inserted\n");
@@ -1625,18 +1617,9 @@ static long cmm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 
                }
                break;
-#ifdef PCMCIA_DEBUG
-       case CM_IOSDBGLVL:      /* set debug log level */
-               {
-                       int old_pc_debug = 0;
-
-                       old_pc_debug = pc_debug;
-                       if (copy_from_user(&pc_debug, argp, sizeof(int)))
-                               rc = -EFAULT;
-                       else if (old_pc_debug != pc_debug)
-                               DEBUGP(0, dev, "Changed debug log level "
-                                      "to %i\n", pc_debug);
-               }
+#ifdef CM4000_DEBUG
+       case CM_IOSDBGLVL:
+               rc = -ENOTTY;
                break;
 #endif
        default:
index 4f0723b07974615f5177134b49deb671580e8813..a6a70e476beaf4babb7446643775d92ed5866635 100644 (file)
@@ -17,8 +17,6 @@
  * All rights reserved, Dual BSD/GPL Licensed.
  */
 
-/* #define PCMCIA_DEBUG 6 */
-
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/slab.h>
 #include "cm4040_cs.h"
 
 
-#ifdef PCMCIA_DEBUG
-#define reader_to_dev(x)       (&handle_to_dev(x->p_dev))
-static int pc_debug = PCMCIA_DEBUG;
-module_param(pc_debug, int, 0600);
-#define DEBUGP(n, rdr, x, args...) do {                                \
-       if (pc_debug >= (n))                                            \
-               dev_printk(KERN_DEBUG, reader_to_dev(rdr), "%s:" x,     \
-                          __func__ , ##args);                  \
+#define reader_to_dev(x)       (&x->p_dev->dev)
+
+/* n (debug level) is ignored */
+/* additional debug output may be enabled by re-compiling with
+ * CM4040_DEBUG set */
+/* #define CM4040_DEBUG */
+#define DEBUGP(n, rdr, x, args...) do {                \
+               dev_dbg(reader_to_dev(rdr), "%s:" x,    \
+                          __func__ , ## args);         \
        } while (0)
-#else
-#define DEBUGP(n, rdr, x, args...)
-#endif
 
 static char *version =
 "OMNIKEY CardMan 4040 v1.1.0gm5 - All bugs added by Harald Welte";
@@ -90,14 +86,13 @@ struct reader_dev {
 
 static struct pcmcia_device *dev_table[CM_MAX_DEV];
 
-#ifndef PCMCIA_DEBUG
+#ifndef CM4040_DEBUG
 #define        xoutb   outb
 #define        xinb    inb
 #else
 static inline void xoutb(unsigned char val, unsigned short port)
 {
-       if (pc_debug >= 7)
-               printk(KERN_DEBUG "outb(val=%.2x,port=%.4x)\n", val, port);
+       pr_debug("outb(val=%.2x,port=%.4x)\n", val, port);
        outb(val, port);
 }
 
@@ -106,8 +101,7 @@ static inline unsigned char xinb(unsigned short port)
        unsigned char val;
 
        val = inb(port);
-       if (pc_debug >= 7)
-               printk(KERN_DEBUG "%.2x=inb(%.4x)\n", val, port);
+       pr_debug("%.2x=inb(%.4x)\n", val, port);
        return val;
 }
 #endif
@@ -260,23 +254,22 @@ static ssize_t cm4040_read(struct file *filp, char __user *buf,
                        return -EIO;
                }
                dev->r_buf[i] = xinb(iobase + REG_OFFSET_BULK_IN);
-#ifdef PCMCIA_DEBUG
-               if (pc_debug >= 6)
-                       printk(KERN_DEBUG "%lu:%2x ", i, dev->r_buf[i]);
+#ifdef CM4040_DEBUG
+               pr_debug("%lu:%2x ", i, dev->r_buf[i]);
        }
-       printk("\n");
+       pr_debug("\n");
 #else
        }
 #endif
 
        bytes_to_read = 5 + le32_to_cpu(*(__le32 *)&dev->r_buf[1]);
 
-       DEBUGP(6, dev, "BytesToRead=%lu\n", bytes_to_read);
+       DEBUGP(6, dev, "BytesToRead=%zu\n", bytes_to_read);
 
        min_bytes_to_read = min(count, bytes_to_read + 5);
        min_bytes_to_read = min_t(size_t, min_bytes_to_read, READ_WRITE_BUFFER_SIZE);
 
-       DEBUGP(6, dev, "Min=%lu\n", min_bytes_to_read);
+       DEBUGP(6, dev, "Min=%zu\n", min_bytes_to_read);
 
        for (i = 0; i < (min_bytes_to_read-5); i++) {
                rc = wait_for_bulk_in_ready(dev);
@@ -288,11 +281,10 @@ static ssize_t cm4040_read(struct file *filp, char __user *buf,
                        return -EIO;
                }
                dev->r_buf[i+5] = xinb(iobase + REG_OFFSET_BULK_IN);
-#ifdef PCMCIA_DEBUG
-               if (pc_debug >= 6)
-                       printk(KERN_DEBUG "%lu:%2x ", i, dev->r_buf[i]);
+#ifdef CM4040_DEBUG
+               pr_debug("%lu:%2x ", i, dev->r_buf[i]);
        }
-       printk("\n");
+       pr_debug("\n");
 #else
        }
 #endif
@@ -547,7 +539,7 @@ static int cm4040_config_check(struct pcmcia_device *p_dev,
        p_dev->io.IOAddrLines = cfg->io.flags & CISTPL_IO_LINES_MASK;
 
        rc = pcmcia_request_io(p_dev, &p_dev->io);
-       dev_printk(KERN_INFO, &handle_to_dev(p_dev),
+       dev_printk(KERN_INFO, &p_dev->dev,
                   "pcmcia_request_io returned 0x%x\n", rc);
        return rc;
 }
@@ -569,7 +561,7 @@ static int reader_config(struct pcmcia_device *link, int devno)
 
        fail_rc = pcmcia_request_configuration(link, &link->conf);
        if (fail_rc != 0) {
-               dev_printk(KERN_INFO, &handle_to_dev(link),
+               dev_printk(KERN_INFO, &link->dev,
                           "pcmcia_request_configuration failed 0x%x\n",
                           fail_rc);
                goto cs_release;
index 4c1820cad71230045624f002368c6c03efbd0061..99cffdab1056565c3e73276a3cf304a8224c5d8e 100644 (file)
@@ -1213,12 +1213,12 @@ static irqreturn_t ipwireless_handle_v2_v3_interrupt(int irq,
 
 irqreturn_t ipwireless_interrupt(int irq, void *dev_id)
 {
-       struct ipw_hardware *hw = dev_id;
+       struct ipw_dev *ipw = dev_id;
 
-       if (hw->hw_version == HW_VERSION_1)
-               return ipwireless_handle_v1_interrupt(irq, hw);
+       if (ipw->hardware->hw_version == HW_VERSION_1)
+               return ipwireless_handle_v1_interrupt(irq, ipw->hardware);
        else
-               return ipwireless_handle_v2_v3_interrupt(irq, hw);
+               return ipwireless_handle_v2_v3_interrupt(irq, ipw->hardware);
 }
 
 static void flush_packets_to_hw(struct ipw_hardware *hw)
index 5216fce0c62d57ce6d2947750ac7dc22f1b82f0e..dff24dae1485e28e9e365b975fe5fb86f91e6249 100644 (file)
@@ -65,10 +65,7 @@ static void signalled_reboot_work(struct work_struct *work_reboot)
        struct ipw_dev *ipw = container_of(work_reboot, struct ipw_dev,
                        work_reboot);
        struct pcmcia_device *link = ipw->link;
-       int ret = pcmcia_reset_card(link->socket);
-
-       if (ret != 0)
-               cs_error(link, ResetCard, ret);
+       pcmcia_reset_card(link->socket);
 }
 
 static void signalled_reboot_callback(void *callback_data)
@@ -79,208 +76,127 @@ static void signalled_reboot_callback(void *callback_data)
        schedule_work(&ipw->work_reboot);
 }
 
-static int config_ipwireless(struct ipw_dev *ipw)
+static int ipwireless_probe(struct pcmcia_device *p_dev,
+                           cistpl_cftable_entry_t *cfg,
+                           cistpl_cftable_entry_t *dflt,
+                           unsigned int vcc,
+                           void *priv_data)
 {
-       struct pcmcia_device *link = ipw->link;
-       int ret;
-       tuple_t tuple;
-       unsigned short buf[64];
-       cisparse_t parse;
-       unsigned short cor_value;
+       struct ipw_dev *ipw = priv_data;
+       struct resource *io_resource;
        memreq_t memreq_attr_memory;
        memreq_t memreq_common_memory;
+       int ret;
 
-       ipw->is_v2_card = 0;
-
-       tuple.Attributes = 0;
-       tuple.TupleData = (cisdata_t *) buf;
-       tuple.TupleDataMax = sizeof(buf);
-       tuple.TupleOffset = 0;
-
-       tuple.DesiredTuple = RETURN_FIRST_TUPLE;
-
-       ret = pcmcia_get_first_tuple(link, &tuple);
-
-       while (ret == 0) {
-               ret = pcmcia_get_tuple_data(link, &tuple);
-
-               if (ret != 0) {
-                       cs_error(link, GetTupleData, ret);
-                       goto exit0;
-               }
-               ret = pcmcia_get_next_tuple(link, &tuple);
-       }
-
-       tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
-
-       ret = pcmcia_get_first_tuple(link, &tuple);
-
-       if (ret != 0) {
-               cs_error(link, GetFirstTuple, ret);
-               goto exit0;
-       }
-
-       ret = pcmcia_get_tuple_data(link, &tuple);
-
-       if (ret != 0) {
-               cs_error(link, GetTupleData, ret);
-               goto exit0;
-       }
-
-       ret = pcmcia_parse_tuple(&tuple, &parse);
-
-       if (ret != 0) {
-               cs_error(link, ParseTuple, ret);
-               goto exit0;
-       }
-
-       link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
-       link->io.BasePort1 = parse.cftable_entry.io.win[0].base;
-       link->io.NumPorts1 = parse.cftable_entry.io.win[0].len;
-       link->io.IOAddrLines = 16;
-
-       link->irq.IRQInfo1 = parse.cftable_entry.irq.IRQInfo1;
+       p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
+       p_dev->io.BasePort1 = cfg->io.win[0].base;
+       p_dev->io.NumPorts1 = cfg->io.win[0].len;
+       p_dev->io.IOAddrLines = 16;
 
        /* 0x40 causes it to generate level mode interrupts. */
        /* 0x04 enables IREQ pin. */
-       cor_value = parse.cftable_entry.index | 0x44;
-       link->conf.ConfigIndex = cor_value;
+       p_dev->conf.ConfigIndex = cfg->index | 0x44;
+       ret = pcmcia_request_io(p_dev, &p_dev->io);
+       if (ret)
+               return ret;
 
-       /* IRQ and I/O settings */
-       tuple.DesiredTuple = CISTPL_CONFIG;
+       io_resource = request_region(p_dev->io.BasePort1, p_dev->io.NumPorts1,
+                               IPWIRELESS_PCCARD_NAME);
 
-       ret = pcmcia_get_first_tuple(link, &tuple);
+       if (cfg->mem.nwin == 0)
+               return 0;
 
-       if (ret != 0) {
-               cs_error(link, GetFirstTuple, ret);
-               goto exit0;
-       }
+       ipw->request_common_memory.Attributes =
+               WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_CM | WIN_ENABLE;
+       ipw->request_common_memory.Base = cfg->mem.win[0].host_addr;
+       ipw->request_common_memory.Size = cfg->mem.win[0].len;
+       if (ipw->request_common_memory.Size < 0x1000)
+               ipw->request_common_memory.Size = 0x1000;
+       ipw->request_common_memory.AccessSpeed = 0;
 
-       ret = pcmcia_get_tuple_data(link, &tuple);
-
-       if (ret != 0) {
-               cs_error(link, GetTupleData, ret);
-               goto exit0;
-       }
+       ret = pcmcia_request_window(p_dev, &ipw->request_common_memory,
+                               &ipw->handle_common_memory);
 
-       ret = pcmcia_parse_tuple(&tuple, &parse);
+       if (ret != 0)
+               goto exit1;
 
-       if (ret != 0) {
-               cs_error(link, GetTupleData, ret);
-               goto exit0;
-       }
-       link->conf.Attributes = CONF_ENABLE_IRQ;
-       link->conf.ConfigBase = parse.config.base;
-       link->conf.Present = parse.config.rmask[0];
-       link->conf.IntType = INT_MEMORY_AND_IO;
+       memreq_common_memory.CardOffset = cfg->mem.win[0].card_addr;
+       memreq_common_memory.Page = 0;
 
-       link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
-       link->irq.Handler = ipwireless_interrupt;
-       link->irq.Instance = ipw->hardware;
+       ret = pcmcia_map_mem_page(p_dev, ipw->handle_common_memory,
+                               &memreq_common_memory);
 
-       ret = pcmcia_request_io(link, &link->io);
+       if (ret != 0)
+               goto exit2;
 
-       if (ret != 0) {
-               cs_error(link, RequestIO, ret);
-               goto exit0;
-       }
+       ipw->is_v2_card = cfg->mem.win[0].len == 0x100;
 
-       request_region(link->io.BasePort1, link->io.NumPorts1,
+       ipw->common_memory = ioremap(ipw->request_common_memory.Base,
+                               ipw->request_common_memory.Size);
+       request_mem_region(ipw->request_common_memory.Base,
+                       ipw->request_common_memory.Size,
                        IPWIRELESS_PCCARD_NAME);
 
-       /* memory settings */
-
-       tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
-
-       ret = pcmcia_get_first_tuple(link, &tuple);
-
-       if (ret != 0) {
-               cs_error(link, GetFirstTuple, ret);
-               goto exit1;
-       }
-
-       ret = pcmcia_get_tuple_data(link, &tuple);
+       ipw->request_attr_memory.Attributes =
+               WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_AM | WIN_ENABLE;
+       ipw->request_attr_memory.Base = 0;
+       ipw->request_attr_memory.Size = 0;      /* this used to be 0x1000 */
+       ipw->request_attr_memory.AccessSpeed = 0;
 
-       if (ret != 0) {
-               cs_error(link, GetTupleData, ret);
-               goto exit1;
-       }
-
-       ret = pcmcia_parse_tuple(&tuple, &parse);
-
-       if (ret != 0) {
-               cs_error(link, ParseTuple, ret);
-               goto exit1;
-       }
+       ret = pcmcia_request_window(p_dev, &ipw->request_attr_memory,
+                               &ipw->handle_attr_memory);
 
-       if (parse.cftable_entry.mem.nwin > 0) {
-               ipw->request_common_memory.Attributes =
-                       WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_CM | WIN_ENABLE;
-               ipw->request_common_memory.Base =
-                       parse.cftable_entry.mem.win[0].host_addr;
-               ipw->request_common_memory.Size = parse.cftable_entry.mem.win[0].len;
-               if (ipw->request_common_memory.Size < 0x1000)
-                       ipw->request_common_memory.Size = 0x1000;
-               ipw->request_common_memory.AccessSpeed = 0;
-
-               ret = pcmcia_request_window(&link, &ipw->request_common_memory,
-                               &ipw->handle_common_memory);
+       if (ret != 0)
+               goto exit2;
 
-               if (ret != 0) {
-                       cs_error(link, RequestWindow, ret);
-                       goto exit1;
-               }
+       memreq_attr_memory.CardOffset = 0;
+       memreq_attr_memory.Page = 0;
 
-               memreq_common_memory.CardOffset =
-                       parse.cftable_entry.mem.win[0].card_addr;
-               memreq_common_memory.Page = 0;
+       ret = pcmcia_map_mem_page(p_dev, ipw->handle_attr_memory,
+                               &memreq_attr_memory);
 
-               ret = pcmcia_map_mem_page(ipw->handle_common_memory,
-                               &memreq_common_memory);
+       if (ret != 0)
+               goto exit3;
 
-               if (ret != 0) {
-                       cs_error(link, MapMemPage, ret);
-                       goto exit1;
-               }
+       ipw->attr_memory = ioremap(ipw->request_attr_memory.Base,
+                               ipw->request_attr_memory.Size);
+       request_mem_region(ipw->request_attr_memory.Base,
+                       ipw->request_attr_memory.Size, IPWIRELESS_PCCARD_NAME);
 
-               ipw->is_v2_card =
-                       parse.cftable_entry.mem.win[0].len == 0x100;
+       return 0;
 
-               ipw->common_memory = ioremap(ipw->request_common_memory.Base,
+exit3:
+       pcmcia_release_window(p_dev, ipw->handle_attr_memory);
+exit2:
+       if (ipw->common_memory) {
+               release_mem_region(ipw->request_common_memory.Base,
                                ipw->request_common_memory.Size);
-               request_mem_region(ipw->request_common_memory.Base,
-                               ipw->request_common_memory.Size, IPWIRELESS_PCCARD_NAME);
-
-               ipw->request_attr_memory.Attributes =
-                       WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_AM | WIN_ENABLE;
-               ipw->request_attr_memory.Base = 0;
-               ipw->request_attr_memory.Size = 0;      /* this used to be 0x1000 */
-               ipw->request_attr_memory.AccessSpeed = 0;
-
-               ret = pcmcia_request_window(&link, &ipw->request_attr_memory,
-                               &ipw->handle_attr_memory);
+               iounmap(ipw->common_memory);
+               pcmcia_release_window(p_dev, ipw->handle_common_memory);
+       } else
+               pcmcia_release_window(p_dev, ipw->handle_common_memory);
+exit1:
+       release_resource(io_resource);
+       pcmcia_disable_device(p_dev);
+       return -1;
+}
 
-               if (ret != 0) {
-                       cs_error(link, RequestWindow, ret);
-                       goto exit2;
-               }
+static int config_ipwireless(struct ipw_dev *ipw)
+{
+       struct pcmcia_device *link = ipw->link;
+       int ret = 0;
 
-               memreq_attr_memory.CardOffset = 0;
-               memreq_attr_memory.Page = 0;
+       ipw->is_v2_card = 0;
 
-               ret = pcmcia_map_mem_page(ipw->handle_attr_memory,
-                               &memreq_attr_memory);
+       ret = pcmcia_loop_config(link, ipwireless_probe, ipw);
+       if (ret != 0)
+               return ret;
 
-               if (ret != 0) {
-                       cs_error(link, MapMemPage, ret);
-                       goto exit2;
-               }
+       link->conf.Attributes = CONF_ENABLE_IRQ;
+       link->conf.IntType = INT_MEMORY_AND_IO;
 
-               ipw->attr_memory = ioremap(ipw->request_attr_memory.Base,
-                               ipw->request_attr_memory.Size);
-               request_mem_region(ipw->request_attr_memory.Base, ipw->request_attr_memory.Size,
-                               IPWIRELESS_PCCARD_NAME);
-       }
+       link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
+       link->irq.Handler = ipwireless_interrupt;
 
        INIT_WORK(&ipw->work_reboot, signalled_reboot_work);
 
@@ -291,10 +207,8 @@ static int config_ipwireless(struct ipw_dev *ipw)
 
        ret = pcmcia_request_irq(link, &link->irq);
 
-       if (ret != 0) {
-               cs_error(link, RequestIRQ, ret);
-               goto exit3;
-       }
+       if (ret != 0)
+               goto exit;
 
        printk(KERN_INFO IPWIRELESS_PCCARD_NAME ": Card type %s\n",
                        ipw->is_v2_card ? "V2/V3" : "V1");
@@ -316,12 +230,12 @@ static int config_ipwireless(struct ipw_dev *ipw)
 
        ipw->network = ipwireless_network_create(ipw->hardware);
        if (!ipw->network)
-               goto exit3;
+               goto exit;
 
        ipw->tty = ipwireless_tty_create(ipw->hardware, ipw->network,
                        ipw->nodes);
        if (!ipw->tty)
-               goto exit3;
+               goto exit;
 
        ipwireless_init_hardware_v2_v3(ipw->hardware);
 
@@ -331,35 +245,27 @@ static int config_ipwireless(struct ipw_dev *ipw)
         */
        ret = pcmcia_request_configuration(link, &link->conf);
 
-       if (ret != 0) {
-               cs_error(link, RequestConfiguration, ret);
-               goto exit4;
-       }
+       if (ret != 0)
+               goto exit;
 
        link->dev_node = &ipw->nodes[0];
 
        return 0;
 
-exit4:
-       pcmcia_disable_device(link);
-exit3:
+exit:
        if (ipw->attr_memory) {
                release_mem_region(ipw->request_attr_memory.Base,
                                ipw->request_attr_memory.Size);
                iounmap(ipw->attr_memory);
-               pcmcia_release_window(ipw->handle_attr_memory);
-               pcmcia_disable_device(link);
+               pcmcia_release_window(link, ipw->handle_attr_memory);
        }
-exit2:
        if (ipw->common_memory) {
                release_mem_region(ipw->request_common_memory.Base,
                                ipw->request_common_memory.Size);
                iounmap(ipw->common_memory);
-               pcmcia_release_window(ipw->handle_common_memory);
+               pcmcia_release_window(link, ipw->handle_common_memory);
        }
-exit1:
        pcmcia_disable_device(link);
-exit0:
        return -1;
 }
 
@@ -378,9 +284,9 @@ static void release_ipwireless(struct ipw_dev *ipw)
                iounmap(ipw->attr_memory);
        }
        if (ipw->common_memory)
-               pcmcia_release_window(ipw->handle_common_memory);
+               pcmcia_release_window(ipw->link, ipw->handle_common_memory);
        if (ipw->attr_memory)
-               pcmcia_release_window(ipw->handle_attr_memory);
+               pcmcia_release_window(ipw->link, ipw->handle_attr_memory);
 
        /* Break the link with Card Services */
        pcmcia_disable_device(ipw->link);
@@ -406,7 +312,6 @@ static int ipwireless_attach(struct pcmcia_device *link)
 
        ipw->link = link;
        link->priv = ipw;
-       link->irq.Instance = ipw;
 
        /* Link this device into our device list. */
        link->dev_node = &ipw->nodes[0];
@@ -421,7 +326,6 @@ static int ipwireless_attach(struct pcmcia_device *link)
        ret = config_ipwireless(ipw);
 
        if (ret != 0) {
-               cs_error(link, RegisterClient, ret);
                ipwireless_detach(link);
                return ret;
        }
index caf6e4d194696204fa41632e220369a2ca2876a7..c31a0d913d370ae2f2354109bf3c57d410e6e155 100644 (file)
@@ -554,7 +554,6 @@ static int mgslpc_probe(struct pcmcia_device *link)
 
     /* Interrupt setup */
     link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
-    link->irq.IRQInfo1   = IRQ_LEVEL_ID;
     link->irq.Handler = NULL;
 
     link->conf.Attributes = 0;
@@ -572,69 +571,51 @@ static int mgslpc_probe(struct pcmcia_device *link)
 /* Card has been inserted.
  */
 
-#define CS_CHECK(fn, ret) \
-do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
+static int mgslpc_ioprobe(struct pcmcia_device *p_dev,
+                         cistpl_cftable_entry_t *cfg,
+                         cistpl_cftable_entry_t *dflt,
+                         unsigned int vcc,
+                         void *priv_data)
+{
+       if (cfg->io.nwin > 0) {
+               p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
+               if (!(cfg->io.flags & CISTPL_IO_8BIT))
+                       p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
+               if (!(cfg->io.flags & CISTPL_IO_16BIT))
+                       p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
+               p_dev->io.IOAddrLines = cfg->io.flags & CISTPL_IO_LINES_MASK;
+               p_dev->io.BasePort1 = cfg->io.win[0].base;
+               p_dev->io.NumPorts1 = cfg->io.win[0].len;
+               return pcmcia_request_io(p_dev, &p_dev->io);
+       }
+       return -ENODEV;
+}
 
 static int mgslpc_config(struct pcmcia_device *link)
 {
     MGSLPC_INFO *info = link->priv;
-    tuple_t tuple;
-    cisparse_t parse;
-    int last_fn, last_ret;
-    u_char buf[64];
-    cistpl_cftable_entry_t dflt = { 0 };
-    cistpl_cftable_entry_t *cfg;
+    int ret;
 
     if (debug_level >= DEBUG_LEVEL_INFO)
            printk("mgslpc_config(0x%p)\n", link);
 
-    tuple.Attributes = 0;
-    tuple.TupleData = buf;
-    tuple.TupleDataMax = sizeof(buf);
-    tuple.TupleOffset = 0;
-
-    /* get CIS configuration entry */
-
-    tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
-    CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
-
-    cfg = &(parse.cftable_entry);
-    CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
-    CS_CHECK(ParseTuple, pcmcia_parse_tuple(&tuple, &parse));
-
-    if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg;
-    if (cfg->index == 0)
-           goto cs_failed;
-
-    link->conf.ConfigIndex = cfg->index;
-    link->conf.Attributes |= CONF_ENABLE_IRQ;
-
-    /* IO window settings */
-    link->io.NumPorts1 = 0;
-    if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
-           cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
-           link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
-           if (!(io->flags & CISTPL_IO_8BIT))
-                   link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
-           if (!(io->flags & CISTPL_IO_16BIT))
-                   link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
-           link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
-           link->io.BasePort1 = io->win[0].base;
-           link->io.NumPorts1 = io->win[0].len;
-           CS_CHECK(RequestIO, pcmcia_request_io(link, &link->io));
-    }
+    ret = pcmcia_loop_config(link, mgslpc_ioprobe, NULL);
+    if (ret != 0)
+           goto failed;
 
     link->conf.Attributes = CONF_ENABLE_IRQ;
     link->conf.IntType = INT_MEMORY_AND_IO;
     link->conf.ConfigIndex = 8;
     link->conf.Present = PRESENT_OPTION;
 
-    link->irq.Attributes |= IRQ_HANDLE_PRESENT;
     link->irq.Handler     = mgslpc_isr;
-    link->irq.Instance    = info;
-    CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
 
-    CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
+    ret = pcmcia_request_irq(link, &link->irq);
+    if (ret)
+           goto failed;
+    ret = pcmcia_request_configuration(link, &link->conf);
+    if (ret)
+           goto failed;
 
     info->io_base = link->io.BasePort1;
     info->irq_level = link->irq.AssignedIRQ;
@@ -654,8 +635,7 @@ static int mgslpc_config(struct pcmcia_device *link)
     printk("\n");
     return 0;
 
-cs_failed:
-    cs_error(link, last_fn, last_ret);
+failed:
     mgslpc_release((u_long)link);
     return -ENODEV;
 }
index 47c2d276345665bb6e1c46ff2386d002e87853bc..f06bb37defb12d300eec4c7f5de67efa3d59b9f8 100644 (file)
@@ -31,7 +31,7 @@
 
 enum tpm_const {
        TPM_MINOR = 224,        /* officially assigned */
-       TPM_BUFSIZE = 2048,
+       TPM_BUFSIZE = 4096,
        TPM_NUM_DEVICES = 256,
 };
 
index 0b73e4ec1addafff42a79752a666fecd4b25d665..2405f17b29ddd87994f354e5530f264c726d5761 100644 (file)
@@ -257,6 +257,10 @@ out:
        return size;
 }
 
+static int itpm;
+module_param(itpm, bool, 0444);
+MODULE_PARM_DESC(itpm, "Force iTPM workarounds (found on some Lenovo laptops)");
+
 /*
  * If interrupts are used (signaled by an irq set in the vendor structure)
  * tpm.c can skip polling for the data to be available as the interrupt is
@@ -293,7 +297,7 @@ static int tpm_tis_send(struct tpm_chip *chip, u8 *buf, size_t len)
                wait_for_stat(chip, TPM_STS_VALID, chip->vendor.timeout_c,
                              &chip->vendor.int_queue);
                status = tpm_tis_status(chip);
-               if ((status & TPM_STS_DATA_EXPECT) == 0) {
+               if (!itpm && (status & TPM_STS_DATA_EXPECT) == 0) {
                        rc = -EIO;
                        goto out_err;
                }
@@ -467,6 +471,10 @@ static int tpm_tis_init(struct device *dev, resource_size_t start,
                 "1.2 TPM (device-id 0x%X, rev-id %d)\n",
                 vendor >> 16, ioread8(chip->vendor.iobase + TPM_RID(0)));
 
+       if (itpm)
+               dev_info(dev, "Intel iTPM workaround enabled\n");
+
+
        /* Figure out the capabilities */
        intfcaps =
            ioread32(chip->vendor.iobase +
@@ -629,6 +637,7 @@ static struct pnp_device_id tpm_pnp_tbl[] __devinitdata = {
        {"", 0},                /* User Specified */
        {"", 0}                 /* Terminator */
 };
+MODULE_DEVICE_TABLE(pnp, tpm_pnp_tbl);
 
 static __devexit void tpm_tis_pnp_remove(struct pnp_dev *dev)
 {
index a4bbb28f10be4473a0550e51466b14ee81a35b67..c63f3d33914a7def6b4e49d2f3d33a25dbf8fc0c 100644 (file)
@@ -219,8 +219,14 @@ int tty_port_block_til_ready(struct tty_port *port,
 
        /* if non-blocking mode is set we can pass directly to open unless
           the port has just hung up or is in another error state */
-       if ((filp->f_flags & O_NONBLOCK) ||
-                       (tty->flags & (1 << TTY_IO_ERROR))) {
+       if (tty->flags & (1 << TTY_IO_ERROR)) {
+               port->flags |= ASYNC_NORMAL_ACTIVE;
+               return 0;
+       }
+       if (filp->f_flags & O_NONBLOCK) {
+               /* Indicate we are open */
+               if (tty->termios->c_cflag & CBAUD)
+                       tty_port_raise_dtr_rts(port);
                port->flags |= ASYNC_NORMAL_ACTIVE;
                return 0;
        }
index ed86d3bf249a1e001a076e27985216cf94714d0e..6aa10284104aeb6e4bc3a22833ea347e67c5d976 100644 (file)
@@ -103,8 +103,8 @@ void vt_event_post(unsigned int event, unsigned int old, unsigned int new)
                ve->event.event = event;
                /* kernel view is consoles 0..n-1, user space view is
                   console 1..n with 0 meaning current, so we must bias */
-               ve->event.old = old + 1;
-               ve->event.new = new + 1;
+               ve->event.oldev = old + 1;
+               ve->event.newev = new + 1;
                wake = 1;
                ve->done = 1;
        }
@@ -186,7 +186,7 @@ int vt_waitactive(int n)
                vt_event_wait(&vw);
                if (vw.done == 0)
                        return -EINTR;
-       } while (vw.event.new != n);
+       } while (vw.event.newev != n);
        return 0;
 }
 
index 3938c7817095d0747a44045b51cff3c680e6e78a..ff57c40e9b8b94905ca090e79698390a66ad2583 100644 (file)
@@ -41,7 +41,7 @@ static struct cpufreq_driver *cpufreq_driver;
 static DEFINE_PER_CPU(struct cpufreq_policy *, cpufreq_cpu_data);
 #ifdef CONFIG_HOTPLUG_CPU
 /* This one keeps track of the previously set governor of a removed CPU */
-static DEFINE_PER_CPU(struct cpufreq_governor *, cpufreq_cpu_governor);
+static DEFINE_PER_CPU(char[CPUFREQ_NAME_LEN], cpufreq_cpu_governor);
 #endif
 static DEFINE_SPINLOCK(cpufreq_driver_lock);
 
@@ -774,10 +774,12 @@ int cpufreq_add_dev_policy(unsigned int cpu, struct cpufreq_policy *policy,
 #ifdef CONFIG_SMP
        unsigned long flags;
        unsigned int j;
-
 #ifdef CONFIG_HOTPLUG_CPU
-       if (per_cpu(cpufreq_cpu_governor, cpu)) {
-               policy->governor = per_cpu(cpufreq_cpu_governor, cpu);
+       struct cpufreq_governor *gov;
+
+       gov = __find_governor(per_cpu(cpufreq_cpu_governor, cpu));
+       if (gov) {
+               policy->governor = gov;
                dprintk("Restoring governor %s for cpu %d\n",
                       policy->governor->name, cpu);
        }
@@ -949,10 +951,13 @@ err_out_kobj_put:
 static int cpufreq_add_dev(struct sys_device *sys_dev)
 {
        unsigned int cpu = sys_dev->id;
-       int ret = 0;
+       int ret = 0, found = 0;
        struct cpufreq_policy *policy;
        unsigned long flags;
        unsigned int j;
+#ifdef CONFIG_HOTPLUG_CPU
+       int sibling;
+#endif
 
        if (cpu_is_offline(cpu))
                return 0;
@@ -999,7 +1004,19 @@ static int cpufreq_add_dev(struct sys_device *sys_dev)
        INIT_WORK(&policy->update, handle_update);
 
        /* Set governor before ->init, so that driver could check it */
-       policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
+#ifdef CONFIG_HOTPLUG_CPU
+       for_each_online_cpu(sibling) {
+               struct cpufreq_policy *cp = per_cpu(cpufreq_cpu_data, sibling);
+               if (cp && cp->governor &&
+                   (cpumask_test_cpu(cpu, cp->related_cpus))) {
+                       policy->governor = cp->governor;
+                       found = 1;
+                       break;
+               }
+       }
+#endif
+       if (!found)
+               policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
        /* call driver. From then on the cpufreq must be able
         * to accept all calls to ->verify and ->setpolicy for this CPU
         */
@@ -1111,7 +1128,8 @@ static int __cpufreq_remove_dev(struct sys_device *sys_dev)
 #ifdef CONFIG_SMP
 
 #ifdef CONFIG_HOTPLUG_CPU
-       per_cpu(cpufreq_cpu_governor, cpu) = data->governor;
+       strncpy(per_cpu(cpufreq_cpu_governor, cpu), data->governor->name,
+                       CPUFREQ_NAME_LEN);
 #endif
 
        /* if we have other CPUs still registered, we need to unlink them,
@@ -1135,7 +1153,8 @@ static int __cpufreq_remove_dev(struct sys_device *sys_dev)
                                continue;
                        dprintk("removing link for cpu %u\n", j);
 #ifdef CONFIG_HOTPLUG_CPU
-                       per_cpu(cpufreq_cpu_governor, j) = data->governor;
+                       strncpy(per_cpu(cpufreq_cpu_governor, j),
+                               data->governor->name, CPUFREQ_NAME_LEN);
 #endif
                        cpu_sys_dev = get_cpu_sysdev(j);
                        sysfs_remove_link(&cpu_sys_dev->kobj, "cpufreq");
@@ -1606,9 +1625,22 @@ EXPORT_SYMBOL_GPL(cpufreq_register_governor);
 
 void cpufreq_unregister_governor(struct cpufreq_governor *governor)
 {
+#ifdef CONFIG_HOTPLUG_CPU
+       int cpu;
+#endif
+
        if (!governor)
                return;
 
+#ifdef CONFIG_HOTPLUG_CPU
+       for_each_present_cpu(cpu) {
+               if (cpu_online(cpu))
+                       continue;
+               if (!strcmp(per_cpu(cpufreq_cpu_governor, cpu), governor->name))
+                       strcpy(per_cpu(cpufreq_cpu_governor, cpu), "\0");
+       }
+#endif
+
        mutex_lock(&cpufreq_governor_mutex);
        list_del(&governor->governor_list);
        mutex_unlock(&cpufreq_governor_mutex);
index bc33ddc9c97cddd9e29eedc1a2737dee7e5cf5f7..c7b081b839ffe1fb37df117fb2f0395467383ec4 100644 (file)
@@ -116,9 +116,9 @@ static inline cputime64_t get_cpu_idle_time_jiffy(unsigned int cpu,
 
        idle_time = cputime64_sub(cur_wall_time, busy_time);
        if (wall)
-               *wall = cur_wall_time;
+               *wall = (cputime64_t)jiffies_to_usecs(cur_wall_time);
 
-       return idle_time;
+       return (cputime64_t)jiffies_to_usecs(idle_time);;
 }
 
 static inline cputime64_t get_cpu_idle_time(unsigned int cpu, cputime64_t *wall)
index 071699de50eef68a56e586224ccbe1d07e319011..4b34ade2332baaa50bb1ca1af9c45e1a9893d321 100644 (file)
@@ -133,9 +133,9 @@ static inline cputime64_t get_cpu_idle_time_jiffy(unsigned int cpu,
 
        idle_time = cputime64_sub(cur_wall_time, busy_time);
        if (wall)
-               *wall = cur_wall_time;
+               *wall = (cputime64_t)jiffies_to_usecs(cur_wall_time);
 
-       return idle_time;
+       return (cputime64_t)jiffies_to_usecs(idle_time);
 }
 
 static inline cputime64_t get_cpu_idle_time(unsigned int cpu, cputime64_t *wall)
index a9952b1236b07ee407cd84990ab53d02622318d4..84c51e17726966c196ac53ce05671e972f65b98a 100644 (file)
@@ -236,7 +236,7 @@ static inline void ecb_crypt(const u8 *in, u8 *out, u32 *key,
        /* Padlock in ECB mode fetches at least ecb_fetch_bytes of data.
         * We could avoid some copying here but it's probably not worth it.
         */
-       if (unlikely(((unsigned long)in & PAGE_SIZE) + ecb_fetch_bytes > PAGE_SIZE)) {
+       if (unlikely(((unsigned long)in & ~PAGE_MASK) + ecb_fetch_bytes > PAGE_SIZE)) {
                ecb_crypt_copy(in, out, key, cword, count);
                return;
        }
@@ -248,7 +248,7 @@ static inline u8 *cbc_crypt(const u8 *in, u8 *out, u32 *key,
                            u8 *iv, struct cword *cword, int count)
 {
        /* Padlock in CBC mode fetches at least cbc_fetch_bytes of data. */
-       if (unlikely(((unsigned long)in & PAGE_SIZE) + cbc_fetch_bytes > PAGE_SIZE))
+       if (unlikely(((unsigned long)in & ~PAGE_MASK) + cbc_fetch_bytes > PAGE_SIZE))
                return cbc_crypt_copy(in, out, key, iv, cword, count);
 
        return rep_xcrypt_cbc(in, out, key, iv, cword, count);
index 5903a88351bfdf5b844a45c616aa68419318a3fb..b401dadad4a87af4e567186ce8f7153f7b62a3a4 100644 (file)
@@ -26,6 +26,8 @@ config INTEL_IOATDMA
        select DMA_ENGINE
        select DCA
        select ASYNC_TX_DISABLE_CHANNEL_SWITCH
+       select ASYNC_TX_DISABLE_PQ_VAL_DMA
+       select ASYNC_TX_DISABLE_XOR_VAL_DMA
        help
          Enable support for the Intel(R) I/OAT DMA engine present
          in recent Intel Xeon chipsets.
index bd0b248de2cfabc28f1fecd63e5d64ed61236844..8f99354082ceaa169f7ac081594bc83b0c003478 100644 (file)
@@ -632,11 +632,21 @@ static bool device_has_all_tx_types(struct dma_device *device)
        #if defined(CONFIG_ASYNC_XOR) || defined(CONFIG_ASYNC_XOR_MODULE)
        if (!dma_has_cap(DMA_XOR, device->cap_mask))
                return false;
+
+       #ifndef CONFIG_ASYNC_TX_DISABLE_XOR_VAL_DMA
+       if (!dma_has_cap(DMA_XOR_VAL, device->cap_mask))
+               return false;
+       #endif
        #endif
 
        #if defined(CONFIG_ASYNC_PQ) || defined(CONFIG_ASYNC_PQ_MODULE)
        if (!dma_has_cap(DMA_PQ, device->cap_mask))
                return false;
+
+       #ifndef CONFIG_ASYNC_TX_DISABLE_PQ_VAL_DMA
+       if (!dma_has_cap(DMA_PQ_VAL, device->cap_mask))
+               return false;
+       #endif
        #endif
 
        return true;
index 69d02615c4d69d77276d760cc9b728c5986bc262..abd9038e06b1351ab7706c81fcbd96e8dbf2eebd 100644 (file)
@@ -98,17 +98,17 @@ static int dca_enabled_in_bios(struct pci_dev *pdev)
        cpuid_level_9 = cpuid_eax(9);
        res = test_bit(0, &cpuid_level_9);
        if (!res)
-               dev_err(&pdev->dev, "DCA is disabled in BIOS\n");
+               dev_dbg(&pdev->dev, "DCA is disabled in BIOS\n");
 
        return res;
 }
 
-static int system_has_dca_enabled(struct pci_dev *pdev)
+int system_has_dca_enabled(struct pci_dev *pdev)
 {
        if (boot_cpu_has(X86_FEATURE_DCA))
                return dca_enabled_in_bios(pdev);
 
-       dev_err(&pdev->dev, "boot cpu doesn't have X86_FEATURE_DCA\n");
+       dev_dbg(&pdev->dev, "boot cpu doesn't have X86_FEATURE_DCA\n");
        return 0;
 }
 
index c14fdfeb7f33f2c6c1d9a540c65f3ee21ebe9840..45edde99648070e8c9a0ca14f214ead551cbfc84 100644 (file)
@@ -297,9 +297,7 @@ static inline bool is_ioat_suspended(unsigned long status)
 /* channel was fatally programmed */
 static inline bool is_ioat_bug(unsigned long err)
 {
-       return !!(err & (IOAT_CHANERR_SRC_ADDR_ERR|IOAT_CHANERR_DEST_ADDR_ERR|
-                        IOAT_CHANERR_NEXT_ADDR_ERR|IOAT_CHANERR_CONTROL_ERR|
-                        IOAT_CHANERR_LENGTH_ERR));
+       return !!err;
 }
 
 static inline void ioat_unmap(struct pci_dev *pdev, dma_addr_t addr, size_t len,
index 96ffab7d37a70e82e882160dde2649487dffd742..8f1f7f05deaadaac6cd428cbef09e35e161ededc 100644 (file)
@@ -279,6 +279,8 @@ void ioat2_timer_event(unsigned long data)
                        u32 chanerr;
 
                        chanerr = readl(chan->reg_base + IOAT_CHANERR_OFFSET);
+                       dev_err(to_dev(chan), "%s: Channel halted (%x)\n",
+                               __func__, chanerr);
                        BUG_ON(is_ioat_bug(chanerr));
                }
 
index 35d1e33afd5b9c3bf7a185d3f9df5b37747dacf6..42f6f10fb0cc249b2b07854f00e556f8335029d7 100644 (file)
@@ -378,6 +378,8 @@ static void ioat3_timer_event(unsigned long data)
                        u32 chanerr;
 
                        chanerr = readl(chan->reg_base + IOAT_CHANERR_OFFSET);
+                       dev_err(to_dev(chan), "%s: Channel halted (%x)\n",
+                               __func__, chanerr);
                        BUG_ON(is_ioat_bug(chanerr));
                }
 
@@ -569,7 +571,7 @@ __ioat3_prep_xor_lock(struct dma_chan *c, enum sum_check_flags *result,
        dump_desc_dbg(ioat, compl_desc);
 
        /* we leave the channel locked to ensure in order submission */
-       return &desc->txd;
+       return &compl_desc->txd;
 }
 
 static struct dma_async_tx_descriptor *
@@ -728,7 +730,7 @@ __ioat3_prep_pq_lock(struct dma_chan *c, enum sum_check_flags *result,
        dump_desc_dbg(ioat, compl_desc);
 
        /* we leave the channel locked to ensure in order submission */
-       return &desc->txd;
+       return &compl_desc->txd;
 }
 
 static struct dma_async_tx_descriptor *
@@ -736,10 +738,16 @@ ioat3_prep_pq(struct dma_chan *chan, dma_addr_t *dst, dma_addr_t *src,
              unsigned int src_cnt, const unsigned char *scf, size_t len,
              unsigned long flags)
 {
+       /* specify valid address for disabled result */
+       if (flags & DMA_PREP_PQ_DISABLE_P)
+               dst[0] = dst[1];
+       if (flags & DMA_PREP_PQ_DISABLE_Q)
+               dst[1] = dst[0];
+
        /* handle the single source multiply case from the raid6
         * recovery path
         */
-       if (unlikely((flags & DMA_PREP_PQ_DISABLE_P) && src_cnt == 1)) {
+       if ((flags & DMA_PREP_PQ_DISABLE_P) && src_cnt == 1) {
                dma_addr_t single_source[2];
                unsigned char single_source_coef[2];
 
@@ -761,6 +769,12 @@ ioat3_prep_pq_val(struct dma_chan *chan, dma_addr_t *pq, dma_addr_t *src,
                  unsigned int src_cnt, const unsigned char *scf, size_t len,
                  enum sum_check_flags *pqres, unsigned long flags)
 {
+       /* specify valid address for disabled result */
+       if (flags & DMA_PREP_PQ_DISABLE_P)
+               pq[0] = pq[1];
+       if (flags & DMA_PREP_PQ_DISABLE_Q)
+               pq[1] = pq[0];
+
        /* the cleanup routine only sets bits on validate failure, it
         * does not clear bits on validate success... so clear it here
         */
@@ -778,9 +792,9 @@ ioat3_prep_pqxor(struct dma_chan *chan, dma_addr_t dst, dma_addr_t *src,
        dma_addr_t pq[2];
 
        memset(scf, 0, src_cnt);
-       flags |= DMA_PREP_PQ_DISABLE_Q;
        pq[0] = dst;
-       pq[1] = ~0;
+       flags |= DMA_PREP_PQ_DISABLE_Q;
+       pq[1] = dst; /* specify valid address for disabled result */
 
        return __ioat3_prep_pq_lock(chan, NULL, pq, src, src_cnt, scf, len,
                                    flags);
@@ -800,9 +814,9 @@ ioat3_prep_pqxor_val(struct dma_chan *chan, dma_addr_t *src,
        *result = 0;
 
        memset(scf, 0, src_cnt);
-       flags |= DMA_PREP_PQ_DISABLE_Q;
        pq[0] = src[0];
-       pq[1] = ~0;
+       flags |= DMA_PREP_PQ_DISABLE_Q;
+       pq[1] = pq[0]; /* specify valid address for disabled result */
 
        return __ioat3_prep_pq_lock(chan, result, pq, &src[1], src_cnt - 1, scf,
                                    len, flags);
@@ -1117,6 +1131,7 @@ static int __devinit ioat3_dma_self_test(struct ioatdma_device *device)
 int __devinit ioat3_dma_probe(struct ioatdma_device *device, int dca)
 {
        struct pci_dev *pdev = device->pdev;
+       int dca_en = system_has_dca_enabled(pdev);
        struct dma_device *dma;
        struct dma_chan *c;
        struct ioat_chan_common *chan;
@@ -1137,6 +1152,11 @@ int __devinit ioat3_dma_probe(struct ioatdma_device *device, int dca)
        dma->device_prep_dma_interrupt = ioat3_prep_interrupt_lock;
 
        cap = readl(device->reg_base + IOAT_DMA_CAP_OFFSET);
+
+       /* dca is incompatible with raid operations */
+       if (dca_en && (cap & (IOAT_CAP_XOR|IOAT_CAP_PQ)))
+               cap &= ~(IOAT_CAP_XOR|IOAT_CAP_PQ);
+
        if (cap & IOAT_CAP_XOR) {
                is_raid_device = true;
                dma->max_xor = 8;
@@ -1186,6 +1206,16 @@ int __devinit ioat3_dma_probe(struct ioatdma_device *device, int dca)
                device->timer_fn = ioat2_timer_event;
        }
 
+       #ifdef CONFIG_ASYNC_TX_DISABLE_PQ_VAL_DMA
+       dma_cap_clear(DMA_PQ_VAL, dma->cap_mask);
+       dma->device_prep_dma_pq_val = NULL;
+       #endif
+
+       #ifdef CONFIG_ASYNC_TX_DISABLE_XOR_VAL_DMA
+       dma_cap_clear(DMA_XOR_VAL, dma->cap_mask);
+       dma->device_prep_dma_xor_val = NULL;
+       #endif
+
        /* -= IOAT ver.3 workarounds =- */
        /* Write CHANERRMSK_INT with 3E07h to mask out the errors
         * that can cause stability issues for IOAT ver.3
index 99afb12bd4093fe862006111ebe1b8a560abe26f..60e675455b6aa13d10aef2fe50b753fbe0a5942d 100644 (file)
@@ -39,6 +39,8 @@
 #define IOAT_VER_3_0            0x30    /* Version 3.0 */
 #define IOAT_VER_3_2            0x32    /* Version 3.2 */
 
+int system_has_dca_enabled(struct pci_dev *pdev);
+
 struct ioat_dma_descriptor {
        uint32_t        size;
        union {
index 63038e18ab03266fe20a6891a91e938bad7dc79d..f015ec1967004ed103149c5e93b8ad2d670eae80 100644 (file)
@@ -92,9 +92,7 @@
 #define IOAT_CHANCTRL_ERR_COMPLETION_EN                0x0004
 #define IOAT_CHANCTRL_INT_REARM                        0x0001
 #define IOAT_CHANCTRL_RUN                      (IOAT_CHANCTRL_INT_REARM |\
-                                                IOAT_CHANCTRL_ERR_COMPLETION_EN |\
-                                                IOAT_CHANCTRL_ANY_ERR_ABORT_EN |\
-                                                IOAT_CHANCTRL_ERR_INT_EN)
+                                                IOAT_CHANCTRL_ANY_ERR_ABORT_EN)
 
 #define IOAT_DMA_COMP_OFFSET                   0x02    /* 16-bit DMA channel compatibility */
 #define IOAT_DMA_COMP_V1                       0x0001  /* Compatibility with DMA version 1 */
index b3b065c4e5c1f4eb0990c5e81286a8191e81edee..034ecf0ace03751b5fb20b282328e8a4d70005fe 100644 (file)
@@ -640,17 +640,16 @@ static int __init sh_dmae_probe(struct platform_device *pdev)
 #endif
        struct sh_dmae_device *shdev;
 
+       /* get platform data */
+       if (!pdev->dev.platform_data)
+               return -ENODEV;
+
        shdev = kzalloc(sizeof(struct sh_dmae_device), GFP_KERNEL);
        if (!shdev) {
                dev_err(&pdev->dev, "No enough memory\n");
-               err = -ENOMEM;
-               goto shdev_err;
+               return -ENOMEM;
        }
 
-       /* get platform data */
-       if (!pdev->dev.platform_data)
-               goto shdev_err;
-
        /* platform data */
        memcpy(&shdev->pdata, pdev->dev.platform_data,
                        sizeof(struct sh_dmae_pdata));
@@ -722,7 +721,6 @@ eirq_err:
 rst_err:
        kfree(shdev);
 
-shdev_err:
        return err;
 }
 
index 5d524254499ed154b6585c328e6b5a88413792db..94260aa76aa3a88c87a2d3f805ed1abee38d7d44 100644 (file)
@@ -275,7 +275,7 @@ static void log_irqs(u32 evt)
            !(evt & OHCI1394_busReset))
                return;
 
-       fw_notify("IRQ %08x%s%s%s%s%s%s%s%s%s%s%s%s%s\n", evt,
+       fw_notify("IRQ %08x%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n", evt,
            evt & OHCI1394_selfIDComplete       ? " selfID"             : "",
            evt & OHCI1394_RQPkt                ? " AR_req"             : "",
            evt & OHCI1394_RSPkt                ? " AR_resp"            : "",
@@ -286,6 +286,7 @@ static void log_irqs(u32 evt)
            evt & OHCI1394_postedWriteErr       ? " postedWriteErr"     : "",
            evt & OHCI1394_cycleTooLong         ? " cycleTooLong"       : "",
            evt & OHCI1394_cycle64Seconds       ? " cycle64Seconds"     : "",
+           evt & OHCI1394_cycleInconsistent    ? " cycleInconsistent"  : "",
            evt & OHCI1394_regAccessFail        ? " regAccessFail"      : "",
            evt & OHCI1394_busReset             ? " busReset"           : "",
            evt & ~(OHCI1394_selfIDComplete | OHCI1394_RQPkt |
@@ -293,6 +294,7 @@ static void log_irqs(u32 evt)
                    OHCI1394_respTxComplete | OHCI1394_isochRx |
                    OHCI1394_isochTx | OHCI1394_postedWriteErr |
                    OHCI1394_cycleTooLong | OHCI1394_cycle64Seconds |
+                   OHCI1394_cycleInconsistent |
                    OHCI1394_regAccessFail | OHCI1394_busReset)
                                                ? " ?"                  : "");
 }
@@ -1439,6 +1441,17 @@ static irqreturn_t irq_handler(int irq, void *data)
                          OHCI1394_LinkControl_cycleMaster);
        }
 
+       if (unlikely(event & OHCI1394_cycleInconsistent)) {
+               /*
+                * We need to clear this event bit in order to make
+                * cycleMatch isochronous I/O work.  In theory we should
+                * stop active cycleMatch iso contexts now and restart
+                * them at least two cycles later.  (FIXME?)
+                */
+               if (printk_ratelimit())
+                       fw_notify("isochronous cycle inconsistent\n");
+       }
+
        if (event & OHCI1394_cycle64Seconds) {
                cycle_time = reg_read(ohci, OHCI1394_IsochronousCycleTimer);
                if ((cycle_time & 0x80000000) == 0)
@@ -1528,6 +1541,7 @@ static int ohci_enable(struct fw_card *card, u32 *config_rom, size_t length)
                  OHCI1394_reqTxComplete | OHCI1394_respTxComplete |
                  OHCI1394_isochRx | OHCI1394_isochTx |
                  OHCI1394_postedWriteErr | OHCI1394_cycleTooLong |
+                 OHCI1394_cycleInconsistent |
                  OHCI1394_cycle64Seconds | OHCI1394_regAccessFail |
                  OHCI1394_masterIntEnable);
        if (param_debug & OHCI_PARAM_DEBUG_BUSRESETS)
@@ -1890,15 +1904,30 @@ static int handle_it_packet(struct context *context,
 {
        struct iso_context *ctx =
                container_of(context, struct iso_context, context);
+       int i;
+       struct descriptor *pd;
 
-       if (last->transfer_status == 0)
-               /* This descriptor isn't done yet, stop iteration. */
+       for (pd = d; pd <= last; pd++)
+               if (pd->transfer_status)
+                       break;
+       if (pd > last)
+               /* Descriptor(s) not done yet, stop iteration */
                return 0;
 
-       if (le16_to_cpu(last->control) & DESCRIPTOR_IRQ_ALWAYS)
+       i = ctx->header_length;
+       if (i + 4 < PAGE_SIZE) {
+               /* Present this value as big-endian to match the receive code */
+               *(__be32 *)(ctx->header + i) = cpu_to_be32(
+                               ((u32)le16_to_cpu(pd->transfer_status) << 16) |
+                               le16_to_cpu(pd->res_count));
+               ctx->header_length += 4;
+       }
+       if (le16_to_cpu(last->control) & DESCRIPTOR_IRQ_ALWAYS) {
                ctx->base.callback(&ctx->base, le16_to_cpu(last->res_count),
-                                  0, NULL, ctx->base.callback_data);
-
+                                  ctx->header_length, ctx->header,
+                                  ctx->base.callback_data);
+               ctx->header_length = 0;
+       }
        return 1;
 }
 
index 5711ce5353c65975ec801f66a407b459cd8e664b..4baf3d7d0f8e6e4f1f7887625b7f73a62dba1a83 100644 (file)
@@ -144,13 +144,6 @@ static int lnw_irq_type(unsigned irq, unsigned type)
 
 static void lnw_irq_unmask(unsigned irq)
 {
-       struct lnw_gpio *lnw = get_irq_chip_data(irq);
-       u32 gpio = irq - lnw->irq_base;
-       u8 reg = gpio / 32;
-       void __iomem *gedr;
-
-       gedr = (void __iomem *)(&lnw->reg_base->GEDR[reg]);
-       writel(BIT(gpio % 32), gedr);
 };
 
 static void lnw_irq_mask(unsigned irq)
@@ -183,13 +176,11 @@ static void lnw_irq_handler(unsigned irq, struct irq_desc *desc)
                gedr_v = readl(gedr);
                if (!gedr_v)
                        continue;
-               for (gpio = reg*32; gpio < reg*32+32; gpio++) {
-                       gedr_v = readl(gedr);
+               for (gpio = reg*32; gpio < reg*32+32; gpio++)
                        if (gedr_v & BIT(gpio % 32)) {
                                pr_debug("pin %d triggered\n", gpio);
                                generic_handle_irq(lnw->irq_base + gpio);
                        }
-               }
                /* clear the edge detect status bit */
                writel(gedr_v, gedr);
        }
index f831ea15929169af0f825343ec366974e9738932..96eddd17e050c8aed4fa202360abebb310f7b05c 100644 (file)
@@ -92,6 +92,7 @@ config DRM_I830
 config DRM_I915
        tristate "i915 driver"
        depends on AGP_INTEL
+       select SHMEM
        select DRM_KMS_HELPER
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
index cea665d86dd387e3515b0ed1a1fb310d1ac15075..b54ba63d506e0350abbf53acd50420cbeb79f7c3 100644 (file)
@@ -662,6 +662,12 @@ static struct drm_display_mode *drm_mode_detailed(struct drm_device *dev,
                return NULL;
        }
 
+       /* Some EDIDs have bogus h/vtotal values */
+       if (mode->hsync_end > mode->htotal)
+               mode->htotal = mode->hsync_end + 1;
+       if (mode->vsync_end > mode->vtotal)
+               mode->vtotal = mode->vsync_end + 1;
+
        drm_mode_set_name(mode);
 
        if (pt->misc & DRM_EDID_PT_INTERLACED)
index dc8e374a0b55e6852103cfdd56d0e84dcd0232d3..65ef011fa8ba093297d9e94983db2d0236d2a842 100644 (file)
@@ -599,7 +599,7 @@ int drm_fb_helper_check_var(struct fb_var_screeninfo *var,
        struct drm_framebuffer *fb = fb_helper->fb;
        int depth;
 
-       if (var->pixclock == -1 || !var->pixclock)
+       if (var->pixclock != 0)
                return -EINVAL;
 
        /* Need to resize the fb object !!! */
@@ -691,7 +691,7 @@ int drm_fb_helper_set_par(struct fb_info *info)
        int ret;
        int i;
 
-       if (var->pixclock != -1) {
+       if (var->pixclock != 0) {
                DRM_ERROR("PIXEL CLCOK SET\n");
                return -EINVAL;
        }
@@ -904,7 +904,7 @@ int drm_fb_helper_single_fb_probe(struct drm_device *dev,
        fb_helper->fb = fb;
 
        if (new_fb) {
-               info->var.pixclock = -1;
+               info->var.pixclock = 0;
                if (register_framebuffer(info) < 0)
                        return -EINVAL;
        } else {
index 80391995bdec05f07e809e33651466379c7823b3..e9dbb481c469f4a0071256349bd7a5e7a1239dcd 100644 (file)
@@ -552,7 +552,7 @@ int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma)
        vma->vm_flags |= VM_RESERVED | VM_IO | VM_PFNMAP | VM_DONTEXPAND;
        vma->vm_ops = obj->dev->driver->gem_vm_ops;
        vma->vm_private_data = map->handle;
-       vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
+       vma->vm_page_prot =  pgprot_writecombine(vm_get_page_prot(vma->vm_flags));
 
        /* Take a ref for this mapping of the object, so that the fault
         * handler can dereference the mmap offset's pointer to the object.
index c861d80fd779c68d6b4ce4af2c3b5191db8e3bbf..97dc5a4f0de42604463ac99a7a161c33b2d3550f 100644 (file)
@@ -103,6 +103,11 @@ static struct drm_mm_node *drm_mm_kmalloc(struct drm_mm *mm, int atomic)
        return child;
 }
 
+/* drm_mm_pre_get() - pre allocate drm_mm_node structure
+ * drm_mm:     memory manager struct we are pre-allocating for
+ *
+ * Returns 0 on success or -ENOMEM if allocation fails.
+ */
 int drm_mm_pre_get(struct drm_mm *mm)
 {
        struct drm_mm_node *node;
@@ -253,12 +258,14 @@ void drm_mm_put_block(struct drm_mm_node *cur)
                                prev_node->size += next_node->size;
                                list_del(&next_node->ml_entry);
                                list_del(&next_node->fl_entry);
+                               spin_lock(&mm->unused_lock);
                                if (mm->num_unused < MM_UNUSED_TARGET) {
                                        list_add(&next_node->fl_entry,
                                                 &mm->unused_nodes);
                                        ++mm->num_unused;
                                } else
                                        kfree(next_node);
+                               spin_unlock(&mm->unused_lock);
                        } else {
                                next_node->size += cur->size;
                                next_node->start = cur->start;
@@ -271,11 +278,13 @@ void drm_mm_put_block(struct drm_mm_node *cur)
                list_add(&cur->fl_entry, &mm->fl_entry);
        } else {
                list_del(&cur->ml_entry);
+               spin_lock(&mm->unused_lock);
                if (mm->num_unused < MM_UNUSED_TARGET) {
                        list_add(&cur->fl_entry, &mm->unused_nodes);
                        ++mm->num_unused;
                } else
                        kfree(cur);
+               spin_unlock(&mm->unused_lock);
        }
 }
 
index f8ce9a3a420de39c39c2f517f0c067cfda7669a5..26bf0552b3cb572cf3c03b7c63e3a338573eddad 100644 (file)
@@ -267,10 +267,10 @@ static void i915_dump_pages(struct seq_file *m, struct page **pages, int page_co
        uint32_t *mem;
 
        for (page = 0; page < page_count; page++) {
-               mem = kmap(pages[page]);
+               mem = kmap_atomic(pages[page], KM_USER0);
                for (i = 0; i < PAGE_SIZE; i += 4)
                        seq_printf(m, "%08x :  %08x\n", i, mem[i / 4]);
-               kunmap(pages[page]);
+               kunmap_atomic(pages[page], KM_USER0);
        }
 }
 
index 57204e298975b4b9516f5be83734e442806bb76c..a725f6591192e2216798fc4dcf04108125795b3e 100644 (file)
@@ -296,6 +296,7 @@ typedef struct drm_i915_private {
        u32 saveVBLANK_A;
        u32 saveVSYNC_A;
        u32 saveBCLRPAT_A;
+       u32 saveTRANSACONF;
        u32 saveTRANS_HTOTAL_A;
        u32 saveTRANS_HBLANK_A;
        u32 saveTRANS_HSYNC_A;
@@ -326,6 +327,7 @@ typedef struct drm_i915_private {
        u32 saveVBLANK_B;
        u32 saveVSYNC_B;
        u32 saveBCLRPAT_B;
+       u32 saveTRANSBCONF;
        u32 saveTRANS_HTOTAL_B;
        u32 saveTRANS_HBLANK_B;
        u32 saveTRANS_HSYNC_B;
@@ -414,6 +416,16 @@ typedef struct drm_i915_private {
        u32 savePFB_WIN_SZ;
        u32 savePFA_WIN_POS;
        u32 savePFB_WIN_POS;
+       u32 savePCH_DREF_CONTROL;
+       u32 saveDISP_ARB_CTL;
+       u32 savePIPEA_DATA_M1;
+       u32 savePIPEA_DATA_N1;
+       u32 savePIPEA_LINK_M1;
+       u32 savePIPEA_LINK_N1;
+       u32 savePIPEB_DATA_M1;
+       u32 savePIPEB_DATA_N1;
+       u32 savePIPEB_LINK_M1;
+       u32 savePIPEB_LINK_N1;
 
        struct {
                struct drm_mm gtt_space;
index c3ceffa46ea0e2dfdfc600e7440f1750376eb1f9..aa7fd82aa6eb343afa3fdb4b7088104f311f00d9 100644 (file)
@@ -254,10 +254,15 @@ irqreturn_t igdng_irq_handler(struct drm_device *dev)
 {
        drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
        int ret = IRQ_NONE;
-       u32 de_iir, gt_iir;
+       u32 de_iir, gt_iir, de_ier;
        u32 new_de_iir, new_gt_iir;
        struct drm_i915_master_private *master_priv;
 
+       /* disable master interrupt before clearing iir  */
+       de_ier = I915_READ(DEIER);
+       I915_WRITE(DEIER, de_ier & ~DE_MASTER_IRQ_CONTROL);
+       (void)I915_READ(DEIER);
+
        de_iir = I915_READ(DEIIR);
        gt_iir = I915_READ(GTIIR);
 
@@ -290,6 +295,9 @@ irqreturn_t igdng_irq_handler(struct drm_device *dev)
                gt_iir = new_gt_iir;
        }
 
+       I915_WRITE(DEIER, de_ier);
+       (void)I915_READ(DEIER);
+
        return ret;
 }
 
index 992d5617e79829d4a7586d81f4e4579a0de8c251..6eec8171a44e55f6000ec5545b8f4733c4cbe86a 100644 (file)
@@ -239,6 +239,11 @@ static void i915_save_modeset_reg(struct drm_device *dev)
        if (drm_core_check_feature(dev, DRIVER_MODESET))
                return;
 
+       if (IS_IGDNG(dev)) {
+               dev_priv->savePCH_DREF_CONTROL = I915_READ(PCH_DREF_CONTROL);
+               dev_priv->saveDISP_ARB_CTL = I915_READ(DISP_ARB_CTL);
+       }
+
        /* Pipe & plane A info */
        dev_priv->savePIPEACONF = I915_READ(PIPEACONF);
        dev_priv->savePIPEASRC = I915_READ(PIPEASRC);
@@ -263,6 +268,11 @@ static void i915_save_modeset_reg(struct drm_device *dev)
                dev_priv->saveBCLRPAT_A = I915_READ(BCLRPAT_A);
 
        if (IS_IGDNG(dev)) {
+               dev_priv->savePIPEA_DATA_M1 = I915_READ(PIPEA_DATA_M1);
+               dev_priv->savePIPEA_DATA_N1 = I915_READ(PIPEA_DATA_N1);
+               dev_priv->savePIPEA_LINK_M1 = I915_READ(PIPEA_LINK_M1);
+               dev_priv->savePIPEA_LINK_N1 = I915_READ(PIPEA_LINK_N1);
+
                dev_priv->saveFDI_TXA_CTL = I915_READ(FDI_TXA_CTL);
                dev_priv->saveFDI_RXA_CTL = I915_READ(FDI_RXA_CTL);
 
@@ -270,6 +280,7 @@ static void i915_save_modeset_reg(struct drm_device *dev)
                dev_priv->savePFA_WIN_SZ = I915_READ(PFA_WIN_SZ);
                dev_priv->savePFA_WIN_POS = I915_READ(PFA_WIN_POS);
 
+               dev_priv->saveTRANSACONF = I915_READ(TRANSACONF);
                dev_priv->saveTRANS_HTOTAL_A = I915_READ(TRANS_HTOTAL_A);
                dev_priv->saveTRANS_HBLANK_A = I915_READ(TRANS_HBLANK_A);
                dev_priv->saveTRANS_HSYNC_A = I915_READ(TRANS_HSYNC_A);
@@ -314,6 +325,11 @@ static void i915_save_modeset_reg(struct drm_device *dev)
                dev_priv->saveBCLRPAT_B = I915_READ(BCLRPAT_B);
 
        if (IS_IGDNG(dev)) {
+               dev_priv->savePIPEB_DATA_M1 = I915_READ(PIPEB_DATA_M1);
+               dev_priv->savePIPEB_DATA_N1 = I915_READ(PIPEB_DATA_N1);
+               dev_priv->savePIPEB_LINK_M1 = I915_READ(PIPEB_LINK_M1);
+               dev_priv->savePIPEB_LINK_N1 = I915_READ(PIPEB_LINK_N1);
+
                dev_priv->saveFDI_TXB_CTL = I915_READ(FDI_TXB_CTL);
                dev_priv->saveFDI_RXB_CTL = I915_READ(FDI_RXB_CTL);
 
@@ -321,6 +337,7 @@ static void i915_save_modeset_reg(struct drm_device *dev)
                dev_priv->savePFB_WIN_SZ = I915_READ(PFB_WIN_SZ);
                dev_priv->savePFB_WIN_POS = I915_READ(PFB_WIN_POS);
 
+               dev_priv->saveTRANSBCONF = I915_READ(TRANSBCONF);
                dev_priv->saveTRANS_HTOTAL_B = I915_READ(TRANS_HTOTAL_B);
                dev_priv->saveTRANS_HBLANK_B = I915_READ(TRANS_HBLANK_B);
                dev_priv->saveTRANS_HSYNC_B = I915_READ(TRANS_HSYNC_B);
@@ -368,6 +385,11 @@ static void i915_restore_modeset_reg(struct drm_device *dev)
                fpb1_reg = FPB1;
        }
 
+       if (IS_IGDNG(dev)) {
+               I915_WRITE(PCH_DREF_CONTROL, dev_priv->savePCH_DREF_CONTROL);
+               I915_WRITE(DISP_ARB_CTL, dev_priv->saveDISP_ARB_CTL);
+       }
+
        /* Pipe & plane A info */
        /* Prime the clock */
        if (dev_priv->saveDPLL_A & DPLL_VCO_ENABLE) {
@@ -395,6 +417,11 @@ static void i915_restore_modeset_reg(struct drm_device *dev)
                I915_WRITE(BCLRPAT_A, dev_priv->saveBCLRPAT_A);
 
        if (IS_IGDNG(dev)) {
+               I915_WRITE(PIPEA_DATA_M1, dev_priv->savePIPEA_DATA_M1);
+               I915_WRITE(PIPEA_DATA_N1, dev_priv->savePIPEA_DATA_N1);
+               I915_WRITE(PIPEA_LINK_M1, dev_priv->savePIPEA_LINK_M1);
+               I915_WRITE(PIPEA_LINK_N1, dev_priv->savePIPEA_LINK_N1);
+
                I915_WRITE(FDI_RXA_CTL, dev_priv->saveFDI_RXA_CTL);
                I915_WRITE(FDI_TXA_CTL, dev_priv->saveFDI_TXA_CTL);
 
@@ -402,6 +429,7 @@ static void i915_restore_modeset_reg(struct drm_device *dev)
                I915_WRITE(PFA_WIN_SZ, dev_priv->savePFA_WIN_SZ);
                I915_WRITE(PFA_WIN_POS, dev_priv->savePFA_WIN_POS);
 
+               I915_WRITE(TRANSACONF, dev_priv->saveTRANSACONF);
                I915_WRITE(TRANS_HTOTAL_A, dev_priv->saveTRANS_HTOTAL_A);
                I915_WRITE(TRANS_HBLANK_A, dev_priv->saveTRANS_HBLANK_A);
                I915_WRITE(TRANS_HSYNC_A, dev_priv->saveTRANS_HSYNC_A);
@@ -439,7 +467,7 @@ static void i915_restore_modeset_reg(struct drm_device *dev)
        /* Actually enable it */
        I915_WRITE(dpll_b_reg, dev_priv->saveDPLL_B);
        DRM_UDELAY(150);
-       if (IS_I965G(dev))
+       if (IS_I965G(dev) && !IS_IGDNG(dev))
                I915_WRITE(DPLL_B_MD, dev_priv->saveDPLL_B_MD);
        DRM_UDELAY(150);
 
@@ -454,6 +482,11 @@ static void i915_restore_modeset_reg(struct drm_device *dev)
                I915_WRITE(BCLRPAT_B, dev_priv->saveBCLRPAT_B);
 
        if (IS_IGDNG(dev)) {
+               I915_WRITE(PIPEB_DATA_M1, dev_priv->savePIPEB_DATA_M1);
+               I915_WRITE(PIPEB_DATA_N1, dev_priv->savePIPEB_DATA_N1);
+               I915_WRITE(PIPEB_LINK_M1, dev_priv->savePIPEB_LINK_M1);
+               I915_WRITE(PIPEB_LINK_N1, dev_priv->savePIPEB_LINK_N1);
+
                I915_WRITE(FDI_RXB_CTL, dev_priv->saveFDI_RXB_CTL);
                I915_WRITE(FDI_TXB_CTL, dev_priv->saveFDI_TXB_CTL);
 
@@ -461,6 +494,7 @@ static void i915_restore_modeset_reg(struct drm_device *dev)
                I915_WRITE(PFB_WIN_SZ, dev_priv->savePFB_WIN_SZ);
                I915_WRITE(PFB_WIN_POS, dev_priv->savePFB_WIN_POS);
 
+               I915_WRITE(TRANSBCONF, dev_priv->saveTRANSBCONF);
                I915_WRITE(TRANS_HTOTAL_B, dev_priv->saveTRANS_HTOTAL_B);
                I915_WRITE(TRANS_HBLANK_B, dev_priv->saveTRANS_HBLANK_B);
                I915_WRITE(TRANS_HSYNC_B, dev_priv->saveTRANS_HSYNC_B);
index 212e22740fc123e4a569a1e84e7445ae8a9de135..e5051446c48e12ff14f5d504fbc3bdef72c8b2b8 100644 (file)
@@ -262,8 +262,8 @@ static bool intel_crt_detect_hotplug(struct drm_connector *connector)
                } while (time_after(timeout, jiffies));
        }
 
-       if ((I915_READ(PORT_HOTPLUG_STAT) & CRT_HOTPLUG_MONITOR_MASK) ==
-           CRT_HOTPLUG_MONITOR_COLOR)
+       if ((I915_READ(PORT_HOTPLUG_STAT) & CRT_HOTPLUG_MONITOR_MASK) !=
+           CRT_HOTPLUG_MONITOR_NONE)
                return true;
 
        return false;
index 3ba6546b7c7f6875938ac8bc9b7345a4ca3ac200..099f420de57a2350d1da373cd7059b8305776e0a 100644 (file)
@@ -863,10 +863,8 @@ intel_igdng_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
        struct drm_device *dev = crtc->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
        intel_clock_t clock;
-       int max_n;
-       bool found;
        int err_most = 47;
-       found = false;
+       int err_min = 10000;
 
        /* eDP has only 2 clock choice, no n/m/p setting */
        if (HAS_eDP)
@@ -890,10 +888,9 @@ intel_igdng_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
        }
 
        memset(best_clock, 0, sizeof(*best_clock));
-       max_n = limit->n.max;
        for (clock.p1 = limit->p1.max; clock.p1 >= limit->p1.min; clock.p1--) {
                /* based on hardware requriment prefer smaller n to precision */
-               for (clock.n = limit->n.min; clock.n <= max_n; clock.n++) {
+               for (clock.n = limit->n.min; clock.n <= limit->n.max; clock.n++) {
                        /* based on hardware requirment prefere larger m1,m2 */
                        for (clock.m1 = limit->m1.max;
                             clock.m1 >= limit->m1.min; clock.m1--) {
@@ -907,18 +904,18 @@ intel_igdng_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
                                        this_err = abs((10000 - (target*10000/clock.dot)));
                                        if (this_err < err_most) {
                                                *best_clock = clock;
-                                               err_most = this_err;
-                                               max_n = clock.n;
-                                               found = true;
                                                /* found on first matching */
                                                goto out;
+                                       } else if (this_err < err_min) {
+                                               *best_clock = clock;
+                                               err_min = this_err;
                                        }
                                }
                        }
                }
        }
 out:
-       return found;
+       return true;
 }
 
 /* DisplayPort has only two frequencies, 162MHz and 270MHz */
index 663ab6de0b582602d0b62cc8e088cbf6f99c7fae..c33451aec1bd647a601c7f256fd805598fb42d01 100644 (file)
@@ -77,14 +77,32 @@ static void intel_hdmi_dpms(struct drm_encoder *encoder, int mode)
        struct intel_hdmi_priv *hdmi_priv = intel_output->dev_priv;
        u32 temp;
 
-       if (mode != DRM_MODE_DPMS_ON) {
-               temp = I915_READ(hdmi_priv->sdvox_reg);
+       temp = I915_READ(hdmi_priv->sdvox_reg);
+
+       /* HW workaround, need to toggle enable bit off and on for 12bpc, but
+        * we do this anyway which shows more stable in testing.
+        */
+       if (IS_IGDNG(dev)) {
                I915_WRITE(hdmi_priv->sdvox_reg, temp & ~SDVO_ENABLE);
+               POSTING_READ(hdmi_priv->sdvox_reg);
+       }
+
+       if (mode != DRM_MODE_DPMS_ON) {
+               temp &= ~SDVO_ENABLE;
        } else {
-               temp = I915_READ(hdmi_priv->sdvox_reg);
-               I915_WRITE(hdmi_priv->sdvox_reg, temp | SDVO_ENABLE);
+               temp |= SDVO_ENABLE;
        }
+
+       I915_WRITE(hdmi_priv->sdvox_reg, temp);
        POSTING_READ(hdmi_priv->sdvox_reg);
+
+       /* HW workaround, need to write this twice for issue that may result
+        * in first write getting masked.
+        */
+       if (IS_IGDNG(dev)) {
+               I915_WRITE(hdmi_priv->sdvox_reg, temp);
+               POSTING_READ(hdmi_priv->sdvox_reg);
+       }
 }
 
 static void intel_hdmi_save(struct drm_connector *connector)
index 901befe03da278e7a6879c9cab1498a315eb0248..d67c42555ab9b826b4f18a7a91fa30e02b2522ae 100644 (file)
@@ -107,6 +107,7 @@ static uint32_t atom_iio_execute(struct atom_context *ctx, int base,
                        base += 3;
                        break;
                case ATOM_IIO_WRITE:
+                       (void)ctx->card->reg_read(ctx->card, CU16(base + 1));
                        ctx->card->reg_write(ctx->card, CU16(base + 1), temp);
                        base += 3;
                        break;
index fb211e585dea68abc5cff1bebec33ff0a72e2d58..0d79577c15761759f6634eb636b78c8b711989a8 100644 (file)
@@ -561,7 +561,7 @@ struct table {
        char *gpu_prefix;
 };
 
-struct offset *offset_new(unsigned o)
+static struct offset *offset_new(unsigned o)
 {
        struct offset *offset;
 
@@ -573,12 +573,12 @@ struct offset *offset_new(unsigned o)
        return offset;
 }
 
-void table_offset_add(struct table *t, struct offset *offset)
+static void table_offset_add(struct table *t, struct offset *offset)
 {
        list_add_tail(&offset->list, &t->offsets);
 }
 
-void table_init(struct table *t)
+static void table_init(struct table *t)
 {
        INIT_LIST_HEAD(&t->offsets);
        t->offset_max = 0;
@@ -586,7 +586,7 @@ void table_init(struct table *t)
        t->table = NULL;
 }
 
-void table_print(struct table *t)
+static void table_print(struct table *t)
 {
        unsigned nlloop, i, j, n, c, id;
 
@@ -611,7 +611,7 @@ void table_print(struct table *t)
        printf("};\n");
 }
 
-int table_build(struct table *t)
+static int table_build(struct table *t)
 {
        struct offset *offset;
        unsigned i, m;
@@ -631,7 +631,7 @@ int table_build(struct table *t)
 }
 
 static char gpu_name[10];
-int parser_auth(struct table *t, const char *filename)
+static int parser_auth(struct table *t, const char *filename)
 {
        FILE *file;
        regex_t mask_rex;
index 757f5cd37744cc40163338a121c7ae2b4abc6467..224506a2f7b1ae6d53d5b68347a4a7889a262a2c 100644 (file)
@@ -519,6 +519,7 @@ typedef int (*radeon_packet3_check_t)(struct radeon_cs_parser *p,
  * AGP
  */
 int radeon_agp_init(struct radeon_device *rdev);
+void radeon_agp_resume(struct radeon_device *rdev);
 void radeon_agp_fini(struct radeon_device *rdev);
 
 
index 23ea9955ac596f28423fb28781e76a975e7c3995..54bf49a6d676b6a53c1e301ec5db855d2cf7f4fb 100644 (file)
@@ -237,6 +237,18 @@ int radeon_agp_init(struct radeon_device *rdev)
 #endif
 }
 
+void radeon_agp_resume(struct radeon_device *rdev)
+{
+#if __OS_HAS_AGP
+       int r;
+       if (rdev->flags & RADEON_IS_AGP) {
+               r = radeon_agp_init(rdev);
+               if (r)
+                       dev_warn(rdev->dev, "radeon AGP reinit failed\n");
+       }
+#endif
+}
+
 void radeon_agp_fini(struct radeon_device *rdev)
 {
 #if __OS_HAS_AGP
index fce4c4087fda1cce504228b5a218c0a9cfd714da..29763ceae3af9de8dc2067ff38e0ac63d59fe75e 100644 (file)
@@ -566,8 +566,9 @@ static enum drm_connector_status radeon_vga_detect(struct drm_connector *connect
                radeon_i2c_do_lock(radeon_connector, 0);
 
                if (!radeon_connector->edid) {
-                       DRM_ERROR("DDC responded but not EDID found for %s\n",
-                                 drm_get_connector_name(connector));
+                       DRM_ERROR("%s: probed a monitor but no|invalid EDID\n",
+                                       drm_get_connector_name(connector));
+                       ret = connector_status_connected;
                } else {
                        radeon_connector->use_digital = !!(radeon_connector->edid->input & DRM_EDID_INPUT_DIGITAL);
 
@@ -720,8 +721,8 @@ static enum drm_connector_status radeon_dvi_detect(struct drm_connector *connect
                radeon_i2c_do_lock(radeon_connector, 0);
 
                if (!radeon_connector->edid) {
-                       DRM_ERROR("DDC responded but not EDID found for %s\n",
-                                 drm_get_connector_name(connector));
+                       DRM_ERROR("%s: probed a monitor but no|invalid EDID\n",
+                                       drm_get_connector_name(connector));
                } else {
                        radeon_connector->use_digital = !!(radeon_connector->edid->input & DRM_EDID_INPUT_DIGITAL);
 
@@ -1149,6 +1150,13 @@ radeon_add_legacy_connector(struct drm_device *dev,
                        if (ret)
                                goto failed;
                        radeon_connector->dac_load_detect = true;
+                       /* RS400,RC410,RS480 chipset seems to report a lot
+                        * of false positive on load detect, we haven't yet
+                        * found a way to make load detect reliable on those
+                        * chipset, thus just disable it for TV.
+                        */
+                       if (rdev->family == CHIP_RS400 || rdev->family == CHIP_RS480)
+                               radeon_connector->dac_load_detect = false;
                        drm_connector_attach_property(&radeon_connector->base,
                                                      rdev->mode_info.load_detect_property,
                                                      1);
index e3f9edfa40fe8a5d63b64eee70e91345c4a1bd7b..41bb76fbe734f282dadbfee6d70ba1e046e6ecee 100644 (file)
@@ -688,6 +688,8 @@ int radeon_resume_kms(struct drm_device *dev)
                return -1;
        }
        pci_set_master(dev->pdev);
+       /* resume AGP if in use */
+       radeon_agp_resume(rdev);
        radeon_resume(rdev);
        radeon_restore_bios_scratch_regs(rdev);
        fb_set_suspend(rdev->fbdev_info, 0);
index 7935f793bf629b8599644d242ddfbfcaf3a04cb6..ba68c9fe90a1b7db910e8f6d551a192e42ef264e 100644 (file)
@@ -137,8 +137,6 @@ int rv515_mc_wait_for_idle(struct radeon_device *rdev)
 
 void rv515_vga_render_disable(struct radeon_device *rdev)
 {
-       WREG32(R_000330_D1VGA_CONTROL, 0);
-       WREG32(R_000338_D2VGA_CONTROL, 0);
        WREG32(R_000300_VGA_RENDER_CONTROL,
                RREG32(R_000300_VGA_RENDER_CONTROL) & C_000300_VGA_VSTATUS_CNTL);
 }
@@ -382,7 +380,6 @@ void rv515_mc_stop(struct radeon_device *rdev, struct rv515_mc_save *save)
        save->d2crtc_control = RREG32(R_006880_D2CRTC_CONTROL);
 
        /* Stop all video */
-       WREG32(R_000330_D1VGA_CONTROL, 0);
        WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 0);
        WREG32(R_000300_VGA_RENDER_CONTROL, 0);
        WREG32(R_0060E8_D1CRTC_UPDATE_LOCK, 1);
@@ -391,6 +388,8 @@ void rv515_mc_stop(struct radeon_device *rdev, struct rv515_mc_save *save)
        WREG32(R_006880_D2CRTC_CONTROL, 0);
        WREG32(R_0060E8_D1CRTC_UPDATE_LOCK, 0);
        WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 0);
+       WREG32(R_000330_D1VGA_CONTROL, 0);
+       WREG32(R_000338_D2VGA_CONTROL, 0);
 }
 
 void rv515_mc_resume(struct radeon_device *rdev, struct rv515_mc_save *save)
@@ -404,14 +403,14 @@ void rv515_mc_resume(struct radeon_device *rdev, struct rv515_mc_save *save)
        WREG32(R_000328_VGA_HDP_CONTROL, save->vga_hdp_control);
        mdelay(1);
        /* Restore video state */
+       WREG32(R_000330_D1VGA_CONTROL, save->d1vga_control);
+       WREG32(R_000338_D2VGA_CONTROL, save->d2vga_control);
        WREG32(R_0060E8_D1CRTC_UPDATE_LOCK, 1);
        WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 1);
        WREG32(R_006080_D1CRTC_CONTROL, save->d1crtc_control);
        WREG32(R_006880_D2CRTC_CONTROL, save->d2crtc_control);
        WREG32(R_0060E8_D1CRTC_UPDATE_LOCK, 0);
        WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 0);
-       WREG32(R_000330_D1VGA_CONTROL, save->d1vga_control);
-       WREG32(R_000338_D2VGA_CONTROL, save->d2vga_control);
        WREG32(R_000300_VGA_RENDER_CONTROL, save->vga_render_control);
 }
 
index d39877a7da636f037ee7628525772075b093be65..b5a95193c694a44f5c142cd9e5d1fd52c10b93b6 100644 (file)
@@ -350,8 +350,7 @@ static ssize_t show_temp(struct device *dev, struct device_attribute *attr,
 
        case FAULT:
                /* Note - only for remote1 and remote2 */
-               out = data->alarms & (sattr->index ? 0x8000 : 0x4000);
-               out = out ? 0 : 1;
+               out = !!(data->alarms & (sattr->index ? 0x8000 : 0x4000));
                break;
 
        default:
@@ -863,7 +862,7 @@ static SENSOR_DEVICE_ATTR_2(pwm1_freq, S_IRUGO | S_IWUSR, show_pwmfreq,
                            set_pwmfreq, INPUT, 0);
 static SENSOR_DEVICE_ATTR_2(pwm1_enable, S_IRUGO | S_IWUSR, show_pwmctrl,
                            set_pwmctrl, INPUT, 0);
-static SENSOR_DEVICE_ATTR_2(pwm1_auto_channel_temp, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR_2(pwm1_auto_channels_temp, S_IRUGO | S_IWUSR,
                            show_pwmchan, set_pwmchan, INPUT, 0);
 static SENSOR_DEVICE_ATTR_2(pwm1_auto_point1_pwm, S_IRUGO | S_IWUSR, show_pwm,
                            set_pwm, MIN, 0);
@@ -875,7 +874,7 @@ static SENSOR_DEVICE_ATTR_2(pwm2_freq, S_IRUGO | S_IWUSR, show_pwmfreq,
                            set_pwmfreq, INPUT, 1);
 static SENSOR_DEVICE_ATTR_2(pwm2_enable, S_IRUGO | S_IWUSR, show_pwmctrl,
                            set_pwmctrl, INPUT, 1);
-static SENSOR_DEVICE_ATTR_2(pwm2_auto_channel_temp, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR_2(pwm2_auto_channels_temp, S_IRUGO | S_IWUSR,
                            show_pwmchan, set_pwmchan, INPUT, 1);
 static SENSOR_DEVICE_ATTR_2(pwm2_auto_point1_pwm, S_IRUGO | S_IWUSR, show_pwm,
                            set_pwm, MIN, 1);
@@ -887,7 +886,7 @@ static SENSOR_DEVICE_ATTR_2(pwm3_freq, S_IRUGO | S_IWUSR, show_pwmfreq,
                            set_pwmfreq, INPUT, 2);
 static SENSOR_DEVICE_ATTR_2(pwm3_enable, S_IRUGO | S_IWUSR, show_pwmctrl,
                            set_pwmctrl, INPUT, 2);
-static SENSOR_DEVICE_ATTR_2(pwm3_auto_channel_temp, S_IRUGO | S_IWUSR,
+static SENSOR_DEVICE_ATTR_2(pwm3_auto_channels_temp, S_IRUGO | S_IWUSR,
                            show_pwmchan, set_pwmchan, INPUT, 2);
 static SENSOR_DEVICE_ATTR_2(pwm3_auto_point1_pwm, S_IRUGO | S_IWUSR, show_pwm,
                            set_pwm, MIN, 2);
@@ -947,19 +946,19 @@ static struct attribute *adt7475_attrs[] = {
        &sensor_dev_attr_pwm1.dev_attr.attr,
        &sensor_dev_attr_pwm1_freq.dev_attr.attr,
        &sensor_dev_attr_pwm1_enable.dev_attr.attr,
-       &sensor_dev_attr_pwm1_auto_channel_temp.dev_attr.attr,
+       &sensor_dev_attr_pwm1_auto_channels_temp.dev_attr.attr,
        &sensor_dev_attr_pwm1_auto_point1_pwm.dev_attr.attr,
        &sensor_dev_attr_pwm1_auto_point2_pwm.dev_attr.attr,
        &sensor_dev_attr_pwm2.dev_attr.attr,
        &sensor_dev_attr_pwm2_freq.dev_attr.attr,
        &sensor_dev_attr_pwm2_enable.dev_attr.attr,
-       &sensor_dev_attr_pwm2_auto_channel_temp.dev_attr.attr,
+       &sensor_dev_attr_pwm2_auto_channels_temp.dev_attr.attr,
        &sensor_dev_attr_pwm2_auto_point1_pwm.dev_attr.attr,
        &sensor_dev_attr_pwm2_auto_point2_pwm.dev_attr.attr,
        &sensor_dev_attr_pwm3.dev_attr.attr,
        &sensor_dev_attr_pwm3_freq.dev_attr.attr,
        &sensor_dev_attr_pwm3_enable.dev_attr.attr,
-       &sensor_dev_attr_pwm3_auto_channel_temp.dev_attr.attr,
+       &sensor_dev_attr_pwm3_auto_channels_temp.dev_attr.attr,
        &sensor_dev_attr_pwm3_auto_point1_pwm.dev_attr.attr,
        &sensor_dev_attr_pwm3_auto_point2_pwm.dev_attr.attr,
        NULL,
@@ -1152,7 +1151,7 @@ static struct adt7475_data *adt7475_update_device(struct device *dev)
        }
 
        /* Limits and settings, should never change update every 60 seconds */
-       if (time_after(jiffies, data->limits_updated + HZ * 2) ||
+       if (time_after(jiffies, data->limits_updated + HZ * 60) ||
            !data->valid) {
                data->config5 = adt7475_read(REG_CONFIG5);
 
index 3a524f2fe49352af9b6a8acd869d2ed5a2abc5e9..71835412529fca92dd4964dc28c95c6c749162be 100644 (file)
@@ -323,14 +323,21 @@ static int __devinit s3c_hwmon_probe(struct platform_device *dev)
        }
 
        for (i = 0; i < ARRAY_SIZE(pdata->in); i++) {
-               if (!pdata->in[i])
+               struct s3c24xx_adc_hwmon_incfg *cfg = pdata->in[i];
+
+               if (!cfg)
                        continue;
 
-               if (pdata->in[i]->mult >= 0x10000)
+               if (cfg->mult >= 0x10000)
                        dev_warn(&dev->dev,
                                 "channel %d multiplier too large\n",
                                 i);
 
+               if (cfg->divider == 0) {
+                       dev_err(&dev->dev, "channel %d divider zero\n", i);
+                       continue;
+               }
+
                ret = s3c_hwmon_create_attr(&dev->dev, pdata->in[i],
                                            &hwmon->attrs[i], i);
                if (ret) {
index 6ff6c20f1e78d261d6543b4e633c53aa0f80325c..fbab6846ae645a0a1324ecf3f23c939aae78289a 100644 (file)
@@ -19,7 +19,9 @@
 #include <linux/completion.h>
 #include <linux/platform_device.h>
 #include <linux/i2c-pnx.h>
+#include <linux/io.h>
 #include <mach/hardware.h>
+#include <mach/i2c.h>
 #include <asm/irq.h>
 #include <asm/uaccess.h>
 
@@ -54,6 +56,9 @@ static inline void i2c_pnx_arm_timer(struct i2c_adapter *adap)
        struct timer_list *timer = &data->mif.timer;
        int expires = I2C_PNX_TIMEOUT / (1000 / HZ);
 
+       if (expires <= 1)
+               expires = 2;
+
        del_timer_sync(timer);
 
        dev_dbg(&adap->dev, "Timer armed at %lu plus %u jiffies.\n",
@@ -645,7 +650,7 @@ static int __devinit i2c_pnx_probe(struct platform_device *pdev)
        return 0;
 
 out_irq:
-       free_irq(alg_data->irq, alg_data);
+       free_irq(alg_data->irq, i2c_pnx->adapter);
 out_clock:
        i2c_pnx->set_clock_stop(pdev);
 out_unmap:
@@ -664,7 +669,7 @@ static int __devexit i2c_pnx_remove(struct platform_device *pdev)
        struct i2c_adapter *adap = i2c_pnx->adapter;
        struct i2c_pnx_algo_data *alg_data = adap->algo_data;
 
-       free_irq(alg_data->irq, alg_data);
+       free_irq(alg_data->irq, i2c_pnx->adapter);
        i2c_del_adapter(adap);
        i2c_pnx->set_clock_stop(pdev);
        iounmap((void *)alg_data->ioaddr);
index aa96bd2d27ead9452d08da3bb62065468f1822f2..a0702f36a72fd065651e78c80ab4076eff77d4b8 100644 (file)
@@ -257,6 +257,7 @@ static DEVICE_ATTR(operating_mode, S_IWUSR | S_IRUGO,
 
 static ssize_t __tsl2550_show_lux(struct i2c_client *client, char *buf)
 {
+       struct tsl2550_data *data = i2c_get_clientdata(client);
        u8 ch0, ch1;
        int ret;
 
@@ -274,6 +275,8 @@ static ssize_t __tsl2550_show_lux(struct i2c_client *client, char *buf)
        ret = tsl2550_calculate_lux(ch0, ch1);
        if (ret < 0)
                return ret;
+       if (data->operating_mode == 1)
+               ret *= 5;
 
        return sprintf(buf, "%d\n", ret);
 }
index 8d80fceca6a4aaf8ff9ff1a24851687e684f579e..296504355142f2f7bb5f3338a30fe79d37f36b8f 100644 (file)
@@ -762,6 +762,7 @@ int i2c_del_adapter(struct i2c_adapter *adap)
 {
        int res = 0;
        struct i2c_adapter *found;
+       struct i2c_client *client, *next;
 
        /* First make sure that this adapter was ever added */
        mutex_lock(&core_lock);
@@ -781,6 +782,16 @@ int i2c_del_adapter(struct i2c_adapter *adap)
        if (res)
                return res;
 
+       /* Remove devices instantiated from sysfs */
+       list_for_each_entry_safe(client, next, &userspace_devices, detected) {
+               if (client->adapter == adap) {
+                       dev_dbg(&adap->dev, "Removing %s at 0x%x\n",
+                               client->name, client->addr);
+                       list_del(&client->detected);
+                       i2c_unregister_device(client);
+               }
+       }
+
        /* Detach any active clients. This can't fail, thus we do not
           checking the returned value. */
        res = device_for_each_child(&adap->dev, NULL, __unregister_client);
index 063b933d864a81f04acc0bbabdce2ec0297b7088..dd6396384c25cd22f82149a4a188bd65aab35814 100644 (file)
@@ -60,15 +60,6 @@ MODULE_AUTHOR("David Hinds <dahinds@users.sourceforge.net>");
 MODULE_DESCRIPTION("PCMCIA ATA/IDE card driver");
 MODULE_LICENSE("Dual MPL/GPL");
 
-#define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0)
-
-#ifdef CONFIG_PCMCIA_DEBUG
-INT_MODULE_PARM(pc_debug, 0);
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
-#else
-#define DEBUG(n, args...)
-#endif
-
 /*====================================================================*/
 
 typedef struct ide_info_t {
@@ -98,7 +89,7 @@ static int ide_probe(struct pcmcia_device *link)
 {
     ide_info_t *info;
 
-    DEBUG(0, "ide_attach()\n");
+    dev_dbg(&link->dev, "ide_attach()\n");
 
     /* Create new ide device */
     info = kzalloc(sizeof(*info), GFP_KERNEL);
@@ -112,7 +103,6 @@ static int ide_probe(struct pcmcia_device *link)
     link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
     link->io.IOAddrLines = 3;
     link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
-    link->irq.IRQInfo1 = IRQ_LEVEL_ID;
     link->conf.Attributes = CONF_ENABLE_IRQ;
     link->conf.IntType = INT_MEMORY_AND_IO;
 
@@ -134,7 +124,7 @@ static void ide_detach(struct pcmcia_device *link)
     ide_hwif_t *hwif = info->host->ports[0];
     unsigned long data_addr, ctl_addr;
 
-    DEBUG(0, "ide_detach(0x%p)\n", link);
+    dev_dbg(&link->dev, "ide_detach(0x%p)\n", link);
 
     data_addr = hwif->io_ports.data_addr;
     ctl_addr  = hwif->io_ports.ctl_addr;
@@ -217,9 +207,6 @@ out_release:
 
 ======================================================================*/
 
-#define CS_CHECK(fn, ret) \
-do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
-
 struct pcmcia_config_check {
        unsigned long ctl_base;
        int skip_vcc;
@@ -282,11 +269,11 @@ static int ide_config(struct pcmcia_device *link)
 {
     ide_info_t *info = link->priv;
     struct pcmcia_config_check *stk = NULL;
-    int last_ret = 0, last_fn = 0, is_kme = 0;
+    int ret = 0, is_kme = 0;
     unsigned long io_base, ctl_base;
     struct ide_host *host;
 
-    DEBUG(0, "ide_config(0x%p)\n", link);
+    dev_dbg(&link->dev, "ide_config(0x%p)\n", link);
 
     is_kme = ((link->manf_id == MANFID_KME) &&
              ((link->card_id == PRODID_KME_KXLC005_A) ||
@@ -306,8 +293,12 @@ static int ide_config(struct pcmcia_device *link)
     io_base = link->io.BasePort1;
     ctl_base = stk->ctl_base;
 
-    CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
-    CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
+    ret = pcmcia_request_irq(link, &link->irq);
+    if (ret)
+           goto failed;
+    ret = pcmcia_request_configuration(link, &link->conf);
+    if (ret)
+           goto failed;
 
     /* disable drive interrupts during IDE probe */
     outb(0x02, ctl_base);
@@ -342,8 +333,6 @@ err_mem:
     printk(KERN_NOTICE "ide-cs: ide_config failed memory allocation\n");
     goto failed;
 
-cs_failed:
-    cs_error(link, last_fn, last_ret);
 failed:
     kfree(stk);
     ide_release(link);
@@ -363,7 +352,7 @@ static void ide_release(struct pcmcia_device *link)
     ide_info_t *info = link->priv;
     struct ide_host *host = info->host;
 
-    DEBUG(0, "ide_release(0x%p)\n", link);
+    dev_dbg(&link->dev, "ide_release(0x%p)\n", link);
 
     if (info->ndev)
        /* FIXME: if this fails we need to queue the cleanup somehow
index d3440b5010a5830fc936383b4a65ffd66b4163d6..6e7ae2b6cfc64c018131349e4474f04506b6aa36 100644 (file)
@@ -162,7 +162,7 @@ static int ide_cmd_ioctl(ide_drive_t *drive, unsigned long arg)
        if (tf->command == ATA_CMD_SET_FEATURES &&
            tf->feature == SETFEATURES_XFER &&
            tf->nsect >= XFER_SW_DMA_0) {
-               xfer_rate = ide_find_dma_mode(drive, XFER_UDMA_6);
+               xfer_rate = ide_find_dma_mode(drive, tf->nsect);
                if (xfer_rate != tf->nsect) {
                        err = -EINVAL;
                        goto abort;
index 96a2959ce877e10905acfcc84cb1897e874d7143..7c544f7c74c4f07ad735ce35b92a58b28a426d37 100644 (file)
@@ -260,15 +260,12 @@ static int ieee802154_fake_close(struct net_device *dev)
 static netdev_tx_t ieee802154_fake_xmit(struct sk_buff *skb,
                                              struct net_device *dev)
 {
-       skb->iif = dev->ifindex;
-       skb->dev = dev;
        dev->stats.tx_packets++;
        dev->stats.tx_bytes += skb->len;
 
-       dev->trans_start = jiffies;
-
        /* FIXME: do hardware work here ... */
 
+       dev_kfree_skb(skb);
        return NETDEV_TX_OK;
 }
 
index 72c63e5dd630709ddffccf8dc945147857bf41ba..38df81fcdc3a90bdb4f812a02a4d064e6d657f2d 100644 (file)
@@ -337,16 +337,16 @@ int input_ff_create(struct input_dev *dev, int max_effects)
        dev->ff = ff;
        dev->flush = flush_effects;
        dev->event = input_ff_event;
-       set_bit(EV_FF, dev->evbit);
+       __set_bit(EV_FF, dev->evbit);
 
        /* Copy "true" bits into ff device bitmap */
        for (i = 0; i <= FF_MAX; i++)
                if (test_bit(i, dev->ffbit))
-                       set_bit(i, ff->ffbit);
+                       __set_bit(i, ff->ffbit);
 
        /* we can emulate RUMBLE with periodic effects */
        if (test_bit(FF_PERIODIC, ff->ffbit))
-               set_bit(FF_RUMBLE, dev->ffbit);
+               __set_bit(FF_RUMBLE, dev->ffbit);
 
        return 0;
 }
@@ -362,12 +362,14 @@ EXPORT_SYMBOL_GPL(input_ff_create);
  */
 void input_ff_destroy(struct input_dev *dev)
 {
-       clear_bit(EV_FF, dev->evbit);
-       if (dev->ff) {
-               if (dev->ff->destroy)
-                       dev->ff->destroy(dev->ff);
-               kfree(dev->ff->private);
-               kfree(dev->ff);
+       struct ff_device *ff = dev->ff;
+
+       __clear_bit(EV_FF, dev->evbit);
+       if (ff) {
+               if (ff->destroy)
+                       ff->destroy(ff);
+               kfree(ff->private);
+               kfree(ff);
                dev->ff = NULL;
        }
 }
index 2d1415e1683467ae55de53ba3fb273996ba7a795..b483b2995fa9918ad9cec432b37f0248517c45af 100644 (file)
@@ -61,7 +61,6 @@ struct ml_device {
        struct ml_effect_state states[FF_MEMLESS_EFFECTS];
        int gain;
        struct timer_list timer;
-       spinlock_t timer_lock;
        struct input_dev *dev;
 
        int (*play_effect)(struct input_dev *dev, void *data,
@@ -368,38 +367,38 @@ static void ml_effect_timer(unsigned long timer_data)
 {
        struct input_dev *dev = (struct input_dev *)timer_data;
        struct ml_device *ml = dev->ff->private;
+       unsigned long flags;
 
        debug("timer: updating effects");
 
-       spin_lock(&ml->timer_lock);
+       spin_lock_irqsave(&dev->event_lock, flags);
        ml_play_effects(ml);
-       spin_unlock(&ml->timer_lock);
+       spin_unlock_irqrestore(&dev->event_lock, flags);
 }
 
+/*
+ * Sets requested gain for FF effects. Called with dev->event_lock held.
+ */
 static void ml_ff_set_gain(struct input_dev *dev, u16 gain)
 {
        struct ml_device *ml = dev->ff->private;
        int i;
 
-       spin_lock_bh(&ml->timer_lock);
-
        ml->gain = gain;
 
        for (i = 0; i < FF_MEMLESS_EFFECTS; i++)
                __clear_bit(FF_EFFECT_PLAYING, &ml->states[i].flags);
 
        ml_play_effects(ml);
-
-       spin_unlock_bh(&ml->timer_lock);
 }
 
+/*
+ * Start/stop specified FF effect. Called with dev->event_lock held.
+ */
 static int ml_ff_playback(struct input_dev *dev, int effect_id, int value)
 {
        struct ml_device *ml = dev->ff->private;
        struct ml_effect_state *state = &ml->states[effect_id];
-       unsigned long flags;
-
-       spin_lock_irqsave(&ml->timer_lock, flags);
 
        if (value > 0) {
                debug("initiated play");
@@ -425,8 +424,6 @@ static int ml_ff_playback(struct input_dev *dev, int effect_id, int value)
                ml_play_effects(ml);
        }
 
-       spin_unlock_irqrestore(&ml->timer_lock, flags);
-
        return 0;
 }
 
@@ -436,7 +433,7 @@ static int ml_ff_upload(struct input_dev *dev,
        struct ml_device *ml = dev->ff->private;
        struct ml_effect_state *state = &ml->states[effect->id];
 
-       spin_lock_bh(&ml->timer_lock);
+       spin_lock_irq(&dev->event_lock);
 
        if (test_bit(FF_EFFECT_STARTED, &state->flags)) {
                __clear_bit(FF_EFFECT_PLAYING, &state->flags);
@@ -448,7 +445,7 @@ static int ml_ff_upload(struct input_dev *dev,
                ml_schedule_timer(ml);
        }
 
-       spin_unlock_bh(&ml->timer_lock);
+       spin_unlock_irq(&dev->event_lock);
 
        return 0;
 }
@@ -482,7 +479,6 @@ int input_ff_create_memless(struct input_dev *dev, void *data,
        ml->private = data;
        ml->play_effect = play_effect;
        ml->gain = 0xffff;
-       spin_lock_init(&ml->timer_lock);
        setup_timer(&ml->timer, ml_effect_timer, (unsigned long)dev);
 
        set_bit(FF_GAIN, dev->ffbit);
index cc763c96fadadf0565048a2a897d0f6202d81f09..2266ecbfbc010789390c9a5ebb36b72d0960526e 100644 (file)
@@ -1292,17 +1292,24 @@ static int input_dev_uevent(struct device *device, struct kobj_uevent_env *env)
        return 0;
 }
 
-#define INPUT_DO_TOGGLE(dev, type, bits, on)                   \
-       do {                                                    \
-               int i;                                          \
-               if (!test_bit(EV_##type, dev->evbit))           \
-                       break;                                  \
-               for (i = 0; i < type##_MAX; i++) {              \
-                       if (!test_bit(i, dev->bits##bit) ||     \
-                           !test_bit(i, dev->bits))            \
-                               continue;                       \
-                       dev->event(dev, EV_##type, i, on);      \
-               }                                               \
+#define INPUT_DO_TOGGLE(dev, type, bits, on)                           \
+       do {                                                            \
+               int i;                                                  \
+               bool active;                                            \
+                                                                       \
+               if (!test_bit(EV_##type, dev->evbit))                   \
+                       break;                                          \
+                                                                       \
+               for (i = 0; i < type##_MAX; i++) {                      \
+                       if (!test_bit(i, dev->bits##bit))               \
+                               continue;                               \
+                                                                       \
+                       active = test_bit(i, dev->bits);                \
+                       if (!active && !on)                             \
+                               continue;                               \
+                                                                       \
+                       dev->event(dev, EV_##type, i, on ? active : 0); \
+               }                                                       \
        } while (0)
 
 #ifdef CONFIG_PM
index 4452eabbee6d66f14482271c35943a3125721aa6..28e6110d1ff8a51c3eed113f49f6410a1db8784d 100644 (file)
@@ -1174,6 +1174,18 @@ static int atkbd_reconnect(struct serio *serio)
                        return -1;
 
                atkbd_activate(atkbd);
+
+               /*
+                * Restore LED state and repeat rate. While input core
+                * will do this for us at resume time reconnect may happen
+                * because user requested it via sysfs or simply because
+                * keyboard was unplugged and plugged in again so we need
+                * to do it ourselves here.
+                */
+               atkbd_set_leds(atkbd);
+               if (!atkbd->softrepeat)
+                       atkbd_set_repeat_rate(atkbd);
+
        }
 
        atkbd_enable(atkbd);
@@ -1422,6 +1434,7 @@ static ssize_t atkbd_set_set(struct atkbd *atkbd, const char *buf, size_t count)
 
                atkbd->dev = new_dev;
                atkbd->set = atkbd_select_set(atkbd, value, atkbd->extra);
+               atkbd_reset_state(atkbd);
                atkbd_activate(atkbd);
                atkbd_set_keycode_table(atkbd);
                atkbd_set_device_attrs(atkbd);
index 5e6308694408d695515264885ea906053191136c..82811558ec3314ec181cf95b8a5fe0bb22114a99 100644 (file)
@@ -107,8 +107,7 @@ static const struct dmi_system_id lifebook_dmi_table[] = {
                .matches = {
                        DMI_MATCH(DMI_PRODUCT_NAME, "CF-72"),
                },
-               .callback = lifebook_set_serio_phys,
-               .driver_data = "isa0060/serio3",
+               .callback = lifebook_set_6byte_proto,
        },
        {
                .ident = "Lifebook B142",
index 690aed90543694e0c4d94cf6e8234bbef228843e..07c53798301a6b51f5e6574fc2e3e4477a9c1ca8 100644 (file)
@@ -581,7 +581,7 @@ static int cortron_detect(struct psmouse *psmouse, bool set_properties)
 static int psmouse_extensions(struct psmouse *psmouse,
                              unsigned int max_proto, bool set_properties)
 {
-       bool synaptics_hardware = true;
+       bool synaptics_hardware = false;
 
 /*
  * We always check for lifebook because it does not disturb mouse
@@ -1673,7 +1673,7 @@ static int psmouse_get_maxproto(char *buffer, struct kernel_param *kp)
 {
        int type = *((unsigned int *)kp->arg);
 
-       return sprintf(buffer, "%s\n", psmouse_protocol_by_type(type)->name);
+       return sprintf(buffer, "%s", psmouse_protocol_by_type(type)->name);
 }
 
 static int __init psmouse_init(void)
index a537925f76511ee0d1b5cb50e5f3d18d39f62a8d..2bcf1ace27c0e5b85838008cf892de94dc82a890 100644 (file)
@@ -447,6 +447,27 @@ static struct dmi_system_id __initdata i8042_dmi_reset_table[] = {
                        DMI_MATCH(DMI_PRODUCT_NAME, "N10"),
                },
        },
+       {
+               .ident = "Dell Vostro 1320",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 1320"),
+               },
+       },
+       {
+               .ident = "Dell Vostro 1520",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 1520"),
+               },
+       },
+       {
+               .ident = "Dell Vostro 1720",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 1720"),
+               },
+       },
        { }
 };
 
index c72565520e418cdad31796d9f310f4f103636117..5a6ae646a6363efe0e28ee0639fca7ef8263b35c 100644 (file)
@@ -111,8 +111,6 @@ static int avmcs_probe(struct pcmcia_device *p_dev)
     p_dev->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
     p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
 
-    p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID;
-
     /* General socket configuration */
     p_dev->conf.Attributes = CONF_ENABLE_IRQ;
     p_dev->conf.IntType = INT_MEMORY_AND_IO;
@@ -198,7 +196,6 @@ static int avmcs_config(struct pcmcia_device *link)
         */
        i = pcmcia_request_irq(link, &link->irq);
        if (i != 0) {
-           cs_error(link, RequestIRQ, i);
            /* undo */
            pcmcia_disable_device(link);
            break;
@@ -209,7 +206,6 @@ static int avmcs_config(struct pcmcia_device *link)
          */
        i = pcmcia_request_configuration(link, &link->conf);
        if (i != 0) {
-           cs_error(link, RequestConfiguration, i);
            pcmcia_disable_device(link);
            break;
        }
index faed794cf75afcf50b8312395b5a01e7b5174a8d..a6624ad252c54a2f535e8e710b214d904ba5b731 100644 (file)
@@ -5481,7 +5481,7 @@ HFCmulti_init(void)
                if (err) {
                        printk(KERN_ERR "error registering embedded driver: "
                                "%x\n", err);
-                       return -err;
+                       return err;
                }
                HFC_cnt++;
                printk(KERN_INFO "%d devices registered\n", HFC_cnt);
index 23560c897ec361d59526ffa1d36fad6264ddadcb..f9bdff39cf4aff3dd32e33ac2b417eb145e4fbf3 100644 (file)
@@ -30,22 +30,6 @@ MODULE_DESCRIPTION("ISDN4Linux: PCMCIA client driver for AVM A1/Fritz!PCMCIA car
 MODULE_AUTHOR("Carsten Paeth");
 MODULE_LICENSE("GPL");
 
-/*
-   All the PCMCIA modules use PCMCIA_DEBUG to control debugging.  If
-   you do not define PCMCIA_DEBUG at all, all the debug code will be
-   left out.  If you compile with PCMCIA_DEBUG=0, the debug code will
-   be present but disabled -- but it can then be enabled for specific
-   modules at load time with a 'pc_debug=#' option to insmod.
-*/
-#ifdef PCMCIA_DEBUG
-static int pc_debug = PCMCIA_DEBUG;
-module_param(pc_debug, int, 0);
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args);
-static char *version =
-"avma1_cs.c 1.00 1998/01/23 10:00:00 (Carsten Paeth)";
-#else
-#define DEBUG(n, args...)
-#endif
 
 /*====================================================================*/
 
@@ -119,7 +103,7 @@ static int avma1cs_probe(struct pcmcia_device *p_dev)
 {
     local_info_t *local;
 
-    DEBUG(0, "avma1cs_attach()\n");
+    dev_dbg(&p_dev->dev, "avma1cs_attach()\n");
 
     /* Allocate space for private device-specific data */
     local = kzalloc(sizeof(local_info_t), GFP_KERNEL);
@@ -139,8 +123,6 @@ static int avma1cs_probe(struct pcmcia_device *p_dev)
     p_dev->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
     p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
 
-    p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID;
-
     /* General socket configuration */
     p_dev->conf.Attributes = CONF_ENABLE_IRQ;
     p_dev->conf.IntType = INT_MEMORY_AND_IO;
@@ -161,7 +143,7 @@ static int avma1cs_probe(struct pcmcia_device *p_dev)
 
 static void avma1cs_detach(struct pcmcia_device *link)
 {
-       DEBUG(0, "avma1cs_detach(0x%p)\n", link);
+       dev_dbg(&link->dev, "avma1cs_detach(0x%p)\n", link);
        avma1cs_release(link);
        kfree(link->priv);
 } /* avma1cs_detach */
@@ -203,7 +185,7 @@ static int avma1cs_config(struct pcmcia_device *link)
 
     dev = link->priv;
 
-    DEBUG(0, "avma1cs_config(0x%p)\n", link);
+    dev_dbg(&link->dev, "avma1cs_config(0x%p)\n", link);
 
     devname[0] = 0;
     if (link->prod_id[1])
@@ -218,7 +200,6 @@ static int avma1cs_config(struct pcmcia_device *link)
         */
        i = pcmcia_request_irq(link, &link->irq);
        if (i != 0) {
-           cs_error(link, RequestIRQ, i);
            /* undo */
            pcmcia_disable_device(link);
            break;
@@ -229,7 +210,6 @@ static int avma1cs_config(struct pcmcia_device *link)
         */
        i = pcmcia_request_configuration(link, &link->conf);
        if (i != 0) {
-           cs_error(link, RequestConfiguration, i);
            pcmcia_disable_device(link);
            break;
        }
@@ -281,7 +261,7 @@ static void avma1cs_release(struct pcmcia_device *link)
 {
        local_info_t *local = link->priv;
 
-       DEBUG(0, "avma1cs_release(0x%p)\n", link);
+       dev_dbg(&link->dev, "avma1cs_release(0x%p)\n", link);
 
        /* now unregister function with hisax */
        HiSax_closecard(local->node.minor);
index f4d0fe29bcf8b1a855a69fa1c1395a4bd9ee863d..a2f709f5397413f8352e66391207875bdbd93c1d 100644 (file)
@@ -57,23 +57,6 @@ MODULE_DESCRIPTION("ISDN4Linux: PCMCIA client driver for Elsa PCM cards");
 MODULE_AUTHOR("Klaus Lichtenwalder");
 MODULE_LICENSE("Dual MPL/GPL");
 
-/*
-   All the PCMCIA modules use PCMCIA_DEBUG to control debugging.  If
-   you do not define PCMCIA_DEBUG at all, all the debug code will be
-   left out.  If you compile with PCMCIA_DEBUG=0, the debug code will
-   be present but disabled -- but it can then be enabled for specific
-   modules at load time with a 'pc_debug=#' option to insmod.
-*/
-
-#ifdef PCMCIA_DEBUG
-static int pc_debug = PCMCIA_DEBUG;
-module_param(pc_debug, int, 0);
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args);
-static char *version =
-"elsa_cs.c $Revision: 1.2.2.4 $ $Date: 2004/01/25 15:07:06 $ (K.Lichtenwalder)";
-#else
-#define DEBUG(n, args...)
-#endif
 
 /*====================================================================*/
 
@@ -142,7 +125,7 @@ static int elsa_cs_probe(struct pcmcia_device *link)
 {
     local_info_t *local;
 
-    DEBUG(0, "elsa_cs_attach()\n");
+    dev_dbg(&link->dev, "elsa_cs_attach()\n");
 
     /* Allocate space for private device-specific data */
     local = kzalloc(sizeof(local_info_t), GFP_KERNEL);
@@ -155,7 +138,6 @@ static int elsa_cs_probe(struct pcmcia_device *link)
 
     /* Interrupt setup */
     link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
-    link->irq.IRQInfo1 = IRQ_LEVEL_ID|IRQ_SHARE_ID;
     link->irq.Handler = NULL;
 
     /*
@@ -188,7 +170,7 @@ static void elsa_cs_detach(struct pcmcia_device *link)
 {
        local_info_t *info = link->priv;
 
-       DEBUG(0, "elsa_cs_detach(0x%p)\n", link);
+       dev_dbg(&link->dev, "elsa_cs_detach(0x%p)\n", link);
 
        info->busy = 1;
        elsa_cs_release(link);
@@ -231,30 +213,25 @@ static int elsa_cs_configcheck(struct pcmcia_device *p_dev,
 static int elsa_cs_config(struct pcmcia_device *link)
 {
     local_info_t *dev;
-    int i, last_fn;
+    int i;
     IsdnCard_t icard;
 
-    DEBUG(0, "elsa_config(0x%p)\n", link);
+    dev_dbg(&link->dev, "elsa_config(0x%p)\n", link);
     dev = link->priv;
 
     i = pcmcia_loop_config(link, elsa_cs_configcheck, NULL);
-    if (i != 0) {
-       last_fn = RequestIO;
-       goto cs_failed;
-    }
+    if (i != 0)
+       goto failed;
 
     i = pcmcia_request_irq(link, &link->irq);
     if (i != 0) {
         link->irq.AssignedIRQ = 0;
-       last_fn = RequestIRQ;
-        goto cs_failed;
+       goto failed;
     }
 
     i = pcmcia_request_configuration(link, &link->conf);
-    if (i != 0) {
-      last_fn = RequestConfiguration;
-      goto cs_failed;
-    }
+    if (i != 0)
+       goto failed;
 
     /* At this point, the dev_node_t structure(s) should be
        initialized and arranged in a linked list at link->dev. *//*  */
@@ -290,8 +267,7 @@ static int elsa_cs_config(struct pcmcia_device *link)
        ((local_info_t*)link->priv)->cardnr = i;
 
     return 0;
-cs_failed:
-    cs_error(link, last_fn, i);
+failed:
     elsa_cs_release(link);
     return -ENODEV;
 } /* elsa_cs_config */
@@ -308,7 +284,7 @@ static void elsa_cs_release(struct pcmcia_device *link)
 {
     local_info_t *local = link->priv;
 
-    DEBUG(0, "elsa_cs_release(0x%p)\n", link);
+    dev_dbg(&link->dev, "elsa_cs_release(0x%p)\n", link);
 
     if (local) {
        if (local->cardnr >= 0) {
index 9a3c9f5e4fe82b5e132bc426592e603b243a091b..af5d393cc2d0afe2f099ad72ef489c411117391b 100644 (file)
@@ -57,24 +57,6 @@ MODULE_DESCRIPTION("ISDN4Linux: PCMCIA client driver for Sedlbauer cards");
 MODULE_AUTHOR("Marcus Niemann");
 MODULE_LICENSE("Dual MPL/GPL");
 
-/*
-   All the PCMCIA modules use PCMCIA_DEBUG to control debugging.  If
-   you do not define PCMCIA_DEBUG at all, all the debug code will be
-   left out.  If you compile with PCMCIA_DEBUG=0, the debug code will
-   be present but disabled -- but it can then be enabled for specific
-   modules at load time with a 'pc_debug=#' option to insmod.
-*/
-
-#ifdef PCMCIA_DEBUG
-static int pc_debug = PCMCIA_DEBUG;
-module_param(pc_debug, int, 0);
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args); 
-static char *version =
-"sedlbauer_cs.c 1.1a 2001/01/28 15:04:04 (M.Niemann)";
-#else
-#define DEBUG(n, args...)
-#endif
-
 
 /*====================================================================*/
 
@@ -151,7 +133,7 @@ static int sedlbauer_probe(struct pcmcia_device *link)
 {
     local_info_t *local;
 
-    DEBUG(0, "sedlbauer_attach()\n");
+    dev_dbg(&link->dev, "sedlbauer_attach()\n");
 
     /* Allocate space for private device-specific data */
     local = kzalloc(sizeof(local_info_t), GFP_KERNEL);
@@ -163,7 +145,6 @@ static int sedlbauer_probe(struct pcmcia_device *link)
 
     /* Interrupt setup */
     link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
-    link->irq.IRQInfo1 = IRQ_LEVEL_ID;
     link->irq.Handler = NULL;
 
     /*
@@ -198,7 +179,7 @@ static int sedlbauer_probe(struct pcmcia_device *link)
 
 static void sedlbauer_detach(struct pcmcia_device *link)
 {
-       DEBUG(0, "sedlbauer_detach(0x%p)\n", link);
+       dev_dbg(&link->dev, "sedlbauer_detach(0x%p)\n", link);
 
        ((local_info_t *)link->priv)->stop = 1;
        sedlbauer_release(link);
@@ -214,9 +195,6 @@ static void sedlbauer_detach(struct pcmcia_device *link)
     device available to the system.
     
 ======================================================================*/
-#define CS_CHECK(fn, ret) \
-do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
-
 static int sedlbauer_config_check(struct pcmcia_device *p_dev,
                                  cistpl_cftable_entry_t *cfg,
                                  cistpl_cftable_entry_t *dflt,
@@ -293,11 +271,11 @@ static int sedlbauer_config_check(struct pcmcia_device *p_dev,
                req->Base = mem->win[0].host_addr;
                req->Size = mem->win[0].len;
                req->AccessSpeed = 0;
-               if (pcmcia_request_window(&p_dev, req, &p_dev->win) != 0)
+               if (pcmcia_request_window(p_dev, req, &p_dev->win) != 0)
                        return -ENODEV;
                map.Page = 0;
                map.CardOffset = mem->win[0].card_addr;
-               if (pcmcia_map_mem_page(p_dev->win, &map) != 0)
+               if (pcmcia_map_mem_page(p_dev, p_dev->win, &map) != 0)
                        return -ENODEV;
        }
        return 0;
@@ -309,10 +287,10 @@ static int sedlbauer_config(struct pcmcia_device *link)
 {
     local_info_t *dev = link->priv;
     win_req_t *req;
-    int last_fn, last_ret;
+    int ret;
     IsdnCard_t  icard;
 
-    DEBUG(0, "sedlbauer_config(0x%p)\n", link);
+    dev_dbg(&link->dev, "sedlbauer_config(0x%p)\n", link);
 
     req = kzalloc(sizeof(win_req_t), GFP_KERNEL);
     if (!req)
@@ -330,8 +308,8 @@ static int sedlbauer_config(struct pcmcia_device *link)
       these things without consulting the CIS, and most client drivers
       will only use the CIS to fill in implementation-defined details.
     */
-    last_ret = pcmcia_loop_config(link, sedlbauer_config_check, req);
-    if (last_ret)
+    ret = pcmcia_loop_config(link, sedlbauer_config_check, req);
+    if (ret)
            goto failed;
 
     /*
@@ -339,15 +317,20 @@ static int sedlbauer_config(struct pcmcia_device *link)
        handler to the interrupt, unless the 'Handler' member of the
        irq structure is initialized.
     */
-    if (link->conf.Attributes & CONF_ENABLE_IRQ)
-       CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
+    if (link->conf.Attributes & CONF_ENABLE_IRQ) {
+           ret = pcmcia_request_irq(link, &link->irq);
+           if (ret)
+                   goto failed;
+    }
        
     /*
        This actually configures the PCMCIA socket -- setting up
        the I/O windows and the interrupt mapping, and putting the
        card and host interface into "Memory and IO" mode.
     */
-    CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
+    ret = pcmcia_request_configuration(link, &link->conf);
+    if (ret)
+           goto failed;
 
     /*
       At this point, the dev_node_t structure(s) need to be
@@ -380,19 +363,18 @@ static int sedlbauer_config(struct pcmcia_device *link)
     icard.protocol = protocol;
     icard.typ = ISDN_CTYPE_SEDLBAUER_PCMCIA;
     
-    last_ret = hisax_init_pcmcia(link, &(((local_info_t*)link->priv)->stop), &icard);
-    if (last_ret < 0) {
-       printk(KERN_ERR "sedlbauer_cs: failed to initialize SEDLBAUER PCMCIA %d at i/o %#x\n",
-               last_ret, link->io.BasePort1);
+    ret = hisax_init_pcmcia(link, 
+                           &(((local_info_t *)link->priv)->stop), &icard);
+    if (ret < 0) {
+       printk(KERN_ERR "sedlbauer_cs: failed to initialize SEDLBAUER PCMCIA %d at i/o %#x\n",
+               ret, link->io.BasePort1);
        sedlbauer_release(link);
        return -ENODEV;
     } else
-       ((local_info_t*)link->priv)->cardnr = last_ret;
+       ((local_info_t *)link->priv)->cardnr = ret;
 
     return 0;
 
-cs_failed:
-    cs_error(link, last_fn, last_ret);
 failed:
     sedlbauer_release(link);
     return -ENODEV;
@@ -410,7 +392,7 @@ failed:
 static void sedlbauer_release(struct pcmcia_device *link)
 {
     local_info_t *local = link->priv;
-    DEBUG(0, "sedlbauer_release(0x%p)\n", link);
+    dev_dbg(&link->dev, "sedlbauer_release(0x%p)\n", link);
 
     if (local) {
        if (local->cardnr >= 0) {
index 623d111544d43dfe7859eef6ca14c82533c64a8c..ea705394ce2bf4c06d7d6c49b87dd5d0c16063e4 100644 (file)
@@ -38,23 +38,6 @@ MODULE_DESCRIPTION("ISDN4Linux: PCMCIA client driver for Teles PCMCIA cards");
 MODULE_AUTHOR("Christof Petig, christof.petig@wtal.de, Karsten Keil, kkeil@suse.de");
 MODULE_LICENSE("GPL");
 
-/*
-   All the PCMCIA modules use PCMCIA_DEBUG to control debugging.  If
-   you do not define PCMCIA_DEBUG at all, all the debug code will be
-   left out.  If you compile with PCMCIA_DEBUG=0, the debug code will
-   be present but disabled -- but it can then be enabled for specific
-   modules at load time with a 'pc_debug=#' option to insmod.
-*/
-
-#ifdef PCMCIA_DEBUG
-static int pc_debug = PCMCIA_DEBUG;
-module_param(pc_debug, int, 0);
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args);
-static char *version =
-"teles_cs.c 2.10 2002/07/30 22:23:34 kkeil";
-#else
-#define DEBUG(n, args...)
-#endif
 
 /*====================================================================*/
 
@@ -133,7 +116,7 @@ static int teles_probe(struct pcmcia_device *link)
 {
     local_info_t *local;
 
-    DEBUG(0, "teles_attach()\n");
+    dev_dbg(&link->dev, "teles_attach()\n");
 
     /* Allocate space for private device-specific data */
     local = kzalloc(sizeof(local_info_t), GFP_KERNEL);
@@ -145,7 +128,6 @@ static int teles_probe(struct pcmcia_device *link)
 
     /* Interrupt setup */
     link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
-    link->irq.IRQInfo1 = IRQ_LEVEL_ID|IRQ_SHARE_ID;
     link->irq.Handler = NULL;
 
     /*
@@ -178,7 +160,7 @@ static void teles_detach(struct pcmcia_device *link)
 {
        local_info_t *info = link->priv;
 
-       DEBUG(0, "teles_detach(0x%p)\n", link);
+       dev_dbg(&link->dev, "teles_detach(0x%p)\n", link);
 
        info->busy = 1;
        teles_cs_release(link);
@@ -221,30 +203,25 @@ static int teles_cs_configcheck(struct pcmcia_device *p_dev,
 static int teles_cs_config(struct pcmcia_device *link)
 {
     local_info_t *dev;
-    int i, last_fn;
+    int i;
     IsdnCard_t icard;
 
-    DEBUG(0, "teles_config(0x%p)\n", link);
+    dev_dbg(&link->dev, "teles_config(0x%p)\n", link);
     dev = link->priv;
 
     i = pcmcia_loop_config(link, teles_cs_configcheck, NULL);
-    if (i != 0) {
-       last_fn = RequestIO;
+    if (i != 0)
        goto cs_failed;
-    }
 
     i = pcmcia_request_irq(link, &link->irq);
     if (i != 0) {
         link->irq.AssignedIRQ = 0;
-       last_fn = RequestIRQ;
         goto cs_failed;
     }
 
     i = pcmcia_request_configuration(link, &link->conf);
-    if (i != 0) {
-      last_fn = RequestConfiguration;
+    if (i != 0)
       goto cs_failed;
-    }
 
     /* At this point, the dev_node_t structure(s) should be
        initialized and arranged in a linked list at link->dev. *//*  */
@@ -283,7 +260,6 @@ static int teles_cs_config(struct pcmcia_device *link)
     return 0;
 
 cs_failed:
-    cs_error(link, last_fn, i);
     teles_cs_release(link);
     return -ENODEV;
 } /* teles_cs_config */
@@ -300,7 +276,7 @@ static void teles_cs_release(struct pcmcia_device *link)
 {
     local_info_t *local = link->priv;
 
-    DEBUG(0, "teles_cs_release(0x%p)\n", link);
+    dev_dbg(&link->dev, "teles_cs_release(0x%p)\n", link);
 
     if (local) {
        if (local->cardnr >= 0) {
index 2d14b64202a39d7b8745c97e0f2372b56e318aca..642d5aaf53cece9819e60c79b799c22cfdf71b1d 100644 (file)
@@ -1535,10 +1535,8 @@ static int isdn_ppp_mp_bundle_array_init(void)
        int sz = ISDN_MAX_CHANNELS*sizeof(ippp_bundle);
        if( (isdn_ppp_bundle_arr = kzalloc(sz, GFP_KERNEL)) == NULL )
                return -ENOMEM;
-       for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
+       for( i = 0; i < ISDN_MAX_CHANNELS; i++ )
                spin_lock_init(&isdn_ppp_bundle_arr[i].lock);
-               skb_queue_head_init(&isdn_ppp_bundle_arr[i].frags);
-       }
        return 0;
 }
 
@@ -1571,7 +1569,7 @@ static int isdn_ppp_mp_init( isdn_net_local * lp, ippp_bundle * add_to )
                if ((lp->netdev->pb = isdn_ppp_mp_bundle_alloc()) == NULL)
                        return -ENOMEM;
                lp->next = lp->last = lp;       /* nobody else in a queue */
-               skb_queue_head_init(&lp->netdev->pb->frags);
+               lp->netdev->pb->frags = NULL;
                lp->netdev->pb->frames = 0;
                lp->netdev->pb->seq = UINT_MAX;
        }
@@ -1583,29 +1581,28 @@ static int isdn_ppp_mp_init( isdn_net_local * lp, ippp_bundle * add_to )
 
 static u32 isdn_ppp_mp_get_seq( int short_seq, 
                                        struct sk_buff * skb, u32 last_seq );
-static void isdn_ppp_mp_discard(ippp_bundle *mp, struct sk_buff *from,
-                               struct sk_buff *to);
-static void isdn_ppp_mp_reassembly(isdn_net_dev *net_dev, isdn_net_local *lp,
-                                  struct sk_buff *from, struct sk_buff *to,
-                                  u32 lastseq);
-static void isdn_ppp_mp_free_skb(ippp_bundle *mp, struct sk_buff *skb);
+static struct sk_buff * isdn_ppp_mp_discard( ippp_bundle * mp,
+                       struct sk_buff * from, struct sk_buff * to );
+static void isdn_ppp_mp_reassembly( isdn_net_dev * net_dev, isdn_net_local * lp,
+                               struct sk_buff * from, struct sk_buff * to );
+static void isdn_ppp_mp_free_skb( ippp_bundle * mp, struct sk_buff * skb );
 static void isdn_ppp_mp_print_recv_pkt( int slot, struct sk_buff * skb );
 
 static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp, 
-                               struct sk_buff *skb)
+                                                       struct sk_buff *skb)
 {
-       struct sk_buff *newfrag, *frag, *start, *nextf;
-       u32 newseq, minseq, thisseq;
-       isdn_mppp_stats *stats;
        struct ippp_struct *is;
+       isdn_net_local * lpq;
+       ippp_bundle * mp;
+       isdn_mppp_stats * stats;
+       struct sk_buff * newfrag, * frag, * start, *nextf;
+       u32 newseq, minseq, thisseq;
        unsigned long flags;
-       isdn_net_local *lpq;
-       ippp_bundle *mp;
        int slot;
 
        spin_lock_irqsave(&net_dev->pb->lock, flags);
-       mp = net_dev->pb;
-       stats = &mp->stats;
+       mp = net_dev->pb;
+        stats = &mp->stats;
        slot = lp->ppp_slot;
        if (slot < 0 || slot >= ISDN_MAX_CHANNELS) {
                printk(KERN_ERR "%s: lp->ppp_slot(%d)\n",
@@ -1616,19 +1613,20 @@ static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp,
                return;
        }
        is = ippp_table[slot];
-       if (++mp->frames > stats->max_queue_len)
+       if( ++mp->frames > stats->max_queue_len )
                stats->max_queue_len = mp->frames;
-
+       
        if (is->debug & 0x8)
                isdn_ppp_mp_print_recv_pkt(lp->ppp_slot, skb);
 
-       newseq = isdn_ppp_mp_get_seq(is->mpppcfg & SC_IN_SHORT_SEQ,
-                                    skb, is->last_link_seqno);
+       newseq = isdn_ppp_mp_get_seq(is->mpppcfg & SC_IN_SHORT_SEQ, 
+                                               skb, is->last_link_seqno);
+
 
        /* if this packet seq # is less than last already processed one,
         * toss it right away, but check for sequence start case first 
         */
-       if (mp->seq > MP_LONGSEQ_MAX && (newseq & MP_LONGSEQ_MAXBIT)) {
+       if( mp->seq > MP_LONGSEQ_MAX && (newseq & MP_LONGSEQ_MAXBIT) ) {
                mp->seq = newseq;       /* the first packet: required for
                                         * rfc1990 non-compliant clients --
                                         * prevents constant packet toss */
@@ -1638,7 +1636,7 @@ static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp,
                spin_unlock_irqrestore(&mp->lock, flags);
                return;
        }
-
+       
        /* find the minimum received sequence number over all links */
        is->last_link_seqno = minseq = newseq;
        for (lpq = net_dev->queue;;) {
@@ -1659,31 +1657,22 @@ static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp,
                                         * packets */
        newfrag = skb;
 
-       /* Insert new fragment into the proper sequence slot.  */
-       skb_queue_walk(&mp->frags, frag) {
-               if (MP_SEQ(frag) == newseq) {
-                       isdn_ppp_mp_free_skb(mp, newfrag);
-                       newfrag = NULL;
-                       break;
-               }
-               if (MP_LT(newseq, MP_SEQ(frag))) {
-                       __skb_queue_before(&mp->frags, frag, newfrag);
-                       newfrag = NULL;
-                       break;
-               }
-       }
-       if (newfrag)
-               __skb_queue_tail(&mp->frags, newfrag);
+       /* if this new fragment is before the first one, then enqueue it now. */
+       if ((frag = mp->frags) == NULL || MP_LT(newseq, MP_SEQ(frag))) {
+               newfrag->next = frag;
+               mp->frags = frag = newfrag;
+               newfrag = NULL;
+       }
 
-       frag = skb_peek(&mp->frags);
-       start = ((MP_FLAGS(frag) & MP_BEGIN_FRAG) &&
-                (MP_SEQ(frag) == mp->seq)) ? frag : NULL;
-       if (!start)
-               goto check_overflow;
+       start = MP_FLAGS(frag) & MP_BEGIN_FRAG &&
+                               MP_SEQ(frag) == mp->seq ? frag : NULL;
 
-       /* main fragment traversing loop
+       /* 
+        * main fragment traversing loop
         *
         * try to accomplish several tasks:
+        * - insert new fragment into the proper sequence slot (once that's done
+        *   newfrag will be set to NULL)
         * - reassemble any complete fragment sequence (non-null 'start'
         *   indicates there is a continguous sequence present)
         * - discard any incomplete sequences that are below minseq -- due
@@ -1692,46 +1681,71 @@ static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp,
         *   come to complete such sequence and it should be discarded
         *
         * loop completes when we accomplished the following tasks:
+        * - new fragment is inserted in the proper sequence ('newfrag' is 
+        *   set to NULL)
         * - we hit a gap in the sequence, so no reassembly/processing is 
         *   possible ('start' would be set to NULL)
         *
         * algorithm for this code is derived from code in the book
         * 'PPP Design And Debugging' by James Carlson (Addison-Wesley)
         */
-       skb_queue_walk_safe(&mp->frags, frag, nextf) {
-               thisseq = MP_SEQ(frag);
-
-               /* check for misplaced start */
-               if (start != frag && (MP_FLAGS(frag) & MP_BEGIN_FRAG)) {
-                       printk(KERN_WARNING"isdn_mppp(seq %d): new "
-                              "BEGIN flag with no prior END", thisseq);
-                       stats->seqerrs++;
-                       stats->frame_drops++;
-                       isdn_ppp_mp_discard(mp, start, frag);
-                       start = frag;
-               } else if (MP_LE(thisseq, minseq)) {            
-                       if (MP_FLAGS(frag) & MP_BEGIN_FRAG)
+       while (start != NULL || newfrag != NULL) {
+
+               thisseq = MP_SEQ(frag);
+               nextf = frag->next;
+
+               /* drop any duplicate fragments */
+               if (newfrag != NULL && thisseq == newseq) {
+                       isdn_ppp_mp_free_skb(mp, newfrag);
+                       newfrag = NULL;
+               }
+
+               /* insert new fragment before next element if possible. */
+               if (newfrag != NULL && (nextf == NULL || 
+                                               MP_LT(newseq, MP_SEQ(nextf)))) {
+                       newfrag->next = nextf;
+                       frag->next = nextf = newfrag;
+                       newfrag = NULL;
+               }
+
+               if (start != NULL) {
+                       /* check for misplaced start */
+                       if (start != frag && (MP_FLAGS(frag) & MP_BEGIN_FRAG)) {
+                               printk(KERN_WARNING"isdn_mppp(seq %d): new "
+                                     "BEGIN flag with no prior END", thisseq);
+                               stats->seqerrs++;
+                               stats->frame_drops++;
+                               start = isdn_ppp_mp_discard(mp, start,frag);
+                               nextf = frag->next;
+                       }
+               } else if (MP_LE(thisseq, minseq)) {            
+                       if (MP_FLAGS(frag) & MP_BEGIN_FRAG)
                                start = frag;
-                       else {
+                       else {
                                if (MP_FLAGS(frag) & MP_END_FRAG)
-                                       stats->frame_drops++;
-                               __skb_unlink(skb, &mp->frags);
+                                       stats->frame_drops++;
+                               if( mp->frags == frag )
+                                       mp->frags = nextf;      
                                isdn_ppp_mp_free_skb(mp, frag);
+                               frag = nextf;
                                continue;
-                       }
+                       }
                }
-
-               /* if we have end fragment, then we have full reassembly
-                * sequence -- reassemble and process packet now
+               
+               /* if start is non-null and we have end fragment, then
+                * we have full reassembly sequence -- reassemble 
+                * and process packet now
                 */
-               if (MP_FLAGS(frag) & MP_END_FRAG) {
-                       minseq = mp->seq = (thisseq+1) & MP_LONGSEQ_MASK;
-                       /* Reassemble the packet then dispatch it */
-                       isdn_ppp_mp_reassembly(net_dev, lp, start, frag, thisseq);
+               if (start != NULL && (MP_FLAGS(frag) & MP_END_FRAG)) {
+                       minseq = mp->seq = (thisseq+1) & MP_LONGSEQ_MASK;
+                       /* Reassemble the packet then dispatch it */
+                       isdn_ppp_mp_reassembly(net_dev, lp, start, nextf);
+      
+                       start = NULL;
+                       frag = NULL;
 
-                       start = NULL;
-                       frag = NULL;
-               }
+                       mp->frags = nextf;
+               }
 
                /* check if need to update start pointer: if we just
                 * reassembled the packet and sequence is contiguous
@@ -1742,25 +1756,26 @@ static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp,
                 * below low watermark and set start to the next frag or
                 * clear start ptr.
                 */ 
-               if (nextf != (struct sk_buff *)&mp->frags && 
+               if (nextf != NULL && 
                    ((thisseq+1) & MP_LONGSEQ_MASK) == MP_SEQ(nextf)) {
-                       /* if we just reassembled and the next one is here, 
-                        * then start another reassembly.
-                        */
-                       if (frag == NULL) {
+                       /* if we just reassembled and the next one is here, 
+                        * then start another reassembly. */
+
+                       if (frag == NULL) {
                                if (MP_FLAGS(nextf) & MP_BEGIN_FRAG)
-                                       start = nextf;
-                               else {
-                                       printk(KERN_WARNING"isdn_mppp(seq %d):"
-                                              " END flag with no following "
-                                              "BEGIN", thisseq);
+                                       start = nextf;
+                               else
+                               {
+                                       printk(KERN_WARNING"isdn_mppp(seq %d):"
+                                               " END flag with no following "
+                                               "BEGIN", thisseq);
                                        stats->seqerrs++;
                                }
                        }
-               } else {
-                       if (nextf != (struct sk_buff *)&mp->frags &&
-                           frag != NULL &&
-                           MP_LT(thisseq, minseq)) {
+
+               } else {
+                       if ( nextf != NULL && frag != NULL &&
+                                               MP_LT(thisseq, minseq)) {
                                /* we've got a break in the sequence
                                 * and we not at the end yet
                                 * and we did not just reassembled
@@ -1769,39 +1784,41 @@ static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp,
                                 * discard all the frames below low watermark 
                                 * and start over */
                                stats->frame_drops++;
-                               isdn_ppp_mp_discard(mp, start, nextf);
+                               mp->frags = isdn_ppp_mp_discard(mp,start,nextf);
                        }
                        /* break in the sequence, no reassembly */
-                       start = NULL;
-               }
-               if (!start)
-                       break;
-       }
-
-check_overflow:
+                       start = NULL;
+               }
+                               
+               frag = nextf;
+       }       /* while -- main loop */
+       
+       if (mp->frags == NULL)
+               mp->frags = frag;
+               
        /* rather straighforward way to deal with (not very) possible 
-        * queue overflow
-        */
+        * queue overflow */
        if (mp->frames > MP_MAX_QUEUE_LEN) {
                stats->overflows++;
-               skb_queue_walk_safe(&mp->frags, frag, nextf) {
-                       if (mp->frames <= MP_MAX_QUEUE_LEN)
-                               break;
-                       __skb_unlink(frag, &mp->frags);
-                       isdn_ppp_mp_free_skb(mp, frag);
+               while (mp->frames > MP_MAX_QUEUE_LEN) {
+                       frag = mp->frags->next;
+                       isdn_ppp_mp_free_skb(mp, mp->frags);
+                       mp->frags = frag;
                }
        }
        spin_unlock_irqrestore(&mp->lock, flags);
 }
 
-static void isdn_ppp_mp_cleanup(isdn_net_local *lp)
+static void isdn_ppp_mp_cleanup( isdn_net_local * lp )
 {
-       struct sk_buff *skb, *tmp;
-
-       skb_queue_walk_safe(&lp->netdev->pb->frags, skb, tmp) {
-               __skb_unlink(skb, &lp->netdev->pb->frags);
-               isdn_ppp_mp_free_skb(lp->netdev->pb, skb);
-       }
+       struct sk_buff * frag = lp->netdev->pb->frags;
+       struct sk_buff * nextfrag;
+       while( frag ) {
+               nextfrag = frag->next;
+               isdn_ppp_mp_free_skb(lp->netdev->pb, frag);
+               frag = nextfrag;
+       }
+       lp->netdev->pb->frags = NULL;
 }
 
 static u32 isdn_ppp_mp_get_seq( int short_seq, 
@@ -1838,115 +1855,72 @@ static u32 isdn_ppp_mp_get_seq( int short_seq,
        return seq;
 }
 
-static void isdn_ppp_mp_discard(ippp_bundle *mp, struct sk_buff *from,
-                               struct sk_buff *to)
+struct sk_buff * isdn_ppp_mp_discard( ippp_bundle * mp,
+                       struct sk_buff * from, struct sk_buff * to )
 {
-       if (from) {
-               struct sk_buff *skb, *tmp;
-               int freeing = 0;
-
-               skb_queue_walk_safe(&mp->frags, skb, tmp) {
-                       if (skb == to)
-                               break;
-                       if (skb == from)
-                               freeing = 1;
-                       if (!freeing)
-                               continue;
-                       __skb_unlink(skb, &mp->frags);
-                       isdn_ppp_mp_free_skb(mp, skb);
+       if( from )
+               while (from != to) {
+                       struct sk_buff * next = from->next;
+                       isdn_ppp_mp_free_skb(mp, from);
+                       from = next;
                }
-       }
-}
-
-static unsigned int calc_tot_len(struct sk_buff_head *queue,
-                                struct sk_buff *from, struct sk_buff *to)
-{
-       unsigned int tot_len = 0;
-       struct sk_buff *skb;
-       int found_start = 0;
-
-       skb_queue_walk(queue, skb) {
-               if (skb == from)
-                       found_start = 1;
-               if (!found_start)
-                       continue;
-               tot_len += skb->len - MP_HEADER_LEN;
-               if (skb == to)
-                       break;
-       }
-       return tot_len;
+       return from;
 }
 
-/* Reassemble packet using fragments in the reassembly queue from
- * 'from' until 'to', inclusive.
- */
-static void isdn_ppp_mp_reassembly(isdn_net_dev *net_dev, isdn_net_local *lp,
-                                  struct sk_buff *from, struct sk_buff *to,
-                                  u32 lastseq)
+void isdn_ppp_mp_reassembly( isdn_net_dev * net_dev, isdn_net_local * lp,
+                               struct sk_buff * from, struct sk_buff * to )
 {
-       ippp_bundle *mp = net_dev->pb;
-       unsigned int tot_len;
-       struct sk_buff *skb;
+       ippp_bundle * mp = net_dev->pb;
        int proto;
+       struct sk_buff * skb;
+       unsigned int tot_len;
 
        if (lp->ppp_slot < 0 || lp->ppp_slot >= ISDN_MAX_CHANNELS) {
                printk(KERN_ERR "%s: lp->ppp_slot(%d) out of range\n",
                        __func__, lp->ppp_slot);
                return;
        }
-
-       tot_len = calc_tot_len(&mp->frags, from, to);
-
-       if (MP_FLAGS(from) == (MP_BEGIN_FRAG | MP_END_FRAG)) {
-               if (ippp_table[lp->ppp_slot]->debug & 0x40)
+       if( MP_FLAGS(from) == (MP_BEGIN_FRAG | MP_END_FRAG) ) {
+               if( ippp_table[lp->ppp_slot]->debug & 0x40 )
                        printk(KERN_DEBUG "isdn_mppp: reassembly: frame %d, "
-                              "len %d\n", MP_SEQ(from), from->len);
+                                       "len %d\n", MP_SEQ(from), from->len );
                skb = from;
                skb_pull(skb, MP_HEADER_LEN);
-               __skb_unlink(skb, &mp->frags);
                mp->frames--;   
        } else {
-               struct sk_buff *walk, *tmp;
-               int found_start = 0;
+               struct sk_buff * frag;
+               int n;
 
-               if (ippp_table[lp->ppp_slot]->debug & 0x40)
-                       printk(KERN_DEBUG"isdn_mppp: reassembling frames %d "
-                              "to %d, len %d\n", MP_SEQ(from), lastseq,
-                              tot_len);
+               for(tot_len=n=0, frag=from; frag != to; frag=frag->next, n++)
+                       tot_len += frag->len - MP_HEADER_LEN;
 
-               skb = dev_alloc_skb(tot_len);
-               if (!skb)
+               if( ippp_table[lp->ppp_slot]->debug & 0x40 )
+                       printk(KERN_DEBUG"isdn_mppp: reassembling frames %d "
+                               "to %d, len %d\n", MP_SEQ(from), 
+                               (MP_SEQ(from)+n-1) & MP_LONGSEQ_MASK, tot_len );
+               if( (skb = dev_alloc_skb(tot_len)) == NULL ) {
                        printk(KERN_ERR "isdn_mppp: cannot allocate sk buff "
-                              "of size %d\n", tot_len);
-
-               found_start = 0;
-               skb_queue_walk_safe(&mp->frags, walk, tmp) {
-                       if (walk == from)
-                               found_start = 1;
-                       if (!found_start)
-                               continue;
+                                       "of size %d\n", tot_len);
+                       isdn_ppp_mp_discard(mp, from, to);
+                       return;
+               }
 
-                       if (skb) {
-                               unsigned int len = walk->len - MP_HEADER_LEN;
-                               skb_copy_from_linear_data_offset(walk, MP_HEADER_LEN,
-                                                                skb_put(skb, len),
-                                                                len);
-                       }
-                       __skb_unlink(walk, &mp->frags);
-                       isdn_ppp_mp_free_skb(mp, walk);
+               while( from != to ) {
+                       unsigned int len = from->len - MP_HEADER_LEN;
 
-                       if (walk == to)
-                               break;
+                       skb_copy_from_linear_data_offset(from, MP_HEADER_LEN,
+                                                        skb_put(skb,len),
+                                                        len);
+                       frag = from->next;
+                       isdn_ppp_mp_free_skb(mp, from);
+                       from = frag; 
                }
        }
-       if (!skb)
-               return;
-
        proto = isdn_ppp_strip_proto(skb);
        isdn_ppp_push_higher(net_dev, lp, skb, proto);
 }
 
-static void isdn_ppp_mp_free_skb(ippp_bundle *mp, struct sk_buff *skb)
+static void isdn_ppp_mp_free_skb(ippp_bundle * mp, struct sk_buff * skb)
 {
        dev_kfree_skb(skb);
        mp->frames--;
index 7467980b8cf975dd92758c13d57d189322b2a6f2..e5225d28f39245cbff44373f38947e3839847a6f 100644 (file)
@@ -78,6 +78,8 @@ static int __devinit create_gpio_led(const struct gpio_led *template,
 {
        int ret, state;
 
+       led_dat->gpio = -1;
+
        /* skip leds that aren't available */
        if (!gpio_is_valid(template->gpio)) {
                printk(KERN_INFO "Skipping unavailable LED gpio %d (%s)\n",
index e64c971038d14a4ddc588876d010e5b748b05d8f..b182f86a19dda9c71d12553e9d6891f2e24d0cfe 100644 (file)
@@ -944,6 +944,14 @@ static int super_90_validate(mddev_t *mddev, mdk_rdev_t *rdev)
                            desc->raid_disk < mddev->raid_disks */) {
                        set_bit(In_sync, &rdev->flags);
                        rdev->raid_disk = desc->raid_disk;
+               } else if (desc->state & (1<<MD_DISK_ACTIVE)) {
+                       /* active but not in sync implies recovery up to
+                        * reshape position.  We don't know exactly where
+                        * that is, so set to zero for now */
+                       if (mddev->minor_version >= 91) {
+                               rdev->recovery_offset = 0;
+                               rdev->raid_disk = desc->raid_disk;
+                       }
                }
                if (desc->state & (1<<MD_DISK_WRITEMOSTLY))
                        set_bit(WriteMostly, &rdev->flags);
@@ -1032,8 +1040,19 @@ static void super_90_sync(mddev_t *mddev, mdk_rdev_t *rdev)
        list_for_each_entry(rdev2, &mddev->disks, same_set) {
                mdp_disk_t *d;
                int desc_nr;
-               if (rdev2->raid_disk >= 0 && test_bit(In_sync, &rdev2->flags)
-                   && !test_bit(Faulty, &rdev2->flags))
+               int is_active = test_bit(In_sync, &rdev2->flags);
+
+               if (rdev2->raid_disk >= 0 &&
+                   sb->minor_version >= 91)
+                       /* we have nowhere to store the recovery_offset,
+                        * but if it is not below the reshape_position,
+                        * we can piggy-back on that.
+                        */
+                       is_active = 1;
+               if (rdev2->raid_disk < 0 ||
+                   test_bit(Faulty, &rdev2->flags))
+                       is_active = 0;
+               if (is_active)
                        desc_nr = rdev2->raid_disk;
                else
                        desc_nr = next_spare++;
@@ -1043,16 +1062,16 @@ static void super_90_sync(mddev_t *mddev, mdk_rdev_t *rdev)
                d->number = rdev2->desc_nr;
                d->major = MAJOR(rdev2->bdev->bd_dev);
                d->minor = MINOR(rdev2->bdev->bd_dev);
-               if (rdev2->raid_disk >= 0 && test_bit(In_sync, &rdev2->flags)
-                   && !test_bit(Faulty, &rdev2->flags))
+               if (is_active)
                        d->raid_disk = rdev2->raid_disk;
                else
                        d->raid_disk = rdev2->desc_nr; /* compatibility */
                if (test_bit(Faulty, &rdev2->flags))
                        d->state = (1<<MD_DISK_FAULTY);
-               else if (test_bit(In_sync, &rdev2->flags)) {
+               else if (is_active) {
                        d->state = (1<<MD_DISK_ACTIVE);
-                       d->state |= (1<<MD_DISK_SYNC);
+                       if (test_bit(In_sync, &rdev2->flags))
+                               d->state |= (1<<MD_DISK_SYNC);
                        active++;
                        working++;
                } else {
@@ -1382,8 +1401,6 @@ static void super_1_sync(mddev_t *mddev, mdk_rdev_t *rdev)
 
        if (rdev->raid_disk >= 0 &&
            !test_bit(In_sync, &rdev->flags)) {
-               if (mddev->curr_resync_completed > rdev->recovery_offset)
-                       rdev->recovery_offset = mddev->curr_resync_completed;
                if (rdev->recovery_offset > 0) {
                        sb->feature_map |=
                                cpu_to_le32(MD_FEATURE_RECOVERY_OFFSET);
@@ -1917,6 +1934,14 @@ static void sync_sbs(mddev_t * mddev, int nospares)
         */
        mdk_rdev_t *rdev;
 
+       /* First make sure individual recovery_offsets are correct */
+       list_for_each_entry(rdev, &mddev->disks, same_set) {
+               if (rdev->raid_disk >= 0 &&
+                   !test_bit(In_sync, &rdev->flags) &&
+                   mddev->curr_resync_completed > rdev->recovery_offset)
+                               rdev->recovery_offset = mddev->curr_resync_completed;
+
+       }       
        list_for_each_entry(rdev, &mddev->disks, same_set) {
                if (rdev->sb_events == mddev->events ||
                    (nospares &&
index a053423785c92e74256e4ad8e2aadc658538aee0..e07ce2e033a95c48ba2c9a78c519640743220e2d 100644 (file)
@@ -1650,11 +1650,12 @@ static void raid1d(mddev_t *mddev)
                                               r1_bio->sector,
                                               r1_bio->sectors);
                                unfreeze_array(conf);
-                       }
+                       } else
+                               md_error(mddev,
+                                        conf->mirrors[r1_bio->read_disk].rdev);
 
                        bio = r1_bio->bios[r1_bio->read_disk];
-                       if ((disk=read_balance(conf, r1_bio)) == -1 ||
-                           disk == r1_bio->read_disk) {
+                       if ((disk=read_balance(conf, r1_bio)) == -1) {
                                printk(KERN_ALERT "raid1: %s: unrecoverable I/O"
                                       " read error for block %llu\n",
                                       bdevname(bio->bi_bdev,b),
index dcce204b6c733bb36887ab1981e25ac35ece189b..d29215d966dadc23f4c1a6844a725dc89d6a8304 100644 (file)
@@ -4823,11 +4823,40 @@ static raid5_conf_t *setup_conf(mddev_t *mddev)
                return ERR_PTR(-ENOMEM);
 }
 
+
+static int only_parity(int raid_disk, int algo, int raid_disks, int max_degraded)
+{
+       switch (algo) {
+       case ALGORITHM_PARITY_0:
+               if (raid_disk < max_degraded)
+                       return 1;
+               break;
+       case ALGORITHM_PARITY_N:
+               if (raid_disk >= raid_disks - max_degraded)
+                       return 1;
+               break;
+       case ALGORITHM_PARITY_0_6:
+               if (raid_disk == 0 || 
+                   raid_disk == raid_disks - 1)
+                       return 1;
+               break;
+       case ALGORITHM_LEFT_ASYMMETRIC_6:
+       case ALGORITHM_RIGHT_ASYMMETRIC_6:
+       case ALGORITHM_LEFT_SYMMETRIC_6:
+       case ALGORITHM_RIGHT_SYMMETRIC_6:
+               if (raid_disk == raid_disks - 1)
+                       return 1;
+       }
+       return 0;
+}
+
 static int run(mddev_t *mddev)
 {
        raid5_conf_t *conf;
        int working_disks = 0, chunk_size;
+       int dirty_parity_disks = 0;
        mdk_rdev_t *rdev;
+       sector_t reshape_offset = 0;
 
        if (mddev->recovery_cp != MaxSector)
                printk(KERN_NOTICE "raid5: %s is not clean"
@@ -4861,6 +4890,7 @@ static int run(mddev_t *mddev)
                               "on a stripe boundary\n");
                        return -EINVAL;
                }
+               reshape_offset = here_new * mddev->new_chunk_sectors;
                /* here_new is the stripe we will write to */
                here_old = mddev->reshape_position;
                sector_div(here_old, mddev->chunk_sectors *
@@ -4916,10 +4946,51 @@ static int run(mddev_t *mddev)
        /*
         * 0 for a fully functional array, 1 or 2 for a degraded array.
         */
-       list_for_each_entry(rdev, &mddev->disks, same_set)
-               if (rdev->raid_disk >= 0 &&
-                   test_bit(In_sync, &rdev->flags))
+       list_for_each_entry(rdev, &mddev->disks, same_set) {
+               if (rdev->raid_disk < 0)
+                       continue;
+               if (test_bit(In_sync, &rdev->flags))
                        working_disks++;
+               /* This disc is not fully in-sync.  However if it
+                * just stored parity (beyond the recovery_offset),
+                * when we don't need to be concerned about the
+                * array being dirty.
+                * When reshape goes 'backwards', we never have
+                * partially completed devices, so we only need
+                * to worry about reshape going forwards.
+                */
+               /* Hack because v0.91 doesn't store recovery_offset properly. */
+               if (mddev->major_version == 0 &&
+                   mddev->minor_version > 90)
+                       rdev->recovery_offset = reshape_offset;
+                       
+               printk("%d: w=%d pa=%d pr=%d m=%d a=%d r=%d op1=%d op2=%d\n",
+                      rdev->raid_disk, working_disks, conf->prev_algo,
+                      conf->previous_raid_disks, conf->max_degraded,
+                      conf->algorithm, conf->raid_disks, 
+                      only_parity(rdev->raid_disk,
+                                  conf->prev_algo,
+                                  conf->previous_raid_disks,
+                                  conf->max_degraded),
+                      only_parity(rdev->raid_disk,
+                                  conf->algorithm,
+                                  conf->raid_disks,
+                                  conf->max_degraded));
+               if (rdev->recovery_offset < reshape_offset) {
+                       /* We need to check old and new layout */
+                       if (!only_parity(rdev->raid_disk,
+                                        conf->algorithm,
+                                        conf->raid_disks,
+                                        conf->max_degraded))
+                               continue;
+               }
+               if (!only_parity(rdev->raid_disk,
+                                conf->prev_algo,
+                                conf->previous_raid_disks,
+                                conf->max_degraded))
+                       continue;
+               dirty_parity_disks++;
+       }
 
        mddev->degraded = (max(conf->raid_disks, conf->previous_raid_disks)
                           - working_disks);
@@ -4935,7 +5006,7 @@ static int run(mddev_t *mddev)
        mddev->dev_sectors &= ~(mddev->chunk_sectors - 1);
        mddev->resync_max_sectors = mddev->dev_sectors;
 
-       if (mddev->degraded > 0 &&
+       if (mddev->degraded > dirty_parity_disks &&
            mddev->recovery_cp != MaxSector) {
                if (mddev->ok_start_degraded)
                        printk(KERN_WARNING
@@ -5361,9 +5432,11 @@ static int raid5_start_reshape(mddev_t *mddev)
                    !test_bit(Faulty, &rdev->flags)) {
                        if (raid5_add_disk(mddev, rdev) == 0) {
                                char nm[20];
-                               set_bit(In_sync, &rdev->flags);
+                               if (rdev->raid_disk >= conf->previous_raid_disks)
+                                       set_bit(In_sync, &rdev->flags);
+                               else
+                                       rdev->recovery_offset = 0;
                                added_devices++;
-                               rdev->recovery_offset = 0;
                                sprintf(nm, "rd%d", rdev->raid_disk);
                                if (sysfs_create_link(&mddev->kobj,
                                                      &rdev->kobj, nm))
index 655474b29e21ca23347cf15d7dc707a644a0011e..abd4791acb0ec0a426283d1174b4e088a1b497fc 100644 (file)
@@ -64,7 +64,7 @@ void ir_input_init(struct input_dev *dev, struct ir_input_state *ir,
 
        ir->ir_type = ir_type;
 
-       memset(ir->ir_codes, sizeof(ir->ir_codes), 0);
+       memset(ir->ir_codes, 0, sizeof(ir->ir_codes));
 
        /*
         * FIXME: This is a temporary workaround to use the new IR tables
index ddf639ed2fd8de2d59c4ddfc663bcceb46f95ee2..98082416aa52aec23e14ec242a6416f02ae443c3 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/wait.h>
 #include <linux/slab.h>
 #include <linux/poll.h>
+#include <linux/semaphore.h>
 #include <linux/module.h>
 #include <linux/list.h>
 #include <linux/freezer.h>
index f65591fb7cec36d720d9717b8503c513cbcd3082..2a53dd096eef86b678fff1939d58f9b387ea3fce 100644 (file)
@@ -663,6 +663,14 @@ static struct zl10353_config cxusb_zl10353_xc3028_config = {
        .parallel_ts = 1,
 };
 
+static struct zl10353_config cxusb_zl10353_xc3028_config_no_i2c_gate = {
+       .demod_address = 0x0f,
+       .if2 = 45600,
+       .no_tuner = 1,
+       .parallel_ts = 1,
+       .disable_i2c_gate_ctrl = 1,
+};
+
 static struct mt352_config cxusb_mt352_xc3028_config = {
        .demod_address = 0x0f,
        .if2 = 4560,
@@ -894,7 +902,7 @@ static int cxusb_dualdig4_frontend_attach(struct dvb_usb_adapter *adap)
        cxusb_bluebird_gpio_pulse(adap->dev, 0x02, 1);
 
        if ((adap->fe = dvb_attach(zl10353_attach,
-                                  &cxusb_zl10353_xc3028_config,
+                                  &cxusb_zl10353_xc3028_config_no_i2c_gate,
                                   &adap->dev->i2c_adap)) == NULL)
                return -EIO;
 
index 8c1aed77ea30b9af7c281b13d079d30923fe7350..85a222c4eaa0606fb7f64da99ba43ce99b3516eb 100644 (file)
@@ -4,7 +4,7 @@
 
 config SMS_SIANO_MDTV
        tristate "Siano SMS1xxx based MDTV receiver"
-       depends on DVB_CORE && INPUT
+       depends on DVB_CORE && INPUT && HAS_DMA
        ---help---
          Choose Y or M here if you have MDTV receiver with a Siano chipset.
 
index c3f579de6e7171b1c7dce048b82ce526b0ba9c59..c6cf1166186824b1c062350617c14c7edef0ed01 100644 (file)
@@ -181,12 +181,10 @@ static void gemtek_pci_mute(struct gemtek_pci *card)
 
 static void gemtek_pci_unmute(struct gemtek_pci *card)
 {
-       mutex_lock(&card->lock);
        if (card->mute) {
                gemtek_pci_setfrequency(card, card->current_frequency);
                card->mute = false;
        }
-       mutex_unlock(&card->lock);
 }
 
 static int gemtek_pci_getsignal(struct gemtek_pci *card)
index c015da813dda1fa159a824ca91d6cf2a5477322e..d14cfb200ed0f83674ee106f1e9c3200cbf81697 100644 (file)
@@ -1426,7 +1426,6 @@ static __init int vpif_probe(struct platform_device *pdev)
        struct vpif_display_config *config;
        int i, j = 0, k, q, m, err = 0;
        struct i2c_adapter *i2c_adap;
-       struct vpif_config *config;
        struct common_obj *common;
        struct channel_obj *ch;
        struct video_device *vfd;
index bdb249bd9d5d272ae534dc7ed036ece6efe858e6..c0fd5c6feeac987a8d7cfabeb975dbc9e7ad0663 100644 (file)
@@ -1584,8 +1584,8 @@ struct em28xx_board em28xx_boards[] = {
        [EM2870_BOARD_REDDO_DVB_C_USB_BOX] = {
                .name          = "Reddo DVB-C USB TV Box",
                .tuner_type    = TUNER_ABSENT,
+               .tuner_gpio    = reddo_dvb_c_usb_box,
                .has_dvb       = 1,
-               .dvb_gpio      = reddo_dvb_c_usb_box,
        },
 };
 const unsigned int em28xx_bcount = ARRAY_SIZE(em28xx_boards);
index 5f37952c75cf77962fce4bf4f3e665afcf8cf8fe..72802291e81238f5f1797cd7fd6c2336255803d1 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/moduleparam.h>
 #include <linux/mutex.h>
 #include <linux/platform_device.h>
+#include <linux/sched.h>
 #include <linux/time.h>
 #include <linux/version.h>
 #include <linux/videodev2.h>
index dff2e5e2d8c6bc7d879577750c9831f859445dc9..7db82bdf6f31bc9421308b21872fb2da39813da0 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/clk.h>
 #include <linux/vmalloc.h>
 #include <linux/interrupt.h>
+#include <linux/sched.h>
 
 #include <media/v4l2-common.h>
 #include <media/v4l2-dev.h>
index 2f78b4f263f5861008bedb906809155b95ef3c46..9c8b7c7b89ee6de7a6c5199636feb2d49194947a 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/platform_device.h>
 #include <linux/videodev2.h>
 #include <linux/pm_runtime.h>
+#include <linux/sched.h>
 
 #include <media/v4l2-common.h>
 #include <media/v4l2-dev.h>
@@ -1723,11 +1724,12 @@ static int __devinit sh_mobile_ceu_probe(struct platform_device *pdev)
 
        err = soc_camera_host_register(&pcdev->ici);
        if (err)
-               goto exit_free_irq;
+               goto exit_free_clk;
 
        return 0;
 
-exit_free_irq:
+exit_free_clk:
+       pm_runtime_disable(&pdev->dev);
        free_irq(pcdev->irq, pcdev);
 exit_release_mem:
        if (platform_get_resource(pdev, IORESOURCE_MEM, 1))
@@ -1747,6 +1749,7 @@ static int __devexit sh_mobile_ceu_remove(struct platform_device *pdev)
                                        struct sh_mobile_ceu_dev, ici);
 
        soc_camera_host_unregister(soc_host);
+       pm_runtime_disable(&pdev->dev);
        free_irq(pcdev->irq, pcdev);
        if (platform_get_resource(pdev, IORESOURCE_MEM, 1))
                dma_release_declared_memory(&pdev->dev);
index 36e617bd13c73778d6c945ef78f95491bf305f08..95fdeb23c2c1455f2930c4645369d266f62bc74e 100644 (file)
@@ -1097,6 +1097,13 @@ static int default_s_crop(struct soc_camera_device *icd, struct v4l2_crop *a)
        return v4l2_subdev_call(sd, video, s_crop, a);
 }
 
+static void soc_camera_device_init(struct device *dev, void *pdata)
+{
+       dev->platform_data      = pdata;
+       dev->bus                = &soc_camera_bus_type;
+       dev->release            = dummy_release;
+}
+
 int soc_camera_host_register(struct soc_camera_host *ici)
 {
        struct soc_camera_host *ix;
@@ -1158,6 +1165,7 @@ void soc_camera_host_unregister(struct soc_camera_host *ici)
 
        list_for_each_entry(icd, &devices, list) {
                if (icd->iface == ici->nr) {
+                       void *pdata = icd->dev.platform_data;
                        /* The bus->remove will be called */
                        device_unregister(&icd->dev);
                        /*
@@ -1169,6 +1177,7 @@ void soc_camera_host_unregister(struct soc_camera_host *ici)
                         * device private data.
                         */
                        memset(&icd->dev, 0, sizeof(icd->dev));
+                       soc_camera_device_init(&icd->dev, pdata);
                }
        }
 
@@ -1200,10 +1209,7 @@ static int soc_camera_device_register(struct soc_camera_device *icd)
                 * man, stay reasonable... */
                return -ENOMEM;
 
-       icd->devnum = num;
-       icd->dev.bus = &soc_camera_bus_type;
-
-       icd->dev.release        = dummy_release;
+       icd->devnum             = num;
        icd->use_count          = 0;
        icd->host_priv          = NULL;
        mutex_init(&icd->video_lock);
@@ -1311,12 +1317,13 @@ static int __devinit soc_camera_pdrv_probe(struct platform_device *pdev)
        icd->iface = icl->bus_id;
        icd->pdev = &pdev->dev;
        platform_set_drvdata(pdev, icd);
-       icd->dev.platform_data = icl;
 
        ret = soc_camera_device_register(icd);
        if (ret < 0)
                goto escdevreg;
 
+       soc_camera_device_init(&icd->dev, icl);
+
        icd->user_width         = DEFAULT_WIDTH;
        icd->user_height        = DEFAULT_HEIGHT;
 
index 635ffc7b03910582b215b3399f27f4eef912b181..c3065c4bcba9fb6019fb664de98f075423348994 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/mm.h>
 #include <linux/pagemap.h>
 #include <linux/dma-mapping.h>
+#include <linux/sched.h>
 #include <media/videobuf-dma-contig.h>
 
 struct videobuf_dma_contig_memory {
index 49b7885c2702ce5ae286b8e267ff75f4ac698c6a..7f27576ca0464bede0c3bb6e1a1f86d04630f5eb 100644 (file)
@@ -29,7 +29,7 @@
 /* Current settings - values are 2*2^(reg_val/4) microamps.  These are
  * exported since they are used by multiple drivers.
  */
-int wm831x_isinkv_values[WM831X_ISINK_MAX_ISEL] = {
+int wm831x_isinkv_values[WM831X_ISINK_MAX_ISEL + 1] = {
        2,
        2,
        3,
index db39f4a52f5311b56f73bf1a54d7c41808cb1174..2cb2736d65aa41bf959c62f6475d0b5ee57d8f15 100644 (file)
@@ -158,6 +158,7 @@ static ssize_t at24_eeprom_read(struct at24_data *at24, char *buf,
        struct i2c_msg msg[2];
        u8 msgbuf[2];
        struct i2c_client *client;
+       unsigned long timeout, read_time;
        int status, i;
 
        memset(msg, 0, sizeof(msg));
@@ -183,47 +184,60 @@ static ssize_t at24_eeprom_read(struct at24_data *at24, char *buf,
        if (count > io_limit)
                count = io_limit;
 
-       /* Smaller eeproms can work given some SMBus extension calls */
        if (at24->use_smbus) {
+               /* Smaller eeproms can work given some SMBus extension calls */
                if (count > I2C_SMBUS_BLOCK_MAX)
                        count = I2C_SMBUS_BLOCK_MAX;
-               status = i2c_smbus_read_i2c_block_data(client, offset,
-                               count, buf);
-               dev_dbg(&client->dev, "smbus read %zu@%d --> %d\n",
-                               count, offset, status);
-               return (status < 0) ? -EIO : status;
+       } else {
+               /*
+                * When we have a better choice than SMBus calls, use a
+                * combined I2C message. Write address; then read up to
+                * io_limit data bytes. Note that read page rollover helps us
+                * here (unlike writes). msgbuf is u8 and will cast to our
+                * needs.
+                */
+               i = 0;
+               if (at24->chip.flags & AT24_FLAG_ADDR16)
+                       msgbuf[i++] = offset >> 8;
+               msgbuf[i++] = offset;
+
+               msg[0].addr = client->addr;
+               msg[0].buf = msgbuf;
+               msg[0].len = i;
+
+               msg[1].addr = client->addr;
+               msg[1].flags = I2C_M_RD;
+               msg[1].buf = buf;
+               msg[1].len = count;
        }
 
        /*
-        * When we have a better choice than SMBus calls, use a combined
-        * I2C message. Write address; then read up to io_limit data bytes.
-        * Note that read page rollover helps us here (unlike writes).
-        * msgbuf is u8 and will cast to our needs.
+        * Reads fail if the previous write didn't complete yet. We may
+        * loop a few times until this one succeeds, waiting at least
+        * long enough for one entire page write to work.
         */
-       i = 0;
-       if (at24->chip.flags & AT24_FLAG_ADDR16)
-               msgbuf[i++] = offset >> 8;
-       msgbuf[i++] = offset;
-
-       msg[0].addr = client->addr;
-       msg[0].buf = msgbuf;
-       msg[0].len = i;
+       timeout = jiffies + msecs_to_jiffies(write_timeout);
+       do {
+               read_time = jiffies;
+               if (at24->use_smbus) {
+                       status = i2c_smbus_read_i2c_block_data(client, offset,
+                                       count, buf);
+               } else {
+                       status = i2c_transfer(client->adapter, msg, 2);
+                       if (status == 2)
+                               status = count;
+               }
+               dev_dbg(&client->dev, "read %zu@%d --> %d (%ld)\n",
+                               count, offset, status, jiffies);
 
-       msg[1].addr = client->addr;
-       msg[1].flags = I2C_M_RD;
-       msg[1].buf = buf;
-       msg[1].len = count;
+               if (status == count)
+                       return count;
 
-       status = i2c_transfer(client->adapter, msg, 2);
-       dev_dbg(&client->dev, "i2c read %zu@%d --> %d\n",
-                       count, offset, status);
+               /* REVISIT: at HZ=100, this is sloooow */
+               msleep(1);
+       } while (time_before(read_time, timeout));
 
-       if (status == 2)
-               return count;
-       else if (status >= 0)
-               return -EIO;
-       else
-               return status;
+       return -ETIMEDOUT;
 }
 
 static ssize_t at24_read(struct at24_data *at24,
index b00d6731905826864abf43a762910899087a3887..9fb480bb0e0a8cca4398941ad4ad483b47dc4887 100644 (file)
@@ -760,6 +760,8 @@ static int pxamci_remove(struct platform_device *pdev)
        if (mmc) {
                struct pxamci_host *host = mmc_priv(mmc);
 
+               mmc_remove_host(mmc);
+
                if (host->pdata) {
                        gpio_cd = host->pdata->gpio_card_detect;
                        gpio_ro = host->pdata->gpio_card_ro;
@@ -779,8 +781,6 @@ static int pxamci_remove(struct platform_device *pdev)
                if (host->pdata && host->pdata->exit)
                        host->pdata->exit(&pdev->dev, mmc);
 
-               mmc_remove_host(mmc);
-
                pxamci_stop_clock(host);
                writel(TXFIFO_WR_REQ|RXFIFO_RD_REQ|CLK_IS_OFF|STOP_CMD|
                       END_CMD_RES|PRG_DONE|DATA_TRAN_DONE,
index d600c2deff73824a70edb5e36f29157f4a36e16a..689d6a79ffc0ed239b3ccdbae50e035b723c7351 100644 (file)
@@ -118,11 +118,9 @@ static caddr_t remap_window(struct map_info *map, unsigned long to)
                DEBUG(2, "Remapping window from 0x%8.8x to 0x%8.8x",
                      dev->offset, mrq.CardOffset);
                mrq.Page = 0;
-               ret = pcmcia_map_mem_page(win, &mrq);
-               if (ret != 0) {
-                       cs_error(dev->p_dev, MapMemPage, ret);
+               ret = pcmcia_map_mem_page(dev->p_dev, win, &mrq);
+               if (ret != 0)
                        return NULL;
-               }
                dev->offset = mrq.CardOffset;
        }
        return dev->win_base + (to & (dev->win_size-1));
@@ -327,8 +325,6 @@ static void pcmciamtd_set_vpp(struct map_info *map, int on)
 
        DEBUG(2, "dev = %p on = %d vpp = %d\n", dev, on, dev->vpp);
        ret = pcmcia_modify_configuration(link, &mod);
-       if (ret != 0)
-               cs_error(link, ModifyConfiguration, ret);
 }
 
 
@@ -348,107 +344,116 @@ static void pcmciamtd_release(struct pcmcia_device *link)
                        iounmap(dev->win_base);
                        dev->win_base = NULL;
                }
-               pcmcia_release_window(link->win);
+               pcmcia_release_window(link, link->win);
        }
        pcmcia_disable_device(link);
 }
 
 
-static void card_settings(struct pcmciamtd_dev *dev, struct pcmcia_device *link, int *new_name)
+#ifdef CONFIG_MTD_DEBUG
+static int pcmciamtd_cistpl_format(struct pcmcia_device *p_dev,
+                               tuple_t *tuple,
+                               void *priv_data)
 {
-       int rc;
-       tuple_t tuple;
        cisparse_t parse;
-       u_char buf[64];
-
-       tuple.Attributes = 0;
-       tuple.TupleData = (cisdata_t *)buf;
-       tuple.TupleDataMax = sizeof(buf);
-       tuple.TupleOffset = 0;
-       tuple.DesiredTuple = RETURN_FIRST_TUPLE;
-
-       rc = pcmcia_get_first_tuple(link, &tuple);
-       while (rc == 0) {
-               rc = pcmcia_get_tuple_data(link, &tuple);
-               if (rc != 0) {
-                       cs_error(link, GetTupleData, rc);
-                       break;
-               }
-               rc = pcmcia_parse_tuple(&tuple, &parse);
-               if (rc != 0) {
-                       cs_error(link, ParseTuple, rc);
-                       break;
-               }
 
-               switch(tuple.TupleCode) {
-               case  CISTPL_FORMAT: {
-                       cistpl_format_t *t = &parse.format;
-                       (void)t; /* Shut up, gcc */
-                       DEBUG(2, "Format type: %u, Error Detection: %u, offset = %u, length =%u",
-                             t->type, t->edc, t->offset, t->length);
-                       break;
+       if (!pcmcia_parse_tuple(tuple, &parse)) {
+               cistpl_format_t *t = &parse.format;
+               (void)t; /* Shut up, gcc */
+               DEBUG(2, "Format type: %u, Error Detection: %u, offset = %u, length =%u",
+                       t->type, t->edc, t->offset, t->length);
+       }
+       return -ENOSPC;
+}
 
-               }
+static int pcmciamtd_cistpl_jedec(struct pcmcia_device *p_dev,
+                               tuple_t *tuple,
+                               void *priv_data)
+{
+       cisparse_t parse;
+       int i;
 
-               case CISTPL_DEVICE: {
-                       cistpl_device_t *t = &parse.device;
-                       int i;
-                       DEBUG(2, "Common memory:");
-                       dev->pcmcia_map.size = t->dev[0].size;
-                       for(i = 0; i < t->ndev; i++) {
-                               DEBUG(2, "Region %d, type = %u", i, t->dev[i].type);
-                               DEBUG(2, "Region %d, wp = %u", i, t->dev[i].wp);
-                               DEBUG(2, "Region %d, speed = %u ns", i, t->dev[i].speed);
-                               DEBUG(2, "Region %d, size = %u bytes", i, t->dev[i].size);
-                       }
-                       break;
-               }
+       if (!pcmcia_parse_tuple(tuple, &parse)) {
+               cistpl_jedec_t *t = &parse.jedec;
+               for (i = 0; i < t->nid; i++)
+                       DEBUG(2, "JEDEC: 0x%02x 0x%02x", t->id[i].mfr, t->id[i].info);
+       }
+       return -ENOSPC;
+}
+#endif
 
-               case CISTPL_VERS_1: {
-                       cistpl_vers_1_t *t = &parse.version_1;
-                       int i;
-                       if(t->ns) {
-                               dev->mtd_name[0] = '\0';
-                               for(i = 0; i < t->ns; i++) {
-                                       if(i)
-                                               strcat(dev->mtd_name, " ");
-                                       strcat(dev->mtd_name, t->str+t->ofs[i]);
-                               }
-                       }
-                       DEBUG(2, "Found name: %s", dev->mtd_name);
-                       break;
-               }
+static int pcmciamtd_cistpl_device(struct pcmcia_device *p_dev,
+                               tuple_t *tuple,
+                               void *priv_data)
+{
+       struct pcmciamtd_dev *dev = priv_data;
+       cisparse_t parse;
+       cistpl_device_t *t = &parse.device;
+       int i;
 
-               case CISTPL_JEDEC_C: {
-                       cistpl_jedec_t *t = &parse.jedec;
-                       int i;
-                       for(i = 0; i < t->nid; i++) {
-                               DEBUG(2, "JEDEC: 0x%02x 0x%02x", t->id[i].mfr, t->id[i].info);
-                       }
-                       break;
-               }
+       if (pcmcia_parse_tuple(tuple, &parse))
+               return -EINVAL;
+
+       DEBUG(2, "Common memory:");
+       dev->pcmcia_map.size = t->dev[0].size;
+       /* from here on: DEBUG only */
+       for (i = 0; i < t->ndev; i++) {
+               DEBUG(2, "Region %d, type = %u", i, t->dev[i].type);
+               DEBUG(2, "Region %d, wp = %u", i, t->dev[i].wp);
+               DEBUG(2, "Region %d, speed = %u ns", i, t->dev[i].speed);
+               DEBUG(2, "Region %d, size = %u bytes", i, t->dev[i].size);
+       }
+       return 0;
+}
 
-               case CISTPL_DEVICE_GEO: {
-                       cistpl_device_geo_t *t = &parse.device_geo;
-                       int i;
-                       dev->pcmcia_map.bankwidth = t->geo[0].buswidth;
-                       for(i = 0; i < t->ngeo; i++) {
-                               DEBUG(2, "region: %d bankwidth = %u", i, t->geo[i].buswidth);
-                               DEBUG(2, "region: %d erase_block = %u", i, t->geo[i].erase_block);
-                               DEBUG(2, "region: %d read_block = %u", i, t->geo[i].read_block);
-                               DEBUG(2, "region: %d write_block = %u", i, t->geo[i].write_block);
-                               DEBUG(2, "region: %d partition = %u", i, t->geo[i].partition);
-                               DEBUG(2, "region: %d interleave = %u", i, t->geo[i].interleave);
-                       }
-                       break;
-               }
+static int pcmciamtd_cistpl_geo(struct pcmcia_device *p_dev,
+                               tuple_t *tuple,
+                               void *priv_data)
+{
+       struct pcmciamtd_dev *dev = priv_data;
+       cisparse_t parse;
+       cistpl_device_geo_t *t = &parse.device_geo;
+       int i;
 
-               default:
-                       DEBUG(2, "Unknown tuple code %d", tuple.TupleCode);
-               }
+       if (pcmcia_parse_tuple(tuple, &parse))
+               return -EINVAL;
+
+       dev->pcmcia_map.bankwidth = t->geo[0].buswidth;
+       /* from here on: DEBUG only */
+       for (i = 0; i < t->ngeo; i++) {
+               DEBUG(2, "region: %d bankwidth = %u", i, t->geo[i].buswidth);
+               DEBUG(2, "region: %d erase_block = %u", i, t->geo[i].erase_block);
+               DEBUG(2, "region: %d read_block = %u", i, t->geo[i].read_block);
+               DEBUG(2, "region: %d write_block = %u", i, t->geo[i].write_block);
+               DEBUG(2, "region: %d partition = %u", i, t->geo[i].partition);
+               DEBUG(2, "region: %d interleave = %u", i, t->geo[i].interleave);
+       }
+       return 0;
+}
+
+
+static void card_settings(struct pcmciamtd_dev *dev, struct pcmcia_device *link, int *new_name)
+{
+       int i;
 
-               rc = pcmcia_get_next_tuple(link, &tuple);
+       if (p_dev->prod_id[0]) {
+               dev->mtd_name[0] = '\0';
+               for (i = 0; i < 4; i++) {
+                       if (i)
+                               strcat(dev->mtd_name, " ");
+                       if (p_dev->prod_id[i])
+                               strcat(dev->mtd_name, p_dev->prod_id[i]);
+               }
+               DEBUG(2, "Found name: %s", dev->mtd_name);
        }
+
+#ifdef CONFIG_MTD_DEBUG
+       pcmcia_loop_tuple(p_dev, CISTPL_FORMAT, pcmciamtd_cistpl_format, NULL);
+       pcmcia_loop_tuple(p_dev, CISTPL_JEDEC_C, pcmciamtd_cistpl_jedec, NULL);
+#endif
+       pcmcia_loop_tuple(p_dev, CISTPL_DEVICE, pcmciamtd_cistpl_device, dev);
+       pcmcia_loop_tuple(p_dev, CISTPL_DEVICE_GEO, pcmciamtd_cistpl_geo, dev);
+
        if(!dev->pcmcia_map.size)
                dev->pcmcia_map.size = MAX_PCMCIA_ADDR;
 
@@ -481,16 +486,12 @@ static void card_settings(struct pcmciamtd_dev *dev, struct pcmcia_device *link,
  * MTD device available to the system.
  */
 
-#define CS_CHECK(fn, ret) \
-do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
-
 static int pcmciamtd_config(struct pcmcia_device *link)
 {
        struct pcmciamtd_dev *dev = link->priv;
        struct mtd_info *mtd = NULL;
        cs_status_t status;
        win_req_t req;
-       int last_ret = 0, last_fn = 0;
        int ret;
        int i;
        static char *probes[] = { "jedec_probe", "cfi_probe" };
@@ -529,7 +530,7 @@ static int pcmciamtd_config(struct pcmcia_device *link)
                int ret;
                DEBUG(2, "requesting window with size = %dKiB memspeed = %d",
                      req.Size >> 10, req.AccessSpeed);
-               ret = pcmcia_request_window(&link, &req, &link->win);
+               ret = pcmcia_request_window(link, &req, &link->win);
                DEBUG(2, "ret = %d dev->win_size = %d", ret, dev->win_size);
                if(ret) {
                        req.Size >>= 1;
@@ -577,7 +578,6 @@ static int pcmciamtd_config(struct pcmcia_device *link)
        DEBUG(2, "Setting Configuration");
        ret = pcmcia_request_configuration(link, &link->conf);
        if (ret != 0) {
-               cs_error(link, RequestConfiguration, ret);
                if (dev->win_base) {
                        iounmap(dev->win_base);
                        dev->win_base = NULL;
@@ -652,8 +652,7 @@ static int pcmciamtd_config(struct pcmcia_device *link)
        link->dev_node = &dev->node;
        return 0;
 
- cs_failed:
-       cs_error(link, last_fn, last_ret);
+ failed:
        err("CS Error, exiting");
        pcmciamtd_release(link);
        return -ENODEV;
index fdb97f3d30e9afc8b0c6b07143ebba9ece6bae79..d7a47574d21e5b9d3cb69a64fba9917eca6acce3 100644 (file)
@@ -209,8 +209,8 @@ static int sa1100_probe_subdev(struct sa_subdev_info *subdev, struct resource *r
        }
        subdev->mtd->owner = THIS_MODULE;
 
-       printk(KERN_INFO "SA1100 flash: CFI device at 0x%08lx, %dMiB, "
-               "%d-bit\n", phys, subdev->mtd->size >> 20,
+       printk(KERN_INFO "SA1100 flash: CFI device at 0x%08lx, %uMiB, %d-bit\n",
+               phys, (unsigned)(subdev->mtd->size >> 20),
                subdev->map.bankwidth * 8);
 
        return 0;
index e19ca4bb75102448879208df00d90aece5b8503b..b2f71f79baaf1f5981aa539f8d96dbb2af627c50 100644 (file)
@@ -975,7 +975,7 @@ config ENC28J60_WRITEVERIFY
 
 config ETHOC
        tristate "OpenCores 10/100 Mbps Ethernet MAC support"
-       depends on NET_ETHERNET && HAS_IOMEM
+       depends on NET_ETHERNET && HAS_IOMEM && HAS_DMA
        select MII
        select PHYLIB
        select CRC32
index 2be49c817995d45e7802fee8eeb61b0e99cf7ad8..b25467ac895c3e8f232506030665c398fe80f73e 100644 (file)
@@ -628,15 +628,6 @@ static int ep93xx_open(struct net_device *dev)
        if (ep93xx_alloc_buffers(ep))
                return -ENOMEM;
 
-       if (is_zero_ether_addr(dev->dev_addr)) {
-               random_ether_addr(dev->dev_addr);
-               printk(KERN_INFO "%s: generated random MAC address "
-                       "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x.\n", dev->name,
-                       dev->dev_addr[0], dev->dev_addr[1],
-                       dev->dev_addr[2], dev->dev_addr[3],
-                       dev->dev_addr[4], dev->dev_addr[5]);
-       }
-
        napi_enable(&ep->napi);
 
        if (ep93xx_start_hw(dev)) {
@@ -877,6 +868,9 @@ static int ep93xx_eth_probe(struct platform_device *pdev)
        ep->mii.mdio_write = ep93xx_mdio_write;
        ep->mdc_divisor = 40;   /* Max HCLK 100 MHz, min MDIO clk 2.5 MHz.  */
 
+       if (is_zero_ether_addr(dev->dev_addr))
+               random_ether_addr(dev->dev_addr);
+
        err = register_netdev(dev);
        if (err) {
                dev_err(&pdev->dev, "Failed to register netdev\n");
index ce6f1ac25df83e6ea3b26298f707cad6a9e488a3..3f4b4300f5332c163c8f520636ff8caf58dd3e90 100644 (file)
@@ -1088,7 +1088,14 @@ static struct net_device * au1000_probe(int port_num)
                return NULL;
        }
 
-       if ((err = register_netdev(dev)) != 0) {
+       dev->base_addr = base;
+       dev->irq = irq;
+       dev->netdev_ops = &au1000_netdev_ops;
+       SET_ETHTOOL_OPS(dev, &au1000_ethtool_ops);
+       dev->watchdog_timeo = ETH_TX_TIMEOUT;
+
+       err = register_netdev(dev);
+       if (err != 0) {
                printk(KERN_ERR "%s: Cannot register net device, error %d\n",
                                DRV_NAME, err);
                free_netdev(dev);
@@ -1209,12 +1216,6 @@ static struct net_device * au1000_probe(int port_num)
                aup->tx_db_inuse[i] = pDB;
        }
 
-       dev->base_addr = base;
-       dev->irq = irq;
-       dev->netdev_ops = &au1000_netdev_ops;
-       SET_ETHTOOL_OPS(dev, &au1000_ethtool_ops);
-       dev->watchdog_timeo = ETH_TX_TIMEOUT;
-
        /*
         * The boot code uses the ethernet controller, so reset it to start
         * fresh.  au1000_init() expects that the device is in reset state.
index e046943ef29dc6c9243bb84ad0c5ab5fcdde19bf..2a9132343b66135fb2487c30a20ba6ce0db786ec 100644 (file)
@@ -912,9 +912,6 @@ static irqreturn_t b44_interrupt(int irq, void *dev_id)
                        bp->istat = istat;
                        __b44_disable_ints(bp);
                        __napi_schedule(&bp->napi);
-               } else {
-                       printk(KERN_ERR PFX "%s: Error, poll already scheduled\n",
-                              dev->name);
                }
 
 irq_ack:
index df32c109b7acee953f48eef55ddd7b6100cc1e40..772f6d2489ce4047ad60c6ae6d5cd23b9adfe11b 100644 (file)
@@ -35,66 +35,16 @@ config CAN_CALC_BITTIMING
          arguments "tq", "prop_seg", "phase_seg1", "phase_seg2" and "sjw".
          If unsure, say Y.
 
-config CAN_SJA1000
-       depends on CAN_DEV && HAS_IOMEM
-       tristate "Philips SJA1000"
-       ---help---
-         Driver for the SJA1000 CAN controllers from Philips or NXP
-
-config CAN_SJA1000_ISA
-       depends on CAN_SJA1000 && ISA
-       tristate "ISA Bus based legacy SJA1000 driver"
-       ---help---
-         This driver adds legacy support for SJA1000 chips connected to
-         the ISA bus using I/O port, memory mapped or indirect access.
-
-config CAN_SJA1000_PLATFORM
-       depends on CAN_SJA1000
-       tristate "Generic Platform Bus based SJA1000 driver"
-       ---help---
-         This driver adds support for the SJA1000 chips connected to
-         the "platform bus" (Linux abstraction for directly to the
-         processor attached devices).  Which can be found on various
-         boards from Phytec (http://www.phytec.de) like the PCM027,
-         PCM038.
-
-config CAN_SJA1000_OF_PLATFORM
-       depends on CAN_SJA1000 && PPC_OF
-       tristate "Generic OF Platform Bus based SJA1000 driver"
-       ---help---
-         This driver adds support for the SJA1000 chips connected to
-         the OpenFirmware "platform bus" found on embedded systems with
-         OpenFirmware bindings, e.g. if you have a PowerPC based system
-         you may want to enable this option.
-
-config CAN_EMS_PCI
-       tristate "EMS CPC-PCI, CPC-PCIe and CPC-104P Card"
-       depends on PCI && CAN_SJA1000
-       ---help---
-         This driver is for the one, two or four channel CPC-PCI,
-         CPC-PCIe and CPC-104P cards from EMS Dr. Thomas Wuensche
-         (http://www.ems-wuensche.de).
-
-config CAN_EMS_USB
-       tristate "EMS CPC-USB/ARM7 CAN/USB interface"
-       depends on USB && CAN_DEV
-       ---help---
-         This driver is for the one channel CPC-USB/ARM7 CAN/USB interface
-         from from EMS Dr. Thomas Wuensche (http://www.ems-wuensche.de).
-
-config CAN_KVASER_PCI
-       tristate "Kvaser PCIcanx and Kvaser PCIcan PCI Cards"
-       depends on PCI && CAN_SJA1000
-       ---help---
-         This driver is for the the PCIcanx and PCIcan cards (1, 2 or
-         4 channel) from Kvaser (http://www.kvaser.com).
-
 config CAN_AT91
        tristate "Atmel AT91 onchip CAN controller"
-       depends on CAN && CAN_DEV && ARCH_AT91SAM9263
+       depends on CAN_DEV && ARCH_AT91SAM9263
        ---help---
          This is a driver for the SoC CAN controller in Atmel's AT91SAM9263.
 
+source "drivers/net/can/sja1000/Kconfig"
+
+source "drivers/net/can/usb/Kconfig"
+
 config CAN_DEBUG_DEVICES
        bool "CAN devices debugging messages"
        depends on CAN
index 564e31c9fee449ba1e56a61a8347429eb1942a59..2868fe842a41cce6d52dcc6dde863c66012c7750 100644 (file)
@@ -629,6 +629,11 @@ nla_put_failure:
        return -EMSGSIZE;
 }
 
+static size_t can_get_xstats_size(const struct net_device *dev)
+{
+       return sizeof(struct can_device_stats);
+}
+
 static int can_fill_xstats(struct sk_buff *skb, const struct net_device *dev)
 {
        struct can_priv *priv = netdev_priv(dev);
@@ -657,6 +662,7 @@ static struct rtnl_link_ops can_link_ops __read_mostly = {
        .changelink     = can_changelink,
        .get_size       = can_get_size,
        .fill_info      = can_fill_info,
+       .get_xstats_size = can_get_xstats_size,
        .fill_xstats    = can_fill_xstats,
 };
 
diff --git a/drivers/net/can/sja1000/Kconfig b/drivers/net/can/sja1000/Kconfig
new file mode 100644 (file)
index 0000000..4c67492
--- /dev/null
@@ -0,0 +1,47 @@
+menuconfig CAN_SJA1000
+       tristate "Philips/NXP SJA1000 devices"
+       depends on CAN_DEV && HAS_IOMEM
+
+if CAN_SJA1000
+
+config CAN_SJA1000_ISA
+       tristate "ISA Bus based legacy SJA1000 driver"
+       depends on ISA
+       ---help---
+         This driver adds legacy support for SJA1000 chips connected to
+         the ISA bus using I/O port, memory mapped or indirect access.
+
+config CAN_SJA1000_PLATFORM
+       tristate "Generic Platform Bus based SJA1000 driver"
+       ---help---
+         This driver adds support for the SJA1000 chips connected to
+         the "platform bus" (Linux abstraction for directly to the
+         processor attached devices).  Which can be found on various
+         boards from Phytec (http://www.phytec.de) like the PCM027,
+         PCM038.
+
+config CAN_SJA1000_OF_PLATFORM
+       tristate "Generic OF Platform Bus based SJA1000 driver"
+       depends on PPC_OF
+       ---help---
+         This driver adds support for the SJA1000 chips connected to
+         the OpenFirmware "platform bus" found on embedded systems with
+         OpenFirmware bindings, e.g. if you have a PowerPC based system
+         you may want to enable this option.
+
+config CAN_EMS_PCI
+       tristate "EMS CPC-PCI, CPC-PCIe and CPC-104P Card"
+       depends on PCI
+       ---help---
+         This driver is for the one, two or four channel CPC-PCI,
+         CPC-PCIe and CPC-104P cards from EMS Dr. Thomas Wuensche
+         (http://www.ems-wuensche.de).
+
+config CAN_KVASER_PCI
+       tristate "Kvaser PCIcanx and Kvaser PCIcan PCI Cards"
+       depends on PCI
+       ---help---
+         This driver is for the the PCIcanx and PCIcan cards (1, 2 or
+         4 channel) from Kvaser (http://www.kvaser.com).
+
+endif
diff --git a/drivers/net/can/usb/Kconfig b/drivers/net/can/usb/Kconfig
new file mode 100644 (file)
index 0000000..bbc78e0
--- /dev/null
@@ -0,0 +1,10 @@
+menu "CAN USB interfaces"
+       depends on USB && CAN_DEV
+
+config CAN_EMS_USB
+       tristate "EMS CPC-USB/ARM7 CAN/USB interface"
+       ---help---
+         This driver is for the one channel CPC-USB/ARM7 CAN/USB interface
+         from from EMS Dr. Thomas Wuensche (http://www.ems-wuensche.de).
+
+endmenu
index c3f75ba701b1dbfa7f6bb718237aefc07eabc3a3..0afd51d4c7a5632965855b650120bac72f34def4 100644 (file)
@@ -3,3 +3,5 @@
 #
 
 obj-$(CONFIG_CAN_EMS_USB) += ems_usb.o
+
+ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG
index f86612857a73b2bb470aecb92dfe94b5c50a1cd7..6366061712f447c198b31e5c5307ede58de51c06 100644 (file)
@@ -879,7 +879,7 @@ recycle:
        pci_dma_sync_single_for_cpu(adap->pdev, dma_addr, len,
                                    PCI_DMA_FROMDEVICE);
        (*sd->pg_chunk.p_cnt)--;
-       if (!*sd->pg_chunk.p_cnt)
+       if (!*sd->pg_chunk.p_cnt && sd->pg_chunk.page != fl->pg_chunk.page)
                pci_unmap_page(adap->pdev,
                               sd->pg_chunk.mapping,
                               fl->alloc_size,
@@ -2088,7 +2088,7 @@ static void lro_add_page(struct adapter *adap, struct sge_qset *qs,
                                    PCI_DMA_FROMDEVICE);
 
        (*sd->pg_chunk.p_cnt)--;
-       if (!*sd->pg_chunk.p_cnt)
+       if (!*sd->pg_chunk.p_cnt && sd->pg_chunk.page != fl->pg_chunk.page)
                pci_unmap_page(adap->pdev,
                               sd->pg_chunk.mapping,
                               fl->alloc_size,
index 3179521aee90152ea16a886f023eba620247ea45..e3478314c0029a9a1a24d89b8ba22812f97752c0 100644 (file)
@@ -164,16 +164,14 @@ static const char emac_version_string[] = "TI DaVinci EMAC Linux v6.1";
 # define EMAC_MBP_MCASTCHAN(ch)                ((ch) & 0x7)
 
 /* EMAC mac_control register */
-#define EMAC_MACCONTROL_TXPTYPE                (0x200)
-#define EMAC_MACCONTROL_TXPACEEN       (0x40)
-#define EMAC_MACCONTROL_MIIEN          (0x20)
-#define EMAC_MACCONTROL_GIGABITEN      (0x80)
-#define EMAC_MACCONTROL_GIGABITEN_SHIFT (7)
-#define EMAC_MACCONTROL_FULLDUPLEXEN   (0x1)
+#define EMAC_MACCONTROL_TXPTYPE                BIT(9)
+#define EMAC_MACCONTROL_TXPACEEN       BIT(6)
+#define EMAC_MACCONTROL_GMIIEN         BIT(5)
+#define EMAC_MACCONTROL_GIGABITEN      BIT(7)
+#define EMAC_MACCONTROL_FULLDUPLEXEN   BIT(0)
 #define EMAC_MACCONTROL_RMIISPEED_MASK BIT(15)
 
 /* GIGABIT MODE related bits */
-#define EMAC_DM646X_MACCONTORL_GMIIEN  BIT(5)
 #define EMAC_DM646X_MACCONTORL_GIG     BIT(7)
 #define EMAC_DM646X_MACCONTORL_GIGFORCE        BIT(17)
 
@@ -192,10 +190,10 @@ static const char emac_version_string[] = "TI DaVinci EMAC Linux v6.1";
 #define EMAC_RX_BUFFER_OFFSET_MASK     (0xFFFF)
 
 /* MAC_IN_VECTOR (0x180) register bit fields */
-#define EMAC_DM644X_MAC_IN_VECTOR_HOST_INT           (0x20000)
-#define EMAC_DM644X_MAC_IN_VECTOR_STATPEND_INT       (0x10000)
-#define EMAC_DM644X_MAC_IN_VECTOR_RX_INT_VEC         (0x0100)
-#define EMAC_DM644X_MAC_IN_VECTOR_TX_INT_VEC         (0x01)
+#define EMAC_DM644X_MAC_IN_VECTOR_HOST_INT     BIT(17)
+#define EMAC_DM644X_MAC_IN_VECTOR_STATPEND_INT BIT(16)
+#define EMAC_DM644X_MAC_IN_VECTOR_RX_INT_VEC   BIT(8)
+#define EMAC_DM644X_MAC_IN_VECTOR_TX_INT_VEC   BIT(0)
 
 /** NOTE:: For DM646x the IN_VECTOR has changed */
 #define EMAC_DM646X_MAC_IN_VECTOR_RX_INT_VEC   BIT(EMAC_DEF_RX_CH)
@@ -203,7 +201,6 @@ static const char emac_version_string[] = "TI DaVinci EMAC Linux v6.1";
 #define EMAC_DM646X_MAC_IN_VECTOR_HOST_INT     BIT(26)
 #define EMAC_DM646X_MAC_IN_VECTOR_STATPEND_INT BIT(27)
 
-
 /* CPPI bit positions */
 #define EMAC_CPPI_SOP_BIT              BIT(31)
 #define EMAC_CPPI_EOP_BIT              BIT(30)
@@ -750,8 +747,7 @@ static void emac_update_phystatus(struct emac_priv *priv)
 
        if (priv->speed == SPEED_1000 && (priv->version == EMAC_VERSION_2)) {
                mac_control = emac_read(EMAC_MACCONTROL);
-               mac_control |= (EMAC_DM646X_MACCONTORL_GMIIEN |
-                               EMAC_DM646X_MACCONTORL_GIG |
+               mac_control |= (EMAC_DM646X_MACCONTORL_GIG |
                                EMAC_DM646X_MACCONTORL_GIGFORCE);
        } else {
                /* Clear the GIG bit and GIGFORCE bit */
@@ -2108,7 +2104,7 @@ static int emac_hw_enable(struct emac_priv *priv)
 
        /* Enable MII */
        val = emac_read(EMAC_MACCONTROL);
-       val |= (EMAC_MACCONTROL_MIIEN);
+       val |= (EMAC_MACCONTROL_GMIIEN);
        emac_write(EMAC_MACCONTROL, val);
 
        /* Enable NAPI and interrupts */
@@ -2140,9 +2136,6 @@ static int emac_poll(struct napi_struct *napi, int budget)
        u32 status = 0;
        u32 num_pkts = 0;
 
-       if (!netif_running(ndev))
-               return 0;
-
        /* Check interrupt vectors and call packet processing */
        status = emac_read(EMAC_MACINVECTOR);
 
index 3c29a20b751e831fd4d338ec316535cc7e43c093..d269a68ce3545d485a506708bb0474af3ad2bdaf 100644 (file)
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/dma-mapping.h>
+#include <linux/dmapool.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/mii.h>
@@ -602,6 +603,7 @@ struct nic {
        struct mem *mem;
        dma_addr_t dma_addr;
 
+       struct pci_pool *cbs_pool;
        dma_addr_t cbs_dma_addr;
        u8 adaptive_ifs;
        u8 tx_threshold;
@@ -1793,9 +1795,7 @@ static void e100_clean_cbs(struct nic *nic)
                        nic->cb_to_clean = nic->cb_to_clean->next;
                        nic->cbs_avail++;
                }
-               pci_free_consistent(nic->pdev,
-                       sizeof(struct cb) * nic->params.cbs.count,
-                       nic->cbs, nic->cbs_dma_addr);
+               pci_pool_free(nic->cbs_pool, nic->cbs, nic->cbs_dma_addr);
                nic->cbs = NULL;
                nic->cbs_avail = 0;
        }
@@ -1813,8 +1813,8 @@ static int e100_alloc_cbs(struct nic *nic)
        nic->cb_to_use = nic->cb_to_send = nic->cb_to_clean = NULL;
        nic->cbs_avail = 0;
 
-       nic->cbs = pci_alloc_consistent(nic->pdev,
-               sizeof(struct cb) * count, &nic->cbs_dma_addr);
+       nic->cbs = pci_pool_alloc(nic->cbs_pool, GFP_KERNEL,
+                                 &nic->cbs_dma_addr);
        if (!nic->cbs)
                return -ENOMEM;
 
@@ -2841,7 +2841,11 @@ static int __devinit e100_probe(struct pci_dev *pdev,
                DPRINTK(PROBE, ERR, "Cannot register net device, aborting.\n");
                goto err_out_free;
        }
-
+       nic->cbs_pool = pci_pool_create(netdev->name,
+                          nic->pdev,
+                          nic->params.cbs.count * sizeof(struct cb),
+                          sizeof(u32),
+                          0);
        DPRINTK(PROBE, INFO, "addr 0x%llx, irq %d, MAC addr %pM\n",
                (unsigned long long)pci_resource_start(pdev, use_io ? 1 : 0),
                pdev->irq, netdev->dev_addr);
@@ -2871,6 +2875,7 @@ static void __devexit e100_remove(struct pci_dev *pdev)
                unregister_netdev(netdev);
                e100_free(nic);
                pci_iounmap(pdev, nic->csr);
+               pci_pool_destroy(nic->cbs_pool);
                free_netdev(netdev);
                pci_release_regions(pdev);
                pci_disable_device(pdev);
index 189dfa2d6c76b80ad4702bfb281a541ed500b783..3e187b0e4203e5aa574435a200c57d30468ab397 100644 (file)
@@ -141,6 +141,8 @@ struct e1000_info;
 #define HV_TNCRS_UPPER         PHY_REG(778, 29) /* Transmit with no CRS */
 #define HV_TNCRS_LOWER         PHY_REG(778, 30)
 
+#define E1000_FCRTV_PCH     0x05F40 /* PCH Flow Control Refresh Timer Value */
+
 /* BM PHY Copper Specific Status */
 #define BM_CS_STATUS                      17
 #define BM_CS_STATUS_LINK_UP              0x0400
index 1bf4d2a5d34f8b7421839033c7dd4cedb748bc1c..e82638ecae88dbc079adf98089b7c42a0626c4a2 100644 (file)
@@ -327,10 +327,18 @@ static int e1000_set_pauseparam(struct net_device *netdev,
 
                hw->fc.current_mode = hw->fc.requested_mode;
 
-               retval = ((hw->phy.media_type == e1000_media_type_fiber) ?
-                         hw->mac.ops.setup_link(hw) : e1000e_force_mac_fc(hw));
+               if (hw->phy.media_type == e1000_media_type_fiber) {
+                       retval = hw->mac.ops.setup_link(hw);
+                       /* implicit goto out */
+               } else {
+                       retval = e1000e_force_mac_fc(hw);
+                       if (retval)
+                               goto out;
+                       e1000e_set_fc_watermarks(hw);
+               }
        }
 
+out:
        clear_bit(__E1000_RESETTING, &adapter->state);
        return retval;
 }
index 51ddb04ab19588adcb16e460f7beecd1261b8e69..eff3f478365556bf00a5ed996a398bf051190105 100644 (file)
@@ -1118,7 +1118,8 @@ static s32 e1000_oem_bits_config_ich8lan(struct e1000_hw *hw, bool d0_state)
                        oem_reg |= HV_OEM_BITS_LPLU;
        }
        /* Restart auto-neg to activate the bits */
-       oem_reg |= HV_OEM_BITS_RESTART_AN;
+       if (!e1000_check_reset_block(hw))
+               oem_reg |= HV_OEM_BITS_RESTART_AN;
        ret_val = hw->phy.ops.write_phy_reg_locked(hw, HV_OEM_BITS, oem_reg);
 
 out:
@@ -3558,6 +3559,7 @@ struct e1000_info e1000_pch_info = {
                                  | FLAG_HAS_AMT
                                  | FLAG_HAS_FLASH
                                  | FLAG_HAS_JUMBO_FRAMES
+                                 | FLAG_DISABLE_FC_PAUSE_TIME /* errata */
                                  | FLAG_APME_IN_WUC,
        .pba                    = 26,
        .max_hw_frame_size      = 4096,
index 0687c6aa4e46e406c0dd67d33169b6574be75f7f..fad8f9ea00435589a383afb004b55e7a8a05727f 100644 (file)
@@ -2769,25 +2769,38 @@ void e1000e_reset(struct e1000_adapter *adapter)
        /*
         * flow control settings
         *
-        * The high water mark must be low enough to fit two full frame
+        * The high water mark must be low enough to fit one full frame
         * (or the size used for early receive) above it in the Rx FIFO.
         * Set it to the lower of:
         * - 90% of the Rx FIFO size, and
         * - the full Rx FIFO size minus the early receive size (for parts
         *   with ERT support assuming ERT set to E1000_ERT_2048), or
-        * - the full Rx FIFO size minus two full frames
+        * - the full Rx FIFO size minus one full frame
         */
-       if ((adapter->flags & FLAG_HAS_ERT) &&
-           (adapter->netdev->mtu > ETH_DATA_LEN))
-               hwm = min(((pba << 10) * 9 / 10),
-                         ((pba << 10) - (E1000_ERT_2048 << 3)));
-       else
-               hwm = min(((pba << 10) * 9 / 10),
-                         ((pba << 10) - (2 * adapter->max_frame_size)));
+       if (hw->mac.type == e1000_pchlan) {
+               /*
+                * Workaround PCH LOM adapter hangs with certain network
+                * loads.  If hangs persist, try disabling Tx flow control.
+                */
+               if (adapter->netdev->mtu > ETH_DATA_LEN) {
+                       fc->high_water = 0x3500;
+                       fc->low_water  = 0x1500;
+               } else {
+                       fc->high_water = 0x5000;
+                       fc->low_water  = 0x3000;
+               }
+       } else {
+               if ((adapter->flags & FLAG_HAS_ERT) &&
+                   (adapter->netdev->mtu > ETH_DATA_LEN))
+                       hwm = min(((pba << 10) * 9 / 10),
+                                 ((pba << 10) - (E1000_ERT_2048 << 3)));
+               else
+                       hwm = min(((pba << 10) * 9 / 10),
+                                 ((pba << 10) - adapter->max_frame_size));
 
-       fc->high_water = hwm & E1000_FCRTH_RTH; /* 8-byte granularity */
-       fc->low_water = (fc->high_water - (2 * adapter->max_frame_size));
-       fc->low_water &= E1000_FCRTL_RTL; /* 8-byte granularity */
+               fc->high_water = hwm & E1000_FCRTH_RTH; /* 8-byte granularity */
+               fc->low_water = fc->high_water - 8;
+       }
 
        if (adapter->flags & FLAG_DISABLE_FC_PAUSE_TIME)
                fc->pause_time = 0xFFFF;
@@ -2813,6 +2826,10 @@ void e1000e_reset(struct e1000_adapter *adapter)
        if (mac->ops.init_hw(hw))
                e_err("Hardware Error\n");
 
+       /* additional part of the flow-control workaround above */
+       if (hw->mac.type == e1000_pchlan)
+               ew32(FCRTV_PCH, 0x1000);
+
        e1000_update_mng_vlan(adapter);
 
        /* Enable h/w to recognize an 802.1Q VLAN Ethernet packet */
@@ -3610,7 +3627,7 @@ static void e1000_watchdog_task(struct work_struct *work)
                        case SPEED_100:
                                txb2b = 0;
                                netdev->tx_queue_len = 100;
-                               /* maybe add some timeout factor ? */
+                               adapter->tx_timeout_factor = 10;
                                break;
                        }
 
@@ -4288,8 +4305,10 @@ static int e1000_change_mtu(struct net_device *netdev, int new_mtu)
 
        while (test_and_set_bit(__E1000_RESETTING, &adapter->state))
                msleep(1);
-       /* e1000e_down has a dependency on max_frame_size */
+       /* e1000e_down -> e1000e_reset dependent on max_frame_size & mtu */
        adapter->max_frame_size = max_frame;
+       e_info("changing MTU from %d to %d\n", netdev->mtu, new_mtu);
+       netdev->mtu = new_mtu;
        if (netif_running(netdev))
                e1000e_down(adapter);
 
@@ -4319,9 +4338,6 @@ static int e1000_change_mtu(struct net_device *netdev, int new_mtu)
                adapter->rx_buffer_len = ETH_FRAME_LEN + VLAN_HLEN
                                         + ETH_FCS_LEN;
 
-       e_info("changing MTU from %d to %d\n", netdev->mtu, new_mtu);
-       netdev->mtu = new_mtu;
-
        if (netif_running(netdev))
                e1000e_up(adapter);
        else
index 03175b3a2c9e25c28923439db0699ea312bca376..85f955f7041716855e313cf0d23e817a078d31bd 100644 (file)
@@ -71,7 +71,6 @@ static const u16 e1000_igp_2_cable_length_table[] =
 #define I82577_CFG_ASSERT_CRS_ON_TX       (1 << 15)
 #define I82577_CFG_ENABLE_DOWNSHIFT       (3 << 10) /* auto downshift 100/10 */
 #define I82577_CTRL_REG                   23
-#define I82577_CTRL_DOWNSHIFT_MASK        (7 << 10)
 
 /* 82577 specific PHY registers */
 #define I82577_PHY_CTRL_2            18
@@ -660,15 +659,6 @@ s32 e1000_copper_link_setup_82577(struct e1000_hw *hw)
        phy_data |= I82577_CFG_ENABLE_DOWNSHIFT;
 
        ret_val = phy->ops.write_phy_reg(hw, I82577_CFG_REG, phy_data);
-       if (ret_val)
-               goto out;
-
-       /* Set number of link attempts before downshift */
-       ret_val = phy->ops.read_phy_reg(hw, I82577_CTRL_REG, &phy_data);
-       if (ret_val)
-               goto out;
-       phy_data &= ~I82577_CTRL_DOWNSHIFT_MASK;
-       ret_val = phy->ops.write_phy_reg(hw, I82577_CTRL_REG, phy_data);
 
 out:
        return ret_val;
@@ -2658,19 +2648,18 @@ static s32 __e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data,
                page = 0;
 
        if (reg > MAX_PHY_MULTI_PAGE_REG) {
-               if ((hw->phy.type != e1000_phy_82578) ||
-                   ((reg != I82578_ADDR_REG) &&
-                    (reg != I82578_ADDR_REG + 1))) {
-                       u32 phy_addr = hw->phy.addr;
+               u32 phy_addr = hw->phy.addr;
 
-                       hw->phy.addr = 1;
+               hw->phy.addr = 1;
 
-                       /* Page is shifted left, PHY expects (page x 32) */
-                       ret_val = e1000e_write_phy_reg_mdic(hw,
-                                                    IGP01E1000_PHY_PAGE_SELECT,
-                                                    (page << IGP_PAGE_SHIFT));
-                       hw->phy.addr = phy_addr;
-               }
+               /* Page is shifted left, PHY expects (page x 32) */
+               ret_val = e1000e_write_phy_reg_mdic(hw,
+                                            IGP01E1000_PHY_PAGE_SELECT,
+                                            (page << IGP_PAGE_SHIFT));
+               hw->phy.addr = phy_addr;
+
+               if (ret_val)
+                       goto out;
        }
 
        ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & reg,
@@ -2678,7 +2667,7 @@ static s32 __e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data,
 out:
        /* Revert to MDIO fast mode, if applicable */
        if ((hw->phy.type == e1000_phy_82577) && in_slow_mode)
-               ret_val = e1000_set_mdio_slow_mode_hv(hw, false);
+               ret_val |= e1000_set_mdio_slow_mode_hv(hw, false);
 
        if (!locked)
                hw->phy.ops.release_phy(hw);
@@ -2784,19 +2773,18 @@ static s32 __e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data,
        }
 
        if (reg > MAX_PHY_MULTI_PAGE_REG) {
-               if ((hw->phy.type != e1000_phy_82578) ||
-                   ((reg != I82578_ADDR_REG) &&
-                    (reg != I82578_ADDR_REG + 1))) {
-                       u32 phy_addr = hw->phy.addr;
+               u32 phy_addr = hw->phy.addr;
 
-                       hw->phy.addr = 1;
+               hw->phy.addr = 1;
 
-                       /* Page is shifted left, PHY expects (page x 32) */
-                       ret_val = e1000e_write_phy_reg_mdic(hw,
-                                                    IGP01E1000_PHY_PAGE_SELECT,
-                                                    (page << IGP_PAGE_SHIFT));
-                       hw->phy.addr = phy_addr;
-               }
+               /* Page is shifted left, PHY expects (page x 32) */
+               ret_val = e1000e_write_phy_reg_mdic(hw,
+                                            IGP01E1000_PHY_PAGE_SELECT,
+                                            (page << IGP_PAGE_SHIFT));
+               hw->phy.addr = phy_addr;
+
+               if (ret_val)
+                       goto out;
        }
 
        ret_val = e1000e_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & reg,
@@ -2805,7 +2793,7 @@ static s32 __e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data,
 out:
        /* Revert to MDIO fast mode, if applicable */
        if ((hw->phy.type == e1000_phy_82577) && in_slow_mode)
-               ret_val = e1000_set_mdio_slow_mode_hv(hw, false);
+               ret_val |= e1000_set_mdio_slow_mode_hv(hw, false);
 
        if (!locked)
                hw->phy.ops.release_phy(hw);
index e1da4666f20426ecf4e5e9848fae64975d2bf463..3116601dbfea859984fa480edd0ecd4db5893e4e 100644 (file)
@@ -5821,10 +5821,7 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
                        dev->dev_addr);
                dev_printk(KERN_ERR, &pci_dev->dev,
                        "Please complain to your hardware vendor. Switching to a random MAC.\n");
-               dev->dev_addr[0] = 0x00;
-               dev->dev_addr[1] = 0x00;
-               dev->dev_addr[2] = 0x6c;
-               get_random_bytes(&dev->dev_addr[3], 3);
+               random_ether_addr(dev->dev_addr);
        }
 
        dprintk(KERN_DEBUG "%s: MAC Address %pM\n",
index d34adf99fc6a45c87d5294f05b675251131b52dd..8a61b597a169e78a3a6035e274cc919bfa13b301 100644 (file)
@@ -263,8 +263,8 @@ struct emac_regs {
 
 
 /* EMACx_TRTR */
-#define EMAC_TRTR_SHIFT_EMAC4          27
-#define EMAC_TRTR_SHIFT                        24
+#define EMAC_TRTR_SHIFT_EMAC4          24
+#define EMAC_TRTR_SHIFT                27
 
 /* EMAC specific TX descriptor control fields (write access) */
 #define EMAC_TX_CTRL_GFCS              0x0200
index 5bd9e6bf6f2f0a8cbcc87c94c7613c94bb93a002..a456578b85786da64b32c75d98fafbe169b12893 100644 (file)
@@ -240,11 +240,11 @@ static void ixgbe_unmap_and_free_tx_resource(struct ixgbe_adapter *adapter,
 static inline bool ixgbe_tx_is_paused(struct ixgbe_adapter *adapter,
                                       struct ixgbe_ring *tx_ring)
 {
-       int tc;
        u32 txoff = IXGBE_TFCS_TXOFF;
 
 #ifdef CONFIG_IXGBE_DCB
        if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) {
+               int tc;
                int reg_idx = tx_ring->reg_idx;
                int dcb_i = adapter->ring_feature[RING_F_DCB].indices;
 
@@ -5994,6 +5994,7 @@ static pci_ers_result_t ixgbe_io_slot_reset(struct pci_dev *pdev)
        } else {
                pci_set_master(pdev);
                pci_restore_state(pdev);
+               pci_save_state(pdev);
 
                pci_wake_from_d3(pdev, false);
 
index 0be14d702bebcbb53aae6d5001ecd3ffa2a310e7..c146304d8d6ca6398b22a3bef00e10416719fe79 100644 (file)
@@ -568,6 +568,16 @@ static inline void ks_outblk(struct ks_net *ks, u16 *wptr, u32 len)
                iowrite16(*wptr++, ks->hw_addr);
 }
 
+static void ks_disable_int(struct ks_net *ks)
+{
+       ks_wrreg16(ks, KS_IER, 0x0000);
+}  /* ks_disable_int */
+
+static void ks_enable_int(struct ks_net *ks)
+{
+       ks_wrreg16(ks, KS_IER, ks->rc_ier);
+}  /* ks_enable_int */
+
 /**
  * ks_tx_fifo_space - return the available hardware buffer size.
  * @ks: The chip information
@@ -681,6 +691,47 @@ static void ks_soft_reset(struct ks_net *ks, unsigned op)
 }
 
 
+void ks_enable_qmu(struct ks_net *ks)
+{
+       u16 w;
+
+       w = ks_rdreg16(ks, KS_TXCR);
+       /* Enables QMU Transmit (TXCR). */
+       ks_wrreg16(ks, KS_TXCR, w | TXCR_TXE);
+
+       /*
+        * RX Frame Count Threshold Enable and Auto-Dequeue RXQ Frame
+        * Enable
+        */
+
+       w = ks_rdreg16(ks, KS_RXQCR);
+       ks_wrreg16(ks, KS_RXQCR, w | RXQCR_RXFCTE);
+
+       /* Enables QMU Receive (RXCR1). */
+       w = ks_rdreg16(ks, KS_RXCR1);
+       ks_wrreg16(ks, KS_RXCR1, w | RXCR1_RXE);
+       ks->enabled = true;
+}  /* ks_enable_qmu */
+
+static void ks_disable_qmu(struct ks_net *ks)
+{
+       u16     w;
+
+       w = ks_rdreg16(ks, KS_TXCR);
+
+       /* Disables QMU Transmit (TXCR). */
+       w  &= ~TXCR_TXE;
+       ks_wrreg16(ks, KS_TXCR, w);
+
+       /* Disables QMU Receive (RXCR1). */
+       w = ks_rdreg16(ks, KS_RXCR1);
+       w &= ~RXCR1_RXE ;
+       ks_wrreg16(ks, KS_RXCR1, w);
+
+       ks->enabled = false;
+
+}  /* ks_disable_qmu */
+
 /**
  * ks_read_qmu - read 1 pkt data from the QMU.
  * @ks: The chip information
@@ -752,7 +803,7 @@ static void ks_rcv(struct ks_net *ks, struct net_device *netdev)
                        (frame_hdr->len < RX_BUF_SIZE) && frame_hdr->len)) {
                        skb_reserve(skb, 2);
                        /* read data block including CRC 4 bytes */
-                       ks_read_qmu(ks, (u16 *)skb->data, frame_hdr->len + 4);
+                       ks_read_qmu(ks, (u16 *)skb->data, frame_hdr->len);
                        skb_put(skb, frame_hdr->len);
                        skb->dev = netdev;
                        skb->protocol = eth_type_trans(skb, netdev);
@@ -861,7 +912,7 @@ static int ks_net_open(struct net_device *netdev)
                ks_dbg(ks, "%s - entry\n", __func__);
 
        /* reset the HW */
-       err = request_irq(ks->irq, ks_irq, KS_INT_FLAGS, DRV_NAME, ks);
+       err = request_irq(ks->irq, ks_irq, KS_INT_FLAGS, DRV_NAME, netdev);
 
        if (err) {
                printk(KERN_ERR "Failed to request IRQ: %d: %d\n",
@@ -869,6 +920,15 @@ static int ks_net_open(struct net_device *netdev)
                return err;
        }
 
+       /* wake up powermode to normal mode */
+       ks_set_powermode(ks, PMECR_PM_NORMAL);
+       mdelay(1);      /* wait for normal mode to take effect */
+
+       ks_wrreg16(ks, KS_ISR, 0xffff);
+       ks_enable_int(ks);
+       ks_enable_qmu(ks);
+       netif_start_queue(ks->netdev);
+
        if (netif_msg_ifup(ks))
                ks_dbg(ks, "network device %s up\n", netdev->name);
 
@@ -892,19 +952,14 @@ static int ks_net_stop(struct net_device *netdev)
 
        netif_stop_queue(netdev);
 
-       kfree(ks->frame_head_info);
-
        mutex_lock(&ks->lock);
 
        /* turn off the IRQs and ack any outstanding */
        ks_wrreg16(ks, KS_IER, 0x0000);
        ks_wrreg16(ks, KS_ISR, 0xffff);
 
-       /* shutdown RX process */
-       ks_wrreg16(ks, KS_RXCR1, 0x0000);
-
-       /* shutdown TX process */
-       ks_wrreg16(ks, KS_TXCR, 0x0000);
+       /* shutdown RX/TX QMU */
+       ks_disable_qmu(ks);
 
        /* set powermode to soft power down to save power */
        ks_set_powermode(ks, PMECR_PM_SOFTDOWN);
@@ -929,17 +984,8 @@ static int ks_net_stop(struct net_device *netdev)
  */
 static void ks_write_qmu(struct ks_net *ks, u8 *pdata, u16 len)
 {
-       unsigned fid = ks->fid;
-
-       fid = ks->fid;
-       ks->fid = (ks->fid + 1) & TXFR_TXFID_MASK;
-
-       /* reduce the tx interrupt occurrances. */
-       if (!fid)
-               fid |= TXFR_TXIC;       /* irq on completion */
-
        /* start header at txb[0] to align txw entries */
-       ks->txh.txw[0] = cpu_to_le16(fid);
+       ks->txh.txw[0] = 0;
        ks->txh.txw[1] = cpu_to_le16(len);
 
        /* 1. set sudo-DMA mode */
@@ -957,16 +1003,6 @@ static void ks_write_qmu(struct ks_net *ks, u8 *pdata, u16 len)
                ;
 }
 
-static void ks_disable_int(struct ks_net *ks)
-{
-       ks_wrreg16(ks, KS_IER, 0x0000);
-}  /* ks_disable_int */
-
-static void ks_enable_int(struct ks_net *ks)
-{
-       ks_wrreg16(ks, KS_IER, ks->rc_ier);
-}  /* ks_enable_int */
-
 /**
  * ks_start_xmit - transmit packet
  * @skb                : The buffer to transmit
@@ -1410,25 +1446,6 @@ static int ks_read_selftest(struct ks_net *ks)
        return ret;
 }
 
-static void ks_disable(struct ks_net *ks)
-{
-       u16     w;
-
-       w = ks_rdreg16(ks, KS_TXCR);
-
-       /* Disables QMU Transmit (TXCR). */
-       w  &= ~TXCR_TXE;
-       ks_wrreg16(ks, KS_TXCR, w);
-
-       /* Disables QMU Receive (RXCR1). */
-       w = ks_rdreg16(ks, KS_RXCR1);
-       w &= ~RXCR1_RXE ;
-       ks_wrreg16(ks, KS_RXCR1, w);
-
-       ks->enabled = false;
-
-}  /* ks_disable */
-
 static void ks_setup(struct ks_net *ks)
 {
        u16     w;
@@ -1463,7 +1480,7 @@ static void ks_setup(struct ks_net *ks)
        w = TXCR_TXFCE | TXCR_TXPE | TXCR_TXCRC | TXCR_TCGIP;
        ks_wrreg16(ks, KS_TXCR, w);
 
-       w = RXCR1_RXFCE | RXCR1_RXBE | RXCR1_RXUE;
+       w = RXCR1_RXFCE | RXCR1_RXBE | RXCR1_RXUE | RXCR1_RXME | RXCR1_RXIPFCC;
 
        if (ks->promiscuous)         /* bPromiscuous */
                w |= (RXCR1_RXAE | RXCR1_RXINVF);
@@ -1486,28 +1503,6 @@ static void ks_setup_int(struct ks_net *ks)
        ks->rc_ier = (IRQ_LCI | IRQ_TXI | IRQ_RXI);
 }  /* ks_setup_int */
 
-void ks_enable(struct ks_net *ks)
-{
-       u16 w;
-
-       w = ks_rdreg16(ks, KS_TXCR);
-       /* Enables QMU Transmit (TXCR). */
-       ks_wrreg16(ks, KS_TXCR, w | TXCR_TXE);
-
-       /*
-        * RX Frame Count Threshold Enable and Auto-Dequeue RXQ Frame
-        * Enable
-        */
-
-       w = ks_rdreg16(ks, KS_RXQCR);
-       ks_wrreg16(ks, KS_RXQCR, w | RXQCR_RXFCTE);
-
-       /* Enables QMU Receive (RXCR1). */
-       w = ks_rdreg16(ks, KS_RXCR1);
-       ks_wrreg16(ks, KS_RXCR1, w | RXCR1_RXE);
-       ks->enabled = true;
-}  /* ks_enable */
-
 static int ks_hw_init(struct ks_net *ks)
 {
 #define        MHEADER_SIZE    (sizeof(struct type_frame_head) * MAX_RECV_FRAMES)
@@ -1612,11 +1607,9 @@ static int __devinit ks8851_probe(struct platform_device *pdev)
 
        ks_soft_reset(ks, GRR_GSR);
        ks_hw_init(ks);
-       ks_disable(ks);
+       ks_disable_qmu(ks);
        ks_setup(ks);
        ks_setup_int(ks);
-       ks_enable_int(ks);
-       ks_enable(ks);
        memcpy(netdev->dev_addr, ks->mac_addr, 6);
 
        data = ks_rdreg16(ks, KS_OBCR);
@@ -1658,6 +1651,7 @@ static int __devexit ks8851_remove(struct platform_device *pdev)
        struct ks_net *ks = netdev_priv(netdev);
        struct resource *iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 
+       kfree(ks->frame_head_info);
        unregister_netdev(netdev);
        iounmap(ks->hw_addr);
        free_netdev(netdev);
index 3aabfd9dd2121d7eaab6a7f30e2113e4bc0d22c4..2490aa39804ce3e6e6d74727cc0fa082034526a3 100644 (file)
@@ -360,6 +360,7 @@ static int macvlan_init(struct net_device *dev)
        dev->state              = (dev->state & ~MACVLAN_STATE_MASK) |
                                  (lowerdev->state & MACVLAN_STATE_MASK);
        dev->features           = lowerdev->features & MACVLAN_FEATURES;
+       dev->gso_max_size       = lowerdev->gso_max_size;
        dev->iflink             = lowerdev->ifindex;
        dev->hard_header_len    = lowerdev->hard_header_len;
 
@@ -596,6 +597,7 @@ static int macvlan_device_event(struct notifier_block *unused,
        case NETDEV_FEAT_CHANGE:
                list_for_each_entry(vlan, &port->vlans, list) {
                        vlan->dev->features = dev->features & MACVLAN_FEATURES;
+                       vlan->dev->gso_max_size = dev->gso_max_size;
                        netdev_features_change(vlan->dev);
                }
                break;
index 7384f59df61572a6cb3d170998b116ca1aae5aa7..e1237b8028724bce9a936cdeb1d3a7704175969e 100644 (file)
@@ -1163,6 +1163,8 @@ struct netxen_adapter {
        u32 int_vec_bit;
        u32 heartbit;
 
+       u8 mac_addr[ETH_ALEN];
+
        struct netxen_adapter_stats stats;
 
        struct netxen_recv_context recv_ctx;
index 1c46da63212586647c7d3696a117f9de1821541f..17bb3818d84e63a3faedb7aecec0073502911b6f 100644 (file)
@@ -545,6 +545,8 @@ enum {
 #define        NETXEN_NIU_TEST_MUX_CTL         (NETXEN_CRB_NIU + 0x00094)
 #define        NETXEN_NIU_XG_PAUSE_CTL         (NETXEN_CRB_NIU + 0x00098)
 #define        NETXEN_NIU_XG_PAUSE_LEVEL       (NETXEN_CRB_NIU + 0x000dc)
+#define        NETXEN_NIU_FRAME_COUNT_SELECT   (NETXEN_CRB_NIU + 0x000ac)
+#define        NETXEN_NIU_FRAME_COUNT          (NETXEN_CRB_NIU + 0x000b0)
 #define        NETXEN_NIU_XG_SEL               (NETXEN_CRB_NIU + 0x00128)
 #define NETXEN_NIU_GB_PAUSE_CTL                (NETXEN_CRB_NIU + 0x0030c)
 
index 3185a98b0917ead8c51d4b3fea2f13da3abe6f66..52a3798d8d947a9992762dab2987df158b6252bd 100644 (file)
@@ -383,24 +383,51 @@ int netxen_niu_disable_xg_port(struct netxen_adapter *adapter)
 
 int netxen_p2_nic_set_promisc(struct netxen_adapter *adapter, u32 mode)
 {
-       __u32 reg;
+       u32 mac_cfg;
+       u32 cnt = 0;
+       __u32 reg = 0x0200;
        u32 port = adapter->physical_port;
+       u16 board_type = adapter->ahw.board_type;
 
        if (port > NETXEN_NIU_MAX_XG_PORTS)
                return -EINVAL;
 
-       reg = NXRD32(adapter, NETXEN_NIU_XGE_CONFIG_1 + (0x10000 * port));
-       if (mode == NETXEN_NIU_PROMISC_MODE)
-               reg = (reg | 0x2000UL);
-       else
-               reg = (reg & ~0x2000UL);
+       mac_cfg = NXRD32(adapter, NETXEN_NIU_XGE_CONFIG_0 + (0x10000 * port));
+       mac_cfg &= ~0x4;
+       NXWR32(adapter, NETXEN_NIU_XGE_CONFIG_0 + (0x10000 * port), mac_cfg);
 
-       if (mode == NETXEN_NIU_ALLMULTI_MODE)
-               reg = (reg | 0x1000UL);
-       else
-               reg = (reg & ~0x1000UL);
+       if ((board_type == NETXEN_BRDTYPE_P2_SB31_10G_IMEZ) ||
+                       (board_type == NETXEN_BRDTYPE_P2_SB31_10G_HMEZ))
+               reg = (0x20 << port);
+
+       NXWR32(adapter, NETXEN_NIU_FRAME_COUNT_SELECT, reg);
+
+       mdelay(10);
+
+       while (NXRD32(adapter, NETXEN_NIU_FRAME_COUNT) && ++cnt < 20)
+               mdelay(10);
+
+       if (cnt < 20) {
+
+               reg = NXRD32(adapter,
+                       NETXEN_NIU_XGE_CONFIG_1 + (0x10000 * port));
+
+               if (mode == NETXEN_NIU_PROMISC_MODE)
+                       reg = (reg | 0x2000UL);
+               else
+                       reg = (reg & ~0x2000UL);
+
+               if (mode == NETXEN_NIU_ALLMULTI_MODE)
+                       reg = (reg | 0x1000UL);
+               else
+                       reg = (reg & ~0x1000UL);
+
+               NXWR32(adapter,
+                       NETXEN_NIU_XGE_CONFIG_1 + (0x10000 * port), reg);
+       }
 
-       NXWR32(adapter, NETXEN_NIU_XGE_CONFIG_1 + (0x10000 * port), reg);
+       mac_cfg |= 0x4;
+       NXWR32(adapter, NETXEN_NIU_XGE_CONFIG_0 + (0x10000 * port), mac_cfg);
 
        return 0;
 }
@@ -436,7 +463,7 @@ netxen_nic_enable_mcast_filter(struct netxen_adapter *adapter)
 {
        u32     val = 0;
        u16 port = adapter->physical_port;
-       u8 *addr = adapter->netdev->dev_addr;
+       u8 *addr = adapter->mac_addr;
 
        if (adapter->mc_enabled)
                return 0;
@@ -465,7 +492,7 @@ netxen_nic_disable_mcast_filter(struct netxen_adapter *adapter)
 {
        u32     val = 0;
        u16 port = adapter->physical_port;
-       u8 *addr = adapter->netdev->dev_addr;
+       u8 *addr = adapter->mac_addr;
 
        if (!adapter->mc_enabled)
                return 0;
@@ -660,7 +687,7 @@ void netxen_p3_nic_set_multi(struct net_device *netdev)
 
        list_splice_tail_init(&adapter->mac_list, &del_list);
 
-       nx_p3_nic_add_mac(adapter, netdev->dev_addr, &del_list);
+       nx_p3_nic_add_mac(adapter, adapter->mac_addr, &del_list);
        nx_p3_nic_add_mac(adapter, bcast_addr, &del_list);
 
        if (netdev->flags & IFF_PROMISC) {
index e40b914d6faf7def7bedbb9f309195afc2a61e59..8a0904368e0838027e7a23621918203ebdd02d5e 100644 (file)
@@ -544,6 +544,8 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose)
                                continue;
                        if (off == (ROMUSB_GLB + 0x1c)) /* MS clock */
                                continue;
+                       if ((off & 0x0ff00000) == NETXEN_CRB_DDR_NET)
+                               continue;
                        if (off == (NETXEN_CRB_PEG_NET_1 + 0x18))
                                buf[i].data = 0x1020;
                        /* skip the function enable register */
index 0b4a56a8c8d5fc2d9d9d1f8619e88e2031577a55..3bf78dbfbf0f5d63e3ed92251b32f16cae911da5 100644 (file)
@@ -437,6 +437,7 @@ netxen_read_mac_addr(struct netxen_adapter *adapter)
                netdev->dev_addr[i] = *(p + 5 - i);
 
        memcpy(netdev->perm_addr, netdev->dev_addr, netdev->addr_len);
+       memcpy(adapter->mac_addr, netdev->dev_addr, netdev->addr_len);
 
        /* set station address */
 
@@ -459,6 +460,7 @@ int netxen_nic_set_mac(struct net_device *netdev, void *p)
                netxen_napi_disable(adapter);
        }
 
+       memcpy(adapter->mac_addr, addr->sa_data, netdev->addr_len);
        memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
        adapter->macaddr_set(adapter, addr->sa_data);
 
@@ -956,7 +958,7 @@ netxen_nic_up(struct netxen_adapter *adapter, struct net_device *netdev)
                return err;
        }
        if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
-               adapter->macaddr_set(adapter, netdev->dev_addr);
+               adapter->macaddr_set(adapter, adapter->mac_addr);
 
        adapter->set_multi(netdev);
        adapter->set_mtu(adapter, netdev->mtu);
index b58965a2b3ae256eba2642a7b98d1dbff4bfa9b9..17a27225cc98cbc076f705ec6c850812ed6f56c8 100644 (file)
@@ -118,14 +118,6 @@ INT_MODULE_PARM(full_duplex, 0);
 /* Autodetect link polarity reversal? */
 INT_MODULE_PARM(auto_polarity, 1);
 
-#ifdef PCMCIA_DEBUG
-INT_MODULE_PARM(pc_debug, PCMCIA_DEBUG);
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
-static char *version =
-"3c574_cs.c 1.65ac1 2003/04/07 Donald Becker/David Hinds, becker@scyld.com.\n";
-#else
-#define DEBUG(n, args...)
-#endif
 
 /*====================================================================*/
 
@@ -278,7 +270,7 @@ static int tc574_probe(struct pcmcia_device *link)
        struct el3_private *lp;
        struct net_device *dev;
 
-       DEBUG(0, "3c574_attach()\n");
+       dev_dbg(&link->dev, "3c574_attach()\n");
 
        /* Create the PC card device object. */
        dev = alloc_etherdev(sizeof(struct el3_private));
@@ -291,10 +283,8 @@ static int tc574_probe(struct pcmcia_device *link)
        spin_lock_init(&lp->window_lock);
        link->io.NumPorts1 = 32;
        link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
-       link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_HANDLE_PRESENT;
-       link->irq.IRQInfo1 = IRQ_LEVEL_ID;
+       link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
        link->irq.Handler = &el3_interrupt;
-       link->irq.Instance = dev;
        link->conf.Attributes = CONF_ENABLE_IRQ;
        link->conf.IntType = INT_MEMORY_AND_IO;
        link->conf.ConfigIndex = 1;
@@ -319,7 +309,7 @@ static void tc574_detach(struct pcmcia_device *link)
 {
        struct net_device *dev = link->priv;
 
-       DEBUG(0, "3c574_detach(0x%p)\n", link);
+       dev_dbg(&link->dev, "3c574_detach()\n");
 
        if (link->dev_node)
                unregister_netdev(dev);
@@ -335,26 +325,23 @@ static void tc574_detach(struct pcmcia_device *link)
        ethernet device available to the system.
 */
 
-#define CS_CHECK(fn, ret) \
-  do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
-
 static const char *ram_split[] = {"5:3", "3:1", "1:1", "3:5"};
 
 static int tc574_config(struct pcmcia_device *link)
 {
        struct net_device *dev = link->priv;
        struct el3_private *lp = netdev_priv(dev);
-       tuple_t tuple;
-       __le16 buf[32];
-       int last_fn, last_ret, i, j;
+       int ret, i, j;
        unsigned int ioaddr;
        __be16 *phys_addr;
        char *cardname;
        __u32 config;
+       u8 *buf;
+       size_t len;
 
        phys_addr = (__be16 *)dev->dev_addr;
 
-       DEBUG(0, "3c574_config(0x%p)\n", link);
+       dev_dbg(&link->dev, "3c574_config()\n");
 
        link->io.IOAddrLines = 16;
        for (i = j = 0; j < 0x400; j += 0x20) {
@@ -363,12 +350,16 @@ static int tc574_config(struct pcmcia_device *link)
                if (i == 0)
                        break;
        }
-       if (i != 0) {
-               cs_error(link, RequestIO, i);
+       if (i != 0)
+               goto failed;
+
+       ret = pcmcia_request_irq(link, &link->irq);
+       if (ret)
+               goto failed;
+
+       ret = pcmcia_request_configuration(link, &link->conf);
+       if (ret)
                goto failed;
-       }
-       CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
-       CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
 
        dev->irq = link->irq.AssignedIRQ;
        dev->base_addr = link->io.BasePort1;
@@ -378,16 +369,14 @@ static int tc574_config(struct pcmcia_device *link)
        /* The 3c574 normally uses an EEPROM for configuration info, including
           the hardware address.  The future products may include a modem chip
           and put the address in the CIS. */
-       tuple.Attributes = 0;
-       tuple.TupleData = (cisdata_t *)buf;
-       tuple.TupleDataMax = 64;
-       tuple.TupleOffset = 0;
-       tuple.DesiredTuple = 0x88;
-       if (pcmcia_get_first_tuple(link, &tuple) == 0) {
-               pcmcia_get_tuple_data(link, &tuple);
+
+       len = pcmcia_get_tuple(link, 0x88, &buf);
+       if (buf && len >= 6) {
                for (i = 0; i < 3; i++)
-                       phys_addr[i] = htons(le16_to_cpu(buf[i]));
+                       phys_addr[i] = htons(le16_to_cpu(buf[i * 2]));
+               kfree(buf);
        } else {
+               kfree(buf); /* 0 < len < 6 */
                EL3WINDOW(0);
                for (i = 0; i < 3; i++)
                        phys_addr[i] = htons(read_eeprom(ioaddr, i + 10));
@@ -435,7 +424,8 @@ static int tc574_config(struct pcmcia_device *link)
                        mii_status = mdio_read(ioaddr, phy & 0x1f, 1);
                        if (mii_status != 0xffff) {
                                lp->phys = phy & 0x1f;
-                               DEBUG(0, "  MII transceiver at index %d, status %x.\n",
+                               dev_dbg(&link->dev, "  MII transceiver at "
+                                       "index %d, status %x.\n",
                                          phy, mii_status);
                                if ((mii_status & 0x0040) == 0)
                                        mii_preamble_required = 1;
@@ -457,7 +447,7 @@ static int tc574_config(struct pcmcia_device *link)
        }
 
        link->dev_node = &lp->node;
-       SET_NETDEV_DEV(dev, &handle_to_dev(link));
+       SET_NETDEV_DEV(dev, &link->dev);
 
        if (register_netdev(dev) != 0) {
                printk(KERN_NOTICE "3c574_cs: register_netdev() failed\n");
@@ -478,8 +468,6 @@ static int tc574_config(struct pcmcia_device *link)
 
        return 0;
 
-cs_failed:
-       cs_error(link, last_fn, last_ret);
 failed:
        tc574_release(link);
        return -ENODEV;
@@ -738,7 +726,7 @@ static int el3_open(struct net_device *dev)
        lp->media.expires = jiffies + HZ;
        add_timer(&lp->media);
        
-       DEBUG(2, "%s: opened, status %4.4x.\n",
+       dev_dbg(&link->dev, "%s: opened, status %4.4x.\n",
                  dev->name, inw(dev->base_addr + EL3_STATUS));
        
        return 0;
@@ -772,7 +760,7 @@ static void pop_tx_status(struct net_device *dev)
                if (tx_status & 0x30)
                        tc574_wait_for_completion(dev, TxReset);
                if (tx_status & 0x38) {
-                       DEBUG(1, "%s: transmit error: status 0x%02x\n",
+                       pr_debug("%s: transmit error: status 0x%02x\n",
                                  dev->name, tx_status);
                        outw(TxEnable, ioaddr + EL3_CMD);
                        dev->stats.tx_aborted_errors++;
@@ -788,7 +776,7 @@ static netdev_tx_t el3_start_xmit(struct sk_buff *skb,
        struct el3_private *lp = netdev_priv(dev);
        unsigned long flags;
 
-       DEBUG(3, "%s: el3_start_xmit(length = %ld) called, "
+       pr_debug("%s: el3_start_xmit(length = %ld) called, "
                  "status %4.4x.\n", dev->name, (long)skb->len,
                  inw(ioaddr + EL3_STATUS));
 
@@ -827,7 +815,7 @@ static irqreturn_t el3_interrupt(int irq, void *dev_id)
                return IRQ_NONE;
        ioaddr = dev->base_addr;
 
-       DEBUG(3, "%s: interrupt, status %4.4x.\n",
+       pr_debug("%s: interrupt, status %4.4x.\n",
                  dev->name, inw(ioaddr + EL3_STATUS));
 
        spin_lock(&lp->window_lock);
@@ -836,7 +824,7 @@ static irqreturn_t el3_interrupt(int irq, void *dev_id)
                   (IntLatch | RxComplete | RxEarly | StatsFull)) {
                if (!netif_device_present(dev) ||
                        ((status & 0xe000) != 0x2000)) {
-                       DEBUG(1, "%s: Interrupt from dead card\n", dev->name);
+                       pr_debug("%s: Interrupt from dead card\n", dev->name);
                        break;
                }
 
@@ -846,7 +834,7 @@ static irqreturn_t el3_interrupt(int irq, void *dev_id)
                        work_budget = el3_rx(dev, work_budget);
 
                if (status & TxAvailable) {
-                       DEBUG(3, "  TX room bit was handled.\n");
+                       pr_debug("  TX room bit was handled.\n");
                        /* There's room in the FIFO for a full-sized packet. */
                        outw(AckIntr | TxAvailable, ioaddr + EL3_CMD);
                        netif_wake_queue(dev);
@@ -886,7 +874,7 @@ static irqreturn_t el3_interrupt(int irq, void *dev_id)
                }
 
                if (--work_budget < 0) {
-                       DEBUG(0, "%s: Too much work in interrupt, "
+                       pr_debug("%s: Too much work in interrupt, "
                                  "status %4.4x.\n", dev->name, status);
                        /* Clear all interrupts */
                        outw(AckIntr | 0xFF, ioaddr + EL3_CMD);
@@ -896,7 +884,7 @@ static irqreturn_t el3_interrupt(int irq, void *dev_id)
                outw(AckIntr | IntReq | IntLatch, ioaddr + EL3_CMD);
        }
 
-       DEBUG(3, "%s: exiting interrupt, status %4.4x.\n",
+       pr_debug("%s: exiting interrupt, status %4.4x.\n",
                  dev->name, inw(ioaddr + EL3_STATUS));
                  
        spin_unlock(&lp->window_lock);
@@ -1003,7 +991,7 @@ static void update_stats(struct net_device *dev)
        unsigned int ioaddr = dev->base_addr;
        u8 rx, tx, up;
 
-       DEBUG(2, "%s: updating the statistics.\n", dev->name);
+       pr_debug("%s: updating the statistics.\n", dev->name);
 
        if (inw(ioaddr+EL3_STATUS) == 0xffff) /* No card. */
                return;
@@ -1039,7 +1027,7 @@ static int el3_rx(struct net_device *dev, int worklimit)
        unsigned int ioaddr = dev->base_addr;
        short rx_status;
        
-       DEBUG(3, "%s: in rx_packet(), status %4.4x, rx_status %4.4x.\n",
+       pr_debug("%s: in rx_packet(), status %4.4x, rx_status %4.4x.\n",
                  dev->name, inw(ioaddr+EL3_STATUS), inw(ioaddr+RxStatus));
        while (!((rx_status = inw(ioaddr + RxStatus)) & 0x8000) &&
                        worklimit > 0) {
@@ -1061,7 +1049,7 @@ static int el3_rx(struct net_device *dev, int worklimit)
 
                        skb = dev_alloc_skb(pkt_len+5);
 
-                       DEBUG(3, "  Receiving packet size %d status %4.4x.\n",
+                       pr_debug("  Receiving packet size %d status %4.4x.\n",
                                  pkt_len, rx_status);
                        if (skb != NULL) {
                                skb_reserve(skb, 2);
@@ -1072,7 +1060,7 @@ static int el3_rx(struct net_device *dev, int worklimit)
                                dev->stats.rx_packets++;
                                dev->stats.rx_bytes += pkt_len;
                        } else {
-                               DEBUG(1, "%s: couldn't allocate a sk_buff of"
+                               pr_debug("%s: couldn't allocate a sk_buff of"
                                          " size %d.\n", dev->name, pkt_len);
                                dev->stats.rx_dropped++;
                        }
@@ -1101,7 +1089,7 @@ static int el3_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
        struct mii_ioctl_data *data = if_mii(rq);
        int phy = lp->phys & 0x1f;
 
-       DEBUG(2, "%s: In ioct(%-.6s, %#4.4x) %4.4x %4.4x %4.4x %4.4x.\n",
+       pr_debug("%s: In ioct(%-.6s, %#4.4x) %4.4x %4.4x %4.4x %4.4x.\n",
                  dev->name, rq->ifr_ifrn.ifrn_name, cmd,
                  data->phy_id, data->reg_num, data->val_in, data->val_out);
 
@@ -1178,7 +1166,7 @@ static int el3_close(struct net_device *dev)
        struct el3_private *lp = netdev_priv(dev);
        struct pcmcia_device *link = lp->p_dev;
 
-       DEBUG(2, "%s: shutting down ethercard.\n", dev->name);
+       dev_dbg(&link->dev, "%s: shutting down ethercard.\n", dev->name);
        
        if (pcmcia_dev_present(link)) {
                unsigned long flags;
index 569fb06793cf7da4da614a597113e7eadeeed022..6f8d7e2e592246205df9ae45625ae1816e9f03b3 100644 (file)
@@ -130,14 +130,6 @@ MODULE_LICENSE("GPL");
 /* Special hook for setting if_port when module is loaded */
 INT_MODULE_PARM(if_port, 0);
 
-#ifdef PCMCIA_DEBUG
-INT_MODULE_PARM(pc_debug, PCMCIA_DEBUG);
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
-static char *version =
-DRV_NAME ".c " DRV_VERSION " 2001/10/13 00:08:50 (David Hinds)";
-#else
-#define DEBUG(n, args...)
-#endif
 
 /*====================================================================*/
 
@@ -189,7 +181,7 @@ static int tc589_probe(struct pcmcia_device *link)
     struct el3_private *lp;
     struct net_device *dev;
 
-    DEBUG(0, "3c589_attach()\n");
+    dev_dbg(&link->dev, "3c589_attach()\n");
 
     /* Create new ethernet device */
     dev = alloc_etherdev(sizeof(struct el3_private));
@@ -202,10 +194,8 @@ static int tc589_probe(struct pcmcia_device *link)
     spin_lock_init(&lp->lock);
     link->io.NumPorts1 = 16;
     link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
-    link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_HANDLE_PRESENT;
-    link->irq.IRQInfo1 = IRQ_LEVEL_ID;
+    link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
     link->irq.Handler = &el3_interrupt;
-    link->irq.Instance = dev;
     link->conf.Attributes = CONF_ENABLE_IRQ;
     link->conf.IntType = INT_MEMORY_AND_IO;
     link->conf.ConfigIndex = 1;
@@ -231,7 +221,7 @@ static void tc589_detach(struct pcmcia_device *link)
 {
     struct net_device *dev = link->priv;
 
-    DEBUG(0, "3c589_detach(0x%p)\n", link);
+    dev_dbg(&link->dev, "3c589_detach\n");
 
     if (link->dev_node)
        unregister_netdev(dev);
@@ -249,29 +239,20 @@ static void tc589_detach(struct pcmcia_device *link)
     
 ======================================================================*/
 
-#define CS_CHECK(fn, ret) \
-do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
-
 static int tc589_config(struct pcmcia_device *link)
 {
     struct net_device *dev = link->priv;
     struct el3_private *lp = netdev_priv(dev);
-    tuple_t tuple;
-    __le16 buf[32];
     __be16 *phys_addr;
-    int last_fn, last_ret, i, j, multi = 0, fifo;
+    int ret, i, j, multi = 0, fifo;
     unsigned int ioaddr;
     char *ram_split[] = {"5:3", "3:1", "1:1", "3:5"};
+    u8 *buf;
+    size_t len;
     
-    DEBUG(0, "3c589_config(0x%p)\n", link);
+    dev_dbg(&link->dev, "3c589_config\n");
 
     phys_addr = (__be16 *)dev->dev_addr;
-    tuple.Attributes = 0;
-    tuple.TupleData = (cisdata_t *)buf;
-    tuple.TupleDataMax = sizeof(buf);
-    tuple.TupleOffset = 0;
-    tuple.Attributes = TUPLE_RETURN_COMMON;
-
     /* Is this a 3c562? */
     if (link->manf_id != MANFID_3COM)
            printk(KERN_INFO "3c589_cs: hmmm, is this really a "
@@ -287,12 +268,16 @@ static int tc589_config(struct pcmcia_device *link)
        if (i == 0)
                break;
     }
-    if (i != 0) {
-       cs_error(link, RequestIO, i);
+    if (i != 0)
        goto failed;
-    }
-    CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
-    CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
+
+    ret = pcmcia_request_irq(link, &link->irq);
+    if (ret)
+           goto failed;
+
+    ret = pcmcia_request_configuration(link, &link->conf);
+    if (ret)
+           goto failed;
        
     dev->irq = link->irq.AssignedIRQ;
     dev->base_addr = link->io.BasePort1;
@@ -301,12 +286,13 @@ static int tc589_config(struct pcmcia_device *link)
 
     /* The 3c589 has an extra EEPROM for configuration info, including
        the hardware address.  The 3c562 puts the address in the CIS. */
-    tuple.DesiredTuple = 0x88;
-    if (pcmcia_get_first_tuple(link, &tuple) == 0) {
-       pcmcia_get_tuple_data(link, &tuple);
-       for (i = 0; i < 3; i++)
-           phys_addr[i] = htons(le16_to_cpu(buf[i]));
+    len = pcmcia_get_tuple(link, 0x88, &buf);
+    if (buf && len >= 6) {
+           for (i = 0; i < 3; i++)
+                   phys_addr[i] = htons(le16_to_cpu(buf[i*2]));
+           kfree(buf);
     } else {
+       kfree(buf); /* 0 < len < 6 */
        for (i = 0; i < 3; i++)
            phys_addr[i] = htons(read_eeprom(ioaddr, i));
        if (phys_addr[0] == htons(0x6060)) {
@@ -328,7 +314,7 @@ static int tc589_config(struct pcmcia_device *link)
        printk(KERN_ERR "3c589_cs: invalid if_port requested\n");
     
     link->dev_node = &lp->node;
-    SET_NETDEV_DEV(dev, &handle_to_dev(link));
+    SET_NETDEV_DEV(dev, &link->dev);
 
     if (register_netdev(dev) != 0) {
        printk(KERN_ERR "3c589_cs: register_netdev() failed\n");
@@ -347,8 +333,6 @@ static int tc589_config(struct pcmcia_device *link)
           if_names[dev->if_port]);
     return 0;
 
-cs_failed:
-    cs_error(link, last_fn, last_ret);
 failed:
     tc589_release(link);
     return -ENODEV;
@@ -511,24 +495,8 @@ static void netdev_get_drvinfo(struct net_device *dev,
        sprintf(info->bus_info, "PCMCIA 0x%lx", dev->base_addr);
 }
 
-#ifdef PCMCIA_DEBUG
-static u32 netdev_get_msglevel(struct net_device *dev)
-{
-       return pc_debug;
-}
-
-static void netdev_set_msglevel(struct net_device *dev, u32 level)
-{
-       pc_debug = level;
-}
-#endif /* PCMCIA_DEBUG */
-
 static const struct ethtool_ops netdev_ethtool_ops = {
        .get_drvinfo            = netdev_get_drvinfo,
-#ifdef PCMCIA_DEBUG
-       .get_msglevel           = netdev_get_msglevel,
-       .set_msglevel           = netdev_set_msglevel,
-#endif /* PCMCIA_DEBUG */
 };
 
 static int el3_config(struct net_device *dev, struct ifmap *map)
@@ -563,7 +531,7 @@ static int el3_open(struct net_device *dev)
     lp->media.expires = jiffies + HZ;
     add_timer(&lp->media);
 
-    DEBUG(1, "%s: opened, status %4.4x.\n",
+    dev_dbg(&link->dev, "%s: opened, status %4.4x.\n",
          dev->name, inw(dev->base_addr + EL3_STATUS));
     
     return 0;
@@ -596,7 +564,7 @@ static void pop_tx_status(struct net_device *dev)
        if (tx_status & 0x30)
            tc589_wait_for_completion(dev, TxReset);
        if (tx_status & 0x38) {
-           DEBUG(1, "%s: transmit error: status 0x%02x\n",
+           pr_debug("%s: transmit error: status 0x%02x\n",
                  dev->name, tx_status);
            outw(TxEnable, ioaddr + EL3_CMD);
            dev->stats.tx_aborted_errors++;
@@ -612,7 +580,7 @@ static netdev_tx_t el3_start_xmit(struct sk_buff *skb,
     struct el3_private *priv = netdev_priv(dev);
     unsigned long flags;
 
-    DEBUG(3, "%s: el3_start_xmit(length = %ld) called, "
+    pr_debug("%s: el3_start_xmit(length = %ld) called, "
          "status %4.4x.\n", dev->name, (long)skb->len,
          inw(ioaddr + EL3_STATUS));
 
@@ -654,14 +622,14 @@ static irqreturn_t el3_interrupt(int irq, void *dev_id)
 
     ioaddr = dev->base_addr;
 
-    DEBUG(3, "%s: interrupt, status %4.4x.\n",
+    pr_debug("%s: interrupt, status %4.4x.\n",
          dev->name, inw(ioaddr + EL3_STATUS));
 
     spin_lock(&lp->lock);    
     while ((status = inw(ioaddr + EL3_STATUS)) &
        (IntLatch | RxComplete | StatsFull)) {
        if ((status & 0xe000) != 0x2000) {
-           DEBUG(1, "%s: interrupt from dead card\n", dev->name);
+           pr_debug("%s: interrupt from dead card\n", dev->name);
            handled = 0;
            break;
        }
@@ -670,7 +638,7 @@ static irqreturn_t el3_interrupt(int irq, void *dev_id)
            el3_rx(dev);
        
        if (status & TxAvailable) {
-           DEBUG(3, "    TX room bit was handled.\n");
+           pr_debug("    TX room bit was handled.\n");
            /* There's room in the FIFO for a full-sized packet. */
            outw(AckIntr | TxAvailable, ioaddr + EL3_CMD);
            netif_wake_queue(dev);
@@ -722,7 +690,7 @@ static irqreturn_t el3_interrupt(int irq, void *dev_id)
 
     lp->last_irq = jiffies;
     spin_unlock(&lp->lock);    
-    DEBUG(3, "%s: exiting interrupt, status %4.4x.\n",
+    pr_debug("%s: exiting interrupt, status %4.4x.\n",
          dev->name, inw(ioaddr + EL3_STATUS));
     return IRQ_RETVAL(handled);
 }
@@ -833,7 +801,7 @@ static void update_stats(struct net_device *dev)
 {
     unsigned int ioaddr = dev->base_addr;
 
-    DEBUG(2, "%s: updating the statistics.\n", dev->name);
+    pr_debug("%s: updating the statistics.\n", dev->name);
     /* Turn off statistics updates while reading. */
     outw(StatsDisable, ioaddr + EL3_CMD);
     /* Switch to the stats window, and read everything. */
@@ -861,7 +829,7 @@ static int el3_rx(struct net_device *dev)
     int worklimit = 32;
     short rx_status;
     
-    DEBUG(3, "%s: in rx_packet(), status %4.4x, rx_status %4.4x.\n",
+    pr_debug("%s: in rx_packet(), status %4.4x, rx_status %4.4x.\n",
          dev->name, inw(ioaddr+EL3_STATUS), inw(ioaddr+RX_STATUS));
     while (!((rx_status = inw(ioaddr + RX_STATUS)) & 0x8000) &&
                    worklimit > 0) {
@@ -883,7 +851,7 @@ static int el3_rx(struct net_device *dev)
            
            skb = dev_alloc_skb(pkt_len+5);
            
-           DEBUG(3, "    Receiving packet size %d status %4.4x.\n",
+           pr_debug("    Receiving packet size %d status %4.4x.\n",
                  pkt_len, rx_status);
            if (skb != NULL) {
                skb_reserve(skb, 2);
@@ -894,7 +862,7 @@ static int el3_rx(struct net_device *dev)
                dev->stats.rx_packets++;
                dev->stats.rx_bytes += pkt_len;
            } else {
-               DEBUG(1, "%s: couldn't allocate a sk_buff of"
+               pr_debug("%s: couldn't allocate a sk_buff of"
                      " size %d.\n", dev->name, pkt_len);
                dev->stats.rx_dropped++;
            }
@@ -935,7 +903,7 @@ static int el3_close(struct net_device *dev)
     struct pcmcia_device *link = lp->p_dev;
     unsigned int ioaddr = dev->base_addr;
     
-    DEBUG(1, "%s: shutting down ethercard.\n", dev->name);
+    dev_dbg(&link->dev, "%s: shutting down ethercard.\n", dev->name);
 
     if (pcmcia_dev_present(link)) {
        /* Turn off statistics ASAP.  We update dev->stats below. */
index 3131a59a8d32b4cfbf1f032e237cece52b2f54ea..800597b82d18107e52c8fd5574a63c998e7a3cb4 100644 (file)
@@ -75,16 +75,6 @@ MODULE_AUTHOR("David Hinds <dahinds@users.sourceforge.net>");
 MODULE_DESCRIPTION("Asix AX88190 PCMCIA ethernet driver");
 MODULE_LICENSE("GPL");
 
-#ifdef PCMCIA_DEBUG
-#define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0)
-
-INT_MODULE_PARM(pc_debug, PCMCIA_DEBUG);
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
-static char *version =
-"axnet_cs.c 1.28 2002/06/29 06:27:37 (David Hinds)";
-#else
-#define DEBUG(n, args...)
-#endif
 
 /*====================================================================*/
 
@@ -167,7 +157,7 @@ static int axnet_probe(struct pcmcia_device *link)
     struct net_device *dev;
     struct ei_device *ei_local;
 
-    DEBUG(0, "axnet_attach()\n");
+    dev_dbg(&link->dev, "axnet_attach()\n");
 
     dev = alloc_etherdev(sizeof(struct ei_device) + sizeof(axnet_dev_t));
     if (!dev)
@@ -180,7 +170,6 @@ static int axnet_probe(struct pcmcia_device *link)
     info->p_dev = link;
     link->priv = dev;
     link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
-    link->irq.IRQInfo1 = IRQ_LEVEL_ID;
     link->conf.Attributes = CONF_ENABLE_IRQ;
     link->conf.IntType = INT_MEMORY_AND_IO;
 
@@ -205,7 +194,7 @@ static void axnet_detach(struct pcmcia_device *link)
 {
     struct net_device *dev = link->priv;
 
-    DEBUG(0, "axnet_detach(0x%p)\n", link);
+    dev_dbg(&link->dev, "axnet_detach(0x%p)\n", link);
 
     if (link->dev_node)
        unregister_netdev(dev);
@@ -272,9 +261,6 @@ static int get_prom(struct pcmcia_device *link)
 
 ======================================================================*/
 
-#define CS_CHECK(fn, ret) \
-do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
-
 static int try_io_port(struct pcmcia_device *link)
 {
     int j, ret;
@@ -341,26 +327,29 @@ static int axnet_config(struct pcmcia_device *link)
 {
     struct net_device *dev = link->priv;
     axnet_dev_t *info = PRIV(dev);
-    int i, j, j2, last_ret, last_fn;
+    int i, j, j2, ret;
 
-    DEBUG(0, "axnet_config(0x%p)\n", link);
+    dev_dbg(&link->dev, "axnet_config(0x%p)\n", link);
 
     /* don't trust the CIS on this; Linksys got it wrong */
     link->conf.Present = 0x63;
-    last_ret = pcmcia_loop_config(link, axnet_configcheck, NULL);
-    if (last_ret != 0) {
-       cs_error(link, RequestIO, last_ret);
+    ret = pcmcia_loop_config(link, axnet_configcheck, NULL);
+    if (ret != 0)
        goto failed;
-    }
 
-    CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
+    ret = pcmcia_request_irq(link, &link->irq);
+    if (ret)
+           goto failed;
     
     if (link->io.NumPorts2 == 8) {
        link->conf.Attributes |= CONF_ENABLE_SPKR;
        link->conf.Status = CCSR_AUDIO_ENA;
     }
     
-    CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
+    ret = pcmcia_request_configuration(link, &link->conf);
+    if (ret)
+           goto failed;
+
     dev->irq = link->irq.AssignedIRQ;
     dev->base_addr = link->io.BasePort1;
 
@@ -410,7 +399,7 @@ static int axnet_config(struct pcmcia_device *link)
 
     info->phy_id = (i < 32) ? i : -1;
     link->dev_node = &info->node;
-    SET_NETDEV_DEV(dev, &handle_to_dev(link));
+    SET_NETDEV_DEV(dev, &link->dev);
 
     if (register_netdev(dev) != 0) {
        printk(KERN_NOTICE "axnet_cs: register_netdev() failed\n");
@@ -426,14 +415,12 @@ static int axnet_config(struct pcmcia_device *link)
           dev->base_addr, dev->irq,
           dev->dev_addr);
     if (info->phy_id != -1) {
-       DEBUG(0, "  MII transceiver at index %d, status %x.\n", info->phy_id, j);
+       dev_dbg(&link->dev, "  MII transceiver at index %d, status %x.\n", info->phy_id, j);
     } else {
        printk(KERN_NOTICE "  No MII transceivers found!\n");
     }
     return 0;
 
-cs_failed:
-    cs_error(link, last_fn, last_ret);
 failed:
     axnet_release(link);
     return -ENODEV;
@@ -543,7 +530,7 @@ static int axnet_open(struct net_device *dev)
     struct pcmcia_device *link = info->p_dev;
     unsigned int nic_base = dev->base_addr;
     
-    DEBUG(2, "axnet_open('%s')\n", dev->name);
+    dev_dbg(&link->dev, "axnet_open('%s')\n", dev->name);
 
     if (!pcmcia_dev_present(link))
        return -ENODEV;
@@ -572,7 +559,7 @@ static int axnet_close(struct net_device *dev)
     axnet_dev_t *info = PRIV(dev);
     struct pcmcia_device *link = info->p_dev;
 
-    DEBUG(2, "axnet_close('%s')\n", dev->name);
+    dev_dbg(&link->dev, "axnet_close('%s')\n", dev->name);
 
     ax_close(dev);
     free_irq(dev->irq, dev);
@@ -741,10 +728,8 @@ static void block_input(struct net_device *dev, int count,
     int xfer_count = count;
     char *buf = skb->data;
 
-#ifdef PCMCIA_DEBUG
     if ((ei_debug > 4) && (count != 4))
-       printk(KERN_DEBUG "%s: [bi=%d]\n", dev->name, count+4);
-#endif
+           pr_debug("%s: [bi=%d]\n", dev->name, count+4);
     outb_p(ring_offset & 0xff, nic_base + EN0_RSARLO);
     outb_p(ring_offset >> 8, nic_base + EN0_RSARHI);
     outb_p(E8390_RREAD+E8390_START, nic_base + AXNET_CMD);
@@ -762,10 +747,7 @@ static void block_output(struct net_device *dev, int count,
 {
     unsigned int nic_base = dev->base_addr;
 
-#ifdef PCMCIA_DEBUG
-    if (ei_debug > 4)
-       printk(KERN_DEBUG "%s: [bo=%d]\n", dev->name, count);
-#endif
+    pr_debug("%s: [bo=%d]\n", dev->name, count);
 
     /* Round the count up for word writes.  Do we need to do this?
        What effect will an odd byte count have on the 8390?
index 7b5c77b7bd27ebc9185a99da37ac7bc0871c96fb..21d9c9d815d12c9eb2e4d2302b0e99ea514aaf58 100644 (file)
 
 #define VERSION "arcnet: COM20020 PCMCIA support loaded.\n"
 
-#ifdef PCMCIA_DEBUG
-
-static int pc_debug = PCMCIA_DEBUG;
-module_param(pc_debug, int, 0);
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
+#ifdef DEBUG
 
 static void regdump(struct net_device *dev)
 {
@@ -92,7 +88,6 @@ static void regdump(struct net_device *dev)
 
 #else
 
-#define DEBUG(n, args...) do { } while (0)
 static inline void regdump(struct net_device *dev) { }
 
 #endif
@@ -144,7 +139,7 @@ static int com20020_probe(struct pcmcia_device *p_dev)
     struct net_device *dev;
     struct arcnet_local *lp;
 
-    DEBUG(0, "com20020_attach()\n");
+    dev_dbg(&p_dev->dev, "com20020_attach()\n");
 
     /* Create new network device */
     info = kzalloc(sizeof(struct com20020_dev_t), GFP_KERNEL);
@@ -169,11 +164,10 @@ static int com20020_probe(struct pcmcia_device *p_dev)
     p_dev->io.NumPorts1 = 16;
     p_dev->io.IOAddrLines = 16;
     p_dev->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
-    p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID;
     p_dev->conf.Attributes = CONF_ENABLE_IRQ;
     p_dev->conf.IntType = INT_MEMORY_AND_IO;
 
-    p_dev->irq.Instance = info->dev = dev;
+    info->dev = dev;
     p_dev->priv = info;
 
     return com20020_config(p_dev);
@@ -198,12 +192,12 @@ static void com20020_detach(struct pcmcia_device *link)
     struct com20020_dev_t *info = link->priv;
     struct net_device *dev = info->dev;
 
-    DEBUG(1,"detach...\n");
+    dev_dbg(&link->dev, "detach...\n");
 
-    DEBUG(0, "com20020_detach(0x%p)\n", link);
+    dev_dbg(&link->dev, "com20020_detach\n");
 
     if (link->dev_node) {
-       DEBUG(1,"unregister...\n");
+       dev_dbg(&link->dev, "unregister...\n");
 
        unregister_netdev(dev);
 
@@ -218,16 +212,16 @@ static void com20020_detach(struct pcmcia_device *link)
     com20020_release(link);
 
     /* Unlink device structure, free bits */
-    DEBUG(1,"unlinking...\n");
+    dev_dbg(&link->dev, "unlinking...\n");
     if (link->priv)
     {
        dev = info->dev;
        if (dev)
        {
-           DEBUG(1,"kfree...\n");
+           dev_dbg(&link->dev, "kfree...\n");
            free_netdev(dev);
        }
-       DEBUG(1,"kfree2...\n");
+       dev_dbg(&link->dev, "kfree2...\n");
        kfree(info);
     }
 
@@ -241,25 +235,22 @@ static void com20020_detach(struct pcmcia_device *link)
 
 ======================================================================*/
 
-#define CS_CHECK(fn, ret) \
-do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
-
 static int com20020_config(struct pcmcia_device *link)
 {
     struct arcnet_local *lp;
     com20020_dev_t *info;
     struct net_device *dev;
-    int i, last_ret, last_fn;
+    int i, ret;
     int ioaddr;
 
     info = link->priv;
     dev = info->dev;
 
-    DEBUG(1,"config...\n");
+    dev_dbg(&link->dev, "config...\n");
 
-    DEBUG(0, "com20020_config(0x%p)\n", link);
+    dev_dbg(&link->dev, "com20020_config\n");
 
-    DEBUG(1,"arcnet: baseport1 is %Xh\n", link->io.BasePort1);
+    dev_dbg(&link->dev, "baseport1 is %Xh\n", link->io.BasePort1);
     i = -ENODEV;
     if (!link->io.BasePort1)
     {
@@ -276,26 +267,27 @@ static int com20020_config(struct pcmcia_device *link)
     
     if (i != 0)
     {
-       DEBUG(1,"arcnet: requestIO failed totally!\n");
+       dev_dbg(&link->dev, "requestIO failed totally!\n");
        goto failed;
     }
        
     ioaddr = dev->base_addr = link->io.BasePort1;
-    DEBUG(1,"arcnet: got ioaddr %Xh\n", ioaddr);
+    dev_dbg(&link->dev, "got ioaddr %Xh\n", ioaddr);
 
-    DEBUG(1,"arcnet: request IRQ %d (%Xh/%Xh)\n",
-          link->irq.AssignedIRQ,
-          link->irq.IRQInfo1, link->irq.IRQInfo2);
+    dev_dbg(&link->dev, "request IRQ %d\n",
+           link->irq.AssignedIRQ);
     i = pcmcia_request_irq(link, &link->irq);
     if (i != 0)
     {
-       DEBUG(1,"arcnet: requestIRQ failed totally!\n");
+       dev_dbg(&link->dev, "requestIRQ failed totally!\n");
        goto failed;
     }
 
     dev->irq = link->irq.AssignedIRQ;
 
-    CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
+    ret = pcmcia_request_configuration(link, &link->conf);
+    if (ret)
+           goto failed;
 
     if (com20020_check(dev))
     {
@@ -308,26 +300,25 @@ static int com20020_config(struct pcmcia_device *link)
     lp->card_flags = ARC_CAN_10MBIT; /* pretend all of them can 10Mbit */
 
     link->dev_node = &info->node;
-    SET_NETDEV_DEV(dev, &handle_to_dev(link));
+    SET_NETDEV_DEV(dev, &link->dev);
 
     i = com20020_found(dev, 0);        /* calls register_netdev */
     
     if (i != 0) {
-       DEBUG(1,KERN_NOTICE "com20020_cs: com20020_found() failed\n");
+       dev_printk(KERN_NOTICE, &link->dev,
+               "com20020_cs: com20020_found() failed\n");
        link->dev_node = NULL;
        goto failed;
     }
 
     strcpy(info->node.dev_name, dev->name);
 
-    DEBUG(1,KERN_INFO "%s: port %#3lx, irq %d\n",
+    dev_dbg(&link->dev,KERN_INFO "%s: port %#3lx, irq %d\n",
            dev->name, dev->base_addr, dev->irq);
     return 0;
 
-cs_failed:
-    cs_error(link, last_fn, last_ret);
 failed:
-    DEBUG(1,"com20020_config failed...\n");
+    dev_dbg(&link->dev, "com20020_config failed...\n");
     com20020_release(link);
     return -ENODEV;
 } /* com20020_config */
@@ -342,7 +333,7 @@ failed:
 
 static void com20020_release(struct pcmcia_device *link)
 {
-       DEBUG(0, "com20020_release(0x%p)\n", link);
+       dev_dbg(&link->dev, "com20020_release\n");
        pcmcia_disable_device(link);
 }
 
index 7e01fbdb87e0f52ad94cb99d834c52dbd97aeaeb..6e3e1ced6db491f15a115670268dad8aa0de4fc6 100644 (file)
@@ -72,13 +72,6 @@ MODULE_LICENSE("GPL");
 /* 0:4KB*2 TX buffer   else:8KB*2 TX buffer */
 INT_MODULE_PARM(sram_config, 0);
 
-#ifdef PCMCIA_DEBUG
-INT_MODULE_PARM(pc_debug, PCMCIA_DEBUG);
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
-static char *version = DRV_NAME ".c " DRV_VERSION " 2002/03/23";
-#else
-#define DEBUG(n, args...)
-#endif
 
 /*====================================================================*/
 /*
@@ -245,7 +238,7 @@ static int fmvj18x_probe(struct pcmcia_device *link)
     local_info_t *lp;
     struct net_device *dev;
 
-    DEBUG(0, "fmvj18x_attach()\n");
+    dev_dbg(&link->dev, "fmvj18x_attach()\n");
 
     /* Make up a FMVJ18x specific data structure */
     dev = alloc_etherdev(sizeof(local_info_t));
@@ -262,10 +255,8 @@ static int fmvj18x_probe(struct pcmcia_device *link)
     link->io.IOAddrLines = 5;
 
     /* Interrupt setup */
-    link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_HANDLE_PRESENT;
-    link->irq.IRQInfo1 = IRQ_LEVEL_ID;
+    link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
     link->irq.Handler = &fjn_interrupt;
-    link->irq.Instance = dev;
 
     /* General socket configuration */
     link->conf.Attributes = CONF_ENABLE_IRQ;
@@ -285,7 +276,7 @@ static void fmvj18x_detach(struct pcmcia_device *link)
 {
     struct net_device *dev = link->priv;
 
-    DEBUG(0, "fmvj18x_detach(0x%p)\n", link);
+    dev_dbg(&link->dev, "fmvj18x_detach\n");
 
     if (link->dev_node)
        unregister_netdev(dev);
@@ -297,9 +288,6 @@ static void fmvj18x_detach(struct pcmcia_device *link)
 
 /*====================================================================*/
 
-#define CS_CHECK(fn, ret) \
-do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
-
 static int mfc_try_io_port(struct pcmcia_device *link)
 {
     int i, ret;
@@ -341,33 +329,38 @@ static int ungermann_try_io_port(struct pcmcia_device *link)
     return ret;        /* RequestIO failed */
 }
 
+static int fmvj18x_ioprobe(struct pcmcia_device *p_dev,
+                          cistpl_cftable_entry_t *cfg,
+                          cistpl_cftable_entry_t *dflt,
+                          unsigned int vcc,
+                          void *priv_data)
+{
+       return 0; /* strange, but that's what the code did already before... */
+}
+
 static int fmvj18x_config(struct pcmcia_device *link)
 {
     struct net_device *dev = link->priv;
     local_info_t *lp = netdev_priv(dev);
-    tuple_t tuple;
-    cisparse_t parse;
-    u_short buf[32];
-    int i, last_fn = 0, last_ret = 0, ret;
+    int i, ret;
     unsigned int ioaddr;
     cardtype_t cardtype;
     char *card_name = "unknown";
-    u_char *node_id;
+    u8 *buf;
+    size_t len;
+    u_char buggybuf[32];
+
+    dev_dbg(&link->dev, "fmvj18x_config\n");
 
-    DEBUG(0, "fmvj18x_config(0x%p)\n", link);
+    len = pcmcia_get_tuple(link, CISTPL_FUNCE, &buf);
+    kfree(buf);
 
-    tuple.TupleData = (u_char *)buf;
-    tuple.TupleDataMax = 64;
-    tuple.TupleOffset = 0;
-    tuple.DesiredTuple = CISTPL_FUNCE;
-    tuple.TupleOffset = 0;
-    if (pcmcia_get_first_tuple(link, &tuple) == 0) {
+    if (len) {
        /* Yes, I have CISTPL_FUNCE. Let's check CISTPL_MANFID */
-       tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
-       CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
-       CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
-       CS_CHECK(ParseTuple, pcmcia_parse_tuple(&tuple, &parse));
-       link->conf.ConfigIndex = parse.cftable_entry.index;
+       ret = pcmcia_loop_config(link, fmvj18x_ioprobe, NULL);
+       if (ret != 0)
+               goto failed;
+
        switch (link->manf_id) {
        case MANFID_TDK:
            cardtype = TDK;
@@ -433,17 +426,24 @@ static int fmvj18x_config(struct pcmcia_device *link)
 
     if (link->io.NumPorts2 != 0) {
        link->irq.Attributes =
-               IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED|IRQ_HANDLE_PRESENT;
+               IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
        ret = mfc_try_io_port(link);
-       if (ret != 0) goto cs_failed;
+       if (ret != 0) goto failed;
     } else if (cardtype == UNGERMANN) {
        ret = ungermann_try_io_port(link);
-       if (ret != 0) goto cs_failed;
+       if (ret != 0) goto failed;
     } else { 
-       CS_CHECK(RequestIO, pcmcia_request_io(link, &link->io));
+           ret = pcmcia_request_io(link, &link->io);
+           if (ret)
+                   goto failed;
     }
-    CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
-    CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
+    ret = pcmcia_request_irq(link, &link->irq);
+    if (ret)
+           goto failed;
+    ret = pcmcia_request_configuration(link, &link->conf);
+    if (ret)
+           goto failed;
+
     dev->irq = link->irq.AssignedIRQ;
     dev->base_addr = link->io.BasePort1;
 
@@ -474,21 +474,21 @@ static int fmvj18x_config(struct pcmcia_device *link)
     case CONTEC:
     case NEC:
     case KME:
-       tuple.DesiredTuple = CISTPL_FUNCE;
-       tuple.TupleOffset = 0;
-       CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
-       tuple.TupleOffset = 0;
-       CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
        if (cardtype == MBH10304) {
-           /* MBH10304's CIS_FUNCE is corrupted */
-           node_id = &(tuple.TupleData[5]);
            card_name = "FMV-J182";
-       } else {
-           while (tuple.TupleData[0] != CISTPL_FUNCE_LAN_NODE_ID ) {
-               CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple));
-               CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
+
+           len = pcmcia_get_tuple(link, CISTPL_FUNCE, &buf);
+           if (len < 11) {
+                   kfree(buf);
+                   goto failed;
            }
-           node_id = &(tuple.TupleData[2]);
+           /* Read MACID from CIS */
+           for (i = 5; i < 11; i++)
+                   dev->dev_addr[i] = buf[i];
+           kfree(buf);
+       } else {
+           if (pcmcia_get_mac_from_cis(link, dev))
+               goto failed;
            if( cardtype == TDK ) {
                card_name = "TDK LAK-CD021";
            } else if( cardtype == LA501 ) {
@@ -501,9 +501,6 @@ static int fmvj18x_config(struct pcmcia_device *link)
                card_name = "C-NET(PC)C";
            }
        }
-       /* Read MACID from CIS */
-       for (i = 0; i < 6; i++)
-           dev->dev_addr[i] = node_id[i];
        break;
     case UNGERMANN:
        /* Read MACID from register */
@@ -513,12 +510,12 @@ static int fmvj18x_config(struct pcmcia_device *link)
        break;
     case XXX10304:
        /* Read MACID from Buggy CIS */
-       if (fmvj18x_get_hwinfo(link, tuple.TupleData) == -1) {
+       if (fmvj18x_get_hwinfo(link, buggybuf) == -1) {
            printk(KERN_NOTICE "fmvj18x_cs: unable to read hardware net address.\n");
            goto failed;
        }
        for (i = 0 ; i < 6; i++) {
-           dev->dev_addr[i] = tuple.TupleData[i];
+           dev->dev_addr[i] = buggybuf[i];
        }
        card_name = "FMV-J182";
        break;
@@ -533,7 +530,7 @@ static int fmvj18x_config(struct pcmcia_device *link)
 
     lp->cardtype = cardtype;
     link->dev_node = &lp->node;
-    SET_NETDEV_DEV(dev, &handle_to_dev(link));
+    SET_NETDEV_DEV(dev, &link->dev);
 
     if (register_netdev(dev) != 0) {
        printk(KERN_NOTICE "fmvj18x_cs: register_netdev() failed\n");
@@ -551,9 +548,6 @@ static int fmvj18x_config(struct pcmcia_device *link)
 
     return 0;
     
-cs_failed:
-    /* All Card Services errors end up here */
-    cs_error(link, last_fn, last_ret);
 failed:
     fmvj18x_release(link);
     return -ENODEV;
@@ -571,16 +565,14 @@ static int fmvj18x_get_hwinfo(struct pcmcia_device *link, u_char *node_id)
     req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE;
     req.Base = 0; req.Size = 0;
     req.AccessSpeed = 0;
-    i = pcmcia_request_window(&link, &req, &link->win);
-    if (i != 0) {
-       cs_error(link, RequestWindow, i);
+    i = pcmcia_request_window(link, &req, &link->win);
+    if (i != 0)
        return -1;
-    }
 
     base = ioremap(req.Base, req.Size);
     mem.Page = 0;
     mem.CardOffset = 0;
-    pcmcia_map_mem_page(link->win, &mem);
+    pcmcia_map_mem_page(link, link->win, &mem);
 
     /*
      *  MBH10304 CISTPL_FUNCE_LAN_NODE_ID format
@@ -605,9 +597,7 @@ static int fmvj18x_get_hwinfo(struct pcmcia_device *link, u_char *node_id)
     }
 
     iounmap(base);
-    j = pcmcia_release_window(link->win);
-    if (j != 0)
-       cs_error(link, ReleaseWindow, j);
+    j = pcmcia_release_window(link, link->win);
     return (i != 0x200) ? 0 : -1;
 
 } /* fmvj18x_get_hwinfo */
@@ -626,11 +616,9 @@ static int fmvj18x_setup_mfc(struct pcmcia_device *link)
     req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE;
     req.Base = 0; req.Size = 0;
     req.AccessSpeed = 0;
-    i = pcmcia_request_window(&link, &req, &link->win);
-    if (i != 0) {
-       cs_error(link, RequestWindow, i);
+    i = pcmcia_request_window(link, &req, &link->win);
+    if (i != 0)
        return -1;
-    }
 
     lp->base = ioremap(req.Base, req.Size);
     if (lp->base == NULL) {
@@ -640,11 +628,10 @@ static int fmvj18x_setup_mfc(struct pcmcia_device *link)
 
     mem.Page = 0;
     mem.CardOffset = 0;
-    i = pcmcia_map_mem_page(link->win, &mem);
+    i = pcmcia_map_mem_page(link, link->win, &mem);
     if (i != 0) {
        iounmap(lp->base);
        lp->base = NULL;
-       cs_error(link, MapMemPage, i);
        return -1;
     }
     
@@ -671,15 +658,13 @@ static void fmvj18x_release(struct pcmcia_device *link)
     u_char __iomem *tmp;
     int j;
 
-    DEBUG(0, "fmvj18x_release(0x%p)\n", link);
+    dev_dbg(&link->dev, "fmvj18x_release\n");
 
     if (lp->base != NULL) {
        tmp = lp->base;
        lp->base = NULL;    /* set NULL before iounmap */
        iounmap(tmp);
-       j = pcmcia_release_window(link->win);
-       if (j != 0)
-           cs_error(link, ReleaseWindow, j);
+       j = pcmcia_release_window(link, link->win);
     }
 
     pcmcia_disable_device(link);
@@ -788,8 +773,8 @@ static irqreturn_t fjn_interrupt(int dummy, void *dev_id)
     outb(tx_stat, ioaddr + TX_STATUS);
     outb(rx_stat, ioaddr + RX_STATUS);
     
-    DEBUG(4, "%s: interrupt, rx_status %02x.\n", dev->name, rx_stat);
-    DEBUG(4, "               tx_status %02x.\n", tx_stat);
+    pr_debug("%s: interrupt, rx_status %02x.\n", dev->name, rx_stat);
+    pr_debug("               tx_status %02x.\n", tx_stat);
     
     if (rx_stat || (inb(ioaddr + RX_MODE) & F_BUF_EMP) == 0) {
        /* there is packet(s) in rx buffer */
@@ -809,8 +794,8 @@ static irqreturn_t fjn_interrupt(int dummy, void *dev_id)
        }
        netif_wake_queue(dev);
     }
-    DEBUG(4, "%s: exiting interrupt,\n", dev->name);
-    DEBUG(4, "    tx_status %02x, rx_status %02x.\n", tx_stat, rx_stat);
+    pr_debug("%s: exiting interrupt,\n", dev->name);
+    pr_debug("    tx_status %02x, rx_status %02x.\n", tx_stat, rx_stat);
 
     outb(D_TX_INTR, ioaddr + TX_INTR);
     outb(D_RX_INTR, ioaddr + RX_INTR);
@@ -882,7 +867,7 @@ static netdev_tx_t fjn_start_xmit(struct sk_buff *skb,
            return NETDEV_TX_BUSY;
        }
 
-       DEBUG(4, "%s: Transmitting a packet of length %lu.\n",
+       pr_debug("%s: Transmitting a packet of length %lu.\n",
              dev->name, (unsigned long)skb->len);
        dev->stats.tx_bytes += skb->len;
 
@@ -937,7 +922,7 @@ static void fjn_reset(struct net_device *dev)
     unsigned int ioaddr = dev->base_addr;
     int i;
 
-    DEBUG(4, "fjn_reset(%s) called.\n",dev->name);
+    pr_debug("fjn_reset(%s) called.\n",dev->name);
 
     /* Reset controller */
     if( sram_config == 0 ) 
@@ -1015,13 +1000,13 @@ static void fjn_rx(struct net_device *dev)
     unsigned int ioaddr = dev->base_addr;
     int boguscount = 10;       /* 5 -> 10: by agy 19940922 */
 
-    DEBUG(4, "%s: in rx_packet(), rx_status %02x.\n",
+    pr_debug("%s: in rx_packet(), rx_status %02x.\n",
          dev->name, inb(ioaddr + RX_STATUS));
 
     while ((inb(ioaddr + RX_MODE) & F_BUF_EMP) == 0) {
        u_short status = inw(ioaddr + DATAPORT);
 
-       DEBUG(4, "%s: Rxing packet mode %02x status %04x.\n",
+       pr_debug("%s: Rxing packet mode %02x status %04x.\n",
              dev->name, inb(ioaddr + RX_MODE), status);
 #ifndef final_version
        if (status == 0) {
@@ -1061,16 +1046,14 @@ static void fjn_rx(struct net_device *dev)
                 (pkt_len + 1) >> 1);
            skb->protocol = eth_type_trans(skb, dev);
 
-#ifdef PCMCIA_DEBUG
-           if (pc_debug > 5) {
+           {
                int i;
-               printk(KERN_DEBUG "%s: Rxed packet of length %d: ",
-                      dev->name, pkt_len);
+               pr_debug("%s: Rxed packet of length %d: ",
+                       dev->name, pkt_len);
                for (i = 0; i < 14; i++)
-                   printk(" %02x", skb->data[i]);
-               printk(".\n");
+                       pr_debug(" %02x", skb->data[i]);
+               pr_debug(".\n");
            }
-#endif
 
            netif_rx(skb);
            dev->stats.rx_packets++;
@@ -1094,7 +1077,7 @@ static void fjn_rx(struct net_device *dev)
        }
 
        if (i > 0)
-           DEBUG(5, "%s: Exint Rx packet with mode %02x after "
+           pr_debug("%s: Exint Rx packet with mode %02x after "
                  "%d ticks.\n", dev->name, inb(ioaddr + RX_MODE), i);
     }
 */
@@ -1112,24 +1095,8 @@ static void netdev_get_drvinfo(struct net_device *dev,
        sprintf(info->bus_info, "PCMCIA 0x%lx", dev->base_addr);
 }
 
-#ifdef PCMCIA_DEBUG
-static u32 netdev_get_msglevel(struct net_device *dev)
-{
-       return pc_debug;
-}
-
-static void netdev_set_msglevel(struct net_device *dev, u32 level)
-{
-       pc_debug = level;
-}
-#endif /* PCMCIA_DEBUG */
-
 static const struct ethtool_ops netdev_ethtool_ops = {
        .get_drvinfo            = netdev_get_drvinfo,
-#ifdef PCMCIA_DEBUG
-       .get_msglevel           = netdev_get_msglevel,
-       .set_msglevel           = netdev_set_msglevel,
-#endif /* PCMCIA_DEBUG */
 };
 
 static int fjn_config(struct net_device *dev, struct ifmap *map){
@@ -1141,7 +1108,7 @@ static int fjn_open(struct net_device *dev)
     struct local_info_t *lp = netdev_priv(dev);
     struct pcmcia_device *link = lp->p_dev;
 
-    DEBUG(4, "fjn_open('%s').\n", dev->name);
+    pr_debug("fjn_open('%s').\n", dev->name);
 
     if (!pcmcia_dev_present(link))
        return -ENODEV;
@@ -1167,7 +1134,7 @@ static int fjn_close(struct net_device *dev)
     struct pcmcia_device *link = lp->p_dev;
     unsigned int ioaddr = dev->base_addr;
 
-    DEBUG(4, "fjn_close('%s').\n", dev->name);
+    pr_debug("fjn_close('%s').\n", dev->name);
 
     lp->open_time = 0;
     netif_stop_queue(dev);
index 06618af1a4680d6c208536c903aa5de8638e8d2f..37f4a6fdc3ef46525a7655e1c45cd71382e278b8 100644 (file)
 #define PCMCIA
 #include "../tokenring/ibmtr.c"
 
-#ifdef PCMCIA_DEBUG
-static int pc_debug = PCMCIA_DEBUG;
-module_param(pc_debug, int, 0);
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
-static char *version =
-"ibmtr_cs.c 1.10   1996/01/06 05:19:00 (Steve Kipisz)\n"
-"           2.2.7  1999/05/03 12:00:00 (Mike Phillips)\n"
-"           2.4.2  2001/30/28 Midnight (Burt Silverman)\n";
-#else
-#define DEBUG(n, args...)
-#endif
 
 /*====================================================================*/
 
@@ -130,6 +119,12 @@ static const struct ethtool_ops netdev_ethtool_ops = {
        .get_drvinfo            = netdev_get_drvinfo,
 };
 
+static irqreturn_t ibmtr_interrupt(int irq, void *dev_id) {
+       ibmtr_dev_t *info = dev_id;
+       struct net_device *dev = info->dev;
+       return tok_interrupt(irq, dev);
+};
+
 /*======================================================================
 
     ibmtr_attach() creates an "instance" of the driver, allocating
@@ -143,7 +138,7 @@ static int __devinit ibmtr_attach(struct pcmcia_device *link)
     ibmtr_dev_t *info;
     struct net_device *dev;
 
-    DEBUG(0, "ibmtr_attach()\n");
+    dev_dbg(&link->dev, "ibmtr_attach()\n");
 
     /* Create new token-ring device */
     info = kzalloc(sizeof(*info), GFP_KERNEL);
@@ -161,14 +156,13 @@ static int __devinit ibmtr_attach(struct pcmcia_device *link)
     link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
     link->io.NumPorts1 = 4;
     link->io.IOAddrLines = 16;
-    link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
-    link->irq.IRQInfo1 = IRQ_LEVEL_ID;
-    link->irq.Handler = &tok_interrupt;
+    link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
+    link->irq.Handler = ibmtr_interrupt;
     link->conf.Attributes = CONF_ENABLE_IRQ;
     link->conf.IntType = INT_MEMORY_AND_IO;
     link->conf.Present = PRESENT_OPTION;
 
-    link->irq.Instance = info->dev = dev;
+    info->dev = dev;
 
     SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
 
@@ -190,7 +184,7 @@ static void ibmtr_detach(struct pcmcia_device *link)
     struct net_device *dev = info->dev;
      struct tok_info *ti = netdev_priv(dev);
 
-    DEBUG(0, "ibmtr_detach(0x%p)\n", link);
+    dev_dbg(&link->dev, "ibmtr_detach\n");
     
     /* 
      * When the card removal interrupt hits tok_interrupt(), 
@@ -217,9 +211,6 @@ static void ibmtr_detach(struct pcmcia_device *link)
 
 ======================================================================*/
 
-#define CS_CHECK(fn, ret) \
-do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
-
 static int __devinit ibmtr_config(struct pcmcia_device *link)
 {
     ibmtr_dev_t *info = link->priv;
@@ -227,9 +218,9 @@ static int __devinit ibmtr_config(struct pcmcia_device *link)
     struct tok_info *ti = netdev_priv(dev);
     win_req_t req;
     memreq_t mem;
-    int i, last_ret, last_fn;
+    int i, ret;
 
-    DEBUG(0, "ibmtr_config(0x%p)\n", link);
+    dev_dbg(&link->dev, "ibmtr_config\n");
 
     link->conf.ConfigIndex = 0x61;
 
@@ -241,11 +232,15 @@ static int __devinit ibmtr_config(struct pcmcia_device *link)
     if (i != 0) {
        /* Couldn't get 0xA20-0xA23.  Try ALTERNATE at 0xA24-0xA27. */
        link->io.BasePort1 = 0xA24;
-       CS_CHECK(RequestIO, pcmcia_request_io(link, &link->io));
+       ret = pcmcia_request_io(link, &link->io);
+       if (ret)
+               goto failed;
     }
     dev->base_addr = link->io.BasePort1;
 
-    CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
+    ret = pcmcia_request_irq(link, &link->irq);
+    if (ret)
+           goto failed;
     dev->irq = link->irq.AssignedIRQ;
     ti->irq = link->irq.AssignedIRQ;
     ti->global_int_enable=GLOBAL_INT_ENABLE+((dev->irq==9) ? 2 : dev->irq);
@@ -256,11 +251,15 @@ static int __devinit ibmtr_config(struct pcmcia_device *link)
     req.Base = 0; 
     req.Size = 0x2000;
     req.AccessSpeed = 250;
-    CS_CHECK(RequestWindow, pcmcia_request_window(&link, &req, &link->win));
+    ret = pcmcia_request_window(link, &req, &link->win);
+    if (ret)
+           goto failed;
 
     mem.CardOffset = mmiobase;
     mem.Page = 0;
-    CS_CHECK(MapMemPage, pcmcia_map_mem_page(link->win, &mem));
+    ret = pcmcia_map_mem_page(link, link->win, &mem);
+    if (ret)
+           goto failed;
     ti->mmio = ioremap(req.Base, req.Size);
 
     /* Allocate the SRAM memory window */
@@ -269,17 +268,23 @@ static int __devinit ibmtr_config(struct pcmcia_device *link)
     req.Base = 0;
     req.Size = sramsize * 1024;
     req.AccessSpeed = 250;
-    CS_CHECK(RequestWindow, pcmcia_request_window(&link, &req, &info->sram_win_handle));
+    ret = pcmcia_request_window(link, &req, &info->sram_win_handle);
+    if (ret)
+           goto failed;
 
     mem.CardOffset = srambase;
     mem.Page = 0;
-    CS_CHECK(MapMemPage, pcmcia_map_mem_page(info->sram_win_handle, &mem));
+    ret = pcmcia_map_mem_page(link, info->sram_win_handle, &mem);
+    if (ret)
+           goto failed;
 
     ti->sram_base = mem.CardOffset >> 12;
     ti->sram_virt = ioremap(req.Base, req.Size);
     ti->sram_phys = req.Base;
 
-    CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
+    ret = pcmcia_request_configuration(link, &link->conf);
+    if (ret)
+           goto failed;
 
     /*  Set up the Token-Ring Controller Configuration Register and
         turn on the card.  Check the "Local Area Network Credit Card
@@ -287,7 +292,7 @@ static int __devinit ibmtr_config(struct pcmcia_device *link)
     ibmtr_hw_setup(dev, mmiobase);
 
     link->dev_node = &info->node;
-    SET_NETDEV_DEV(dev, &handle_to_dev(link));
+    SET_NETDEV_DEV(dev, &link->dev);
 
     i = ibmtr_probe_card(dev);
     if (i != 0) {
@@ -305,8 +310,6 @@ static int __devinit ibmtr_config(struct pcmcia_device *link)
           dev->dev_addr);
     return 0;
 
-cs_failed:
-    cs_error(link, last_fn, last_ret);
 failed:
     ibmtr_release(link);
     return -ENODEV;
@@ -325,12 +328,12 @@ static void ibmtr_release(struct pcmcia_device *link)
        ibmtr_dev_t *info = link->priv;
        struct net_device *dev = info->dev;
 
-       DEBUG(0, "ibmtr_release(0x%p)\n", link);
+       dev_dbg(&link->dev, "ibmtr_release\n");
 
        if (link->win) {
                struct tok_info *ti = netdev_priv(dev);
                iounmap(ti->mmio);
-               pcmcia_release_window(info->sram_win_handle);
+               pcmcia_release_window(link, info->sram_win_handle);
        }
        pcmcia_disable_device(link);
 }
index 5ed6339c52bcbb6e021e08b334b6e614eacf75f8..dae5ef6b26092a334544b2dcd66872317e1b30a8 100644 (file)
@@ -381,13 +381,6 @@ typedef struct _mace_private {
 Private Global Variables
 ---------------------------------------------------------------------------- */
 
-#ifdef PCMCIA_DEBUG
-static char rcsid[] =
-"nmclan_cs.c,v 0.16 1995/07/01 06:42:17 rpao Exp rpao";
-static char *version =
-DRV_NAME " " DRV_VERSION " (Roger C. Pao)";
-#endif
-
 static const char *if_names[]={
     "Auto", "10baseT", "BNC",
 };
@@ -406,12 +399,6 @@ MODULE_LICENSE("GPL");
 /* 0=auto, 1=10baseT, 2 = 10base2, default=auto */
 INT_MODULE_PARM(if_port, 0);
 
-#ifdef PCMCIA_DEBUG
-INT_MODULE_PARM(pc_debug, PCMCIA_DEBUG);
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
-#else
-#define DEBUG(n, args...)
-#endif
 
 /* ----------------------------------------------------------------------------
 Function Prototypes
@@ -462,8 +449,7 @@ static int nmclan_probe(struct pcmcia_device *link)
     mace_private *lp;
     struct net_device *dev;
 
-    DEBUG(0, "nmclan_attach()\n");
-    DEBUG(1, "%s\n", rcsid);
+    dev_dbg(&link->dev, "nmclan_attach()\n");
 
     /* Create new ethernet device */
     dev = alloc_etherdev(sizeof(mace_private));
@@ -477,10 +463,8 @@ static int nmclan_probe(struct pcmcia_device *link)
     link->io.NumPorts1 = 32;
     link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
     link->io.IOAddrLines = 5;
-    link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
-    link->irq.IRQInfo1 = IRQ_LEVEL_ID;
+    link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
     link->irq.Handler = &mace_interrupt;
-    link->irq.Instance = dev;
     link->conf.Attributes = CONF_ENABLE_IRQ;
     link->conf.IntType = INT_MEMORY_AND_IO;
     link->conf.ConfigIndex = 1;
@@ -507,7 +491,7 @@ static void nmclan_detach(struct pcmcia_device *link)
 {
     struct net_device *dev = link->priv;
 
-    DEBUG(0, "nmclan_detach(0x%p)\n", link);
+    dev_dbg(&link->dev, "nmclan_detach\n");
 
     if (link->dev_node)
        unregister_netdev(dev);
@@ -654,37 +638,40 @@ nmclan_config
        ethernet device available to the system.
 ---------------------------------------------------------------------------- */
 
-#define CS_CHECK(fn, ret) \
-  do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
-
 static int nmclan_config(struct pcmcia_device *link)
 {
   struct net_device *dev = link->priv;
   mace_private *lp = netdev_priv(dev);
-  tuple_t tuple;
-  u_char buf[64];
-  int i, last_ret, last_fn;
+  u8 *buf;
+  size_t len;
+  int i, ret;
   unsigned int ioaddr;
 
-  DEBUG(0, "nmclan_config(0x%p)\n", link);
+  dev_dbg(&link->dev, "nmclan_config\n");
+
+  ret = pcmcia_request_io(link, &link->io);
+  if (ret)
+         goto failed;
+  ret = pcmcia_request_irq(link, &link->irq);
+  if (ret)
+         goto failed;
+  ret = pcmcia_request_configuration(link, &link->conf);
+  if (ret)
+         goto failed;
 
-  CS_CHECK(RequestIO, pcmcia_request_io(link, &link->io));
-  CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
-  CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
   dev->irq = link->irq.AssignedIRQ;
   dev->base_addr = link->io.BasePort1;
 
   ioaddr = dev->base_addr;
 
   /* Read the ethernet address from the CIS. */
-  tuple.DesiredTuple = 0x80 /* CISTPL_CFTABLE_ENTRY_MISC */;
-  tuple.TupleData = buf;
-  tuple.TupleDataMax = 64;
-  tuple.TupleOffset = 0;
-  tuple.Attributes = 0;
-  CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
-  CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
-  memcpy(dev->dev_addr, tuple.TupleData, ETHER_ADDR_LEN);
+  len = pcmcia_get_tuple(link, 0x80, &buf);
+  if (!buf || len < ETHER_ADDR_LEN) {
+         kfree(buf);
+         goto failed;
+  }
+  memcpy(dev->dev_addr, buf, ETHER_ADDR_LEN);
+  kfree(buf);
 
   /* Verify configuration by reading the MACE ID. */
   {
@@ -693,7 +680,7 @@ static int nmclan_config(struct pcmcia_device *link)
     sig[0] = mace_read(lp, ioaddr, MACE_CHIPIDL);
     sig[1] = mace_read(lp, ioaddr, MACE_CHIPIDH);
     if ((sig[0] == 0x40) && ((sig[1] & 0x0F) == 0x09)) {
-      DEBUG(0, "nmclan_cs configured: mace id=%x %x\n",
+      dev_dbg(&link->dev, "nmclan_cs configured: mace id=%x %x\n",
            sig[0], sig[1]);
     } else {
       printk(KERN_NOTICE "nmclan_cs: mace id not found: %x %x should"
@@ -712,7 +699,7 @@ static int nmclan_config(struct pcmcia_device *link)
     printk(KERN_NOTICE "nmclan_cs: invalid if_port requested\n");
 
   link->dev_node = &lp->node;
-  SET_NETDEV_DEV(dev, &handle_to_dev(link));
+  SET_NETDEV_DEV(dev, &link->dev);
 
   i = register_netdev(dev);
   if (i != 0) {
@@ -729,8 +716,6 @@ static int nmclan_config(struct pcmcia_device *link)
         dev->dev_addr);
   return 0;
 
-cs_failed:
-       cs_error(link, last_fn, last_ret);
 failed:
        nmclan_release(link);
        return -ENODEV;
@@ -744,7 +729,7 @@ nmclan_release
 ---------------------------------------------------------------------------- */
 static void nmclan_release(struct pcmcia_device *link)
 {
-       DEBUG(0, "nmclan_release(0x%p)\n", link);
+       dev_dbg(&link->dev, "nmclan_release\n");
        pcmcia_disable_device(link);
 }
 
@@ -795,7 +780,7 @@ static void nmclan_reset(struct net_device *dev)
   /* Reset Xilinx */
   reg.Action = CS_WRITE;
   reg.Offset = CISREG_COR;
-  DEBUG(1, "nmclan_reset: OrigCorValue=0x%lX, resetting...\n",
+  dev_dbg(&link->dev, "nmclan_reset: OrigCorValue=0x%lX, resetting...\n",
        OrigCorValue);
   reg.Value = COR_SOFT_RESET;
   pcmcia_access_configuration_register(link, &reg);
@@ -872,7 +857,7 @@ static int mace_close(struct net_device *dev)
   mace_private *lp = netdev_priv(dev);
   struct pcmcia_device *link = lp->p_dev;
 
-  DEBUG(2, "%s: shutting down ethercard.\n", dev->name);
+  dev_dbg(&link->dev, "%s: shutting down ethercard.\n", dev->name);
 
   /* Mask off all interrupts from the MACE chip. */
   outb(0xFF, ioaddr + AM2150_MACE_BASE + MACE_IMR);
@@ -891,24 +876,8 @@ static void netdev_get_drvinfo(struct net_device *dev,
        sprintf(info->bus_info, "PCMCIA 0x%lx", dev->base_addr);
 }
 
-#ifdef PCMCIA_DEBUG
-static u32 netdev_get_msglevel(struct net_device *dev)
-{
-       return pc_debug;
-}
-
-static void netdev_set_msglevel(struct net_device *dev, u32 level)
-{
-       pc_debug = level;
-}
-#endif /* PCMCIA_DEBUG */
-
 static const struct ethtool_ops netdev_ethtool_ops = {
        .get_drvinfo            = netdev_get_drvinfo,
-#ifdef PCMCIA_DEBUG
-       .get_msglevel           = netdev_get_msglevel,
-       .set_msglevel           = netdev_set_msglevel,
-#endif /* PCMCIA_DEBUG */
 };
 
 /* ----------------------------------------------------------------------------
@@ -946,7 +915,7 @@ static netdev_tx_t mace_start_xmit(struct sk_buff *skb,
 
   netif_stop_queue(dev);
 
-  DEBUG(3, "%s: mace_start_xmit(length = %ld) called.\n",
+  pr_debug("%s: mace_start_xmit(length = %ld) called.\n",
        dev->name, (long)skb->len);
 
 #if (!TX_INTERRUPTABLE)
@@ -1008,7 +977,7 @@ static irqreturn_t mace_interrupt(int irq, void *dev_id)
   int IntrCnt = MACE_MAX_IR_ITERATIONS;
 
   if (dev == NULL) {
-    DEBUG(2, "mace_interrupt(): irq 0x%X for unknown device.\n",
+    pr_debug("mace_interrupt(): irq 0x%X for unknown device.\n",
          irq);
     return IRQ_NONE;
   }
@@ -1031,7 +1000,7 @@ static irqreturn_t mace_interrupt(int irq, void *dev_id)
   }
 
   if (!netif_device_present(dev)) {
-    DEBUG(2, "%s: interrupt from dead card\n", dev->name);
+    pr_debug("%s: interrupt from dead card\n", dev->name);
     return IRQ_NONE;
   }
 
@@ -1039,7 +1008,7 @@ static irqreturn_t mace_interrupt(int irq, void *dev_id)
     /* WARNING: MACE_IR is a READ/CLEAR port! */
     status = inb(ioaddr + AM2150_MACE_BASE + MACE_IR);
 
-    DEBUG(3, "mace_interrupt: irq 0x%X status 0x%X.\n", irq, status);
+    pr_debug("mace_interrupt: irq 0x%X status 0x%X.\n", irq, status);
 
     if (status & MACE_IR_RCVINT) {
       mace_rx(dev, MACE_MAX_RX_ITERATIONS);
@@ -1158,7 +1127,7 @@ static int mace_rx(struct net_device *dev, unsigned char RxCnt)
   ) {
     rx_status = inw(ioaddr + AM2150_RCV);
 
-    DEBUG(3, "%s: in mace_rx(), framecnt 0x%X, rx_status"
+    pr_debug("%s: in mace_rx(), framecnt 0x%X, rx_status"
          " 0x%X.\n", dev->name, rx_framecnt, rx_status);
 
     if (rx_status & MACE_RCVFS_RCVSTS) { /* Error, update stats. */
@@ -1185,7 +1154,7 @@ static int mace_rx(struct net_device *dev, unsigned char RxCnt)
       lp->mace_stats.rfs_rcvcc += inb(ioaddr + AM2150_RCV);
         /* rcv collision count */
 
-      DEBUG(3, "    receiving packet size 0x%X rx_status"
+      pr_debug("    receiving packet size 0x%X rx_status"
            " 0x%X.\n", pkt_len, rx_status);
 
       skb = dev_alloc_skb(pkt_len+2);
@@ -1204,7 +1173,7 @@ static int mace_rx(struct net_device *dev, unsigned char RxCnt)
        outb(0xFF, ioaddr + AM2150_RCV_NEXT); /* skip to next frame */
        continue;
       } else {
-       DEBUG(1, "%s: couldn't allocate a sk_buff of size"
+       pr_debug("%s: couldn't allocate a sk_buff of size"
              " %d.\n", dev->name, pkt_len);
        lp->linux_stats.rx_dropped++;
       }
@@ -1220,28 +1189,28 @@ pr_linux_stats
 ---------------------------------------------------------------------------- */
 static void pr_linux_stats(struct net_device_stats *pstats)
 {
-  DEBUG(2, "pr_linux_stats\n");
-  DEBUG(2, " rx_packets=%-7ld        tx_packets=%ld\n",
+  pr_debug("pr_linux_stats\n");
+  pr_debug(" rx_packets=%-7ld        tx_packets=%ld\n",
        (long)pstats->rx_packets, (long)pstats->tx_packets);
-  DEBUG(2, " rx_errors=%-7ld         tx_errors=%ld\n",
+  pr_debug(" rx_errors=%-7ld         tx_errors=%ld\n",
        (long)pstats->rx_errors, (long)pstats->tx_errors);
-  DEBUG(2, " rx_dropped=%-7ld        tx_dropped=%ld\n",
+  pr_debug(" rx_dropped=%-7ld        tx_dropped=%ld\n",
        (long)pstats->rx_dropped, (long)pstats->tx_dropped);
-  DEBUG(2, " multicast=%-7ld         collisions=%ld\n",
+  pr_debug(" multicast=%-7ld         collisions=%ld\n",
        (long)pstats->multicast, (long)pstats->collisions);
 
-  DEBUG(2, " rx_length_errors=%-7ld  rx_over_errors=%ld\n",
+  pr_debug(" rx_length_errors=%-7ld  rx_over_errors=%ld\n",
        (long)pstats->rx_length_errors, (long)pstats->rx_over_errors);
-  DEBUG(2, " rx_crc_errors=%-7ld     rx_frame_errors=%ld\n",
+  pr_debug(" rx_crc_errors=%-7ld     rx_frame_errors=%ld\n",
        (long)pstats->rx_crc_errors, (long)pstats->rx_frame_errors);
-  DEBUG(2, " rx_fifo_errors=%-7ld    rx_missed_errors=%ld\n",
+  pr_debug(" rx_fifo_errors=%-7ld    rx_missed_errors=%ld\n",
        (long)pstats->rx_fifo_errors, (long)pstats->rx_missed_errors);
 
-  DEBUG(2, " tx_aborted_errors=%-7ld tx_carrier_errors=%ld\n",
+  pr_debug(" tx_aborted_errors=%-7ld tx_carrier_errors=%ld\n",
        (long)pstats->tx_aborted_errors, (long)pstats->tx_carrier_errors);
-  DEBUG(2, " tx_fifo_errors=%-7ld    tx_heartbeat_errors=%ld\n",
+  pr_debug(" tx_fifo_errors=%-7ld    tx_heartbeat_errors=%ld\n",
        (long)pstats->tx_fifo_errors, (long)pstats->tx_heartbeat_errors);
-  DEBUG(2, " tx_window_errors=%ld\n",
+  pr_debug(" tx_window_errors=%ld\n",
        (long)pstats->tx_window_errors);
 } /* pr_linux_stats */
 
@@ -1250,48 +1219,48 @@ pr_mace_stats
 ---------------------------------------------------------------------------- */
 static void pr_mace_stats(mace_statistics *pstats)
 {
-  DEBUG(2, "pr_mace_stats\n");
+  pr_debug("pr_mace_stats\n");
 
-  DEBUG(2, " xmtsv=%-7d             uflo=%d\n",
+  pr_debug(" xmtsv=%-7d             uflo=%d\n",
        pstats->xmtsv, pstats->uflo);
-  DEBUG(2, " lcol=%-7d              more=%d\n",
+  pr_debug(" lcol=%-7d              more=%d\n",
        pstats->lcol, pstats->more);
-  DEBUG(2, " one=%-7d               defer=%d\n",
+  pr_debug(" one=%-7d               defer=%d\n",
        pstats->one, pstats->defer);
-  DEBUG(2, " lcar=%-7d              rtry=%d\n",
+  pr_debug(" lcar=%-7d              rtry=%d\n",
        pstats->lcar, pstats->rtry);
 
   /* MACE_XMTRC */
-  DEBUG(2, " exdef=%-7d             xmtrc=%d\n",
+  pr_debug(" exdef=%-7d             xmtrc=%d\n",
        pstats->exdef, pstats->xmtrc);
 
   /* RFS1--Receive Status (RCVSTS) */
-  DEBUG(2, " oflo=%-7d              clsn=%d\n",
+  pr_debug(" oflo=%-7d              clsn=%d\n",
        pstats->oflo, pstats->clsn);
-  DEBUG(2, " fram=%-7d              fcs=%d\n",
+  pr_debug(" fram=%-7d              fcs=%d\n",
        pstats->fram, pstats->fcs);
 
   /* RFS2--Runt Packet Count (RNTPC) */
   /* RFS3--Receive Collision Count (RCVCC) */
-  DEBUG(2, " rfs_rntpc=%-7d         rfs_rcvcc=%d\n",
+  pr_debug(" rfs_rntpc=%-7d         rfs_rcvcc=%d\n",
        pstats->rfs_rntpc, pstats->rfs_rcvcc);
 
   /* MACE_IR */
-  DEBUG(2, " jab=%-7d               babl=%d\n",
+  pr_debug(" jab=%-7d               babl=%d\n",
        pstats->jab, pstats->babl);
-  DEBUG(2, " cerr=%-7d              rcvcco=%d\n",
+  pr_debug(" cerr=%-7d              rcvcco=%d\n",
        pstats->cerr, pstats->rcvcco);
-  DEBUG(2, " rntpco=%-7d            mpco=%d\n",
+  pr_debug(" rntpco=%-7d            mpco=%d\n",
        pstats->rntpco, pstats->mpco);
 
   /* MACE_MPC */
-  DEBUG(2, " mpc=%d\n", pstats->mpc);
+  pr_debug(" mpc=%d\n", pstats->mpc);
 
   /* MACE_RNTPC */
-  DEBUG(2, " rntpc=%d\n", pstats->rntpc);
+  pr_debug(" rntpc=%d\n", pstats->rntpc);
 
   /* MACE_RCVCC */
-  DEBUG(2, " rcvcc=%d\n", pstats->rcvcc);
+  pr_debug(" rcvcc=%d\n", pstats->rcvcc);
 
 } /* pr_mace_stats */
 
@@ -1360,7 +1329,7 @@ static struct net_device_stats *mace_get_stats(struct net_device *dev)
 
   update_stats(dev->base_addr, dev);
 
-  DEBUG(1, "%s: updating the statistics.\n", dev->name);
+  pr_debug("%s: updating the statistics.\n", dev->name);
   pr_linux_stats(&lp->linux_stats);
   pr_mace_stats(&lp->mace_stats);
 
@@ -1427,7 +1396,7 @@ static void BuildLAF(int *ladrf, int *adr)
   ladrf[byte] |= (1 << (hashcode & 7));
 
 #ifdef PCMCIA_DEBUG
-  if (pc_debug > 2)
+  if (0)
     printk(KERN_DEBUG "    adr =%pM\n", adr);
   printk(KERN_DEBUG "    hashcode = %d(decimal), ladrf[0:63] =", hashcode);
   for (i = 0; i < 8; i++)
@@ -1454,12 +1423,12 @@ static void restore_multicast_list(struct net_device *dev)
   unsigned int ioaddr = dev->base_addr;
   int i;
 
-  DEBUG(2, "%s: restoring Rx mode to %d addresses.\n",
+  pr_debug("%s: restoring Rx mode to %d addresses.\n",
        dev->name, num_addrs);
 
   if (num_addrs > 0) {
 
-    DEBUG(1, "Attempt to restore multicast list detected.\n");
+    pr_debug("Attempt to restore multicast list detected.\n");
 
     mace_write(lp, ioaddr, MACE_IAC, MACE_IAC_ADDRCHG | MACE_IAC_LOGADDR);
     /* Poll ADDRCHG bit */
@@ -1511,11 +1480,11 @@ static void set_multicast_list(struct net_device *dev)
   struct dev_mc_list *dmi = dev->mc_list;
 
 #ifdef PCMCIA_DEBUG
-  if (pc_debug > 1) {
+  {
     static int old;
     if (dev->mc_count != old) {
       old = dev->mc_count;
-      DEBUG(0, "%s: setting Rx mode to %d addresses.\n",
+      pr_debug("%s: setting Rx mode to %d addresses.\n",
            dev->name, old);
     }
   }
@@ -1546,7 +1515,7 @@ static void restore_multicast_list(struct net_device *dev)
   unsigned int ioaddr = dev->base_addr;
   mace_private *lp = netdev_priv(dev);
 
-  DEBUG(2, "%s: restoring Rx mode to %d addresses.\n", dev->name,
+  pr_debug("%s: restoring Rx mode to %d addresses.\n", dev->name,
        lp->multicast_num_addrs);
 
   if (dev->flags & IFF_PROMISC) {
@@ -1567,11 +1536,11 @@ static void set_multicast_list(struct net_device *dev)
   mace_private *lp = netdev_priv(dev);
 
 #ifdef PCMCIA_DEBUG
-  if (pc_debug > 1) {
+  {
     static int old;
     if (dev->mc_count != old) {
       old = dev->mc_count;
-      DEBUG(0, "%s: setting Rx mode to %d addresses.\n",
+      pr_debug("%s: setting Rx mode to %d addresses.\n",
            dev->name, old);
     }
   }
index 94c9ad2746bc68cede7ea8ae5f4a42b5114d3095..cbe462ed221f7624bb46282208a5e0a21bb7cf32 100644 (file)
 
 static const char *if_names[] = { "auto", "10baseT", "10base2"};
 
-#ifdef PCMCIA_DEBUG
-static int pc_debug = PCMCIA_DEBUG;
-module_param(pc_debug, int, 0);
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
-static char *version =
-"pcnet_cs.c 1.153 2003/11/09 18:53:09 (David Hinds)";
-#else
-#define DEBUG(n, args...)
-#endif
 
 /*====================================================================*/
 
@@ -265,7 +256,7 @@ static int pcnet_probe(struct pcmcia_device *link)
     pcnet_dev_t *info;
     struct net_device *dev;
 
-    DEBUG(0, "pcnet_attach()\n");
+    dev_dbg(&link->dev, "pcnet_attach()\n");
 
     /* Create new ethernet device */
     dev = __alloc_ei_netdev(sizeof(pcnet_dev_t));
@@ -275,7 +266,6 @@ static int pcnet_probe(struct pcmcia_device *link)
     link->priv = dev;
 
     link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
-    link->irq.IRQInfo1 = IRQ_LEVEL_ID;
     link->conf.Attributes = CONF_ENABLE_IRQ;
     link->conf.IntType = INT_MEMORY_AND_IO;
 
@@ -297,7 +287,7 @@ static void pcnet_detach(struct pcmcia_device *link)
 {
        struct net_device *dev = link->priv;
 
-       DEBUG(0, "pcnet_detach(0x%p)\n", link);
+       dev_dbg(&link->dev, "pcnet_detach\n");
 
        if (link->dev_node)
                unregister_netdev(dev);
@@ -326,17 +316,15 @@ static hw_info_t *get_hwinfo(struct pcmcia_device *link)
     req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE;
     req.Base = 0; req.Size = 0;
     req.AccessSpeed = 0;
-    i = pcmcia_request_window(&link, &req, &link->win);
-    if (i != 0) {
-       cs_error(link, RequestWindow, i);
+    i = pcmcia_request_window(link, &req, &link->win);
+    if (i != 0)
        return NULL;
-    }
 
     virt = ioremap(req.Base, req.Size);
     mem.Page = 0;
     for (i = 0; i < NR_INFO; i++) {
        mem.CardOffset = hw_info[i].offset & ~(req.Size-1);
-       pcmcia_map_mem_page(link->win, &mem);
+       pcmcia_map_mem_page(link, link->win, &mem);
        base = &virt[hw_info[i].offset & (req.Size-1)];
        if ((readb(base+0) == hw_info[i].a0) &&
            (readb(base+2) == hw_info[i].a1) &&
@@ -348,9 +336,7 @@ static hw_info_t *get_hwinfo(struct pcmcia_device *link)
     }
 
     iounmap(virt);
-    j = pcmcia_release_window(link->win);
-    if (j != 0)
-       cs_error(link, ReleaseWindow, j);
+    j = pcmcia_release_window(link, link->win);
     return (i < NR_INFO) ? hw_info+i : NULL;
 } /* get_hwinfo */
 
@@ -495,9 +481,6 @@ static hw_info_t *get_hwired(struct pcmcia_device *link)
 
 ======================================================================*/
 
-#define CS_CHECK(fn, ret) \
-do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
-
 static int try_io_port(struct pcmcia_device *link)
 {
     int j, ret;
@@ -567,19 +550,19 @@ static int pcnet_config(struct pcmcia_device *link)
 {
     struct net_device *dev = link->priv;
     pcnet_dev_t *info = PRIV(dev);
-    int last_ret, last_fn, start_pg, stop_pg, cm_offset;
+    int ret, start_pg, stop_pg, cm_offset;
     int has_shmem = 0;
     hw_info_t *local_hw_info;
 
-    DEBUG(0, "pcnet_config(0x%p)\n", link);
+    dev_dbg(&link->dev, "pcnet_config\n");
 
-    last_ret = pcmcia_loop_config(link, pcnet_confcheck, &has_shmem);
-    if (last_ret) {
-       cs_error(link, RequestIO, last_ret);
+    ret = pcmcia_loop_config(link, pcnet_confcheck, &has_shmem);
+    if (ret)
        goto failed;
-    }
 
-    CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
+    ret = pcmcia_request_irq(link, &link->irq);
+    if (ret)
+           goto failed;
 
     if (link->io.NumPorts2 == 8) {
        link->conf.Attributes |= CONF_ENABLE_SPKR;
@@ -589,7 +572,9 @@ static int pcnet_config(struct pcmcia_device *link)
        (link->card_id == PRODID_IBM_HOME_AND_AWAY))
        link->conf.ConfigIndex |= 0x10;
 
-    CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
+    ret = pcmcia_request_configuration(link, &link->conf);
+    if (ret)
+           goto failed;
     dev->irq = link->irq.AssignedIRQ;
     dev->base_addr = link->io.BasePort1;
     if (info->flags & HAS_MISC_REG) {
@@ -660,7 +645,7 @@ static int pcnet_config(struct pcmcia_device *link)
        mii_phy_probe(dev);
 
     link->dev_node = &info->node;
-    SET_NETDEV_DEV(dev, &handle_to_dev(link));
+    SET_NETDEV_DEV(dev, &link->dev);
 
     if (register_netdev(dev) != 0) {
        printk(KERN_NOTICE "pcnet_cs: register_netdev() failed\n");
@@ -687,8 +672,6 @@ static int pcnet_config(struct pcmcia_device *link)
     printk(" hw_addr %pM\n", dev->dev_addr);
     return 0;
 
-cs_failed:
-    cs_error(link, last_fn, last_ret);
 failed:
     pcnet_release(link);
     return -ENODEV;
@@ -706,7 +689,7 @@ static void pcnet_release(struct pcmcia_device *link)
 {
        pcnet_dev_t *info = PRIV(link->priv);
 
-       DEBUG(0, "pcnet_release(0x%p)\n", link);
+       dev_dbg(&link->dev, "pcnet_release\n");
 
        if (info->flags & USE_SHMEM)
                iounmap(info->base);
@@ -960,7 +943,7 @@ static void mii_phy_probe(struct net_device *dev)
        phyid = tmp << 16;
        phyid |= mdio_read(mii_addr, i, MII_PHYID_REG2);
        phyid &= MII_PHYID_REV_MASK;
-       DEBUG(0, "%s: MII at %d is 0x%08x\n", dev->name, i, phyid);
+       pr_debug("%s: MII at %d is 0x%08x\n", dev->name, i, phyid);
        if (phyid == AM79C9XX_HOME_PHY) {
            info->pna_phy = i;
        } else if (phyid != AM79C9XX_ETH_PHY) {
@@ -976,7 +959,7 @@ static int pcnet_open(struct net_device *dev)
     struct pcmcia_device *link = info->p_dev;
     unsigned int nic_base = dev->base_addr;
 
-    DEBUG(2, "pcnet_open('%s')\n", dev->name);
+    dev_dbg(&link->dev, "pcnet_open('%s')\n", dev->name);
 
     if (!pcmcia_dev_present(link))
        return -ENODEV;
@@ -1008,7 +991,7 @@ static int pcnet_close(struct net_device *dev)
     pcnet_dev_t *info = PRIV(dev);
     struct pcmcia_device *link = info->p_dev;
 
-    DEBUG(2, "pcnet_close('%s')\n", dev->name);
+    dev_dbg(&link->dev, "pcnet_close('%s')\n", dev->name);
 
     ei_close(dev);
     free_irq(dev->irq, dev);
@@ -1251,10 +1234,8 @@ static void dma_block_input(struct net_device *dev, int count,
     int xfer_count = count;
     char *buf = skb->data;
 
-#ifdef PCMCIA_DEBUG
     if ((ei_debug > 4) && (count != 4))
-       printk(KERN_DEBUG "%s: [bi=%d]\n", dev->name, count+4);
-#endif
+       pr_debug("%s: [bi=%d]\n", dev->name, count+4);
     if (ei_status.dmaing) {
        printk(KERN_NOTICE "%s: DMAing conflict in dma_block_input."
               "[DMAstat:%1x][irqlock:%1x]\n",
@@ -1495,7 +1476,7 @@ static int setup_shmem_window(struct pcmcia_device *link, int start_pg,
     pcnet_dev_t *info = PRIV(dev);
     win_req_t req;
     memreq_t mem;
-    int i, window_size, offset, last_ret, last_fn;
+    int i, window_size, offset, ret;
 
     window_size = (stop_pg - start_pg) << 8;
     if (window_size > 32 * 1024)
@@ -1509,13 +1490,17 @@ static int setup_shmem_window(struct pcmcia_device *link, int start_pg,
     req.Attributes |= WIN_USE_WAIT;
     req.Base = 0; req.Size = window_size;
     req.AccessSpeed = mem_speed;
-    CS_CHECK(RequestWindow, pcmcia_request_window(&link, &req, &link->win));
+    ret = pcmcia_request_window(link, &req, &link->win);
+    if (ret)
+           goto failed;
 
     mem.CardOffset = (start_pg << 8) + cm_offset;
     offset = mem.CardOffset % window_size;
     mem.CardOffset -= offset;
     mem.Page = 0;
-    CS_CHECK(MapMemPage, pcmcia_map_mem_page(link->win, &mem));
+    ret = pcmcia_map_mem_page(link, link->win, &mem);
+    if (ret)
+           goto failed;
 
     /* Try scribbling on the buffer */
     info->base = ioremap(req.Base, window_size);
@@ -1527,8 +1512,8 @@ static int setup_shmem_window(struct pcmcia_device *link, int start_pg,
     pcnet_reset_8390(dev);
     if (i != (TX_PAGES<<8)) {
        iounmap(info->base);
-       pcmcia_release_window(link->win);
-       info->base = NULL; link->win = NULL;
+       pcmcia_release_window(link, link->win);
+       info->base = NULL; link->win = 0;
        goto failed;
     }
 
@@ -1549,8 +1534,6 @@ static int setup_shmem_window(struct pcmcia_device *link, int start_pg,
     info->flags |= USE_SHMEM;
     return 0;
 
-cs_failed:
-    cs_error(link, last_fn, last_ret);
 failed:
     return 1;
 }
@@ -1788,7 +1771,6 @@ static int __init init_pcnet_cs(void)
 
 static void __exit exit_pcnet_cs(void)
 {
-    DEBUG(0, "pcnet_cs: unloading\n");
     pcmcia_unregister_driver(&pcnet_driver);
 }
 
index 7bde2cd34c7e823882ba515ed88d7c6ed290a9cc..9e0da370912e42f4b78df2a315f4e06863e0c580 100644 (file)
@@ -79,14 +79,6 @@ MODULE_FIRMWARE(FIRMWARE_NAME);
 */
 INT_MODULE_PARM(if_port, 0);
 
-#ifdef PCMCIA_DEBUG
-INT_MODULE_PARM(pc_debug, PCMCIA_DEBUG);
-static const char *version =
-"smc91c92_cs.c 1.123 2006/11/09 Donald Becker, becker@scyld.com.\n";
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
-#else
-#define DEBUG(n, args...)
-#endif
 
 #define DRV_NAME       "smc91c92_cs"
 #define DRV_VERSION    "1.123"
@@ -126,12 +118,6 @@ struct smc_private {
     int                                rx_ovrn;
 };
 
-struct smc_cfg_mem {
-    tuple_t tuple;
-    cisparse_t parse;
-    u_char buf[255];
-};
-
 /* Special definitions for Megahertz multifunction cards */
 #define MEGAHERTZ_ISR          0x0380
 
@@ -329,7 +315,7 @@ static int smc91c92_probe(struct pcmcia_device *link)
     struct smc_private *smc;
     struct net_device *dev;
 
-    DEBUG(0, "smc91c92_attach()\n");
+    dev_dbg(&link->dev, "smc91c92_attach()\n");
 
     /* Create new ethernet device */
     dev = alloc_etherdev(sizeof(struct smc_private));
@@ -343,10 +329,8 @@ static int smc91c92_probe(struct pcmcia_device *link)
     link->io.NumPorts1 = 16;
     link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
     link->io.IOAddrLines = 4;
-    link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_HANDLE_PRESENT;
-    link->irq.IRQInfo1 = IRQ_LEVEL_ID;
+    link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
     link->irq.Handler = &smc_interrupt;
-    link->irq.Instance = dev;
     link->conf.Attributes = CONF_ENABLE_IRQ;
     link->conf.IntType = INT_MEMORY_AND_IO;
 
@@ -377,7 +361,7 @@ static void smc91c92_detach(struct pcmcia_device *link)
 {
     struct net_device *dev = link->priv;
 
-    DEBUG(0, "smc91c92_detach(0x%p)\n", link);
+    dev_dbg(&link->dev, "smc91c92_detach\n");
 
     if (link->dev_node)
        unregister_netdev(dev);
@@ -408,34 +392,7 @@ static int cvt_ascii_address(struct net_device *dev, char *s)
     return 0;
 }
 
-/*====================================================================*/
-
-static int first_tuple(struct pcmcia_device *handle, tuple_t *tuple,
-               cisparse_t *parse)
-{
-       int i;
-
-       i = pcmcia_get_first_tuple(handle, tuple);
-       if (i != 0)
-               return i;
-       i = pcmcia_get_tuple_data(handle, tuple);
-       if (i != 0)
-               return i;
-       return pcmcia_parse_tuple(tuple, parse);
-}
-
-static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple,
-               cisparse_t *parse)
-{
-       int i;
-
-       if ((i = pcmcia_get_next_tuple(handle, tuple)) != 0 ||
-                       (i = pcmcia_get_tuple_data(handle, tuple)) != 0)
-               return i;
-       return pcmcia_parse_tuple(tuple, parse);
-}
-
-/*======================================================================
+/*====================================================================
 
     Configuration stuff for Megahertz cards
 
@@ -490,19 +447,14 @@ static int mhz_mfc_config(struct pcmcia_device *link)
 {
     struct net_device *dev = link->priv;
     struct smc_private *smc = netdev_priv(dev);
-    struct smc_cfg_mem *cfg_mem;
     win_req_t req;
     memreq_t mem;
     int i;
 
-    cfg_mem = kmalloc(sizeof(struct smc_cfg_mem), GFP_KERNEL);
-    if (!cfg_mem)
-           return -ENOMEM;
-
     link->conf.Attributes |= CONF_ENABLE_SPKR;
     link->conf.Status = CCSR_AUDIO_ENA;
     link->irq.Attributes =
-       IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED|IRQ_HANDLE_PRESENT;
+       IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
     link->io.IOAddrLines = 16;
     link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
     link->io.NumPorts2 = 8;
@@ -510,91 +462,80 @@ static int mhz_mfc_config(struct pcmcia_device *link)
     /* The Megahertz combo cards have modem-like CIS entries, so
        we have to explicitly try a bunch of port combinations. */
     if (pcmcia_loop_config(link, mhz_mfc_config_check, NULL))
-       goto free_cfg_mem;
+           return -ENODEV;
+
     dev->base_addr = link->io.BasePort1;
 
     /* Allocate a memory window, for accessing the ISR */
     req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE;
     req.Base = req.Size = 0;
     req.AccessSpeed = 0;
-    i = pcmcia_request_window(&link, &req, &link->win);
+    i = pcmcia_request_window(link, &req, &link->win);
     if (i != 0)
-       goto free_cfg_mem;
+           return -ENODEV;
+
     smc->base = ioremap(req.Base, req.Size);
     mem.CardOffset = mem.Page = 0;
     if (smc->manfid == MANFID_MOTOROLA)
        mem.CardOffset = link->conf.ConfigBase;
-    i = pcmcia_map_mem_page(link->win, &mem);
+    i = pcmcia_map_mem_page(link, link->win, &mem);
 
     if ((i == 0)
        && (smc->manfid == MANFID_MEGAHERTZ)
        && (smc->cardid == PRODID_MEGAHERTZ_EM3288))
        mhz_3288_power(link);
 
-free_cfg_mem:
-    kfree(cfg_mem);
-    return -ENODEV;
+    return 0;
 }
 
-static int mhz_setup(struct pcmcia_device *link)
+static int pcmcia_get_versmac(struct pcmcia_device *p_dev,
+                             tuple_t *tuple,
+                             void *priv)
 {
-    struct net_device *dev = link->priv;
-    struct smc_cfg_mem *cfg_mem;
-    tuple_t *tuple;
-    cisparse_t *parse;
-    u_char *buf, *station_addr;
-    int rc;
+       struct net_device *dev = priv;
+       cisparse_t parse;
 
-    cfg_mem = kmalloc(sizeof(struct smc_cfg_mem), GFP_KERNEL);
-    if (!cfg_mem)
-       return -1;
+       if (pcmcia_parse_tuple(tuple, &parse))
+               return -EINVAL;
 
-    tuple = &cfg_mem->tuple;
-    parse = &cfg_mem->parse;
-    buf = cfg_mem->buf;
+       if ((parse.version_1.ns > 3) &&
+           (cvt_ascii_address(dev,
+                              (parse.version_1.str + parse.version_1.ofs[3]))))
+               return 0;
 
-    tuple->Attributes = tuple->TupleOffset = 0;
-    tuple->TupleData = (cisdata_t *)buf;
-    tuple->TupleDataMax = 255;
+       return -EINVAL;
+};
+
+static int mhz_setup(struct pcmcia_device *link)
+{
+    struct net_device *dev = link->priv;
+    size_t len;
+    u8 *buf;
+    int rc;
 
     /* Read the station address from the CIS.  It is stored as the last
        (fourth) string in the Version 1 Version/ID tuple. */
-    tuple->DesiredTuple = CISTPL_VERS_1;
-    if (first_tuple(link, tuple, parse) != 0) {
-       rc = -1;
-       goto free_cfg_mem;
-    }
+    if ((link->prod_id[3]) &&
+       (cvt_ascii_address(dev, link->prod_id[3]) == 0))
+           return 0;
+
+    /* Workarounds for broken cards start here. */
     /* Ugh -- the EM1144 card has two VERS_1 tuples!?! */
-    if (next_tuple(link, tuple, parse) != 0)
-       first_tuple(link, tuple, parse);
-    if (parse->version_1.ns > 3) {
-       station_addr = parse->version_1.str + parse->version_1.ofs[3];
-       if (cvt_ascii_address(dev, station_addr) == 0) {
-               rc = 0;
-               goto free_cfg_mem;
-       }
-    }
+    if (!pcmcia_loop_tuple(link, CISTPL_VERS_1, pcmcia_get_versmac, dev))
+           return 0;
 
     /* Another possibility: for the EM3288, in a special tuple */
-    tuple->DesiredTuple = 0x81;
-    if (pcmcia_get_first_tuple(link, tuple) != 0) {
-       rc = -1;
-       goto free_cfg_mem;
-    }
-    if (pcmcia_get_tuple_data(link, tuple) != 0) {
-       rc = -1;
-       goto free_cfg_mem;
-    }
-    buf[12] = '\0';
-    if (cvt_ascii_address(dev, buf) == 0) {
-       rc = 0;
-       goto free_cfg_mem;
-   }
     rc = -1;
-free_cfg_mem:
-   kfree(cfg_mem);
-   return rc;
-}
+    len = pcmcia_get_tuple(link, 0x81, &buf);
+    if (buf && len >= 13) {
+           buf[12] = '\0';
+           if (cvt_ascii_address(dev, buf))
+                   rc = 0;
+    }
+    kfree(buf);
+
+    return rc;
+};
 
 /*======================================================================
 
@@ -684,58 +625,21 @@ static int smc_config(struct pcmcia_device *link)
     return i;
 }
 
+
 static int smc_setup(struct pcmcia_device *link)
 {
     struct net_device *dev = link->priv;
-    struct smc_cfg_mem *cfg_mem;
-    tuple_t *tuple;
-    cisparse_t *parse;
-    cistpl_lan_node_id_t *node_id;
-    u_char *buf, *station_addr;
-    int i, rc;
-
-    cfg_mem = kmalloc(sizeof(struct smc_cfg_mem), GFP_KERNEL);
-    if (!cfg_mem)
-           return -ENOMEM;
-
-    tuple = &cfg_mem->tuple;
-    parse = &cfg_mem->parse;
-    buf = cfg_mem->buf;
-
-    tuple->Attributes = tuple->TupleOffset = 0;
-    tuple->TupleData = (cisdata_t *)buf;
-    tuple->TupleDataMax = 255;
 
     /* Check for a LAN function extension tuple */
-    tuple->DesiredTuple = CISTPL_FUNCE;
-    i = first_tuple(link, tuple, parse);
-    while (i == 0) {
-       if (parse->funce.type == CISTPL_FUNCE_LAN_NODE_ID)
-           break;
-       i = next_tuple(link, tuple, parse);
-    }
-    if (i == 0) {
-       node_id = (cistpl_lan_node_id_t *)parse->funce.data;
-       if (node_id->nb == 6) {
-           for (i = 0; i < 6; i++)
-               dev->dev_addr[i] = node_id->id[i];
-           rc = 0;
-           goto free_cfg_mem;
-       }
-    }
+    if (!pcmcia_get_mac_from_cis(link, dev))
+           return 0;
+
     /* Try the third string in the Version 1 Version/ID tuple. */
     if (link->prod_id[2]) {
-       station_addr = link->prod_id[2];
-       if (cvt_ascii_address(dev, station_addr) == 0) {
-               rc = 0;
-               goto free_cfg_mem;
-       }
+           if (cvt_ascii_address(dev, link->prod_id[2]) == 0)
+                   return 0;
     }
-
-    rc = -1;
-free_cfg_mem:
-    kfree(cfg_mem);
-    return rc;
+    return -1;
 }
 
 /*====================================================================*/
@@ -749,7 +653,7 @@ static int osi_config(struct pcmcia_device *link)
     link->conf.Attributes |= CONF_ENABLE_SPKR;
     link->conf.Status = CCSR_AUDIO_ENA;
     link->irq.Attributes =
-       IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED|IRQ_HANDLE_PRESENT;
+       IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
     link->io.NumPorts1 = 64;
     link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
     link->io.NumPorts2 = 8;
@@ -794,41 +698,31 @@ static int osi_load_firmware(struct pcmcia_device *link)
        return err;
 }
 
-static int osi_setup(struct pcmcia_device *link, u_short manfid, u_short cardid)
+static int pcmcia_osi_mac(struct pcmcia_device *p_dev,
+                         tuple_t *tuple,
+                         void *priv)
 {
-    struct net_device *dev = link->priv;
-    struct smc_cfg_mem *cfg_mem;
-    tuple_t *tuple;
-    u_char *buf;
-    int i, rc;
+       struct net_device *dev = priv;
+       int i;
 
-    cfg_mem = kmalloc(sizeof(struct smc_cfg_mem), GFP_KERNEL);
-    if (!cfg_mem)
-        return -1;
+       if (tuple->TupleDataLen < 8)
+               return -EINVAL;
+       if (tuple->TupleData[0] != 0x04)
+               return -EINVAL;
+       for (i = 0; i < 6; i++)
+               dev->dev_addr[i] = tuple->TupleData[i+2];
+       return 0;
+};
 
-    tuple = &cfg_mem->tuple;
-    buf = cfg_mem->buf;
 
-    tuple->Attributes = TUPLE_RETURN_COMMON;
-    tuple->TupleData = (cisdata_t *)buf;
-    tuple->TupleDataMax = 255;
-    tuple->TupleOffset = 0;
+static int osi_setup(struct pcmcia_device *link, u_short manfid, u_short cardid)
+{
+    struct net_device *dev = link->priv;
+    int rc;
 
     /* Read the station address from tuple 0x90, subtuple 0x04 */
-    tuple->DesiredTuple = 0x90;
-    i = pcmcia_get_first_tuple(link, tuple);
-    while (i == 0) {
-       i = pcmcia_get_tuple_data(link, tuple);
-       if ((i != 0) || (buf[0] == 0x04))
-           break;
-       i = pcmcia_get_next_tuple(link, tuple);
-    }
-    if (i != 0) {
-       rc = -1;
-       goto free_cfg_mem;
-    }
-    for (i = 0; i < 6; i++)
-       dev->dev_addr[i] = buf[i+2];
+    if (pcmcia_loop_tuple(link, 0x90, pcmcia_osi_mac, dev))
+           return -1;
 
     if (((manfid == MANFID_OSITECH) &&
         (cardid == PRODID_OSITECH_SEVEN)) ||
@@ -836,20 +730,17 @@ static int osi_setup(struct pcmcia_device *link, u_short manfid, u_short cardid)
         (cardid == PRODID_PSION_NET100))) {
        rc = osi_load_firmware(link);
        if (rc)
-               goto free_cfg_mem;
+               return rc;
     } else if (manfid == MANFID_OSITECH) {
        /* Make sure both functions are powered up */
        set_bits(0x300, link->io.BasePort1 + OSITECH_AUI_PWR);
        /* Now, turn on the interrupt for both card functions */
        set_bits(0x300, link->io.BasePort1 + OSITECH_RESET_ISR);
-       DEBUG(2, "AUI/PWR: %4.4x RESET/ISR: %4.4x\n",
+       dev_dbg(&link->dev, "AUI/PWR: %4.4x RESET/ISR: %4.4x\n",
              inw(link->io.BasePort1 + OSITECH_AUI_PWR),
              inw(link->io.BasePort1 + OSITECH_RESET_ISR));
     }
-    rc = 0;
-free_cfg_mem:
-   kfree(cfg_mem);
-   return rc;
+    return 0;
 }
 
 static int smc91c92_suspend(struct pcmcia_device *link)
@@ -959,12 +850,6 @@ static int check_sig(struct pcmcia_device *link)
 
 ======================================================================*/
 
-#define CS_EXIT_TEST(ret, svc, label)  \
-if (ret != 0) {                                \
-       cs_error(link, svc, ret);       \
-       goto label;                     \
-}
-
 static int smc91c92_config(struct pcmcia_device *link)
 {
     struct net_device *dev = link->priv;
@@ -974,7 +859,7 @@ static int smc91c92_config(struct pcmcia_device *link)
     unsigned int ioaddr;
     u_long mir;
 
-    DEBUG(0, "smc91c92_config(0x%p)\n", link);
+    dev_dbg(&link->dev, "smc91c92_config\n");
 
     smc->manfid = link->manf_id;
     smc->cardid = link->card_id;
@@ -990,12 +875,15 @@ static int smc91c92_config(struct pcmcia_device *link)
     } else {
        i = smc_config(link);
     }
-    CS_EXIT_TEST(i, RequestIO, config_failed);
+    if (i)
+           goto config_failed;
 
     i = pcmcia_request_irq(link, &link->irq);
-    CS_EXIT_TEST(i, RequestIRQ, config_failed);
+    if (i)
+           goto config_failed;
     i = pcmcia_request_configuration(link, &link->conf);
-    CS_EXIT_TEST(i, RequestConfiguration, config_failed);
+    if (i)
+           goto config_failed;
 
     if (smc->manfid == MANFID_MOTOROLA)
        mot_config(link);
@@ -1074,7 +962,7 @@ static int smc91c92_config(struct pcmcia_device *link)
     }
 
     link->dev_node = &smc->node;
-    SET_NETDEV_DEV(dev, &handle_to_dev(link));
+    SET_NETDEV_DEV(dev, &link->dev);
 
     if (register_netdev(dev) != 0) {
        printk(KERN_ERR "smc91c92_cs: register_netdev() failed\n");
@@ -1100,7 +988,7 @@ static int smc91c92_config(struct pcmcia_device *link)
 
     if (smc->cfg & CFG_MII_SELECT) {
        if (smc->mii_if.phy_id != -1) {
-           DEBUG(0, "  MII transceiver at index %d, status %x.\n",
+           dev_dbg(&link->dev, "  MII transceiver at index %d, status %x.\n",
                  smc->mii_if.phy_id, j);
        } else {
            printk(KERN_NOTICE "  No MII transceivers found!\n");
@@ -1110,7 +998,7 @@ static int smc91c92_config(struct pcmcia_device *link)
 
 config_undo:
     unregister_netdev(dev);
-config_failed:                 /* CS_EXIT_TEST() calls jump to here... */
+config_failed:
     smc91c92_release(link);
     return -ENODEV;
 } /* smc91c92_config */
@@ -1125,7 +1013,7 @@ config_failed:                    /* CS_EXIT_TEST() calls jump to here... */
 
 static void smc91c92_release(struct pcmcia_device *link)
 {
-       DEBUG(0, "smc91c92_release(0x%p)\n", link);
+       dev_dbg(&link->dev, "smc91c92_release\n");
        if (link->win) {
                struct net_device *dev = link->priv;
                struct smc_private *smc = netdev_priv(dev);
@@ -1222,10 +1110,10 @@ static int smc_open(struct net_device *dev)
     struct smc_private *smc = netdev_priv(dev);
     struct pcmcia_device *link = smc->p_dev;
 
-#ifdef PCMCIA_DEBUG
-    DEBUG(0, "%s: smc_open(%p), ID/Window %4.4x.\n",
+    dev_dbg(&link->dev, "%s: smc_open(%p), ID/Window %4.4x.\n",
          dev->name, dev, inw(dev->base_addr + BANK_SELECT));
-    if (pc_debug > 1) smc_dump(dev);
+#ifdef PCMCIA_DEBUG
+    smc_dump(dev);
 #endif
 
     /* Check that the PCMCIA card is still here. */
@@ -1260,7 +1148,7 @@ static int smc_close(struct net_device *dev)
     struct pcmcia_device *link = smc->p_dev;
     unsigned int ioaddr = dev->base_addr;
 
-    DEBUG(0, "%s: smc_close(), status %4.4x.\n",
+    dev_dbg(&link->dev, "%s: smc_close(), status %4.4x.\n",
          dev->name, inw(ioaddr + BANK_SELECT));
 
     netif_stop_queue(dev);
@@ -1327,7 +1215,7 @@ static void smc_hardware_send_packet(struct net_device * dev)
        u_char *buf = skb->data;
        u_int length = skb->len; /* The chip will pad to ethernet min. */
 
-       DEBUG(2, "%s: Trying to xmit packet of length %d.\n",
+       pr_debug("%s: Trying to xmit packet of length %d.\n",
              dev->name, length);
        
        /* send the packet length: +6 for status word, length, and ctl */
@@ -1382,7 +1270,7 @@ static netdev_tx_t smc_start_xmit(struct sk_buff *skb,
 
     netif_stop_queue(dev);
 
-    DEBUG(2, "%s: smc_start_xmit(length = %d) called,"
+    pr_debug("%s: smc_start_xmit(length = %d) called,"
          " status %4.4x.\n", dev->name, skb->len, inw(ioaddr + 2));
 
     if (smc->saved_skb) {
@@ -1429,7 +1317,7 @@ static netdev_tx_t smc_start_xmit(struct sk_buff *skb,
     }
 
     /* Otherwise defer until the Tx-space-allocated interrupt. */
-    DEBUG(2, "%s: memory allocation deferred.\n", dev->name);
+    pr_debug("%s: memory allocation deferred.\n", dev->name);
     outw((IM_ALLOC_INT << 8) | (ir & 0xff00), ioaddr + INTERRUPT);
     spin_unlock_irqrestore(&smc->lock, flags);
 
@@ -1494,7 +1382,7 @@ static void smc_eph_irq(struct net_device *dev)
 
     SMC_SELECT_BANK(0);
     ephs = inw(ioaddr + EPH);
-    DEBUG(2, "%s: Ethernet protocol handler interrupt, status"
+    pr_debug("%s: Ethernet protocol handler interrupt, status"
          " %4.4x.\n", dev->name, ephs);
     /* Could be a counter roll-over warning: update stats. */
     card_stats = inw(ioaddr + COUNTER);
@@ -1534,7 +1422,7 @@ static irqreturn_t smc_interrupt(int irq, void *dev_id)
 
     ioaddr = dev->base_addr;
 
-    DEBUG(3, "%s: SMC91c92 interrupt %d at %#x.\n", dev->name,
+    pr_debug("%s: SMC91c92 interrupt %d at %#x.\n", dev->name,
          irq, ioaddr);
 
     spin_lock(&smc->lock);
@@ -1543,7 +1431,7 @@ static irqreturn_t smc_interrupt(int irq, void *dev_id)
     if ((saved_bank & 0xff00) != 0x3300) {
        /* The device does not exist -- the card could be off-line, or
           maybe it has been ejected. */
-       DEBUG(1, "%s: SMC91c92 interrupt %d for non-existent"
+       pr_debug("%s: SMC91c92 interrupt %d for non-existent"
              "/ejected device.\n", dev->name, irq);
        handled = 0;
        goto irq_done;
@@ -1557,7 +1445,7 @@ static irqreturn_t smc_interrupt(int irq, void *dev_id)
 
     do { /* read the status flag, and mask it */
        status = inw(ioaddr + INTERRUPT) & 0xff;
-       DEBUG(3, "%s: Status is %#2.2x (mask %#2.2x).\n", dev->name,
+       pr_debug("%s: Status is %#2.2x (mask %#2.2x).\n", dev->name,
              status, mask);
        if ((status & mask) == 0) {
            if (bogus_cnt == INTR_WORK)
@@ -1602,7 +1490,7 @@ static irqreturn_t smc_interrupt(int irq, void *dev_id)
            smc_eph_irq(dev);
     } while (--bogus_cnt);
 
-    DEBUG(3, "  Restoring saved registers mask %2.2x bank %4.4x"
+    pr_debug("  Restoring saved registers mask %2.2x bank %4.4x"
          " pointer %4.4x.\n", mask, saved_bank, saved_pointer);
 
     /* restore state register */
@@ -1610,7 +1498,7 @@ static irqreturn_t smc_interrupt(int irq, void *dev_id)
     outw(saved_pointer, ioaddr + POINTER);
     SMC_SELECT_BANK(saved_bank);
 
-    DEBUG(3, "%s: Exiting interrupt IRQ%d.\n", dev->name, irq);
+    pr_debug("%s: Exiting interrupt IRQ%d.\n", dev->name, irq);
 
 irq_done:
 
@@ -1661,7 +1549,7 @@ static void smc_rx(struct net_device *dev)
     rx_status = inw(ioaddr + DATA_1);
     packet_length = inw(ioaddr + DATA_1) & 0x07ff;
 
-    DEBUG(2, "%s: Receive status %4.4x length %d.\n",
+    pr_debug("%s: Receive status %4.4x length %d.\n",
          dev->name, rx_status, packet_length);
 
     if (!(rx_status & RS_ERRORS)) {            
@@ -1672,7 +1560,7 @@ static void smc_rx(struct net_device *dev)
        skb = dev_alloc_skb(packet_length+2);
        
        if (skb == NULL) {
-           DEBUG(1, "%s: Low memory, packet dropped.\n", dev->name);
+           pr_debug("%s: Low memory, packet dropped.\n", dev->name);
            dev->stats.rx_dropped++;
            outw(MC_RELEASE, ioaddr + MMU_CMD);
            return;
@@ -1832,7 +1720,7 @@ static void smc_reset(struct net_device *dev)
     struct smc_private *smc = netdev_priv(dev);
     int i;
 
-    DEBUG(0, "%s: smc91c92 reset called.\n", dev->name);
+    pr_debug("%s: smc91c92 reset called.\n", dev->name);
 
     /* The first interaction must be a write to bring the chip out
        of sleep mode. */
@@ -2149,18 +2037,6 @@ static u32 smc_get_link(struct net_device *dev)
        return ret;
 }
 
-#ifdef PCMCIA_DEBUG
-static u32 smc_get_msglevel(struct net_device *dev)
-{
-       return pc_debug;
-}
-
-static void smc_set_msglevel(struct net_device *dev, u32 val)
-{
-       pc_debug = val;
-}
-#endif
-
 static int smc_nway_reset(struct net_device *dev)
 {
        struct smc_private *smc = netdev_priv(dev);
@@ -2184,10 +2060,6 @@ static const struct ethtool_ops ethtool_ops = {
        .get_settings = smc_get_settings,
        .set_settings = smc_set_settings,
        .get_link = smc_get_link,
-#ifdef PCMCIA_DEBUG
-       .get_msglevel = smc_get_msglevel,
-       .set_msglevel = smc_set_msglevel,
-#endif
        .nway_reset = smc_nway_reset,
 };
 
index cf842310253816a94bcd2e22bd59158fd94c6442..fe504b7f369f8294c13a56733ddd5d42a64e096a 100644 (file)
@@ -211,20 +211,6 @@ enum xirc_cmd {        /* Commands */
 
 static const char *if_names[] = { "Auto", "10BaseT", "10Base2", "AUI", "100BaseT" };
 
-/****************
- * All the PCMCIA modules use PCMCIA_DEBUG to control debugging.  If
- * you do not define PCMCIA_DEBUG at all, all the debug code will be
- * left out.  If you compile with PCMCIA_DEBUG=0, the debug code will
- * be present but disabled -- but it can then be enabled for specific
- * modules at load time with a 'pc_debug=#' option to insmod.
- */
-#ifdef PCMCIA_DEBUG
-static int pc_debug = PCMCIA_DEBUG;
-module_param(pc_debug, int, 0);
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KDBG_XIRC args)
-#else
-#define DEBUG(n, args...)
-#endif
 
 #define KDBG_XIRC KERN_DEBUG   "xirc2ps_cs: "
 #define KERR_XIRC KERN_ERR     "xirc2ps_cs: "
@@ -359,7 +345,7 @@ static void xirc_tx_timeout(struct net_device *dev);
 static void xirc2ps_tx_timeout_task(struct work_struct *work);
 static void set_addresses(struct net_device *dev);
 static void set_multicast_list(struct net_device *dev);
-static int set_card_type(struct pcmcia_device *link, const void *s);
+static int set_card_type(struct pcmcia_device *link);
 static int do_config(struct net_device *dev, struct ifmap *map);
 static int do_open(struct net_device *dev);
 static int do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
@@ -371,28 +357,6 @@ static void do_powerdown(struct net_device *dev);
 static int do_stop(struct net_device *dev);
 
 /*=============== Helper functions =========================*/
-static int
-first_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse)
-{
-       int err;
-
-       if ((err = pcmcia_get_first_tuple(handle, tuple)) == 0 &&
-                       (err = pcmcia_get_tuple_data(handle, tuple)) == 0)
-               err = pcmcia_parse_tuple(tuple, parse);
-       return err;
-}
-
-static int
-next_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse)
-{
-       int err;
-
-       if ((err = pcmcia_get_next_tuple(handle, tuple)) == 0 &&
-                       (err = pcmcia_get_tuple_data(handle, tuple)) == 0)
-               err = pcmcia_parse_tuple(tuple, parse);
-       return err;
-}
-
 #define SelectPage(pgnr)   outb((pgnr), ioaddr + XIRCREG_PR)
 #define GetByte(reg)      ((unsigned)inb(ioaddr + (reg)))
 #define GetWord(reg)      ((unsigned)inw(ioaddr + (reg)))
@@ -400,7 +364,7 @@ next_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse)
 #define PutWord(reg,value) outw((value), ioaddr+(reg))
 
 /*====== Functions used for debugging =================================*/
-#if defined(PCMCIA_DEBUG) && 0 /* reading regs may change system status */
+#if 0 /* reading regs may change system status */
 static void
 PrintRegisters(struct net_device *dev)
 {
@@ -432,7 +396,7 @@ PrintRegisters(struct net_device *dev)
        }
     }
 }
-#endif /* PCMCIA_DEBUG */
+#endif /* 0 */
 
 /*============== MII Management functions ===============*/
 
@@ -576,7 +540,7 @@ xirc2ps_probe(struct pcmcia_device *link)
     struct net_device *dev;
     local_info_t *local;
 
-    DEBUG(0, "attach()\n");
+    dev_dbg(&link->dev, "attach()\n");
 
     /* Allocate the device structure */
     dev = alloc_etherdev(sizeof(local_info_t));
@@ -592,7 +556,6 @@ xirc2ps_probe(struct pcmcia_device *link)
     link->conf.IntType = INT_MEMORY_AND_IO;
     link->conf.ConfigIndex = 1;
     link->irq.Handler = xirc2ps_interrupt;
-    link->irq.Instance = dev;
 
     /* Fill in card specific entries */
     dev->netdev_ops = &netdev_ops;
@@ -615,7 +578,7 @@ xirc2ps_detach(struct pcmcia_device *link)
 {
     struct net_device *dev = link->priv;
 
-    DEBUG(0, "detach(0x%p)\n", link);
+    dev_dbg(&link->dev, "detach\n");
 
     if (link->dev_node)
        unregister_netdev(dev);
@@ -644,17 +607,25 @@ xirc2ps_detach(struct pcmcia_device *link)
  *
  */
 static int
-set_card_type(struct pcmcia_device *link, const void *s)
+set_card_type(struct pcmcia_device *link)
 {
     struct net_device *dev = link->priv;
     local_info_t *local = netdev_priv(dev);
-  #ifdef PCMCIA_DEBUG
-    unsigned cisrev = ((const unsigned char *)s)[2];
-  #endif
-    unsigned mediaid= ((const unsigned char *)s)[3];
-    unsigned prodid = ((const unsigned char *)s)[4];
+    u8 *buf;
+    unsigned int cisrev, mediaid, prodid;
+    size_t len;
+
+    len = pcmcia_get_tuple(link, CISTPL_MANFID, &buf);
+    if (len < 5) {
+           dev_err(&link->dev, "invalid CIS -- sorry\n");
+           return 0;
+    }
 
-    DEBUG(0, "cisrev=%02x mediaid=%02x prodid=%02x\n",
+    cisrev = buf[2];
+    mediaid = buf[3];
+    prodid = buf[4];
+
+    dev_dbg(&link->dev, "cisrev=%02x mediaid=%02x prodid=%02x\n",
          cisrev, mediaid, prodid);
 
     local->mohawk = 0;
@@ -761,6 +732,26 @@ xirc2ps_config_check(struct pcmcia_device *p_dev,
 
 }
 
+
+static int pcmcia_get_mac_ce(struct pcmcia_device *p_dev,
+                            tuple_t *tuple,
+                            void *priv)
+{
+       struct net_device *dev = priv;
+       int i;
+
+       if (tuple->TupleDataLen != 13)
+               return -EINVAL;
+       if ((tuple->TupleData[0] != 2) || (tuple->TupleData[1] != 1) ||
+               (tuple->TupleData[2] != 6))
+               return -EINVAL;
+       /* another try  (James Lehmer's CE2 version 4.1)*/
+       for (i = 2; i < 6; i++)
+               dev->dev_addr[i] = tuple->TupleData[i+2];
+       return 0;
+};
+
+
 /****************
  * xirc2ps_config() is scheduled to run after a CARD_INSERTION event
  * is received, to configure the PCMCIA socket, and to make the
@@ -772,33 +763,21 @@ xirc2ps_config(struct pcmcia_device * link)
     struct net_device *dev = link->priv;
     local_info_t *local = netdev_priv(dev);
     unsigned int ioaddr;
-    tuple_t tuple;
-    cisparse_t parse;
-    int err, i;
-    u_char buf[64];
-    cistpl_lan_node_id_t *node_id = (cistpl_lan_node_id_t*)parse.funce.data;
+    int err;
+    u8 *buf;
+    size_t len;
 
     local->dingo_ccr = NULL;
 
-    DEBUG(0, "config(0x%p)\n", link);
-
-    /*
-     * This reads the card's CONFIG tuple to find its configuration
-     * registers.
-     */
-    tuple.Attributes = 0;
-    tuple.TupleData = buf;
-    tuple.TupleDataMax = 64;
-    tuple.TupleOffset = 0;
+    dev_dbg(&link->dev, "config\n");
 
     /* Is this a valid card */
-    tuple.DesiredTuple = CISTPL_MANFID;
-    if ((err=first_tuple(link, &tuple, &parse))) {
+    if (link->has_manf_id == 0) {
        printk(KNOT_XIRC "manfid not found in CIS\n");
        goto failure;
     }
 
-    switch(parse.manfid.manf) {
+    switch (link->manf_id) {
       case MANFID_XIRCOM:
        local->manf_str = "Xircom";
        break;
@@ -817,65 +796,44 @@ xirc2ps_config(struct pcmcia_device * link)
        break;
       default:
        printk(KNOT_XIRC "Unknown Card Manufacturer ID: 0x%04x\n",
-              (unsigned)parse.manfid.manf);
+              (unsigned)link->manf_id);
        goto failure;
     }
-    DEBUG(0, "found %s card\n", local->manf_str);
+    dev_dbg(&link->dev, "found %s card\n", local->manf_str);
 
-    if (!set_card_type(link, buf)) {
+    if (!set_card_type(link)) {
        printk(KNOT_XIRC "this card is not supported\n");
        goto failure;
     }
 
     /* get the ethernet address from the CIS */
-    tuple.DesiredTuple = CISTPL_FUNCE;
-    for (err = first_tuple(link, &tuple, &parse); !err;
-                            err = next_tuple(link, &tuple, &parse)) {
-       /* Once I saw two CISTPL_FUNCE_LAN_NODE_ID entries:
-        * the first one with a length of zero the second correct -
-        * so I skip all entries with length 0 */
-       if (parse.funce.type == CISTPL_FUNCE_LAN_NODE_ID
-           && ((cistpl_lan_node_id_t *)parse.funce.data)->nb)
-           break;
-    }
-    if (err) { /* not found: try to get the node-id from tuple 0x89 */
-       tuple.DesiredTuple = 0x89;  /* data layout looks like tuple 0x22 */
-       if ((err = pcmcia_get_first_tuple(link, &tuple)) == 0 &&
-               (err = pcmcia_get_tuple_data(link, &tuple)) == 0) {
-           if (tuple.TupleDataLen == 8 && *buf == CISTPL_FUNCE_LAN_NODE_ID)
-               memcpy(&parse, buf, 8);
-           else
-               err = -1;
-       }
-    }
-    if (err) { /* another try  (James Lehmer's CE2 version 4.1)*/
-       tuple.DesiredTuple = CISTPL_FUNCE;
-       for (err = first_tuple(link, &tuple, &parse); !err;
-                                err = next_tuple(link, &tuple, &parse)) {
-           if (parse.funce.type == 0x02 && parse.funce.data[0] == 1
-               && parse.funce.data[1] == 6 && tuple.TupleDataLen == 13) {
-               buf[1] = 4;
-               memcpy(&parse, buf+1, 8);
-               break;
+    err = pcmcia_get_mac_from_cis(link, dev);
+
+    /* not found: try to get the node-id from tuple 0x89 */
+    if (err) {
+           len = pcmcia_get_tuple(link, 0x89, &buf);
+           /* data layout looks like tuple 0x22 */
+           if (buf && len == 8) {
+                   if (*buf == CISTPL_FUNCE_LAN_NODE_ID) {
+                           int i;
+                           for (i = 2; i < 6; i++)
+                                   dev->dev_addr[i] = buf[i+2];
+                   } else
+                           err = -1;
            }
-       }
+           kfree(buf);
     }
+
+    if (err)
+       err = pcmcia_loop_tuple(link, CISTPL_FUNCE, pcmcia_get_mac_ce, dev);
+
     if (err) {
        printk(KNOT_XIRC "node-id not found in CIS\n");
        goto failure;
     }
-    node_id = (cistpl_lan_node_id_t *)parse.funce.data;
-    if (node_id->nb != 6) {
-       printk(KNOT_XIRC "malformed node-id in CIS\n");
-       goto failure;
-    }
-    for (i=0; i < 6; i++)
-       dev->dev_addr[i] = node_id->id[i];
 
     link->io.IOAddrLines =10;
     link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
-    link->irq.Attributes = IRQ_HANDLE_PRESENT;
-    link->irq.IRQInfo1 = IRQ_LEVEL_ID;
     if (local->modem) {
        int pass;
 
@@ -916,10 +874,8 @@ xirc2ps_config(struct pcmcia_device * link)
                goto port_found;
        }
        link->io.BasePort1 = 0; /* let CS decide */
-       if ((err=pcmcia_request_io(link, &link->io))) {
-           cs_error(link, RequestIO, err);
+       if ((err=pcmcia_request_io(link, &link->io)))
            goto config_error;
-       }
     }
   port_found:
     if (err)
@@ -929,19 +885,15 @@ xirc2ps_config(struct pcmcia_device * link)
      * Now allocate an interrupt line. Note that this does not
      * actually assign a handler to the interrupt.
      */
-    if ((err=pcmcia_request_irq(link, &link->irq))) {
-       cs_error(link, RequestIRQ, err);
+    if ((err=pcmcia_request_irq(link, &link->irq)))
        goto config_error;
-    }
 
     /****************
      * This actually configures the PCMCIA socket -- setting up
      * the I/O windows and the interrupt mapping.
      */
-    if ((err=pcmcia_request_configuration(link, &link->conf))) {
-       cs_error(link, RequestConfiguration, err);
+    if ((err=pcmcia_request_configuration(link, &link->conf)))
        goto config_error;
-    }
 
     if (local->dingo) {
        conf_reg_t reg;
@@ -956,17 +908,13 @@ xirc2ps_config(struct pcmcia_device * link)
        reg.Action = CS_WRITE;
        reg.Offset = CISREG_IOBASE_0;
        reg.Value = link->io.BasePort2 & 0xff;
-       if ((err = pcmcia_access_configuration_register(link, &reg))) {
-           cs_error(link, AccessConfigurationRegister, err);
+       if ((err = pcmcia_access_configuration_register(link, &reg)))
            goto config_error;
-       }
        reg.Action = CS_WRITE;
        reg.Offset = CISREG_IOBASE_1;
        reg.Value = (link->io.BasePort2 >> 8) & 0xff;
-       if ((err = pcmcia_access_configuration_register(link, &reg))) {
-           cs_error(link, AccessConfigurationRegister, err);
+       if ((err = pcmcia_access_configuration_register(link, &reg)))
            goto config_error;
-       }
 
        /* There is no config entry for the Ethernet part which
         * is at 0x0800. So we allocate a window into the attribute
@@ -975,17 +923,14 @@ xirc2ps_config(struct pcmcia_device * link)
        req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE;
        req.Base = req.Size = 0;
        req.AccessSpeed = 0;
-       if ((err = pcmcia_request_window(&link, &req, &link->win))) {
-           cs_error(link, RequestWindow, err);
+       if ((err = pcmcia_request_window(link, &req, &link->win)))
            goto config_error;
-       }
+
        local->dingo_ccr = ioremap(req.Base,0x1000) + 0x0800;
        mem.CardOffset = 0x0;
        mem.Page = 0;
-       if ((err = pcmcia_map_mem_page(link->win, &mem))) {
-           cs_error(link, MapMemPage, err);
+       if ((err = pcmcia_map_mem_page(link, link->win, &mem)))
            goto config_error;
-       }
 
        /* Setup the CCRs; there are no infos in the CIS about the Ethernet
         * part.
@@ -1044,7 +989,7 @@ xirc2ps_config(struct pcmcia_device * link)
        do_reset(dev, 1); /* a kludge to make the cem56 work */
 
     link->dev_node = &local->node;
-    SET_NETDEV_DEV(dev, &handle_to_dev(link));
+    SET_NETDEV_DEV(dev, &link->dev);
 
     if ((err=register_netdev(dev))) {
        printk(KNOT_XIRC "register_netdev() failed\n");
@@ -1077,7 +1022,7 @@ xirc2ps_config(struct pcmcia_device * link)
 static void
 xirc2ps_release(struct pcmcia_device *link)
 {
-       DEBUG(0, "release(0x%p)\n", link);
+       dev_dbg(&link->dev, "release\n");
 
        if (link->win) {
                struct net_device *dev = link->priv;
@@ -1144,7 +1089,7 @@ xirc2ps_interrupt(int irq, void *dev_id)
        PutByte(XIRCREG_CR, 0);
     }
 
-    DEBUG(6, "%s: interrupt %d at %#x.\n", dev->name, irq, ioaddr);
+    pr_debug("%s: interrupt %d at %#x.\n", dev->name, irq, ioaddr);
 
     saved_page = GetByte(XIRCREG_PR);
     /* Read the ISR to see whats the cause for the interrupt.
@@ -1154,7 +1099,7 @@ xirc2ps_interrupt(int irq, void *dev_id)
     bytes_rcvd = 0;
   loop_entry:
     if (int_status == 0xff) { /* card may be ejected */
-       DEBUG(3, "%s: interrupt %d for dead card\n", dev->name, irq);
+       pr_debug("%s: interrupt %d for dead card\n", dev->name, irq);
        goto leave;
     }
     eth_status = GetByte(XIRCREG_ESR);
@@ -1167,7 +1112,7 @@ xirc2ps_interrupt(int irq, void *dev_id)
     PutByte(XIRCREG40_TXST0, 0);
     PutByte(XIRCREG40_TXST1, 0);
 
-    DEBUG(3, "%s: ISR=%#2.2x ESR=%#2.2x RSR=%#2.2x TSR=%#4.4x\n",
+    pr_debug("%s: ISR=%#2.2x ESR=%#2.2x RSR=%#2.2x TSR=%#4.4x\n",
          dev->name, int_status, eth_status, rx_status, tx_status);
 
     /***** receive section ******/
@@ -1178,14 +1123,14 @@ xirc2ps_interrupt(int irq, void *dev_id)
            /* too many bytes received during this int, drop the rest of the
             * packets */
            dev->stats.rx_dropped++;
-           DEBUG(2, "%s: RX drop, too much done\n", dev->name);
+           pr_debug("%s: RX drop, too much done\n", dev->name);
        } else if (rsr & PktRxOk) {
            struct sk_buff *skb;
 
            pktlen = GetWord(XIRCREG0_RBC);
            bytes_rcvd += pktlen;
 
-           DEBUG(5, "rsr=%#02x packet_length=%u\n", rsr, pktlen);
+           pr_debug("rsr=%#02x packet_length=%u\n", rsr, pktlen);
 
            skb = dev_alloc_skb(pktlen+3); /* 1 extra so we can use insw */
            if (!skb) {
@@ -1253,19 +1198,19 @@ xirc2ps_interrupt(int irq, void *dev_id)
                    dev->stats.multicast++;
            }
        } else { /* bad packet */
-           DEBUG(5, "rsr=%#02x\n", rsr);
+           pr_debug("rsr=%#02x\n", rsr);
        }
        if (rsr & PktTooLong) {
            dev->stats.rx_frame_errors++;
-           DEBUG(3, "%s: Packet too long\n", dev->name);
+           pr_debug("%s: Packet too long\n", dev->name);
        }
        if (rsr & CRCErr) {
            dev->stats.rx_crc_errors++;
-           DEBUG(3, "%s: CRC error\n", dev->name);
+           pr_debug("%s: CRC error\n", dev->name);
        }
        if (rsr & AlignErr) {
            dev->stats.rx_fifo_errors++; /* okay ? */
-           DEBUG(3, "%s: Alignment error\n", dev->name);
+           pr_debug("%s: Alignment error\n", dev->name);
        }
 
        /* clear the received/dropped/error packet */
@@ -1277,7 +1222,7 @@ xirc2ps_interrupt(int irq, void *dev_id)
     if (rx_status & 0x10) { /* Receive overrun */
        dev->stats.rx_over_errors++;
        PutByte(XIRCREG_CR, ClearRxOvrun);
-       DEBUG(3, "receive overrun cleared\n");
+       pr_debug("receive overrun cleared\n");
     }
 
     /***** transmit section ******/
@@ -1290,13 +1235,13 @@ xirc2ps_interrupt(int irq, void *dev_id)
        if (nn < n) /* rollover */
            dev->stats.tx_packets += 256 - n;
        else if (n == nn) { /* happens sometimes - don't know why */
-           DEBUG(0, "PTR not changed?\n");
+           pr_debug("PTR not changed?\n");
        } else
            dev->stats.tx_packets += lp->last_ptr_value - n;
        netif_wake_queue(dev);
     }
     if (tx_status & 0x0002) {  /* Execessive collissions */
-       DEBUG(0, "tx restarted due to execssive collissions\n");
+       pr_debug("tx restarted due to execssive collissions\n");
        PutByte(XIRCREG_CR, RestartTx);  /* restart transmitter process */
     }
     if (tx_status & 0x0040)
@@ -1315,14 +1260,14 @@ xirc2ps_interrupt(int irq, void *dev_id)
                maxrx_bytes = 2000;
            else if (maxrx_bytes > 22000)
                maxrx_bytes = 22000;
-           DEBUG(1, "set maxrx=%u (rcvd=%u ticks=%lu)\n",
+           pr_debug("set maxrx=%u (rcvd=%u ticks=%lu)\n",
                  maxrx_bytes, bytes_rcvd, duration);
        } else if (!duration && maxrx_bytes < 22000) {
            /* now much faster */
            maxrx_bytes += 2000;
            if (maxrx_bytes > 22000)
                maxrx_bytes = 22000;
-           DEBUG(1, "set maxrx=%u\n", maxrx_bytes);
+           pr_debug("set maxrx=%u\n", maxrx_bytes);
        }
     }
 
@@ -1372,7 +1317,7 @@ do_start_xmit(struct sk_buff *skb, struct net_device *dev)
     unsigned freespace;
     unsigned pktlen = skb->len;
 
-    DEBUG(1, "do_start_xmit(skb=%p, dev=%p) len=%u\n",
+    pr_debug("do_start_xmit(skb=%p, dev=%p) len=%u\n",
          skb, dev, pktlen);
 
 
@@ -1398,7 +1343,7 @@ do_start_xmit(struct sk_buff *skb, struct net_device *dev)
     freespace &= 0x7fff;
     /* TRS doesn't work - (indeed it is eliminated with sil-rev 1) */
     okay = pktlen +2 < freespace;
-    DEBUG(2 + (okay ? 2 : 0), "%s: avail. tx space=%u%s\n",
+    pr_debug("%s: avail. tx space=%u%s\n",
          dev->name, freespace, okay ? " (okay)":" (not enough)");
     if (!okay) { /* not enough space */
        return NETDEV_TX_BUSY;  /* upper layer may decide to requeue this packet */
@@ -1500,7 +1445,7 @@ do_config(struct net_device *dev, struct ifmap *map)
 {
     local_info_t *local = netdev_priv(dev);
 
-    DEBUG(0, "do_config(%p)\n", dev);
+    pr_debug("do_config(%p)\n", dev);
     if (map->port != 255 && map->port != dev->if_port) {
        if (map->port > 4)
            return -EINVAL;
@@ -1527,7 +1472,7 @@ do_open(struct net_device *dev)
     local_info_t *lp = netdev_priv(dev);
     struct pcmcia_device *link = lp->p_dev;
 
-    DEBUG(0, "do_open(%p)\n", dev);
+    dev_dbg(&link->dev, "do_open(%p)\n", dev);
 
     /* Check that the PCMCIA card is still here. */
     /* Physical device present signature. */
@@ -1561,7 +1506,7 @@ do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
     unsigned int ioaddr = dev->base_addr;
     struct mii_ioctl_data *data = if_mii(rq);
 
-    DEBUG(1, "%s: ioctl(%-.6s, %#04x) %04x %04x %04x %04x\n",
+    pr_debug("%s: ioctl(%-.6s, %#04x) %04x %04x %04x %04x\n",
          dev->name, rq->ifr_ifrn.ifrn_name, cmd,
          data->phy_id, data->reg_num, data->val_in, data->val_out);
 
@@ -1610,7 +1555,7 @@ do_reset(struct net_device *dev, int full)
     unsigned int ioaddr = dev->base_addr;
     unsigned value;
 
-    DEBUG(0, "%s: do_reset(%p,%d)\n", dev? dev->name:"eth?", dev, full);
+    pr_debug("%s: do_reset(%p,%d)\n", dev? dev->name:"eth?", dev, full);
 
     hardreset(dev);
     PutByte(XIRCREG_CR, SoftReset); /* set */
@@ -1648,8 +1593,8 @@ do_reset(struct net_device *dev, int full)
     }
     msleep(40);                             /* wait 40 msec to let it complete */
 
-  #ifdef PCMCIA_DEBUG
-    if (pc_debug) {
+  #if 0
+    {
        SelectPage(0);
        value = GetByte(XIRCREG_ESR);    /* read the ESR */
        printk(KERN_DEBUG "%s: ESR is: %#02x\n", dev->name, value);
@@ -1666,7 +1611,7 @@ do_reset(struct net_device *dev, int full)
        value |= DisableLinkPulse;
     PutByte(XIRCREG1_ECR, value);
   #endif
-    DEBUG(0, "%s: ECR is: %#02x\n", dev->name, value);
+    pr_debug("%s: ECR is: %#02x\n", dev->name, value);
 
     SelectPage(0x42);
     PutByte(XIRCREG42_SWC0, 0x20); /* disable source insertion */
@@ -1844,7 +1789,7 @@ do_powerdown(struct net_device *dev)
 
     unsigned int ioaddr = dev->base_addr;
 
-    DEBUG(0, "do_powerdown(%p)\n", dev);
+    pr_debug("do_powerdown(%p)\n", dev);
 
     SelectPage(4);
     PutByte(XIRCREG4_GPR1, 0);      /* clear bit 0: power down */
@@ -1858,7 +1803,7 @@ do_stop(struct net_device *dev)
     local_info_t *lp = netdev_priv(dev);
     struct pcmcia_device *link = lp->p_dev;
 
-    DEBUG(0, "do_stop(%p)\n", dev);
+    dev_dbg(&link->dev, "do_stop(%p)\n", dev);
 
     if (!link)
        return -ENODEV;
index 8659d341e7696fcfe8df1b55318db5957181d013..35897134a5dd34c210e72229136e50c7a44a0040 100644 (file)
@@ -139,7 +139,7 @@ out:
        return NULL;
 }
 
-static void __devinit mdio_gpio_bus_deinit(struct device *dev)
+static void mdio_gpio_bus_deinit(struct device *dev)
 {
        struct mii_bus *bus = dev_get_drvdata(dev);
        struct mdio_gpio_info *bitbang = bus->priv;
index 9bf2a6be90319b2cd9249c3acfbaf2a78c56d79f..965adb6174c33a4b65223fabd7372f3da4781b35 100644 (file)
@@ -1944,8 +1944,15 @@ ppp_receive_mp_frame(struct ppp *ppp, struct sk_buff *skb, struct channel *pch)
        }
 
        /* Pull completed packets off the queue and receive them. */
-       while ((skb = ppp_mp_reconstruct(ppp)))
-               ppp_receive_nonmp_frame(ppp, skb);
+       while ((skb = ppp_mp_reconstruct(ppp))) {
+               if (pskb_may_pull(skb, 2))
+                       ppp_receive_nonmp_frame(ppp, skb);
+               else {
+                       ++ppp->dev->stats.rx_length_errors;
+                       kfree_skb(skb);
+                       ppp_receive_error(ppp);
+               }
+       }
 
        return;
 
index 7dfcb58b0eb42d807f401b69b37499b059c8ef08..8b14c6eda7c3379e67eda5fac94960e0e538b46b 100644 (file)
@@ -1085,7 +1085,7 @@ static int __devinit r6040_init_one(struct pci_dev *pdev,
        int bar = 0;
        u16 *adrp;
 
-       printk(KERN_INFO "%s\n", version);
+       printk("%s\n", version);
 
        err = pci_enable_device(pdev);
        if (err)
index fa49356784883049d4487f95bf0b0fa1db8b3cd7..0fe2fc90f207ebdf74d01620b50781fb2d556882 100644 (file)
@@ -3235,6 +3235,10 @@ static void __devexit rtl8169_remove_one(struct pci_dev *pdev)
        flush_scheduled_work();
 
        unregister_netdev(dev);
+
+       /* restore original MAC address */
+       rtl_rar_set(tp, dev->perm_addr);
+
        rtl_disable_msi(pdev, tp);
        rtl8169_release_board(pdev, dev, tp->mmio_addr);
        pci_set_drvdata(pdev, NULL);
@@ -3243,9 +3247,9 @@ static void __devexit rtl8169_remove_one(struct pci_dev *pdev)
 static void rtl8169_set_rxbufsize(struct rtl8169_private *tp,
                                  struct net_device *dev)
 {
-       unsigned int mtu = dev->mtu;
+       unsigned int max_frame = dev->mtu + VLAN_ETH_HLEN + ETH_FCS_LEN;
 
-       tp->rx_buf_sz = (mtu > RX_BUF_SIZE) ? mtu + ETH_HLEN + 8 : RX_BUF_SIZE;
+       tp->rx_buf_sz = (max_frame > RX_BUF_SIZE) ? max_frame : RX_BUF_SIZE;
 }
 
 static int rtl8169_open(struct net_device *dev)
@@ -4881,6 +4885,9 @@ static void rtl_shutdown(struct pci_dev *pdev)
 
        rtl8169_net_suspend(dev);
 
+       /* restore original MAC address */
+       rtl_rar_set(tp, dev->perm_addr);
+
        spin_lock_irq(&tp->lock);
 
        rtl8169_asic_down(ioaddr);
index ddccf5fa56b63b998d2344e6e67cf6e7fd4977e4..0dd7839322bc6044d8d21738978955dc1a752cf6 100644 (file)
@@ -3494,6 +3494,7 @@ static void s2io_reset(struct s2io_nic *sp)
 
                /* Restore the PCI state saved during initialization. */
                pci_restore_state(sp->pdev);
+               pci_save_state(sp->pdev);
                pci_read_config_word(sp->pdev, 0x2, &val16);
                if (check_pci_device_id(val16) != (u16)PCI_ANY_ID)
                        break;
index 05c91ee6921e8a2082ed605db93f3ddb92581b27..f12206bdbb75db7e0ea4d051f1130d2960c66767 100644 (file)
@@ -2283,7 +2283,7 @@ static int __devinit smc_drv_probe(struct platform_device *pdev)
 
        ndev->irq = ires->start;
 
-       if (ires->flags & IRQF_TRIGGER_MASK)
+       if (irq_flags == -1 || ires->flags & IRQF_TRIGGER_MASK)
                irq_flags = ires->flags & IRQF_TRIGGER_MASK;
 
        ret = smc_request_attrib(pdev, ndev);
index ccdd196f5297952f993291819e1d65b5526402b0..f9cdcbcb77d4989efe930f1014a9c32128081216 100644 (file)
@@ -986,7 +986,7 @@ static int smsc911x_poll(struct napi_struct *napi, int budget)
        struct net_device *dev = pdata->dev;
        int npackets = 0;
 
-       while (likely(netif_running(dev)) && (npackets < budget)) {
+       while (npackets < budget) {
                unsigned int pktlength;
                unsigned int pktwords;
                struct sk_buff *skb;
index b4909a2dec66bfb4e9835cf0223654cafcebc347..0f7909276237260593e03263dfbd450884794923 100644 (file)
@@ -252,6 +252,9 @@ static int smsc9420_ethtool_get_settings(struct net_device *dev,
 {
        struct smsc9420_pdata *pd = netdev_priv(dev);
 
+       if (!pd->phy_dev)
+               return -ENODEV;
+
        cmd->maxtxpkt = 1;
        cmd->maxrxpkt = 1;
        return phy_ethtool_gset(pd->phy_dev, cmd);
@@ -262,6 +265,9 @@ static int smsc9420_ethtool_set_settings(struct net_device *dev,
 {
        struct smsc9420_pdata *pd = netdev_priv(dev);
 
+       if (!pd->phy_dev)
+               return -ENODEV;
+
        return phy_ethtool_sset(pd->phy_dev, cmd);
 }
 
@@ -290,6 +296,10 @@ static void smsc9420_ethtool_set_msglevel(struct net_device *netdev, u32 data)
 static int smsc9420_ethtool_nway_reset(struct net_device *netdev)
 {
        struct smsc9420_pdata *pd = netdev_priv(netdev);
+
+       if (!pd->phy_dev)
+               return -ENODEV;
+
        return phy_start_aneg(pd->phy_dev);
 }
 
@@ -312,6 +322,10 @@ smsc9420_ethtool_getregs(struct net_device *dev, struct ethtool_regs *regs,
        for (i = 0; i < 0x100; i += (sizeof(u32)))
                data[j++] = smsc9420_reg_read(pd, i);
 
+       // cannot read phy registers if the net device is down
+       if (!phy_dev)
+               return;
+
        for (i = 0; i <= 31; i++)
                data[j++] = smsc9420_mii_read(phy_dev->bus, phy_dev->addr, i);
 }
index c2f14dc9ba289df6839fad9e9e7eec98c395cf21..9542995ba6674a0ce309001ca7208ab218027214 100644 (file)
@@ -416,13 +416,8 @@ static void init_dma_desc_rings(struct net_device *dev)
        unsigned int txsize = priv->dma_tx_size;
        unsigned int rxsize = priv->dma_rx_size;
        unsigned int bfsize = priv->dma_buf_sz;
-       int buff2_needed = 0;
-       int dis_ic = 0;
+       int buff2_needed = 0, dis_ic = 0;
 
-#ifdef CONFIG_STMMAC_TIMER
-       /* Using Timers disable interrupts on completion for the reception */
-       dis_ic = 1;
-#endif
        /* Set the Buffer size according to the MTU;
         * indeed, in case of jumbo we need to bump-up the buffer sizes.
         */
@@ -437,6 +432,11 @@ static void init_dma_desc_rings(struct net_device *dev)
        else
                bfsize = DMA_BUFFER_SIZE;
 
+#ifdef CONFIG_STMMAC_TIMER
+       /* Disable interrupts on completion for the reception if timer is on */
+       if (likely(priv->tm->enable))
+               dis_ic = 1;
+#endif
        /* If the MTU exceeds 8k so use the second buffer in the chain */
        if (bfsize >= BUF_SIZE_8KiB)
                buff2_needed = 1;
@@ -809,20 +809,22 @@ static void stmmac_tx(struct stmmac_priv *priv)
 
 static inline void stmmac_enable_irq(struct stmmac_priv *priv)
 {
-#ifndef CONFIG_STMMAC_TIMER
-       writel(DMA_INTR_DEFAULT_MASK, priv->dev->base_addr + DMA_INTR_ENA);
-#else
-       priv->tm->timer_start(tmrate);
+#ifdef CONFIG_STMMAC_TIMER
+       if (likely(priv->tm->enable))
+               priv->tm->timer_start(tmrate);
+       else
 #endif
+       writel(DMA_INTR_DEFAULT_MASK, priv->dev->base_addr + DMA_INTR_ENA);
 }
 
 static inline void stmmac_disable_irq(struct stmmac_priv *priv)
 {
-#ifndef CONFIG_STMMAC_TIMER
-       writel(0, priv->dev->base_addr + DMA_INTR_ENA);
-#else
-       priv->tm->timer_stop();
+#ifdef CONFIG_STMMAC_TIMER
+       if (likely(priv->tm->enable))
+               priv->tm->timer_stop();
+       else
 #endif
+       writel(0, priv->dev->base_addr + DMA_INTR_ENA);
 }
 
 static int stmmac_has_work(struct stmmac_priv *priv)
@@ -1031,22 +1033,23 @@ static int stmmac_open(struct net_device *dev)
        }
 
 #ifdef CONFIG_STMMAC_TIMER
-       priv->tm = kmalloc(sizeof(struct stmmac_timer *), GFP_KERNEL);
+       priv->tm = kzalloc(sizeof(struct stmmac_timer *), GFP_KERNEL);
        if (unlikely(priv->tm == NULL)) {
                pr_err("%s: ERROR: timer memory alloc failed \n", __func__);
                return -ENOMEM;
        }
        priv->tm->freq = tmrate;
 
-       /* Test if the HW timer can be actually used.
-        * In case of failure continue with no timer. */
+       /* Test if the external timer can be actually used.
+        * In case of failure continue without timer. */
        if (unlikely((stmmac_open_ext_timer(dev, priv->tm)) < 0)) {
-               pr_warning("stmmaceth: cannot attach the HW timer\n");
+               pr_warning("stmmaceth: cannot attach the external timer.\n");
                tmrate = 0;
                priv->tm->freq = 0;
                priv->tm->timer_start = stmmac_no_timer_started;
                priv->tm->timer_stop = stmmac_no_timer_stopped;
-       }
+       } else
+               priv->tm->enable = 1;
 #endif
 
        /* Create and initialize the TX/RX descriptors chains. */
@@ -1322,9 +1325,11 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
 
        /* Interrupt on completition only for the latest segment */
        priv->mac_type->ops->close_tx_desc(desc);
+
 #ifdef CONFIG_STMMAC_TIMER
-       /* Clean IC while using timers */
-       priv->mac_type->ops->clear_tx_ic(desc);
+       /* Clean IC while using timer */
+       if (likely(priv->tm->enable))
+               priv->mac_type->ops->clear_tx_ic(desc);
 #endif
        /* To avoid raise condition */
        priv->mac_type->ops->set_tx_owner(first);
@@ -2028,7 +2033,8 @@ static int stmmac_suspend(struct platform_device *pdev, pm_message_t state)
 
 #ifdef CONFIG_STMMAC_TIMER
                priv->tm->timer_stop();
-               dis_ic = 1;
+               if (likely(priv->tm->enable))
+                       dis_ic = 1;
 #endif
                napi_disable(&priv->napi);
 
index b838c6582077b0a345e4858fa1f509fb24cb0681..679f61ffb1f868254f75381e652112ae97d8b83b 100644 (file)
@@ -63,7 +63,7 @@ int stmmac_open_ext_timer(struct net_device *dev, struct stmmac_timer *tm)
 
        stmmac_rtc = rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE);
        if (stmmac_rtc == NULL) {
-               pr_error("open rtc device failed\n");
+               pr_err("open rtc device failed\n");
                return -ENODEV;
        }
 
@@ -71,7 +71,7 @@ int stmmac_open_ext_timer(struct net_device *dev, struct stmmac_timer *tm)
 
        /* Periodic mode is not supported */
        if ((rtc_irq_set_freq(stmmac_rtc, &stmmac_task, tm->freq) < 0)) {
-               pr_error("set periodic failed\n");
+               pr_err("set periodic failed\n");
                rtc_irq_unregister(stmmac_rtc, &stmmac_task);
                rtc_class_close(stmmac_rtc);
                return -1;
index f795cae33725913697d654e26e8a839bb6e8a483..6863590d184bcc9c335da8bfb51562eafafc7557 100644 (file)
@@ -26,6 +26,7 @@ struct stmmac_timer {
        void (*timer_start) (unsigned int new_freq);
        void (*timer_stop) (void);
        unsigned int freq;
+       unsigned int enable;
 };
 
 /* Open the HW timer device and return 0 in case of success */
index 7019a0d1a82bd48dd9e15f2e5b213be928423f9e..61640b99b7055d07836c43a08bc311f40b548dc8 100644 (file)
@@ -2063,7 +2063,15 @@ static int gem_check_invariants(struct gem *gp)
                mif_cfg &= ~MIF_CFG_PSELECT;
                writel(mif_cfg, gp->regs + MIF_CFG);
        } else {
-               gp->phy_type = phy_serialink;
+#ifdef CONFIG_SPARC
+               const char *p;
+
+               p = of_get_property(gp->of_node, "shared-pins", NULL);
+               if (p && !strcmp(p, "serdes"))
+                       gp->phy_type = phy_serdes;
+               else
+#endif
+                       gp->phy_type = phy_serialink;
        }
        if (gp->phy_type == phy_mii_mdio1 ||
            gp->phy_type == phy_mii_mdio0) {
index fa4e58196c214f3eeea5afb5893625eed58e61ce..43bc3fcc0d8523e837a07dcd40f3b3ca738fe218 100644 (file)
@@ -378,7 +378,7 @@ static void dbg_dump(int line_count, const char *func_name, unsigned char *buf,
 }
 
 #define DUMP(buf_, len_)       \
-       dbg_dump(__LINE__, __func__, buf_, len_)
+       dbg_dump(__LINE__, __func__, (unsigned char *)buf_, len_)
 
 #define DUMP1(buf_, len_)                      \
        do {                                    \
@@ -1363,7 +1363,7 @@ static void hso_serial_close(struct tty_struct *tty, struct file *filp)
        /* reset the rts and dtr */
        /* do the actual close */
        serial->open_count--;
-       kref_put(&serial->parent->ref, hso_serial_ref_free);
+
        if (serial->open_count <= 0) {
                serial->open_count = 0;
                spin_lock_irq(&serial->serial_lock);
@@ -1383,6 +1383,8 @@ static void hso_serial_close(struct tty_struct *tty, struct file *filp)
                usb_autopm_put_interface(serial->parent->interface);
 
        mutex_unlock(&serial->parent->mutex);
+
+       kref_put(&serial->parent->ref, hso_serial_ref_free);
 }
 
 /* close the requested serial port */
@@ -1527,7 +1529,7 @@ static void tiocmget_intr_callback(struct urb *urb)
                dev_warn(&usb->dev,
                         "hso received invalid serial state notification\n");
                DUMP(serial_state_notification,
-                    sizeof(hso_serial_state_notifation))
+                    sizeof(struct hso_serial_state_notification));
        } else {
 
                UART_state_bitmap = le16_to_cpu(serial_state_notification->
index ade5b344f75d73fb5852a0a9b30322576d1ce868..52af5017c46b42be7051a93b58c1f52da5909fb5 100644 (file)
@@ -210,32 +210,29 @@ rx_drop:
 static struct net_device_stats *veth_get_stats(struct net_device *dev)
 {
        struct veth_priv *priv;
-       struct net_device_stats *dev_stats;
        int cpu;
-       struct veth_net_stats *stats;
+       struct veth_net_stats *stats, total = {0};
 
        priv = netdev_priv(dev);
-       dev_stats = &dev->stats;
-
-       dev_stats->rx_packets = 0;
-       dev_stats->tx_packets = 0;
-       dev_stats->rx_bytes = 0;
-       dev_stats->tx_bytes = 0;
-       dev_stats->tx_dropped = 0;
-       dev_stats->rx_dropped = 0;
 
-       for_each_online_cpu(cpu) {
+       for_each_possible_cpu(cpu) {
                stats = per_cpu_ptr(priv->stats, cpu);
 
-               dev_stats->rx_packets += stats->rx_packets;
-               dev_stats->tx_packets += stats->tx_packets;
-               dev_stats->rx_bytes += stats->rx_bytes;
-               dev_stats->tx_bytes += stats->tx_bytes;
-               dev_stats->tx_dropped += stats->tx_dropped;
-               dev_stats->rx_dropped += stats->rx_dropped;
+               total.rx_packets += stats->rx_packets;
+               total.tx_packets += stats->tx_packets;
+               total.rx_bytes   += stats->rx_bytes;
+               total.tx_bytes   += stats->tx_bytes;
+               total.tx_dropped += stats->tx_dropped;
+               total.rx_dropped += stats->rx_dropped;
        }
-
-       return dev_stats;
+       dev->stats.rx_packets = total.rx_packets;
+       dev->stats.tx_packets = total.tx_packets;
+       dev->stats.rx_bytes   = total.rx_bytes;
+       dev->stats.tx_bytes   = total.tx_bytes;
+       dev->stats.tx_dropped = total.tx_dropped;
+       dev->stats.rx_dropped = total.rx_dropped;
+
+       return &dev->stats;
 }
 
 static int veth_open(struct net_device *dev)
index e2c33c06190bb1fa0975b634b765de70d22ad71f..8e25ca7080c7bb0a73ae3b3eb63ed79721d58d64 100644 (file)
@@ -907,6 +907,7 @@ static ssize_t cosa_write(struct file *file,
                        current->state = TASK_RUNNING;
                        chan->tx_status = 1;
                        spin_unlock_irqrestore(&cosa->lock, flags);
+                       up(&chan->wsem);
                        return -ERESTARTSYS;
                }
        }
index d0593ed9170eb281d820a8e3aadaa3b3f04e71fd..f6036fb423196b59a0bac41a255ff29debe33a5a 100644 (file)
 
 #include "airo.h"
 
-/*
-   All the PCMCIA modules use PCMCIA_DEBUG to control debugging.  If
-   you do not define PCMCIA_DEBUG at all, all the debug code will be
-   left out.  If you compile with PCMCIA_DEBUG=0, the debug code will
-   be present but disabled -- but it can then be enabled for specific
-   modules at load time with a 'pc_debug=#' option to insmod.
-*/
-#ifdef PCMCIA_DEBUG
-static int pc_debug = PCMCIA_DEBUG;
-module_param(pc_debug, int, 0);
-static char *version = "$Revision: 1.2 $";
-#define DEBUG(n, args...) if (pc_debug > (n)) printk(KERN_DEBUG args);
-#else
-#define DEBUG(n, args...)
-#endif
 
 /*====================================================================*/
 
@@ -145,11 +130,10 @@ static int airo_probe(struct pcmcia_device *p_dev)
 {
        local_info_t *local;
 
-       DEBUG(0, "airo_attach()\n");
+       dev_dbg(&p_dev->dev, "airo_attach()\n");
 
        /* Interrupt setup */
        p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
-       p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID;
        p_dev->irq.Handler = NULL;
 
        /*
@@ -184,7 +168,7 @@ static int airo_probe(struct pcmcia_device *p_dev)
 
 static void airo_detach(struct pcmcia_device *link)
 {
-       DEBUG(0, "airo_detach(0x%p)\n", link);
+       dev_dbg(&link->dev, "airo_detach\n");
 
        airo_release(link);
 
@@ -204,9 +188,6 @@ static void airo_detach(struct pcmcia_device *link)
 
   ======================================================================*/
 
-#define CS_CHECK(fn, ret) \
-do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
-
 static int airo_cs_config_check(struct pcmcia_device *p_dev,
                                cistpl_cftable_entry_t *cfg,
                                cistpl_cftable_entry_t *dflt,
@@ -275,11 +256,11 @@ static int airo_cs_config_check(struct pcmcia_device *p_dev,
                req->Base = mem->win[0].host_addr;
                req->Size = mem->win[0].len;
                req->AccessSpeed = 0;
-               if (pcmcia_request_window(&p_dev, req, &p_dev->win) != 0)
+               if (pcmcia_request_window(p_dev, req, &p_dev->win) != 0)
                        return -ENODEV;
                map.Page = 0;
                map.CardOffset = mem->win[0].card_addr;
-               if (pcmcia_map_mem_page(p_dev->win, &map) != 0)
+               if (pcmcia_map_mem_page(p_dev, p_dev->win, &map) != 0)
                        return -ENODEV;
        }
        /* If we got this far, we're cool! */
@@ -291,11 +272,11 @@ static int airo_config(struct pcmcia_device *link)
 {
        local_info_t *dev;
        win_req_t *req;
-       int last_fn, last_ret;
+       int ret;
 
        dev = link->priv;
 
-       DEBUG(0, "airo_config(0x%p)\n", link);
+       dev_dbg(&link->dev, "airo_config\n");
 
        req = kzalloc(sizeof(win_req_t), GFP_KERNEL);
        if (!req)
@@ -315,8 +296,8 @@ static int airo_config(struct pcmcia_device *link)
         * and most client drivers will only use the CIS to fill in
         * implementation-defined details.
         */
-       last_ret = pcmcia_loop_config(link, airo_cs_config_check, req);
-       if (last_ret)
+       ret = pcmcia_loop_config(link, airo_cs_config_check, req);
+       if (ret)
                goto failed;
 
        /*
@@ -324,21 +305,25 @@ static int airo_config(struct pcmcia_device *link)
          handler to the interrupt, unless the 'Handler' member of the
          irq structure is initialized.
        */
-       if (link->conf.Attributes & CONF_ENABLE_IRQ)
-               CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
+       if (link->conf.Attributes & CONF_ENABLE_IRQ) {
+               ret = pcmcia_request_irq(link, &link->irq);
+               if (ret)
+                       goto failed;
+       }
 
        /*
          This actually configures the PCMCIA socket -- setting up
          the I/O windows and the interrupt mapping, and putting the
          card and host interface into "Memory and IO" mode.
        */
-       CS_CHECK(RequestConfiguration,
-                pcmcia_request_configuration(link, &link->conf));
+       ret = pcmcia_request_configuration(link, &link->conf);
+       if (ret)
+               goto failed;
        ((local_info_t *)link->priv)->eth_dev =
                init_airo_card(link->irq.AssignedIRQ,
-                              link->io.BasePort1, 1, &handle_to_dev(link));
+                              link->io.BasePort1, 1, &link->dev);
        if (!((local_info_t *)link->priv)->eth_dev)
-               goto cs_failed;
+               goto failed;
 
        /*
          At this point, the dev_node_t structure(s) need to be
@@ -368,8 +353,6 @@ static int airo_config(struct pcmcia_device *link)
        kfree(req);
        return 0;
 
- cs_failed:
-       cs_error(link, last_fn, last_ret);
  failed:
        airo_release(link);
        kfree(req);
@@ -386,7 +369,7 @@ static int airo_config(struct pcmcia_device *link)
 
 static void airo_release(struct pcmcia_device *link)
 {
-       DEBUG(0, "airo_release(0x%p)\n", link);
+       dev_dbg(&link->dev, "airo_release\n");
        pcmcia_disable_device(link);
 }
 
index 9c6ab5378f6e1a5ab693b88cb67bfd447e294581..95a8e232b58f772a74ea0c7d1d5ab96e11142e2e 100644 (file)
@@ -1125,7 +1125,6 @@ ath5k_mode_setup(struct ath5k_softc *sc)
        /* configure operational mode */
        ath5k_hw_set_opmode(ah);
 
-       ath5k_hw_set_mcast_filter(ah, 0, 0);
        ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "RX filter 0x%x\n", rfilt);
 }
 
index b767c3b67b24b97aad051e2a42301b8d6725bade..b548c8eaaae18f9ab206fc114891a67319fa7f7b 100644 (file)
@@ -63,12 +63,16 @@ static const struct pci_device_id ath5k_led_devices[] = {
        { ATH_SDEVICE(PCI_VENDOR_ID_AMBIT, 0x0422), ATH_LED(1, 1) },
        /* E-machines E510 (tuliom@gmail.com) */
        { ATH_SDEVICE(PCI_VENDOR_ID_AMBIT, 0x0428), ATH_LED(3, 0) },
+       /* BenQ Joybook R55v (nowymarluk@wp.pl) */
+       { ATH_SDEVICE(PCI_VENDOR_ID_QMI, 0x0100), ATH_LED(1, 0) },
        /* Acer Extensa 5620z (nekoreeve@gmail.com) */
        { ATH_SDEVICE(PCI_VENDOR_ID_QMI, 0x0105), ATH_LED(3, 0) },
        /* Fukato Datacask Jupiter 1014a (mrb74@gmx.at) */
        { ATH_SDEVICE(PCI_VENDOR_ID_AZWAVE, 0x1026), ATH_LED(3, 0) },
        /* IBM ThinkPad AR5BXB6 (legovini@spiro.fisica.unipd.it) */
        { ATH_SDEVICE(PCI_VENDOR_ID_IBM, 0x058a), ATH_LED(1, 0) },
+       /* HP Compaq CQ60-206US (ddreggors@jumptv.com) */
+       { ATH_SDEVICE(PCI_VENDOR_ID_HP, 0x0137a), ATH_LED(3, 1) },
        /* HP Compaq C700 (nitrousnrg@gmail.com) */
        { ATH_SDEVICE(PCI_VENDOR_ID_HP, 0x0137b), ATH_LED(3, 1) },
        /* IBM-specific AR5212 (all others) */
index 52bed89063d4e6a0941541683dc116e034ac22fb..43d2be9867fc08e288c5dc3eab5949e0cf1fa96c 100644 (file)
@@ -1555,6 +1555,8 @@ void ath_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
                BIT(NL80211_IFTYPE_ADHOC) |
                BIT(NL80211_IFTYPE_MESH_POINT);
 
+       hw->wiphy->ps_default = false;
+
        hw->queues = 4;
        hw->max_rates = 4;
        hw->channel_change_time = 5000;
index ddaa859c3491d8209a5e834a1a4d1ec0c59ad05f..32407911842f0f3b4d60dcf9bb5c20a93bb26e79 100644 (file)
 
 #include "atmel.h"
 
-/*
-   All the PCMCIA modules use PCMCIA_DEBUG to control debugging.  If
-   you do not define PCMCIA_DEBUG at all, all the debug code will be
-   left out.  If you compile with PCMCIA_DEBUG=0, the debug code will
-   be present but disabled -- but it can then be enabled for specific
-   modules at load time with a 'pc_debug=#' option to insmod.
-*/
-
-#ifdef PCMCIA_DEBUG
-static int pc_debug = PCMCIA_DEBUG;
-module_param(pc_debug, int, 0);
-static char *version = "$Revision: 1.2 $";
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args);
-#else
-#define DEBUG(n, args...)
-#endif
 
 /*====================================================================*/
 
@@ -155,11 +139,10 @@ static int atmel_probe(struct pcmcia_device *p_dev)
 {
        local_info_t *local;
 
-       DEBUG(0, "atmel_attach()\n");
+       dev_dbg(&p_dev->dev, "atmel_attach()\n");
 
        /* Interrupt setup */
        p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
-       p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID;
        p_dev->irq.Handler = NULL;
 
        /*
@@ -194,7 +177,7 @@ static int atmel_probe(struct pcmcia_device *p_dev)
 
 static void atmel_detach(struct pcmcia_device *link)
 {
-       DEBUG(0, "atmel_detach(0x%p)\n", link);
+       dev_dbg(&link->dev, "atmel_detach\n");
 
        atmel_release(link);
 
@@ -209,9 +192,6 @@ static void atmel_detach(struct pcmcia_device *link)
 
   ======================================================================*/
 
-#define CS_CHECK(fn, ret) \
-do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
-
 /* Call-back function to interrogate PCMCIA-specific information
    about the current existance of the card */
 static int card_present(void *arg)
@@ -275,13 +255,13 @@ static int atmel_config_check(struct pcmcia_device *p_dev,
 static int atmel_config(struct pcmcia_device *link)
 {
        local_info_t *dev;
-       int last_fn, last_ret;
+       int ret;
        struct pcmcia_device_id *did;
 
        dev = link->priv;
-       did = dev_get_drvdata(&handle_to_dev(link));
+       did = dev_get_drvdata(&link->dev);
 
-       DEBUG(0, "atmel_config(0x%p)\n", link);
+       dev_dbg(&link->dev, "atmel_config\n");
 
        /*
          In this loop, we scan the CIS for configuration table entries,
@@ -303,31 +283,36 @@ static int atmel_config(struct pcmcia_device *link)
          handler to the interrupt, unless the 'Handler' member of the
          irq structure is initialized.
        */
-       if (link->conf.Attributes & CONF_ENABLE_IRQ)
-               CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
+       if (link->conf.Attributes & CONF_ENABLE_IRQ) {
+               ret = pcmcia_request_irq(link, &link->irq);
+               if (ret)
+                       goto failed;
+       }
 
        /*
          This actually configures the PCMCIA socket -- setting up
          the I/O windows and the interrupt mapping, and putting the
          card and host interface into "Memory and IO" mode.
        */
-       CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
+       ret = pcmcia_request_configuration(link, &link->conf);
+       if (ret)
+               goto failed;
 
        if (link->irq.AssignedIRQ == 0) {
                printk(KERN_ALERT
                       "atmel: cannot assign IRQ: check that CONFIG_ISA is set in kernel config.");
-               goto cs_failed;
+               goto failed;
        }
 
        ((local_info_t*)link->priv)->eth_dev =
                init_atmel_card(link->irq.AssignedIRQ,
                                link->io.BasePort1,
                                did ? did->driver_info : ATMEL_FW_TYPE_NONE,
-                               &handle_to_dev(link),
+                               &link->dev,
                                card_present,
                                link);
        if (!((local_info_t*)link->priv)->eth_dev)
-                       goto cs_failed;
+                       goto failed;
 
 
        /*
@@ -340,8 +325,6 @@ static int atmel_config(struct pcmcia_device *link)
 
        return 0;
 
- cs_failed:
-       cs_error(link, last_fn, last_ret);
  failed:
        atmel_release(link);
        return -ENODEV;
@@ -359,7 +342,7 @@ static void atmel_release(struct pcmcia_device *link)
 {
        struct net_device *dev = ((local_info_t*)link->priv)->eth_dev;
 
-       DEBUG(0, "atmel_release(0x%p)\n", link);
+       dev_dbg(&link->dev, "atmel_release\n");
 
        if (dev)
                stop_atmel_card(dev);
index 86f35827f0085a19d01d94624c4f2aee3603df3f..098dda1a67c13af65abb94e3c5bb0bd2a7c4a816 100644 (file)
@@ -4521,9 +4521,8 @@ static int b43_op_beacon_set_tim(struct ieee80211_hw *hw,
 {
        struct b43_wl *wl = hw_to_b43_wl(hw);
 
-       mutex_lock(&wl->mutex);
+       /* FIXME: add locking */
        b43_update_templates(wl);
-       mutex_unlock(&wl->mutex);
 
        return 0;
 }
index 6c3a74964ab888585e0466424290415fcdf653e0..984174bc7b0ff5411b7961f59b494cd8edeafc36 100644 (file)
@@ -65,35 +65,15 @@ static int __devinit b43_pcmcia_probe(struct pcmcia_device *dev)
        struct ssb_bus *ssb;
        win_req_t win;
        memreq_t mem;
-       tuple_t tuple;
-       cisparse_t parse;
        int err = -ENOMEM;
        int res = 0;
-       unsigned char buf[64];
 
        ssb = kzalloc(sizeof(*ssb), GFP_KERNEL);
        if (!ssb)
                goto out_error;
 
        err = -ENODEV;
-       tuple.DesiredTuple = CISTPL_CONFIG;
-       tuple.Attributes = 0;
-       tuple.TupleData = buf;
-       tuple.TupleDataMax = sizeof(buf);
-       tuple.TupleOffset = 0;
 
-       res = pcmcia_get_first_tuple(dev, &tuple);
-       if (res != 0)
-               goto err_kfree_ssb;
-       res = pcmcia_get_tuple_data(dev, &tuple);
-       if (res != 0)
-               goto err_kfree_ssb;
-       res = pcmcia_parse_tuple(&tuple, &parse);
-       if (res != 0)
-               goto err_kfree_ssb;
-
-       dev->conf.ConfigBase = parse.config.base;
-       dev->conf.Present = parse.config.rmask[0];
        dev->conf.Attributes = CONF_ENABLE_IRQ;
        dev->conf.IntType = INT_MEMORY_AND_IO;
 
@@ -107,20 +87,18 @@ static int __devinit b43_pcmcia_probe(struct pcmcia_device *dev)
        win.Base = 0;
        win.Size = SSB_CORE_SIZE;
        win.AccessSpeed = 250;
-       res = pcmcia_request_window(&dev, &win, &dev->win);
+       res = pcmcia_request_window(dev, &win, &dev->win);
        if (res != 0)
                goto err_kfree_ssb;
 
        mem.CardOffset = 0;
        mem.Page = 0;
-       res = pcmcia_map_mem_page(dev->win, &mem);
+       res = pcmcia_map_mem_page(dev, dev->win, &mem);
        if (res != 0)
                goto err_disable;
 
        dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
-       dev->irq.IRQInfo1 = IRQ_LEVEL_ID;
        dev->irq.Handler = NULL; /* The handler is registered later. */
-       dev->irq.Instance = NULL;
        res = pcmcia_request_irq(dev, &dev->irq);
        if (res != 0)
                goto err_disable;
index ad8eab4a639b05fe82f41d7977f06448f2119760..c9640a3e02c99e60ba3db7c1e701542457197355 100644 (file)
@@ -274,9 +274,6 @@ static int sandisk_enable_wireless(struct net_device *dev)
        conf_reg_t reg;
        struct hostap_interface *iface = netdev_priv(dev);
        local_info_t *local = iface->local;
-       tuple_t tuple;
-       cisparse_t *parse = NULL;
-       u_char buf[64];
        struct hostap_cs_priv *hw_priv = local->hw_priv;
 
        if (hw_priv->link->io.NumPorts1 < 0x42) {
@@ -285,28 +282,13 @@ static int sandisk_enable_wireless(struct net_device *dev)
                goto done;
        }
 
-       parse = kmalloc(sizeof(cisparse_t), GFP_KERNEL);
-       if (parse == NULL) {
-               ret = -ENOMEM;
-               goto done;
-       }
-
-       tuple.Attributes = TUPLE_RETURN_COMMON;
-       tuple.TupleData = buf;
-       tuple.TupleDataMax = sizeof(buf);
-       tuple.TupleOffset = 0;
-
        if (hw_priv->link->manf_id != 0xd601 || hw_priv->link->card_id != 0x0101) {
                /* No SanDisk manfid found */
                ret = -ENODEV;
                goto done;
        }
 
-       tuple.DesiredTuple = CISTPL_LONGLINK_MFC;
-       if (pcmcia_get_first_tuple(hw_priv->link, &tuple) ||
-           pcmcia_get_tuple_data(hw_priv->link, &tuple) ||
-           pcmcia_parse_tuple(&tuple, parse) ||
-               parse->longlink_mfc.nfn < 2) {
+       if (hw_priv->link->socket->functions < 2) {
                /* No multi-function links found */
                ret = -ENODEV;
                goto done;
@@ -354,7 +336,6 @@ static int sandisk_enable_wireless(struct net_device *dev)
        udelay(10);
 
 done:
-       kfree(parse);
        return ret;
 }
 
@@ -529,10 +510,6 @@ static void prism2_detach(struct pcmcia_device *link)
 }
 
 
-#define CS_CHECK(fn, ret) \
-do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
-
-
 /* run after a CARD_INSERTION event is received to configure the PCMCIA
  * socket and make the device available to the system */
 
@@ -624,7 +601,6 @@ static int prism2_config(struct pcmcia_device *link)
        struct hostap_interface *iface;
        local_info_t *local;
        int ret = 1;
-       int last_fn, last_ret;
        struct hostap_cs_priv *hw_priv;
 
        PDEBUG(DEBUG_FLOW, "prism2_config()\n");
@@ -636,19 +612,18 @@ static int prism2_config(struct pcmcia_device *link)
        }
 
        /* Look for an appropriate configuration table entry in the CIS */
-       last_ret = pcmcia_loop_config(link, prism2_config_check, NULL);
-       if (last_ret) {
+       ret = pcmcia_loop_config(link, prism2_config_check, NULL);
+       if (ret) {
                if (!ignore_cis_vcc)
                        printk(KERN_ERR "GetNextTuple(): No matching "
                               "CIS configuration.  Maybe you need the "
                               "ignore_cis_vcc=1 parameter.\n");
-               cs_error(link, RequestIO, last_ret);
                goto failed;
        }
 
        /* Need to allocate net_device before requesting IRQ handler */
        dev = prism2_init_local_data(&prism2_pccard_funcs, 0,
-                                    &handle_to_dev(link));
+                                    &link->dev);
        if (dev == NULL)
                goto failed;
        link->priv = dev;
@@ -666,13 +641,11 @@ static int prism2_config(struct pcmcia_device *link)
         * irq structure is initialized.
         */
        if (link->conf.Attributes & CONF_ENABLE_IRQ) {
-               link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING |
-                                      IRQ_HANDLE_PRESENT;
-               link->irq.IRQInfo1 = IRQ_LEVEL_ID;
+               link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
                link->irq.Handler = prism2_interrupt;
-               link->irq.Instance = dev;
-               CS_CHECK(RequestIRQ,
-                        pcmcia_request_irq(link, &link->irq));
+               ret = pcmcia_request_irq(link, &link->irq);
+               if (ret)
+                       goto failed;
        }
 
        /*
@@ -680,8 +653,9 @@ static int prism2_config(struct pcmcia_device *link)
         * the I/O windows and the interrupt mapping, and putting the
         * card and host interface into "Memory and IO" mode.
         */
-       CS_CHECK(RequestConfiguration,
-                pcmcia_request_configuration(link, &link->conf));
+       ret = pcmcia_request_configuration(link, &link->conf);
+       if (ret)
+               goto failed;
 
        dev->irq = link->irq.AssignedIRQ;
        dev->base_addr = link->io.BasePort1;
@@ -714,9 +688,6 @@ static int prism2_config(struct pcmcia_device *link)
        }
        return ret;
 
- cs_failed:
-       cs_error(link, last_fn, last_ret);
-
  failed:
        kfree(hw_priv);
        prism2_release((u_long)link);
index 240cff1e6979a4e77cb54c11ccc074dadf3ff028..6e2fc0cb6f8a83386252923c9c5cc0d57c190d4b 100644 (file)
@@ -6029,7 +6029,7 @@ static struct net_device *ipw2100_alloc_device(struct pci_dev *pci_dev,
        struct ipw2100_priv *priv;
        struct net_device *dev;
 
-       dev = alloc_ieee80211(sizeof(struct ipw2100_priv), 0);
+       dev = alloc_ieee80211(sizeof(struct ipw2100_priv));
        if (!dev)
                return NULL;
        priv = libipw_priv(dev);
@@ -6342,7 +6342,7 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
                sysfs_remove_group(&pci_dev->dev.kobj,
                                   &ipw2100_attribute_group);
 
-               free_ieee80211(dev, 0);
+               free_ieee80211(dev);
                pci_set_drvdata(pci_dev, NULL);
        }
 
@@ -6400,7 +6400,7 @@ static void __devexit ipw2100_pci_remove_one(struct pci_dev *pci_dev)
                if (dev->base_addr)
                        iounmap((void __iomem *)dev->base_addr);
 
-               free_ieee80211(dev, 0);
+               free_ieee80211(dev);
        }
 
        pci_release_regions(pci_dev);
index 827824d45de9bb1da433ad66be0dc225376270ef..a6ca536e44f81658e15cc361f9e51232a517801a 100644 (file)
@@ -104,25 +104,6 @@ static int antenna = CFG_SYS_ANTENNA_BOTH;
 static int rtap_iface = 0;     /* def: 0 -- do not create rtap interface */
 #endif
 
-static struct ieee80211_rate ipw2200_rates[] = {
-       { .bitrate = 10 },
-       { .bitrate = 20, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
-       { .bitrate = 55, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
-       { .bitrate = 110, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
-       { .bitrate = 60 },
-       { .bitrate = 90 },
-       { .bitrate = 120 },
-       { .bitrate = 180 },
-       { .bitrate = 240 },
-       { .bitrate = 360 },
-       { .bitrate = 480 },
-       { .bitrate = 540 }
-};
-
-#define ipw2200_a_rates                (ipw2200_rates + 4)
-#define ipw2200_num_a_rates    8
-#define ipw2200_bg_rates       (ipw2200_rates + 0)
-#define ipw2200_num_bg_rates   12
 
 #ifdef CONFIG_IPW2200_QOS
 static int qos_enable = 0;
@@ -8674,6 +8655,24 @@ static int ipw_sw_reset(struct ipw_priv *priv, int option)
  *
  */
 
+static int ipw_wx_get_name(struct net_device *dev,
+                          struct iw_request_info *info,
+                          union iwreq_data *wrqu, char *extra)
+{
+       struct ipw_priv *priv = libipw_priv(dev);
+       mutex_lock(&priv->mutex);
+       if (priv->status & STATUS_RF_KILL_MASK)
+               strcpy(wrqu->name, "radio off");
+       else if (!(priv->status & STATUS_ASSOCIATED))
+               strcpy(wrqu->name, "unassociated");
+       else
+               snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11%c",
+                        ipw_modes[priv->assoc_request.ieee_mode]);
+       IPW_DEBUG_WX("Name: %s\n", wrqu->name);
+       mutex_unlock(&priv->mutex);
+       return 0;
+}
+
 static int ipw_set_channel(struct ipw_priv *priv, u8 channel)
 {
        if (channel == 0) {
@@ -9973,7 +9972,7 @@ static int ipw_wx_sw_reset(struct net_device *dev,
 /* Rebase the WE IOCTLs to zero for the handler array */
 #define IW_IOCTL(x) [(x)-SIOCSIWCOMMIT]
 static iw_handler ipw_wx_handlers[] = {
-       IW_IOCTL(SIOCGIWNAME) = (iw_handler) cfg80211_wext_giwname,
+       IW_IOCTL(SIOCGIWNAME) = ipw_wx_get_name,
        IW_IOCTL(SIOCSIWFREQ) = ipw_wx_set_freq,
        IW_IOCTL(SIOCGIWFREQ) = ipw_wx_get_freq,
        IW_IOCTL(SIOCSIWMODE) = ipw_wx_set_mode,
@@ -11417,100 +11416,16 @@ static void ipw_bg_down(struct work_struct *work)
 /* Called by register_netdev() */
 static int ipw_net_init(struct net_device *dev)
 {
-       int i, rc = 0;
        struct ipw_priv *priv = libipw_priv(dev);
-       const struct libipw_geo *geo = libipw_get_geo(priv->ieee);
-       struct wireless_dev *wdev = &priv->ieee->wdev;
        mutex_lock(&priv->mutex);
 
        if (ipw_up(priv)) {
-               rc = -EIO;
-               goto out;
-       }
-
-       memcpy(wdev->wiphy->perm_addr, priv->mac_addr, ETH_ALEN);
-
-       /* fill-out priv->ieee->bg_band */
-       if (geo->bg_channels) {
-               struct ieee80211_supported_band *bg_band = &priv->ieee->bg_band;
-
-               bg_band->band = IEEE80211_BAND_2GHZ;
-               bg_band->n_channels = geo->bg_channels;
-               bg_band->channels =
-                       kzalloc(geo->bg_channels *
-                               sizeof(struct ieee80211_channel), GFP_KERNEL);
-               /* translate geo->bg to bg_band.channels */
-               for (i = 0; i < geo->bg_channels; i++) {
-                       bg_band->channels[i].band = IEEE80211_BAND_2GHZ;
-                       bg_band->channels[i].center_freq = geo->bg[i].freq;
-                       bg_band->channels[i].hw_value = geo->bg[i].channel;
-                       bg_band->channels[i].max_power = geo->bg[i].max_power;
-                       if (geo->bg[i].flags & LIBIPW_CH_PASSIVE_ONLY)
-                               bg_band->channels[i].flags |=
-                                       IEEE80211_CHAN_PASSIVE_SCAN;
-                       if (geo->bg[i].flags & LIBIPW_CH_NO_IBSS)
-                               bg_band->channels[i].flags |=
-                                       IEEE80211_CHAN_NO_IBSS;
-                       if (geo->bg[i].flags & LIBIPW_CH_RADAR_DETECT)
-                               bg_band->channels[i].flags |=
-                                       IEEE80211_CHAN_RADAR;
-                       /* No equivalent for LIBIPW_CH_80211H_RULES,
-                          LIBIPW_CH_UNIFORM_SPREADING, or
-                          LIBIPW_CH_B_ONLY... */
-               }
-               /* point at bitrate info */
-               bg_band->bitrates = ipw2200_bg_rates;
-               bg_band->n_bitrates = ipw2200_num_bg_rates;
-
-               wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = bg_band;
-       }
-
-       /* fill-out priv->ieee->a_band */
-       if (geo->a_channels) {
-               struct ieee80211_supported_band *a_band = &priv->ieee->a_band;
-
-               a_band->band = IEEE80211_BAND_5GHZ;
-               a_band->n_channels = geo->a_channels;
-               a_band->channels =
-                       kzalloc(geo->a_channels *
-                               sizeof(struct ieee80211_channel), GFP_KERNEL);
-               /* translate geo->bg to a_band.channels */
-               for (i = 0; i < geo->a_channels; i++) {
-                       a_band->channels[i].band = IEEE80211_BAND_2GHZ;
-                       a_band->channels[i].center_freq = geo->a[i].freq;
-                       a_band->channels[i].hw_value = geo->a[i].channel;
-                       a_band->channels[i].max_power = geo->a[i].max_power;
-                       if (geo->a[i].flags & LIBIPW_CH_PASSIVE_ONLY)
-                               a_band->channels[i].flags |=
-                                       IEEE80211_CHAN_PASSIVE_SCAN;
-                       if (geo->a[i].flags & LIBIPW_CH_NO_IBSS)
-                               a_band->channels[i].flags |=
-                                       IEEE80211_CHAN_NO_IBSS;
-                       if (geo->a[i].flags & LIBIPW_CH_RADAR_DETECT)
-                               a_band->channels[i].flags |=
-                                       IEEE80211_CHAN_RADAR;
-                       /* No equivalent for LIBIPW_CH_80211H_RULES,
-                          LIBIPW_CH_UNIFORM_SPREADING, or
-                          LIBIPW_CH_B_ONLY... */
-               }
-               /* point at bitrate info */
-               a_band->bitrates = ipw2200_a_rates;
-               a_band->n_bitrates = ipw2200_num_a_rates;
-
-               wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = a_band;
-       }
-
-       set_wiphy_dev(wdev->wiphy, &priv->pci_dev->dev);
-
-       /* With that information in place, we can now register the wiphy... */
-       if (wiphy_register(wdev->wiphy)) {
-               rc = -EIO;
-               goto out;
+               mutex_unlock(&priv->mutex);
+               return -EIO;
        }
 
-out:
        mutex_unlock(&priv->mutex);
-       return rc;
+       return 0;
 }
 
 /* PCI driver stuff */
@@ -11641,7 +11556,7 @@ static int ipw_prom_alloc(struct ipw_priv *priv)
        if (priv->prom_net_dev)
                return -EPERM;
 
-       priv->prom_net_dev = alloc_ieee80211(sizeof(struct ipw_prom_priv), 1);
+       priv->prom_net_dev = alloc_ieee80211(sizeof(struct ipw_prom_priv));
        if (priv->prom_net_dev == NULL)
                return -ENOMEM;
 
@@ -11660,7 +11575,7 @@ static int ipw_prom_alloc(struct ipw_priv *priv)
 
        rc = register_netdev(priv->prom_net_dev);
        if (rc) {
-               free_ieee80211(priv->prom_net_dev, 1);
+               free_ieee80211(priv->prom_net_dev);
                priv->prom_net_dev = NULL;
                return rc;
        }
@@ -11674,7 +11589,7 @@ static void ipw_prom_free(struct ipw_priv *priv)
                return;
 
        unregister_netdev(priv->prom_net_dev);
-       free_ieee80211(priv->prom_net_dev, 1);
+       free_ieee80211(priv->prom_net_dev);
 
        priv->prom_net_dev = NULL;
 }
@@ -11702,7 +11617,7 @@ static int __devinit ipw_pci_probe(struct pci_dev *pdev,
        struct ipw_priv *priv;
        int i;
 
-       net_dev = alloc_ieee80211(sizeof(struct ipw_priv), 0);
+       net_dev = alloc_ieee80211(sizeof(struct ipw_priv));
        if (net_dev == NULL) {
                err = -ENOMEM;
                goto out;
@@ -11850,7 +11765,7 @@ static int __devinit ipw_pci_probe(struct pci_dev *pdev,
        pci_disable_device(pdev);
        pci_set_drvdata(pdev, NULL);
       out_free_ieee80211:
-       free_ieee80211(priv->net_dev, 0);
+       free_ieee80211(priv->net_dev);
       out:
        return err;
 }
@@ -11917,7 +11832,7 @@ static void __devexit ipw_pci_remove(struct pci_dev *pdev)
        pci_release_regions(pdev);
        pci_disable_device(pdev);
        pci_set_drvdata(pdev, NULL);
-       free_ieee80211(priv->net_dev, 0);
+       free_ieee80211(priv->net_dev);
        free_firmware();
 }
 
index bf45391172f3a3a6b739826e8e7816176ba29d0d..1e334ff6bd52263a0dac8447b479aad012c7395f 100644 (file)
@@ -31,7 +31,6 @@
 #include <linux/ieee80211.h>
 
 #include <net/lib80211.h>
-#include <net/cfg80211.h>
 
 #define LIBIPW_VERSION "git-1.1.13"
 
@@ -784,15 +783,12 @@ struct libipw_geo {
 
 struct libipw_device {
        struct net_device *dev;
-       struct wireless_dev wdev;
        struct libipw_security sec;
 
        /* Bookkeeping structures */
        struct libipw_stats ieee_stats;
 
        struct libipw_geo geo;
-       struct ieee80211_supported_band bg_band;
-       struct ieee80211_supported_band a_band;
 
        /* Probe / Beacon management */
        struct list_head network_free_list;
@@ -1018,8 +1014,8 @@ static inline int libipw_is_cck_rate(u8 rate)
 }
 
 /* ieee80211.c */
-extern void free_ieee80211(struct net_device *dev, int monitor);
-extern struct net_device *alloc_ieee80211(int sizeof_priv, int monitor);
+extern void free_ieee80211(struct net_device *dev);
+extern struct net_device *alloc_ieee80211(int sizeof_priv);
 extern int libipw_change_mtu(struct net_device *dev, int new_mtu);
 
 extern void libipw_networks_age(struct libipw_device *ieee,
index a0e9f6aed7daf8568ff27b0d484d17fc9df5da03..eb2b60834c1746e9e8c50046eef6759d7380f21e 100644 (file)
@@ -62,9 +62,6 @@ MODULE_DESCRIPTION(DRV_DESCRIPTION);
 MODULE_AUTHOR(DRV_COPYRIGHT);
 MODULE_LICENSE("GPL");
 
-struct cfg80211_ops libipw_config_ops = { };
-void *libipw_wiphy_privid = &libipw_wiphy_privid;
-
 static int libipw_networks_allocate(struct libipw_device *ieee)
 {
        if (ieee->networks)
@@ -143,7 +140,7 @@ int libipw_change_mtu(struct net_device *dev, int new_mtu)
 }
 EXPORT_SYMBOL(libipw_change_mtu);
 
-struct net_device *alloc_ieee80211(int sizeof_priv, int monitor)
+struct net_device *alloc_ieee80211(int sizeof_priv)
 {
        struct libipw_device *ieee;
        struct net_device *dev;
@@ -160,31 +157,10 @@ struct net_device *alloc_ieee80211(int sizeof_priv, int monitor)
 
        ieee->dev = dev;
 
-       if (!monitor) {
-               ieee->wdev.wiphy = wiphy_new(&libipw_config_ops, 0);
-               if (!ieee->wdev.wiphy) {
-                       LIBIPW_ERROR("Unable to allocate wiphy.\n");
-                       goto failed_free_netdev;
-               }
-
-               ieee->dev->ieee80211_ptr = &ieee->wdev;
-               ieee->wdev.iftype = NL80211_IFTYPE_STATION;
-
-               /* Fill-out wiphy structure bits we know...  Not enough info
-                  here to call set_wiphy_dev or set MAC address or channel info
-                  -- have to do that in ->ndo_init... */
-               ieee->wdev.wiphy->privid = libipw_wiphy_privid;
-
-               ieee->wdev.wiphy->max_scan_ssids = 1;
-               ieee->wdev.wiphy->max_scan_ie_len = 0;
-               ieee->wdev.wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
-                                               | BIT(NL80211_IFTYPE_ADHOC);
-       }
-
        err = libipw_networks_allocate(ieee);
        if (err) {
                LIBIPW_ERROR("Unable to allocate beacon storage: %d\n", err);
-               goto failed_free_wiphy;
+               goto failed_free_netdev;
        }
        libipw_networks_initialize(ieee);
 
@@ -217,31 +193,19 @@ struct net_device *alloc_ieee80211(int sizeof_priv, int monitor)
 
        return dev;
 
-failed_free_wiphy:
-       if (!monitor)
-               wiphy_free(ieee->wdev.wiphy);
 failed_free_netdev:
        free_netdev(dev);
 failed:
        return NULL;
 }
 
-void free_ieee80211(struct net_device *dev, int monitor)
+void free_ieee80211(struct net_device *dev)
 {
        struct libipw_device *ieee = netdev_priv(dev);
 
        lib80211_crypt_info_free(&ieee->crypt_info);
 
        libipw_networks_free(ieee);
-
-       /* free cfg80211 resources */
-       if (!monitor) {
-               wiphy_unregister(ieee->wdev.wiphy);
-               kfree(ieee->a_band.channels);
-               kfree(ieee->bg_band.channels);
-               wiphy_free(ieee->wdev.wiphy);
-       }
-
        free_netdev(dev);
 }
 
index 2716b91ba9fa753b879c80e0de57ae430356a575..950267ab556a96a5abfd225866a9267955900a28 100644 (file)
@@ -161,5 +161,6 @@ struct iwl_cfg iwl1000_bgn_cfg = {
        .max_ll_items = OTP_MAX_LL_ITEMS_1000,
        .shadow_ram_support = false,
        .ht_greenfield_support = true,
+       .use_rts_for_ht = true, /* use rts/cts protection */
 };
 
index c295b8ee922896ab16be8812bef15b0641b7cf2f..1473452ba22fc21a18c171f39a20e858d97aab3c 100644 (file)
@@ -175,6 +175,7 @@ struct iwl_cfg iwl6000h_2agn_cfg = {
        .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
        .shadow_ram_support = true,
        .ht_greenfield_support = true,
+       .use_rts_for_ht = true, /* use rts/cts protection */
 };
 
 /*
@@ -198,6 +199,7 @@ struct iwl_cfg iwl6000i_2agn_cfg = {
        .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
        .shadow_ram_support = true,
        .ht_greenfield_support = true,
+       .use_rts_for_ht = true, /* use rts/cts protection */
 };
 
 struct iwl_cfg iwl6050_2agn_cfg = {
@@ -218,6 +220,7 @@ struct iwl_cfg iwl6050_2agn_cfg = {
        .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
        .shadow_ram_support = true,
        .ht_greenfield_support = true,
+       .use_rts_for_ht = true, /* use rts/cts protection */
 };
 
 struct iwl_cfg iwl6000_3agn_cfg = {
@@ -238,6 +241,7 @@ struct iwl_cfg iwl6000_3agn_cfg = {
        .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
        .shadow_ram_support = true,
        .ht_greenfield_support = true,
+       .use_rts_for_ht = true, /* use rts/cts protection */
 };
 
 struct iwl_cfg iwl6050_3agn_cfg = {
@@ -258,6 +262,7 @@ struct iwl_cfg iwl6050_3agn_cfg = {
        .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
        .shadow_ram_support = true,
        .ht_greenfield_support = true,
+       .use_rts_for_ht = true, /* use rts/cts protection */
 };
 
 MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX));
index 346dc06fa7b77f79f5cdd986653e19b8d547bf56..81726ee32858e131e45f9bb57ba3be62de9d4247 100644 (file)
@@ -418,6 +418,15 @@ static void rs_tl_turn_on_agg(struct iwl_priv *priv, u8 tid,
        else if (tid == IWL_AGG_ALL_TID)
                for (tid = 0; tid < TID_MAX_LOAD_COUNT; tid++)
                        rs_tl_turn_on_agg_for_tid(priv, lq_data, tid, sta);
+       if (priv->cfg->use_rts_for_ht) {
+               /*
+                * switch to RTS/CTS if it is the prefer protection method
+                * for HT traffic
+                */
+               IWL_DEBUG_HT(priv, "use RTS/CTS protection for HT\n");
+               priv->staging_rxon.flags &= ~RXON_FLG_SELF_CTS_EN;
+               iwlcore_commit_rxon(priv);
+       }
 }
 
 static inline int get_num_of_ant_from_rate(u32 rate_n_flags)
index eaafae091f5bd48bfc3eec8d323e2a210864c54a..921dc4a26fe2eef00455865f996cf91d67d17bd3 100644 (file)
@@ -116,9 +116,6 @@ int iwl_commit_rxon(struct iwl_priv *priv)
 
        /* always get timestamp with Rx frame */
        priv->staging_rxon.flags |= RXON_FLG_TSF2HOST_MSK;
-       /* allow CTS-to-self if possible. this is relevant only for
-        * 5000, but will not damage 4965 */
-       priv->staging_rxon.flags |= RXON_FLG_SELF_CTS_EN;
 
        ret = iwl_check_rxon_cmd(priv);
        if (ret) {
@@ -218,6 +215,13 @@ int iwl_commit_rxon(struct iwl_priv *priv)
                                        "Could not send WEP static key.\n");
                }
 
+               /*
+                * allow CTS-to-self if possible for new association.
+                * this is relevant only for 5000 series and up,
+                * but will not damage 4965
+                */
+               priv->staging_rxon.flags |= RXON_FLG_SELF_CTS_EN;
+
                /* Apply the new configuration
                 * RXON assoc doesn't clear the station table in uCode,
                 */
index e50103a956b1052015ddcd072e557e4f694c0540..7754538c2194f3068019295270f1c6e4527a1b64 100644 (file)
@@ -213,6 +213,7 @@ struct iwl_mod_params {
  * @pa_type: used by 6000 series only to identify the type of Power Amplifier
  * @max_ll_items: max number of OTP blocks
  * @shadow_ram_support: shadow support for OTP memory
+ * @use_rts_for_ht: use rts/cts protection for HT traffic
  *
  * We enable the driver to be backward compatible wrt API version. The
  * driver specifies which APIs it supports (with @ucode_api_max being the
@@ -255,6 +256,7 @@ struct iwl_cfg {
        const bool shadow_ram_support;
        const bool ht_greenfield_support;
        const bool broken_powersave;
+       bool use_rts_for_ht;
 };
 
 /***************************
index fb9bcfa6d9471e057bac4a2d7e98237c451c03e0..b7e196e3c8d37e1671171e2cacecf86a99306dcc 100644 (file)
@@ -1277,8 +1277,16 @@ int iwl_tx_agg_stop(struct iwl_priv *priv , const u8 *ra, u16 tid)
                return -ENXIO;
        }
 
+       if (priv->stations[sta_id].tid[tid].agg.state ==
+                               IWL_EMPTYING_HW_QUEUE_ADDBA) {
+               IWL_DEBUG_HT(priv, "AGG stop before setup done\n");
+               ieee80211_stop_tx_ba_cb_irqsafe(priv->hw, ra, tid);
+               priv->stations[sta_id].tid[tid].agg.state = IWL_AGG_OFF;
+               return 0;
+       }
+
        if (priv->stations[sta_id].tid[tid].agg.state != IWL_AGG_ON)
-               IWL_WARN(priv, "Stopping AGG while state not IWL_AGG_ON\n");
+               IWL_WARN(priv, "Stopping AGG while state not ON or starting\n");
 
        tid_data = &priv->stations[sta_id].tid[tid];
        ssn = (tid_data->seq_number & IEEE80211_SCTL_SEQ) >> 4;
index 039b555e4d7630336f4ea9750a796566f9255cdf..53d56ab83c03cb54411885b5f26e67e943030b46 100644 (file)
@@ -169,16 +169,19 @@ static int lbs_ethtool_set_wol(struct net_device *dev,
        struct lbs_private *priv = dev->ml_priv;
        uint32_t criteria = 0;
 
-       if (priv->wol_criteria == 0xffffffff && wol->wolopts)
-               return -EOPNOTSUPP;
-
        if (wol->wolopts & ~(WAKE_UCAST|WAKE_MCAST|WAKE_BCAST|WAKE_PHY))
                return -EOPNOTSUPP;
 
-       if (wol->wolopts & WAKE_UCAST) criteria |= EHS_WAKE_ON_UNICAST_DATA;
-       if (wol->wolopts & WAKE_MCAST) criteria |= EHS_WAKE_ON_MULTICAST_DATA;
-       if (wol->wolopts & WAKE_BCAST) criteria |= EHS_WAKE_ON_BROADCAST_DATA;
-       if (wol->wolopts & WAKE_PHY)   criteria |= EHS_WAKE_ON_MAC_EVENT;
+       if (wol->wolopts & WAKE_UCAST)
+               criteria |= EHS_WAKE_ON_UNICAST_DATA;
+       if (wol->wolopts & WAKE_MCAST)
+               criteria |= EHS_WAKE_ON_MULTICAST_DATA;
+       if (wol->wolopts & WAKE_BCAST)
+               criteria |= EHS_WAKE_ON_BROADCAST_DATA;
+       if (wol->wolopts & WAKE_PHY)
+               criteria |= EHS_WAKE_ON_MAC_EVENT;
+       if (wol->wolopts == 0)
+               criteria |= EHS_REMOVE_WAKEUP;
 
        return lbs_host_sleep_cfg(priv, criteria, (struct wol_config *)NULL);
 }
index 62381768f2d599e2ff65932a09908d3b1c5ddaa0..b1d84592b959d742a22cd890e726be4392caaf54 100644 (file)
@@ -590,7 +590,7 @@ static int if_cs_prog_helper(struct if_cs_card *card)
 
        /* TODO: make firmware file configurable */
        ret = request_firmware(&fw, "libertas_cs_helper.fw",
-               &handle_to_dev(card->p_dev));
+               &card->p_dev->dev);
        if (ret) {
                lbs_pr_err("can't load helper firmware\n");
                ret = -ENODEV;
@@ -663,7 +663,7 @@ static int if_cs_prog_real(struct if_cs_card *card)
 
        /* TODO: make firmware file configurable */
        ret = request_firmware(&fw, "libertas_cs.fw",
-               &handle_to_dev(card->p_dev));
+               &card->p_dev->dev);
        if (ret) {
                lbs_pr_err("can't load firmware\n");
                ret = -ENODEV;
@@ -793,18 +793,37 @@ static void if_cs_release(struct pcmcia_device *p_dev)
  * configure the card at this point -- we wait until we receive a card
  * insertion event.
  */
+
+static int if_cs_ioprobe(struct pcmcia_device *p_dev,
+                        cistpl_cftable_entry_t *cfg,
+                        cistpl_cftable_entry_t *dflt,
+                        unsigned int vcc,
+                        void *priv_data)
+{
+       p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
+       p_dev->io.BasePort1 = cfg->io.win[0].base;
+       p_dev->io.NumPorts1 = cfg->io.win[0].len;
+
+       /* Do we need to allocate an interrupt? */
+       if (cfg->irq.IRQInfo1)
+               p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
+
+       /* IO window settings */
+       if (cfg->io.nwin != 1) {
+               lbs_pr_err("wrong CIS (check number of IO windows)\n");
+               return -ENODEV;
+       }
+
+       /* This reserves IO space but doesn't actually enable it */
+       return pcmcia_request_io(p_dev, &p_dev->io);
+}
+
 static int if_cs_probe(struct pcmcia_device *p_dev)
 {
        int ret = -ENOMEM;
        unsigned int prod_id;
        struct lbs_private *priv;
        struct if_cs_card *card;
-       /* CIS parsing */
-       tuple_t tuple;
-       cisparse_t parse;
-       cistpl_cftable_entry_t *cfg = &parse.cftable_entry;
-       cistpl_io_t *io = &cfg->io;
-       u_char buf[64];
 
        lbs_deb_enter(LBS_DEB_CS);
 
@@ -818,48 +837,15 @@ static int if_cs_probe(struct pcmcia_device *p_dev)
 
        p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
        p_dev->irq.Handler = NULL;
-       p_dev->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID;
 
        p_dev->conf.Attributes = 0;
        p_dev->conf.IntType = INT_MEMORY_AND_IO;
 
-       tuple.Attributes = 0;
-       tuple.TupleData = buf;
-       tuple.TupleDataMax = sizeof(buf);
-       tuple.TupleOffset = 0;
-
-       tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
-       if ((ret = pcmcia_get_first_tuple(p_dev, &tuple)) != 0 ||
-           (ret = pcmcia_get_tuple_data(p_dev, &tuple)) != 0 ||
-           (ret = pcmcia_parse_tuple(&tuple, &parse)) != 0)
-       {
-               lbs_pr_err("error in pcmcia_get_first_tuple etc\n");
-               goto out1;
-       }
-
-       p_dev->conf.ConfigIndex = cfg->index;
-
-       /* Do we need to allocate an interrupt? */
-       if (cfg->irq.IRQInfo1) {
-               p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
-       }
-
-       /* IO window settings */
-       if (cfg->io.nwin != 1) {
-               lbs_pr_err("wrong CIS (check number of IO windows)\n");
-               ret = -ENODEV;
+       if (pcmcia_loop_config(p_dev, if_cs_ioprobe, NULL)) {
+               lbs_pr_err("error in pcmcia_loop_config\n");
                goto out1;
        }
-       p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
-       p_dev->io.BasePort1 = io->win[0].base;
-       p_dev->io.NumPorts1 = io->win[0].len;
 
-       /* This reserves IO space but doesn't actually enable it */
-       ret = pcmcia_request_io(p_dev, &p_dev->io);
-       if (ret) {
-               lbs_pr_err("error in pcmcia_request_io\n");
-               goto out1;
-       }
 
        /*
         * Allocate an interrupt line.  Note that this does not assign
index 9498b46c99a48d1355eedd18b8044f3402432156..e61e6b9440abec403af70d32efb8c99961021af5 100644 (file)
@@ -145,23 +145,6 @@ static const unsigned int txConfEUD    = 0x10; /* Enable Uni-Data packets */
 static const unsigned int txConfKey    = 0x02; /* Scramble data packets */
 static const unsigned int txConfLoop   = 0x01; /* Loopback mode */
 
-/*
-   All the PCMCIA modules use PCMCIA_DEBUG to control debugging.  If
-   you do not define PCMCIA_DEBUG at all, all the debug code will be
-   left out.  If you compile with PCMCIA_DEBUG=0, the debug code will
-   be present but disabled -- but it can then be enabled for specific
-   modules at load time with a 'pc_debug=#' option to insmod.
-*/
-
-#ifdef PCMCIA_DEBUG
-static int pc_debug = PCMCIA_DEBUG;
-module_param(pc_debug, int, 0);
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
-static char *version =
-"netwave_cs.c 0.3.0 Thu Jul 17 14:36:02 1997 (John Markus Bjørndalen)\n";
-#else
-#define DEBUG(n, args...)
-#endif
 
 /*====================================================================*/
 
@@ -383,7 +366,7 @@ static int netwave_probe(struct pcmcia_device *link)
     struct net_device *dev;
     netwave_private *priv;
 
-    DEBUG(0, "netwave_attach()\n");
+    dev_dbg(&link->dev, "netwave_attach()\n");
 
     /* Initialize the struct pcmcia_device structure */
     dev = alloc_etherdev(sizeof(netwave_private));
@@ -401,8 +384,7 @@ static int netwave_probe(struct pcmcia_device *link)
     link->io.IOAddrLines = 5;
     
     /* Interrupt setup */
-    link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
-    link->irq.IRQInfo1 = IRQ_LEVEL_ID;
+    link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
     link->irq.Handler = &netwave_interrupt;
     
     /* General socket configuration */
@@ -421,8 +403,6 @@ static int netwave_probe(struct pcmcia_device *link)
 
     dev->watchdog_timeo = TX_TIMEOUT;
 
-    link->irq.Instance = dev;
-
     return netwave_pcmcia_config( link);
 } /* netwave_attach */
 
@@ -438,7 +418,7 @@ static void netwave_detach(struct pcmcia_device *link)
 {
        struct net_device *dev = link->priv;
 
-       DEBUG(0, "netwave_detach(0x%p)\n", link);
+       dev_dbg(&link->dev, "netwave_detach\n");
 
        netwave_release(link);
 
@@ -725,18 +705,15 @@ static const struct iw_handler_def        netwave_handler_def =
  *
  */
 
-#define CS_CHECK(fn, ret) \
-do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
-
 static int netwave_pcmcia_config(struct pcmcia_device *link) {
     struct net_device *dev = link->priv;
     netwave_private *priv = netdev_priv(dev);
-    int i, j, last_ret, last_fn;
+    int i, j, ret;
     win_req_t req;
     memreq_t mem;
     u_char __iomem *ramBase = NULL;
 
-    DEBUG(0, "netwave_pcmcia_config(0x%p)\n", link);
+    dev_dbg(&link->dev, "netwave_pcmcia_config\n");
 
     /*
      *  Try allocating IO ports.  This tries a few fixed addresses.
@@ -749,22 +726,24 @@ static int netwave_pcmcia_config(struct pcmcia_device *link) {
        if (i == 0)
                break;
     }
-    if (i != 0) {
-       cs_error(link, RequestIO, i);
+    if (i != 0)
        goto failed;
-    }
 
     /*
      *  Now allocate an interrupt line.  Note that this does not
      *  actually assign a handler to the interrupt.
      */
-    CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
+    ret = pcmcia_request_irq(link, &link->irq);
+    if (ret)
+           goto failed;
 
     /*
      *  This actually configures the PCMCIA socket -- setting up
      *  the I/O windows and the interrupt mapping.
      */
-    CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
+    ret = pcmcia_request_configuration(link, &link->conf);
+    if (ret)
+           goto failed;
 
     /*
      *  Allocate a 32K memory window.  Note that the struct pcmcia_device
@@ -772,14 +751,18 @@ static int netwave_pcmcia_config(struct pcmcia_device *link) {
      *  device needs several windows, you'll need to keep track of
      *  the handles in your private data structure, dev->priv.
      */
-    DEBUG(1, "Setting mem speed of %d\n", mem_speed);
+    dev_dbg(&link->dev, "Setting mem speed of %d\n", mem_speed);
 
     req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_CM|WIN_ENABLE;
     req.Base = 0; req.Size = 0x8000;
     req.AccessSpeed = mem_speed;
-    CS_CHECK(RequestWindow, pcmcia_request_window(&link, &req, &link->win));
+    ret = pcmcia_request_window(link, &req, &link->win);
+    if (ret)
+           goto failed;
     mem.CardOffset = 0x20000; mem.Page = 0; 
-    CS_CHECK(MapMemPage, pcmcia_map_mem_page(link->win, &mem));
+    ret = pcmcia_map_mem_page(link, link->win, &mem);
+    if (ret)
+           goto failed;
 
     /* Store base address of the common window frame */
     ramBase = ioremap(req.Base, 0x8000);
@@ -787,7 +770,7 @@ static int netwave_pcmcia_config(struct pcmcia_device *link) {
 
     dev->irq = link->irq.AssignedIRQ;
     dev->base_addr = link->io.BasePort1;
-    SET_NETDEV_DEV(dev, &handle_to_dev(link));
+    SET_NETDEV_DEV(dev, &link->dev);
 
     if (register_netdev(dev) != 0) {
        printk(KERN_DEBUG "netwave_cs: register_netdev() failed\n");
@@ -818,8 +801,6 @@ static int netwave_pcmcia_config(struct pcmcia_device *link) {
           get_uint16(ramBase + NETWAVE_EREG_ARW+2));
     return 0;
 
-cs_failed:
-    cs_error(link, last_fn, last_ret);
 failed:
     netwave_release(link);
     return -ENODEV;
@@ -837,7 +818,7 @@ static void netwave_release(struct pcmcia_device *link)
        struct net_device *dev = link->priv;
        netwave_private *priv = netdev_priv(dev);
 
-       DEBUG(0, "netwave_release(0x%p)\n", link);
+       dev_dbg(&link->dev, "netwave_release\n");
 
        pcmcia_disable_device(link);
        if (link->win)
@@ -892,7 +873,7 @@ static void netwave_reset(struct net_device *dev) {
     u_char __iomem *ramBase = priv->ramBase;
     unsigned int iobase = dev->base_addr;
 
-    DEBUG(0, "netwave_reset: Done with hardware reset\n");
+    pr_debug("netwave_reset: Done with hardware reset\n");
 
     priv->timeoutCounter = 0;
 
@@ -988,7 +969,7 @@ static int netwave_hw_xmit(unsigned char* data, int len,
 
     dev->stats.tx_bytes += len;
 
-    DEBUG(3, "Transmitting with SPCQ %x SPU %x LIF %x ISPLQ %x\n",
+    pr_debug("Transmitting with SPCQ %x SPU %x LIF %x ISPLQ %x\n",
          readb(ramBase + NETWAVE_EREG_SPCQ),
          readb(ramBase + NETWAVE_EREG_SPU),
          readb(ramBase + NETWAVE_EREG_LIF),
@@ -1000,7 +981,7 @@ static int netwave_hw_xmit(unsigned char* data, int len,
     MaxData    = get_uint16(ramBase + NETWAVE_EREG_TDP+2);
     DataOffset = get_uint16(ramBase + NETWAVE_EREG_TDP+4);
        
-    DEBUG(3, "TxFreeList %x, MaxData %x, DataOffset %x\n",
+    pr_debug("TxFreeList %x, MaxData %x, DataOffset %x\n",
          TxFreeList, MaxData, DataOffset);
 
     /* Copy packet to the adapter fragment buffers */
@@ -1088,7 +1069,7 @@ static irqreturn_t netwave_interrupt(int irq, void* dev_id)
         status = inb(iobase + NETWAVE_REG_ASR);
                
        if (!pcmcia_dev_present(link)) {
-           DEBUG(1, "netwave_interrupt: Interrupt with status 0x%x "
+           pr_debug("netwave_interrupt: Interrupt with status 0x%x "
                  "from removed or suspended card!\n", status);
            break;
        }
@@ -1132,7 +1113,7 @@ static irqreturn_t netwave_interrupt(int irq, void* dev_id)
            int txStatus;
 
            txStatus = readb(ramBase + NETWAVE_EREG_TSER);
-           DEBUG(3, "Transmit done. TSER = %x id %x\n", 
+           pr_debug("Transmit done. TSER = %x id %x\n",
                  txStatus, readb(ramBase + NETWAVE_EREG_TSER + 1));
            
            if (txStatus & 0x20) {
@@ -1156,7 +1137,7 @@ static irqreturn_t netwave_interrupt(int irq, void* dev_id)
                 *      TxGU and TxNOAP is set. (Those are the only ones
                 *      to set TxErr).
                 */
-               DEBUG(3, "netwave_interrupt: TxDN with error status %x\n", 
+               pr_debug("netwave_interrupt: TxDN with error status %x\n",
                      txStatus);
                
                /* Clear out TxGU, TxNOAP, TxErr and TxTrys */
@@ -1164,7 +1145,7 @@ static irqreturn_t netwave_interrupt(int irq, void* dev_id)
                writeb(0xdf & txStatus, ramBase+NETWAVE_EREG_TSER+4);
                ++dev->stats.tx_errors;
            }
-           DEBUG(3, "New status is TSER %x ASR %x\n",
+           pr_debug("New status is TSER %x ASR %x\n",
                  readb(ramBase + NETWAVE_EREG_TSER),
                  inb(iobase + NETWAVE_REG_ASR));
 
@@ -1172,7 +1153,7 @@ static irqreturn_t netwave_interrupt(int irq, void* dev_id)
        }
        /* TxBA, this would trigger on all error packets received */
        /* if (status & 0x01) {
-          DEBUG(4, "Transmit buffers available, %x\n", status);
+          pr_debug("Transmit buffers available, %x\n", status);
           }
           */
     }
@@ -1190,7 +1171,7 @@ static irqreturn_t netwave_interrupt(int irq, void* dev_id)
  */
 static void netwave_watchdog(struct net_device *dev) {
 
-    DEBUG(1, "%s: netwave_watchdog: watchdog timer expired\n", dev->name);
+    pr_debug("%s: netwave_watchdog: watchdog timer expired\n", dev->name);
     netwave_reset(dev);
     dev->trans_start = jiffies;
     netif_wake_queue(dev);
@@ -1211,7 +1192,7 @@ static int netwave_rx(struct net_device *dev)
     int i;
     u_char *ptr;
        
-    DEBUG(3, "xinw_rx: Receiving ... \n");
+    pr_debug("xinw_rx: Receiving ... \n");
 
     /* Receive max 10 packets for now. */
     for (i = 0; i < 10; i++) {
@@ -1237,7 +1218,7 @@ static int netwave_rx(struct net_device *dev)
                
        skb = dev_alloc_skb(rcvLen+5);
        if (skb == NULL) {
-           DEBUG(1, "netwave_rx: Could not allocate an sk_buff of "
+           pr_debug("netwave_rx: Could not allocate an sk_buff of "
                  "length %d\n", rcvLen);
            ++dev->stats.rx_dropped;
            /* Tell the adapter to skip the packet */
@@ -1279,7 +1260,7 @@ static int netwave_rx(struct net_device *dev)
        wait_WOC(iobase);
        writeb(NETWAVE_CMD_SRP, ramBase + NETWAVE_EREG_CB + 0);
        writeb(NETWAVE_CMD_EOC, ramBase + NETWAVE_EREG_CB + 1);
-       DEBUG(3, "Packet reception ok\n");
+       pr_debug("Packet reception ok\n");
     }
     return 0;
 }
@@ -1288,7 +1269,7 @@ static int netwave_open(struct net_device *dev) {
     netwave_private *priv = netdev_priv(dev);
     struct pcmcia_device *link = priv->p_dev;
 
-    DEBUG(1, "netwave_open: starting.\n");
+    dev_dbg(&link->dev, "netwave_open: starting.\n");
     
     if (!pcmcia_dev_present(link))
        return -ENODEV;
@@ -1305,7 +1286,7 @@ static int netwave_close(struct net_device *dev) {
     netwave_private *priv = netdev_priv(dev);
     struct pcmcia_device *link = priv->p_dev;
 
-    DEBUG(1, "netwave_close: finishing.\n");
+    dev_dbg(&link->dev, "netwave_close: finishing.\n");
 
     link->open--;
     netif_stop_queue(dev);
@@ -1358,11 +1339,11 @@ static void set_multicast_list(struct net_device *dev)
     u_char  rcvMode = 0;
    
 #ifdef PCMCIA_DEBUG
-    if (pc_debug > 2) {
-       static int old;
+    {
+       xstatic int old;
        if (old != dev->mc_count) {
            old = dev->mc_count;
-           DEBUG(0, "%s: setting Rx mode to %d addresses.\n",
+           pr_debug("%s: setting Rx mode to %d addresses.\n",
                  dev->name, dev->mc_count);
        }
     }
index 38c1c9d2abb85dd43b6f7627699f5af135fd1a53..f27bb8367c983e2efc3019223b2d52d835394cd3 100644 (file)
@@ -109,7 +109,7 @@ orinoco_cs_probe(struct pcmcia_device *link)
        struct orinoco_private *priv;
        struct orinoco_pccard *card;
 
-       priv = alloc_orinocodev(sizeof(*card), &handle_to_dev(link),
+       priv = alloc_orinocodev(sizeof(*card), &link->dev,
                                orinoco_cs_hard_reset, NULL);
        if (!priv)
                return -ENOMEM;
@@ -120,10 +120,8 @@ orinoco_cs_probe(struct pcmcia_device *link)
        link->priv = priv;
 
        /* Interrupt setup */
-       link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
-       link->irq.IRQInfo1 = IRQ_LEVEL_ID;
+       link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
        link->irq.Handler = orinoco_interrupt;
-       link->irq.Instance = priv;
 
        /* General socket configuration defaults can go here.  In this
         * client, we assume very little, and rely on the CIS for
@@ -160,12 +158,6 @@ static void orinoco_cs_detach(struct pcmcia_device *link)
  * device available to the system.
  */
 
-#define CS_CHECK(fn, ret) do { \
-       last_fn = (fn); \
-       if ((last_ret = (ret)) != 0) \
-               goto cs_failed; \
-} while (0)
-
 static int orinoco_cs_config_check(struct pcmcia_device *p_dev,
                                   cistpl_cftable_entry_t *cfg,
                                   cistpl_cftable_entry_t *dflt,
@@ -240,7 +232,7 @@ orinoco_cs_config(struct pcmcia_device *link)
        struct orinoco_private *priv = link->priv;
        struct orinoco_pccard *card = priv->card;
        hermes_t *hw = &priv->hw;
-       int last_fn, last_ret;
+       int ret;
        void __iomem *mem;
 
        /*
@@ -257,13 +249,12 @@ orinoco_cs_config(struct pcmcia_device *link)
         * and most client drivers will only use the CIS to fill in
         * implementation-defined details.
         */
-       last_ret = pcmcia_loop_config(link, orinoco_cs_config_check, NULL);
-       if (last_ret) {
+       ret = pcmcia_loop_config(link, orinoco_cs_config_check, NULL);
+       if (ret) {
                if (!ignore_cis_vcc)
                        printk(KERN_ERR PFX "GetNextTuple(): No matching "
                               "CIS configuration.  Maybe you need the "
                               "ignore_cis_vcc=1 parameter.\n");
-               cs_error(link, RequestIO, last_ret);
                goto failed;
        }
 
@@ -272,14 +263,16 @@ orinoco_cs_config(struct pcmcia_device *link)
         * a handler to the interrupt, unless the 'Handler' member of
         * the irq structure is initialized.
         */
-       CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
+       ret = pcmcia_request_irq(link, &link->irq);
+       if (ret)
+               goto failed;
 
        /* We initialize the hermes structure before completing PCMCIA
         * configuration just in case the interrupt handler gets
         * called. */
        mem = ioport_map(link->io.BasePort1, link->io.NumPorts1);
        if (!mem)
-               goto cs_failed;
+               goto failed;
 
        hermes_struct_init(hw, mem, HERMES_16BIT_REGSPACING);
 
@@ -288,8 +281,9 @@ orinoco_cs_config(struct pcmcia_device *link)
         * the I/O windows and the interrupt mapping, and putting the
         * card and host interface into "Memory and IO" mode.
         */
-       CS_CHECK(RequestConfiguration,
-                pcmcia_request_configuration(link, &link->conf));
+       ret = pcmcia_request_configuration(link, &link->conf);
+       if (ret)
+               goto failed;
 
        /* Ok, we have the configuration, prepare to register the netdev */
        card->node.major = card->node.minor = 0;
@@ -315,9 +309,6 @@ orinoco_cs_config(struct pcmcia_device *link)
                                       * net_device has been registered */
        return 0;
 
- cs_failed:
-       cs_error(link, last_fn, last_ret);
-
  failed:
        orinoco_cs_release(link);
        return -ENODEV;
index c361310b885d83b0fb076fc0cdfd2f0cfa5bb15a..59bda240fdc228712490e6dfe7a0bea1d0b4c3f4 100644 (file)
@@ -73,9 +73,6 @@ static void spectrum_cs_release(struct pcmcia_device *link);
 #define HCR_MEM16      0x10    /* memory width bit, should be preserved */
 
 
-#define CS_CHECK(fn, ret) \
-  do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
-
 /*
  * Reset the card using configuration registers COR and CCSR.
  * If IDLE is 1, stop the firmware, so that it can be safely rewritten.
@@ -83,7 +80,7 @@ static void spectrum_cs_release(struct pcmcia_device *link);
 static int
 spectrum_reset(struct pcmcia_device *link, int idle)
 {
-       int last_ret, last_fn;
+       int ret;
        conf_reg_t reg;
        u_int save_cor;
 
@@ -95,23 +92,26 @@ spectrum_reset(struct pcmcia_device *link, int idle)
        reg.Function = 0;
        reg.Action = CS_READ;
        reg.Offset = CISREG_COR;
-       CS_CHECK(AccessConfigurationRegister,
-                pcmcia_access_configuration_register(link, &reg));
+       ret = pcmcia_access_configuration_register(link, &reg);
+       if (ret)
+               goto failed;
        save_cor = reg.Value;
 
        /* Soft-Reset card */
        reg.Action = CS_WRITE;
        reg.Offset = CISREG_COR;
        reg.Value = (save_cor | COR_SOFT_RESET);
-       CS_CHECK(AccessConfigurationRegister,
-                pcmcia_access_configuration_register(link, &reg));
+       ret = pcmcia_access_configuration_register(link, &reg);
+       if (ret)
+               goto failed;
        udelay(1000);
 
        /* Read CCSR */
        reg.Action = CS_READ;
        reg.Offset = CISREG_CCSR;
-       CS_CHECK(AccessConfigurationRegister,
-                pcmcia_access_configuration_register(link, &reg));
+       ret = pcmcia_access_configuration_register(link, &reg);
+       if (ret)
+               goto failed;
 
        /*
         * Start or stop the firmware.  Memory width bit should be
@@ -120,21 +120,22 @@ spectrum_reset(struct pcmcia_device *link, int idle)
        reg.Action = CS_WRITE;
        reg.Offset = CISREG_CCSR;
        reg.Value = (idle ? HCR_IDLE : HCR_RUN) | (reg.Value & HCR_MEM16);
-       CS_CHECK(AccessConfigurationRegister,
-                pcmcia_access_configuration_register(link, &reg));
+       ret = pcmcia_access_configuration_register(link, &reg);
+       if (ret)
+               goto failed;
        udelay(1000);
 
        /* Restore original COR configuration index */
        reg.Action = CS_WRITE;
        reg.Offset = CISREG_COR;
        reg.Value = (save_cor & ~COR_SOFT_RESET);
-       CS_CHECK(AccessConfigurationRegister,
-                pcmcia_access_configuration_register(link, &reg));
+       ret = pcmcia_access_configuration_register(link, &reg);
+       if (ret)
+               goto failed;
        udelay(1000);
        return 0;
 
-cs_failed:
-       cs_error(link, last_fn, last_ret);
+failed:
        return -ENODEV;
 }
 
@@ -181,7 +182,7 @@ spectrum_cs_probe(struct pcmcia_device *link)
        struct orinoco_private *priv;
        struct orinoco_pccard *card;
 
-       priv = alloc_orinocodev(sizeof(*card), &handle_to_dev(link),
+       priv = alloc_orinocodev(sizeof(*card), &link->dev,
                                spectrum_cs_hard_reset,
                                spectrum_cs_stop_firmware);
        if (!priv)
@@ -193,10 +194,8 @@ spectrum_cs_probe(struct pcmcia_device *link)
        link->priv = priv;
 
        /* Interrupt setup */
-       link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
-       link->irq.IRQInfo1 = IRQ_LEVEL_ID;
+       link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
        link->irq.Handler = orinoco_interrupt;
-       link->irq.Instance = priv;
 
        /* General socket configuration defaults can go here.  In this
         * client, we assume very little, and rely on the CIS for
@@ -307,7 +306,7 @@ spectrum_cs_config(struct pcmcia_device *link)
        struct orinoco_private *priv = link->priv;
        struct orinoco_pccard *card = priv->card;
        hermes_t *hw = &priv->hw;
-       int last_fn, last_ret;
+       int ret;
        void __iomem *mem;
 
        /*
@@ -324,13 +323,12 @@ spectrum_cs_config(struct pcmcia_device *link)
         * and most client drivers will only use the CIS to fill in
         * implementation-defined details.
         */
-       last_ret = pcmcia_loop_config(link, spectrum_cs_config_check, NULL);
-       if (last_ret) {
+       ret = pcmcia_loop_config(link, spectrum_cs_config_check, NULL);
+       if (ret) {
                if (!ignore_cis_vcc)
                        printk(KERN_ERR PFX "GetNextTuple(): No matching "
                               "CIS configuration.  Maybe you need the "
                               "ignore_cis_vcc=1 parameter.\n");
-               cs_error(link, RequestIO, last_ret);
                goto failed;
        }
 
@@ -339,14 +337,16 @@ spectrum_cs_config(struct pcmcia_device *link)
         * a handler to the interrupt, unless the 'Handler' member of
         * the irq structure is initialized.
         */
-       CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
+       ret = pcmcia_request_irq(link, &link->irq);
+       if (ret)
+               goto failed;
 
        /* We initialize the hermes structure before completing PCMCIA
         * configuration just in case the interrupt handler gets
         * called. */
        mem = ioport_map(link->io.BasePort1, link->io.NumPorts1);
        if (!mem)
-               goto cs_failed;
+               goto failed;
 
        hermes_struct_init(hw, mem, HERMES_16BIT_REGSPACING);
 
@@ -355,8 +355,9 @@ spectrum_cs_config(struct pcmcia_device *link)
         * the I/O windows and the interrupt mapping, and putting the
         * card and host interface into "Memory and IO" mode.
         */
-       CS_CHECK(RequestConfiguration,
-                pcmcia_request_configuration(link, &link->conf));
+       ret = pcmcia_request_configuration(link, &link->conf);
+       if (ret)
+               goto failed;
 
        /* Ok, we have the configuration, prepare to register the netdev */
        card->node.major = card->node.minor = 0;
@@ -386,9 +387,6 @@ spectrum_cs_config(struct pcmcia_device *link)
                                       * net_device has been registered */
        return 0;
 
- cs_failed:
-       cs_error(link, last_fn, last_ret);
-
  failed:
        spectrum_cs_release(link);
        return -ENODEV;
index 17e199546eebca34e7089e93382739005e7241fc..92af9b96bb7a2bb51f3adba3316db4ca86bf1beb 100644 (file)
@@ -426,12 +426,16 @@ static const char p54u_romboot_3887[] = "~~~~";
 static int p54u_firmware_reset_3887(struct ieee80211_hw *dev)
 {
        struct p54u_priv *priv = dev->priv;
-       u8 buf[4];
+       u8 *buf;
        int ret;
 
-       memcpy(&buf, p54u_romboot_3887, sizeof(buf));
+       buf = kmalloc(4, GFP_KERNEL);
+       if (!buf)
+               return -ENOMEM;
+       memcpy(buf, p54u_romboot_3887, 4);
        ret = p54u_bulk_msg(priv, P54U_PIPE_DATA,
-                           buf, sizeof(buf));
+                           buf, 4);
+       kfree(buf);
        if (ret)
                dev_err(&priv->udev->dev, "(p54usb) unable to jump to "
                        "boot ROM (%d)!\n", ret);
index 1c88c2ea59aa4e605fc738f8adde1e2d01ea26cb..5b8e3e4cdd9f15a2cf0d278f73eb666ae338173d 100644 (file)
@@ -71,25 +71,7 @@ typedef u_char mac_addr[ETH_ALEN];   /* Hardware address */
 #include "rayctl.h"
 #include "ray_cs.h"
 
-/* All the PCMCIA modules use PCMCIA_DEBUG to control debugging.  If
-   you do not define PCMCIA_DEBUG at all, all the debug code will be
-   left out.  If you compile with PCMCIA_DEBUG=0, the debug code will
-   be present but disabled -- but it can then be enabled for specific
-   modules at load time with a 'pc_debug=#' option to insmod.
-*/
 
-#ifdef RAYLINK_DEBUG
-#define PCMCIA_DEBUG RAYLINK_DEBUG
-#endif
-#ifdef PCMCIA_DEBUG
-static int ray_debug;
-static int pc_debug = PCMCIA_DEBUG;
-module_param(pc_debug, int, 0);
-/* #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args); */
-#define DEBUG(n, args...) if (pc_debug > (n)) printk(args);
-#else
-#define DEBUG(n, args...)
-#endif
 /** Prototypes based on PCMCIA skeleton driver *******************************/
 static int ray_config(struct pcmcia_device *link);
 static void ray_release(struct pcmcia_device *link);
@@ -325,7 +307,7 @@ static int ray_probe(struct pcmcia_device *p_dev)
        ray_dev_t *local;
        struct net_device *dev;
 
-       DEBUG(1, "ray_attach()\n");
+       dev_dbg(&p_dev->dev, "ray_attach()\n");
 
        /* Allocate space for private device-specific data */
        dev = alloc_etherdev(sizeof(ray_dev_t));
@@ -341,8 +323,7 @@ static int ray_probe(struct pcmcia_device *p_dev)
        p_dev->io.IOAddrLines = 5;
 
        /* Interrupt setup. For PCMCIA, driver takes what's given */
-       p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
-       p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID;
+       p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
        p_dev->irq.Handler = &ray_interrupt;
 
        /* General socket configuration */
@@ -351,13 +332,12 @@ static int ray_probe(struct pcmcia_device *p_dev)
        p_dev->conf.ConfigIndex = 1;
 
        p_dev->priv = dev;
-       p_dev->irq.Instance = dev;
 
        local->finder = p_dev;
        local->card_status = CARD_INSERTED;
        local->authentication_state = UNAUTHENTICATED;
        local->num_multi = 0;
-       DEBUG(2, "ray_attach p_dev = %p,  dev = %p,  local = %p, intr = %p\n",
+       dev_dbg(&p_dev->dev, "ray_attach p_dev = %p,  dev = %p,  local = %p, intr = %p\n",
              p_dev, dev, local, &ray_interrupt);
 
        /* Raylink entries in the device structure */
@@ -370,7 +350,7 @@ static int ray_probe(struct pcmcia_device *p_dev)
 #endif /* WIRELESS_SPY */
 
 
-       DEBUG(2, "ray_cs ray_attach calling ether_setup.)\n");
+       dev_dbg(&p_dev->dev, "ray_cs ray_attach calling ether_setup.)\n");
        netif_stop_queue(dev);
 
        init_timer(&local->timer);
@@ -393,7 +373,7 @@ static void ray_detach(struct pcmcia_device *link)
        struct net_device *dev;
        ray_dev_t *local;
 
-       DEBUG(1, "ray_detach(0x%p)\n", link);
+       dev_dbg(&link->dev, "ray_detach\n");
 
        this_device = NULL;
        dev = link->priv;
@@ -408,7 +388,7 @@ static void ray_detach(struct pcmcia_device *link)
                        unregister_netdev(dev);
                free_netdev(dev);
        }
-       DEBUG(2, "ray_cs ray_detach ending\n");
+       dev_dbg(&link->dev, "ray_cs ray_detach ending\n");
 } /* ray_detach */
 
 /*=============================================================================
@@ -416,19 +396,17 @@ static void ray_detach(struct pcmcia_device *link)
     is received, to configure the PCMCIA socket, and to make the
     ethernet device available to the system.
 =============================================================================*/
-#define CS_CHECK(fn, ret) \
-do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
 #define MAX_TUPLE_SIZE 128
 static int ray_config(struct pcmcia_device *link)
 {
-       int last_fn = 0, last_ret = 0;
+       int ret = 0;
        int i;
        win_req_t req;
        memreq_t mem;
        struct net_device *dev = (struct net_device *)link->priv;
        ray_dev_t *local = netdev_priv(dev);
 
-       DEBUG(1, "ray_config(0x%p)\n", link);
+       dev_dbg(&link->dev, "ray_config\n");
 
        /* Determine card type and firmware version */
        printk(KERN_INFO "ray_cs Detected: %s%s%s%s\n",
@@ -440,14 +418,17 @@ static int ray_config(struct pcmcia_device *link)
        /* Now allocate an interrupt line.  Note that this does not
           actually assign a handler to the interrupt.
         */
-       CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
+       ret = pcmcia_request_irq(link, &link->irq);
+       if (ret)
+               goto failed;
        dev->irq = link->irq.AssignedIRQ;
 
        /* This actually configures the PCMCIA socket -- setting up
           the I/O windows and the interrupt mapping.
         */
-       CS_CHECK(RequestConfiguration,
-                pcmcia_request_configuration(link, &link->conf));
+       ret = pcmcia_request_configuration(link, &link->conf);
+       if (ret)
+               goto failed;
 
 /*** Set up 32k window for shared memory (transmit and control) ************/
        req.Attributes =
@@ -455,10 +436,14 @@ static int ray_config(struct pcmcia_device *link)
        req.Base = 0;
        req.Size = 0x8000;
        req.AccessSpeed = ray_mem_speed;
-       CS_CHECK(RequestWindow, pcmcia_request_window(&link, &req, &link->win));
+       ret = pcmcia_request_window(link, &req, &link->win);
+       if (ret)
+               goto failed;
        mem.CardOffset = 0x0000;
        mem.Page = 0;
-       CS_CHECK(MapMemPage, pcmcia_map_mem_page(link->win, &mem));
+       ret = pcmcia_map_mem_page(link, link->win, &mem);
+       if (ret)
+               goto failed;
        local->sram = ioremap(req.Base, req.Size);
 
 /*** Set up 16k window for shared memory (receive buffer) ***************/
@@ -467,11 +452,14 @@ static int ray_config(struct pcmcia_device *link)
        req.Base = 0;
        req.Size = 0x4000;
        req.AccessSpeed = ray_mem_speed;
-       CS_CHECK(RequestWindow,
-                pcmcia_request_window(&link, &req, &local->rmem_handle));
+       ret = pcmcia_request_window(link, &req, &local->rmem_handle);
+       if (ret)
+               goto failed;
        mem.CardOffset = 0x8000;
        mem.Page = 0;
-       CS_CHECK(MapMemPage, pcmcia_map_mem_page(local->rmem_handle, &mem));
+       ret = pcmcia_map_mem_page(link, local->rmem_handle, &mem);
+       if (ret)
+               goto failed;
        local->rmem = ioremap(req.Base, req.Size);
 
 /*** Set up window for attribute memory ***********************************/
@@ -480,22 +468,25 @@ static int ray_config(struct pcmcia_device *link)
        req.Base = 0;
        req.Size = 0x1000;
        req.AccessSpeed = ray_mem_speed;
-       CS_CHECK(RequestWindow,
-                pcmcia_request_window(&link, &req, &local->amem_handle));
+       ret = pcmcia_request_window(link, &req, &local->amem_handle);
+       if (ret)
+               goto failed;
        mem.CardOffset = 0x0000;
        mem.Page = 0;
-       CS_CHECK(MapMemPage, pcmcia_map_mem_page(local->amem_handle, &mem));
+       ret = pcmcia_map_mem_page(link, local->amem_handle, &mem);
+       if (ret)
+               goto failed;
        local->amem = ioremap(req.Base, req.Size);
 
-       DEBUG(3, "ray_config sram=%p\n", local->sram);
-       DEBUG(3, "ray_config rmem=%p\n", local->rmem);
-       DEBUG(3, "ray_config amem=%p\n", local->amem);
+       dev_dbg(&link->dev, "ray_config sram=%p\n", local->sram);
+       dev_dbg(&link->dev, "ray_config rmem=%p\n", local->rmem);
+       dev_dbg(&link->dev, "ray_config amem=%p\n", local->amem);
        if (ray_init(dev) < 0) {
                ray_release(link);
                return -ENODEV;
        }
 
-       SET_NETDEV_DEV(dev, &handle_to_dev(link));
+       SET_NETDEV_DEV(dev, &link->dev);
        i = register_netdev(dev);
        if (i != 0) {
                printk("ray_config register_netdev() failed\n");
@@ -511,9 +502,7 @@ static int ray_config(struct pcmcia_device *link)
 
        return 0;
 
-cs_failed:
-       cs_error(link, last_fn, last_ret);
-
+failed:
        ray_release(link);
        return -ENODEV;
 } /* ray_config */
@@ -543,9 +532,9 @@ static int ray_init(struct net_device *dev)
        struct ccs __iomem *pccs;
        ray_dev_t *local = netdev_priv(dev);
        struct pcmcia_device *link = local->finder;
-       DEBUG(1, "ray_init(0x%p)\n", dev);
+       dev_dbg(&link->dev, "ray_init(0x%p)\n", dev);
        if (!(pcmcia_dev_present(link))) {
-               DEBUG(0, "ray_init - device not present\n");
+               dev_dbg(&link->dev, "ray_init - device not present\n");
                return -1;
        }
 
@@ -567,13 +556,13 @@ static int ray_init(struct net_device *dev)
        local->fw_ver = local->startup_res.firmware_version[0];
        local->fw_bld = local->startup_res.firmware_version[1];
        local->fw_var = local->startup_res.firmware_version[2];
-       DEBUG(1, "ray_init firmware version %d.%d \n", local->fw_ver,
+       dev_dbg(&link->dev, "ray_init firmware version %d.%d \n", local->fw_ver,
              local->fw_bld);
 
        local->tib_length = 0x20;
        if ((local->fw_ver == 5) && (local->fw_bld >= 30))
                local->tib_length = local->startup_res.tib_length;
-       DEBUG(2, "ray_init tib_length = 0x%02x\n", local->tib_length);
+       dev_dbg(&link->dev, "ray_init tib_length = 0x%02x\n", local->tib_length);
        /* Initialize CCS's to buffer free state */
        pccs = ccs_base(local);
        for (i = 0; i < NUMBER_OF_CCS; i++) {
@@ -592,7 +581,7 @@ static int ray_init(struct net_device *dev)
 
        clear_interrupt(local); /* Clear any interrupt from the card */
        local->card_status = CARD_AWAITING_PARAM;
-       DEBUG(2, "ray_init ending\n");
+       dev_dbg(&link->dev, "ray_init ending\n");
        return 0;
 } /* ray_init */
 
@@ -605,9 +594,9 @@ static int dl_startup_params(struct net_device *dev)
        struct ccs __iomem *pccs;
        struct pcmcia_device *link = local->finder;
 
-       DEBUG(1, "dl_startup_params entered\n");
+       dev_dbg(&link->dev, "dl_startup_params entered\n");
        if (!(pcmcia_dev_present(link))) {
-               DEBUG(2, "ray_cs dl_startup_params - device not present\n");
+               dev_dbg(&link->dev, "ray_cs dl_startup_params - device not present\n");
                return -1;
        }
 
@@ -625,7 +614,7 @@ static int dl_startup_params(struct net_device *dev)
        local->dl_param_ccs = ccsindex;
        pccs = ccs_base(local) + ccsindex;
        writeb(CCS_DOWNLOAD_STARTUP_PARAMS, &pccs->cmd);
-       DEBUG(2, "dl_startup_params start ccsindex = %d\n",
+       dev_dbg(&link->dev, "dl_startup_params start ccsindex = %d\n",
              local->dl_param_ccs);
        /* Interrupt the firmware to process the command */
        if (interrupt_ecf(local, ccsindex)) {
@@ -641,7 +630,7 @@ static int dl_startup_params(struct net_device *dev)
        local->timer.data = (long)local;
        local->timer.function = &verify_dl_startup;
        add_timer(&local->timer);
-       DEBUG(2,
+       dev_dbg(&link->dev,
              "ray_cs dl_startup_params started timer for verify_dl_startup\n");
        return 0;
 } /* dl_startup_params */
@@ -717,11 +706,11 @@ static void verify_dl_startup(u_long data)
        struct pcmcia_device *link = local->finder;
 
        if (!(pcmcia_dev_present(link))) {
-               DEBUG(2, "ray_cs verify_dl_startup - device not present\n");
+               dev_dbg(&link->dev, "ray_cs verify_dl_startup - device not present\n");
                return;
        }
-#ifdef PCMCIA_DEBUG
-       if (pc_debug > 2) {
+#if 0
+       {
                int i;
                printk(KERN_DEBUG
                       "verify_dl_startup parameters sent via ccs %d:\n",
@@ -760,7 +749,7 @@ static void start_net(u_long data)
        int ccsindex;
        struct pcmcia_device *link = local->finder;
        if (!(pcmcia_dev_present(link))) {
-               DEBUG(2, "ray_cs start_net - device not present\n");
+               dev_dbg(&link->dev, "ray_cs start_net - device not present\n");
                return;
        }
        /* Fill in the CCS fields for the ECF */
@@ -771,7 +760,7 @@ static void start_net(u_long data)
        writeb(0, &pccs->var.start_network.update_param);
        /* Interrupt the firmware to process the command */
        if (interrupt_ecf(local, ccsindex)) {
-               DEBUG(1, "ray start net failed - card not ready for intr\n");
+               dev_dbg(&link->dev, "ray start net failed - card not ready for intr\n");
                writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
                return;
        }
@@ -790,7 +779,7 @@ static void join_net(u_long data)
        struct pcmcia_device *link = local->finder;
 
        if (!(pcmcia_dev_present(link))) {
-               DEBUG(2, "ray_cs join_net - device not present\n");
+               dev_dbg(&link->dev, "ray_cs join_net - device not present\n");
                return;
        }
        /* Fill in the CCS fields for the ECF */
@@ -802,7 +791,7 @@ static void join_net(u_long data)
        writeb(0, &pccs->var.join_network.net_initiated);
        /* Interrupt the firmware to process the command */
        if (interrupt_ecf(local, ccsindex)) {
-               DEBUG(1, "ray join net failed - card not ready for intr\n");
+               dev_dbg(&link->dev, "ray join net failed - card not ready for intr\n");
                writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
                return;
        }
@@ -821,7 +810,7 @@ static void ray_release(struct pcmcia_device *link)
        ray_dev_t *local = netdev_priv(dev);
        int i;
 
-       DEBUG(1, "ray_release(0x%p)\n", link);
+       dev_dbg(&link->dev, "ray_release\n");
 
        del_timer(&local->timer);
 
@@ -829,15 +818,15 @@ static void ray_release(struct pcmcia_device *link)
        iounmap(local->rmem);
        iounmap(local->amem);
        /* Do bother checking to see if these succeed or not */
-       i = pcmcia_release_window(local->amem_handle);
+       i = pcmcia_release_window(link, local->amem_handle);
        if (i != 0)
-               DEBUG(0, "ReleaseWindow(local->amem) ret = %x\n", i);
-       i = pcmcia_release_window(local->rmem_handle);
+               dev_dbg(&link->dev, "ReleaseWindow(local->amem) ret = %x\n", i);
+       i = pcmcia_release_window(link, local->rmem_handle);
        if (i != 0)
-               DEBUG(0, "ReleaseWindow(local->rmem) ret = %x\n", i);
+               dev_dbg(&link->dev, "ReleaseWindow(local->rmem) ret = %x\n", i);
        pcmcia_disable_device(link);
 
-       DEBUG(2, "ray_release ending\n");
+       dev_dbg(&link->dev, "ray_release ending\n");
 }
 
 static int ray_suspend(struct pcmcia_device *link)
@@ -871,9 +860,9 @@ static int ray_dev_init(struct net_device *dev)
        ray_dev_t *local = netdev_priv(dev);
        struct pcmcia_device *link = local->finder;
 
-       DEBUG(1, "ray_dev_init(dev=%p)\n", dev);
+       dev_dbg(&link->dev, "ray_dev_init(dev=%p)\n", dev);
        if (!(pcmcia_dev_present(link))) {
-               DEBUG(2, "ray_dev_init - device not present\n");
+               dev_dbg(&link->dev, "ray_dev_init - device not present\n");
                return -1;
        }
 #ifdef RAY_IMMEDIATE_INIT
@@ -887,7 +876,7 @@ static int ray_dev_init(struct net_device *dev)
        /* Postpone the card init so that we can still configure the card,
         * for example using the Wireless Extensions. The init will happen
         * in ray_open() - Jean II */
-       DEBUG(1,
+       dev_dbg(&link->dev,
              "ray_dev_init: postponing card init to ray_open() ; Status = %d\n",
              local->card_status);
 #endif /* RAY_IMMEDIATE_INIT */
@@ -896,7 +885,7 @@ static int ray_dev_init(struct net_device *dev)
        memcpy(dev->dev_addr, &local->sparm.b4.a_mac_addr, ADDRLEN);
        memset(dev->broadcast, 0xff, ETH_ALEN);
 
-       DEBUG(2, "ray_dev_init ending\n");
+       dev_dbg(&link->dev, "ray_dev_init ending\n");
        return 0;
 }
 
@@ -906,9 +895,9 @@ static int ray_dev_config(struct net_device *dev, struct ifmap *map)
        ray_dev_t *local = netdev_priv(dev);
        struct pcmcia_device *link = local->finder;
        /* Dummy routine to satisfy device structure */
-       DEBUG(1, "ray_dev_config(dev=%p,ifmap=%p)\n", dev, map);
+       dev_dbg(&link->dev, "ray_dev_config(dev=%p,ifmap=%p)\n", dev, map);
        if (!(pcmcia_dev_present(link))) {
-               DEBUG(2, "ray_dev_config - device not present\n");
+               dev_dbg(&link->dev, "ray_dev_config - device not present\n");
                return -1;
        }
 
@@ -924,14 +913,14 @@ static netdev_tx_t ray_dev_start_xmit(struct sk_buff *skb,
        short length = skb->len;
 
        if (!pcmcia_dev_present(link)) {
-               DEBUG(2, "ray_dev_start_xmit - device not present\n");
+               dev_dbg(&link->dev, "ray_dev_start_xmit - device not present\n");
                dev_kfree_skb(skb);
                return NETDEV_TX_OK;
        }
 
-       DEBUG(3, "ray_dev_start_xmit(skb=%p, dev=%p)\n", skb, dev);
+       dev_dbg(&link->dev, "ray_dev_start_xmit(skb=%p, dev=%p)\n", skb, dev);
        if (local->authentication_state == NEED_TO_AUTH) {
-               DEBUG(0, "ray_cs Sending authentication request.\n");
+               dev_dbg(&link->dev, "ray_cs Sending authentication request.\n");
                if (!build_auth_frame(local, local->auth_id, OPEN_AUTH_REQUEST)) {
                        local->authentication_state = AUTHENTICATED;
                        netif_stop_queue(dev);
@@ -971,7 +960,7 @@ static int ray_hw_xmit(unsigned char *data, int len, struct net_device *dev,
        struct tx_msg __iomem *ptx;     /* Address of xmit buffer in PC space */
        short int addr;         /* Address of xmit buffer in card space */
 
-       DEBUG(3, "ray_hw_xmit(data=%p, len=%d, dev=%p)\n", data, len, dev);
+       pr_debug("ray_hw_xmit(data=%p, len=%d, dev=%p)\n", data, len, dev);
        if (len + TX_HEADER_LENGTH > TX_BUF_SIZE) {
                printk(KERN_INFO "ray_hw_xmit packet too large: %d bytes\n",
                       len);
@@ -979,9 +968,9 @@ static int ray_hw_xmit(unsigned char *data, int len, struct net_device *dev,
        }
        switch (ccsindex = get_free_tx_ccs(local)) {
        case ECCSBUSY:
-               DEBUG(2, "ray_hw_xmit tx_ccs table busy\n");
+               pr_debug("ray_hw_xmit tx_ccs table busy\n");
        case ECCSFULL:
-               DEBUG(2, "ray_hw_xmit No free tx ccs\n");
+               pr_debug("ray_hw_xmit No free tx ccs\n");
        case ECARDGONE:
                netif_stop_queue(dev);
                return XMIT_NO_CCS;
@@ -1018,12 +1007,12 @@ static int ray_hw_xmit(unsigned char *data, int len, struct net_device *dev,
        writeb(PSM_CAM, &pccs->var.tx_request.pow_sav_mode);
        writeb(local->net_default_tx_rate, &pccs->var.tx_request.tx_rate);
        writeb(0, &pccs->var.tx_request.antenna);
-       DEBUG(3, "ray_hw_xmit default_tx_rate = 0x%x\n",
+       pr_debug("ray_hw_xmit default_tx_rate = 0x%x\n",
              local->net_default_tx_rate);
 
        /* Interrupt the firmware to process the command */
        if (interrupt_ecf(local, ccsindex)) {
-               DEBUG(2, "ray_hw_xmit failed - ECF not ready for intr\n");
+               pr_debug("ray_hw_xmit failed - ECF not ready for intr\n");
 /* TBD very inefficient to copy packet to buffer, and then not
    send it, but the alternative is to queue the messages and that
    won't be done for a while.  Maybe set tbusy until a CCS is free?
@@ -1040,7 +1029,7 @@ static int translate_frame(ray_dev_t *local, struct tx_msg __iomem *ptx,
 {
        __be16 proto = ((struct ethhdr *)data)->h_proto;
        if (ntohs(proto) >= 1536) { /* DIX II ethernet frame */
-               DEBUG(3, "ray_cs translate_frame DIX II\n");
+               pr_debug("ray_cs translate_frame DIX II\n");
                /* Copy LLC header to card buffer */
                memcpy_toio(&ptx->var, eth2_llc, sizeof(eth2_llc));
                memcpy_toio(((void __iomem *)&ptx->var) + sizeof(eth2_llc),
@@ -1056,9 +1045,9 @@ static int translate_frame(ray_dev_t *local, struct tx_msg __iomem *ptx,
                            len - ETH_HLEN);
                return (int)sizeof(struct snaphdr_t) - ETH_HLEN;
        } else { /* already  802 type, and proto is length */
-               DEBUG(3, "ray_cs translate_frame 802\n");
+               pr_debug("ray_cs translate_frame 802\n");
                if (proto == htons(0xffff)) { /* evil netware IPX 802.3 without LLC */
-                       DEBUG(3, "ray_cs translate_frame evil IPX\n");
+                       pr_debug("ray_cs translate_frame evil IPX\n");
                        memcpy_toio(&ptx->var, data + ETH_HLEN, len - ETH_HLEN);
                        return 0 - ETH_HLEN;
                }
@@ -1603,7 +1592,7 @@ static int ray_open(struct net_device *dev)
        struct pcmcia_device *link;
        link = local->finder;
 
-       DEBUG(1, "ray_open('%s')\n", dev->name);
+       dev_dbg(&link->dev, "ray_open('%s')\n", dev->name);
 
        if (link->open == 0)
                local->num_multi = 0;
@@ -1613,7 +1602,7 @@ static int ray_open(struct net_device *dev)
        if (local->card_status == CARD_AWAITING_PARAM) {
                int i;
 
-               DEBUG(1, "ray_open: doing init now !\n");
+               dev_dbg(&link->dev, "ray_open: doing init now !\n");
 
                /* Download startup parameters */
                if ((i = dl_startup_params(dev)) < 0) {
@@ -1629,7 +1618,7 @@ static int ray_open(struct net_device *dev)
        else
                netif_start_queue(dev);
 
-       DEBUG(2, "ray_open ending\n");
+       dev_dbg(&link->dev, "ray_open ending\n");
        return 0;
 } /* end ray_open */
 
@@ -1640,7 +1629,7 @@ static int ray_dev_close(struct net_device *dev)
        struct pcmcia_device *link;
        link = local->finder;
 
-       DEBUG(1, "ray_dev_close('%s')\n", dev->name);
+       dev_dbg(&link->dev, "ray_dev_close('%s')\n", dev->name);
 
        link->open--;
        netif_stop_queue(dev);
@@ -1656,7 +1645,7 @@ static int ray_dev_close(struct net_device *dev)
 /*===========================================================================*/
 static void ray_reset(struct net_device *dev)
 {
-       DEBUG(1, "ray_reset entered\n");
+       pr_debug("ray_reset entered\n");
        return;
 }
 
@@ -1669,17 +1658,17 @@ static int interrupt_ecf(ray_dev_t *local, int ccs)
        struct pcmcia_device *link = local->finder;
 
        if (!(pcmcia_dev_present(link))) {
-               DEBUG(2, "ray_cs interrupt_ecf - device not present\n");
+               dev_dbg(&link->dev, "ray_cs interrupt_ecf - device not present\n");
                return -1;
        }
-       DEBUG(2, "interrupt_ecf(local=%p, ccs = 0x%x\n", local, ccs);
+       dev_dbg(&link->dev, "interrupt_ecf(local=%p, ccs = 0x%x\n", local, ccs);
 
        while (i &&
               (readb(local->amem + CIS_OFFSET + ECF_INTR_OFFSET) &
                ECF_INTR_SET))
                i--;
        if (i == 0) {
-               DEBUG(2, "ray_cs interrupt_ecf card not ready for interrupt\n");
+               dev_dbg(&link->dev, "ray_cs interrupt_ecf card not ready for interrupt\n");
                return -1;
        }
        /* Fill the mailbox, then kick the card */
@@ -1698,12 +1687,12 @@ static int get_free_tx_ccs(ray_dev_t *local)
        struct pcmcia_device *link = local->finder;
 
        if (!(pcmcia_dev_present(link))) {
-               DEBUG(2, "ray_cs get_free_tx_ccs - device not present\n");
+               dev_dbg(&link->dev, "ray_cs get_free_tx_ccs - device not present\n");
                return ECARDGONE;
        }
 
        if (test_and_set_bit(0, &local->tx_ccs_lock)) {
-               DEBUG(1, "ray_cs tx_ccs_lock busy\n");
+               dev_dbg(&link->dev, "ray_cs tx_ccs_lock busy\n");
                return ECCSBUSY;
        }
 
@@ -1716,7 +1705,7 @@ static int get_free_tx_ccs(ray_dev_t *local)
                }
        }
        local->tx_ccs_lock = 0;
-       DEBUG(2, "ray_cs ERROR no free tx CCS for raylink card\n");
+       dev_dbg(&link->dev, "ray_cs ERROR no free tx CCS for raylink card\n");
        return ECCSFULL;
 } /* get_free_tx_ccs */
 
@@ -1730,11 +1719,11 @@ static int get_free_ccs(ray_dev_t *local)
        struct pcmcia_device *link = local->finder;
 
        if (!(pcmcia_dev_present(link))) {
-               DEBUG(2, "ray_cs get_free_ccs - device not present\n");
+               dev_dbg(&link->dev, "ray_cs get_free_ccs - device not present\n");
                return ECARDGONE;
        }
        if (test_and_set_bit(0, &local->ccs_lock)) {
-               DEBUG(1, "ray_cs ccs_lock busy\n");
+               dev_dbg(&link->dev, "ray_cs ccs_lock busy\n");
                return ECCSBUSY;
        }
 
@@ -1747,7 +1736,7 @@ static int get_free_ccs(ray_dev_t *local)
                }
        }
        local->ccs_lock = 0;
-       DEBUG(1, "ray_cs ERROR no free CCS for raylink card\n");
+       dev_dbg(&link->dev, "ray_cs ERROR no free CCS for raylink card\n");
        return ECCSFULL;
 } /* get_free_ccs */
 
@@ -1823,7 +1812,7 @@ static struct net_device_stats *ray_get_stats(struct net_device *dev)
        struct pcmcia_device *link = local->finder;
        struct status __iomem *p = local->sram + STATUS_BASE;
        if (!(pcmcia_dev_present(link))) {
-               DEBUG(2, "ray_cs net_device_stats - device not present\n");
+               dev_dbg(&link->dev, "ray_cs net_device_stats - device not present\n");
                return &local->stats;
        }
        if (readb(&p->mrx_overflow_for_host)) {
@@ -1856,12 +1845,12 @@ static void ray_update_parm(struct net_device *dev, UCHAR objid, UCHAR *value,
        struct ccs __iomem *pccs;
 
        if (!(pcmcia_dev_present(link))) {
-               DEBUG(2, "ray_update_parm - device not present\n");
+               dev_dbg(&link->dev, "ray_update_parm - device not present\n");
                return;
        }
 
        if ((ccsindex = get_free_ccs(local)) < 0) {
-               DEBUG(0, "ray_update_parm - No free ccs\n");
+               dev_dbg(&link->dev, "ray_update_parm - No free ccs\n");
                return;
        }
        pccs = ccs_base(local) + ccsindex;
@@ -1874,7 +1863,7 @@ static void ray_update_parm(struct net_device *dev, UCHAR objid, UCHAR *value,
        }
        /* Interrupt the firmware to process the command */
        if (interrupt_ecf(local, ccsindex)) {
-               DEBUG(0, "ray_cs associate failed - ECF not ready for intr\n");
+               dev_dbg(&link->dev, "ray_cs associate failed - ECF not ready for intr\n");
                writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
        }
 }
@@ -1891,12 +1880,12 @@ static void ray_update_multi_list(struct net_device *dev, int all)
        void __iomem *p = local->sram + HOST_TO_ECF_BASE;
 
        if (!(pcmcia_dev_present(link))) {
-               DEBUG(2, "ray_update_multi_list - device not present\n");
+               dev_dbg(&link->dev, "ray_update_multi_list - device not present\n");
                return;
        } else
-               DEBUG(2, "ray_update_multi_list(%p)\n", dev);
+               dev_dbg(&link->dev, "ray_update_multi_list(%p)\n", dev);
        if ((ccsindex = get_free_ccs(local)) < 0) {
-               DEBUG(1, "ray_update_multi - No free ccs\n");
+               dev_dbg(&link->dev, "ray_update_multi - No free ccs\n");
                return;
        }
        pccs = ccs_base(local) + ccsindex;
@@ -1910,7 +1899,7 @@ static void ray_update_multi_list(struct net_device *dev, int all)
                for (dmip = &dev->mc_list; (dmi = *dmip) != NULL;
                     dmip = &dmi->next) {
                        memcpy_toio(p, dmi->dmi_addr, ETH_ALEN);
-                       DEBUG(1,
+                       dev_dbg(&link->dev,
                              "ray_update_multi add addr %02x%02x%02x%02x%02x%02x\n",
                              dmi->dmi_addr[0], dmi->dmi_addr[1],
                              dmi->dmi_addr[2], dmi->dmi_addr[3],
@@ -1921,12 +1910,12 @@ static void ray_update_multi_list(struct net_device *dev, int all)
                if (i > 256 / ADDRLEN)
                        i = 256 / ADDRLEN;
                writeb((UCHAR) i, &pccs->var);
-               DEBUG(1, "ray_cs update_multi %d addresses in list\n", i);
+               dev_dbg(&link->dev, "ray_cs update_multi %d addresses in list\n", i);
                /* Interrupt the firmware to process the command */
                local->num_multi = i;
        }
        if (interrupt_ecf(local, ccsindex)) {
-               DEBUG(1,
+               dev_dbg(&link->dev,
                      "ray_cs update_multi failed - ECF not ready for intr\n");
                writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
        }
@@ -1938,11 +1927,11 @@ static void set_multicast_list(struct net_device *dev)
        ray_dev_t *local = netdev_priv(dev);
        UCHAR promisc;
 
-       DEBUG(2, "ray_cs set_multicast_list(%p)\n", dev);
+       pr_debug("ray_cs set_multicast_list(%p)\n", dev);
 
        if (dev->flags & IFF_PROMISC) {
                if (local->sparm.b5.a_promiscuous_mode == 0) {
-                       DEBUG(1, "ray_cs set_multicast_list promisc on\n");
+                       pr_debug("ray_cs set_multicast_list promisc on\n");
                        local->sparm.b5.a_promiscuous_mode = 1;
                        promisc = 1;
                        ray_update_parm(dev, OBJID_promiscuous_mode,
@@ -1950,7 +1939,7 @@ static void set_multicast_list(struct net_device *dev)
                }
        } else {
                if (local->sparm.b5.a_promiscuous_mode == 1) {
-                       DEBUG(1, "ray_cs set_multicast_list promisc off\n");
+                       pr_debug("ray_cs set_multicast_list promisc off\n");
                        local->sparm.b5.a_promiscuous_mode = 0;
                        promisc = 0;
                        ray_update_parm(dev, OBJID_promiscuous_mode,
@@ -1984,19 +1973,19 @@ static irqreturn_t ray_interrupt(int irq, void *dev_id)
        if (dev == NULL)        /* Note that we want interrupts with dev->start == 0 */
                return IRQ_NONE;
 
-       DEBUG(4, "ray_cs: interrupt for *dev=%p\n", dev);
+       pr_debug("ray_cs: interrupt for *dev=%p\n", dev);
 
        local = netdev_priv(dev);
        link = (struct pcmcia_device *)local->finder;
        if (!pcmcia_dev_present(link)) {
-               DEBUG(2,
-                     "ray_cs interrupt from device not present or suspended.\n");
+               pr_debug(
+                       "ray_cs interrupt from device not present or suspended.\n");
                return IRQ_NONE;
        }
        rcsindex = readb(&((struct scb __iomem *)(local->sram))->rcs_index);
 
        if (rcsindex >= (NUMBER_OF_CCS + NUMBER_OF_RCS)) {
-               DEBUG(1, "ray_cs interrupt bad rcsindex = 0x%x\n", rcsindex);
+               dev_dbg(&link->dev, "ray_cs interrupt bad rcsindex = 0x%x\n", rcsindex);
                clear_interrupt(local);
                return IRQ_HANDLED;
        }
@@ -2008,33 +1997,33 @@ static irqreturn_t ray_interrupt(int irq, void *dev_id)
                case CCS_DOWNLOAD_STARTUP_PARAMS:       /* Happens in firmware someday */
                        del_timer(&local->timer);
                        if (status == CCS_COMMAND_COMPLETE) {
-                               DEBUG(1,
+                               dev_dbg(&link->dev,
                                      "ray_cs interrupt download_startup_parameters OK\n");
                        } else {
-                               DEBUG(1,
+                               dev_dbg(&link->dev,
                                      "ray_cs interrupt download_startup_parameters fail\n");
                        }
                        break;
                case CCS_UPDATE_PARAMS:
-                       DEBUG(1, "ray_cs interrupt update params done\n");
+                       dev_dbg(&link->dev, "ray_cs interrupt update params done\n");
                        if (status != CCS_COMMAND_COMPLETE) {
                                tmp =
                                    readb(&pccs->var.update_param.
                                          failure_cause);
-                               DEBUG(0,
+                               dev_dbg(&link->dev,
                                      "ray_cs interrupt update params failed - reason %d\n",
                                      tmp);
                        }
                        break;
                case CCS_REPORT_PARAMS:
-                       DEBUG(1, "ray_cs interrupt report params done\n");
+                       dev_dbg(&link->dev, "ray_cs interrupt report params done\n");
                        break;
                case CCS_UPDATE_MULTICAST_LIST: /* Note that this CCS isn't returned */
-                       DEBUG(1,
+                       dev_dbg(&link->dev,
                              "ray_cs interrupt CCS Update Multicast List done\n");
                        break;
                case CCS_UPDATE_POWER_SAVINGS_MODE:
-                       DEBUG(1,
+                       dev_dbg(&link->dev,
                              "ray_cs interrupt update power save mode done\n");
                        break;
                case CCS_START_NETWORK:
@@ -2043,11 +2032,11 @@ static irqreturn_t ray_interrupt(int irq, void *dev_id)
                                if (readb
                                    (&pccs->var.start_network.net_initiated) ==
                                    1) {
-                                       DEBUG(0,
+                                       dev_dbg(&link->dev,
                                              "ray_cs interrupt network \"%s\" started\n",
                                              local->sparm.b4.a_current_ess_id);
                                } else {
-                                       DEBUG(0,
+                                       dev_dbg(&link->dev,
                                              "ray_cs interrupt network \"%s\" joined\n",
                                              local->sparm.b4.a_current_ess_id);
                                }
@@ -2075,12 +2064,12 @@ static irqreturn_t ray_interrupt(int irq, void *dev_id)
                                local->timer.expires = jiffies + HZ * 5;
                                local->timer.data = (long)local;
                                if (status == CCS_START_NETWORK) {
-                                       DEBUG(0,
+                                       dev_dbg(&link->dev,
                                              "ray_cs interrupt network \"%s\" start failed\n",
                                              local->sparm.b4.a_current_ess_id);
                                        local->timer.function = &start_net;
                                } else {
-                                       DEBUG(0,
+                                       dev_dbg(&link->dev,
                                              "ray_cs interrupt network \"%s\" join failed\n",
                                              local->sparm.b4.a_current_ess_id);
                                        local->timer.function = &join_net;
@@ -2091,19 +2080,19 @@ static irqreturn_t ray_interrupt(int irq, void *dev_id)
                case CCS_START_ASSOCIATION:
                        if (status == CCS_COMMAND_COMPLETE) {
                                local->card_status = CARD_ASSOC_COMPLETE;
-                               DEBUG(0, "ray_cs association successful\n");
+                               dev_dbg(&link->dev, "ray_cs association successful\n");
                        } else {
-                               DEBUG(0, "ray_cs association failed,\n");
+                               dev_dbg(&link->dev, "ray_cs association failed,\n");
                                local->card_status = CARD_ASSOC_FAILED;
                                join_net((u_long) local);
                        }
                        break;
                case CCS_TX_REQUEST:
                        if (status == CCS_COMMAND_COMPLETE) {
-                               DEBUG(3,
+                               dev_dbg(&link->dev,
                                      "ray_cs interrupt tx request complete\n");
                        } else {
-                               DEBUG(1,
+                               dev_dbg(&link->dev,
                                      "ray_cs interrupt tx request failed\n");
                        }
                        if (!sniffer)
@@ -2111,21 +2100,21 @@ static irqreturn_t ray_interrupt(int irq, void *dev_id)
                        netif_wake_queue(dev);
                        break;
                case CCS_TEST_MEMORY:
-                       DEBUG(1, "ray_cs interrupt mem test done\n");
+                       dev_dbg(&link->dev, "ray_cs interrupt mem test done\n");
                        break;
                case CCS_SHUTDOWN:
-                       DEBUG(1,
+                       dev_dbg(&link->dev,
                              "ray_cs interrupt Unexpected CCS returned - Shutdown\n");
                        break;
                case CCS_DUMP_MEMORY:
-                       DEBUG(1, "ray_cs interrupt dump memory done\n");
+                       dev_dbg(&link->dev, "ray_cs interrupt dump memory done\n");
                        break;
                case CCS_START_TIMER:
-                       DEBUG(2,
+                       dev_dbg(&link->dev,
                              "ray_cs interrupt DING - raylink timer expired\n");
                        break;
                default:
-                       DEBUG(1,
+                       dev_dbg(&link->dev,
                              "ray_cs interrupt Unexpected CCS 0x%x returned 0x%x\n",
                              rcsindex, cmd);
                }
@@ -2139,7 +2128,7 @@ static irqreturn_t ray_interrupt(int irq, void *dev_id)
                        ray_rx(dev, local, prcs);
                        break;
                case REJOIN_NET_COMPLETE:
-                       DEBUG(1, "ray_cs interrupt rejoin net complete\n");
+                       dev_dbg(&link->dev, "ray_cs interrupt rejoin net complete\n");
                        local->card_status = CARD_ACQ_COMPLETE;
                        /* do we need to clear tx buffers CCS's? */
                        if (local->sparm.b4.a_network_type == ADHOC) {
@@ -2149,7 +2138,7 @@ static irqreturn_t ray_interrupt(int irq, void *dev_id)
                                memcpy_fromio(&local->bss_id,
                                              prcs->var.rejoin_net_complete.
                                              bssid, ADDRLEN);
-                               DEBUG(1,
+                               dev_dbg(&link->dev,
                                      "ray_cs new BSSID = %02x%02x%02x%02x%02x%02x\n",
                                      local->bss_id[0], local->bss_id[1],
                                      local->bss_id[2], local->bss_id[3],
@@ -2159,15 +2148,15 @@ static irqreturn_t ray_interrupt(int irq, void *dev_id)
                        }
                        break;
                case ROAMING_INITIATED:
-                       DEBUG(1, "ray_cs interrupt roaming initiated\n");
+                       dev_dbg(&link->dev, "ray_cs interrupt roaming initiated\n");
                        netif_stop_queue(dev);
                        local->card_status = CARD_DOING_ACQ;
                        break;
                case JAPAN_CALL_SIGN_RXD:
-                       DEBUG(1, "ray_cs interrupt japan call sign rx\n");
+                       dev_dbg(&link->dev, "ray_cs interrupt japan call sign rx\n");
                        break;
                default:
-                       DEBUG(1,
+                       dev_dbg(&link->dev,
                              "ray_cs Unexpected interrupt for RCS 0x%x cmd = 0x%x\n",
                              rcsindex,
                              (unsigned int)readb(&prcs->interrupt_id));
@@ -2186,7 +2175,7 @@ static void ray_rx(struct net_device *dev, ray_dev_t *local,
        int rx_len;
        unsigned int pkt_addr;
        void __iomem *pmsg;
-       DEBUG(4, "ray_rx process rx packet\n");
+       pr_debug("ray_rx process rx packet\n");
 
        /* Calculate address of packet within Rx buffer */
        pkt_addr = ((readb(&prcs->var.rx_packet.rx_data_ptr[0]) << 8)
@@ -2199,28 +2188,28 @@ static void ray_rx(struct net_device *dev, ray_dev_t *local,
        pmsg = local->rmem + pkt_addr;
        switch (readb(pmsg)) {
        case DATA_TYPE:
-               DEBUG(4, "ray_rx data type\n");
+               pr_debug("ray_rx data type\n");
                rx_data(dev, prcs, pkt_addr, rx_len);
                break;
        case AUTHENTIC_TYPE:
-               DEBUG(4, "ray_rx authentic type\n");
+               pr_debug("ray_rx authentic type\n");
                if (sniffer)
                        rx_data(dev, prcs, pkt_addr, rx_len);
                else
                        rx_authenticate(local, prcs, pkt_addr, rx_len);
                break;
        case DEAUTHENTIC_TYPE:
-               DEBUG(4, "ray_rx deauth type\n");
+               pr_debug("ray_rx deauth type\n");
                if (sniffer)
                        rx_data(dev, prcs, pkt_addr, rx_len);
                else
                        rx_deauthenticate(local, prcs, pkt_addr, rx_len);
                break;
        case NULL_MSG_TYPE:
-               DEBUG(3, "ray_cs rx NULL msg\n");
+               pr_debug("ray_cs rx NULL msg\n");
                break;
        case BEACON_TYPE:
-               DEBUG(4, "ray_rx beacon type\n");
+               pr_debug("ray_rx beacon type\n");
                if (sniffer)
                        rx_data(dev, prcs, pkt_addr, rx_len);
 
@@ -2233,7 +2222,7 @@ static void ray_rx(struct net_device *dev, ray_dev_t *local,
                ray_get_stats(dev);
                break;
        default:
-               DEBUG(0, "ray_cs unknown pkt type %2x\n",
+               pr_debug("ray_cs unknown pkt type %2x\n",
                      (unsigned int)readb(pmsg));
                break;
        }
@@ -2262,7 +2251,7 @@ static void rx_data(struct net_device *dev, struct rcs __iomem *prcs,
                            rx_len >
                            (dev->mtu + RX_MAC_HEADER_LENGTH + ETH_HLEN +
                             FCS_LEN)) {
-                               DEBUG(0,
+                               pr_debug(
                                      "ray_cs invalid packet length %d received \n",
                                      rx_len);
                                return;
@@ -2273,17 +2262,17 @@ static void rx_data(struct net_device *dev, struct rcs __iomem *prcs,
                            rx_len >
                            (dev->mtu + RX_MAC_HEADER_LENGTH + ETH_HLEN +
                             FCS_LEN)) {
-                               DEBUG(0,
+                               pr_debug(
                                      "ray_cs invalid packet length %d received \n",
                                      rx_len);
                                return;
                        }
                }
        }
-       DEBUG(4, "ray_cs rx_data packet\n");
+       pr_debug("ray_cs rx_data packet\n");
        /* If fragmented packet, verify sizes of fragments add up */
        if (readb(&prcs->var.rx_packet.next_frag_rcs_index) != 0xFF) {
-               DEBUG(1, "ray_cs rx'ed fragment\n");
+               pr_debug("ray_cs rx'ed fragment\n");
                tmp = (readb(&prcs->var.rx_packet.totalpacketlength[0]) << 8)
                    + readb(&prcs->var.rx_packet.totalpacketlength[1]);
                total_len = tmp;
@@ -2301,7 +2290,7 @@ static void rx_data(struct net_device *dev, struct rcs __iomem *prcs,
                } while (1);
 
                if (tmp < 0) {
-                       DEBUG(0,
+                       pr_debug(
                              "ray_cs rx_data fragment lengths don't add up\n");
                        local->stats.rx_dropped++;
                        release_frag_chain(local, prcs);
@@ -2313,7 +2302,7 @@ static void rx_data(struct net_device *dev, struct rcs __iomem *prcs,
 
        skb = dev_alloc_skb(total_len + 5);
        if (skb == NULL) {
-               DEBUG(0, "ray_cs rx_data could not allocate skb\n");
+               pr_debug("ray_cs rx_data could not allocate skb\n");
                local->stats.rx_dropped++;
                if (readb(&prcs->var.rx_packet.next_frag_rcs_index) != 0xFF)
                        release_frag_chain(local, prcs);
@@ -2321,7 +2310,7 @@ static void rx_data(struct net_device *dev, struct rcs __iomem *prcs,
        }
        skb_reserve(skb, 2);    /* Align IP on 16 byte (TBD check this) */
 
-       DEBUG(4, "ray_cs rx_data total_len = %x, rx_len = %x\n", total_len,
+       pr_debug("ray_cs rx_data total_len = %x, rx_len = %x\n", total_len,
              rx_len);
 
 /************************/
@@ -2354,7 +2343,7 @@ static void rx_data(struct net_device *dev, struct rcs __iomem *prcs,
        tmp = 17;
        if (readb(&prcs->var.rx_packet.next_frag_rcs_index) != 0xFF) {
                prcslink = prcs;
-               DEBUG(1, "ray_cs rx_data in fragment loop\n");
+               pr_debug("ray_cs rx_data in fragment loop\n");
                do {
                        prcslink = rcs_base(local)
                            +
@@ -2426,8 +2415,8 @@ static void untranslate(ray_dev_t *local, struct sk_buff *skb, int len)
        memcpy(destaddr, ieee80211_get_DA(pmac), ADDRLEN);
        memcpy(srcaddr, ieee80211_get_SA(pmac), ADDRLEN);
 
-#ifdef PCMCIA_DEBUG
-       if (pc_debug > 3) {
+#if 0
+       if {
                print_hex_dump(KERN_DEBUG, "skb->data before untranslate: ",
                               DUMP_PREFIX_NONE, 16, 1,
                               skb->data, 64, true);
@@ -2441,7 +2430,7 @@ static void untranslate(ray_dev_t *local, struct sk_buff *skb, int len)
 
        if (psnap->dsap != 0xaa || psnap->ssap != 0xaa || psnap->ctrl != 3) {
                /* not a snap type so leave it alone */
-               DEBUG(3, "ray_cs untranslate NOT SNAP %02x %02x %02x\n",
+               pr_debug("ray_cs untranslate NOT SNAP %02x %02x %02x\n",
                      psnap->dsap, psnap->ssap, psnap->ctrl);
 
                delta = RX_MAC_HEADER_LENGTH - ETH_HLEN;
@@ -2450,7 +2439,7 @@ static void untranslate(ray_dev_t *local, struct sk_buff *skb, int len)
        } else { /* Its a SNAP */
                if (memcmp(psnap->org, org_bridge, 3) == 0) {
                /* EtherII and nuke the LLC */
-                       DEBUG(3, "ray_cs untranslate Bridge encap\n");
+                       pr_debug("ray_cs untranslate Bridge encap\n");
                        delta = RX_MAC_HEADER_LENGTH
                            + sizeof(struct snaphdr_t) - ETH_HLEN;
                        peth = (struct ethhdr *)(skb->data + delta);
@@ -2459,14 +2448,14 @@ static void untranslate(ray_dev_t *local, struct sk_buff *skb, int len)
                        switch (ntohs(type)) {
                        case ETH_P_IPX:
                        case ETH_P_AARP:
-                               DEBUG(3, "ray_cs untranslate RFC IPX/AARP\n");
+                               pr_debug("ray_cs untranslate RFC IPX/AARP\n");
                                delta = RX_MAC_HEADER_LENGTH - ETH_HLEN;
                                peth = (struct ethhdr *)(skb->data + delta);
                                peth->h_proto =
                                    htons(len - RX_MAC_HEADER_LENGTH);
                                break;
                        default:
-                               DEBUG(3, "ray_cs untranslate RFC default\n");
+                               pr_debug("ray_cs untranslate RFC default\n");
                                delta = RX_MAC_HEADER_LENGTH +
                                    sizeof(struct snaphdr_t) - ETH_HLEN;
                                peth = (struct ethhdr *)(skb->data + delta);
@@ -2482,12 +2471,12 @@ static void untranslate(ray_dev_t *local, struct sk_buff *skb, int len)
        }
 /* TBD reserve  skb_reserve(skb, delta); */
        skb_pull(skb, delta);
-       DEBUG(3, "untranslate after skb_pull(%d), skb->data = %p\n", delta,
+       pr_debug("untranslate after skb_pull(%d), skb->data = %p\n", delta,
              skb->data);
        memcpy(peth->h_dest, destaddr, ADDRLEN);
        memcpy(peth->h_source, srcaddr, ADDRLEN);
-#ifdef PCMCIA_DEBUG
-       if (pc_debug > 3) {
+#if 0
+       {
                int i;
                printk(KERN_DEBUG "skb->data after untranslate:");
                for (i = 0; i < 64; i++)
@@ -2529,7 +2518,7 @@ static void release_frag_chain(ray_dev_t *local, struct rcs __iomem *prcs)
        while (tmp--) {
                writeb(CCS_BUFFER_FREE, &prcslink->buffer_status);
                if (rcsindex >= (NUMBER_OF_CCS + NUMBER_OF_RCS)) {
-                       DEBUG(1, "ray_cs interrupt bad rcsindex = 0x%x\n",
+                       pr_debug("ray_cs interrupt bad rcsindex = 0x%x\n",
                              rcsindex);
                        break;
                }
@@ -2543,9 +2532,9 @@ static void release_frag_chain(ray_dev_t *local, struct rcs __iomem *prcs)
 static void authenticate(ray_dev_t *local)
 {
        struct pcmcia_device *link = local->finder;
-       DEBUG(0, "ray_cs Starting authentication.\n");
+       dev_dbg(&link->dev, "ray_cs Starting authentication.\n");
        if (!(pcmcia_dev_present(link))) {
-               DEBUG(2, "ray_cs authenticate - device not present\n");
+               dev_dbg(&link->dev, "ray_cs authenticate - device not present\n");
                return;
        }
 
@@ -2573,11 +2562,11 @@ static void rx_authenticate(ray_dev_t *local, struct rcs __iomem *prcs,
        copy_from_rx_buff(local, buff, pkt_addr, rx_len & 0xff);
        /* if we are trying to get authenticated */
        if (local->sparm.b4.a_network_type == ADHOC) {
-               DEBUG(1, "ray_cs rx_auth var= %02x %02x %02x %02x %02x %02x\n",
+               pr_debug("ray_cs rx_auth var= %02x %02x %02x %02x %02x %02x\n",
                      msg->var[0], msg->var[1], msg->var[2], msg->var[3],
                      msg->var[4], msg->var[5]);
                if (msg->var[2] == 1) {
-                       DEBUG(0, "ray_cs Sending authentication response.\n");
+                       pr_debug("ray_cs Sending authentication response.\n");
                        if (!build_auth_frame
                            (local, msg->mac.addr_2, OPEN_AUTH_RESPONSE)) {
                                local->authentication_state = NEED_TO_AUTH;
@@ -2591,13 +2580,13 @@ static void rx_authenticate(ray_dev_t *local, struct rcs __iomem *prcs,
                        /* Verify authentication sequence #2 and success */
                        if (msg->var[2] == 2) {
                                if ((msg->var[3] | msg->var[4]) == 0) {
-                                       DEBUG(1, "Authentication successful\n");
+                                       pr_debug("Authentication successful\n");
                                        local->card_status = CARD_AUTH_COMPLETE;
                                        associate(local);
                                        local->authentication_state =
                                            AUTHENTICATED;
                                } else {
-                                       DEBUG(0, "Authentication refused\n");
+                                       pr_debug("Authentication refused\n");
                                        local->card_status = CARD_AUTH_REFUSED;
                                        join_net((u_long) local);
                                        local->authentication_state =
@@ -2617,22 +2606,22 @@ static void associate(ray_dev_t *local)
        struct net_device *dev = link->priv;
        int ccsindex;
        if (!(pcmcia_dev_present(link))) {
-               DEBUG(2, "ray_cs associate - device not present\n");
+               dev_dbg(&link->dev, "ray_cs associate - device not present\n");
                return;
        }
        /* If no tx buffers available, return */
        if ((ccsindex = get_free_ccs(local)) < 0) {
 /* TBD should never be here but... what if we are? */
-               DEBUG(1, "ray_cs associate - No free ccs\n");
+               dev_dbg(&link->dev, "ray_cs associate - No free ccs\n");
                return;
        }
-       DEBUG(1, "ray_cs Starting association with access point\n");
+       dev_dbg(&link->dev, "ray_cs Starting association with access point\n");
        pccs = ccs_base(local) + ccsindex;
        /* fill in the CCS */
        writeb(CCS_START_ASSOCIATION, &pccs->cmd);
        /* Interrupt the firmware to process the command */
        if (interrupt_ecf(local, ccsindex)) {
-               DEBUG(1, "ray_cs associate failed - ECF not ready for intr\n");
+               dev_dbg(&link->dev, "ray_cs associate failed - ECF not ready for intr\n");
                writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
 
                del_timer(&local->timer);
@@ -2655,7 +2644,7 @@ static void rx_deauthenticate(ray_dev_t *local, struct rcs __iomem *prcs,
 /*  UCHAR buff[256];
     struct rx_msg *msg = (struct rx_msg *)buff;
 */
-       DEBUG(0, "Deauthentication frame received\n");
+       pr_debug("Deauthentication frame received\n");
        local->authentication_state = UNAUTHENTICATED;
        /* Need to reauthenticate or rejoin depending on reason code */
 /*  copy_from_rx_buff(local, buff, pkt_addr, rx_len & 0xff);
@@ -2823,7 +2812,7 @@ static int build_auth_frame(ray_dev_t *local, UCHAR *dest, int auth_type)
 
        /* If no tx buffers available, return */
        if ((ccsindex = get_free_tx_ccs(local)) < 0) {
-               DEBUG(1, "ray_cs send authenticate - No free tx ccs\n");
+               pr_debug("ray_cs send authenticate - No free tx ccs\n");
                return -1;
        }
 
@@ -2855,7 +2844,7 @@ static int build_auth_frame(ray_dev_t *local, UCHAR *dest, int auth_type)
 
        /* Interrupt the firmware to process the command */
        if (interrupt_ecf(local, ccsindex)) {
-               DEBUG(1,
+               pr_debug(
                      "ray_cs send authentication request failed - ECF not ready for intr\n");
                writeb(CCS_BUFFER_FREE, &(pccs++)->buffer_status);
                return -1;
@@ -2942,9 +2931,9 @@ static int __init init_ray_cs(void)
 {
        int rc;
 
-       DEBUG(1, "%s\n", rcsid);
+       pr_debug("%s\n", rcsid);
        rc = pcmcia_register_driver(&ray_driver);
-       DEBUG(1, "raylink init_module register_pcmcia_driver returns 0x%x\n",
+       pr_debug("raylink init_module register_pcmcia_driver returns 0x%x\n",
              rc);
 
 #ifdef CONFIG_PROC_FS
@@ -2964,7 +2953,7 @@ static int __init init_ray_cs(void)
 
 static void __exit exit_ray_cs(void)
 {
-       DEBUG(0, "ray_cs: cleanup_module\n");
+       pr_debug("ray_cs: cleanup_module\n");
 
 #ifdef CONFIG_PROC_FS
        remove_proc_entry("driver/ray_cs/ray_cs", NULL);
index 9fab13e4004e805aff19fa9796ee08956a5bafcd..cad8037ab2af3a4d136194dcdf3e322d65495ad6 100644 (file)
@@ -18,6 +18,7 @@
 #include <net/mac80211.h>
 
 #include "rtl8187.h"
+#include "rtl8187_rfkill.h"
 
 static bool rtl8187_is_radio_enabled(struct rtl8187_priv *priv)
 {
index 431a20ec6db6d9e39674f93c658a9239bc45a9b6..33918fd5b2311180ee53bac82b26be933c1459ce 100644 (file)
@@ -3656,10 +3656,7 @@ wv_pcmcia_reset(struct net_device *      dev)
 
   i = pcmcia_access_configuration_register(link, &reg);
   if (i != 0)
-    {
-      cs_error(link, AccessConfigurationRegister, i);
       return FALSE;
-    }
       
 #ifdef DEBUG_CONFIG_INFO
   printk(KERN_DEBUG "%s: wavelan_pcmcia_reset(): Config reg is 0x%x\n",
@@ -3670,19 +3667,13 @@ wv_pcmcia_reset(struct net_device *     dev)
   reg.Value = reg.Value | COR_SW_RESET;
   i = pcmcia_access_configuration_register(link, &reg);
   if (i != 0)
-    {
-      cs_error(link, AccessConfigurationRegister, i);
       return FALSE;
-    }
       
   reg.Action = CS_WRITE;
   reg.Value = COR_LEVEL_IRQ | COR_CONFIG;
   i = pcmcia_access_configuration_register(link, &reg);
   if (i != 0)
-    {
-      cs_error(link, AccessConfigurationRegister, i);
       return FALSE;
-    }
 
 #ifdef DEBUG_CONFIG_TRACE
   printk(KERN_DEBUG "%s: <-wv_pcmcia_reset()\n", dev->name);
@@ -3857,10 +3848,7 @@ wv_pcmcia_config(struct pcmcia_device *  link)
     {
       i = pcmcia_request_io(link, &link->io);
       if (i != 0)
-       {
-         cs_error(link, RequestIO, i);
          break;
-       }
 
       /*
        * Now allocate an interrupt line.  Note that this does not
@@ -3868,10 +3856,7 @@ wv_pcmcia_config(struct pcmcia_device *  link)
        */
       i = pcmcia_request_irq(link, &link->irq);
       if (i != 0)
-       {
-         cs_error(link, RequestIRQ, i);
          break;
-       }
 
       /*
        * This actually configures the PCMCIA socket -- setting up
@@ -3880,10 +3865,7 @@ wv_pcmcia_config(struct pcmcia_device *  link)
       link->conf.ConfigIndex = 1;
       i = pcmcia_request_configuration(link, &link->conf);
       if (i != 0)
-       {
-         cs_error(link, RequestConfiguration, i);
          break;
-       }
 
       /*
        * Allocate a small memory window.  Note that the struct pcmcia_device
@@ -3894,24 +3876,18 @@ wv_pcmcia_config(struct pcmcia_device * link)
       req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE;
       req.Base = req.Size = 0;
       req.AccessSpeed = mem_speed;
-      i = pcmcia_request_window(&link, &req, &link->win);
+      i = pcmcia_request_window(link, &req, &link->win);
       if (i != 0)
-       {
-         cs_error(link, RequestWindow, i);
          break;
-       }
 
       lp->mem = ioremap(req.Base, req.Size);
       dev->mem_start = (u_long)lp->mem;
       dev->mem_end = dev->mem_start + req.Size;
 
       mem.CardOffset = 0; mem.Page = 0;
-      i = pcmcia_map_mem_page(link->win, &mem);
+      i = pcmcia_map_mem_page(link, link->win, &mem);
       if (i != 0)
-       {
-         cs_error(link, MapMemPage, i);
          break;
-       }
 
       /* Feed device with this info... */
       dev->irq = link->irq.AssignedIRQ;
@@ -3923,7 +3899,7 @@ wv_pcmcia_config(struct pcmcia_device *   link)
             lp->mem, dev->irq, (u_int) dev->base_addr);
 #endif
 
-      SET_NETDEV_DEV(dev, &handle_to_dev(link));
+      SET_NETDEV_DEV(dev, &link->dev);
       i = register_netdev(dev);
       if(i != 0)
        {
@@ -4462,8 +4438,7 @@ wavelan_probe(struct pcmcia_device *p_dev)
   p_dev->io.IOAddrLines = 3;
 
   /* Interrupt setup */
-  p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
-  p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID;
+  p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
   p_dev->irq.Handler = wavelan_interrupt;
 
   /* General socket configuration */
@@ -4475,7 +4450,7 @@ wavelan_probe(struct pcmcia_device *p_dev)
   if (!dev)
       return -ENOMEM;
 
-  p_dev->priv = p_dev->irq.Instance = dev;
+  p_dev->priv = dev;
 
   lp = netdev_priv(dev);
 
index 4f1e0cfe609ba5dec34f73364994b294bdfd3a8a..5f0401a52cff4e0ea60688ee5a7230ec6d23d229 100644 (file)
 /* For rough constant delay */
 #define WL3501_NOPLOOP(n) { int x = 0; while (x++ < n) slow_down_io(); }
 
-/*
- * All the PCMCIA modules use PCMCIA_DEBUG to control debugging.  If you do not
- * define PCMCIA_DEBUG at all, all the debug code will be left out.  If you
- * compile with PCMCIA_DEBUG=0, the debug code will be present but disabled --
- * but it can then be enabled for specific modules at load time with a
- * 'pc_debug=#' option to insmod.
- */
-#define PCMCIA_DEBUG 0
-#ifdef PCMCIA_DEBUG
-static int pc_debug = PCMCIA_DEBUG;
-module_param(pc_debug, int, 0);
-#define dprintk(n, format, args...) \
-       { if (pc_debug > (n)) \
-               printk(KERN_INFO "%s: " format "\n", __func__ , ##args); }
-#else
-#define dprintk(n, format, args...)
-#endif
+
 
 #define wl3501_outb(a, b) { outb(a, b); slow_down_io(); }
 #define wl3501_outb_p(a, b) { outb_p(a, b); slow_down_io(); }
@@ -684,10 +668,10 @@ static void wl3501_mgmt_scan_confirm(struct wl3501_card *this, u16 addr)
        int matchflag = 0;
        struct wl3501_scan_confirm sig;
 
-       dprintk(3, "entry");
+       pr_debug("entry");
        wl3501_get_from_wla(this, addr, &sig, sizeof(sig));
        if (sig.status == WL3501_STATUS_SUCCESS) {
-               dprintk(3, "success");
+               pr_debug("success");
                if ((this->net_type == IW_MODE_INFRA &&
                     (sig.cap_info & WL3501_MGMT_CAPABILITY_ESS)) ||
                    (this->net_type == IW_MODE_ADHOC &&
@@ -722,7 +706,7 @@ static void wl3501_mgmt_scan_confirm(struct wl3501_card *this, u16 addr)
                        }
                }
        } else if (sig.status == WL3501_STATUS_TIMEOUT) {
-               dprintk(3, "timeout");
+               pr_debug("timeout");
                this->join_sta_bss = 0;
                for (i = this->join_sta_bss; i < this->bss_cnt; i++)
                        if (!wl3501_mgmt_join(this, i))
@@ -879,7 +863,7 @@ static int wl3501_mgmt_auth(struct wl3501_card *this)
                .timeout = 1000,
        };
 
-       dprintk(3, "entry");
+       pr_debug("entry");
        memcpy(sig.mac_addr, this->bssid, ETH_ALEN);
        return wl3501_esbq_exec(this, &sig, sizeof(sig));
 }
@@ -893,7 +877,7 @@ static int wl3501_mgmt_association(struct wl3501_card *this)
                .cap_info        = this->cap_info,
        };
 
-       dprintk(3, "entry");
+       pr_debug("entry");
        memcpy(sig.mac_addr, this->bssid, ETH_ALEN);
        return wl3501_esbq_exec(this, &sig, sizeof(sig));
 }
@@ -903,7 +887,7 @@ static void wl3501_mgmt_join_confirm(struct net_device *dev, u16 addr)
        struct wl3501_card *this = netdev_priv(dev);
        struct wl3501_join_confirm sig;
 
-       dprintk(3, "entry");
+       pr_debug("entry");
        wl3501_get_from_wla(this, addr, &sig, sizeof(sig));
        if (sig.status == WL3501_STATUS_SUCCESS) {
                if (this->net_type == IW_MODE_INFRA) {
@@ -962,7 +946,7 @@ static inline void wl3501_md_confirm_interrupt(struct net_device *dev,
 {
        struct wl3501_md_confirm sig;
 
-       dprintk(3, "entry");
+       pr_debug("entry");
        wl3501_get_from_wla(this, addr, &sig, sizeof(sig));
        wl3501_free_tx_buffer(this, sig.data);
        if (netif_queue_stopped(dev))
@@ -1017,7 +1001,7 @@ static inline void wl3501_md_ind_interrupt(struct net_device *dev,
 static inline void wl3501_get_confirm_interrupt(struct wl3501_card *this,
                                                u16 addr, void *sig, int size)
 {
-       dprintk(3, "entry");
+       pr_debug("entry");
        wl3501_get_from_wla(this, addr, &this->sig_get_confirm,
                            sizeof(this->sig_get_confirm));
        wake_up(&this->wait);
@@ -1029,7 +1013,7 @@ static inline void wl3501_start_confirm_interrupt(struct net_device *dev,
 {
        struct wl3501_start_confirm sig;
 
-       dprintk(3, "entry");
+       pr_debug("entry");
        wl3501_get_from_wla(this, addr, &sig, sizeof(sig));
        if (sig.status == WL3501_STATUS_SUCCESS)
                netif_wake_queue(dev);
@@ -1041,7 +1025,7 @@ static inline void wl3501_assoc_confirm_interrupt(struct net_device *dev,
        struct wl3501_card *this = netdev_priv(dev);
        struct wl3501_assoc_confirm sig;
 
-       dprintk(3, "entry");
+       pr_debug("entry");
        wl3501_get_from_wla(this, addr, &sig, sizeof(sig));
 
        if (sig.status == WL3501_STATUS_SUCCESS)
@@ -1053,7 +1037,7 @@ static inline void wl3501_auth_confirm_interrupt(struct wl3501_card *this,
 {
        struct wl3501_auth_confirm sig;
 
-       dprintk(3, "entry");
+       pr_debug("entry");
        wl3501_get_from_wla(this, addr, &sig, sizeof(sig));
 
        if (sig.status == WL3501_STATUS_SUCCESS)
@@ -1069,7 +1053,7 @@ static inline void wl3501_rx_interrupt(struct net_device *dev)
        u8 sig_id;
        struct wl3501_card *this = netdev_priv(dev);
 
-       dprintk(3, "entry");
+       pr_debug("entry");
 loop:
        morepkts = 0;
        if (!wl3501_esbq_confirm(this))
@@ -1302,7 +1286,7 @@ static int wl3501_reset(struct net_device *dev)
        wl3501_ack_interrupt(this);
        wl3501_unblock_interrupt(this);
        wl3501_mgmt_scan(this, 100);
-       dprintk(1, "%s: device reset", dev->name);
+       pr_debug("%s: device reset", dev->name);
        rc = 0;
 out:
        return rc;
@@ -1376,7 +1360,7 @@ static int wl3501_open(struct net_device *dev)
        link->open++;
 
        /* Initial WL3501 firmware */
-       dprintk(1, "%s: Initialize WL3501 firmware...", dev->name);
+       pr_debug("%s: Initialize WL3501 firmware...", dev->name);
        if (wl3501_init_firmware(this))
                goto fail;
        /* Initial device variables */
@@ -1388,7 +1372,7 @@ static int wl3501_open(struct net_device *dev)
        wl3501_unblock_interrupt(this);
        wl3501_mgmt_scan(this, 100);
        rc = 0;
-       dprintk(1, "%s: WL3501 opened", dev->name);
+       pr_debug("%s: WL3501 opened", dev->name);
        printk(KERN_INFO "%s: Card Name: %s\n"
                         "%s: Firmware Date: %s\n",
                         dev->name, this->card_name,
@@ -1914,8 +1898,7 @@ static int wl3501_probe(struct pcmcia_device *p_dev)
        p_dev->io.IOAddrLines   = 5;
 
        /* Interrupt setup */
-       p_dev->irq.Attributes   = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
-       p_dev->irq.IRQInfo1     = IRQ_LEVEL_ID;
+       p_dev->irq.Attributes   = IRQ_TYPE_DYNAMIC_SHARING;
        p_dev->irq.Handler = wl3501_interrupt;
 
        /* General socket configuration */
@@ -1938,16 +1921,13 @@ static int wl3501_probe(struct pcmcia_device *p_dev)
        dev->wireless_handlers  = &wl3501_handler_def;
        SET_ETHTOOL_OPS(dev, &ops);
        netif_stop_queue(dev);
-       p_dev->priv = p_dev->irq.Instance = dev;
+       p_dev->priv = dev;
 
        return wl3501_config(p_dev);
 out_link:
        return -ENOMEM;
 }
 
-#define CS_CHECK(fn, ret) \
-do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
-
 /**
  * wl3501_config - configure the PCMCIA socket and make eth device available
  * @link - FILL_IN
@@ -1959,7 +1939,7 @@ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
 static int wl3501_config(struct pcmcia_device *link)
 {
        struct net_device *dev = link->priv;
-       int i = 0, j, last_fn, last_ret;
+       int i = 0, j, ret;
        struct wl3501_card *this;
 
        /* Try allocating IO ports.  This tries a few fixed addresses.  If you
@@ -1975,24 +1955,26 @@ static int wl3501_config(struct pcmcia_device *link)
                if (i == 0)
                        break;
        }
-       if (i != 0) {
-               cs_error(link, RequestIO, i);
+       if (i != 0)
                goto failed;
-       }
 
        /* Now allocate an interrupt line. Note that this does not actually
         * assign a handler to the interrupt. */
 
-       CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
+       ret = pcmcia_request_irq(link, &link->irq);
+       if (ret)
+               goto failed;
 
        /* This actually configures the PCMCIA socket -- setting up the I/O
         * windows and the interrupt mapping.  */
 
-       CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
+       ret = pcmcia_request_configuration(link, &link->conf);
+       if (ret)
+               goto failed;
 
        dev->irq = link->irq.AssignedIRQ;
        dev->base_addr = link->io.BasePort1;
-       SET_NETDEV_DEV(dev, &handle_to_dev(link));
+       SET_NETDEV_DEV(dev, &link->dev);
        if (register_netdev(dev)) {
                printk(KERN_NOTICE "wl3501_cs: register_netdev() failed\n");
                goto failed;
@@ -2041,8 +2023,6 @@ static int wl3501_config(struct pcmcia_device *link)
        netif_start_queue(dev);
        return 0;
 
-cs_failed:
-       cs_error(link, last_fn, last_ret);
 failed:
        wl3501_release(link);
        return -ENODEV;
index 8fdfa4f537a6ec9b4e189641f61130163c7dfa5c..7dd370fa343934904c0f7b349a532a8a03d4e642 100644 (file)
@@ -67,14 +67,6 @@ MODULE_LICENSE("Dual MPL/GPL");
 
 INT_MODULE_PARM(epp_mode, 1);
 
-#ifdef PCMCIA_DEBUG
-INT_MODULE_PARM(pc_debug, PCMCIA_DEBUG);
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
-static char *version =
-"parport_cs.c 1.29 2002/10/11 06:57:41 (David Hinds)";
-#else
-#define DEBUG(n, args...)
-#endif
 
 /*====================================================================*/
 
@@ -103,7 +95,7 @@ static int parport_probe(struct pcmcia_device *link)
 {
     parport_info_t *info;
 
-    DEBUG(0, "parport_attach()\n");
+    dev_dbg(&link->dev, "parport_attach()\n");
 
     /* Create new parport device */
     info = kzalloc(sizeof(*info), GFP_KERNEL);
@@ -114,7 +106,6 @@ static int parport_probe(struct pcmcia_device *link)
     link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
     link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
     link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
-    link->irq.IRQInfo1 = IRQ_LEVEL_ID;
     link->conf.Attributes = CONF_ENABLE_IRQ;
     link->conf.IntType = INT_MEMORY_AND_IO;
 
@@ -132,7 +123,7 @@ static int parport_probe(struct pcmcia_device *link)
 
 static void parport_detach(struct pcmcia_device *link)
 {
-    DEBUG(0, "parport_detach(0x%p)\n", link);
+    dev_dbg(&link->dev, "parport_detach\n");
 
     parport_cs_release(link);
 
@@ -147,9 +138,6 @@ static void parport_detach(struct pcmcia_device *link)
 
 ======================================================================*/
 
-#define CS_CHECK(fn, ret) \
-do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
-
 static int parport_config_check(struct pcmcia_device *p_dev,
                                cistpl_cftable_entry_t *cfg,
                                cistpl_cftable_entry_t *dflt,
@@ -178,18 +166,20 @@ static int parport_config(struct pcmcia_device *link)
 {
     parport_info_t *info = link->priv;
     struct parport *p;
-    int last_ret, last_fn;
+    int ret;
 
-    DEBUG(0, "parport_config(0x%p)\n", link);
+    dev_dbg(&link->dev, "parport_config\n");
 
-    last_ret = pcmcia_loop_config(link, parport_config_check, NULL);
-    if (last_ret) {
-           cs_error(link, RequestIO, last_ret);
+    ret = pcmcia_loop_config(link, parport_config_check, NULL);
+    if (ret)
            goto failed;
-    }
 
-    CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
-    CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
+    ret = pcmcia_request_irq(link, &link->irq);
+    if (ret)
+           goto failed;
+    ret = pcmcia_request_configuration(link, &link->conf);
+    if (ret)
+           goto failed;
 
     p = parport_pc_probe_port(link->io.BasePort1, link->io.BasePort2,
                              link->irq.AssignedIRQ, PARPORT_DMA_NONE,
@@ -213,8 +203,6 @@ static int parport_config(struct pcmcia_device *link)
 
     return 0;
 
-cs_failed:
-    cs_error(link, last_fn, last_ret);
 failed:
     parport_cs_release(link);
     return -ENODEV;
@@ -232,7 +220,7 @@ static void parport_cs_release(struct pcmcia_device *link)
 {
        parport_info_t *info = link->priv;
 
-       DEBUG(0, "parport_release(0x%p)\n", link);
+       dev_dbg(&link->dev, "parport_release\n");
 
        if (info->ndev) {
                struct parport *p = info->port;
index 22b02c6df8542138a27fcad4511eb008f0afbb0c..416f6ac65b761080a2e81a8ace5c5d442a8ea2d1 100644 (file)
@@ -175,15 +175,6 @@ dmar_parse_one_drhd(struct acpi_dmar_header *header)
        int ret = 0;
 
        drhd = (struct acpi_dmar_hardware_unit *)header;
-       if (!drhd->address) {
-               /* Promote an attitude of violence to a BIOS engineer today */
-               WARN(1, "Your BIOS is broken; DMAR reported at address zero!\n"
-                    "BIOS vendor: %s; Ver: %s; Product Version: %s\n",
-                    dmi_get_system_info(DMI_BIOS_VENDOR),
-                    dmi_get_system_info(DMI_BIOS_VERSION),
-                    dmi_get_system_info(DMI_PRODUCT_VERSION));
-               return -ENODEV;
-       }
        dmaru = kzalloc(sizeof(*dmaru), GFP_KERNEL);
        if (!dmaru)
                return -ENOMEM;
@@ -591,12 +582,53 @@ int __init dmar_table_init(void)
        return 0;
 }
 
+int __init check_zero_address(void)
+{
+       struct acpi_table_dmar *dmar;
+       struct acpi_dmar_header *entry_header;
+       struct acpi_dmar_hardware_unit *drhd;
+
+       dmar = (struct acpi_table_dmar *)dmar_tbl;
+       entry_header = (struct acpi_dmar_header *)(dmar + 1);
+
+       while (((unsigned long)entry_header) <
+                       (((unsigned long)dmar) + dmar_tbl->length)) {
+               /* Avoid looping forever on bad ACPI tables */
+               if (entry_header->length == 0) {
+                       printk(KERN_WARNING PREFIX
+                               "Invalid 0-length structure\n");
+                       return 0;
+               }
+
+               if (entry_header->type == ACPI_DMAR_TYPE_HARDWARE_UNIT) {
+                       drhd = (void *)entry_header;
+                       if (!drhd->address) {
+                               /* Promote an attitude of violence to a BIOS engineer today */
+                               WARN(1, "Your BIOS is broken; DMAR reported at address zero!\n"
+                                    "BIOS vendor: %s; Ver: %s; Product Version: %s\n",
+                                    dmi_get_system_info(DMI_BIOS_VENDOR),
+                                    dmi_get_system_info(DMI_BIOS_VERSION),
+                                    dmi_get_system_info(DMI_PRODUCT_VERSION));
+#ifdef CONFIG_DMAR
+                               dmar_disabled = 1;
+#endif
+                               return 0;
+                       }
+                       break;
+               }
+
+               entry_header = ((void *)entry_header + entry_header->length);
+       }
+       return 1;
+}
+
 void __init detect_intel_iommu(void)
 {
        int ret;
 
        ret = dmar_table_detect();
-
+       if (ret)
+               ret = check_zero_address();
        {
 #ifdef CONFIG_INTR_REMAP
                struct acpi_table_dmar *dmar;
@@ -613,9 +645,12 @@ void __init detect_intel_iommu(void)
                               "x2apic and Intr-remapping.\n");
 #endif
 #ifdef CONFIG_DMAR
-               if (ret && !no_iommu && !iommu_detected && !swiotlb &&
-                   !dmar_disabled)
+               if (ret && !no_iommu && !iommu_detected && !dmar_disabled)
                        iommu_detected = 1;
+#endif
+#ifdef CONFIG_X86
+               if (ret)
+                       x86_init.iommu.iommu_init = intel_iommu_init;
 #endif
        }
        early_acpi_os_unmap_memory(dmar_tbl, dmar_tbl_size);
index b1e97e6825009295088d62b183f8136616bbe917..9261327b49f308941c07af292a31bc379b7cb6b9 100644 (file)
@@ -2767,7 +2767,15 @@ static void *intel_alloc_coherent(struct device *hwdev, size_t size,
 
        size = PAGE_ALIGN(size);
        order = get_order(size);
-       flags &= ~(GFP_DMA | GFP_DMA32);
+
+       if (!iommu_no_mapping(hwdev))
+               flags &= ~(GFP_DMA | GFP_DMA32);
+       else if (hwdev->coherent_dma_mask < dma_get_required_mask(hwdev)) {
+               if (hwdev->coherent_dma_mask < DMA_BIT_MASK(32))
+                       flags |= GFP_DMA;
+               else
+                       flags |= GFP_DMA32;
+       }
 
        vaddr = (void *)__get_free_pages(flags, order);
        if (!vaddr)
@@ -3207,6 +3215,33 @@ static int __init init_iommu_sysfs(void)
 }
 #endif /* CONFIG_PM */
 
+/*
+ * Here we only respond to action of unbound device from driver.
+ *
+ * Added device is not attached to its DMAR domain here yet. That will happen
+ * when mapping the device to iova.
+ */
+static int device_notifier(struct notifier_block *nb,
+                                 unsigned long action, void *data)
+{
+       struct device *dev = data;
+       struct pci_dev *pdev = to_pci_dev(dev);
+       struct dmar_domain *domain;
+
+       domain = find_domain(pdev);
+       if (!domain)
+               return 0;
+
+       if (action == BUS_NOTIFY_UNBOUND_DRIVER && !iommu_pass_through)
+               domain_remove_one_dev_info(domain, pdev);
+
+       return 0;
+}
+
+static struct notifier_block device_nb = {
+       .notifier_call = device_notifier,
+};
+
 int __init intel_iommu_init(void)
 {
        int ret = 0;
@@ -3231,7 +3266,7 @@ int __init intel_iommu_init(void)
         * Check the need for DMA-remapping initialization now.
         * Above initialization will also be used by Interrupt-remapping.
         */
-       if (no_iommu || swiotlb || dmar_disabled)
+       if (no_iommu || dmar_disabled)
                return -ENODEV;
 
        iommu_init_mempool();
@@ -3252,13 +3287,17 @@ int __init intel_iommu_init(void)
        "PCI-DMA: Intel(R) Virtualization Technology for Directed I/O\n");
 
        init_timer(&unmap_timer);
-       force_iommu = 1;
+#ifdef CONFIG_SWIOTLB
+       swiotlb = 0;
+#endif
        dma_ops = &intel_dma_ops;
 
        init_iommu_sysfs();
 
        register_iommu(&intel_iommu_ops);
 
+       bus_register_notifier(&pci_bus_type, &device_nb);
+
        return 0;
 }
 
index 17f38a781d47b5d3a2510da5a2e680e7bf8f2346..f3ccbccf5f21f86690ae1d7b5893678f860d8da0 100644 (file)
@@ -17,24 +17,6 @@ menuconfig PCCARD
 
 if PCCARD
 
-config PCMCIA_DEBUG
-       bool "Enable PCCARD debugging"
-       help
-         Say Y here to enable PCMCIA subsystem debugging.  You
-         will need to choose the debugging level either via the
-         kernel command line, or module options depending whether
-         you build the PCMCIA as modules.
-
-         The kernel command line options are:
-           pcmcia_core.pc_debug=N
-           pcmcia.pc_debug=N
-           sa11xx_core.pc_debug=N
-
-         The module option is called pc_debug=N
-
-         In all the above examples, N is the debugging verbosity
-         level.
-
 config PCMCIA
        tristate "16-bit PCMCIA support"
        select CRC32
@@ -196,9 +178,13 @@ config PCMCIA_BCM63XX
        tristate "bcm63xx pcmcia support"
        depends on BCM63XX && PCMCIA
 
+config PCMCIA_SOC_COMMON
+       bool
+
 config PCMCIA_SA1100
        tristate "SA1100 support"
        depends on ARM && ARCH_SA1100 && PCMCIA
+       select PCMCIA_SOC_COMMON
        help
          Say Y here to include support for SA11x0-based PCMCIA or CF
          sockets, found on HP iPAQs, Yopy, and other StrongARM(R)/
@@ -209,6 +195,7 @@ config PCMCIA_SA1100
 config PCMCIA_SA1111
        tristate "SA1111 support"
        depends on ARM && ARCH_SA1100 && SA1111 && PCMCIA
+       select PCMCIA_SOC_COMMON
        help
          Say Y  here to include support for SA1111-based PCMCIA or CF
          sockets, found on the Jornada 720, Graphicsmaster and other
@@ -222,9 +209,28 @@ config PCMCIA_PXA2XX
        depends on (ARCH_LUBBOCK || MACH_MAINSTONE || PXA_SHARPSL \
                    || MACH_ARMCORE || ARCH_PXA_PALM || TRIZEPS_PCMCIA \
                    || ARCH_VIPER || ARCH_PXA_ESERIES || MACH_STARGATE2)
+       select PCMCIA_SOC_COMMON
        help
          Say Y here to include support for the PXA2xx PCMCIA controller
 
+config PCMCIA_DEBUG
+       bool "Enable debugging"
+       depends on (PCMCIA_SA1111 || PCMCIA_SA1100 || PCMCIA_PXA2XX)
+       help
+         Say Y here to enable debugging for the SoC PCMCIA layer.
+         You will need to choose the debugging level either via the
+         kernel command line, or module options depending whether
+         you build the drivers as modules.
+
+         The kernel command line options are:
+           sa11xx_core.pc_debug=N
+           pxa2xx_core.pc_debug=N
+
+         The module option is called pc_debug=N
+
+         In all the above examples, N is the debugging verbosity
+         level.
+
 config PCMCIA_PROBE
        bool
        default y if ISA && !ARCH_SA1100 && !ARCH_CLPS711X && !PARISC
index a03a38acd77d5a1ed1b34f63a24b03611c67d47f..382938313991a263d77a43c5a03d28516f9939cb 100644 (file)
@@ -22,8 +22,9 @@ obj-$(CONFIG_I82365)                          += i82365.o
 obj-$(CONFIG_I82092)                           += i82092.o
 obj-$(CONFIG_TCIC)                             += tcic.o
 obj-$(CONFIG_PCMCIA_M8XX)                      += m8xx_pcmcia.o
-obj-$(CONFIG_PCMCIA_SA1100)                    += sa11xx_core.o sa1100_cs.o
-obj-$(CONFIG_PCMCIA_SA1111)                    += sa11xx_core.o sa1111_cs.o
+obj-$(CONFIG_PCMCIA_SOC_COMMON)                        += soc_common.o
+obj-$(CONFIG_PCMCIA_SA1100)                    += sa11xx_base.o sa1100_cs.o
+obj-$(CONFIG_PCMCIA_SA1111)                    += sa11xx_base.o sa1111_cs.o
 obj-$(CONFIG_M32R_PCC)                         += m32r_pcc.o
 obj-$(CONFIG_M32R_CFC)                         += m32r_cfc.o
 obj-$(CONFIG_PCMCIA_AU1X00)                    += au1x00_ss.o
@@ -35,9 +36,6 @@ obj-$(CONFIG_BFIN_CFPCMCIA)                   += bfin_cf_pcmcia.o
 obj-$(CONFIG_AT91_CF)                          += at91_cf.o
 obj-$(CONFIG_ELECTRA_CF)                       += electra_cf.o
 
-sa11xx_core-y                                  += soc_common.o sa11xx_base.o
-pxa2xx_core-y                                  += soc_common.o pxa2xx_base.o
-
 au1x00_ss-y                                    += au1000_generic.o
 au1x00_ss-$(CONFIG_MIPS_PB1000)                        += au1000_pb1x00.o
 au1x00_ss-$(CONFIG_MIPS_PB1100)                        += au1000_pb1x00.o
@@ -77,4 +75,4 @@ pxa2xx-obj-$(CONFIG_MACH_PALMLD)              += pxa2xx_palmld.o
 pxa2xx-obj-$(CONFIG_MACH_E740)                 += pxa2xx_e740.o
 pxa2xx-obj-$(CONFIG_MACH_STARGATE2)            += pxa2xx_stargate2.o
 
-obj-$(CONFIG_PCMCIA_PXA2XX)                    += pxa2xx_core.o $(pxa2xx-obj-y)
+obj-$(CONFIG_PCMCIA_PXA2XX)                    += pxa2xx_base.o $(pxa2xx-obj-y)
index db77e1f3309a087a6c93c06d251284981df80311..4cd70d0568109d061d6b716140adc52494cfd062 100644 (file)
@@ -91,7 +91,7 @@ static u_int xlate_rom_addr(void __iomem *b, u_int addr)
 static void cb_release_cis_mem(struct pcmcia_socket * s)
 {
        if (s->cb_cis_virt) {
-               cs_dbg(s, 1, "cb_release_cis_mem()\n");
+               dev_dbg(&s->dev, "cb_release_cis_mem()\n");
                iounmap(s->cb_cis_virt);
                s->cb_cis_virt = NULL;
                s->cb_cis_res = NULL;
@@ -132,7 +132,7 @@ int read_cb_mem(struct pcmcia_socket * s, int space, u_int addr, u_int len, void
        struct pci_dev *dev;
        struct resource *res;
 
-       cs_dbg(s, 3, "read_cb_mem(%d, %#x, %u)\n", space, addr, len);
+       dev_dbg(&s->dev, "read_cb_mem(%d, %#x, %u)\n", space, addr, len);
 
        dev = pci_get_slot(s->cb_dev->subordinate, 0);
        if (!dev)
index ecd4fc7f666f286170251c99943f23ebdf29edce..446a4576e73e6c717d44b5dd954f1f606fd3e414 100644 (file)
 #ifndef _LINUX_CIRRUS_H
 #define _LINUX_CIRRUS_H
 
-#ifndef PCI_VENDOR_ID_CIRRUS
-#define PCI_VENDOR_ID_CIRRUS           0x1013
-#endif
-#ifndef PCI_DEVICE_ID_CIRRUS_6729
-#define PCI_DEVICE_ID_CIRRUS_6729      0x1100
-#endif
-#ifndef PCI_DEVICE_ID_CIRRUS_6832
-#define PCI_DEVICE_ID_CIRRUS_6832      0x1110
-#endif
-
 #define PD67_MISC_CTL_1                0x16    /* Misc control 1 */
 #define PD67_FIFO_CTL          0x17    /* FIFO control */
 #define PD67_MISC_CTL_2                0x1E    /* Misc control 2 */
index 6c4a4fc836309e0af50b0a252de0a964a8291612..8c1b73cf021b2fee37c17f792748f27b0ec5f794 100644 (file)
@@ -138,7 +138,7 @@ int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
     void __iomem *sys, *end;
     unsigned char *buf = ptr;
     
-    cs_dbg(s, 3, "pcmcia_read_cis_mem(%d, %#x, %u)\n", attr, addr, len);
+    dev_dbg(&s->dev, "pcmcia_read_cis_mem(%d, %#x, %u)\n", attr, addr, len);
 
     if (attr & IS_INDIRECT) {
        /* Indirect accesses use a bunch of special registers at fixed
@@ -190,7 +190,7 @@ int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
            addr = 0;
        }
     }
-    cs_dbg(s, 3, "  %#2.2x %#2.2x %#2.2x %#2.2x ...\n",
+    dev_dbg(&s->dev, "  %#2.2x %#2.2x %#2.2x %#2.2x ...\n",
          *(u_char *)(ptr+0), *(u_char *)(ptr+1),
          *(u_char *)(ptr+2), *(u_char *)(ptr+3));
     return 0;
@@ -204,7 +204,7 @@ void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
     void __iomem *sys, *end;
     unsigned char *buf = ptr;
     
-    cs_dbg(s, 3, "pcmcia_write_cis_mem(%d, %#x, %u)\n", attr, addr, len);
+    dev_dbg(&s->dev, "pcmcia_write_cis_mem(%d, %#x, %u)\n", attr, addr, len);
 
     if (attr & IS_INDIRECT) {
        /* Indirect accesses use a bunch of special registers at fixed
@@ -584,7 +584,7 @@ int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int function, tuple_
        ofs += link[1] + 2;
     }
     if (i == MAX_TUPLES) {
-       cs_dbg(s, 1, "cs: overrun in pcmcia_get_next_tuple\n");
+       dev_dbg(&s->dev, "cs: overrun in pcmcia_get_next_tuple\n");
        return -ENOSPC;
     }
     
@@ -1440,7 +1440,7 @@ int pcmcia_parse_tuple(tuple_t *tuple, cisparse_t *parse)
        break;
     }
     if (ret)
-           __cs_dbg(0, "parse_tuple failed %d\n", ret);
+           pr_debug("parse_tuple failed %d\n", ret);
     return ret;
 }
 EXPORT_SYMBOL(pcmcia_parse_tuple);
@@ -1482,6 +1482,67 @@ done:
 }
 EXPORT_SYMBOL(pccard_read_tuple);
 
+
+/**
+ * pccard_loop_tuple() - loop over tuples in the CIS
+ * @s:         the struct pcmcia_socket where the card is inserted
+ * @function:  the device function we loop for
+ * @code:      which CIS code shall we look for?
+ * @parse:     buffer where the tuple shall be parsed (or NULL, if no parse)
+ * @priv_data: private data to be passed to the loop_tuple function.
+ * @loop_tuple:        function to call for each CIS entry of type @function. IT
+ *             gets passed the raw tuple, the paresed tuple (if @parse is
+ *             set) and @priv_data.
+ *
+ * pccard_loop_tuple() loops over all CIS entries of type @function, and
+ * calls the @loop_tuple function for each entry. If the call to @loop_tuple
+ * returns 0, the loop exits. Returns 0 on success or errorcode otherwise.
+ */
+int pccard_loop_tuple(struct pcmcia_socket *s, unsigned int function,
+                     cisdata_t code, cisparse_t *parse, void *priv_data,
+                     int (*loop_tuple) (tuple_t *tuple,
+                                        cisparse_t *parse,
+                                        void *priv_data))
+{
+       tuple_t tuple;
+       cisdata_t *buf;
+       int ret;
+
+       buf = kzalloc(256, GFP_KERNEL);
+       if (buf == NULL) {
+               dev_printk(KERN_WARNING, &s->dev, "no memory to read tuple\n");
+               return -ENOMEM;
+       }
+
+       tuple.TupleData = buf;
+       tuple.TupleDataMax = 255;
+       tuple.TupleOffset = 0;
+       tuple.DesiredTuple = code;
+       tuple.Attributes = 0;
+
+       ret = pccard_get_first_tuple(s, function, &tuple);
+       while (!ret) {
+               if (pccard_get_tuple_data(s, &tuple))
+                       goto next_entry;
+
+               if (parse)
+                       if (pcmcia_parse_tuple(&tuple, parse))
+                               goto next_entry;
+
+               ret = loop_tuple(&tuple, parse, priv_data);
+               if (!ret)
+                       break;
+
+next_entry:
+               ret = pccard_get_next_tuple(s, function, &tuple);
+       }
+
+       kfree(buf);
+       return ret;
+}
+EXPORT_SYMBOL(pccard_loop_tuple);
+
+
 /*======================================================================
 
     This tries to determine if a card has a sensible CIS.  It returns
index 698d75cda084c36a4e15cdae7c6c1809bb9d417b..790af87a922fc6e541f5ab2bb02d2b2f315388d9 100644 (file)
@@ -61,17 +61,6 @@ INT_MODULE_PARM(unreset_limit,       30);            /* unreset_check's */
 /* Access speed for attribute memory windows */
 INT_MODULE_PARM(cis_speed,     300);           /* ns */
 
-#ifdef CONFIG_PCMCIA_DEBUG
-static int pc_debug;
-
-module_param(pc_debug, int, 0644);
-
-int cs_debug_level(int level)
-{
-       return pc_debug > level;
-}
-#endif
-
 
 socket_state_t dead_socket = {
        .csc_mask       = SS_DETECT,
@@ -190,7 +179,7 @@ int pcmcia_register_socket(struct pcmcia_socket *socket)
        if (!socket || !socket->ops || !socket->dev.parent || !socket->resource_ops)
                return -EINVAL;
 
-       cs_dbg(socket, 0, "pcmcia_register_socket(0x%p)\n", socket->ops);
+       dev_dbg(&socket->dev, "pcmcia_register_socket(0x%p)\n", socket->ops);
 
        spin_lock_init(&socket->lock);
 
@@ -262,6 +251,13 @@ int pcmcia_register_socket(struct pcmcia_socket *socket)
 
        pcmcia_parse_events(socket, SS_DETECT);
 
+       /*
+        * Let's try to get the PCMCIA module for 16-bit PCMCIA support.
+        * If it fails, it doesn't matter -- we still have 32-bit CardBus
+        * support to offer, so this is not a failure mode.
+        */
+       request_module_nowait("pcmcia");
+
        return 0;
 
  err:
@@ -282,7 +278,7 @@ void pcmcia_unregister_socket(struct pcmcia_socket *socket)
        if (!socket)
                return;
 
-       cs_dbg(socket, 0, "pcmcia_unregister_socket(0x%p)\n", socket->ops);
+       dev_dbg(&socket->dev, "pcmcia_unregister_socket(0x%p)\n", socket->ops);
 
        if (socket->thread)
                kthread_stop(socket->thread);
@@ -335,7 +331,7 @@ static int send_event(struct pcmcia_socket *s, event_t event, int priority)
        if (s->state & SOCKET_CARDBUS)
                return 0;
 
-       cs_dbg(s, 1, "send_event(event %d, pri %d, callback 0x%p)\n",
+       dev_dbg(&s->dev, "send_event(event %d, pri %d, callback 0x%p)\n",
           event, priority, s->callback);
 
        if (!s->callback)
@@ -352,7 +348,7 @@ static int send_event(struct pcmcia_socket *s, event_t event, int priority)
 
 static void socket_remove_drivers(struct pcmcia_socket *skt)
 {
-       cs_dbg(skt, 4, "remove_drivers\n");
+       dev_dbg(&skt->dev, "remove_drivers\n");
 
        send_event(skt, CS_EVENT_CARD_REMOVAL, CS_EVENT_PRI_HIGH);
 }
@@ -361,7 +357,7 @@ static int socket_reset(struct pcmcia_socket *skt)
 {
        int status, i;
 
-       cs_dbg(skt, 4, "reset\n");
+       dev_dbg(&skt->dev, "reset\n");
 
        skt->socket.flags |= SS_OUTPUT_ENA | SS_RESET;
        skt->ops->set_socket(skt, &skt->socket);
@@ -383,7 +379,7 @@ static int socket_reset(struct pcmcia_socket *skt)
                msleep(unreset_check * 10);
        }
 
-       cs_err(skt, "time out after reset.\n");
+       dev_printk(KERN_ERR, &skt->dev, "time out after reset.\n");
        return -ETIMEDOUT;
 }
 
@@ -397,7 +393,7 @@ static void socket_shutdown(struct pcmcia_socket *s)
 {
        int status;
 
-       cs_dbg(s, 4, "shutdown\n");
+       dev_dbg(&s->dev, "shutdown\n");
 
        socket_remove_drivers(s);
        s->state &= SOCKET_INUSE | SOCKET_PRESENT;
@@ -432,7 +428,7 @@ static int socket_setup(struct pcmcia_socket *skt, int initial_delay)
 {
        int status, i;
 
-       cs_dbg(skt, 4, "setup\n");
+       dev_dbg(&skt->dev, "setup\n");
 
        skt->ops->get_status(skt, &status);
        if (!(status & SS_DETECT))
@@ -452,13 +448,15 @@ static int socket_setup(struct pcmcia_socket *skt, int initial_delay)
        }
 
        if (status & SS_PENDING) {
-               cs_err(skt, "voltage interrogation timed out.\n");
+               dev_printk(KERN_ERR, &skt->dev,
+                          "voltage interrogation timed out.\n");
                return -ETIMEDOUT;
        }
 
        if (status & SS_CARDBUS) {
                if (!(skt->features & SS_CAP_CARDBUS)) {
-                       cs_err(skt, "cardbus cards are not supported.\n");
+                       dev_printk(KERN_ERR, &skt->dev,
+                               "cardbus cards are not supported.\n");
                        return -EINVAL;
                }
                skt->state |= SOCKET_CARDBUS;
@@ -472,7 +470,7 @@ static int socket_setup(struct pcmcia_socket *skt, int initial_delay)
        else if (!(status & SS_XVCARD))
                skt->socket.Vcc = skt->socket.Vpp = 50;
        else {
-               cs_err(skt, "unsupported voltage key.\n");
+               dev_printk(KERN_ERR, &skt->dev, "unsupported voltage key.\n");
                return -EIO;
        }
 
@@ -489,7 +487,7 @@ static int socket_setup(struct pcmcia_socket *skt, int initial_delay)
 
        skt->ops->get_status(skt, &status);
        if (!(status & SS_POWERON)) {
-               cs_err(skt, "unable to apply power.\n");
+               dev_printk(KERN_ERR, &skt->dev, "unable to apply power.\n");
                return -EIO;
        }
 
@@ -509,7 +507,7 @@ static int socket_insert(struct pcmcia_socket *skt)
 {
        int ret;
 
-       cs_dbg(skt, 4, "insert\n");
+       dev_dbg(&skt->dev, "insert\n");
 
        if (!cs_socket_get(skt))
                return -ENODEV;
@@ -529,7 +527,7 @@ static int socket_insert(struct pcmcia_socket *skt)
                        skt->state |= SOCKET_CARDBUS_CONFIG;
                }
 #endif
-               cs_dbg(skt, 4, "insert done\n");
+               dev_dbg(&skt->dev, "insert done\n");
 
                send_event(skt, CS_EVENT_CARD_INSERTION, CS_EVENT_PRI_LOW);
        } else {
@@ -576,7 +574,7 @@ static int socket_late_resume(struct pcmcia_socket *skt)
                 * FIXME: need a better check here for cardbus cards.
                 */
                if (verify_cis_cache(skt) != 0) {
-                       cs_dbg(skt, 4, "cis mismatch - different card\n");
+                       dev_dbg(&skt->dev, "cis mismatch - different card\n");
                        socket_remove_drivers(skt);
                        destroy_cis_cache(skt);
                        /*
@@ -587,7 +585,7 @@ static int socket_late_resume(struct pcmcia_socket *skt)
                        msleep(200);
                        send_event(skt, CS_EVENT_CARD_INSERTION, CS_EVENT_PRI_LOW);
                } else {
-                       cs_dbg(skt, 4, "cis matches cache\n");
+                       dev_dbg(&skt->dev, "cis matches cache\n");
                        send_event(skt, CS_EVENT_PM_RESUME, CS_EVENT_PRI_LOW);
                }
        } else {
@@ -723,7 +721,7 @@ static int pccardd(void *__skt)
 void pcmcia_parse_events(struct pcmcia_socket *s, u_int events)
 {
        unsigned long flags;
-       cs_dbg(s, 4, "parse_events: events %08x\n", events);
+       dev_dbg(&s->dev, "parse_events: events %08x\n", events);
        if (s->thread) {
                spin_lock_irqsave(&s->thread_lock, flags);
                s->thread_events |= events;
@@ -773,19 +771,22 @@ int pcmcia_reset_card(struct pcmcia_socket *skt)
 {
        int ret;
 
-       cs_dbg(skt, 1, "resetting socket\n");
+       dev_dbg(&skt->dev, "resetting socket\n");
 
        mutex_lock(&skt->skt_mutex);
        do {
                if (!(skt->state & SOCKET_PRESENT)) {
+                       dev_dbg(&skt->dev, "can't reset, not present\n");
                        ret = -ENODEV;
                        break;
                }
                if (skt->state & SOCKET_SUSPEND) {
+                       dev_dbg(&skt->dev, "can't reset, suspended\n");
                        ret = -EBUSY;
                        break;
                }
                if (skt->state & SOCKET_CARDBUS) {
+                       dev_dbg(&skt->dev, "can't reset, is cardbus\n");
                        ret = -EPERM;
                        break;
                }
@@ -818,7 +819,7 @@ int pcmcia_suspend_card(struct pcmcia_socket *skt)
 {
        int ret;
 
-       cs_dbg(skt, 1, "suspending socket\n");
+       dev_dbg(&skt->dev, "suspending socket\n");
 
        mutex_lock(&skt->skt_mutex);
        do {
@@ -848,7 +849,7 @@ int pcmcia_resume_card(struct pcmcia_socket *skt)
 {
        int ret;
     
-       cs_dbg(skt, 1, "waking up socket\n");
+       dev_dbg(&skt->dev, "waking up socket\n");
 
        mutex_lock(&skt->skt_mutex);
        do {
@@ -876,7 +877,7 @@ int pcmcia_eject_card(struct pcmcia_socket *skt)
 {
        int ret;
     
-       cs_dbg(skt, 1, "user eject request\n");
+       dev_dbg(&skt->dev, "user eject request\n");
 
        mutex_lock(&skt->skt_mutex);
        do {
@@ -905,7 +906,7 @@ int pcmcia_insert_card(struct pcmcia_socket *skt)
 {
        int ret;
 
-       cs_dbg(skt, 1, "user insert request\n");
+       dev_dbg(&skt->dev, "user insert request\n");
 
        mutex_lock(&skt->skt_mutex);
        do {
index 1f4098f1354db464cccf1b8ab0f7345c62516ee8..3bc02d53a3a30ae91bd61a6bd3bd2554958c93b9 100644 (file)
@@ -107,28 +107,6 @@ static inline void cs_socket_put(struct pcmcia_socket *skt)
        }
 }
 
-#ifdef CONFIG_PCMCIA_DEBUG
-extern int cs_debug_level(int);
-
-#define cs_dbg(skt, lvl, fmt, arg...) do {             \
-       if (cs_debug_level(lvl))                        \
-               dev_printk(KERN_DEBUG, &skt->dev,       \
-                "cs: " fmt, ## arg);                   \
-} while (0)
-#define __cs_dbg(lvl, fmt, arg...) do {                        \
-       if (cs_debug_level(lvl))                        \
-               printk(KERN_DEBUG                       \
-                "cs: " fmt, ## arg);                   \
-} while (0)
-
-#else
-#define cs_dbg(skt, lvl, fmt, arg...) do { } while (0)
-#define __cs_dbg(lvl, fmt, arg...) do { } while (0)
-#endif
-
-#define cs_err(skt, fmt, arg...) \
-       dev_printk(KERN_ERR, &skt->dev, "cs: " fmt, ## arg)
-
 
 /*
  * Stuff internal to module "pcmcia_core":
@@ -170,10 +148,6 @@ extern struct rw_semaphore pcmcia_socket_list_rwsem;
 extern struct list_head pcmcia_socket_list;
 extern struct class pcmcia_socket_class;
 
-int pcmcia_get_window(struct pcmcia_socket *s,
-                     window_handle_t *handle,
-                     int idx,
-                     win_req_t *req);
 int pccard_register_pcmcia(struct pcmcia_socket *s, struct pcmcia_callback *c);
 struct pcmcia_socket *pcmcia_get_socket_by_nr(unsigned int nr);
 
@@ -199,6 +173,22 @@ int pcmcia_replace_cis(struct pcmcia_socket *s,
                       const u8 *data, const size_t len);
 int pccard_validate_cis(struct pcmcia_socket *s, unsigned int *count);
 
+/* loop over CIS entries */
+int pccard_loop_tuple(struct pcmcia_socket *s, unsigned int function,
+                     cisdata_t code, cisparse_t *parse, void *priv_data,
+                     int (*loop_tuple) (tuple_t *tuple,
+                                        cisparse_t *parse,
+                                        void *priv_data));
+
+int pccard_get_first_tuple(struct pcmcia_socket *s, unsigned int function,
+                       tuple_t *tuple);
+
+int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int function,
+                       tuple_t *tuple);
+
+int pccard_get_tuple_data(struct pcmcia_socket *s, tuple_t *tuple);
+
+
 /* rsrc_mgr.c */
 int pcmcia_validate_mem(struct pcmcia_socket *s);
 struct resource *pcmcia_find_io_region(unsigned long base,
index f5b7079f13d36e90d606215af99965a3b2f1fe52..05893d41dd418d19dde7847da6f33c7926b2b966 100644 (file)
@@ -41,129 +41,11 @@ MODULE_AUTHOR("David Hinds <dahinds@users.sourceforge.net>");
 MODULE_DESCRIPTION("PCMCIA Driver Services");
 MODULE_LICENSE("GPL");
 
-#ifdef CONFIG_PCMCIA_DEBUG
-int ds_pc_debug;
-
-module_param_named(pc_debug, ds_pc_debug, int, 0644);
-
-#define ds_dbg(lvl, fmt, arg...) do {                          \
-       if (ds_pc_debug > (lvl))                                \
-               printk(KERN_DEBUG "ds: " fmt , ## arg);         \
-} while (0)
-#define ds_dev_dbg(lvl, dev, fmt, arg...) do {                         \
-       if (ds_pc_debug > (lvl))                                        \
-               dev_printk(KERN_DEBUG, dev, "ds: " fmt , ## arg);       \
-} while (0)
-#else
-#define ds_dbg(lvl, fmt, arg...) do { } while (0)
-#define ds_dev_dbg(lvl, dev, fmt, arg...) do { } while (0)
-#endif
 
 spinlock_t pcmcia_dev_list_lock;
 
 /*====================================================================*/
 
-/* code which was in cs.c before */
-
-/* String tables for error messages */
-
-typedef struct lookup_t {
-    const int key;
-    const char *msg;
-} lookup_t;
-
-static const lookup_t error_table[] = {
-    { 0,                       "Operation succeeded" },
-    { -EIO,                    "Input/Output error" },
-    { -ENODEV,                 "No card present" },
-    { -EINVAL,                 "Bad parameter" },
-    { -EACCES,                 "Configuration locked" },
-    { -EBUSY,                  "Resource in use" },
-    { -ENOSPC,                 "No more items" },
-    { -ENOMEM,                 "Out of resource" },
-};
-
-
-static const lookup_t service_table[] = {
-    { AccessConfigurationRegister,     "AccessConfigurationRegister" },
-    { AddSocketServices,               "AddSocketServices" },
-    { AdjustResourceInfo,              "AdjustResourceInfo" },
-    { CheckEraseQueue,                 "CheckEraseQueue" },
-    { CloseMemory,                     "CloseMemory" },
-    { DeregisterClient,                        "DeregisterClient" },
-    { DeregisterEraseQueue,            "DeregisterEraseQueue" },
-    { GetCardServicesInfo,             "GetCardServicesInfo" },
-    { GetClientInfo,                   "GetClientInfo" },
-    { GetConfigurationInfo,            "GetConfigurationInfo" },
-    { GetEventMask,                    "GetEventMask" },
-    { GetFirstClient,                  "GetFirstClient" },
-    { GetFirstRegion,                  "GetFirstRegion" },
-    { GetFirstTuple,                   "GetFirstTuple" },
-    { GetNextClient,                   "GetNextClient" },
-    { GetNextRegion,                   "GetNextRegion" },
-    { GetNextTuple,                    "GetNextTuple" },
-    { GetStatus,                       "GetStatus" },
-    { GetTupleData,                    "GetTupleData" },
-    { MapMemPage,                      "MapMemPage" },
-    { ModifyConfiguration,             "ModifyConfiguration" },
-    { ModifyWindow,                    "ModifyWindow" },
-    { OpenMemory,                      "OpenMemory" },
-    { ParseTuple,                      "ParseTuple" },
-    { ReadMemory,                      "ReadMemory" },
-    { RegisterClient,                  "RegisterClient" },
-    { RegisterEraseQueue,              "RegisterEraseQueue" },
-    { RegisterMTD,                     "RegisterMTD" },
-    { ReleaseConfiguration,            "ReleaseConfiguration" },
-    { ReleaseIO,                       "ReleaseIO" },
-    { ReleaseIRQ,                      "ReleaseIRQ" },
-    { ReleaseWindow,                   "ReleaseWindow" },
-    { RequestConfiguration,            "RequestConfiguration" },
-    { RequestIO,                       "RequestIO" },
-    { RequestIRQ,                      "RequestIRQ" },
-    { RequestSocketMask,               "RequestSocketMask" },
-    { RequestWindow,                   "RequestWindow" },
-    { ResetCard,                       "ResetCard" },
-    { SetEventMask,                    "SetEventMask" },
-    { ValidateCIS,                     "ValidateCIS" },
-    { WriteMemory,                     "WriteMemory" },
-    { BindDevice,                      "BindDevice" },
-    { BindMTD,                         "BindMTD" },
-    { ReportError,                     "ReportError" },
-    { SuspendCard,                     "SuspendCard" },
-    { ResumeCard,                      "ResumeCard" },
-    { EjectCard,                       "EjectCard" },
-    { InsertCard,                      "InsertCard" },
-    { ReplaceCIS,                      "ReplaceCIS" }
-};
-
-const char *pcmcia_error_func(int func)
-{
-       int i;
-
-       for (i = 0; i < ARRAY_SIZE(service_table); i++)
-               if (service_table[i].key == func)
-                       return service_table[i].msg;
-
-       return "Unknown service number";
-}
-EXPORT_SYMBOL(pcmcia_error_func);
-
-const char *pcmcia_error_ret(int ret)
-{
-       int i;
-
-       for (i = 0; i < ARRAY_SIZE(error_table); i++)
-               if (error_table[i].key == ret)
-                       return error_table[i].msg;
-
-       return "unknown";
-}
-EXPORT_SYMBOL(pcmcia_error_ret);
-
-/*======================================================================*/
-
-
-
 static void pcmcia_check_driver(struct pcmcia_driver *p_drv)
 {
        struct pcmcia_device_id *did = p_drv->id_table;
@@ -303,7 +185,7 @@ int pcmcia_register_driver(struct pcmcia_driver *driver)
        spin_lock_init(&driver->dynids.lock);
        INIT_LIST_HEAD(&driver->dynids.list);
 
-       ds_dbg(3, "registering driver %s\n", driver->drv.name);
+       pr_debug("registering driver %s\n", driver->drv.name);
 
        error = driver_register(&driver->drv);
        if (error < 0)
@@ -323,7 +205,7 @@ EXPORT_SYMBOL(pcmcia_register_driver);
  */
 void pcmcia_unregister_driver(struct pcmcia_driver *driver)
 {
-       ds_dbg(3, "unregistering driver %s\n", driver->drv.name);
+       pr_debug("unregistering driver %s\n", driver->drv.name);
        driver_unregister(&driver->drv);
        pcmcia_free_dynids(driver);
 }
@@ -350,14 +232,14 @@ void pcmcia_put_dev(struct pcmcia_device *p_dev)
 static void pcmcia_release_function(struct kref *ref)
 {
        struct config_t *c = container_of(ref, struct config_t, ref);
-       ds_dbg(1, "releasing config_t\n");
+       pr_debug("releasing config_t\n");
        kfree(c);
 }
 
 static void pcmcia_release_dev(struct device *dev)
 {
        struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
-       ds_dev_dbg(1, dev, "releasing device\n");
+       dev_dbg(dev, "releasing device\n");
        pcmcia_put_socket(p_dev->socket);
        kfree(p_dev->devname);
        kref_put(&p_dev->function_config->ref, pcmcia_release_function);
@@ -367,7 +249,7 @@ static void pcmcia_release_dev(struct device *dev)
 static void pcmcia_add_device_later(struct pcmcia_socket *s, int mfc)
 {
        if (!s->pcmcia_state.device_add_pending) {
-               ds_dev_dbg(1, &s->dev, "scheduling to add %s secondary"
+               dev_dbg(&s->dev, "scheduling to add %s secondary"
                       " device to %d\n", mfc ? "mfc" : "pfc", s->sock);
                s->pcmcia_state.device_add_pending = 1;
                s->pcmcia_state.mfc_pfc = mfc;
@@ -405,7 +287,7 @@ static int pcmcia_device_probe(struct device * dev)
         */
        did = dev_get_drvdata(&p_dev->dev);
 
-       ds_dev_dbg(1, dev, "trying to bind to %s\n", p_drv->drv.name);
+       dev_dbg(dev, "trying to bind to %s\n", p_drv->drv.name);
 
        if ((!p_drv->probe) || (!p_dev->function_config) ||
            (!try_module_get(p_drv->owner))) {
@@ -428,7 +310,7 @@ static int pcmcia_device_probe(struct device * dev)
 
        ret = p_drv->probe(p_dev);
        if (ret) {
-               ds_dev_dbg(1, dev, "binding to %s failed with %d\n",
+               dev_dbg(dev, "binding to %s failed with %d\n",
                           p_drv->drv.name, ret);
                goto put_module;
        }
@@ -456,7 +338,7 @@ static void pcmcia_card_remove(struct pcmcia_socket *s, struct pcmcia_device *le
        struct pcmcia_device    *tmp;
        unsigned long           flags;
 
-       ds_dev_dbg(2, leftover ? &leftover->dev : &s->dev,
+       dev_dbg(leftover ? &leftover->dev : &s->dev,
                   "pcmcia_card_remove(%d) %s\n", s->sock,
                   leftover ? leftover->devname : "");
 
@@ -475,7 +357,7 @@ static void pcmcia_card_remove(struct pcmcia_socket *s, struct pcmcia_device *le
                p_dev->_removed=1;
                spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
 
-               ds_dev_dbg(2, &p_dev->dev, "unregistering device\n");
+               dev_dbg(&p_dev->dev, "unregistering device\n");
                device_unregister(&p_dev->dev);
        }
 
@@ -492,7 +374,7 @@ static int pcmcia_device_remove(struct device * dev)
        p_dev = to_pcmcia_dev(dev);
        p_drv = to_pcmcia_drv(dev->driver);
 
-       ds_dev_dbg(1, dev, "removing device\n");
+       dev_dbg(dev, "removing device\n");
 
        /* If we're removing the primary module driving a
         * pseudo multi-function card, we need to unbind
@@ -572,7 +454,7 @@ static int pcmcia_device_query(struct pcmcia_device *p_dev)
                }
                if (!pccard_read_tuple(p_dev->socket, p_dev->func,
                                      CISTPL_DEVICE_GEO, devgeo)) {
-                       ds_dev_dbg(0, &p_dev->dev,
+                       dev_dbg(&p_dev->dev,
                                   "mem device geometry probably means "
                                   "FUNCID_MEMORY\n");
                        p_dev->func_id = CISTPL_FUNCID_MEMORY;
@@ -628,7 +510,7 @@ struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int f
 
        mutex_lock(&device_add_lock);
 
-       ds_dbg(3, "adding device to %d, function %d\n", s->sock, function);
+       pr_debug("adding device to %d, function %d\n", s->sock, function);
 
        /* max of 4 devices per card */
        if (s->device_count == 4)
@@ -654,7 +536,7 @@ struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int f
        p_dev->devname = kasprintf(GFP_KERNEL, "pcmcia%s", dev_name(&p_dev->dev));
        if (!p_dev->devname)
                goto err_free;
-       ds_dev_dbg(3, &p_dev->dev, "devname is %s\n", p_dev->devname);
+       dev_dbg(&p_dev->dev, "devname is %s\n", p_dev->devname);
 
        spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
 
@@ -677,7 +559,7 @@ struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int f
        spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
 
        if (!p_dev->function_config) {
-               ds_dev_dbg(3, &p_dev->dev, "creating config_t\n");
+               dev_dbg(&p_dev->dev, "creating config_t\n");
                p_dev->function_config = kzalloc(sizeof(struct config_t),
                                                 GFP_KERNEL);
                if (!p_dev->function_config)
@@ -722,20 +604,20 @@ static int pcmcia_card_add(struct pcmcia_socket *s)
        int ret = 0;
 
        if (!(s->resource_setup_done)) {
-               ds_dev_dbg(3, &s->dev,
+               dev_dbg(&s->dev,
                           "no resources available, delaying card_add\n");
                return -EAGAIN; /* try again, but later... */
        }
 
        if (pcmcia_validate_mem(s)) {
-               ds_dev_dbg(3, &s->dev, "validating mem resources failed, "
+               dev_dbg(&s->dev, "validating mem resources failed, "
                       "delaying card_add\n");
                return -EAGAIN; /* try again, but later... */
        }
 
        ret = pccard_validate_cis(s, &no_chains);
        if (ret || !no_chains) {
-               ds_dev_dbg(0, &s->dev, "invalid CIS or invalid resources\n");
+               dev_dbg(&s->dev, "invalid CIS or invalid resources\n");
                return -ENODEV;
        }
 
@@ -756,7 +638,7 @@ static void pcmcia_delayed_add_device(struct work_struct *work)
 {
        struct pcmcia_socket *s =
                container_of(work, struct pcmcia_socket, device_add);
-       ds_dev_dbg(1, &s->dev, "adding additional device to %d\n", s->sock);
+       dev_dbg(&s->dev, "adding additional device to %d\n", s->sock);
        pcmcia_device_add(s, s->pcmcia_state.mfc_pfc);
        s->pcmcia_state.device_add_pending = 0;
        s->pcmcia_state.mfc_pfc = 0;
@@ -766,7 +648,7 @@ static int pcmcia_requery(struct device *dev, void * _data)
 {
        struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
        if (!p_dev->dev.driver) {
-               ds_dev_dbg(1, dev, "update device information\n");
+               dev_dbg(dev, "update device information\n");
                pcmcia_device_query(p_dev);
        }
 
@@ -780,7 +662,7 @@ static void pcmcia_bus_rescan(struct pcmcia_socket *skt, int new_cis)
        unsigned long flags;
 
        /* must be called with skt_mutex held */
-       ds_dev_dbg(0, &skt->dev, "re-scanning socket %d\n", skt->sock);
+       dev_dbg(&skt->dev, "re-scanning socket %d\n", skt->sock);
 
        spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
        if (list_empty(&skt->devices_list))
@@ -835,7 +717,7 @@ static int pcmcia_load_firmware(struct pcmcia_device *dev, char * filename)
        if (!filename)
                return -EINVAL;
 
-       ds_dev_dbg(1, &dev->dev, "trying to load CIS file %s\n", filename);
+       dev_dbg(&dev->dev, "trying to load CIS file %s\n", filename);
 
        if (request_firmware(&fw, filename, &dev->dev) == 0) {
                if (fw->size >= CISTPL_MAX_CIS_SIZE) {
@@ -953,14 +835,14 @@ static inline int pcmcia_devmatch(struct pcmcia_device *dev,
                 * after it has re-checked that there is no possible module
                 * with a prod_id/manf_id/card_id match.
                 */
-               ds_dev_dbg(0, &dev->dev,
+               dev_dbg(&dev->dev,
                        "skipping FUNC_ID match until userspace interaction\n");
                if (!dev->allow_func_id_match)
                        return 0;
        }
 
        if (did->match_flags & PCMCIA_DEV_ID_MATCH_FAKE_CIS) {
-               ds_dev_dbg(0, &dev->dev, "device needs a fake CIS\n");
+               dev_dbg(&dev->dev, "device needs a fake CIS\n");
                if (!dev->socket->fake_cis)
                        pcmcia_load_firmware(dev, did->cisfile);
 
@@ -992,9 +874,9 @@ static int pcmcia_bus_match(struct device * dev, struct device_driver * drv) {
        /* match dynamic devices first */
        spin_lock(&p_drv->dynids.lock);
        list_for_each_entry(dynid, &p_drv->dynids.list, node) {
-               ds_dev_dbg(3, dev, "trying to match to %s\n", drv->name);
+               dev_dbg(dev, "trying to match to %s\n", drv->name);
                if (pcmcia_devmatch(p_dev, &dynid->id)) {
-                       ds_dev_dbg(0, dev, "matched to %s\n", drv->name);
+                       dev_dbg(dev, "matched to %s\n", drv->name);
                        spin_unlock(&p_drv->dynids.lock);
                        return 1;
                }
@@ -1004,15 +886,15 @@ static int pcmcia_bus_match(struct device * dev, struct device_driver * drv) {
 #ifdef CONFIG_PCMCIA_IOCTL
        /* matching by cardmgr */
        if (p_dev->cardmgr == p_drv) {
-               ds_dev_dbg(0, dev, "cardmgr matched to %s\n", drv->name);
+               dev_dbg(dev, "cardmgr matched to %s\n", drv->name);
                return 1;
        }
 #endif
 
        while (did && did->match_flags) {
-               ds_dev_dbg(3, dev, "trying to match to %s\n", drv->name);
+               dev_dbg(dev, "trying to match to %s\n", drv->name);
                if (pcmcia_devmatch(p_dev, did)) {
-                       ds_dev_dbg(0, dev, "matched to %s\n", drv->name);
+                       dev_dbg(dev, "matched to %s\n", drv->name);
                        return 1;
                }
                did++;
@@ -1218,7 +1100,7 @@ static int pcmcia_dev_suspend(struct device * dev, pm_message_t state)
        if (p_dev->suspended)
                return 0;
 
-       ds_dev_dbg(2, dev, "suspending\n");
+       dev_dbg(dev, "suspending\n");
 
        if (dev->driver)
                p_drv = to_pcmcia_drv(dev->driver);
@@ -1238,7 +1120,7 @@ static int pcmcia_dev_suspend(struct device * dev, pm_message_t state)
        }
 
        if (p_dev->device_no == p_dev->func) {
-               ds_dev_dbg(2, dev, "releasing configuration\n");
+               dev_dbg(dev, "releasing configuration\n");
                pcmcia_release_configuration(p_dev);
        }
 
@@ -1258,7 +1140,7 @@ static int pcmcia_dev_resume(struct device * dev)
        if (!p_dev->suspended)
                return 0;
 
-       ds_dev_dbg(2, dev, "resuming\n");
+       dev_dbg(dev, "resuming\n");
 
        if (dev->driver)
                p_drv = to_pcmcia_drv(dev->driver);
@@ -1267,7 +1149,7 @@ static int pcmcia_dev_resume(struct device * dev)
                goto out;
 
        if (p_dev->device_no == p_dev->func) {
-               ds_dev_dbg(2, dev, "requesting configuration\n");
+               dev_dbg(dev, "requesting configuration\n");
                ret = pcmcia_request_configuration(p_dev, &p_dev->conf);
                if (ret)
                        goto out;
@@ -1309,14 +1191,14 @@ static int pcmcia_bus_resume_callback(struct device *dev, void * _data)
 
 static int pcmcia_bus_resume(struct pcmcia_socket *skt)
 {
-       ds_dev_dbg(2, &skt->dev, "resuming socket %d\n", skt->sock);
+       dev_dbg(&skt->dev, "resuming socket %d\n", skt->sock);
        bus_for_each_dev(&pcmcia_bus_type, NULL, skt, pcmcia_bus_resume_callback);
        return 0;
 }
 
 static int pcmcia_bus_suspend(struct pcmcia_socket *skt)
 {
-       ds_dev_dbg(2, &skt->dev, "suspending socket %d\n", skt->sock);
+       dev_dbg(&skt->dev, "suspending socket %d\n", skt->sock);
        if (bus_for_each_dev(&pcmcia_bus_type, NULL, skt,
                             pcmcia_bus_suspend_callback)) {
                pcmcia_bus_resume(skt);
@@ -1348,7 +1230,7 @@ static int ds_event(struct pcmcia_socket *skt, event_t event, int priority)
                return -ENODEV;
        }
 
-       ds_dev_dbg(1, &skt->dev, "ds_event(0x%06x, %d, 0x%p)\n",
+       dev_dbg(&skt->dev, "ds_event(0x%06x, %d, 0x%p)\n",
                   event, priority, skt);
 
        switch (event) {
index a4aacb830b80772d0f59a99a8bf029b4be6001f8..c13fd9360511b89fe3b52f37477bb86a6dab5f1a 100644 (file)
 #include "vg468.h"
 #include "ricoh.h"
 
-#ifdef CONFIG_PCMCIA_DEBUG
-static const char version[] =
-"i82365.c 1.265 1999/11/10 18:36:21 (David Hinds)";
-
-static int pc_debug;
-
-module_param(pc_debug, int, 0644);
-
-#define debug(lvl, fmt, arg...) do {                           \
-       if (pc_debug > (lvl))                                   \
-               printk(KERN_DEBUG "i82365: " fmt , ## arg);     \
-} while (0)
-#else
-#define debug(lvl, fmt, arg...) do { } while (0)
-#endif
 
 static irqreturn_t i365_count_irq(int, void *);
 static inline int _check_irq(int irq, int flags)
@@ -501,13 +486,13 @@ static irqreturn_t i365_count_irq(int irq, void *dev)
 {
     i365_get(irq_sock, I365_CSC);
     irq_hits++;
-    debug(2, "-> hit on irq %d\n", irq);
+    pr_debug("i82365: -> hit on irq %d\n", irq);
     return IRQ_HANDLED;
 }
 
 static u_int __init test_irq(u_short sock, int irq)
 {
-    debug(2, "  testing ISA irq %d\n", irq);
+    pr_debug("i82365:  testing ISA irq %d\n", irq);
     if (request_irq(irq, i365_count_irq, IRQF_PROBE_SHARED, "scan",
                        i365_count_irq) != 0)
        return 1;
@@ -515,7 +500,7 @@ static u_int __init test_irq(u_short sock, int irq)
     msleep(10);
     if (irq_hits) {
        free_irq(irq, i365_count_irq);
-       debug(2, "    spurious hit!\n");
+       pr_debug("i82365:    spurious hit!\n");
        return 1;
     }
 
@@ -528,7 +513,7 @@ static u_int __init test_irq(u_short sock, int irq)
 
     /* mask all interrupts */
     i365_set(sock, I365_CSCINT, 0);
-    debug(2, "    hits = %d\n", irq_hits);
+    pr_debug("i82365:    hits = %d\n", irq_hits);
     
     return (irq_hits != 1);
 }
@@ -854,7 +839,7 @@ static irqreturn_t pcic_interrupt(int irq, void *dev)
     u_long flags = 0;
     int handled = 0;
 
-    debug(4, "pcic_interrupt(%d)\n", irq);
+    pr_debug("pcic_interrupt(%d)\n", irq);
 
     for (j = 0; j < 20; j++) {
        active = 0;
@@ -878,7 +863,7 @@ static irqreturn_t pcic_interrupt(int irq, void *dev)
                events |= (csc & I365_CSC_READY) ? SS_READY : 0;
            }
            ISA_UNLOCK(i, flags);
-           debug(2, "socket %d event 0x%02x\n", i, events);
+           pr_debug("socket %d event 0x%02x\n", i, events);
 
            if (events)
                pcmcia_parse_events(&socket[i].socket, events);
@@ -890,7 +875,7 @@ static irqreturn_t pcic_interrupt(int irq, void *dev)
     if (j == 20)
        printk(KERN_NOTICE "i82365: infinite loop in interrupt handler\n");
 
-    debug(4, "interrupt done\n");
+    pr_debug("pcic_interrupt done\n");
     return IRQ_RETVAL(handled);
 } /* pcic_interrupt */
 
@@ -932,7 +917,7 @@ static int i365_get_status(u_short sock, u_int *value)
        }
     }
     
-    debug(1, "GetStatus(%d) = %#4.4x\n", sock, *value);
+    pr_debug("GetStatus(%d) = %#4.4x\n", sock, *value);
     return 0;
 } /* i365_get_status */
 
@@ -943,7 +928,7 @@ static int i365_set_socket(u_short sock, socket_state_t *state)
     struct i82365_socket *t = &socket[sock];
     u_char reg;
     
-    debug(1, "SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
+    pr_debug("SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
          "io_irq %d, csc_mask %#2.2x)\n", sock, state->flags,
          state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
     
@@ -1052,7 +1037,7 @@ static int i365_set_io_map(u_short sock, struct pccard_io_map *io)
 {
     u_char map, ioctl;
     
-    debug(1, "SetIOMap(%d, %d, %#2.2x, %d ns, "
+    pr_debug("SetIOMap(%d, %d, %#2.2x, %d ns, "
          "%#llx-%#llx)\n", sock, io->map, io->flags, io->speed,
          (unsigned long long)io->start, (unsigned long long)io->stop);
     map = io->map;
@@ -1082,7 +1067,7 @@ static int i365_set_mem_map(u_short sock, struct pccard_mem_map *mem)
     u_short base, i;
     u_char map;
     
-    debug(1, "SetMemMap(%d, %d, %#2.2x, %d ns, %#llx-%#llx, "
+    pr_debug("SetMemMap(%d, %d, %#2.2x, %d ns, %#llx-%#llx, "
          "%#x)\n", sock, mem->map, mem->flags, mem->speed,
          (unsigned long long)mem->res->start,
          (unsigned long long)mem->res->end, mem->card_start);
index 7dfbee1dcd769acbc9a3ec6308b3cbb72813ceb1..26a621c9e2fcb08c7608494f8494c31978552c04 100644 (file)
 
 #include "m32r_cfc.h"
 
-#ifdef CONFIG_PCMCIA_DEBUG
-static int m32r_cfc_debug;
-module_param(m32r_cfc_debug, int, 0644);
-#define debug(lvl, fmt, arg...) do {                           \
-       if (m32r_cfc_debug > (lvl))                             \
-               printk(KERN_DEBUG "m32r_cfc: " fmt , ## arg);   \
-} while (0)
-#else
-#define debug(n, args...) do { } while (0)
-#endif
-
 /* Poll status interval -- 0 means default to interrupt */
 static int poll_interval = 0;
 
@@ -123,7 +112,7 @@ void pcc_ioread_byte(int sock, unsigned long port, void *buf, size_t size,
        unsigned char *bp = (unsigned char *)buf;
        unsigned long flags;
 
-       debug(3, "m32r_cfc: pcc_ioread_byte: sock=%d, port=%#lx, buf=%p, "
+       pr_debug("m32r_cfc: pcc_ioread_byte: sock=%d, port=%#lx, buf=%p, "
                 "size=%u, nmemb=%d, flag=%d\n",
                  sock, port, buf, size, nmemb, flag);
 
@@ -132,7 +121,7 @@ void pcc_ioread_byte(int sock, unsigned long port, void *buf, size_t size,
                printk("m32r_cfc:ioread_byte null port :%#lx\n",port);
                return;
        }
-       debug(3, "m32r_cfc: pcc_ioread_byte: addr=%#lx\n", addr);
+       pr_debug("m32r_cfc: pcc_ioread_byte: addr=%#lx\n", addr);
 
        spin_lock_irqsave(&pcc_lock, flags);
        /* read Byte */
@@ -148,7 +137,7 @@ void pcc_ioread_word(int sock, unsigned long port, void *buf, size_t size,
        unsigned short *bp = (unsigned short *)buf;
        unsigned long flags;
 
-       debug(3, "m32r_cfc: pcc_ioread_word: sock=%d, port=%#lx, "
+       pr_debug("m32r_cfc: pcc_ioread_word: sock=%d, port=%#lx, "
                 "buf=%p, size=%u, nmemb=%d, flag=%d\n",
                 sock, port, buf, size, nmemb, flag);
 
@@ -163,7 +152,7 @@ void pcc_ioread_word(int sock, unsigned long port, void *buf, size_t size,
                printk("m32r_cfc:ioread_word null port :%#lx\n",port);
                return;
        }
-       debug(3, "m32r_cfc: pcc_ioread_word: addr=%#lx\n", addr);
+       pr_debug("m32r_cfc: pcc_ioread_word: addr=%#lx\n", addr);
 
        spin_lock_irqsave(&pcc_lock, flags);
        /* read Word */
@@ -179,7 +168,7 @@ void pcc_iowrite_byte(int sock, unsigned long port, void *buf, size_t size,
        unsigned char *bp = (unsigned char *)buf;
        unsigned long flags;
 
-       debug(3, "m32r_cfc: pcc_iowrite_byte: sock=%d, port=%#lx, "
+       pr_debug("m32r_cfc: pcc_iowrite_byte: sock=%d, port=%#lx, "
                 "buf=%p, size=%u, nmemb=%d, flag=%d\n",
                 sock, port, buf, size, nmemb, flag);
 
@@ -189,7 +178,7 @@ void pcc_iowrite_byte(int sock, unsigned long port, void *buf, size_t size,
                printk("m32r_cfc:iowrite_byte null port:%#lx\n",port);
                return;
        }
-       debug(3, "m32r_cfc: pcc_iowrite_byte: addr=%#lx\n", addr);
+       pr_debug("m32r_cfc: pcc_iowrite_byte: addr=%#lx\n", addr);
 
        spin_lock_irqsave(&pcc_lock, flags);
        while (nmemb--)
@@ -204,7 +193,7 @@ void pcc_iowrite_word(int sock, unsigned long port, void *buf, size_t size,
        unsigned short *bp = (unsigned short *)buf;
        unsigned long flags;
 
-       debug(3, "m32r_cfc: pcc_iowrite_word: sock=%d, port=%#lx, "
+       pr_debug("m32r_cfc: pcc_iowrite_word: sock=%d, port=%#lx, "
                 "buf=%p, size=%u, nmemb=%d, flag=%d\n",
                 sock, port, buf, size, nmemb, flag);
 
@@ -226,7 +215,7 @@ void pcc_iowrite_word(int sock, unsigned long port, void *buf, size_t size,
                return;
        }
 #endif
-       debug(3, "m32r_cfc: pcc_iowrite_word: addr=%#lx\n", addr);
+       pr_debug("m32r_cfc: pcc_iowrite_word: addr=%#lx\n", addr);
 
        spin_lock_irqsave(&pcc_lock, flags);
        while (nmemb--)
@@ -262,7 +251,7 @@ static struct timer_list poll_timer;
 static unsigned int pcc_get(u_short sock, unsigned int reg)
 {
        unsigned int val = inw(reg);
-       debug(3, "m32r_cfc: pcc_get: reg(0x%08x)=0x%04x\n", reg, val);
+       pr_debug("m32r_cfc: pcc_get: reg(0x%08x)=0x%04x\n", reg, val);
        return val;
 }
 
@@ -270,7 +259,7 @@ static unsigned int pcc_get(u_short sock, unsigned int reg)
 static void pcc_set(u_short sock, unsigned int reg, unsigned int data)
 {
        outw(data, reg);
-       debug(3, "m32r_cfc: pcc_set: reg(0x%08x)=0x%04x\n", reg, data);
+       pr_debug("m32r_cfc: pcc_set: reg(0x%08x)=0x%04x\n", reg, data);
 }
 
 /*======================================================================
@@ -286,14 +275,14 @@ static int __init is_alive(u_short sock)
 {
        unsigned int stat;
 
-       debug(3, "m32r_cfc: is_alive:\n");
+       pr_debug("m32r_cfc: is_alive:\n");
 
        printk("CF: ");
        stat = pcc_get(sock, (unsigned int)PLD_CFSTS);
        if (!stat)
                printk("No ");
        printk("Card is detected at socket %d : stat = 0x%08x\n", sock, stat);
-       debug(3, "m32r_cfc: is_alive: sock stat is 0x%04x\n", stat);
+       pr_debug("m32r_cfc: is_alive: sock stat is 0x%04x\n", stat);
 
        return 0;
 }
@@ -303,7 +292,7 @@ static void add_pcc_socket(ulong base, int irq, ulong mapaddr,
 {
        pcc_socket_t *t = &socket[pcc_sockets];
 
-       debug(3, "m32r_cfc: add_pcc_socket: base=%#lx, irq=%d, "
+       pr_debug("m32r_cfc: add_pcc_socket: base=%#lx, irq=%d, "
                 "mapaddr=%#lx, ioaddr=%08x\n",
                 base, irq, mapaddr, ioaddr);
 
@@ -358,7 +347,7 @@ static void add_pcc_socket(ulong base, int irq, ulong mapaddr,
        /* eject interrupt */
        request_irq(irq+1, pcc_interrupt, 0, "m32r_cfc", pcc_interrupt);
 #endif
-       debug(3, "m32r_cfc: enable CFMSK, RDYSEL\n");
+       pr_debug("m32r_cfc: enable CFMSK, RDYSEL\n");
        pcc_set(pcc_sockets, (unsigned int)PLD_CFIMASK, 0x01);
 #endif /* CONFIG_PLAT_USRV */
 #if defined(CONFIG_PLAT_M32700UT) || defined(CONFIG_PLAT_USRV) || defined(CONFIG_PLAT_OPSPUT)
@@ -378,26 +367,26 @@ static irqreturn_t pcc_interrupt(int irq, void *dev)
        u_int events = 0;
        int handled = 0;
 
-       debug(3, "m32r_cfc: pcc_interrupt: irq=%d, dev=%p\n", irq, dev);
+       pr_debug("m32r_cfc: pcc_interrupt: irq=%d, dev=%p\n", irq, dev);
        for (i = 0; i < pcc_sockets; i++) {
                if (socket[i].cs_irq1 != irq && socket[i].cs_irq2 != irq)
                        continue;
 
                handled = 1;
-               debug(3, "m32r_cfc: pcc_interrupt: socket %d irq 0x%02x ",
+               pr_debug("m32r_cfc: pcc_interrupt: socket %d irq 0x%02x ",
                        i, irq);
                events |= SS_DETECT;    /* insert or eject */
                if (events)
                        pcmcia_parse_events(&socket[i].socket, events);
        }
-       debug(3, "m32r_cfc: pcc_interrupt: done\n");
+       pr_debug("m32r_cfc: pcc_interrupt: done\n");
 
        return IRQ_RETVAL(handled);
 } /* pcc_interrupt */
 
 static void pcc_interrupt_wrapper(u_long data)
 {
-       debug(3, "m32r_cfc: pcc_interrupt_wrapper:\n");
+       pr_debug("m32r_cfc: pcc_interrupt_wrapper:\n");
        pcc_interrupt(0, NULL);
        init_timer(&poll_timer);
        poll_timer.expires = jiffies + poll_interval;
@@ -410,17 +399,17 @@ static int _pcc_get_status(u_short sock, u_int *value)
 {
        u_int status;
 
-       debug(3, "m32r_cfc: _pcc_get_status:\n");
+       pr_debug("m32r_cfc: _pcc_get_status:\n");
        status = pcc_get(sock, (unsigned int)PLD_CFSTS);
        *value = (status) ? SS_DETECT : 0;
-       debug(3, "m32r_cfc: _pcc_get_status: status=0x%08x\n", status);
+       pr_debug("m32r_cfc: _pcc_get_status: status=0x%08x\n", status);
 
 #if defined(CONFIG_PLAT_M32700UT) || defined(CONFIG_PLAT_USRV) || defined(CONFIG_PLAT_OPSPUT)
        if ( status ) {
                /* enable CF power */
                status = inw((unsigned int)PLD_CPCR);
                if (!(status & PLD_CPCR_CF)) {
-                       debug(3, "m32r_cfc: _pcc_get_status: "
+                       pr_debug("m32r_cfc: _pcc_get_status: "
                                 "power on (CPCR=0x%08x)\n", status);
                        status |= PLD_CPCR_CF;
                        outw(status, (unsigned int)PLD_CPCR);
@@ -439,7 +428,7 @@ static int _pcc_get_status(u_short sock, u_int *value)
                status &= ~PLD_CPCR_CF;
                outw(status, (unsigned int)PLD_CPCR);
                udelay(100);
-               debug(3, "m32r_cfc: _pcc_get_status: "
+               pr_debug("m32r_cfc: _pcc_get_status: "
                         "power off (CPCR=0x%08x)\n", status);
        }
 #elif defined(CONFIG_PLAT_MAPPI2) || defined(CONFIG_PLAT_MAPPI3)
@@ -465,13 +454,13 @@ static int _pcc_get_status(u_short sock, u_int *value)
                /* disable CF power */
                pcc_set(sock, (unsigned int)PLD_CPCR, 0);
                udelay(100);
-               debug(3, "m32r_cfc: _pcc_get_status: "
+               pr_debug("m32r_cfc: _pcc_get_status: "
                         "power off (CPCR=0x%08x)\n", status);
        }
 #else
 #error no platform configuration
 #endif
-       debug(3, "m32r_cfc: _pcc_get_status: GetStatus(%d) = %#4.4x\n",
+       pr_debug("m32r_cfc: _pcc_get_status: GetStatus(%d) = %#4.4x\n",
                 sock, *value);
        return 0;
 } /* _get_status */
@@ -480,7 +469,7 @@ static int _pcc_get_status(u_short sock, u_int *value)
 
 static int _pcc_set_socket(u_short sock, socket_state_t *state)
 {
-       debug(3, "m32r_cfc: SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
+       pr_debug("m32r_cfc: SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
                  "io_irq %d, csc_mask %#2.2x)\n", sock, state->flags,
                  state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
 
@@ -492,41 +481,39 @@ static int _pcc_set_socket(u_short sock, socket_state_t *state)
        }
 #endif
        if (state->flags & SS_RESET) {
-               debug(3, ":RESET\n");
+               pr_debug(":RESET\n");
                pcc_set(sock,(unsigned int)PLD_CFRSTCR,0x101);
        }else{
                pcc_set(sock,(unsigned int)PLD_CFRSTCR,0x100);
        }
        if (state->flags & SS_OUTPUT_ENA){
-               debug(3, ":OUTPUT_ENA\n");
+               pr_debug(":OUTPUT_ENA\n");
                /* bit clear */
                pcc_set(sock,(unsigned int)PLD_CFBUFCR,0);
        } else {
                pcc_set(sock,(unsigned int)PLD_CFBUFCR,1);
        }
 
-#ifdef CONFIG_PCMCIA_DEBUG
        if(state->flags & SS_IOCARD){
-               debug(3, ":IOCARD");
+               pr_debug(":IOCARD");
        }
        if (state->flags & SS_PWR_AUTO) {
-               debug(3, ":PWR_AUTO");
+               pr_debug(":PWR_AUTO");
        }
        if (state->csc_mask & SS_DETECT)
-               debug(3, ":csc-SS_DETECT");
+               pr_debug(":csc-SS_DETECT");
        if (state->flags & SS_IOCARD) {
                if (state->csc_mask & SS_STSCHG)
-                       debug(3, ":STSCHG");
+                       pr_debug(":STSCHG");
        } else {
                if (state->csc_mask & SS_BATDEAD)
-                       debug(3, ":BATDEAD");
+                       pr_debug(":BATDEAD");
                if (state->csc_mask & SS_BATWARN)
-                       debug(3, ":BATWARN");
+                       pr_debug(":BATWARN");
                if (state->csc_mask & SS_READY)
-                       debug(3, ":READY");
+                       pr_debug(":READY");
        }
-       debug(3, "\n");
-#endif
+       pr_debug("\n");
        return 0;
 } /* _set_socket */
 
@@ -536,7 +523,7 @@ static int _pcc_set_io_map(u_short sock, struct pccard_io_map *io)
 {
        u_char map;
 
-       debug(3, "m32r_cfc: SetIOMap(%d, %d, %#2.2x, %d ns, "
+       pr_debug("m32r_cfc: SetIOMap(%d, %d, %#2.2x, %d ns, "
                  "%#llx-%#llx)\n", sock, io->map, io->flags,
                  io->speed, (unsigned long long)io->start,
                  (unsigned long long)io->stop);
@@ -554,7 +541,7 @@ static int _pcc_set_mem_map(u_short sock, struct pccard_mem_map *mem)
        u_long addr;
        pcc_socket_t *t = &socket[sock];
 
-       debug(3, "m32r_cfc: SetMemMap(%d, %d, %#2.2x, %d ns, "
+       pr_debug("m32r_cfc: SetMemMap(%d, %d, %#2.2x, %d ns, "
                 "%#llx, %#x)\n", sock, map, mem->flags,
                 mem->speed, (unsigned long long)mem->static_start,
                 mem->card_start);
@@ -640,11 +627,11 @@ static int pcc_get_status(struct pcmcia_socket *s, u_int *value)
        unsigned int sock = container_of(s, struct pcc_socket, socket)->number;
 
        if (socket[sock].flags & IS_ALIVE) {
-               debug(3, "m32r_cfc: pcc_get_status: sock(%d) -EINVAL\n", sock);
+               dev_dbg(&s->dev, "pcc_get_status: sock(%d) -EINVAL\n", sock);
                *value = 0;
                return -EINVAL;
        }
-       debug(3, "m32r_cfc: pcc_get_status: sock(%d)\n", sock);
+       dev_dbg(&s->dev, "pcc_get_status: sock(%d)\n", sock);
        LOCKED(_pcc_get_status(sock, value));
 }
 
@@ -653,10 +640,10 @@ static int pcc_set_socket(struct pcmcia_socket *s, socket_state_t *state)
        unsigned int sock = container_of(s, struct pcc_socket, socket)->number;
 
        if (socket[sock].flags & IS_ALIVE) {
-               debug(3, "m32r_cfc: pcc_set_socket: sock(%d) -EINVAL\n", sock);
+               dev_dbg(&s->dev, "pcc_set_socket: sock(%d) -EINVAL\n", sock);
                return -EINVAL;
        }
-       debug(3, "m32r_cfc: pcc_set_socket: sock(%d)\n", sock);
+       dev_dbg(&s->dev, "pcc_set_socket: sock(%d)\n", sock);
        LOCKED(_pcc_set_socket(sock, state));
 }
 
@@ -665,10 +652,10 @@ static int pcc_set_io_map(struct pcmcia_socket *s, struct pccard_io_map *io)
        unsigned int sock = container_of(s, struct pcc_socket, socket)->number;
 
        if (socket[sock].flags & IS_ALIVE) {
-               debug(3, "m32r_cfc: pcc_set_io_map: sock(%d) -EINVAL\n", sock);
+               dev_dbg(&s->dev, "pcc_set_io_map: sock(%d) -EINVAL\n", sock);
                return -EINVAL;
        }
-       debug(3, "m32r_cfc: pcc_set_io_map: sock(%d)\n", sock);
+       dev_dbg(&s->dev, "pcc_set_io_map: sock(%d)\n", sock);
        LOCKED(_pcc_set_io_map(sock, io));
 }
 
@@ -677,16 +664,16 @@ static int pcc_set_mem_map(struct pcmcia_socket *s, struct pccard_mem_map *mem)
        unsigned int sock = container_of(s, struct pcc_socket, socket)->number;
 
        if (socket[sock].flags & IS_ALIVE) {
-               debug(3, "m32r_cfc: pcc_set_mem_map: sock(%d) -EINVAL\n", sock);
+               dev_dbg(&s->dev, "pcc_set_mem_map: sock(%d) -EINVAL\n", sock);
                return -EINVAL;
        }
-       debug(3, "m32r_cfc: pcc_set_mem_map: sock(%d)\n", sock);
+       dev_dbg(&s->dev, "pcc_set_mem_map: sock(%d)\n", sock);
        LOCKED(_pcc_set_mem_map(sock, mem));
 }
 
 static int pcc_init(struct pcmcia_socket *s)
 {
-       debug(3, "m32r_cfc: pcc_init()\n");
+       dev_dbg(&s->dev, "pcc_init()\n");
        return 0;
 }
 
index c6524f99ccc390b14f10c1e21d6f7ddd80cdb6a8..72844c5a6d05fb53999ded835e5bf56f22ba6a21 100644 (file)
 
 #define PCC_DEBUG_DBEX
 
-#ifdef CONFIG_PCMCIA_DEBUG
-static int m32r_pcc_debug;
-module_param(m32r_pcc_debug, int, 0644);
-#define debug(lvl, fmt, arg...) do {                           \
-       if (m32r_pcc_debug > (lvl))                             \
-               printk(KERN_DEBUG "m32r_pcc: " fmt , ## arg);   \
-} while (0)
-#else
-#define debug(n, args...) do { } while (0)
-#endif
 
 /* Poll status interval -- 0 means default to interrupt */
 static int poll_interval = 0;
@@ -358,7 +348,7 @@ static irqreturn_t pcc_interrupt(int irq, void *dev)
        u_int events, active;
        int handled = 0;
 
-       debug(4, "m32r: pcc_interrupt(%d)\n", irq);
+       pr_debug("m32r_pcc: pcc_interrupt(%d)\n", irq);
 
        for (j = 0; j < 20; j++) {
                active = 0;
@@ -369,13 +359,14 @@ static irqreturn_t pcc_interrupt(int irq, void *dev)
                        handled = 1;
                        irc = pcc_get(i, PCIRC);
                        irc >>=16;
-                       debug(2, "m32r-pcc:interrupt: socket %d pcirc 0x%02x ", i, irc);
+                       pr_debug("m32r_pcc: interrupt: socket %d pcirc 0x%02x ",
+                               i, irc);
                        if (!irc)
                                continue;
 
                        events = (irc) ? SS_DETECT : 0;
                        events |= (pcc_get(i,PCCR) & PCCR_PCEN) ? SS_READY : 0;
-                       debug(2, " event 0x%02x\n", events);
+                       pr_debug("m32r_pcc: event 0x%02x\n", events);
 
                        if (events)
                                pcmcia_parse_events(&socket[i].socket, events);
@@ -388,7 +379,7 @@ static irqreturn_t pcc_interrupt(int irq, void *dev)
        if (j == 20)
                printk(KERN_NOTICE "m32r-pcc: infinite loop in interrupt handler\n");
 
-       debug(4, "m32r-pcc: interrupt done\n");
+       pr_debug("m32r_pcc: interrupt done\n");
 
        return IRQ_RETVAL(handled);
 } /* pcc_interrupt */
@@ -422,7 +413,7 @@ static int _pcc_get_status(u_short sock, u_int *value)
        status = pcc_get(sock,PCCSIGCR);
        *value |= (status & PCCSIGCR_VEN) ? SS_POWERON : 0;
 
-       debug(3, "m32r-pcc: GetStatus(%d) = %#4.4x\n", sock, *value);
+       pr_debug("m32r_pcc: GetStatus(%d) = %#4.4x\n", sock, *value);
        return 0;
 } /* _get_status */
 
@@ -432,7 +423,7 @@ static int _pcc_set_socket(u_short sock, socket_state_t *state)
 {
        u_long reg = 0;
 
-       debug(3, "m32r-pcc: SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
+       pr_debug("m32r_pcc: SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
                  "io_irq %d, csc_mask %#2.2x)", sock, state->flags,
                  state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
 
@@ -448,11 +439,11 @@ static int _pcc_set_socket(u_short sock, socket_state_t *state)
        }
 
        if (state->flags & SS_RESET) {
-               debug(3, ":RESET\n");
+               pr_debug("m32r_pcc: :RESET\n");
                reg |= PCCSIGCR_CRST;
        }
        if (state->flags & SS_OUTPUT_ENA){
-               debug(3, ":OUTPUT_ENA\n");
+               pr_debug("m32r_pcc: :OUTPUT_ENA\n");
                /* bit clear */
        } else {
                reg |= PCCSIGCR_SEN;
@@ -460,28 +451,26 @@ static int _pcc_set_socket(u_short sock, socket_state_t *state)
 
        pcc_set(sock,PCCSIGCR,reg);
 
-#ifdef CONFIG_PCMCIA_DEBUG
        if(state->flags & SS_IOCARD){
-               debug(3, ":IOCARD");
+               pr_debug("m32r_pcc: :IOCARD");
        }
        if (state->flags & SS_PWR_AUTO) {
-               debug(3, ":PWR_AUTO");
+               pr_debug("m32r_pcc: :PWR_AUTO");
        }
        if (state->csc_mask & SS_DETECT)
-               debug(3, ":csc-SS_DETECT");
+               pr_debug("m32r_pcc: :csc-SS_DETECT");
        if (state->flags & SS_IOCARD) {
                if (state->csc_mask & SS_STSCHG)
-                       debug(3, ":STSCHG");
+                       pr_debug("m32r_pcc: :STSCHG");
        } else {
                if (state->csc_mask & SS_BATDEAD)
-                       debug(3, ":BATDEAD");
+                       pr_debug("m32r_pcc: :BATDEAD");
                if (state->csc_mask & SS_BATWARN)
-                       debug(3, ":BATWARN");
+                       pr_debug("m32r_pcc: :BATWARN");
                if (state->csc_mask & SS_READY)
-                       debug(3, ":READY");
+                       pr_debug("m32r_pcc: :READY");
        }
-       debug(3, "\n");
-#endif
+       pr_debug("m32r_pcc: \n");
        return 0;
 } /* _set_socket */
 
@@ -491,7 +480,7 @@ static int _pcc_set_io_map(u_short sock, struct pccard_io_map *io)
 {
        u_char map;
 
-       debug(3, "m32r-pcc: SetIOMap(%d, %d, %#2.2x, %d ns, "
+       pr_debug("m32r_pcc: SetIOMap(%d, %d, %#2.2x, %d ns, "
                  "%#llx-%#llx)\n", sock, io->map, io->flags,
                  io->speed, (unsigned long long)io->start,
                  (unsigned long long)io->stop);
@@ -515,7 +504,7 @@ static int _pcc_set_mem_map(u_short sock, struct pccard_mem_map *mem)
 #endif
 #endif
 
-       debug(3, "m32r-pcc: SetMemMap(%d, %d, %#2.2x, %d ns, "
+       pr_debug("m32r_pcc: SetMemMap(%d, %d, %#2.2x, %d ns, "
                 "%#llx,  %#x)\n", sock, map, mem->flags,
                 mem->speed, (unsigned long long)mem->static_start,
                 mem->card_start);
@@ -662,7 +651,7 @@ static int pcc_set_mem_map(struct pcmcia_socket *s, struct pccard_mem_map *mem)
 
 static int pcc_init(struct pcmcia_socket *s)
 {
-       debug(4, "m32r-pcc: init call\n");
+       pr_debug("m32r_pcc: init call\n");
        return 0;
 }
 
index 403559ba49dd74954a2ea50516c6e82d4b973a61..7f79c4e169ae982175b48899333f686b32397365 100644 (file)
 #include <pcmcia/cs.h>
 #include <pcmcia/ss.h>
 
-#ifdef CONFIG_PCMCIA_DEBUG
-static int pc_debug;
-module_param(pc_debug, int, 0);
-#define dprintk(args...) printk(KERN_DEBUG "m8xx_pcmcia: " args);
-#else
-#define dprintk(args...)
-#endif
-
 #define pcmcia_info(args...) printk(KERN_INFO "m8xx_pcmcia: "args)
 #define pcmcia_error(args...) printk(KERN_ERR "m8xx_pcmcia: "args)
 
@@ -565,7 +557,7 @@ static irqreturn_t m8xx_interrupt(int irq, void *dev)
        unsigned int i, events, pscr, pipr, per;
        pcmconf8xx_t *pcmcia = socket[0].pcmcia;
 
-       dprintk("Interrupt!\n");
+       pr_debug("m8xx_pcmcia: Interrupt!\n");
        /* get interrupt sources */
 
        pscr = in_be32(&pcmcia->pcmc_pscr);
@@ -614,7 +606,7 @@ static irqreturn_t m8xx_interrupt(int irq, void *dev)
 
                /* call the handler */
 
-               dprintk("slot %u: events = 0x%02x, pscr = 0x%08x, "
+               pr_debug("m8xx_pcmcia: slot %u: events = 0x%02x, pscr = 0x%08x, "
                        "pipr = 0x%08x\n", i, events, pscr, pipr);
 
                if (events) {
@@ -641,7 +633,7 @@ static irqreturn_t m8xx_interrupt(int irq, void *dev)
        /* clear the interrupt sources */
        out_be32(&pcmcia->pcmc_pscr, pscr);
 
-       dprintk("Interrupt done.\n");
+       pr_debug("m8xx_pcmcia: Interrupt done.\n");
 
        return IRQ_HANDLED;
 }
@@ -815,7 +807,7 @@ static int m8xx_get_status(struct pcmcia_socket *sock, unsigned int *value)
                };
        }
 
-       dprintk("GetStatus(%d) = %#2.2x\n", lsock, *value);
+       pr_debug("m8xx_pcmcia: GetStatus(%d) = %#2.2x\n", lsock, *value);
        return 0;
 }
 
@@ -828,7 +820,7 @@ static int m8xx_set_socket(struct pcmcia_socket *sock, socket_state_t * state)
        unsigned long flags;
        pcmconf8xx_t *pcmcia = socket[0].pcmcia;
 
-       dprintk("SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
+       pr_debug("m8xx_pcmcia: SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
                "io_irq %d, csc_mask %#2.2x)\n", lsock, state->flags,
                state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
 
@@ -974,7 +966,7 @@ static int m8xx_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *io)
 #define M8XX_SIZE (io->stop - io->start + 1)
 #define M8XX_BASE (PCMCIA_IO_WIN_BASE + io->start)
 
-       dprintk("SetIOMap(%d, %d, %#2.2x, %d ns, "
+       pr_debug("m8xx_pcmcia: SetIOMap(%d, %d, %#2.2x, %d ns, "
                "%#4.4llx-%#4.4llx)\n", lsock, io->map, io->flags,
                io->speed, (unsigned long long)io->start,
                (unsigned long long)io->stop);
@@ -988,7 +980,7 @@ static int m8xx_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *io)
 
        if (io->flags & MAP_ACTIVE) {
 
-               dprintk("io->flags & MAP_ACTIVE\n");
+               pr_debug("m8xx_pcmcia: io->flags & MAP_ACTIVE\n");
 
                winnr = (PCMCIA_MEM_WIN_NO * PCMCIA_SOCKETS_NO)
                    + (lsock * PCMCIA_IO_WIN_NO) + io->map;
@@ -1018,8 +1010,8 @@ static int m8xx_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *io)
 
                out_be32(&w->or, reg);
 
-               dprintk("Socket %u: Mapped io window %u at %#8.8x, "
-                       "OR = %#8.8x.\n", lsock, io->map, w->br, w->or);
+               pr_debug("m8xx_pcmcia: Socket %u: Mapped io window %u at "
+                       "%#8.8x, OR = %#8.8x.\n", lsock, io->map, w->br, w->or);
        } else {
                /* shutdown IO window */
                winnr = (PCMCIA_MEM_WIN_NO * PCMCIA_SOCKETS_NO)
@@ -1033,14 +1025,14 @@ static int m8xx_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *io)
                out_be32(&w->or, 0);    /* turn off window */
                out_be32(&w->br, 0);    /* turn off base address */
 
-               dprintk("Socket %u: Unmapped io window %u at %#8.8x, "
-                       "OR = %#8.8x.\n", lsock, io->map, w->br, w->or);
+               pr_debug("m8xx_pcmcia: Socket %u: Unmapped io window %u at "
+                       "%#8.8x, OR = %#8.8x.\n", lsock, io->map, w->br, w->or);
        }
 
        /* copy the struct and modify the copy */
        s->io_win[io->map] = *io;
        s->io_win[io->map].flags &= (MAP_WRPROT | MAP_16BIT | MAP_ACTIVE);
-       dprintk("SetIOMap exit\n");
+       pr_debug("m8xx_pcmcia: SetIOMap exit\n");
 
        return 0;
 }
@@ -1055,7 +1047,7 @@ static int m8xx_set_mem_map(struct pcmcia_socket *sock,
        unsigned int reg, winnr;
        pcmconf8xx_t *pcmcia = s->pcmcia;
 
-       dprintk("SetMemMap(%d, %d, %#2.2x, %d ns, "
+       pr_debug("m8xx_pcmcia: SetMemMap(%d, %d, %#2.2x, %d ns, "
                "%#5.5llx, %#5.5x)\n", lsock, mem->map, mem->flags,
                mem->speed, (unsigned long long)mem->static_start,
                mem->card_start);
@@ -1098,7 +1090,7 @@ static int m8xx_set_mem_map(struct pcmcia_socket *sock,
 
        out_be32(&w->or, reg);
 
-       dprintk("Socket %u: Mapped memory window %u at %#8.8x, "
+       pr_debug("m8xx_pcmcia: Socket %u: Mapped memory window %u at %#8.8x, "
                "OR = %#8.8x.\n", lsock, mem->map, w->br, w->or);
 
        if (mem->flags & MAP_ACTIVE) {
@@ -1108,7 +1100,7 @@ static int m8xx_set_mem_map(struct pcmcia_socket *sock,
                    + mem->card_start;
        }
 
-       dprintk("SetMemMap(%d, %d, %#2.2x, %d ns, "
+       pr_debug("m8xx_pcmcia: SetMemMap(%d, %d, %#2.2x, %d ns, "
                "%#5.5llx, %#5.5x)\n", lsock, mem->map, mem->flags,
                mem->speed, (unsigned long long)mem->static_start,
                mem->card_start);
@@ -1129,7 +1121,7 @@ static int m8xx_sock_init(struct pcmcia_socket *sock)
        pccard_io_map io = { 0, 0, 0, 0, 1 };
        pccard_mem_map mem = { 0, 0, 0, 0, 0, 0 };
 
-       dprintk("sock_init(%d)\n", s);
+       pr_debug("m8xx_pcmcia: sock_init(%d)\n", s);
 
        m8xx_set_socket(sock, &dead_socket);
        for (i = 0; i < PCMCIA_IO_WIN_NO; i++) {
index 72188c462c9cc6222b82ff8e79c87e35b3731201..624442fc0d35ceb7d609be947fb2c7dda2e20d5d 100644 (file)
 #ifndef _LINUX_O2MICRO_H
 #define _LINUX_O2MICRO_H
 
-#ifndef PCI_VENDOR_ID_O2
-#define PCI_VENDOR_ID_O2               0x1217
-#endif
-#ifndef PCI_DEVICE_ID_O2_6729
-#define PCI_DEVICE_ID_O2_6729          0x6729
-#endif
-#ifndef PCI_DEVICE_ID_O2_6730
-#define PCI_DEVICE_ID_O2_6730          0x673a
-#endif
-#ifndef PCI_DEVICE_ID_O2_6832
-#define PCI_DEVICE_ID_O2_6832          0x6832
-#endif
-#ifndef PCI_DEVICE_ID_O2_6836
-#define PCI_DEVICE_ID_O2_6836          0x6836
-#endif
-#ifndef PCI_DEVICE_ID_O2_6812
-#define PCI_DEVICE_ID_O2_6812          0x6872
-#endif
-#ifndef PCI_DEVICE_ID_O2_6933
-#define PCI_DEVICE_ID_O2_6933           0x6933
-#endif
-
 /* Additional PCI configuration registers */
 
 #define O2_MUX_CONTROL         0x90    /* 32 bit */
index 30cf71d2ee235ce57cbef4d32600f63dd7b8f324..c4d7908fa37f1974f413627cd3b274512ec872ae 100644 (file)
@@ -58,17 +58,6 @@ typedef struct user_info_t {
 } user_info_t;
 
 
-#ifdef CONFIG_PCMCIA_DEBUG
-extern int ds_pc_debug;
-
-#define ds_dbg(lvl, fmt, arg...) do {          \
-       if (ds_pc_debug >= lvl)                         \
-               printk(KERN_DEBUG "ds: " fmt , ## arg);         \
-} while (0)
-#else
-#define ds_dbg(lvl, fmt, arg...) do { } while (0)
-#endif
-
 static struct pcmcia_device *get_pcmcia_device(struct pcmcia_socket *s,
                                                unsigned int function)
 {
@@ -229,6 +218,61 @@ static int pcmcia_adjust_resource_info(adjust_t *adj)
        return (ret);
 }
 
+
+/** pcmcia_get_window
+ */
+static int pcmcia_get_window(struct pcmcia_socket *s, window_handle_t *wh_out,
+                       window_handle_t wh, win_req_t *req)
+{
+       pccard_mem_map *win;
+       window_handle_t w;
+
+       wh--;
+       if (!s || !(s->state & SOCKET_PRESENT))
+               return -ENODEV;
+       if (wh >= MAX_WIN)
+               return -EINVAL;
+       for (w = wh; w < MAX_WIN; w++)
+               if (s->state & SOCKET_WIN_REQ(w))
+                       break;
+       if (w == MAX_WIN)
+               return -EINVAL;
+       win = &s->win[w];
+       req->Base = win->res->start;
+       req->Size = win->res->end - win->res->start + 1;
+       req->AccessSpeed = win->speed;
+       req->Attributes = 0;
+       if (win->flags & MAP_ATTRIB)
+               req->Attributes |= WIN_MEMORY_TYPE_AM;
+       if (win->flags & MAP_ACTIVE)
+               req->Attributes |= WIN_ENABLE;
+       if (win->flags & MAP_16BIT)
+               req->Attributes |= WIN_DATA_WIDTH_16;
+       if (win->flags & MAP_USE_WAIT)
+               req->Attributes |= WIN_USE_WAIT;
+
+       *wh_out = w + 1;
+       return 0;
+} /* pcmcia_get_window */
+
+
+/** pcmcia_get_mem_page
+ *
+ * Change the card address of an already open memory window.
+ */
+static int pcmcia_get_mem_page(struct pcmcia_socket *skt, window_handle_t wh,
+                       memreq_t *req)
+{
+       wh--;
+       if (wh >= MAX_WIN)
+               return -EINVAL;
+
+       req->Page = 0;
+       req->CardOffset = skt->win[wh].card_start;
+       return 0;
+} /* pcmcia_get_mem_page */
+
+
 /** pccard_get_status
  *
  * Get the current socket state bits.  We don't support the latched
@@ -431,7 +475,7 @@ static int bind_request(struct pcmcia_socket *s, bind_info_t *bind_info)
        if (!s)
                return -EINVAL;
 
-       ds_dbg(2, "bind_request(%d, '%s')\n", s->sock,
+       pr_debug("bind_request(%d, '%s')\n", s->sock,
               (char *)bind_info->dev_info);
 
        p_drv = get_pcmcia_driver(&bind_info->dev_info);
@@ -623,7 +667,7 @@ static int ds_open(struct inode *inode, struct file *file)
     static int warning_printed = 0;
     int ret = 0;
 
-    ds_dbg(0, "ds_open(socket %d)\n", i);
+    pr_debug("ds_open(socket %d)\n", i);
 
     lock_kernel();
     s = pcmcia_get_socket_by_nr(i);
@@ -685,7 +729,7 @@ static int ds_release(struct inode *inode, struct file *file)
     struct pcmcia_socket *s;
     user_info_t *user, **link;
 
-    ds_dbg(0, "ds_release(socket %d)\n", iminor(inode));
+    pr_debug("ds_release(socket %d)\n", iminor(inode));
 
     user = file->private_data;
     if (CHECK_USER(user))
@@ -719,7 +763,7 @@ static ssize_t ds_read(struct file *file, char __user *buf,
     user_info_t *user;
     int ret;
 
-    ds_dbg(2, "ds_read(socket %d)\n", iminor(file->f_path.dentry->d_inode));
+    pr_debug("ds_read(socket %d)\n", iminor(file->f_path.dentry->d_inode));
 
     if (count < 4)
        return -EINVAL;
@@ -744,7 +788,7 @@ static ssize_t ds_read(struct file *file, char __user *buf,
 static ssize_t ds_write(struct file *file, const char __user *buf,
                        size_t count, loff_t *ppos)
 {
-    ds_dbg(2, "ds_write(socket %d)\n", iminor(file->f_path.dentry->d_inode));
+    pr_debug("ds_write(socket %d)\n", iminor(file->f_path.dentry->d_inode));
 
     if (count != 4)
        return -EINVAL;
@@ -762,7 +806,7 @@ static u_int ds_poll(struct file *file, poll_table *wait)
     struct pcmcia_socket *s;
     user_info_t *user;
 
-    ds_dbg(2, "ds_poll(socket %d)\n", iminor(file->f_path.dentry->d_inode));
+    pr_debug("ds_poll(socket %d)\n", iminor(file->f_path.dentry->d_inode));
 
     user = file->private_data;
     if (CHECK_USER(user))
@@ -790,7 +834,7 @@ static int ds_ioctl(struct inode * inode, struct file * file,
     ds_ioctl_arg_t *buf;
     user_info_t *user;
 
-    ds_dbg(2, "ds_ioctl(socket %d, %#x, %#lx)\n", iminor(inode), cmd, arg);
+    pr_debug("ds_ioctl(socket %d, %#x, %#lx)\n", iminor(inode), cmd, arg);
 
     user = file->private_data;
     if (CHECK_USER(user))
@@ -809,13 +853,13 @@ static int ds_ioctl(struct inode * inode, struct file * file,
 
     if (cmd & IOC_IN) {
        if (!access_ok(VERIFY_READ, uarg, size)) {
-           ds_dbg(3, "ds_ioctl(): verify_read = %d\n", -EFAULT);
+           pr_debug("ds_ioctl(): verify_read = %d\n", -EFAULT);
            return -EFAULT;
        }
     }
     if (cmd & IOC_OUT) {
        if (!access_ok(VERIFY_WRITE, uarg, size)) {
-           ds_dbg(3, "ds_ioctl(): verify_write = %d\n", -EFAULT);
+           pr_debug("ds_ioctl(): verify_write = %d\n", -EFAULT);
            return -EFAULT;
        }
     }
@@ -927,15 +971,15 @@ static int ds_ioctl(struct inode * inode, struct file * file,
        goto free_out;
        break;
     case DS_GET_FIRST_WINDOW:
-       ret = pcmcia_get_window(s, &buf->win_info.handle, 0,
+       ret = pcmcia_get_window(s, &buf->win_info.handle, 1,
                        &buf->win_info.window);
        break;
     case DS_GET_NEXT_WINDOW:
        ret = pcmcia_get_window(s, &buf->win_info.handle,
-                       buf->win_info.handle->index + 1, &buf->win_info.window);
+                       buf->win_info.handle + 1, &buf->win_info.window);
        break;
     case DS_GET_MEM_PAGE:
-       ret = pcmcia_get_mem_page(buf->win_info.handle,
+       ret = pcmcia_get_mem_page(s, buf->win_info.handle,
                           &buf->win_info.map);
        break;
     case DS_REPLACE_CIS:
@@ -962,7 +1006,7 @@ static int ds_ioctl(struct inode * inode, struct file * file,
     }
 
     if ((err == 0) && (ret != 0)) {
-       ds_dbg(2, "ds_ioctl: ret = %d\n", ret);
+       pr_debug("ds_ioctl: ret = %d\n", ret);
        switch (ret) {
        case -ENODEV:
        case -EINVAL:
index d919e96c0afd62f5bde18da2ca0a974b63b66079..a8bf8c1b45ede688ab3613eeaf570356d0baa795 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/delay.h>
 #include <linux/pci.h>
 #include <linux/device.h>
+#include <linux/netdevice.h>
 
 #include <pcmcia/cs_types.h>
 #include <pcmcia/ss.h>
@@ -43,21 +44,6 @@ static u8 pcmcia_used_irq[NR_IRQS];
 #endif
 
 
-#ifdef CONFIG_PCMCIA_DEBUG
-extern int ds_pc_debug;
-
-#define ds_dbg(skt, lvl, fmt, arg...) do {                     \
-       if (ds_pc_debug >= lvl)                                 \
-               dev_printk(KERN_DEBUG, &skt->dev,               \
-                          "pcmcia_resource: " fmt,             \
-                          ## arg);                             \
-} while (0)
-#else
-#define ds_dbg(skt, lvl, fmt, arg...) do { } while (0)
-#endif
-
-
-
 /** alloc_io_space
  *
  * Special stuff for managing IO windows, because they are scarce
@@ -72,14 +58,14 @@ static int alloc_io_space(struct pcmcia_socket *s, u_int attr,
        align = (*base) ? (lines ? 1<<lines : 0) : 1;
        if (align && (align < num)) {
                if (*base) {
-                       ds_dbg(s, 0, "odd IO request: num %#x align %#x\n",
+                       dev_dbg(&s->dev, "odd IO request: num %#x align %#x\n",
                               num, align);
                        align = 0;
                } else
                        while (align && (align < num)) align <<= 1;
        }
        if (*base & ~(align-1)) {
-               ds_dbg(s, 0, "odd IO request: base %#x align %#x\n",
+               dev_dbg(&s->dev, "odd IO request: base %#x align %#x\n",
                       *base, align);
                align = 0;
        }
@@ -173,8 +159,10 @@ int pcmcia_access_configuration_register(struct pcmcia_device *p_dev,
        s = p_dev->socket;
        c = p_dev->function_config;
 
-       if (!(c->state & CONFIG_LOCKED))
+       if (!(c->state & CONFIG_LOCKED)) {
+               dev_dbg(&s->dev, "Configuration isnt't locked\n");
                return -EACCES;
+       }
 
        addr = (c->ConfigBase + reg->Offset) >> 1;
 
@@ -188,6 +176,7 @@ int pcmcia_access_configuration_register(struct pcmcia_device *p_dev,
                pcmcia_write_cis_mem(s, 1, addr, 1, &val);
                break;
        default:
+               dev_dbg(&s->dev, "Invalid conf register request\n");
                return -EINVAL;
                break;
        }
@@ -196,68 +185,21 @@ int pcmcia_access_configuration_register(struct pcmcia_device *p_dev,
 EXPORT_SYMBOL(pcmcia_access_configuration_register);
 
 
-/** pcmcia_get_window
- */
-int pcmcia_get_window(struct pcmcia_socket *s, window_handle_t *handle,
-                     int idx, win_req_t *req)
-{
-       window_t *win;
-       int w;
-
-       if (!s || !(s->state & SOCKET_PRESENT))
-               return -ENODEV;
-       for (w = idx; w < MAX_WIN; w++)
-               if (s->state & SOCKET_WIN_REQ(w))
-                       break;
-       if (w == MAX_WIN)
-               return -EINVAL;
-       win = &s->win[w];
-       req->Base = win->ctl.res->start;
-       req->Size = win->ctl.res->end - win->ctl.res->start + 1;
-       req->AccessSpeed = win->ctl.speed;
-       req->Attributes = 0;
-       if (win->ctl.flags & MAP_ATTRIB)
-               req->Attributes |= WIN_MEMORY_TYPE_AM;
-       if (win->ctl.flags & MAP_ACTIVE)
-               req->Attributes |= WIN_ENABLE;
-       if (win->ctl.flags & MAP_16BIT)
-               req->Attributes |= WIN_DATA_WIDTH_16;
-       if (win->ctl.flags & MAP_USE_WAIT)
-               req->Attributes |= WIN_USE_WAIT;
-       *handle = win;
-       return 0;
-} /* pcmcia_get_window */
-EXPORT_SYMBOL(pcmcia_get_window);
-
-
-/** pcmcia_get_mem_page
- *
- * Change the card address of an already open memory window.
- */
-int pcmcia_get_mem_page(window_handle_t win, memreq_t *req)
+int pcmcia_map_mem_page(struct pcmcia_device *p_dev, window_handle_t wh,
+                       memreq_t *req)
 {
-       if ((win == NULL) || (win->magic != WINDOW_MAGIC))
-               return -EINVAL;
-       req->Page = 0;
-       req->CardOffset = win->ctl.card_start;
-       return 0;
-} /* pcmcia_get_mem_page */
-EXPORT_SYMBOL(pcmcia_get_mem_page);
-
+       struct pcmcia_socket *s = p_dev->socket;
 
-int pcmcia_map_mem_page(window_handle_t win, memreq_t *req)
-{
-       struct pcmcia_socket *s;
-       if ((win == NULL) || (win->magic != WINDOW_MAGIC))
+       wh--;
+       if (wh >= MAX_WIN)
                return -EINVAL;
-       s = win->sock;
        if (req->Page != 0) {
-               ds_dbg(s, 0, "failure: requested page is zero\n");
+               dev_dbg(&s->dev, "failure: requested page is zero\n");
                return -EINVAL;
        }
-       win->ctl.card_start = req->CardOffset;
-       if (s->ops->set_mem_map(s, &win->ctl) != 0) {
-               ds_dbg(s, 0, "failed to set_mem_map\n");
+       s->win[wh].card_start = req->CardOffset;
+       if (s->ops->set_mem_map(s, &s->win[wh]) != 0) {
+               dev_dbg(&s->dev, "failed to set_mem_map\n");
                return -EIO;
        }
        return 0;
@@ -278,10 +220,14 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev,
        s = p_dev->socket;
        c = p_dev->function_config;
 
-       if (!(s->state & SOCKET_PRESENT))
+       if (!(s->state & SOCKET_PRESENT)) {
+               dev_dbg(&s->dev, "No card present\n");
                return -ENODEV;
-       if (!(c->state & CONFIG_LOCKED))
+       }
+       if (!(c->state & CONFIG_LOCKED)) {
+               dev_dbg(&s->dev, "Configuration isnt't locked\n");
                return -EACCES;
+       }
 
        if (mod->Attributes & CONF_IRQ_CHANGE_VALID) {
                if (mod->Attributes & CONF_ENABLE_IRQ) {
@@ -295,7 +241,7 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev,
        }
 
        if (mod->Attributes & CONF_VCC_CHANGE_VALID) {
-               ds_dbg(s, 0, "changing Vcc is not allowed at this time\n");
+               dev_dbg(&s->dev, "changing Vcc is not allowed at this time\n");
                return -EINVAL;
        }
 
@@ -303,7 +249,7 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev,
        if ((mod->Attributes & CONF_VPP1_CHANGE_VALID) &&
            (mod->Attributes & CONF_VPP2_CHANGE_VALID)) {
                if (mod->Vpp1 != mod->Vpp2) {
-                       ds_dbg(s, 0, "Vpp1 and Vpp2 must be the same\n");
+                       dev_dbg(&s->dev, "Vpp1 and Vpp2 must be the same\n");
                        return -EINVAL;
                }
                s->socket.Vpp = mod->Vpp1;
@@ -314,7 +260,7 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev,
                }
        } else if ((mod->Attributes & CONF_VPP1_CHANGE_VALID) ||
                   (mod->Attributes & CONF_VPP2_CHANGE_VALID)) {
-               ds_dbg(s, 0, "changing Vcc is not allowed at this time\n");
+               dev_dbg(&s->dev, "changing Vcc is not allowed at this time\n");
                return -EINVAL;
        }
 
@@ -425,11 +371,11 @@ static int pcmcia_release_irq(struct pcmcia_device *p_dev, irq_req_t *req)
        if (c->state & CONFIG_LOCKED)
                return -EACCES;
        if (c->irq.Attributes != req->Attributes) {
-               ds_dbg(s, 0, "IRQ attributes must match assigned ones\n");
+               dev_dbg(&s->dev, "IRQ attributes must match assigned ones\n");
                return -EINVAL;
        }
        if (s->irq.AssignedIRQ != req->AssignedIRQ) {
-               ds_dbg(s, 0, "IRQ must match assigned one\n");
+               dev_dbg(&s->dev, "IRQ must match assigned one\n");
                return -EINVAL;
        }
        if (--s->irq.Config == 0) {
@@ -437,8 +383,8 @@ static int pcmcia_release_irq(struct pcmcia_device *p_dev, irq_req_t *req)
                s->irq.AssignedIRQ = 0;
        }
 
-       if (req->Attributes & IRQ_HANDLE_PRESENT) {
-               free_irq(req->AssignedIRQ, req->Instance);
+       if (req->Handler) {
+               free_irq(req->AssignedIRQ, p_dev->priv);
        }
 
 #ifdef CONFIG_PCMCIA_PROBE
@@ -449,30 +395,34 @@ static int pcmcia_release_irq(struct pcmcia_device *p_dev, irq_req_t *req)
 } /* pcmcia_release_irq */
 
 
-int pcmcia_release_window(window_handle_t win)
+int pcmcia_release_window(struct pcmcia_device *p_dev, window_handle_t wh)
 {
-       struct pcmcia_socket *s;
+       struct pcmcia_socket *s = p_dev->socket;
+       pccard_mem_map *win;
 
-       if ((win == NULL) || (win->magic != WINDOW_MAGIC))
+       wh--;
+       if (wh >= MAX_WIN)
                return -EINVAL;
-       s = win->sock;
-       if (!(win->handle->_win & CLIENT_WIN_REQ(win->index)))
+
+       win = &s->win[wh];
+
+       if (!(p_dev->_win & CLIENT_WIN_REQ(wh))) {
+               dev_dbg(&s->dev, "not releasing unknown window\n");
                return -EINVAL;
+       }
 
        /* Shut down memory window */
-       win->ctl.flags &= ~MAP_ACTIVE;
-       s->ops->set_mem_map(s, &win->ctl);
-       s->state &= ~SOCKET_WIN_REQ(win->index);
+       win->flags &= ~MAP_ACTIVE;
+       s->ops->set_mem_map(s, win);
+       s->state &= ~SOCKET_WIN_REQ(wh);
 
        /* Release system memory */
-       if (win->ctl.res) {
-               release_resource(win->ctl.res);
-               kfree(win->ctl.res);
-               win->ctl.res = NULL;
+       if (win->res) {
+               release_resource(win->res);
+               kfree(win->res);
+               win->res = NULL;
        }
-       win->handle->_win &= ~CLIENT_WIN_REQ(win->index);
-
-       win->magic = 0;
+       p_dev->_win &= ~CLIENT_WIN_REQ(wh);
 
        return 0;
 } /* pcmcia_release_window */
@@ -492,12 +442,14 @@ int pcmcia_request_configuration(struct pcmcia_device *p_dev,
                return -ENODEV;
 
        if (req->IntType & INT_CARDBUS) {
-               ds_dbg(p_dev->socket, 0, "IntType may not be INT_CARDBUS\n");
+               dev_dbg(&s->dev, "IntType may not be INT_CARDBUS\n");
                return -EINVAL;
        }
        c = p_dev->function_config;
-       if (c->state & CONFIG_LOCKED)
+       if (c->state & CONFIG_LOCKED) {
+               dev_dbg(&s->dev, "Configuration is locked\n");
                return -EACCES;
+       }
 
        /* Do power control.  We don't allow changes in Vcc. */
        s->socket.Vpp = req->Vpp;
@@ -609,40 +561,44 @@ int pcmcia_request_io(struct pcmcia_device *p_dev, io_req_t *req)
        struct pcmcia_socket *s = p_dev->socket;
        config_t *c;
 
-       if (!(s->state & SOCKET_PRESENT))
+       if (!(s->state & SOCKET_PRESENT)) {
+               dev_dbg(&s->dev, "No card present\n");
                return -ENODEV;
+       }
 
        if (!req)
                return -EINVAL;
        c = p_dev->function_config;
-       if (c->state & CONFIG_LOCKED)
+       if (c->state & CONFIG_LOCKED) {
+               dev_dbg(&s->dev, "Configuration is locked\n");
                return -EACCES;
+       }
        if (c->state & CONFIG_IO_REQ) {
-               ds_dbg(s, 0, "IO already configured\n");
+               dev_dbg(&s->dev, "IO already configured\n");
                return -EBUSY;
        }
        if (req->Attributes1 & (IO_SHARED | IO_FORCE_ALIAS_ACCESS)) {
-               ds_dbg(s, 0, "bad attribute setting for IO region 1\n");
+               dev_dbg(&s->dev, "bad attribute setting for IO region 1\n");
                return -EINVAL;
        }
        if ((req->NumPorts2 > 0) &&
            (req->Attributes2 & (IO_SHARED | IO_FORCE_ALIAS_ACCESS))) {
-               ds_dbg(s, 0, "bad attribute setting for IO region 2\n");
+               dev_dbg(&s->dev, "bad attribute setting for IO region 2\n");
                return -EINVAL;
        }
 
-       ds_dbg(s, 1, "trying to allocate resource 1\n");
+       dev_dbg(&s->dev, "trying to allocate resource 1\n");
        if (alloc_io_space(s, req->Attributes1, &req->BasePort1,
                           req->NumPorts1, req->IOAddrLines)) {
-               ds_dbg(s, 0, "allocation of resource 1 failed\n");
+               dev_dbg(&s->dev, "allocation of resource 1 failed\n");
                return -EBUSY;
        }
 
        if (req->NumPorts2) {
-               ds_dbg(s, 1, "trying to allocate resource 2\n");
+               dev_dbg(&s->dev, "trying to allocate resource 2\n");
                if (alloc_io_space(s, req->Attributes2, &req->BasePort2,
                                   req->NumPorts2, req->IOAddrLines)) {
-                       ds_dbg(s, 0, "allocation of resource 2 failed\n");
+                       dev_dbg(&s->dev, "allocation of resource 2 failed\n");
                        release_io_space(s, req->BasePort1, req->NumPorts1);
                        return -EBUSY;
                }
@@ -680,13 +636,17 @@ int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req)
        int ret = -EINVAL, irq = 0;
        int type;
 
-       if (!(s->state & SOCKET_PRESENT))
+       if (!(s->state & SOCKET_PRESENT)) {
+               dev_dbg(&s->dev, "No card present\n");
                return -ENODEV;
+       }
        c = p_dev->function_config;
-       if (c->state & CONFIG_LOCKED)
+       if (c->state & CONFIG_LOCKED) {
+               dev_dbg(&s->dev, "Configuration is locked\n");
                return -EACCES;
+       }
        if (c->state & CONFIG_IRQ_REQ) {
-               ds_dbg(s, 0, "IRQ already configured\n");
+               dev_dbg(&s->dev, "IRQ already configured\n");
                return -EBUSY;
        }
 
@@ -704,7 +664,7 @@ int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req)
        /* if the underlying IRQ infrastructure allows for it, only allocate
         * the IRQ, but do not enable it
         */
-       if (!(req->Attributes & IRQ_HANDLE_PRESENT))
+       if (!(req->Handler))
                type |= IRQ_NOAUTOEN;
 #endif /* IRQ_NOAUTOEN */
 
@@ -714,7 +674,7 @@ int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req)
        } else {
                int try;
                u32 mask = s->irq_mask;
-               void *data = &p_dev->dev.driver; /* something unique to this device */
+               void *data = p_dev; /* something unique to this device */
 
                for (try = 0; try < 64; try++) {
                        irq = try % 32;
@@ -731,12 +691,12 @@ int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req)
                         * registering a dummy handle works, i.e. if the IRQ isn't
                         * marked as used by the kernel resource management core */
                        ret = request_irq(irq,
-                                         (req->Attributes & IRQ_HANDLE_PRESENT) ? req->Handler : test_action,
+                                         (req->Handler) ? req->Handler : test_action,
                                          type,
                                          p_dev->devname,
-                                         (req->Attributes & IRQ_HANDLE_PRESENT) ? req->Instance : data);
+                                         (req->Handler) ? p_dev->priv : data);
                        if (!ret) {
-                               if (!(req->Attributes & IRQ_HANDLE_PRESENT))
+                               if (!req->Handler)
                                        free_irq(irq, data);
                                break;
                        }
@@ -745,17 +705,22 @@ int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req)
 #endif
        /* only assign PCI irq if no IRQ already assigned */
        if (ret && !s->irq.AssignedIRQ) {
-               if (!s->pci_irq)
+               if (!s->pci_irq) {
+                       dev_printk(KERN_INFO, &s->dev, "no IRQ found\n");
                        return ret;
+               }
                type = IRQF_SHARED;
                irq = s->pci_irq;
        }
 
-       if (ret && (req->Attributes & IRQ_HANDLE_PRESENT)) {
+       if (ret && req->Handler) {
                ret = request_irq(irq, req->Handler, type,
-                                 p_dev->devname, req->Instance);
-               if (ret)
+                                 p_dev->devname, p_dev->priv);
+               if (ret) {
+                       dev_printk(KERN_INFO, &s->dev,
+                               "request_irq() failed\n");
                        return ret;
+               }
        }
 
        /* Make sure the fact the request type was overridden is passed back */
@@ -787,17 +752,19 @@ EXPORT_SYMBOL(pcmcia_request_irq);
  * Request_window() establishes a mapping between card memory space
  * and system memory space.
  */
-int pcmcia_request_window(struct pcmcia_device **p_dev, win_req_t *req, window_handle_t *wh)
+int pcmcia_request_window(struct pcmcia_device *p_dev, win_req_t *req, window_handle_t *wh)
 {
-       struct pcmcia_socket *s = (*p_dev)->socket;
-       window_t *win;
+       struct pcmcia_socket *s = p_dev->socket;
+       pccard_mem_map *win;
        u_long align;
        int w;
 
-       if (!(s->state & SOCKET_PRESENT))
+       if (!(s->state & SOCKET_PRESENT)) {
+               dev_dbg(&s->dev, "No card present\n");
                return -ENODEV;
+       }
        if (req->Attributes & (WIN_PAGED | WIN_SHARED)) {
-               ds_dbg(s, 0, "bad attribute setting for iomem region\n");
+               dev_dbg(&s->dev, "bad attribute setting for iomem region\n");
                return -EINVAL;
        }
 
@@ -808,12 +775,12 @@ int pcmcia_request_window(struct pcmcia_device **p_dev, win_req_t *req, window_h
                  (req->Attributes & WIN_STRICT_ALIGN)) ?
                 req->Size : s->map_size);
        if (req->Size & (s->map_size-1)) {
-               ds_dbg(s, 0, "invalid map size\n");
+               dev_dbg(&s->dev, "invalid map size\n");
                return -EINVAL;
        }
        if ((req->Base && (s->features & SS_CAP_STATIC_MAP)) ||
            (req->Base & (align-1))) {
-               ds_dbg(s, 0, "invalid base address\n");
+               dev_dbg(&s->dev, "invalid base address\n");
                return -EINVAL;
        }
        if (req->Base)
@@ -823,52 +790,48 @@ int pcmcia_request_window(struct pcmcia_device **p_dev, win_req_t *req, window_h
        for (w = 0; w < MAX_WIN; w++)
                if (!(s->state & SOCKET_WIN_REQ(w))) break;
        if (w == MAX_WIN) {
-               ds_dbg(s, 0, "all windows are used already\n");
+               dev_dbg(&s->dev, "all windows are used already\n");
                return -EINVAL;
        }
 
        win = &s->win[w];
-       win->magic = WINDOW_MAGIC;
-       win->index = w;
-       win->handle = *p_dev;
-       win->sock = s;
 
        if (!(s->features & SS_CAP_STATIC_MAP)) {
-               win->ctl.res = pcmcia_find_mem_region(req->Base, req->Size, align,
+               win->res = pcmcia_find_mem_region(req->Base, req->Size, align,
                                                      (req->Attributes & WIN_MAP_BELOW_1MB), s);
-               if (!win->ctl.res) {
-                       ds_dbg(s, 0, "allocating mem region failed\n");
+               if (!win->res) {
+                       dev_dbg(&s->dev, "allocating mem region failed\n");
                        return -EINVAL;
                }
        }
-       (*p_dev)->_win |= CLIENT_WIN_REQ(w);
+       p_dev->_win |= CLIENT_WIN_REQ(w);
 
        /* Configure the socket controller */
-       win->ctl.map = w+1;
-       win->ctl.flags = 0;
-       win->ctl.speed = req->AccessSpeed;
+       win->map = w+1;
+       win->flags = 0;
+       win->speed = req->AccessSpeed;
        if (req->Attributes & WIN_MEMORY_TYPE)
-               win->ctl.flags |= MAP_ATTRIB;
+               win->flags |= MAP_ATTRIB;
        if (req->Attributes & WIN_ENABLE)
-               win->ctl.flags |= MAP_ACTIVE;
+               win->flags |= MAP_ACTIVE;
        if (req->Attributes & WIN_DATA_WIDTH_16)
-               win->ctl.flags |= MAP_16BIT;
+               win->flags |= MAP_16BIT;
        if (req->Attributes & WIN_USE_WAIT)
-               win->ctl.flags |= MAP_USE_WAIT;
-       win->ctl.card_start = 0;
-       if (s->ops->set_mem_map(s, &win->ctl) != 0) {
-               ds_dbg(s, 0, "failed to set memory mapping\n");
+               win->flags |= MAP_USE_WAIT;
+       win->card_start = 0;
+       if (s->ops->set_mem_map(s, win) != 0) {
+               dev_dbg(&s->dev, "failed to set memory mapping\n");
                return -EIO;
        }
        s->state |= SOCKET_WIN_REQ(w);
 
        /* Return window handle */
        if (s->features & SS_CAP_STATIC_MAP) {
-               req->Base = win->ctl.static_start;
+               req->Base = win->static_start;
        } else {
-               req->Base = win->ctl.res->start;
+               req->Base = win->res->start;
        }
-       *wh = win;
+       *wh = w + 1;
 
        return 0;
 } /* pcmcia_request_window */
@@ -879,18 +842,45 @@ void pcmcia_disable_device(struct pcmcia_device *p_dev) {
        pcmcia_release_io(p_dev, &p_dev->io);
        pcmcia_release_irq(p_dev, &p_dev->irq);
        if (p_dev->win)
-               pcmcia_release_window(p_dev->win);
+               pcmcia_release_window(p_dev, p_dev->win);
 }
 EXPORT_SYMBOL(pcmcia_disable_device);
 
 
 struct pcmcia_cfg_mem {
-       tuple_t tuple;
+       struct pcmcia_device *p_dev;
+       void *priv_data;
+       int (*conf_check) (struct pcmcia_device *p_dev,
+                          cistpl_cftable_entry_t *cfg,
+                          cistpl_cftable_entry_t *dflt,
+                          unsigned int vcc,
+                          void *priv_data);
        cisparse_t parse;
-       u8 buf[256];
        cistpl_cftable_entry_t dflt;
 };
 
+/**
+ * pcmcia_do_loop_config() - internal helper for pcmcia_loop_config()
+ *
+ * pcmcia_do_loop_config() is the internal callback for the call from
+ * pcmcia_loop_config() to pccard_loop_tuple(). Data is transferred
+ * by a struct pcmcia_cfg_mem.
+ */
+static int pcmcia_do_loop_config(tuple_t *tuple, cisparse_t *parse, void *priv)
+{
+       cistpl_cftable_entry_t *cfg = &parse->cftable_entry;
+       struct pcmcia_cfg_mem *cfg_mem = priv;
+
+       /* default values */
+       cfg_mem->p_dev->conf.ConfigIndex = cfg->index;
+       if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
+               cfg_mem->dflt = *cfg;
+
+       return cfg_mem->conf_check(cfg_mem->p_dev, cfg, &cfg_mem->dflt,
+                                  cfg_mem->p_dev->socket->socket.Vcc,
+                                  cfg_mem->priv_data);
+}
+
 /**
  * pcmcia_loop_config() - loop over configuration options
  * @p_dev:     the struct pcmcia_device which we need to loop for.
@@ -913,48 +903,174 @@ int pcmcia_loop_config(struct pcmcia_device *p_dev,
                       void *priv_data)
 {
        struct pcmcia_cfg_mem *cfg_mem;
-
-       tuple_t *tuple;
        int ret;
-       unsigned int vcc;
 
        cfg_mem = kzalloc(sizeof(struct pcmcia_cfg_mem), GFP_KERNEL);
        if (cfg_mem == NULL)
                return -ENOMEM;
 
-       /* get the current Vcc setting */
-       vcc = p_dev->socket->socket.Vcc;
+       cfg_mem->p_dev = p_dev;
+       cfg_mem->conf_check = conf_check;
+       cfg_mem->priv_data = priv_data;
 
-       tuple = &cfg_mem->tuple;
-       tuple->TupleData = cfg_mem->buf;
-       tuple->TupleDataMax = 255;
-       tuple->TupleOffset = 0;
-       tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY;
-       tuple->Attributes = 0;
+       ret = pccard_loop_tuple(p_dev->socket, p_dev->func,
+                               CISTPL_CFTABLE_ENTRY, &cfg_mem->parse,
+                               cfg_mem, pcmcia_do_loop_config);
 
-       ret = pcmcia_get_first_tuple(p_dev, tuple);
-       while (!ret) {
-               cistpl_cftable_entry_t *cfg = &cfg_mem->parse.cftable_entry;
+       kfree(cfg_mem);
+       return ret;
+}
+EXPORT_SYMBOL(pcmcia_loop_config);
+
+
+struct pcmcia_loop_mem {
+       struct pcmcia_device *p_dev;
+       void *priv_data;
+       int (*loop_tuple) (struct pcmcia_device *p_dev,
+                          tuple_t *tuple,
+                          void *priv_data);
+};
+
+/**
+ * pcmcia_do_loop_tuple() - internal helper for pcmcia_loop_config()
+ *
+ * pcmcia_do_loop_tuple() is the internal callback for the call from
+ * pcmcia_loop_tuple() to pccard_loop_tuple(). Data is transferred
+ * by a struct pcmcia_cfg_mem.
+ */
+static int pcmcia_do_loop_tuple(tuple_t *tuple, cisparse_t *parse, void *priv)
+{
+       struct pcmcia_loop_mem *loop = priv;
+
+       return loop->loop_tuple(loop->p_dev, tuple, loop->priv_data);
+};
+
+/**
+ * pcmcia_loop_tuple() - loop over tuples in the CIS
+ * @p_dev:     the struct pcmcia_device which we need to loop for.
+ * @code:      which CIS code shall we look for?
+ * @priv_data: private data to be passed to the loop_tuple function.
+ * @loop_tuple:        function to call for each CIS entry of type @function. IT
+ *             gets passed the raw tuple and @priv_data.
+ *
+ * pcmcia_loop_tuple() loops over all CIS entries of type @function, and
+ * calls the @loop_tuple function for each entry. If the call to @loop_tuple
+ * returns 0, the loop exits. Returns 0 on success or errorcode otherwise.
+ */
+int pcmcia_loop_tuple(struct pcmcia_device *p_dev, cisdata_t code,
+                     int (*loop_tuple) (struct pcmcia_device *p_dev,
+                                        tuple_t *tuple,
+                                        void *priv_data),
+                     void *priv_data)
+{
+       struct pcmcia_loop_mem loop = {
+               .p_dev = p_dev,
+               .loop_tuple = loop_tuple,
+               .priv_data = priv_data};
 
-               if (pcmcia_get_tuple_data(p_dev, tuple))
-                       goto next_entry;
+       return pccard_loop_tuple(p_dev->socket, p_dev->func, code, NULL,
+                                &loop, pcmcia_do_loop_tuple);
+};
+EXPORT_SYMBOL(pcmcia_loop_tuple);
 
-               if (pcmcia_parse_tuple(tuple, &cfg_mem->parse))
-                       goto next_entry;
 
-               /* default values */
-               p_dev->conf.ConfigIndex = cfg->index;
-               if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
-                       cfg_mem->dflt = *cfg;
+struct pcmcia_loop_get {
+       size_t len;
+       cisdata_t **buf;
+};
 
-               ret = conf_check(p_dev, cfg, &cfg_mem->dflt, vcc, priv_data);
-               if (!ret)
-                       break;
+/**
+ * pcmcia_do_get_tuple() - internal helper for pcmcia_get_tuple()
+ *
+ * pcmcia_do_get_tuple() is the internal callback for the call from
+ * pcmcia_get_tuple() to pcmcia_loop_tuple(). As we're only interested in
+ * the first tuple, return 0 unconditionally. Create a memory buffer large
+ * enough to hold the content of the tuple, and fill it with the tuple data.
+ * The caller is responsible to free the buffer.
+ */
+static int pcmcia_do_get_tuple(struct pcmcia_device *p_dev, tuple_t *tuple,
+                              void *priv)
+{
+       struct pcmcia_loop_get *get = priv;
+
+       *get->buf = kzalloc(tuple->TupleDataLen, GFP_KERNEL);
+       if (*get->buf) {
+               get->len = tuple->TupleDataLen;
+               memcpy(*get->buf, tuple->TupleData, tuple->TupleDataLen);
+       } else
+               dev_dbg(&p_dev->dev, "do_get_tuple: out of memory\n");
+       return 0;
+};
 
-next_entry:
-               ret = pcmcia_get_next_tuple(p_dev, tuple);
+/**
+ * pcmcia_get_tuple() - get first tuple from CIS
+ * @p_dev:     the struct pcmcia_device which we need to loop for.
+ * @code:      which CIS code shall we look for?
+ * @buf:        pointer to store the buffer to.
+ *
+ * pcmcia_get_tuple() gets the content of the first CIS entry of type @code.
+ * It returns the buffer length (or zero). The caller is responsible to free
+ * the buffer passed in @buf.
+ */
+size_t pcmcia_get_tuple(struct pcmcia_device *p_dev, cisdata_t code,
+                       unsigned char **buf)
+{
+       struct pcmcia_loop_get get = {
+               .len = 0,
+               .buf = buf,
+       };
+
+       *get.buf = NULL;
+       pcmcia_loop_tuple(p_dev, code, pcmcia_do_get_tuple, &get);
+
+       return get.len;
+};
+EXPORT_SYMBOL(pcmcia_get_tuple);
+
+
+/**
+ * pcmcia_do_get_mac() - internal helper for pcmcia_get_mac_from_cis()
+ *
+ * pcmcia_do_get_mac() is the internal callback for the call from
+ * pcmcia_get_mac_from_cis() to pcmcia_loop_tuple(). We check whether the
+ * tuple contains a proper LAN_NODE_ID of length 6, and copy the data
+ * to struct net_device->dev_addr[i].
+ */
+static int pcmcia_do_get_mac(struct pcmcia_device *p_dev, tuple_t *tuple,
+                            void *priv)
+{
+       struct net_device *dev = priv;
+       int i;
+
+       if (tuple->TupleData[0] != CISTPL_FUNCE_LAN_NODE_ID)
+               return -EINVAL;
+       if (tuple->TupleDataLen < ETH_ALEN + 2) {
+               dev_warn(&p_dev->dev, "Invalid CIS tuple length for "
+                       "LAN_NODE_ID\n");
+               return -EINVAL;
        }
 
-       return ret;
-}
-EXPORT_SYMBOL(pcmcia_loop_config);
+       if (tuple->TupleData[1] != ETH_ALEN) {
+               dev_warn(&p_dev->dev, "Invalid header for LAN_NODE_ID\n");
+               return -EINVAL;
+       }
+       for (i = 0; i < 6; i++)
+               dev->dev_addr[i] = tuple->TupleData[i+2];
+       return 0;
+};
+
+/**
+ * pcmcia_get_mac_from_cis() - read out MAC address from CISTPL_FUNCE
+ * @p_dev:     the struct pcmcia_device for which we want the address.
+ * @dev:       a properly prepared struct net_device to store the info to.
+ *
+ * pcmcia_get_mac_from_cis() reads out the hardware MAC address from
+ * CISTPL_FUNCE and stores it into struct net_device *dev->dev_addr which
+ * must be set up properly by the driver (see examples!).
+ */
+int pcmcia_get_mac_from_cis(struct pcmcia_device *p_dev, struct net_device *dev)
+{
+       return pcmcia_loop_tuple(p_dev, CISTPL_FUNCE, pcmcia_do_get_mac, dev);
+};
+EXPORT_SYMBOL(pcmcia_get_mac_from_cis);
+
index 70a33468bcd0b6851f2320578963b74a4df9ea96..e1741cd875aaae9861bcab302e67be4c106af1e5 100644 (file)
@@ -213,7 +213,8 @@ static irqreturn_t pd6729_interrupt(int irq, void *dev)
 
                        if (csc & I365_CSC_DETECT) {
                                events |= SS_DETECT;
-                               dprintk("Card detected in socket %i!\n", i);
+                               dev_vdbg(&socket[i].socket.dev,
+                                       "Card detected in socket %i!\n", i);
                        }
 
                        if (indirect_read(&socket[i], I365_INTCTL)
@@ -331,11 +332,11 @@ static int pd6729_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
        reg = I365_PWR_NORESET; /* default: disable resetdrv on resume */
 
        if (state->flags & SS_PWR_AUTO) {
-               dprintk("Auto power\n");
+               dev_dbg(&sock->dev, "Auto power\n");
                reg |= I365_PWR_AUTO;   /* automatic power mngmnt */
        }
        if (state->flags & SS_OUTPUT_ENA) {
-               dprintk("Power Enabled\n");
+               dev_dbg(&sock->dev, "Power Enabled\n");
                reg |= I365_PWR_OUT;    /* enable power */
        }
 
@@ -343,40 +344,44 @@ static int pd6729_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
        case 0:
                break;
        case 33:
-               dprintk("setting voltage to Vcc to 3.3V on socket %i\n",
+               dev_dbg(&sock->dev,
+                       "setting voltage to Vcc to 3.3V on socket %i\n",
                        socket->number);
                reg |= I365_VCC_5V;
                indirect_setbit(socket, PD67_MISC_CTL_1, PD67_MC1_VCC_3V);
                break;
        case 50:
-               dprintk("setting voltage to Vcc to 5V on socket %i\n",
+               dev_dbg(&sock->dev,
+                       "setting voltage to Vcc to 5V on socket %i\n",
                        socket->number);
                reg |= I365_VCC_5V;
                indirect_resetbit(socket, PD67_MISC_CTL_1, PD67_MC1_VCC_3V);
                break;
        default:
-               dprintk("pd6729: pd6729_set_socket called with "
-                               "invalid VCC power value: %i\n",
-                       state->Vcc);
+               dev_dbg(&sock->dev,
+                       "pd6729_set_socket called with invalid VCC power "
+                       "value: %i\n", state->Vcc);
                return -EINVAL;
        }
 
        switch (state->Vpp) {
        case 0:
-               dprintk("not setting Vpp on socket %i\n", socket->number);
+               dev_dbg(&sock->dev, "not setting Vpp on socket %i\n",
+                       socket->number);
                break;
        case 33:
        case 50:
-               dprintk("setting Vpp to Vcc for socket %i\n", socket->number);
+               dev_dbg(&sock->dev, "setting Vpp to Vcc for socket %i\n",
+                       socket->number);
                reg |= I365_VPP1_5V;
                break;
        case 120:
-               dprintk("setting Vpp to 12.0\n");
+               dev_dbg(&sock->dev, "setting Vpp to 12.0\n");
                reg |= I365_VPP1_12V;
                break;
        default:
-               dprintk("pd6729: pd6729_set_socket called with invalid VPP power value: %i\n",
-                       state->Vpp);
+               dev_dbg(&sock->dev, "pd6729: pd6729_set_socket called with "
+                       "invalid VPP power value: %i\n", state->Vpp);
                return -EINVAL;
        }
 
@@ -438,7 +443,7 @@ static int pd6729_set_io_map(struct pcmcia_socket *sock,
 
        /* Check error conditions */
        if (map > 1) {
-               dprintk("pd6729_set_io_map with invalid map");
+               dev_dbg(&sock->dev, "pd6729_set_io_map with invalid map\n");
                return -EINVAL;
        }
 
@@ -446,7 +451,7 @@ static int pd6729_set_io_map(struct pcmcia_socket *sock,
        if (indirect_read(socket, I365_ADDRWIN) & I365_ENA_IO(map))
                indirect_resetbit(socket, I365_ADDRWIN, I365_ENA_IO(map));
 
-       /* dprintk("set_io_map: Setting range to %x - %x\n",
+       /* dev_dbg(&sock->dev, "set_io_map: Setting range to %x - %x\n",
           io->start, io->stop);*/
 
        /* write the new values */
@@ -478,12 +483,12 @@ static int pd6729_set_mem_map(struct pcmcia_socket *sock,
 
        map = mem->map;
        if (map > 4) {
-               printk("pd6729_set_mem_map: invalid map");
+               dev_warn(&sock->dev, "invalid map requested\n");
                return -EINVAL;
        }
 
        if ((mem->res->start > mem->res->end) || (mem->speed > 1000)) {
-               printk("pd6729_set_mem_map: invalid address / speed");
+               dev_warn(&sock->dev, "invalid invalid address / speed\n");
                return -EINVAL;
        }
 
@@ -529,12 +534,12 @@ static int pd6729_set_mem_map(struct pcmcia_socket *sock,
        if (mem->flags & MAP_WRPROT)
                i |= I365_MEM_WRPROT;
        if (mem->flags & MAP_ATTRIB) {
-               /* dprintk("requesting attribute memory for socket %i\n",
-                       socket->number);*/
+               /* dev_dbg(&sock->dev, "requesting attribute memory for "
+                  "socket %i\n", socket->number);*/
                i |= I365_MEM_REG;
        } else {
-               /* dprintk("requesting normal memory for socket %i\n",
-                       socket->number);*/
+               /* dev_dbg(&sock->dev, "requesting normal memory for "
+                  "socket %i\n", socket->number);*/
        }
        indirect_write16(socket, base + I365_W_OFF, i);
 
@@ -577,7 +582,7 @@ static struct pccard_operations pd6729_operations = {
 
 static irqreturn_t pd6729_test(int irq, void *dev)
 {
-       dprintk("-> hit on irq %d\n", irq);
+       pr_devel("-> hit on irq %d\n", irq);
        return IRQ_HANDLED;
 }
 
@@ -642,13 +647,13 @@ static int __devinit pd6729_pci_probe(struct pci_dev *dev,
                goto err_out_free_mem;
 
        if (!pci_resource_start(dev, 0)) {
-               printk(KERN_INFO "pd6729: refusing to load the driver "
-                                "as the io_base is 0.\n");
+               dev_warn(&dev->dev, "refusing to load the driver as the "
+                       "io_base is NULL.\n");
                goto err_out_free_mem;
        }
 
-       printk(KERN_INFO "pd6729: Cirrus PD6729 PCI to PCMCIA Bridge "
-               "at 0x%llx on irq %d\n",
+       dev_info(&dev->dev, "Cirrus PD6729 PCI to PCMCIA Bridge at 0x%llx "
+               "on irq %d\n",
                (unsigned long long)pci_resource_start(dev, 0), dev->irq);
        /*
         * Since we have no memory BARs some firmware may not
@@ -656,14 +661,14 @@ static int __devinit pd6729_pci_probe(struct pci_dev *dev,
         */
        pci_read_config_byte(dev, PCI_COMMAND, &configbyte);
        if (!(configbyte & PCI_COMMAND_MEMORY)) {
-               printk(KERN_DEBUG "pd6729: Enabling PCI_COMMAND_MEMORY.\n");
+               dev_dbg(&dev->dev, "pd6729: Enabling PCI_COMMAND_MEMORY.\n");
                configbyte |= PCI_COMMAND_MEMORY;
                pci_write_config_byte(dev, PCI_COMMAND, configbyte);
        }
 
        ret = pci_request_regions(dev, "pd6729");
        if (ret) {
-               printk(KERN_INFO "pd6729: pci request region failed.\n");
+               dev_warn(&dev->dev, "pci request region failed.\n");
                goto err_out_disable;
        }
 
@@ -672,7 +677,7 @@ static int __devinit pd6729_pci_probe(struct pci_dev *dev,
 
        mask = pd6729_isa_scan();
        if (irq_mode == 0 && mask == 0) {
-               printk(KERN_INFO "pd6729: no ISA interrupt is available.\n");
+               dev_warn(&dev->dev, "no ISA interrupt is available.\n");
                goto err_out_free_res;
        }
 
@@ -697,8 +702,8 @@ static int __devinit pd6729_pci_probe(struct pci_dev *dev,
                /* Register the interrupt handler */
                if ((ret = request_irq(dev->irq, pd6729_interrupt, IRQF_SHARED,
                                                        "pd6729", socket))) {
-                       printk(KERN_ERR "pd6729: Failed to register irq %d, "
-                                                       "aborting\n", dev->irq);
+                       dev_err(&dev->dev, "Failed to register irq %d\n",
+                               dev->irq);
                        goto err_out_free_res;
                }
        } else {
@@ -713,8 +718,7 @@ static int __devinit pd6729_pci_probe(struct pci_dev *dev,
        for (i = 0; i < MAX_SOCKETS; i++) {
                ret = pcmcia_register_socket(&socket[i].socket);
                if (ret) {
-                       printk(KERN_INFO "pd6729: pcmcia_register_socket "
-                                              "failed.\n");
+                       dev_warn(&dev->dev, "pcmcia_register_socket failed.\n");
                        for (j = 0; j < i ; j++)
                                pcmcia_unregister_socket(&socket[j].socket);
                        goto err_out_free_res2;
index f392e458cdfd7f7d91957041c506b790aa68108b..41418d394c55bf2c31dab3a12f3b1bc0d2b42913 100644 (file)
@@ -1,13 +1,6 @@
 #ifndef _INCLUDE_GUARD_PD6729_H_
 #define _INCLUDE_GUARD_PD6729_H_
 
-/* Debuging defines */
-#ifdef NOTRACE
-#define dprintk(fmt, args...) printk(fmt , ## args)
-#else
-#define dprintk(fmt, args...) do {} while (0)
-#endif
-
 /* Flags for I365_GENCTL */
 #define I365_DF_VS1            0x40    /* DF-step Voltage Sense */
 #define I365_DF_VS2            0x80
index 0e35acb1366b118773e34db9578daf1b30582119..84dde7768ad54cd6c8d1fbd0899afd2c38700a95 100644 (file)
@@ -228,9 +228,43 @@ static const char *skt_names[] = {
 #define SKT_DEV_INFO_SIZE(n) \
        (sizeof(struct skt_dev_info) + (n)*sizeof(struct soc_pcmcia_socket))
 
+int pxa2xx_drv_pcmcia_add_one(struct soc_pcmcia_socket *skt)
+{
+       skt->res_skt.start = _PCMCIA(skt->nr);
+       skt->res_skt.end = _PCMCIA(skt->nr) + PCMCIASp - 1;
+       skt->res_skt.name = skt_names[skt->nr];
+       skt->res_skt.flags = IORESOURCE_MEM;
+
+       skt->res_io.start = _PCMCIAIO(skt->nr);
+       skt->res_io.end = _PCMCIAIO(skt->nr) + PCMCIAIOSp - 1;
+       skt->res_io.name = "io";
+       skt->res_io.flags = IORESOURCE_MEM | IORESOURCE_BUSY;
+
+       skt->res_mem.start = _PCMCIAMem(skt->nr);
+       skt->res_mem.end = _PCMCIAMem(skt->nr) + PCMCIAMemSp - 1;
+       skt->res_mem.name = "memory";
+       skt->res_mem.flags = IORESOURCE_MEM;
+
+       skt->res_attr.start = _PCMCIAAttr(skt->nr);
+       skt->res_attr.end = _PCMCIAAttr(skt->nr) + PCMCIAAttrSp - 1;
+       skt->res_attr.name = "attribute";
+       skt->res_attr.flags = IORESOURCE_MEM;
+
+       return soc_pcmcia_add_one(skt);
+}
+
+void pxa2xx_drv_pcmcia_ops(struct pcmcia_low_level *ops)
+{
+       /* Provide our PXA2xx specific timing routines. */
+       ops->set_timing  = pxa2xx_pcmcia_set_timing;
+#ifdef CONFIG_CPU_FREQ
+       ops->frequency_change = pxa2xx_pcmcia_frequency_change;
+#endif
+}
+
 int __pxa2xx_drv_pcmcia_probe(struct device *dev)
 {
-       int i, ret;
+       int i, ret = 0;
        struct pcmcia_low_level *ops;
        struct skt_dev_info *sinfo;
        struct soc_pcmcia_socket *skt;
@@ -240,6 +274,8 @@ int __pxa2xx_drv_pcmcia_probe(struct device *dev)
 
        ops = (struct pcmcia_low_level *)dev->platform_data;
 
+       pxa2xx_drv_pcmcia_ops(ops);
+
        sinfo = kzalloc(SKT_DEV_INFO_SIZE(ops->nr), GFP_KERNEL);
        if (!sinfo)
                return -ENOMEM;
@@ -250,40 +286,25 @@ int __pxa2xx_drv_pcmcia_probe(struct device *dev)
        for (i = 0; i < ops->nr; i++) {
                skt = &sinfo->skt[i];
 
-               skt->nr         = ops->first + i;
-               skt->irq        = NO_IRQ;
-
-               skt->res_skt.start      = _PCMCIA(skt->nr);
-               skt->res_skt.end        = _PCMCIA(skt->nr) + PCMCIASp - 1;
-               skt->res_skt.name       = skt_names[skt->nr];
-               skt->res_skt.flags      = IORESOURCE_MEM;
-
-               skt->res_io.start       = _PCMCIAIO(skt->nr);
-               skt->res_io.end         = _PCMCIAIO(skt->nr) + PCMCIAIOSp - 1;
-               skt->res_io.name        = "io";
-               skt->res_io.flags       = IORESOURCE_MEM | IORESOURCE_BUSY;
+               skt->nr = ops->first + i;
+               skt->ops = ops;
+               skt->socket.owner = ops->owner;
+               skt->socket.dev.parent = dev;
+               skt->socket.pci_irq = NO_IRQ;
 
-               skt->res_mem.start      = _PCMCIAMem(skt->nr);
-               skt->res_mem.end        = _PCMCIAMem(skt->nr) + PCMCIAMemSp - 1;
-               skt->res_mem.name       = "memory";
-               skt->res_mem.flags      = IORESOURCE_MEM;
-
-               skt->res_attr.start     = _PCMCIAAttr(skt->nr);
-               skt->res_attr.end       = _PCMCIAAttr(skt->nr) + PCMCIAAttrSp - 1;
-               skt->res_attr.name      = "attribute";
-               skt->res_attr.flags     = IORESOURCE_MEM;
+               ret = pxa2xx_drv_pcmcia_add_one(skt);
+               if (ret)
+                       break;
        }
 
-       /* Provide our PXA2xx specific timing routines. */
-       ops->set_timing  = pxa2xx_pcmcia_set_timing;
-#ifdef CONFIG_CPU_FREQ
-       ops->frequency_change = pxa2xx_pcmcia_frequency_change;
-#endif
-
-       ret = soc_common_drv_pcmcia_probe(dev, ops, sinfo);
-
-       if (!ret)
+       if (ret) {
+               while (--i >= 0)
+                       soc_pcmcia_remove_one(&sinfo->skt[i]);
+               kfree(sinfo);
+       } else {
                pxa2xx_configure_sockets(dev);
+               dev_set_drvdata(dev, sinfo);
+       }
 
        return ret;
 }
@@ -297,7 +318,16 @@ static int pxa2xx_drv_pcmcia_probe(struct platform_device *dev)
 
 static int pxa2xx_drv_pcmcia_remove(struct platform_device *dev)
 {
-       return soc_common_drv_pcmcia_remove(&dev->dev);
+       struct skt_dev_info *sinfo = platform_get_drvdata(dev);
+       int i;
+
+       platform_set_drvdata(dev, NULL);
+
+       for (i = 0; i < sinfo->nskt; i++)
+               soc_pcmcia_remove_one(&sinfo->skt[i]);
+
+       kfree(sinfo);
+       return 0;
 }
 
 static int pxa2xx_drv_pcmcia_suspend(struct device *dev)
index 235d681652c3f625ae31be4b4d592c5bae5ff176..cb5efaec886f2c807849d2dc467aa71b631c6b1a 100644 (file)
@@ -1,3 +1,6 @@
 /* temporary measure */
 extern int __pxa2xx_drv_pcmcia_probe(struct device *);
 
+int pxa2xx_drv_pcmcia_add_one(struct soc_pcmcia_socket *skt);
+void pxa2xx_drv_pcmcia_ops(struct pcmcia_low_level *ops);
+
index 5143a760153b9626aaf15df274e795732951ed80..05913d0bbdbef64b513ab89f1c7fe448c6002248 100644 (file)
@@ -44,7 +44,7 @@ static int cmx255_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
                return ret;
        gpio_direction_output(GPIO_PCMCIA_RESET, 0);
 
-       skt->irq = skt->nr == 0 ? PCMCIA_S0_RDYINT : PCMCIA_S1_RDYINT;
+       skt->socket.pci_irq = skt->nr == 0 ? PCMCIA_S0_RDYINT : PCMCIA_S1_RDYINT;
        ret = soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
        if (!ret)
                gpio_free(GPIO_PCMCIA_RESET);
index a7b943d01e34a85a0e27897f55eec9ba1670b853..5662646b84da9bdb8eda5666f7251b3a3de4faec 100644 (file)
@@ -38,7 +38,7 @@ static int cmx270_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
                return ret;
        gpio_direction_output(GPIO_PCMCIA_RESET, 0);
 
-       skt->irq = PCMCIA_S0_RDYINT;
+       skt->socket.pci_irq = PCMCIA_S0_RDYINT;
        ret = soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
        if (!ret)
                gpio_free(GPIO_PCMCIA_RESET);
index d09c0dc4a31a80bce783e7b3fdda1459399a3fc9..8bfbd4dca131e1a252e4b539fd8927703f28e646 100644 (file)
@@ -38,7 +38,7 @@ static struct pcmcia_irqs cd_irqs[] = {
 
 static int e740_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 {
-       skt->irq = skt->nr == 0 ? IRQ_GPIO(GPIO_E740_PCMCIA_RDY0) :
+       skt->socket.pci_irq = skt->nr == 0 ? IRQ_GPIO(GPIO_E740_PCMCIA_RDY0) :
                                IRQ_GPIO(GPIO_E740_PCMCIA_RDY1);
 
        return soc_pcmcia_request_irqs(skt, &cd_irqs[skt->nr], 1);
index 6cbb1b1f7cfdf0a2224853f7cda97469b6deeffa..b9f8c8fb42bd52417eb1236a8f18b77dea6c5592 100644 (file)
@@ -32,6 +32,7 @@ static int
 lubbock_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
                                const socket_state_t *state)
 {
+       struct sa1111_pcmcia_socket *s = to_skt(skt);
        unsigned int pa_dwr_mask, pa_dwr_set, misc_mask, misc_set;
        int ret = 0;
 
@@ -149,7 +150,7 @@ lubbock_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
 
        if (ret == 0) {
                lubbock_set_misc_wr(misc_mask, misc_set);
-               sa1111_set_io(SA1111_DEV(skt->dev), pa_dwr_mask, pa_dwr_set);
+               sa1111_set_io(s->dev, pa_dwr_mask, pa_dwr_set);
        }
 
 #if 1
@@ -175,7 +176,7 @@ lubbock_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
                         * Switch to 5V,  Configure socket with 5V voltage
                         */
                        lubbock_set_misc_wr(misc_mask, 0);
-                       sa1111_set_io(SA1111_DEV(skt->dev), pa_dwr_mask, 0);
+                       sa1111_set_io(s->dev, pa_dwr_mask, 0);
 
                        /*
                         * It takes about 100ms to turn off Vcc.
@@ -200,12 +201,8 @@ lubbock_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
 
 static struct pcmcia_low_level lubbock_pcmcia_ops = {
        .owner                  = THIS_MODULE,
-       .hw_init                = sa1111_pcmcia_hw_init,
-       .hw_shutdown            = sa1111_pcmcia_hw_shutdown,
-       .socket_state           = sa1111_pcmcia_socket_state,
        .configure_socket       = lubbock_pcmcia_configure_socket,
        .socket_init            = sa1111_pcmcia_socket_init,
-       .socket_suspend         = sa1111_pcmcia_socket_suspend,
        .first                  = 0,
        .nr                     = 2,
 };
@@ -228,8 +225,9 @@ int pcmcia_lubbock_init(struct sa1111_dev *sadev)
                /* Set CF Socket 1 power to standby mode. */
                lubbock_set_misc_wr((1 << 15) | (1 << 14), 0);
 
-               sadev->dev.platform_data = &lubbock_pcmcia_ops;
-               ret = __pxa2xx_drv_pcmcia_probe(&sadev->dev);
+               pxa2xx_drv_pcmcia_ops(&lubbock_pcmcia_ops);
+               ret = sa1111_pcmcia_add(sadev, &lubbock_pcmcia_ops,
+                               pxa2xx_drv_pcmcia_add_one);
        }
 
        return ret;
index 1138551ba8f61fb8f77669b9c2fcb0dea0cf5645..92016fe932b46bfd720b6ecfc56fca26a6add563 100644 (file)
@@ -44,7 +44,7 @@ static int mst_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
         * before we enable them as outputs.
         */
 
-       skt->irq = (skt->nr == 0) ? MAINSTONE_S0_IRQ : MAINSTONE_S1_IRQ;
+       skt->socket.pci_irq = (skt->nr == 0) ? MAINSTONE_S0_IRQ : MAINSTONE_S1_IRQ;
        return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
 }
 
index 5ba9b3664a00abdf8eb5bab95c80cccb12ab2d31..6fb6f7f0672ea7d29f7ce23d709881037ab4250c 100644 (file)
@@ -45,7 +45,7 @@ static int palmld_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
        if (ret)
                goto err4;
 
-       skt->irq = IRQ_GPIO(GPIO_NR_PALMLD_PCMCIA_READY);
+       skt->socket.pci_irq = IRQ_GPIO(GPIO_NR_PALMLD_PCMCIA_READY);
        return 0;
 
 err4:
index e07b5c51ec5bbda422c27bb99c9743b9a1af4b7c..b07b247a399fd5960653164722899a7c40d185bb 100644 (file)
@@ -53,7 +53,7 @@ static int palmtx_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
        if (ret)
                goto err5;
 
-       skt->irq = gpio_to_irq(GPIO_NR_PALMTX_PCMCIA_READY);
+       skt->socket.pci_irq = gpio_to_irq(GPIO_NR_PALMTX_PCMCIA_READY);
        return 0;
 
 err5:
index bc43f78f6f0ba10ae8caa184f76d96cb30389475..0ea3b29440e6b394a5608f41f749610f62b45091 100644 (file)
@@ -66,7 +66,7 @@ static int sharpsl_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
                }
        }
 
-       skt->irq = SCOOP_DEV[skt->nr].irq;
+       skt->socket.pci_irq = SCOOP_DEV[skt->nr].irq;
 
        return 0;
 }
index e0e5cb339b4a8e41e1f046af7a4c8eab561ed8a3..b7e596620db16c594a7ba3cc73c2bbd9643b0e43 100644 (file)
@@ -53,7 +53,7 @@ static int trizeps_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
                        gpio_free(GPIO_PRDY);
                        return -EINVAL;
                }
-               skt->irq = IRQ_GPIO(GPIO_PRDY);
+               skt->socket.pci_irq = IRQ_GPIO(GPIO_PRDY);
                break;
 
 #ifndef CONFIG_MACH_TRIZEPS_CONXS
@@ -63,7 +63,7 @@ static int trizeps_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
                break;
        }
        /* release the reset of this card */
-       pr_debug("%s: sock %d irq %d\n", __func__, skt->nr, skt->irq);
+       pr_debug("%s: sock %d irq %d\n", __func__, skt->nr, skt->socket.pci_irq);
 
        /* supplementory irqs for the socket */
        for (i = 0; i < ARRAY_SIZE(irqs); i++) {
index 17871360fe99efd1247365b51d345510a82858f3..27be2e154df2a92782dbfafa48598c00dc3cd72f 100644 (file)
@@ -40,7 +40,7 @@ static int viper_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 {
        unsigned long flags;
 
-       skt->irq = gpio_to_irq(VIPER_CF_RDY_GPIO);
+       skt->socket.pci_irq = gpio_to_irq(VIPER_CF_RDY_GPIO);
 
        if (gpio_request(VIPER_CF_CD_GPIO, "CF detect"))
                goto err_request_cd;
index e592e0e0d7ed3a88dcdb0b4379b1ad69edfd3cc3..de0e770ce6a30ec404fb9fb1833ce793ab5d55b5 100644 (file)
@@ -18,6 +18,7 @@
 #include <pcmcia/cs_types.h>
 #include <pcmcia/ss.h>
 #include <pcmcia/cs.h>
+#include <pcmcia/cistpl.h>
 #include "cs_internal.h"
 
 
index ac8aa09ba0da56b33f12e3a9ba0168ef73e54779..fd013a1ef47abcdd5746f4fa7f9885670fc2a9cd 100644 (file)
@@ -27,7 +27,7 @@ static struct pcmcia_irqs irqs[] = {
 
 static int assabet_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 {
-       skt->irq = ASSABET_IRQ_GPIO_CF_IRQ;
+       skt->socket.pci_irq = ASSABET_IRQ_GPIO_CF_IRQ;
 
        return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
 }
index 1ca9737ea79ea17c414a9aea9d99ab3a7c7a8cf6..1ce53f493bef64238c9eb26d20ea495ab90718cd 100644 (file)
@@ -127,13 +127,10 @@ badge4_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state
 
 static struct pcmcia_low_level badge4_pcmcia_ops = {
        .owner                  = THIS_MODULE,
-       .hw_init                = sa1111_pcmcia_hw_init,
-       .hw_shutdown            = sa1111_pcmcia_hw_shutdown,
-       .socket_state           = sa1111_pcmcia_socket_state,
        .configure_socket       = badge4_pcmcia_configure_socket,
-
        .socket_init            = sa1111_pcmcia_socket_init,
-       .socket_suspend         = sa1111_pcmcia_socket_suspend,
+       .first                  = 0,
+       .nr                     = 2,
 };
 
 int pcmcia_badge4_init(struct device *dev)
@@ -146,7 +143,9 @@ int pcmcia_badge4_init(struct device *dev)
                       __func__,
                       badge4_pcmvcc, badge4_pcmvpp, badge4_cfvcc);
 
-               ret = sa11xx_drv_pcmcia_probe(dev, &badge4_pcmcia_ops, 0, 2);
+               sa11xx_drv_pcmcia_ops(&badge4_pcmcia_ops);
+               ret = sa1111_pcmcia_add(dev, &badge4_pcmcia_ops,
+                               sa11xx_drv_pcmcia_add_one);
        }
 
        return ret;
index 63e6bc431a0d71fa5cc847d2637818db44cc211e..9bf088b1727592b256c5bafcc3bb6188310d2e0c 100644 (file)
@@ -27,7 +27,7 @@ static struct pcmcia_irqs irqs[] = {
 
 static int cerf_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 {
-       skt->irq = CERF_IRQ_GPIO_CF_IRQ;
+       skt->socket.pci_irq = CERF_IRQ_GPIO_CF_IRQ;
 
        return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
 }
index 2d0e997515308d931bb683d5f58ae8bd624ed5c3..11cc3ba1260ab6bf7763005a3436b85658fd524f 100644 (file)
@@ -83,7 +83,16 @@ static int sa11x0_drv_pcmcia_probe(struct platform_device *dev)
 
 static int sa11x0_drv_pcmcia_remove(struct platform_device *dev)
 {
-       return soc_common_drv_pcmcia_remove(&dev->dev);
+       struct skt_dev_info *sinfo = platform_get_drvdata(dev);
+       int i;
+
+       platform_set_drvdata(dev, NULL);
+
+       for (i = 0; i < sinfo->nskt; i++)
+               soc_pcmcia_remove_one(&sinfo->skt[i]);
+
+       kfree(sinfo);
+       return 0;
 }
 
 static int sa11x0_drv_pcmcia_suspend(struct platform_device *dev,
index 0cc3748f3758d866c0decfd9f7ce020c4cd97b39..3a121ac697d695712048ffc51bd29f4b71683c63 100644 (file)
@@ -25,8 +25,8 @@ static struct pcmcia_irqs irqs[] = {
 
 static int h3600_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 {
-       skt->irq = skt->nr ? IRQ_GPIO_H3600_PCMCIA_IRQ1
-                          : IRQ_GPIO_H3600_PCMCIA_IRQ0;
+       skt->socket.pci_irq = skt->nr ? IRQ_GPIO_H3600_PCMCIA_IRQ1
+                                     : IRQ_GPIO_H3600_PCMCIA_IRQ0;
 
 
        return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
index 7eedb42f800c1f4591c5f4aaa5b7aa6ada01be64..6bcabee6bde468f7dbd82b4f015d0063ea26d526 100644 (file)
 #define SOCKET1_POWER  (GPIO_GPIO1 | GPIO_GPIO3)
 #define SOCKET1_3V     GPIO_GPIO3
 
-static int jornada720_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
-{
-       unsigned int pin = GPIO_A0 | GPIO_A1 | GPIO_A2 | GPIO_A3;
-
-       /*
-       * What is all this crap for?
-       */
-       GRER |= 0x00000002;
-       /* Set GPIO_A<3:1> to be outputs for PCMCIA/CF power controller: */
-       sa1111_set_io_dir(SA1111_DEV(skt->dev), pin, 0, 0);
-       sa1111_set_io(SA1111_DEV(skt->dev), pin, 0);
-       sa1111_set_sleep_io(SA1111_DEV(skt->dev), pin, 0);
-
-       return sa1111_pcmcia_hw_init(skt);
-}
-
 static int
 jornada720_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state)
 {
+       struct sa1111_pcmcia_socket *s = to_skt(skt);
        unsigned int pa_dwr_mask, pa_dwr_set;
        int ret;
 
@@ -97,7 +82,7 @@ jornada720_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_s
                unsigned long flags;
 
                local_irq_save(flags);
-               sa1111_set_io(SA1111_DEV(skt->dev), pa_dwr_mask, pa_dwr_set);
+               sa1111_set_io(s->dev, pa_dwr_mask, pa_dwr_set);
                local_irq_restore(flags);
        }
 
@@ -106,21 +91,30 @@ jornada720_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_s
 
 static struct pcmcia_low_level jornada720_pcmcia_ops = {
        .owner                  = THIS_MODULE,
-       .hw_init                = jornada720_pcmcia_hw_init,
-       .hw_shutdown            = sa1111_pcmcia_hw_shutdown,
-       .socket_state           = sa1111_pcmcia_socket_state,
        .configure_socket       = jornada720_pcmcia_configure_socket,
-
        .socket_init            = sa1111_pcmcia_socket_init,
-       .socket_suspend         = sa1111_pcmcia_socket_suspend,
+       .first                  = 0,
+       .nr                     = 2,
 };
 
 int __devinit pcmcia_jornada720_init(struct device *dev)
 {
        int ret = -ENODEV;
 
-       if (machine_is_jornada720())
-               ret = sa11xx_drv_pcmcia_probe(dev, &jornada720_pcmcia_ops, 0, 2);
+       if (machine_is_jornada720()) {
+               unsigned int pin = GPIO_A0 | GPIO_A1 | GPIO_A2 | GPIO_A3;
+
+               GRER |= 0x00000002;
+
+               /* Set GPIO_A<3:1> to be outputs for PCMCIA/CF power controller: */
+               sa1111_set_io_dir(dev, pin, 0, 0);
+               sa1111_set_io(dev, pin, 0);
+               sa1111_set_sleep_io(dev, pin, 0);
+
+               sa11xx_drv_pcmcia_ops(&jornada720_pcmcia_ops);
+               ret = sa1111_pcmcia_add(dev, &jornada720_pcmcia_ops,
+                               sa11xx_drv_pcmcia_add_one);
+       }
 
        return ret;
 }
index 0c76d337815bca429b2ef094e19c01f1bd39e8a8..c95639b5f2a06095c9c586aebe80f0e1bed9fa8a 100644 (file)
@@ -43,6 +43,7 @@
 static int
 neponset_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state)
 {
+       struct sa1111_pcmcia_socket *s = to_skt(skt);
        unsigned int ncr_mask, ncr_set, pa_dwr_mask, pa_dwr_set;
        int ret;
 
@@ -99,7 +100,7 @@ neponset_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_sta
                NCR_0 = (NCR_0 & ~ncr_mask) | ncr_set;
 
                local_irq_restore(flags);
-               sa1111_set_io(SA1111_DEV(skt->dev), pa_dwr_mask, pa_dwr_set);
+               sa1111_set_io(s->dev, pa_dwr_mask, pa_dwr_set);
        }
 
        return 0;
@@ -115,12 +116,10 @@ static void neponset_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
 
 static struct pcmcia_low_level neponset_pcmcia_ops = {
        .owner                  = THIS_MODULE,
-       .hw_init                = sa1111_pcmcia_hw_init,
-       .hw_shutdown            = sa1111_pcmcia_hw_shutdown,
-       .socket_state           = sa1111_pcmcia_socket_state,
        .configure_socket       = neponset_pcmcia_configure_socket,
        .socket_init            = neponset_pcmcia_socket_init,
-       .socket_suspend         = sa1111_pcmcia_socket_suspend,
+       .first                  = 0,
+       .nr                     = 2,
 };
 
 int pcmcia_neponset_init(struct sa1111_dev *sadev)
@@ -135,7 +134,9 @@ int pcmcia_neponset_init(struct sa1111_dev *sadev)
                sa1111_set_io_dir(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0, 0);
                sa1111_set_io(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0);
                sa1111_set_sleep_io(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0);
-               ret = sa11xx_drv_pcmcia_probe(&sadev->dev, &neponset_pcmcia_ops, 0, 2);
+               sa11xx_drv_pcmcia_ops(&neponset_pcmcia_ops);
+               ret = sa1111_pcmcia_add(sadev, &neponset_pcmcia_ops,
+                               sa11xx_drv_pcmcia_add_one);
        }
 
        return ret;
index 46d8c1977c2a44592652fc4abfb9ce1aeb1ca3fa..c4d51867a050fa09703b469424d10d3a604c4971 100644 (file)
@@ -28,7 +28,7 @@ static int shannon_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
        GAFR &= ~(SHANNON_GPIO_EJECT_0 | SHANNON_GPIO_EJECT_1 | 
                  SHANNON_GPIO_RDY_0 | SHANNON_GPIO_RDY_1);
 
-       skt->irq = skt->nr ? SHANNON_IRQ_GPIO_RDY_1 : SHANNON_IRQ_GPIO_RDY_0;
+       skt->socket.pci_irq = skt->nr ? SHANNON_IRQ_GPIO_RDY_1 : SHANNON_IRQ_GPIO_RDY_0;
 
        return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
 }
index 33a08ae09fdfa7aec75ca698548fe46b8d0903ab..05bd504e6f18a47ff43c24d7bbba27c185ebe822 100644 (file)
@@ -28,7 +28,7 @@ static int simpad_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 
        clear_cs3_bit(VCC_3V_EN|VCC_5V_EN|EN0|EN1);
 
-       skt->irq = IRQ_GPIO_CF_IRQ;
+       skt->socket.pci_irq = IRQ_GPIO_CF_IRQ;
 
        return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
 }
index 4be4e172ffa180aebccd78bd0fa0e241e6b97f74..de6bc333d29907187137203392d659096c312b8b 100644 (file)
@@ -28,23 +28,20 @@ static struct pcmcia_irqs irqs[] = {
        { 1, IRQ_S1_BVD1_STSCHG, "SA1111 CF BVD1"            },
 };
 
-int sa1111_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
+static int sa1111_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
 {
-       if (skt->irq == NO_IRQ)
-               skt->irq = skt->nr ? IRQ_S1_READY_NINT : IRQ_S0_READY_NINT;
-
        return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
 }
 
-void sa1111_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
+static void sa1111_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
 {
        soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
 }
 
 void sa1111_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state)
 {
-       struct sa1111_dev *sadev = SA1111_DEV(skt->dev);
-       unsigned long status = sa1111_readl(sadev->mapbase + SA1111_PCSR);
+       struct sa1111_pcmcia_socket *s = to_skt(skt);
+       unsigned long status = sa1111_readl(s->dev->mapbase + SA1111_PCSR);
 
        switch (skt->nr) {
        case 0:
@@ -71,7 +68,7 @@ void sa1111_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_sta
 
 int sa1111_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state)
 {
-       struct sa1111_dev *sadev = SA1111_DEV(skt->dev);
+       struct sa1111_pcmcia_socket *s = to_skt(skt);
        unsigned int pccr_skt_mask, pccr_set_mask, val;
        unsigned long flags;
 
@@ -100,10 +97,10 @@ int sa1111_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_s
                pccr_set_mask |= PCCR_S0_FLT|PCCR_S1_FLT;
 
        local_irq_save(flags);
-       val = sa1111_readl(sadev->mapbase + SA1111_PCCR);
+       val = sa1111_readl(s->dev->mapbase + SA1111_PCCR);
        val &= ~pccr_skt_mask;
        val |= pccr_set_mask & pccr_skt_mask;
-       sa1111_writel(val, sadev->mapbase + SA1111_PCCR);
+       sa1111_writel(val, s->dev->mapbase + SA1111_PCCR);
        local_irq_restore(flags);
 
        return 0;
@@ -114,15 +111,51 @@ void sa1111_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
        soc_pcmcia_enable_irqs(skt, irqs, ARRAY_SIZE(irqs));
 }
 
-void sa1111_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
+static void sa1111_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
 {
        soc_pcmcia_disable_irqs(skt, irqs, ARRAY_SIZE(irqs));
 }
 
+int sa1111_pcmcia_add(struct sa1111_dev *dev, struct pcmcia_low_level *ops,
+       int (*add)(struct soc_pcmcia_socket *))
+{
+       struct sa1111_pcmcia_socket *s;
+       int i, ret = 0;
+
+       ops->hw_init = sa1111_pcmcia_hw_init;
+       ops->hw_shutdown = sa1111_pcmcia_hw_shutdown;
+       ops->socket_state = sa1111_pcmcia_socket_state;
+       ops->socket_suspend = sa1111_pcmcia_socket_suspend;
+
+       for (i = 0; i < ops->nr; i++) {
+               s = kzalloc(sizeof(*s), GFP_KERNEL);
+               if (!s)
+                       return -ENOMEM;
+
+               s->soc.nr = ops->first + i;
+               s->soc.ops = ops;
+               s->soc.socket.owner = ops->owner;
+               s->soc.socket.dev.parent = &dev->dev;
+               s->soc.socket.pci_irq = s->soc.nr ? IRQ_S1_READY_NINT : IRQ_S0_READY_NINT;
+               s->dev = dev;
+
+               ret = add(&s->soc);
+               if (ret == 0) {
+                       s->next = dev_get_drvdata(&dev->dev);
+                       dev_set_drvdata(&dev->dev, s);
+               } else
+                       kfree(s);
+       }
+
+       return ret;
+}
+
 static int pcmcia_probe(struct sa1111_dev *dev)
 {
        void __iomem *base;
 
+       dev_set_drvdata(&dev->dev, NULL);
+
        if (!request_mem_region(dev->res.start, 512,
                                SA1111_DRIVER_NAME(dev)))
                return -EBUSY;
@@ -152,7 +185,15 @@ static int pcmcia_probe(struct sa1111_dev *dev)
 
 static int __devexit pcmcia_remove(struct sa1111_dev *dev)
 {
-       soc_common_drv_pcmcia_remove(&dev->dev);
+       struct sa1111_pcmcia_socket *next, *s = dev_get_drvdata(&dev->dev);
+
+       dev_set_drvdata(&dev->dev, NULL);
+
+       for (; next = s->next, s; s = next) {
+               soc_pcmcia_remove_one(&s->soc);
+               kfree(s);
+       }
+
        release_mem_region(dev->res.start, 512);
        return 0;
 }
index 10ced4a210d7b18ac967ee8a2598d889efb5936f..02dc8577cdafcaa9f5b9dd09a6fd5948d60e35a1 100644 (file)
@@ -1,12 +1,23 @@
 #include "soc_common.h"
 #include "sa11xx_base.h"
 
-extern int sa1111_pcmcia_hw_init(struct soc_pcmcia_socket *);
-extern void sa1111_pcmcia_hw_shutdown(struct soc_pcmcia_socket *);
+struct sa1111_pcmcia_socket {
+       struct soc_pcmcia_socket soc;
+       struct sa1111_dev *dev;
+       struct sa1111_pcmcia_socket *next;
+};
+
+static inline struct sa1111_pcmcia_socket *to_skt(struct soc_pcmcia_socket *s)
+{
+       return container_of(s, struct sa1111_pcmcia_socket, soc);
+}
+
+int sa1111_pcmcia_add(struct sa1111_dev *dev, struct pcmcia_low_level *ops,
+       int (*add)(struct soc_pcmcia_socket *));
+
 extern void sa1111_pcmcia_socket_state(struct soc_pcmcia_socket *, struct pcmcia_state *);
 extern int sa1111_pcmcia_configure_socket(struct soc_pcmcia_socket *, const socket_state_t *);
 extern void sa1111_pcmcia_socket_init(struct soc_pcmcia_socket *);
-extern void sa1111_pcmcia_socket_suspend(struct soc_pcmcia_socket *);
 
 extern int pcmcia_badge4_init(struct device *);
 extern int pcmcia_jornada720_init(struct device *);
index e15d59f2d8a90f76f0b1e1a55e377956f8801f18..fc9a6527019b033d21a3d234cc09b2d0c29b792d 100644 (file)
@@ -171,12 +171,58 @@ static const char *skt_names[] = {
 #define SKT_DEV_INFO_SIZE(n) \
        (sizeof(struct skt_dev_info) + (n)*sizeof(struct soc_pcmcia_socket))
 
+int sa11xx_drv_pcmcia_add_one(struct soc_pcmcia_socket *skt)
+{
+       skt->res_skt.start = _PCMCIA(skt->nr);
+       skt->res_skt.end = _PCMCIA(skt->nr) + PCMCIASp - 1;
+       skt->res_skt.name = skt_names[skt->nr];
+       skt->res_skt.flags = IORESOURCE_MEM;
+
+       skt->res_io.start = _PCMCIAIO(skt->nr);
+       skt->res_io.end = _PCMCIAIO(skt->nr) + PCMCIAIOSp - 1;
+       skt->res_io.name = "io";
+       skt->res_io.flags = IORESOURCE_MEM | IORESOURCE_BUSY;
+
+       skt->res_mem.start = _PCMCIAMem(skt->nr);
+       skt->res_mem.end = _PCMCIAMem(skt->nr) + PCMCIAMemSp - 1;
+       skt->res_mem.name = "memory";
+       skt->res_mem.flags = IORESOURCE_MEM;
+
+       skt->res_attr.start = _PCMCIAAttr(skt->nr);
+       skt->res_attr.end = _PCMCIAAttr(skt->nr) + PCMCIAAttrSp - 1;
+       skt->res_attr.name = "attribute";
+       skt->res_attr.flags = IORESOURCE_MEM;
+
+       return soc_pcmcia_add_one(skt);
+}
+EXPORT_SYMBOL(sa11xx_drv_pcmcia_add_one);
+
+void sa11xx_drv_pcmcia_ops(struct pcmcia_low_level *ops)
+{
+       /*
+        * set default MECR calculation if the board specific
+        * code did not specify one...
+        */
+       if (!ops->get_timing)
+               ops->get_timing = sa1100_pcmcia_default_mecr_timing;
+
+       /* Provide our SA11x0 specific timing routines. */
+       ops->set_timing  = sa1100_pcmcia_set_timing;
+       ops->show_timing = sa1100_pcmcia_show_timing;
+#ifdef CONFIG_CPU_FREQ
+       ops->frequency_change = sa1100_pcmcia_frequency_change;
+#endif
+}
+EXPORT_SYMBOL(sa11xx_drv_pcmcia_ops);
+
 int sa11xx_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops,
                            int first, int nr)
 {
        struct skt_dev_info *sinfo;
        struct soc_pcmcia_socket *skt;
-       int i;
+       int i, ret = 0;
+
+       sa11xx_drv_pcmcia_ops(ops);
 
        sinfo = kzalloc(SKT_DEV_INFO_SIZE(nr), GFP_KERNEL);
        if (!sinfo)
@@ -188,45 +234,26 @@ int sa11xx_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops,
        for (i = 0; i < nr; i++) {
                skt = &sinfo->skt[i];
 
-               skt->nr         = first + i;
-               skt->irq        = NO_IRQ;
-
-               skt->res_skt.start      = _PCMCIA(skt->nr);
-               skt->res_skt.end        = _PCMCIA(skt->nr) + PCMCIASp - 1;
-               skt->res_skt.name       = skt_names[skt->nr];
-               skt->res_skt.flags      = IORESOURCE_MEM;
-
-               skt->res_io.start       = _PCMCIAIO(skt->nr);
-               skt->res_io.end         = _PCMCIAIO(skt->nr) + PCMCIAIOSp - 1;
-               skt->res_io.name        = "io";
-               skt->res_io.flags       = IORESOURCE_MEM | IORESOURCE_BUSY;
+               skt->nr = first + i;
+               skt->ops = ops;
+               skt->socket.owner = ops->owner;
+               skt->socket.dev.parent = dev;
+               skt->socket.pci_irq = NO_IRQ;
 
-               skt->res_mem.start      = _PCMCIAMem(skt->nr);
-               skt->res_mem.end        = _PCMCIAMem(skt->nr) + PCMCIAMemSp - 1;
-               skt->res_mem.name       = "memory";
-               skt->res_mem.flags      = IORESOURCE_MEM;
-
-               skt->res_attr.start     = _PCMCIAAttr(skt->nr);
-               skt->res_attr.end       = _PCMCIAAttr(skt->nr) + PCMCIAAttrSp - 1;
-               skt->res_attr.name      = "attribute";
-               skt->res_attr.flags     = IORESOURCE_MEM;
+               ret = sa11xx_drv_pcmcia_add_one(skt);
+               if (ret)
+                       break;
        }
 
-       /*
-        * set default MECR calculation if the board specific
-        * code did not specify one...
-        */
-       if (!ops->get_timing)
-               ops->get_timing = sa1100_pcmcia_default_mecr_timing;
-
-       /* Provide our SA11x0 specific timing routines. */
-       ops->set_timing  = sa1100_pcmcia_set_timing;
-       ops->show_timing = sa1100_pcmcia_show_timing;
-#ifdef CONFIG_CPU_FREQ
-       ops->frequency_change = sa1100_pcmcia_frequency_change;
-#endif
+       if (ret) {
+               while (--i >= 0)
+                       soc_pcmcia_remove_one(&sinfo->skt[i]);
+               kfree(sinfo);
+       } else {
+               dev_set_drvdata(dev, sinfo);
+       }
 
-       return soc_common_drv_pcmcia_probe(dev, ops, sinfo);
+       return ret;
 }
 EXPORT_SYMBOL(sa11xx_drv_pcmcia_probe);
 
index 7bc208280527884ad8f9774abdb18965857bca11..3d76d720f463de5628e8c1427505cc84bb1a0dbe 100644 (file)
@@ -118,6 +118,8 @@ static inline unsigned int sa1100_pcmcia_cmd_time(unsigned int cpu_clock_khz,
 }
 
 
+int sa11xx_drv_pcmcia_add_one(struct soc_pcmcia_socket *skt);
+void sa11xx_drv_pcmcia_ops(struct pcmcia_low_level *ops);
 extern int sa11xx_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops, int first, int nr);
 
 #endif  /* !defined(_PCMCIA_SA1100_H) */
index ef7e9e58782b2328c66ab14d4b563656ee3a84a2..6f1a86b43c606ac5e21b9353363da911cc53c314 100644 (file)
@@ -144,10 +144,10 @@ soc_common_pcmcia_config_skt(struct soc_pcmcia_socket *skt, socket_state_t *stat
                 */
                if (skt->irq_state != 1 && state->io_irq) {
                        skt->irq_state = 1;
-                       set_irq_type(skt->irq, IRQ_TYPE_EDGE_FALLING);
+                       set_irq_type(skt->socket.pci_irq, IRQ_TYPE_EDGE_FALLING);
                } else if (skt->irq_state == 1 && state->io_irq == 0) {
                        skt->irq_state = 0;
-                       set_irq_type(skt->irq, IRQ_TYPE_NONE);
+                       set_irq_type(skt->socket.pci_irq, IRQ_TYPE_NONE);
                }
 
                skt->cs_state = *state;
@@ -492,7 +492,8 @@ static ssize_t show_status(struct device *dev, struct device_attribute *attr, ch
 
        p+=sprintf(p, "Vcc      : %d\n", skt->cs_state.Vcc);
        p+=sprintf(p, "Vpp      : %d\n", skt->cs_state.Vpp);
-       p+=sprintf(p, "IRQ      : %d (%d)\n", skt->cs_state.io_irq, skt->irq);
+       p+=sprintf(p, "IRQ      : %d (%d)\n", skt->cs_state.io_irq,
+               skt->socket.pci_irq);
        if (skt->ops->show_timing)
                p+=skt->ops->show_timing(skt, p);
 
@@ -574,7 +575,7 @@ void soc_pcmcia_enable_irqs(struct soc_pcmcia_socket *skt,
 EXPORT_SYMBOL(soc_pcmcia_enable_irqs);
 
 
-LIST_HEAD(soc_pcmcia_sockets);
+static LIST_HEAD(soc_pcmcia_sockets);
 static DEFINE_MUTEX(soc_pcmcia_sockets_lock);
 
 #ifdef CONFIG_CPU_FREQ
@@ -609,177 +610,137 @@ static int soc_pcmcia_cpufreq_register(void)
                                "notifier for PCMCIA (%d)\n", ret);
        return ret;
 }
+fs_initcall(soc_pcmcia_cpufreq_register);
 
 static void soc_pcmcia_cpufreq_unregister(void)
 {
        cpufreq_unregister_notifier(&soc_pcmcia_notifier_block, CPUFREQ_TRANSITION_NOTIFIER);
 }
+module_exit(soc_pcmcia_cpufreq_unregister);
 
-#else
-static int soc_pcmcia_cpufreq_register(void) { return 0; }
-static void soc_pcmcia_cpufreq_unregister(void) {}
 #endif
 
-int soc_common_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops,
-                               struct skt_dev_info *sinfo)
+void soc_pcmcia_remove_one(struct soc_pcmcia_socket *skt)
 {
-       struct soc_pcmcia_socket *skt;
-       int ret, i;
-
        mutex_lock(&soc_pcmcia_sockets_lock);
+       del_timer_sync(&skt->poll_timer);
 
-       /*
-        * Initialise the per-socket structure.
-        */
-       for (i = 0; i < sinfo->nskt; i++) {
-               skt = &sinfo->skt[i];
+       pcmcia_unregister_socket(&skt->socket);
 
-               skt->socket.ops = &soc_common_pcmcia_operations;
-               skt->socket.owner = ops->owner;
-               skt->socket.dev.parent = dev;
+       flush_scheduled_work();
 
-               init_timer(&skt->poll_timer);
-               skt->poll_timer.function = soc_common_pcmcia_poll_event;
-               skt->poll_timer.data = (unsigned long)skt;
-               skt->poll_timer.expires = jiffies + SOC_PCMCIA_POLL_PERIOD;
+       skt->ops->hw_shutdown(skt);
 
-               skt->dev        = dev;
-               skt->ops        = ops;
+       soc_common_pcmcia_config_skt(skt, &dead_socket);
 
-               ret = request_resource(&iomem_resource, &skt->res_skt);
-               if (ret)
-                       goto out_err_1;
+       list_del(&skt->node);
+       mutex_unlock(&soc_pcmcia_sockets_lock);
 
-               ret = request_resource(&skt->res_skt, &skt->res_io);
-               if (ret)
-                       goto out_err_2;
+       iounmap(skt->virt_io);
+       skt->virt_io = NULL;
+       release_resource(&skt->res_attr);
+       release_resource(&skt->res_mem);
+       release_resource(&skt->res_io);
+       release_resource(&skt->res_skt);
+}
+EXPORT_SYMBOL(soc_pcmcia_remove_one);
 
-               ret = request_resource(&skt->res_skt, &skt->res_mem);
-               if (ret)
-                       goto out_err_3;
+int soc_pcmcia_add_one(struct soc_pcmcia_socket *skt)
+{
+       int ret;
 
-               ret = request_resource(&skt->res_skt, &skt->res_attr);
-               if (ret)
-                       goto out_err_4;
+       init_timer(&skt->poll_timer);
+       skt->poll_timer.function = soc_common_pcmcia_poll_event;
+       skt->poll_timer.data = (unsigned long)skt;
+       skt->poll_timer.expires = jiffies + SOC_PCMCIA_POLL_PERIOD;
 
-               skt->virt_io = ioremap(skt->res_io.start, 0x10000);
-               if (skt->virt_io == NULL) {
-                       ret = -ENOMEM;
-                       goto out_err_5;
-               }
+       ret = request_resource(&iomem_resource, &skt->res_skt);
+       if (ret)
+               goto out_err_1;
 
-               if (list_empty(&soc_pcmcia_sockets))
-                       soc_pcmcia_cpufreq_register();
+       ret = request_resource(&skt->res_skt, &skt->res_io);
+       if (ret)
+               goto out_err_2;
 
-               list_add(&skt->node, &soc_pcmcia_sockets);
+       ret = request_resource(&skt->res_skt, &skt->res_mem);
+       if (ret)
+               goto out_err_3;
 
-               /*
-                * We initialize default socket timing here, because
-                * we are not guaranteed to see a SetIOMap operation at
-                * runtime.
-                */
-               ops->set_timing(skt);
+       ret = request_resource(&skt->res_skt, &skt->res_attr);
+       if (ret)
+               goto out_err_4;
 
-               ret = ops->hw_init(skt);
-               if (ret)
-                       goto out_err_6;
+       skt->virt_io = ioremap(skt->res_io.start, 0x10000);
+       if (skt->virt_io == NULL) {
+               ret = -ENOMEM;
+               goto out_err_5;
+       }
 
-               skt->socket.features = SS_CAP_STATIC_MAP|SS_CAP_PCCARD;
-               skt->socket.resource_ops = &pccard_static_ops;
-               skt->socket.irq_mask = 0;
-               skt->socket.map_size = PAGE_SIZE;
-               skt->socket.pci_irq = skt->irq;
-               skt->socket.io_offset = (unsigned long)skt->virt_io;
+       mutex_lock(&soc_pcmcia_sockets_lock);
 
-               skt->status = soc_common_pcmcia_skt_state(skt);
+       list_add(&skt->node, &soc_pcmcia_sockets);
 
-               ret = pcmcia_register_socket(&skt->socket);
-               if (ret)
-                       goto out_err_7;
+       /*
+        * We initialize default socket timing here, because
+        * we are not guaranteed to see a SetIOMap operation at
+        * runtime.
+        */
+       skt->ops->set_timing(skt);
 
-               WARN_ON(skt->socket.sock != i);
+       ret = skt->ops->hw_init(skt);
+       if (ret)
+               goto out_err_6;
 
-               add_timer(&skt->poll_timer);
+       skt->socket.ops = &soc_common_pcmcia_operations;
+       skt->socket.features = SS_CAP_STATIC_MAP|SS_CAP_PCCARD;
+       skt->socket.resource_ops = &pccard_static_ops;
+       skt->socket.irq_mask = 0;
+       skt->socket.map_size = PAGE_SIZE;
+       skt->socket.io_offset = (unsigned long)skt->virt_io;
 
-               ret = device_create_file(&skt->socket.dev, &dev_attr_status);
-               if (ret)
-                       goto out_err_8;
-       }
+       skt->status = soc_common_pcmcia_skt_state(skt);
 
-       dev_set_drvdata(dev, sinfo);
-       ret = 0;
-       goto out;
+       ret = pcmcia_register_socket(&skt->socket);
+       if (ret)
+               goto out_err_7;
 
-       do {
-               skt = &sinfo->skt[i];
+       add_timer(&skt->poll_timer);
+
+       mutex_unlock(&soc_pcmcia_sockets_lock);
+
+       ret = device_create_file(&skt->socket.dev, &dev_attr_status);
+       if (ret)
+               goto out_err_8;
+
+       return ret;
 
-               device_remove_file(&skt->socket.dev, &dev_attr_status);
  out_err_8:
-               del_timer_sync(&skt->poll_timer);
-               pcmcia_unregister_socket(&skt->socket);
+       mutex_lock(&soc_pcmcia_sockets_lock);
+       del_timer_sync(&skt->poll_timer);
+       pcmcia_unregister_socket(&skt->socket);
 
  out_err_7:
-               flush_scheduled_work();
+       flush_scheduled_work();
 
-               ops->hw_shutdown(skt);
+       skt->ops->hw_shutdown(skt);
  out_err_6:
-               list_del(&skt->node);
-               iounmap(skt->virt_io);
+       list_del(&skt->node);
+       mutex_unlock(&soc_pcmcia_sockets_lock);
+       iounmap(skt->virt_io);
  out_err_5:
-               release_resource(&skt->res_attr);
+       release_resource(&skt->res_attr);
  out_err_4:
-               release_resource(&skt->res_mem);
+       release_resource(&skt->res_mem);
  out_err_3:
-               release_resource(&skt->res_io);
+       release_resource(&skt->res_io);
  out_err_2:
-               release_resource(&skt->res_skt);
+       release_resource(&skt->res_skt);
  out_err_1:
-               i--;
-       } while (i > 0);
 
-       kfree(sinfo);
-
- out:
-       mutex_unlock(&soc_pcmcia_sockets_lock);
        return ret;
 }
+EXPORT_SYMBOL(soc_pcmcia_add_one);
 
-int soc_common_drv_pcmcia_remove(struct device *dev)
-{
-       struct skt_dev_info *sinfo = dev_get_drvdata(dev);
-       int i;
-
-       dev_set_drvdata(dev, NULL);
-
-       mutex_lock(&soc_pcmcia_sockets_lock);
-       for (i = 0; i < sinfo->nskt; i++) {
-               struct soc_pcmcia_socket *skt = &sinfo->skt[i];
-
-               del_timer_sync(&skt->poll_timer);
-
-               pcmcia_unregister_socket(&skt->socket);
-
-               flush_scheduled_work();
-
-               skt->ops->hw_shutdown(skt);
-
-               soc_common_pcmcia_config_skt(skt, &dead_socket);
-
-               list_del(&skt->node);
-               iounmap(skt->virt_io);
-               skt->virt_io = NULL;
-               release_resource(&skt->res_attr);
-               release_resource(&skt->res_mem);
-               release_resource(&skt->res_io);
-               release_resource(&skt->res_skt);
-       }
-       if (list_empty(&soc_pcmcia_sockets))
-               soc_pcmcia_cpufreq_unregister();
-
-       mutex_unlock(&soc_pcmcia_sockets_lock);
-
-       kfree(sinfo);
-
-       return 0;
-}
-EXPORT_SYMBOL(soc_common_drv_pcmcia_remove);
+MODULE_AUTHOR("John Dorsey <john+@cs.cmu.edu>");
+MODULE_DESCRIPTION("Linux PCMCIA Card Services: Common SoC support");
+MODULE_LICENSE("Dual MPL/GPL");
index 290e143839ee68802e29ee2688eb31270ddf5f00..e40824ce6b0b2f0960be487acb8cedb3e01cb9fb 100644 (file)
@@ -30,14 +30,12 @@ struct soc_pcmcia_socket {
        /*
         * Info from low level handler
         */
-       struct device           *dev;
        unsigned int            nr;
-       unsigned int            irq;
 
        /*
         * Core PCMCIA state
         */
-       struct pcmcia_low_level *ops;
+       const struct pcmcia_low_level *ops;
 
        unsigned int            status;
        socket_state_t          cs_state;
@@ -135,10 +133,8 @@ extern void soc_pcmcia_enable_irqs(struct soc_pcmcia_socket *skt, struct pcmcia_
 extern void soc_common_pcmcia_get_timing(struct soc_pcmcia_socket *, struct soc_pcmcia_timing *);
 
 
-extern struct list_head soc_pcmcia_sockets;
-
-extern int soc_common_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops, struct skt_dev_info *sinfo);
-extern int soc_common_drv_pcmcia_remove(struct device *dev);
+void soc_pcmcia_remove_one(struct soc_pcmcia_socket *skt);
+int soc_pcmcia_add_one(struct soc_pcmcia_socket *skt);
 
 
 #ifdef CONFIG_PCMCIA_DEBUG
index 6918849d511ec3f447bd5f536e75a91dc61e83ec..12c49ee135e1edb36ce47a17d06f3be9ee2fe822 100644 (file)
 #include <pcmcia/ss.h>
 #include "tcic.h"
 
-#ifdef CONFIG_PCMCIA_DEBUG
-static int pc_debug;
-
-module_param(pc_debug, int, 0644);
-static const char version[] =
-"tcic.c 1.111 2000/02/15 04:13:12 (David Hinds)";
-
-#define debug(lvl, fmt, arg...) do {                           \
-       if (pc_debug > (lvl))                                   \
-               printk(KERN_DEBUG "tcic: " fmt , ## arg);       \
-} while (0)
-#else
-#define debug(lvl, fmt, arg...) do { } while (0)
-#endif
-
 MODULE_AUTHOR("David Hinds <dahinds@users.sourceforge.net>");
 MODULE_DESCRIPTION("Databook TCIC-2 PCMCIA socket driver");
 MODULE_LICENSE("Dual MPL/GPL");
@@ -574,7 +559,7 @@ static irqreturn_t tcic_interrupt(int irq, void *dev)
     } else
        active = 1;
 
-    debug(2, "tcic_interrupt()\n");
+    pr_debug("tcic_interrupt()\n");
     
     for (i = 0; i < sockets; i++) {
        psock = socket_table[i].psock;
@@ -611,13 +596,13 @@ static irqreturn_t tcic_interrupt(int irq, void *dev)
     }
     active = 0;
     
-    debug(2, "interrupt done\n");
+    pr_debug("interrupt done\n");
     return IRQ_HANDLED;
 } /* tcic_interrupt */
 
 static void tcic_timer(u_long data)
 {
-    debug(2, "tcic_timer()\n");
+    pr_debug("tcic_timer()\n");
     tcic_timer_pending = 0;
     tcic_interrupt(0, NULL);
 } /* tcic_timer */
@@ -644,7 +629,7 @@ static int tcic_get_status(struct pcmcia_socket *sock, u_int *value)
     reg = tcic_getb(TCIC_PWR);
     if (reg & (TCIC_PWR_VCC(psock)|TCIC_PWR_VPP(psock)))
        *value |= SS_POWERON;
-    debug(1, "GetStatus(%d) = %#2.2x\n", psock, *value);
+    dev_dbg(&sock->dev, "GetStatus(%d) = %#2.2x\n", psock, *value);
     return 0;
 } /* tcic_get_status */
 
@@ -656,7 +641,7 @@ static int tcic_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
     u_char reg;
     u_short scf1, scf2;
 
-    debug(1, "SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
+    dev_dbg(&sock->dev, "SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
          "io_irq %d, csc_mask %#2.2x)\n", psock, state->flags,
          state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
     tcic_setw(TCIC_ADDR+2, (psock << TCIC_SS_SHFT) | TCIC_ADR2_INDREG);
@@ -731,7 +716,7 @@ static int tcic_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *io)
     u_int addr;
     u_short base, len, ioctl;
     
-    debug(1, "SetIOMap(%d, %d, %#2.2x, %d ns, "
+    dev_dbg(&sock->dev, "SetIOMap(%d, %d, %#2.2x, %d ns, "
          "%#llx-%#llx)\n", psock, io->map, io->flags, io->speed,
          (unsigned long long)io->start, (unsigned long long)io->stop);
     if ((io->map > 1) || (io->start > 0xffff) || (io->stop > 0xffff) ||
@@ -768,7 +753,7 @@ static int tcic_set_mem_map(struct pcmcia_socket *sock, struct pccard_mem_map *m
     u_short addr, ctl;
     u_long base, len, mmap;
 
-    debug(1, "SetMemMap(%d, %d, %#2.2x, %d ns, "
+    dev_dbg(&sock->dev, "SetMemMap(%d, %d, %#2.2x, %d ns, "
          "%#llx-%#llx, %#x)\n", psock, mem->map, mem->flags,
          mem->speed, (unsigned long long)mem->res->start,
          (unsigned long long)mem->res->end, mem->card_start);
index edccfa5bb40087b0a0b9cbefae7bdbae5d781348..615a45a8fe8674fe4d920d87884bde653f2e3b3a 100644 (file)
@@ -114,22 +114,17 @@ static void topic97_zoom_video(struct pcmcia_socket *sock, int onoff)
                reg_zv |= TOPIC97_ZV_CONTROL_ENABLE;
                config_writeb(socket, TOPIC97_ZOOM_VIDEO_CONTROL, reg_zv);
 
-               reg = config_readb(socket, TOPIC97_MISC2);
-               reg |= TOPIC97_MISC2_ZV_ENABLE;
-               config_writeb(socket, TOPIC97_MISC2, reg);
-
-               /* not sure this is needed, doc is unclear */
-#if 0
                reg = config_readb(socket, TOPIC97_AUDIO_VIDEO_SWITCH);
                reg |= TOPIC97_AVS_AUDIO_CONTROL | TOPIC97_AVS_VIDEO_CONTROL;
                config_writeb(socket, TOPIC97_AUDIO_VIDEO_SWITCH, reg);
-#endif
-       }
-       else {
+       } else {
                reg_zv &= ~TOPIC97_ZV_CONTROL_ENABLE;
                config_writeb(socket, TOPIC97_ZOOM_VIDEO_CONTROL, reg_zv);
-       }
 
+               reg = config_readb(socket, TOPIC97_AUDIO_VIDEO_SWITCH);
+               reg &= ~(TOPIC97_AVS_AUDIO_CONTROL | TOPIC97_AVS_VIDEO_CONTROL);
+               config_writeb(socket, TOPIC97_AUDIO_VIDEO_SWITCH, reg);
+       }
 }
 
 static int topic97_override(struct yenta_socket *socket)
index 0a8f735f6c4a9fd4f79b79ef1c341a6b247be73b..ab64522aaa6433df3e1fcb3c2d92c5633d2c72ad 100644 (file)
@@ -52,7 +52,7 @@
  */
 #undef START_IN_KERNEL_MODE
 
-#define DRV_VER "0.5.17"
+#define DRV_VER "0.5.18"
 
 /*
  * According to the Atom N270 datasheet,
@@ -61,7 +61,7 @@
  * measured by the on-die thermal monitor are within 0 <= Tj <= 90. So,
  * assume 89°C is critical temperature.
  */
-#define ACERHDF_TEMP_CRIT 89
+#define ACERHDF_TEMP_CRIT 89000
 #define ACERHDF_FAN_OFF 0
 #define ACERHDF_FAN_AUTO 1
 
@@ -69,7 +69,7 @@
  * No matter what value the user puts into the fanon variable, turn on the fan
  * at 80 degree Celsius to prevent hardware damage
  */
-#define ACERHDF_MAX_FANON 80
+#define ACERHDF_MAX_FANON 80000
 
 /*
  * Maximum interval between two temperature checks is 15 seconds, as the die
@@ -85,8 +85,8 @@ static int kernelmode;
 #endif
 
 static unsigned int interval = 10;
-static unsigned int fanon = 63;
-static unsigned int fanoff = 58;
+static unsigned int fanon = 63000;
+static unsigned int fanoff = 58000;
 static unsigned int verbose;
 static unsigned int fanstate = ACERHDF_FAN_AUTO;
 static char force_bios[16];
@@ -171,7 +171,7 @@ static int acerhdf_get_temp(int *temp)
        if (ec_read(bios_cfg->tempreg, &read_temp))
                return -EINVAL;
 
-       *temp = read_temp;
+       *temp = read_temp * 1000;
 
        return 0;
 }
index d93108d148fc14cebff5ca14202ff161bb3551b0..a848c7e20aeb1895faee46832b3d34811ae92d92 100644 (file)
@@ -1680,36 +1680,48 @@ static void tpacpi_remove_driver_attributes(struct device_driver *drv)
                          | (__bv1) << 8 | (__bv2) }
 
 #define TPV_Q_X(__v, __bid1, __bid2, __bv1, __bv2,     \
-               __eid1, __eid2, __ev1, __ev2)           \
+               __eid, __ev1, __ev2)                    \
        { .vendor       = (__v),                        \
          .bios         = TPID(__bid1, __bid2),         \
-         .ec           = TPID(__eid1, __eid2),         \
+         .ec           = __eid,                        \
          .quirks       = (__ev1) << 24 | (__ev2) << 16 \
                          | (__bv1) << 8 | (__bv2) }
 
 #define TPV_QI0(__id1, __id2, __bv1, __bv2) \
        TPV_Q(PCI_VENDOR_ID_IBM, __id1, __id2, __bv1, __bv2)
 
+/* Outdated IBM BIOSes often lack the EC id string */
 #define TPV_QI1(__id1, __id2, __bv1, __bv2, __ev1, __ev2) \
        TPV_Q_X(PCI_VENDOR_ID_IBM, __id1, __id2,        \
-               __bv1, __bv2, __id1, __id2, __ev1, __ev2)
+               __bv1, __bv2, TPID(__id1, __id2),       \
+               __ev1, __ev2),                          \
+       TPV_Q_X(PCI_VENDOR_ID_IBM, __id1, __id2,        \
+               __bv1, __bv2, TPACPI_MATCH_UNKNOWN,     \
+               __ev1, __ev2)
 
+/* Outdated IBM BIOSes often lack the EC id string */
 #define TPV_QI2(__bid1, __bid2, __bv1, __bv2,          \
                __eid1, __eid2, __ev1, __ev2)           \
        TPV_Q_X(PCI_VENDOR_ID_IBM, __bid1, __bid2,      \
-               __bv1, __bv2, __eid1, __eid2, __ev1, __ev2)
+               __bv1, __bv2, TPID(__eid1, __eid2),     \
+               __ev1, __ev2),                          \
+       TPV_Q_X(PCI_VENDOR_ID_IBM, __bid1, __bid2,      \
+               __bv1, __bv2, TPACPI_MATCH_UNKNOWN,     \
+               __ev1, __ev2)
 
 #define TPV_QL0(__id1, __id2, __bv1, __bv2) \
        TPV_Q(PCI_VENDOR_ID_LENOVO, __id1, __id2, __bv1, __bv2)
 
 #define TPV_QL1(__id1, __id2, __bv1, __bv2, __ev1, __ev2) \
        TPV_Q_X(PCI_VENDOR_ID_LENOVO, __id1, __id2,     \
-               __bv1, __bv2, __id1, __id2, __ev1, __ev2)
+               __bv1, __bv2, TPID(__id1, __id2),       \
+               __ev1, __ev2)
 
 #define TPV_QL2(__bid1, __bid2, __bv1, __bv2,          \
                __eid1, __eid2, __ev1, __ev2)           \
        TPV_Q_X(PCI_VENDOR_ID_LENOVO, __bid1, __bid2,   \
-               __bv1, __bv2, __eid1, __eid2, __ev1, __ev2)
+               __bv1, __bv2, TPID(__eid1, __eid2),     \
+               __ev1, __ev2)
 
 static const struct tpacpi_quirk tpacpi_bios_version_qtable[] __initconst = {
        /*  Numeric models ------------------ */
@@ -6313,7 +6325,7 @@ static int brightness_write(char *buf)
         * Doing it this way makes the syscall restartable in case of EINTR
         */
        rc = brightness_set(level);
-       return (rc == -EINTR)? ERESTARTSYS : rc;
+       return (rc == -EINTR)? -ERESTARTSYS : rc;
 }
 
 static struct ibm_struct brightness_driver_data = {
index 744ea1d0b59bf084f19559b8f199b644fbb0899c..efe568deda12b7710e882e07d81388af9053e484 100644 (file)
@@ -1283,7 +1283,8 @@ static int _regulator_disable(struct regulator_dev *rdev)
                return -EIO;
 
        /* are we the last user and permitted to disable ? */
-       if (rdev->use_count == 1 && !rdev->constraints->always_on) {
+       if (rdev->use_count == 1 &&
+           (rdev->constraints && !rdev->constraints->always_on)) {
 
                /* we are last user */
                if (_regulator_can_change_status(rdev) &&
index f8b295700d7d706e6a19d6f273e34a149d49e897..f9f516a3028aa219a9dee0b397fc7e85fd54888d 100644 (file)
@@ -196,11 +196,10 @@ static int regulator_fixed_voltage_remove(struct platform_device *pdev)
        struct fixed_voltage_data *drvdata = platform_get_drvdata(pdev);
 
        regulator_unregister(drvdata->dev);
-       kfree(drvdata->desc.name);
-       kfree(drvdata);
-
        if (gpio_is_valid(drvdata->gpio))
                gpio_free(drvdata->gpio);
+       kfree(drvdata->desc.name);
+       kfree(drvdata);
 
        return 0;
 }
index 1d8d9879d3a1bacb6d73b0d6729ff8d18d65bd25..48857008758cc96248b38cccc24a05754bd5197d 100644 (file)
@@ -167,6 +167,8 @@ static __devinit int wm831x_isink_probe(struct platform_device *pdev)
                return -ENOMEM;
        }
 
+       isink->wm831x = wm831x;
+
        res = platform_get_resource(pdev, IORESOURCE_IO, 0);
        if (res == NULL) {
                dev_err(&pdev->dev, "No I/O resource\n");
index bb61aede48010ec20e4b2b52e3c6bae6a9d91c18..902db56ce099676f6a2a3f2483dd0d7b3c75811f 100644 (file)
@@ -175,18 +175,18 @@ static unsigned int wm831x_gp_ldo_get_mode(struct regulator_dev *rdev)
        struct wm831x *wm831x = ldo->wm831x;
        int ctrl_reg = ldo->base + WM831X_LDO_CONTROL;
        int on_reg = ldo->base + WM831X_LDO_ON_CONTROL;
-       unsigned int ret;
+       int ret;
 
        ret = wm831x_reg_read(wm831x, on_reg);
        if (ret < 0)
-               return 0;
+               return ret;
 
        if (!(ret & WM831X_LDO1_ON_MODE))
                return REGULATOR_MODE_NORMAL;
 
        ret = wm831x_reg_read(wm831x, ctrl_reg);
        if (ret < 0)
-               return 0;
+               return ret;
 
        if (ret & WM831X_LDO1_LP_MODE)
                return REGULATOR_MODE_STANDBY;
index 7fe1fa26c52c5e202287db14ea5cf2551f7031e2..03ea530981d1e66328625fb26567cc40e35f9f23 100644 (file)
@@ -58,7 +58,16 @@ static irqreturn_t coh901331_interrupt(int irq, void *data)
        clk_enable(rtap->clk);
        /* Ack IRQ */
        writel(1, rtap->virtbase + COH901331_IRQ_EVENT);
+       /*
+        * Disable the interrupt. This is necessary because
+        * the RTC lives on a lower-clocked line and will
+        * not release the IRQ line until after a few (slower)
+        * clock cycles. The interrupt will be re-enabled when
+        * a new alarm is set anyway.
+        */
+       writel(0, rtap->virtbase + COH901331_IRQ_MASK);
        clk_disable(rtap->clk);
+
        /* Set alarm flag */
        rtc_update_irq(rtap->rtc, 1, RTC_AF);
 
@@ -128,6 +137,8 @@ static int coh901331_alarm_irq_enable(struct device *dev, unsigned int enabled)
        else
                writel(0, rtap->virtbase + COH901331_IRQ_MASK);
        clk_disable(rtap->clk);
+
+       return 0;
 }
 
 static struct rtc_class_ops coh901331_ops = {
index 33a10c47260e8ff5d1818d53e5b59933150f7133..4c5d5d0c4cfcf13a4cbf462c7d03a8ad8531f99c 100644 (file)
@@ -292,8 +292,9 @@ static int __devinit pcf50633_rtc_probe(struct platform_device *pdev)
                                &pcf50633_rtc_ops, THIS_MODULE);
 
        if (IS_ERR(rtc->rtc_dev)) {
+               int ret =  PTR_ERR(rtc->rtc_dev);
                kfree(rtc);
-               return PTR_ERR(rtc->rtc_dev);
+               return ret;
        }
 
        pcf50633_register_irq(rtc->pcf, PCF50633_IRQ_ALARM,
index 310c10795e9a81cf0c37960a1d40fb46a743369a..6583c1a8b0702b260c70cb7f13845ea8257b0f2b 100644 (file)
@@ -195,7 +195,7 @@ static int x1205_set_datetime(struct i2c_client *client, struct rtc_time *tm,
                /* year, since the rtc epoch*/
                buf[CCR_YEAR] = bin2bcd(tm->tm_year % 100);
                buf[CCR_WDAY] = tm->tm_wday & 0x07;
-               buf[CCR_Y2K] = bin2bcd(tm->tm_year / 100);
+               buf[CCR_Y2K] = bin2bcd((tm->tm_year + 1900) / 100);
        }
 
        /* If writing alarm registers, set compare bits on registers 0-4 */
@@ -280,9 +280,9 @@ static int x1205_fix_osc(struct i2c_client *client)
        int err;
        struct rtc_time tm;
 
-       tm.tm_hour = tm.tm_min = tm.tm_sec = 0;
+       memset(&tm, 0, sizeof(tm));
 
-       err = x1205_set_datetime(client, &tm, 0, X1205_CCR_BASE, 0);
+       err = x1205_set_datetime(client, &tm, 1, X1205_CCR_BASE, 0);
        if (err < 0)
                dev_err(&client->dev, "unable to restart the oscillator\n");
 
index 89ece1c235aa7d4919a5efd505196137a156409c..66e21dd23154b4c5c27b0c254a3bfd348cc88d48 100644 (file)
@@ -357,6 +357,7 @@ static int mon_close(struct inode *inode, struct file *filp)
        atomic_set(&monpriv->msglim_count, 0);
        monpriv->write_index  = 0;
        monpriv->read_index   = 0;
+       dev_set_drvdata(monreader_device, NULL);
 
        for (i = 0; i < MON_MSGLIM; i++)
                kfree(monpriv->msg_array[i]);
index 84c191c1cd620fa1e5a723dcb060f9a8d4ae9175..05909a7df8b30df91009c01146acae763f110da4 100644 (file)
 
 #include "sclp.h"
 
+static void (*old_machine_restart)(char *);
+static void (*old_machine_halt)(void);
+static void (*old_machine_power_off)(void);
+
 /* Shutdown handler. Signal completion of shutdown by loading special PSW. */
-static void
-do_machine_quiesce(void)
+static void do_machine_quiesce(void)
 {
        psw_t quiesce_psw;
 
@@ -33,23 +36,48 @@ do_machine_quiesce(void)
 }
 
 /* Handler for quiesce event. Start shutdown procedure. */
-static void
-sclp_quiesce_handler(struct evbuf_header *evbuf)
+static void sclp_quiesce_handler(struct evbuf_header *evbuf)
 {
-       _machine_restart = (void *) do_machine_quiesce;
-       _machine_halt = do_machine_quiesce;
-       _machine_power_off = do_machine_quiesce;
+       if (_machine_restart != (void *) do_machine_quiesce) {
+               old_machine_restart = _machine_restart;
+               old_machine_halt = _machine_halt;
+               old_machine_power_off = _machine_power_off;
+               _machine_restart = (void *) do_machine_quiesce;
+               _machine_halt = do_machine_quiesce;
+               _machine_power_off = do_machine_quiesce;
+       }
        ctrl_alt_del();
 }
 
+/* Undo machine restart/halt/power_off modification on resume */
+static void sclp_quiesce_pm_event(struct sclp_register *reg,
+                                 enum sclp_pm_event sclp_pm_event)
+{
+       switch (sclp_pm_event) {
+       case SCLP_PM_EVENT_RESTORE:
+               if (old_machine_restart) {
+                       _machine_restart = old_machine_restart;
+                       _machine_halt = old_machine_halt;
+                       _machine_power_off = old_machine_power_off;
+                       old_machine_restart = NULL;
+                       old_machine_halt = NULL;
+                       old_machine_power_off = NULL;
+               }
+               break;
+       case SCLP_PM_EVENT_FREEZE:
+       case SCLP_PM_EVENT_THAW:
+               break;
+       }
+}
+
 static struct sclp_register sclp_quiesce_event = {
        .receive_mask = EVTYP_SIGQUIESCE_MASK,
-       .receiver_fn = sclp_quiesce_handler
+       .receiver_fn = sclp_quiesce_handler,
+       .pm_event_fn = sclp_quiesce_pm_event
 };
 
 /* Initialize quiesce driver. */
-static int __init
-sclp_quiesce_init(void)
+static int __init sclp_quiesce_init(void)
 {
        return sclp_register(&sclp_quiesce_event);
 }
index b2f6949bc8d33996c0cc294b2f4d98367f2257ec..bd34b0db2d6b3bdd29f1616687d94299ebc33a68 100644 (file)
@@ -41,6 +41,8 @@ u32 *bfi_image_cb;
 
 #define        BFAD_FW_FILE_CT "ctfw.bin"
 #define        BFAD_FW_FILE_CB "cbfw.bin"
+MODULE_FIRMWARE(BFAD_FW_FILE_CT);
+MODULE_FIRMWARE(BFAD_FW_FILE_CB);
 
 u32 *
 bfad_read_firmware(struct pci_dev *pdev, u32 **bfi_image,
index 158c99243c089f9fa104872d1eb2a8024e3cb6ba..55d012a9a6681d74203c09944840f32127411004 100644 (file)
@@ -948,7 +948,7 @@ bfad_os_fc_host_init(struct bfad_im_port_s *im_port)
        if (bfad_supported_fc4s & (BFA_PORT_ROLE_FCP_IM | BFA_PORT_ROLE_FCP_TM))
                /* For FCP type 0x08 */
                fc_host_supported_fc4s(host)[2] = 1;
-       if (bfad_supported_fc4s | BFA_PORT_ROLE_FCP_IPFC)
+       if (bfad_supported_fc4s & BFA_PORT_ROLE_FCP_IPFC)
                /* For LLC/SNAP type 0x05 */
                fc_host_supported_fc4s(host)[3] = 0x20;
        /* For fibre channel services type 0x20 */
index 185e6bc4dd40076519dea524d9687fa8cc0f51f5..9e8fce0f0c1b3f1022b5658a2ad503fcc810abf6 100644 (file)
@@ -2900,7 +2900,7 @@ static int gdth_read_event(gdth_ha_str *ha, int handle, gdth_evt_str *estr)
         eindex = handle;
     estr->event_source = 0;
 
-    if (eindex >= MAX_EVENTS) {
+    if (eindex < 0 || eindex >= MAX_EVENTS) {
         spin_unlock_irqrestore(&ha->smp_lock, flags);
         return eindex;
     }
index 5fd2da494d087da334b65b9bd88b2945191184ff..c968cc31cd862514ae432eee7573d6ade5277863 100644 (file)
@@ -164,8 +164,8 @@ void scsi_remove_host(struct Scsi_Host *shost)
                        return;
                }
        spin_unlock_irqrestore(shost->host_lock, flags);
-       mutex_unlock(&shost->scan_mutex);
        scsi_forget_host(shost);
+       mutex_unlock(&shost->scan_mutex);
        scsi_proc_host_rm(shost);
 
        spin_lock_irqsave(shost->host_lock, flags);
index 5f045505a1f4a48eb5f5a1d17ff61508f7cadf7e..76d294fc78461c13bdf6aae03dc6c2fc2273a0cf 100644 (file)
@@ -4188,6 +4188,25 @@ static irqreturn_t ipr_handle_other_interrupt(struct ipr_ioa_cfg *ioa_cfg,
        return rc;
 }
 
+/**
+ * ipr_isr_eh - Interrupt service routine error handler
+ * @ioa_cfg:   ioa config struct
+ * @msg:       message to log
+ *
+ * Return value:
+ *     none
+ **/
+static void ipr_isr_eh(struct ipr_ioa_cfg *ioa_cfg, char *msg)
+{
+       ioa_cfg->errors_logged++;
+       dev_err(&ioa_cfg->pdev->dev, "%s\n", msg);
+
+       if (WAIT_FOR_DUMP == ioa_cfg->sdt_state)
+               ioa_cfg->sdt_state = GET_DUMP;
+
+       ipr_initiate_ioa_reset(ioa_cfg, IPR_SHUTDOWN_NONE);
+}
+
 /**
  * ipr_isr - Interrupt service routine
  * @irq:       irq number
@@ -4203,6 +4222,7 @@ static irqreturn_t ipr_isr(int irq, void *devp)
        volatile u32 int_reg, int_mask_reg;
        u32 ioasc;
        u16 cmd_index;
+       int num_hrrq = 0;
        struct ipr_cmnd *ipr_cmd;
        irqreturn_t rc = IRQ_NONE;
 
@@ -4233,13 +4253,7 @@ static irqreturn_t ipr_isr(int irq, void *devp)
                                     IPR_HRRQ_REQ_RESP_HANDLE_MASK) >> IPR_HRRQ_REQ_RESP_HANDLE_SHIFT;
 
                        if (unlikely(cmd_index >= IPR_NUM_CMD_BLKS)) {
-                               ioa_cfg->errors_logged++;
-                               dev_err(&ioa_cfg->pdev->dev, "Invalid response handle from IOA\n");
-
-                               if (WAIT_FOR_DUMP == ioa_cfg->sdt_state)
-                                       ioa_cfg->sdt_state = GET_DUMP;
-
-                               ipr_initiate_ioa_reset(ioa_cfg, IPR_SHUTDOWN_NONE);
+                               ipr_isr_eh(ioa_cfg, "Invalid response handle from IOA");
                                spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
                                return IRQ_HANDLED;
                        }
@@ -4266,8 +4280,18 @@ static irqreturn_t ipr_isr(int irq, void *devp)
 
                if (ipr_cmd != NULL) {
                        /* Clear the PCI interrupt */
-                       writel(IPR_PCII_HRRQ_UPDATED, ioa_cfg->regs.clr_interrupt_reg);
-                       int_reg = readl(ioa_cfg->regs.sense_interrupt_reg) & ~int_mask_reg;
+                       do {
+                               writel(IPR_PCII_HRRQ_UPDATED, ioa_cfg->regs.clr_interrupt_reg);
+                               int_reg = readl(ioa_cfg->regs.sense_interrupt_reg) & ~int_mask_reg;
+                       } while (int_reg & IPR_PCII_HRRQ_UPDATED &&
+                                       num_hrrq++ < IPR_MAX_HRRQ_RETRIES);
+
+                       if (int_reg & IPR_PCII_HRRQ_UPDATED) {
+                               ipr_isr_eh(ioa_cfg, "Error clearing HRRQ");
+                               spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
+                               return IRQ_HANDLED;
+                       }
+
                } else
                        break;
        }
index 163245a1c3e5a666b0d97cabbf5813eccb4a6dcb..19bbcf39f0c9fb759af60b670782e3c48dc12e01 100644 (file)
 #define IPR_IOA_MAX_SECTORS                            32767
 #define IPR_VSET_MAX_SECTORS                           512
 #define IPR_MAX_CDB_LEN                                        16
+#define IPR_MAX_HRRQ_RETRIES                           3
 
 #define IPR_DEFAULT_BUS_WIDTH                          16
 #define IPR_80MBs_SCSI_RATE            ((80 * 10) / (IPR_DEFAULT_BUS_WIDTH / 8))
index b3381959acce19ee167c183ccd7b2b9354203c1b..33cf988c8c8a2cd25548ce5be0f67d97ee58e997 100644 (file)
@@ -960,7 +960,6 @@ static int sas_ex_discover_dev(struct domain_device *dev, int phy_id)
 
                        }
                }
-               res = 0;
        }
 
        return res;
index 67cde0138061dd2b23179e72d3cda93e19b276e8..528733b4a392ca9072a749e5497eafcdcac2900a 100644 (file)
 #include <pcmcia/cistpl.h>
 #include <pcmcia/ds.h>
 
-#ifdef PCMCIA_DEBUG
-static int pc_debug = PCMCIA_DEBUG;
-module_param(pc_debug, int, 0644);
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
-static char *version =
-"aha152x_cs.c 1.54 2000/06/12 21:27:25 (David Hinds)";
-#else
-#define DEBUG(n, args...)
-#endif
 
 /*====================================================================*/
 
@@ -103,7 +94,7 @@ static int aha152x_probe(struct pcmcia_device *link)
 {
     scsi_info_t *info;
 
-    DEBUG(0, "aha152x_attach()\n");
+    dev_dbg(&link->dev, "aha152x_attach()\n");
 
     /* Create new SCSI device */
     info = kzalloc(sizeof(*info), GFP_KERNEL);
@@ -115,7 +106,6 @@ static int aha152x_probe(struct pcmcia_device *link)
     link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
     link->io.IOAddrLines = 10;
     link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
-    link->irq.IRQInfo1 = IRQ_LEVEL_ID;
     link->conf.Attributes = CONF_ENABLE_IRQ;
     link->conf.IntType = INT_MEMORY_AND_IO;
     link->conf.Present = PRESENT_OPTION;
@@ -127,7 +117,7 @@ static int aha152x_probe(struct pcmcia_device *link)
 
 static void aha152x_detach(struct pcmcia_device *link)
 {
-    DEBUG(0, "aha152x_detach(0x%p)\n", link);
+    dev_dbg(&link->dev, "aha152x_detach\n");
 
     aha152x_release_cs(link);
 
@@ -137,9 +127,6 @@ static void aha152x_detach(struct pcmcia_device *link)
 
 /*====================================================================*/
 
-#define CS_CHECK(fn, ret) \
-do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
-
 static int aha152x_config_check(struct pcmcia_device *p_dev,
                                cistpl_cftable_entry_t *cfg,
                                cistpl_cftable_entry_t *dflt,
@@ -164,19 +151,22 @@ static int aha152x_config_cs(struct pcmcia_device *link)
 {
     scsi_info_t *info = link->priv;
     struct aha152x_setup s;
-    int last_ret, last_fn;
+    int ret;
     struct Scsi_Host *host;
 
-    DEBUG(0, "aha152x_config(0x%p)\n", link);
+    dev_dbg(&link->dev, "aha152x_config\n");
 
-    last_ret = pcmcia_loop_config(link, aha152x_config_check, NULL);
-    if (last_ret) {
-       cs_error(link, RequestIO, last_ret);
-       goto failed;
-    }
+    ret = pcmcia_loop_config(link, aha152x_config_check, NULL);
+    if (ret)
+           goto failed;
 
-    CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
-    CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
+    ret = pcmcia_request_irq(link, &link->irq);
+    if (ret)
+           goto failed;
+
+    ret = pcmcia_request_configuration(link, &link->conf);
+    if (ret)
+           goto failed;
     
     /* Set configuration options for the aha152x driver */
     memset(&s, 0, sizeof(s));
@@ -194,7 +184,7 @@ static int aha152x_config_cs(struct pcmcia_device *link)
     host = aha152x_probe_one(&s);
     if (host == NULL) {
        printk(KERN_INFO "aha152x_cs: no SCSI devices found\n");
-       goto cs_failed;
+       goto failed;
     }
 
     sprintf(info->node.dev_name, "scsi%d", host->host_no);
@@ -203,8 +193,6 @@ static int aha152x_config_cs(struct pcmcia_device *link)
 
     return 0;
 
-cs_failed:
-    cs_error(link, last_fn, last_ret);
 failed:
     aha152x_release_cs(link);
     return -ENODEV;
index 06254f46a0ddda146322e0b106faa13b90bb9882..914040684079514e32fa9919c513f4f7b5c3759a 100644 (file)
@@ -59,16 +59,6 @@ MODULE_AUTHOR("David Hinds <dahinds@users.sourceforge.net>");
 MODULE_DESCRIPTION("Future Domain PCMCIA SCSI driver");
 MODULE_LICENSE("Dual MPL/GPL");
 
-#ifdef PCMCIA_DEBUG
-static int pc_debug = PCMCIA_DEBUG;
-module_param(pc_debug, int, 0);
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
-static char *version =
-"fdomain_cs.c 1.47 2001/10/13 00:08:52 (David Hinds)";
-#else
-#define DEBUG(n, args...)
-#endif
-
 /*====================================================================*/
 
 typedef struct scsi_info_t {
@@ -86,7 +76,7 @@ static int fdomain_probe(struct pcmcia_device *link)
 {
        scsi_info_t *info;
 
-       DEBUG(0, "fdomain_attach()\n");
+       dev_dbg(&link->dev, "fdomain_attach()\n");
 
        /* Create new SCSI device */
        info = kzalloc(sizeof(*info), GFP_KERNEL);
@@ -99,7 +89,6 @@ static int fdomain_probe(struct pcmcia_device *link)
        link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
        link->io.IOAddrLines = 10;
        link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
-       link->irq.IRQInfo1 = IRQ_LEVEL_ID;
        link->conf.Attributes = CONF_ENABLE_IRQ;
        link->conf.IntType = INT_MEMORY_AND_IO;
        link->conf.Present = PRESENT_OPTION;
@@ -111,7 +100,7 @@ static int fdomain_probe(struct pcmcia_device *link)
 
 static void fdomain_detach(struct pcmcia_device *link)
 {
-       DEBUG(0, "fdomain_detach(0x%p)\n", link);
+       dev_dbg(&link->dev, "fdomain_detach\n");
 
        fdomain_release(link);
 
@@ -120,9 +109,6 @@ static void fdomain_detach(struct pcmcia_device *link)
 
 /*====================================================================*/
 
-#define CS_CHECK(fn, ret) \
-do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
-
 static int fdomain_config_check(struct pcmcia_device *p_dev,
                                cistpl_cftable_entry_t *cfg,
                                cistpl_cftable_entry_t *dflt,
@@ -137,20 +123,22 @@ static int fdomain_config_check(struct pcmcia_device *p_dev,
 static int fdomain_config(struct pcmcia_device *link)
 {
     scsi_info_t *info = link->priv;
-    int last_ret, last_fn;
+    int ret;
     char str[22];
     struct Scsi_Host *host;
 
-    DEBUG(0, "fdomain_config(0x%p)\n", link);
+    dev_dbg(&link->dev, "fdomain_config\n");
 
-    last_ret = pcmcia_loop_config(link, fdomain_config_check, NULL);
-    if (last_ret) {
-           cs_error(link, RequestIO, last_ret);
+    ret = pcmcia_loop_config(link, fdomain_config_check, NULL);
+    if (ret)
            goto failed;
-    }
 
-    CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
-    CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
+    ret = pcmcia_request_irq(link, &link->irq);
+    if (ret)
+           goto failed;
+    ret = pcmcia_request_configuration(link, &link->conf);
+    if (ret)
+           goto failed;
 
     /* A bad hack... */
     release_region(link->io.BasePort1, link->io.NumPorts1);
@@ -162,11 +150,11 @@ static int fdomain_config(struct pcmcia_device *link)
     host = __fdomain_16x0_detect(&fdomain_driver_template);
     if (!host) {
         printk(KERN_INFO "fdomain_cs: no SCSI devices found\n");
-       goto cs_failed;
+       goto failed;
     }
 
     if (scsi_add_host(host, NULL))
-           goto cs_failed;
+           goto failed;
     scsi_scan_host(host);
 
     sprintf(info->node.dev_name, "scsi%d", host->host_no);
@@ -175,8 +163,6 @@ static int fdomain_config(struct pcmcia_device *link)
 
     return 0;
 
-cs_failed:
-    cs_error(link, last_fn, last_ret);
 failed:
     fdomain_release(link);
     return -ENODEV;
@@ -188,7 +174,7 @@ static void fdomain_release(struct pcmcia_device *link)
 {
        scsi_info_t *info = link->priv;
 
-       DEBUG(0, "fdomain_release(0x%p)\n", link);
+       dev_dbg(&link->dev, "fdomain_release\n");
 
        scsi_remove_host(info->host);
        pcmcia_disable_device(link);
index e32c344d7ad853c03f4a5338b2786e3a72cdc247..c2341af587a3111e1920678400f75be246afb017 100644 (file)
@@ -1564,12 +1564,10 @@ static int nsp_cs_probe(struct pcmcia_device *link)
        link->io.IOAddrLines     = 10;  /* not used */
 
        /* Interrupt setup */
-       link->irq.Attributes     = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
-       link->irq.IRQInfo1       = IRQ_LEVEL_ID;
+       link->irq.Attributes     = IRQ_TYPE_EXCLUSIVE;
 
        /* Interrupt handler */
        link->irq.Handler        = &nspintr;
-       link->irq.Instance       = info;
        link->irq.Attributes     |= IRQF_SHARED;
 
        /* General socket configuration */
@@ -1684,10 +1682,10 @@ static int nsp_cs_config_check(struct pcmcia_device *p_dev,
                        if (cfg_mem->req.Size < 0x1000)
                                cfg_mem->req.Size = 0x1000;
                        cfg_mem->req.AccessSpeed = 0;
-                       if (pcmcia_request_window(&p_dev, &cfg_mem->req, &p_dev->win) != 0)
+                       if (pcmcia_request_window(p_dev, &cfg_mem->req, &p_dev->win) != 0)
                                goto next_entry;
                        map.Page = 0; map.CardOffset = mem->win[0].card_addr;
-                       if (pcmcia_map_mem_page(p_dev->win, &map) != 0)
+                       if (pcmcia_map_mem_page(p_dev, p_dev->win, &map) != 0)
                                goto next_entry;
 
                        cfg_mem->data->MmioAddress = (unsigned long) ioremap_nocache(cfg_mem->req.Base, cfg_mem->req.Size);
index 20c3e5e6d88ad369fedf8f059bb6e7c597ecc826..f85f094870b4bf95a9de3a779767218762016728 100644 (file)
 
 static char qlogic_name[] = "qlogic_cs";
 
-#ifdef PCMCIA_DEBUG
-static int pc_debug = PCMCIA_DEBUG;
-module_param(pc_debug, int, 0644);
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
-static char *version = "qlogic_cs.c 1.79-ac 2002/10/26 (David Hinds)";
-#else
-#define DEBUG(n, args...)
-#endif
-
 static struct scsi_host_template qlogicfas_driver_template = {
        .module                 = THIS_MODULE,
        .name                   = qlogic_name,
@@ -159,7 +150,7 @@ static int qlogic_probe(struct pcmcia_device *link)
 {
        scsi_info_t *info;
 
-       DEBUG(0, "qlogic_attach()\n");
+       dev_dbg(&link->dev, "qlogic_attach()\n");
 
        /* Create new SCSI device */
        info = kzalloc(sizeof(*info), GFP_KERNEL);
@@ -171,7 +162,6 @@ static int qlogic_probe(struct pcmcia_device *link)
        link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
        link->io.IOAddrLines = 10;
        link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
-       link->irq.IRQInfo1 = IRQ_LEVEL_ID;
        link->conf.Attributes = CONF_ENABLE_IRQ;
        link->conf.IntType = INT_MEMORY_AND_IO;
        link->conf.Present = PRESENT_OPTION;
@@ -183,7 +173,7 @@ static int qlogic_probe(struct pcmcia_device *link)
 
 static void qlogic_detach(struct pcmcia_device *link)
 {
-       DEBUG(0, "qlogic_detach(0x%p)\n", link);
+       dev_dbg(&link->dev, "qlogic_detach\n");
 
        qlogic_release(link);
        kfree(link->priv);
@@ -192,9 +182,6 @@ static void qlogic_detach(struct pcmcia_device *link)
 
 /*====================================================================*/
 
-#define CS_CHECK(fn, ret) \
-do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
-
 static int qlogic_config_check(struct pcmcia_device *p_dev,
                               cistpl_cftable_entry_t *cfg,
                               cistpl_cftable_entry_t *dflt,
@@ -213,19 +200,22 @@ static int qlogic_config_check(struct pcmcia_device *p_dev,
 static int qlogic_config(struct pcmcia_device * link)
 {
        scsi_info_t *info = link->priv;
-       int last_ret, last_fn;
+       int ret;
        struct Scsi_Host *host;
 
-       DEBUG(0, "qlogic_config(0x%p)\n", link);
+       dev_dbg(&link->dev, "qlogic_config\n");
 
-       last_ret = pcmcia_loop_config(link, qlogic_config_check, NULL);
-       if (last_ret) {
-               cs_error(link, RequestIO, last_ret);
+       ret = pcmcia_loop_config(link, qlogic_config_check, NULL);
+       if (ret)
+               goto failed;
+
+       ret = pcmcia_request_irq(link, &link->irq);
+       if (ret)
                goto failed;
-       }
 
-       CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
-       CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
+       ret = pcmcia_request_configuration(link, &link->conf);
+       if (ret)
+               goto failed;
 
        if ((info->manf_id == MANFID_MACNICA) || (info->manf_id == MANFID_PIONEER) || (info->manf_id == 0x0098)) {
                /* set ATAcmd */
@@ -244,7 +234,7 @@ static int qlogic_config(struct pcmcia_device * link)
        
        if (!host) {
                printk(KERN_INFO "%s: no SCSI devices found\n", qlogic_name);
-               goto cs_failed;
+               goto failed;
        }
 
        sprintf(info->node.dev_name, "scsi%d", host->host_no);
@@ -253,12 +243,9 @@ static int qlogic_config(struct pcmcia_device * link)
 
        return 0;
 
-cs_failed:
-       cs_error(link, last_fn, last_ret);
-       pcmcia_disable_device(link);
 failed:
+       pcmcia_disable_device(link);
        return -ENODEV;
-
 }                              /* qlogic_config */
 
 /*====================================================================*/
@@ -267,7 +254,7 @@ static void qlogic_release(struct pcmcia_device *link)
 {
        scsi_info_t *info = link->priv;
 
-       DEBUG(0, "qlogic_release(0x%p)\n", link);
+       dev_dbg(&link->dev, "qlogic_release\n");
 
        scsi_remove_host(info->host);
 
index b330c11a1752378e95dd831dc053646a63d3171a..e7564d8f0cbf2318c6808a5e3744a5f9b161e077 100644 (file)
 #include <pcmcia/ds.h>
 #include <pcmcia/ciscode.h>
 
-/* ================================================================== */
-
-#ifdef PCMCIA_DEBUG
-static int pc_debug = PCMCIA_DEBUG;
-module_param(pc_debug, int, 0);
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
-static char *version =
-"sym53c500_cs.c 0.9c 2004/10/27 (Bob Tracy)";
-#else
-#define DEBUG(n, args...)
-#endif
 
 /* ================================================================== */
 
@@ -525,7 +514,7 @@ SYM53C500_release(struct pcmcia_device *link)
        struct scsi_info_t *info = link->priv;
        struct Scsi_Host *shost = info->host;
 
-       DEBUG(0, "SYM53C500_release(0x%p)\n", link);
+       dev_dbg(&link->dev, "SYM53C500_release\n");
 
        /*
        *  Do this before releasing/freeing resources.
@@ -697,9 +686,6 @@ static struct scsi_host_template sym53c500_driver_template = {
      .shost_attrs              = SYM53C500_shost_attrs
 };
 
-#define CS_CHECK(fn, ret) \
-do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
-
 static int SYM53C500_config_check(struct pcmcia_device *p_dev,
                                  cistpl_cftable_entry_t *cfg,
                                  cistpl_cftable_entry_t *dflt,
@@ -719,24 +705,27 @@ static int
 SYM53C500_config(struct pcmcia_device *link)
 {
        struct scsi_info_t *info = link->priv;
-       int last_ret, last_fn;
+       int ret;
        int irq_level, port_base;
        struct Scsi_Host *host;
        struct scsi_host_template *tpnt = &sym53c500_driver_template;
        struct sym53c500_data *data;
 
-       DEBUG(0, "SYM53C500_config(0x%p)\n", link);
+       dev_dbg(&link->dev, "SYM53C500_config\n");
 
        info->manf_id = link->manf_id;
 
-       last_ret = pcmcia_loop_config(link, SYM53C500_config_check, NULL);
-       if (last_ret) {
-               cs_error(link, RequestIO, last_ret);
+       ret = pcmcia_loop_config(link, SYM53C500_config_check, NULL);
+       if (ret)
+               goto failed;
+
+       ret = pcmcia_request_irq(link, &link->irq);
+       if (ret)
                goto failed;
-       }
 
-       CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
-       CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
+       ret = pcmcia_request_configuration(link, &link->conf);
+       if (ret)
+               goto failed;
 
        /*
        *  That's the trouble with copying liberally from another driver.
@@ -824,8 +813,6 @@ err_release:
        printk(KERN_INFO "sym53c500_cs: no SCSI devices found\n");
        return -ENODEV;
 
-cs_failed:
-       cs_error(link, last_fn, last_ret);
 failed:
        SYM53C500_release(link);
        return -ENODEV;
@@ -855,7 +842,7 @@ static int sym53c500_resume(struct pcmcia_device *link)
 static void
 SYM53C500_detach(struct pcmcia_device *link)
 {
-       DEBUG(0, "SYM53C500_detach(0x%p)\n", link);
+       dev_dbg(&link->dev, "SYM53C500_detach\n");
 
        SYM53C500_release(link);
 
@@ -868,7 +855,7 @@ SYM53C500_probe(struct pcmcia_device *link)
 {
        struct scsi_info_t *info;
 
-       DEBUG(0, "SYM53C500_attach()\n");
+       dev_dbg(&link->dev, "SYM53C500_attach()\n");
 
        /* Create new SCSI device */
        info = kzalloc(sizeof(*info), GFP_KERNEL);
@@ -880,7 +867,6 @@ SYM53C500_probe(struct pcmcia_device *link)
        link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
        link->io.IOAddrLines = 10;
        link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
-       link->irq.IRQInfo1 = IRQ_LEVEL_ID;
        link->conf.Attributes = CONF_ENABLE_IRQ;
        link->conf.IntType = INT_MEMORY_AND_IO;
 
index f7c70e2a8224b442b827f255728a784ceaf0b0c5..0a97bc9074bb2676429a2d777d5597e2ec8645c3 100644 (file)
@@ -1071,7 +1071,7 @@ static struct pmcraid_cmd *pmcraid_init_hcam
 
        ioarcb->data_transfer_length = cpu_to_le32(rcb_size);
 
-       ioadl[0].flags |= cpu_to_le32(IOADL_FLAGS_READ_LAST);
+       ioadl[0].flags |= IOADL_FLAGS_READ_LAST;
        ioadl[0].data_len = cpu_to_le32(rcb_size);
        ioadl[0].address = cpu_to_le32(dma);
 
@@ -2251,7 +2251,7 @@ static void pmcraid_request_sense(struct pmcraid_cmd *cmd)
 
        ioadl->address = cpu_to_le64(cmd->sense_buffer_dma);
        ioadl->data_len = cpu_to_le32(SCSI_SENSE_BUFFERSIZE);
-       ioadl->flags = cpu_to_le32(IOADL_FLAGS_LAST_DESC);
+       ioadl->flags = IOADL_FLAGS_LAST_DESC;
 
        /* request sense might be called as part of error response processing
         * which runs in tasklets context. It is possible that mid-layer might
@@ -3017,7 +3017,7 @@ static int pmcraid_build_ioadl(
                ioadl[i].flags = 0;
        }
        /* setup last descriptor */
-       ioadl[i - 1].flags = cpu_to_le32(IOADL_FLAGS_LAST_DESC);
+       ioadl[i - 1].flags = IOADL_FLAGS_LAST_DESC;
 
        return 0;
 }
@@ -3387,7 +3387,7 @@ static int pmcraid_build_passthrough_ioadls(
        }
 
        /* setup the last descriptor */
-       ioadl[i - 1].flags = cpu_to_le32(IOADL_FLAGS_LAST_DESC);
+       ioadl[i - 1].flags = IOADL_FLAGS_LAST_DESC;
 
        return 0;
 }
@@ -5314,7 +5314,7 @@ static void pmcraid_querycfg(struct pmcraid_cmd *cmd)
                cpu_to_le32(sizeof(struct pmcraid_config_table));
 
        ioadl = &(ioarcb->add_data.u.ioadl[0]);
-       ioadl->flags = cpu_to_le32(IOADL_FLAGS_LAST_DESC);
+       ioadl->flags = IOADL_FLAGS_LAST_DESC;
        ioadl->address = cpu_to_le64(pinstance->cfg_table_bus_addr);
        ioadl->data_len = cpu_to_le32(sizeof(struct pmcraid_config_table));
 
index 0547a7f44d4277768f6c4fc4b407fedd72df39d0..47291bcff0d52c35b84c089b892a84da46f52990 100644 (file)
@@ -952,16 +952,6 @@ static int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result,
        return SCSI_SCAN_LUN_PRESENT;
 }
 
-static inline void scsi_destroy_sdev(struct scsi_device *sdev)
-{
-       scsi_device_set_state(sdev, SDEV_DEL);
-       if (sdev->host->hostt->slave_destroy)
-               sdev->host->hostt->slave_destroy(sdev);
-       transport_destroy_device(&sdev->sdev_gendev);
-       put_device(&sdev->sdev_dev);
-       put_device(&sdev->sdev_gendev);
-}
-
 #ifdef CONFIG_SCSI_LOGGING
 /** 
  * scsi_inq_str - print INQUIRY data from min to max index, strip trailing whitespace
@@ -1139,7 +1129,7 @@ static int scsi_probe_and_add_lun(struct scsi_target *starget,
                        }
                }
        } else
-               scsi_destroy_sdev(sdev);
+               __scsi_remove_device(sdev);
  out:
        return res;
 }
@@ -1500,7 +1490,7 @@ static int scsi_report_lun_scan(struct scsi_target *starget, int bflags,
                /*
                 * the sdev we used didn't appear in the report luns scan
                 */
-               scsi_destroy_sdev(sdev);
+               __scsi_remove_device(sdev);
        return ret;
 }
 
@@ -1710,7 +1700,7 @@ static void scsi_sysfs_add_devices(struct Scsi_Host *shost)
        shost_for_each_device(sdev, shost) {
                if (!scsi_host_scan_allowed(shost) ||
                    scsi_sysfs_add_sdev(sdev) != 0)
-                       scsi_destroy_sdev(sdev);
+                       __scsi_remove_device(sdev);
        }
 }
 
@@ -1943,7 +1933,7 @@ void scsi_free_host_dev(struct scsi_device *sdev)
 {
        BUG_ON(sdev->id != sdev->host->this_id);
 
-       scsi_destroy_sdev(sdev);
+       __scsi_remove_device(sdev);
 }
 EXPORT_SYMBOL(scsi_free_host_dev);
 
index 5c7eb63a19d13732514e0bd3f50ade6ab380c4d5..392d8db33905cbe31f1e2f96644552d9b692eb27 100644 (file)
@@ -854,82 +854,73 @@ int scsi_sysfs_add_sdev(struct scsi_device *sdev)
        transport_configure_device(&starget->dev);
        error = device_add(&sdev->sdev_gendev);
        if (error) {
-               put_device(sdev->sdev_gendev.parent);
                printk(KERN_INFO "error 1\n");
-               return error;
+               goto out_remove;
        }
        error = device_add(&sdev->sdev_dev);
        if (error) {
                printk(KERN_INFO "error 2\n");
-               goto clean_device;
+               device_del(&sdev->sdev_gendev);
+               goto out_remove;
        }
+       transport_add_device(&sdev->sdev_gendev);
+       sdev->is_visible = 1;
 
        /* create queue files, which may be writable, depending on the host */
        if (sdev->host->hostt->change_queue_depth)
                error = device_create_file(&sdev->sdev_gendev, &sdev_attr_queue_depth_rw);
        else
                error = device_create_file(&sdev->sdev_gendev, &dev_attr_queue_depth);
-       if (error) {
-               __scsi_remove_device(sdev);
-               goto out;
-       }
+       if (error)
+               goto out_remove;
+
        if (sdev->host->hostt->change_queue_type)
                error = device_create_file(&sdev->sdev_gendev, &sdev_attr_queue_type_rw);
        else
                error = device_create_file(&sdev->sdev_gendev, &dev_attr_queue_type);
-       if (error) {
-               __scsi_remove_device(sdev);
-               goto out;
-       }
+       if (error)
+               goto out_remove;
 
        error = bsg_register_queue(rq, &sdev->sdev_gendev, NULL, NULL);
 
        if (error)
+               /* we're treating error on bsg register as non-fatal,
+                * so pretend nothing went wrong */
                sdev_printk(KERN_INFO, sdev,
                            "Failed to register bsg queue, errno=%d\n", error);
 
-       /* we're treating error on bsg register as non-fatal, so pretend
-        * nothing went wrong */
-       error = 0;
-
        /* add additional host specific attributes */
        if (sdev->host->hostt->sdev_attrs) {
                for (i = 0; sdev->host->hostt->sdev_attrs[i]; i++) {
                        error = device_create_file(&sdev->sdev_gendev,
                                        sdev->host->hostt->sdev_attrs[i]);
-                       if (error) {
-                               __scsi_remove_device(sdev);
-                               goto out;
-                       }
+                       if (error)
+                               goto out_remove;
                }
        }
 
-       transport_add_device(&sdev->sdev_gendev);
- out:
-       return error;
-
- clean_device:
-       scsi_device_set_state(sdev, SDEV_CANCEL);
-
-       device_del(&sdev->sdev_gendev);
-       transport_destroy_device(&sdev->sdev_gendev);
-       put_device(&sdev->sdev_dev);
-       put_device(&sdev->sdev_gendev);
+       return 0;
 
+ out_remove:
+       __scsi_remove_device(sdev);
        return error;
+
 }
 
 void __scsi_remove_device(struct scsi_device *sdev)
 {
        struct device *dev = &sdev->sdev_gendev;
 
-       if (scsi_device_set_state(sdev, SDEV_CANCEL) != 0)
-               return;
+       if (sdev->is_visible) {
+               if (scsi_device_set_state(sdev, SDEV_CANCEL) != 0)
+                       return;
 
-       bsg_unregister_queue(sdev->request_queue);
-       device_unregister(&sdev->sdev_dev);
-       transport_remove_device(dev);
-       device_del(dev);
+               bsg_unregister_queue(sdev->request_queue);
+               device_unregister(&sdev->sdev_dev);
+               transport_remove_device(dev);
+               device_del(dev);
+       } else
+               put_device(&sdev->sdev_dev);
        scsi_device_set_state(sdev, SDEV_DEL);
        if (sdev->host->hostt->slave_destroy)
                sdev->host->hostt->slave_destroy(sdev);
index a67fed10598acfc3dd00234d3f3222470d18a9f9..c6f70dae9b2eecdb5a602bc94520d3da032b346d 100644 (file)
@@ -3656,6 +3656,7 @@ fc_bsg_host_dispatch(struct request_queue *q, struct Scsi_Host *shost,
 fail_host_msg:
        /* return the errno failure code as the only status */
        BUG_ON(job->reply_len < sizeof(uint32_t));
+       job->reply->reply_payload_rcv_len = 0;
        job->reply->result = ret;
        job->reply_len = sizeof(uint32_t);
        fc_bsg_jobdone(job);
@@ -3741,6 +3742,7 @@ check_bidi:
 fail_rport_msg:
        /* return the errno failure code as the only status */
        BUG_ON(job->reply_len < sizeof(uint32_t));
+       job->reply->reply_payload_rcv_len = 0;
        job->reply->result = ret;
        job->reply_len = sizeof(uint32_t);
        fc_bsg_jobdone(job);
@@ -3797,6 +3799,7 @@ fc_bsg_request_handler(struct request_queue *q, struct Scsi_Host *shost,
                /* check if we have the msgcode value at least */
                if (job->request_len < sizeof(uint32_t)) {
                        BUG_ON(job->reply_len < sizeof(uint32_t));
+                       job->reply->reply_payload_rcv_len = 0;
                        job->reply->result = -ENOMSG;
                        job->reply_len = sizeof(uint32_t);
                        fc_bsg_jobdone(job);
index 88da977457102e78729781f89a5a8f82f5e2f80a..84be62149c6c92f9de34c1708828398dfba586d9 100644 (file)
@@ -418,7 +418,7 @@ error:
                  __func__, virt, phys, be32_to_cpu(sdt->ref_tag),
                  be16_to_cpu(sdt->app_tag));
 
-       return -EIO;
+       return -EILSEQ;
 }
 
 /*
index beddaa6e906911a2b1e5ee4281fe0c912e6fd73b..37ad0c449937c34046dcef72ec0db07af35b42ec 100644 (file)
@@ -242,7 +242,7 @@ static void bcm_uart_do_rx(struct uart_port *port)
         * higher than fifo size anyway since we're much faster than
         * serial port */
        max_count = 32;
-       tty = port->info->port.tty;
+       tty = port->state->port.tty;
        do {
                unsigned int iestat, c, cstat;
                char flag;
@@ -318,7 +318,7 @@ static void bcm_uart_do_tx(struct uart_port *port)
                return;
        }
 
-       xmit = &port->info->xmit;
+       xmit = &port->state->xmit;
        if (uart_circ_empty(xmit))
                goto txq_empty;
 
index 02406ba6da1c565e7c88d58507da66ba6d0ec8df..cdf172eda2e3792a61abc155d1c63b7c0396b92c 100644 (file)
@@ -161,6 +161,7 @@ static int of_platform_serial_remove(struct of_device *ofdev)
 static struct of_device_id __devinitdata of_platform_serial_table[] = {
        { .type = "serial", .compatible = "ns8250",   .data = (void *)PORT_8250, },
        { .type = "serial", .compatible = "ns16450",  .data = (void *)PORT_16450, },
+       { .type = "serial", .compatible = "ns16550a", .data = (void *)PORT_16550A, },
        { .type = "serial", .compatible = "ns16550",  .data = (void *)PORT_16550, },
        { .type = "serial", .compatible = "ns16750",  .data = (void *)PORT_16750, },
        { .type = "serial", .compatible = "ns16850",  .data = (void *)PORT_16850, },
index 7c7914f5fa02cb239fd27b109ed039045e6b2a0c..fc413f0f8dd29b8eb03ef8695e8afcddbf7b9236 100644 (file)
 
 #include "8250.h"
 
-#ifdef PCMCIA_DEBUG
-static int pc_debug = PCMCIA_DEBUG;
-module_param(pc_debug, int, 0644);
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
-static char *version = "serial_cs.c 1.134 2002/05/04 05:48:53 (David Hinds)";
-#else
-#define DEBUG(n, args...)
-#endif
 
 /*====================================================================*/
 
@@ -121,24 +113,20 @@ static void quirk_setup_brainboxes_0104(struct pcmcia_device *link, struct uart_
 static int quirk_post_ibm(struct pcmcia_device *link)
 {
        conf_reg_t reg = { 0, CS_READ, 0x800, 0 };
-       int last_ret, last_fn;
+       int ret;
+
+       ret = pcmcia_access_configuration_register(link, &reg);
+       if (ret)
+               goto failed;
 
-       last_ret = pcmcia_access_configuration_register(link, &reg);
-       if (last_ret) {
-               last_fn = AccessConfigurationRegister;
-               goto cs_failed;
-       }
        reg.Action = CS_WRITE;
        reg.Value = reg.Value | 1;
-       last_ret = pcmcia_access_configuration_register(link, &reg);
-       if (last_ret) {
-               last_fn = AccessConfigurationRegister;
-               goto cs_failed;
-       }
+       ret = pcmcia_access_configuration_register(link, &reg);
+       if (ret)
+               goto failed;
        return 0;
 
- cs_failed:
-       cs_error(link, last_fn, last_ret);
+ failed:
        return -ENODEV;
 }
 
@@ -283,7 +271,7 @@ static void serial_remove(struct pcmcia_device *link)
        struct serial_info *info = link->priv;
        int i;
 
-       DEBUG(0, "serial_release(0x%p)\n", link);
+       dev_dbg(&link->dev, "serial_release\n");
 
        /*
         * Recheck to see if the device is still configured.
@@ -334,7 +322,7 @@ static int serial_probe(struct pcmcia_device *link)
 {
        struct serial_info *info;
 
-       DEBUG(0, "serial_attach()\n");
+       dev_dbg(&link->dev, "serial_attach()\n");
 
        /* Create new serial device */
        info = kzalloc(sizeof (*info), GFP_KERNEL);
@@ -346,7 +334,6 @@ static int serial_probe(struct pcmcia_device *link)
        link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
        link->io.NumPorts1 = 8;
        link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
-       link->irq.IRQInfo1 = IRQ_LEVEL_ID;
        link->conf.Attributes = CONF_ENABLE_IRQ;
        if (do_sound) {
                link->conf.Attributes |= CONF_ENABLE_SPKR;
@@ -370,7 +357,7 @@ static void serial_detach(struct pcmcia_device *link)
 {
        struct serial_info *info = link->priv;
 
-       DEBUG(0, "serial_detach(0x%p)\n", link);
+       dev_dbg(&link->dev, "serial_detach\n");
 
        /*
         * Ensure any outstanding scheduled tasks are completed.
@@ -399,7 +386,7 @@ static int setup_serial(struct pcmcia_device *handle, struct serial_info * info,
        port.irq = irq;
        port.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_SHARE_IRQ;
        port.uartclk = 1843200;
-       port.dev = &handle_to_dev(handle);
+       port.dev = &handle->dev;
        if (buggy_uart)
                port.flags |= UPF_BUGGY_UART;
 
@@ -426,21 +413,6 @@ static int setup_serial(struct pcmcia_device *handle, struct serial_info * info,
 
 /*====================================================================*/
 
-static int
-first_tuple(struct pcmcia_device *handle, tuple_t * tuple, cisparse_t * parse)
-{
-       int i;
-       i = pcmcia_get_first_tuple(handle, tuple);
-       if (i != 0)
-               return i;
-       i = pcmcia_get_tuple_data(handle, tuple);
-       if (i != 0)
-               return i;
-       return pcmcia_parse_tuple(tuple, parse);
-}
-
-/*====================================================================*/
-
 static int simple_config_check(struct pcmcia_device *p_dev,
                               cistpl_cftable_entry_t *cf,
                               cistpl_cftable_entry_t *dflt,
@@ -522,15 +494,13 @@ static int simple_config(struct pcmcia_device *link)
 
        printk(KERN_NOTICE
               "serial_cs: no usable port range found, giving up\n");
-       cs_error(link, RequestIO, i);
        return -1;
 
 found_port:
        i = pcmcia_request_irq(link, &link->irq);
-       if (i != 0) {
-               cs_error(link, RequestIRQ, i);
+       if (i != 0)
                link->irq.AssignedIRQ = 0;
-       }
+
        if (info->multi && (info->manfid == MANFID_3COM))
                link->conf.ConfigIndex &= ~(0x08);
 
@@ -541,10 +511,8 @@ found_port:
                info->quirk->config(link);
 
        i = pcmcia_request_configuration(link, &link->conf);
-       if (i != 0) {
-               cs_error(link, RequestConfiguration, i);
+       if (i != 0)
                return -1;
-       }
        return setup_serial(link, info, link->io.BasePort1, link->irq.AssignedIRQ);
 }
 
@@ -613,7 +581,6 @@ static int multi_config(struct pcmcia_device *link)
                /* FIXME: comment does not fit, error handling does not fit */
                printk(KERN_NOTICE
                       "serial_cs: no usable port range found, giving up\n");
-               cs_error(link, RequestIRQ, i);
                link->irq.AssignedIRQ = 0;
        }
 
@@ -624,10 +591,8 @@ static int multi_config(struct pcmcia_device *link)
                info->quirk->config(link);
 
        i = pcmcia_request_configuration(link, &link->conf);
-       if (i != 0) {
-               cs_error(link, RequestConfiguration, i);
+       if (i != 0)
                return -ENODEV;
-       }
 
        /* The Oxford Semiconductor OXCF950 cards are in fact single-port:
         * 8 registers are for the UART, the others are extra registers.
@@ -665,6 +630,25 @@ static int multi_config(struct pcmcia_device *link)
        return 0;
 }
 
+static int serial_check_for_multi(struct pcmcia_device *p_dev,
+                                 cistpl_cftable_entry_t *cf,
+                                 cistpl_cftable_entry_t *dflt,
+                                 unsigned int vcc,
+                                 void *priv_data)
+{
+       struct serial_info *info = p_dev->priv;
+
+       if ((cf->io.nwin == 1) && (cf->io.win[0].len % 8 == 0))
+               info->multi = cf->io.win[0].len >> 3;
+
+       if ((cf->io.nwin == 2) && (cf->io.win[0].len == 8) &&
+               (cf->io.win[1].len == 8))
+               info->multi = 2;
+
+       return 0; /* break */
+}
+
+
 /*======================================================================
 
     serial_config() is scheduled to run after a CARD_INSERTION event
@@ -676,46 +660,14 @@ static int multi_config(struct pcmcia_device *link)
 static int serial_config(struct pcmcia_device * link)
 {
        struct serial_info *info = link->priv;
-       struct serial_cfg_mem *cfg_mem;
-       tuple_t *tuple;
-       u_char *buf;
-       cisparse_t *parse;
-       cistpl_cftable_entry_t *cf;
-       int i, last_ret, last_fn;
-
-       DEBUG(0, "serial_config(0x%p)\n", link);
-
-       cfg_mem = kmalloc(sizeof(struct serial_cfg_mem), GFP_KERNEL);
-       if (!cfg_mem)
-               goto failed;
+       int i;
 
-       tuple = &cfg_mem->tuple;
-       parse = &cfg_mem->parse;
-       cf = &parse->cftable_entry;
-       buf = cfg_mem->buf;
-
-       tuple->TupleData = (cisdata_t *) buf;
-       tuple->TupleOffset = 0;
-       tuple->TupleDataMax = 255;
-       tuple->Attributes = 0;
-
-       /* Get configuration register information */
-       tuple->DesiredTuple = CISTPL_CONFIG;
-       last_ret = first_tuple(link, tuple, parse);
-       if (last_ret != 0) {
-               last_fn = ParseTuple;
-               goto cs_failed;
-       }
-       link->conf.ConfigBase = parse->config.base;
-       link->conf.Present = parse->config.rmask[0];
+       dev_dbg(&link->dev, "serial_config\n");
 
        /* Is this a compliant multifunction card? */
-       tuple->DesiredTuple = CISTPL_LONGLINK_MFC;
-       tuple->Attributes = TUPLE_RETURN_COMMON | TUPLE_RETURN_LINK;
-       info->multi = (first_tuple(link, tuple, parse) == 0);
+       info->multi = (link->socket->functions > 1);
 
        /* Is this a multiport card? */
-       tuple->DesiredTuple = CISTPL_MANFID;
        info->manfid = link->manf_id;
        info->prodid = link->card_id;
 
@@ -730,20 +682,11 @@ static int serial_config(struct pcmcia_device * link)
 
        /* Another check for dual-serial cards: look for either serial or
           multifunction cards that ask for appropriate IO port ranges */
-       tuple->DesiredTuple = CISTPL_FUNCID;
        if ((info->multi == 0) &&
            (link->has_func_id) &&
            ((link->func_id == CISTPL_FUNCID_MULTI) ||
-            (link->func_id == CISTPL_FUNCID_SERIAL))) {
-               tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY;
-               if (first_tuple(link, tuple, parse) == 0) {
-                       if ((cf->io.nwin == 1) && (cf->io.win[0].len % 8 == 0))
-                               info->multi = cf->io.win[0].len >> 3;
-                       if ((cf->io.nwin == 2) && (cf->io.win[0].len == 8) &&
-                           (cf->io.win[1].len == 8))
-                               info->multi = 2;
-               }
-       }
+            (link->func_id == CISTPL_FUNCID_SERIAL)))
+               pcmcia_loop_config(link, serial_check_for_multi, info);
 
        /*
         * Apply any multi-port quirk.
@@ -768,14 +711,10 @@ static int serial_config(struct pcmcia_device * link)
                        goto failed;
 
        link->dev_node = &info->node[0];
-       kfree(cfg_mem);
        return 0;
 
-cs_failed:
-       cs_error(link, last_fn, last_ret);
 failed:
        serial_remove(link);
-       kfree(cfg_mem);
        return -ENODEV;
 }
 
index a2d4a19550ab9be4c5fbf99abf93c7e68e248ee1..ed7d958b0a01fa96a2f4a746189090cdce45bc6d 100644 (file)
@@ -53,20 +53,21 @@ void sunserial_unregister_minors(struct uart_driver *drv, int count)
 EXPORT_SYMBOL(sunserial_unregister_minors);
 
 int sunserial_console_match(struct console *con, struct device_node *dp,
-                           struct uart_driver *drv, int line)
+                           struct uart_driver *drv, int line, bool ignore_line)
 {
-       int off;
-
        if (!con || of_console_device != dp)
                return 0;
 
-       off = 0;
-       if (of_console_options &&
-           *of_console_options == 'b')
-               off = 1;
+       if (!ignore_line) {
+               int off = 0;
 
-       if ((line & 1) != off)
-               return 0;
+               if (of_console_options &&
+                   *of_console_options == 'b')
+                       off = 1;
+
+               if ((line & 1) != off)
+                       return 0;
+       }
 
        con->index = line;
        drv->cons = con;
@@ -76,23 +77,24 @@ int sunserial_console_match(struct console *con, struct device_node *dp,
 }
 EXPORT_SYMBOL(sunserial_console_match);
 
-void
-sunserial_console_termios(struct console *con)
+void sunserial_console_termios(struct console *con, struct device_node *uart_dp)
 {
-       struct device_node *dp;
-       const char *od, *mode, *s;
+       const char *mode, *s;
        char mode_prop[] = "ttyX-mode";
        int baud, bits, stop, cflag;
        char parity;
 
-       dp = of_find_node_by_path("/options");
-       od = of_get_property(dp, "output-device", NULL);
-       if (!strcmp(od, "rsc")) {
-               mode = of_get_property(of_console_device,
+       if (!strcmp(uart_dp->name, "rsc") ||
+           !strcmp(uart_dp->name, "rsc-console") ||
+           !strcmp(uart_dp->name, "rsc-control")) {
+               mode = of_get_property(uart_dp,
                                       "ssp-console-modes", NULL);
                if (!mode)
                        mode = "115200,8,n,1,-";
+       } else if (!strcmp(uart_dp->name, "lom-console")) {
+               mode = "9600,8,n,1,-";
        } else {
+               struct device_node *dp;
                char c;
 
                c = 'a';
@@ -101,6 +103,7 @@ sunserial_console_termios(struct console *con)
 
                mode_prop[3] = c;
 
+               dp = of_find_node_by_path("/options");
                mode = of_get_property(dp, mode_prop, NULL);
                if (!mode)
                        mode = "9600,8,n,1,-";
index 042668aa602e756f00d8c011dbcc4307c04709ef..db2057936c31ab6b2f981223e7e86e482364cd6e 100644 (file)
@@ -26,7 +26,8 @@ extern int sunserial_register_minors(struct uart_driver *, int);
 extern void sunserial_unregister_minors(struct uart_driver *, int);
 
 extern int sunserial_console_match(struct console *, struct device_node *,
-                                  struct uart_driver *, int);
-extern void sunserial_console_termios(struct console *);
+                                  struct uart_driver *, int, bool);
+extern void sunserial_console_termios(struct console *,
+                                     struct device_node *);
 
 #endif /* !(_SERIAL_SUN_H) */
index d548652dee5004f6608c3804ad33c07a072f6055..d14cca7fb88d2510f6c8fb2232160eff83c3efa4 100644 (file)
@@ -566,7 +566,7 @@ static int __devinit hv_probe(struct of_device *op, const struct of_device_id *m
                goto out_free_con_read_page;
 
        sunserial_console_match(&sunhv_console, op->node,
-                               &sunhv_reg, port->line);
+                               &sunhv_reg, port->line, false);
 
        err = uart_add_one_port(&sunhv_reg, port);
        if (err)
index d1ad34128635d215c83348bd57ee72bf88894f96..d514e28d07557b7516de0ecd7478d1cb9401f619 100644 (file)
@@ -883,7 +883,7 @@ static int sunsab_console_setup(struct console *con, char *options)
        printk("Console: ttyS%d (SAB82532)\n",
               (sunsab_reg.minor - 64) + con->index);
 
-       sunserial_console_termios(con);
+       sunserial_console_termios(con, to_of_device(up->port.dev)->node);
 
        switch (con->cflag & CBAUD) {
        case B150: baud = 150; break;
@@ -1027,10 +1027,12 @@ static int __devinit sab_probe(struct of_device *op, const struct of_device_id *
                goto out1;
 
        sunserial_console_match(SUNSAB_CONSOLE(), op->node,
-                               &sunsab_reg, up[0].port.line);
+                               &sunsab_reg, up[0].port.line,
+                               false);
 
        sunserial_console_match(SUNSAB_CONSOLE(), op->node,
-                               &sunsab_reg, up[1].port.line);
+                               &sunsab_reg, up[1].port.line,
+                               false);
 
        err = uart_add_one_port(&sunsab_reg, &up[0].port);
        if (err)
@@ -1116,7 +1118,6 @@ static int __init sunsab_init(void)
                if (!sunsab_ports)
                        return -ENOMEM;
 
-               sunsab_reg.cons = SUNSAB_CONSOLE();
                err = sunserial_register_minors(&sunsab_reg, num_channels);
                if (err) {
                        kfree(sunsab_ports);
index 68d262b15749584354defe8c5bf7a886383dad76..170d3d68c8f04d38fb67f8d3b84c9c977f57f7a1 100644 (file)
@@ -1329,11 +1329,9 @@ static void sunsu_console_write(struct console *co, const char *s,
  */
 static int __init sunsu_console_setup(struct console *co, char *options)
 {
+       static struct ktermios dummy;
+       struct ktermios termios;
        struct uart_port *port;
-       int baud = 9600;
-       int bits = 8;
-       int parity = 'n';
-       int flow = 'n';
 
        printk("Console: ttyS%d (SU)\n",
               (sunsu_reg.minor - 64) + co->index);
@@ -1352,10 +1350,15 @@ static int __init sunsu_console_setup(struct console *co, char *options)
         */
        spin_lock_init(&port->lock);
 
-       if (options)
-               uart_parse_options(options, &baud, &parity, &bits, &flow);
+       /* Get firmware console settings.  */
+       sunserial_console_termios(co, to_of_device(port->dev)->node);
 
-       return uart_set_options(port, co, baud, parity, bits, flow);
+       memset(&termios, 0, sizeof(struct ktermios));
+       termios.c_cflag = co->cflag;
+       port->mctrl |= TIOCM_DTR;
+       port->ops->set_termios(port, &termios, &dummy);
+
+       return 0;
 }
 
 static struct console sunsu_console = {
@@ -1409,6 +1412,7 @@ static int __devinit su_probe(struct of_device *op, const struct of_device_id *m
        struct uart_sunsu_port *up;
        struct resource *rp;
        enum su_type type;
+       bool ignore_line;
        int err;
 
        type = su_get_type(dp);
@@ -1467,8 +1471,14 @@ static int __devinit su_probe(struct of_device *op, const struct of_device_id *m
 
        up->port.ops = &sunsu_pops;
 
+       ignore_line = false;
+       if (!strcmp(dp->name, "rsc-console") ||
+           !strcmp(dp->name, "lom-console"))
+               ignore_line = true;
+
        sunserial_console_match(SUNSU_CONSOLE(), dp,
-                               &sunsu_reg, up->port.line);
+                               &sunsu_reg, up->port.line,
+                               ignore_line);
        err = uart_add_one_port(&sunsu_reg, &up->port);
        if (err)
                goto out_unmap;
@@ -1517,6 +1527,10 @@ static const struct of_device_id su_match[] = {
                .name = "serial",
                .compatible = "su",
        },
+       {
+               .type = "serial",
+               .compatible = "su",
+       },
        {},
 };
 MODULE_DEVICE_TABLE(of, su_match);
@@ -1548,6 +1562,12 @@ static int __init sunsu_init(void)
                                num_uart++;
                }
        }
+       for_each_node_by_type(dp, "serial") {
+               if (of_device_is_compatible(dp, "su")) {
+                       if (su_get_type(dp) == SU_PORT_PORT)
+                               num_uart++;
+               }
+       }
 
        if (num_uart) {
                err = sunserial_register_minors(&sunsu_reg, num_uart);
index ef693ae22e7fc98e307eaf6a16a4d4ce7207fd72..2c7a66af4f5289047395cca207dedbd3a311cac2 100644 (file)
@@ -1180,7 +1180,7 @@ static int __init sunzilog_console_setup(struct console *con, char *options)
               (sunzilog_reg.minor - 64) + con->index, con->index);
 
        /* Get firmware console settings.  */
-       sunserial_console_termios(con);
+       sunserial_console_termios(con, to_of_device(up->port.dev)->node);
 
        /* Firmware console speed is limited to 150-->38400 baud so
         * this hackish cflag thing is OK.
@@ -1416,7 +1416,8 @@ static int __devinit zs_probe(struct of_device *op, const struct of_device_id *m
 
        if (!keyboard_mouse) {
                if (sunserial_console_match(SUNZILOG_CONSOLE(), op->node,
-                                           &sunzilog_reg, up[0].port.line))
+                                           &sunzilog_reg, up[0].port.line,
+                                           false))
                        up->flags |= SUNZILOG_FLAG_IS_CONS;
                err = uart_add_one_port(&sunzilog_reg, &up[0].port);
                if (err) {
@@ -1425,7 +1426,8 @@ static int __devinit zs_probe(struct of_device *op, const struct of_device_id *m
                        return err;
                }
                if (sunserial_console_match(SUNZILOG_CONSOLE(), op->node,
-                                           &sunzilog_reg, up[1].port.line))
+                                           &sunzilog_reg, up[1].port.line,
+                                           false))
                        up->flags |= SUNZILOG_FLAG_IS_CONS;
                err = uart_add_one_port(&sunzilog_reg, &up[1].port);
                if (err) {
index d871dc23909ca856bb11b467ae09cb5f60fc7f14..2552bb36400564f58a66285647a7faa951090be8 100644 (file)
@@ -242,7 +242,7 @@ static int stmp_spi_txrx_dma(struct stmp_spi *ss, int cs,
        wait_for_completion(&ss->done);
 
        if (!busy_wait(readl(ss->regs + HW_SSP_CTRL0) & BM_SSP_CTRL0_RUN))
-               status = ETIMEDOUT;
+               status = -ETIMEDOUT;
 
        if (!dma_buf)
                dma_unmap_single(ss->master_dev, spi_buf_dma, len, dir);
index 96057de133ad311a3159944c69adcb70b63930ec..19f75627c3deaf0dd0d31a38689a550abf66f488 100644 (file)
@@ -29,6 +29,8 @@
 
 
 #define SPI_FIFO_SIZE 4
+#define SPI_MAX_DIVIDER 0xff   /* Max. value for SPCR1.SER */
+#define SPI_MIN_DIVIDER 1      /* Min. value for SPCR1.SER */
 
 #define TXx9_SPMCR             0x00
 #define TXx9_SPCR0             0x04
@@ -193,11 +195,8 @@ static void txx9spi_work_one(struct txx9spi *c, struct spi_message *m)
 
                if (prev_speed_hz != speed_hz
                                || prev_bits_per_word != bits_per_word) {
-                       u32 n = (c->baseclk + speed_hz - 1) / speed_hz;
-                       if (n < 1)
-                               n = 1;
-                       else if (n > 0xff)
-                               n = 0xff;
+                       int n = DIV_ROUND_UP(c->baseclk, speed_hz) - 1;
+                       n = clamp(n, SPI_MIN_DIVIDER, SPI_MAX_DIVIDER);
                        /* enter config mode */
                        txx9spi_wr(c, mcr | TXx9_SPMCR_CONFIG | TXx9_SPMCR_BCLR,
                                        TXx9_SPMCR);
@@ -370,8 +369,8 @@ static int __init txx9spi_probe(struct platform_device *dev)
                goto exit;
        }
        c->baseclk = clk_get_rate(c->clk);
-       c->min_speed_hz = (c->baseclk + 0xff - 1) / 0xff;
-       c->max_speed_hz = c->baseclk;
+       c->min_speed_hz = DIV_ROUND_UP(c->baseclk, SPI_MAX_DIVIDER + 1);
+       c->max_speed_hz = c->baseclk / (SPI_MIN_DIVIDER + 1);
 
        res = platform_get_resource(dev, IORESOURCE_MEM, 0);
        if (!res)
index 100e7a5c5ea1f3a48991845ba1e1cf06758e462c..e72f4046a5e0ee1cccb46a7bd11362261f9f3e0b 100644 (file)
@@ -617,136 +617,140 @@ static int ssb_pcmcia_sprom_check_crc(const u16 *sprom, size_t size)
        }                                               \
   } while (0)
 
-int ssb_pcmcia_get_invariants(struct ssb_bus *bus,
-                             struct ssb_init_invariants *iv)
+static int ssb_pcmcia_get_mac(struct pcmcia_device *p_dev,
+                       tuple_t *tuple,
+                       void *priv)
 {
-       tuple_t tuple;
-       int res;
-       unsigned char buf[32];
+       struct ssb_sprom *sprom = priv;
+
+       if (tuple->TupleData[0] != CISTPL_FUNCE_LAN_NODE_ID)
+               return -EINVAL;
+       if (tuple->TupleDataLen != ETH_ALEN + 2)
+               return -EINVAL;
+       if (tuple->TupleData[1] != ETH_ALEN)
+               return -EINVAL;
+       memcpy(sprom->il0mac, &tuple->TupleData[2], ETH_ALEN);
+       return 0;
+};
+
+static int ssb_pcmcia_do_get_invariants(struct pcmcia_device *p_dev,
+                                       tuple_t *tuple,
+                                       void *priv)
+{
+       struct ssb_init_invariants *iv = priv;
        struct ssb_sprom *sprom = &iv->sprom;
        struct ssb_boardinfo *bi = &iv->boardinfo;
        const char *error_description;
 
+       GOTO_ERROR_ON(tuple->TupleDataLen < 1, "VEN tpl < 1");
+       switch (tuple->TupleData[0]) {
+       case SSB_PCMCIA_CIS_ID:
+               GOTO_ERROR_ON((tuple->TupleDataLen != 5) &&
+                             (tuple->TupleDataLen != 7),
+                             "id tpl size");
+               bi->vendor = tuple->TupleData[1] |
+                       ((u16)tuple->TupleData[2] << 8);
+               break;
+       case SSB_PCMCIA_CIS_BOARDREV:
+               GOTO_ERROR_ON(tuple->TupleDataLen != 2,
+                       "boardrev tpl size");
+               sprom->board_rev = tuple->TupleData[1];
+               break;
+       case SSB_PCMCIA_CIS_PA:
+               GOTO_ERROR_ON((tuple->TupleDataLen != 9) &&
+                       (tuple->TupleDataLen != 10),
+                       "pa tpl size");
+               sprom->pa0b0 = tuple->TupleData[1] |
+                       ((u16)tuple->TupleData[2] << 8);
+               sprom->pa0b1 = tuple->TupleData[3] |
+                       ((u16)tuple->TupleData[4] << 8);
+               sprom->pa0b2 = tuple->TupleData[5] |
+                       ((u16)tuple->TupleData[6] << 8);
+               sprom->itssi_a = tuple->TupleData[7];
+               sprom->itssi_bg = tuple->TupleData[7];
+               sprom->maxpwr_a = tuple->TupleData[8];
+               sprom->maxpwr_bg = tuple->TupleData[8];
+               break;
+       case SSB_PCMCIA_CIS_OEMNAME:
+               /* We ignore this. */
+               break;
+       case SSB_PCMCIA_CIS_CCODE:
+               GOTO_ERROR_ON(tuple->TupleDataLen != 2,
+                       "ccode tpl size");
+               sprom->country_code = tuple->TupleData[1];
+               break;
+       case SSB_PCMCIA_CIS_ANTENNA:
+               GOTO_ERROR_ON(tuple->TupleDataLen != 2,
+                       "ant tpl size");
+               sprom->ant_available_a = tuple->TupleData[1];
+               sprom->ant_available_bg = tuple->TupleData[1];
+               break;
+       case SSB_PCMCIA_CIS_ANTGAIN:
+               GOTO_ERROR_ON(tuple->TupleDataLen != 2,
+                       "antg tpl size");
+               sprom->antenna_gain.ghz24.a0 = tuple->TupleData[1];
+               sprom->antenna_gain.ghz24.a1 = tuple->TupleData[1];
+               sprom->antenna_gain.ghz24.a2 = tuple->TupleData[1];
+               sprom->antenna_gain.ghz24.a3 = tuple->TupleData[1];
+               sprom->antenna_gain.ghz5.a0 = tuple->TupleData[1];
+               sprom->antenna_gain.ghz5.a1 = tuple->TupleData[1];
+               sprom->antenna_gain.ghz5.a2 = tuple->TupleData[1];
+               sprom->antenna_gain.ghz5.a3 = tuple->TupleData[1];
+               break;
+       case SSB_PCMCIA_CIS_BFLAGS:
+               GOTO_ERROR_ON((tuple->TupleDataLen != 3) &&
+                       (tuple->TupleDataLen != 5),
+                       "bfl tpl size");
+               sprom->boardflags_lo = tuple->TupleData[1] |
+                       ((u16)tuple->TupleData[2] << 8);
+               break;
+       case SSB_PCMCIA_CIS_LEDS:
+               GOTO_ERROR_ON(tuple->TupleDataLen != 5,
+                       "leds tpl size");
+               sprom->gpio0 = tuple->TupleData[1];
+               sprom->gpio1 = tuple->TupleData[2];
+               sprom->gpio2 = tuple->TupleData[3];
+               sprom->gpio3 = tuple->TupleData[4];
+               break;
+       }
+       return -ENOSPC; /* continue with next entry */
+
+error:
+       ssb_printk(KERN_ERR PFX
+                  "PCMCIA: Failed to fetch device invariants: %s\n",
+                  error_description);
+       return -ENODEV;
+}
+
+
+int ssb_pcmcia_get_invariants(struct ssb_bus *bus,
+                             struct ssb_init_invariants *iv)
+{
+       struct ssb_sprom *sprom = &iv->sprom;
+       int res;
+
        memset(sprom, 0xFF, sizeof(*sprom));
        sprom->revision = 1;
        sprom->boardflags_lo = 0;
        sprom->boardflags_hi = 0;
 
        /* First fetch the MAC address. */
-       memset(&tuple, 0, sizeof(tuple));
-       tuple.DesiredTuple = CISTPL_FUNCE;
-       tuple.TupleData = buf;
-       tuple.TupleDataMax = sizeof(buf);
-       res = pcmcia_get_first_tuple(bus->host_pcmcia, &tuple);
-       GOTO_ERROR_ON(res != 0, "MAC first tpl");
-       res = pcmcia_get_tuple_data(bus->host_pcmcia, &tuple);
-       GOTO_ERROR_ON(res != 0, "MAC first tpl data");
-       while (1) {
-               GOTO_ERROR_ON(tuple.TupleDataLen < 1, "MAC tpl < 1");
-               if (tuple.TupleData[0] == CISTPL_FUNCE_LAN_NODE_ID)
-                       break;
-               res = pcmcia_get_next_tuple(bus->host_pcmcia, &tuple);
-               GOTO_ERROR_ON(res != 0, "MAC next tpl");
-               res = pcmcia_get_tuple_data(bus->host_pcmcia, &tuple);
-               GOTO_ERROR_ON(res != 0, "MAC next tpl data");
+       res = pcmcia_loop_tuple(bus->host_pcmcia, CISTPL_FUNCE,
+                               ssb_pcmcia_get_mac, sprom);
+       if (res != 0) {
+               ssb_printk(KERN_ERR PFX
+                       "PCMCIA: Failed to fetch MAC address\n");
+               return -ENODEV;
        }
-       GOTO_ERROR_ON(tuple.TupleDataLen != ETH_ALEN + 2, "MAC tpl size");
-       memcpy(sprom->il0mac, &tuple.TupleData[2], ETH_ALEN);
 
        /* Fetch the vendor specific tuples. */
-       memset(&tuple, 0, sizeof(tuple));
-       tuple.DesiredTuple = SSB_PCMCIA_CIS;
-       tuple.TupleData = buf;
-       tuple.TupleDataMax = sizeof(buf);
-       res = pcmcia_get_first_tuple(bus->host_pcmcia, &tuple);
-       GOTO_ERROR_ON(res != 0, "VEN first tpl");
-       res = pcmcia_get_tuple_data(bus->host_pcmcia, &tuple);
-       GOTO_ERROR_ON(res != 0, "VEN first tpl data");
-       while (1) {
-               GOTO_ERROR_ON(tuple.TupleDataLen < 1, "VEN tpl < 1");
-               switch (tuple.TupleData[0]) {
-               case SSB_PCMCIA_CIS_ID:
-                       GOTO_ERROR_ON((tuple.TupleDataLen != 5) &&
-                                     (tuple.TupleDataLen != 7),
-                                     "id tpl size");
-                       bi->vendor = tuple.TupleData[1] |
-                              ((u16)tuple.TupleData[2] << 8);
-                       break;
-               case SSB_PCMCIA_CIS_BOARDREV:
-                       GOTO_ERROR_ON(tuple.TupleDataLen != 2,
-                                     "boardrev tpl size");
-                       sprom->board_rev = tuple.TupleData[1];
-                       break;
-               case SSB_PCMCIA_CIS_PA:
-                       GOTO_ERROR_ON((tuple.TupleDataLen != 9) &&
-                                     (tuple.TupleDataLen != 10),
-                                     "pa tpl size");
-                       sprom->pa0b0 = tuple.TupleData[1] |
-                                ((u16)tuple.TupleData[2] << 8);
-                       sprom->pa0b1 = tuple.TupleData[3] |
-                                ((u16)tuple.TupleData[4] << 8);
-                       sprom->pa0b2 = tuple.TupleData[5] |
-                                ((u16)tuple.TupleData[6] << 8);
-                       sprom->itssi_a = tuple.TupleData[7];
-                       sprom->itssi_bg = tuple.TupleData[7];
-                       sprom->maxpwr_a = tuple.TupleData[8];
-                       sprom->maxpwr_bg = tuple.TupleData[8];
-                       break;
-               case SSB_PCMCIA_CIS_OEMNAME:
-                       /* We ignore this. */
-                       break;
-               case SSB_PCMCIA_CIS_CCODE:
-                       GOTO_ERROR_ON(tuple.TupleDataLen != 2,
-                                     "ccode tpl size");
-                       sprom->country_code = tuple.TupleData[1];
-                       break;
-               case SSB_PCMCIA_CIS_ANTENNA:
-                       GOTO_ERROR_ON(tuple.TupleDataLen != 2,
-                                     "ant tpl size");
-                       sprom->ant_available_a = tuple.TupleData[1];
-                       sprom->ant_available_bg = tuple.TupleData[1];
-                       break;
-               case SSB_PCMCIA_CIS_ANTGAIN:
-                       GOTO_ERROR_ON(tuple.TupleDataLen != 2,
-                                     "antg tpl size");
-                       sprom->antenna_gain.ghz24.a0 = tuple.TupleData[1];
-                       sprom->antenna_gain.ghz24.a1 = tuple.TupleData[1];
-                       sprom->antenna_gain.ghz24.a2 = tuple.TupleData[1];
-                       sprom->antenna_gain.ghz24.a3 = tuple.TupleData[1];
-                       sprom->antenna_gain.ghz5.a0 = tuple.TupleData[1];
-                       sprom->antenna_gain.ghz5.a1 = tuple.TupleData[1];
-                       sprom->antenna_gain.ghz5.a2 = tuple.TupleData[1];
-                       sprom->antenna_gain.ghz5.a3 = tuple.TupleData[1];
-                       break;
-               case SSB_PCMCIA_CIS_BFLAGS:
-                       GOTO_ERROR_ON((tuple.TupleDataLen != 3) &&
-                                     (tuple.TupleDataLen != 5),
-                                     "bfl tpl size");
-                       sprom->boardflags_lo = tuple.TupleData[1] |
-                                        ((u16)tuple.TupleData[2] << 8);
-                       break;
-               case SSB_PCMCIA_CIS_LEDS:
-                       GOTO_ERROR_ON(tuple.TupleDataLen != 5,
-                                     "leds tpl size");
-                       sprom->gpio0 = tuple.TupleData[1];
-                       sprom->gpio1 = tuple.TupleData[2];
-                       sprom->gpio2 = tuple.TupleData[3];
-                       sprom->gpio3 = tuple.TupleData[4];
-                       break;
-               }
-               res = pcmcia_get_next_tuple(bus->host_pcmcia, &tuple);
-               if (res == -ENOSPC)
-                       break;
-               GOTO_ERROR_ON(res != 0, "VEN next tpl");
-               res = pcmcia_get_tuple_data(bus->host_pcmcia, &tuple);
-               GOTO_ERROR_ON(res != 0, "VEN next tpl data");
-       }
+       res = pcmcia_loop_tuple(bus->host_pcmcia, SSB_PCMCIA_CIS,
+                               ssb_pcmcia_do_get_invariants, sprom);
+       if ((res == 0) || (res == -ENOSPC))
+               return 0;
 
-       return 0;
-error:
        ssb_printk(KERN_ERR PFX
-                  "PCMCIA: Failed to fetch device invariants: %s\n",
-                  error_description);
+                       "PCMCIA: Failed to fetch device invariants\n");
        return -ENODEV;
 }
 
index b74212d698c78b8d39c541ec44d2857cb9ad0e19..e8b89e8ac9bd96ed1279d0602f4aeee8fc050b84 100644 (file)
@@ -162,6 +162,8 @@ static u8 chipid_to_nrcores(u16 chipid)
 static u32 scan_read32(struct ssb_bus *bus, u8 current_coreidx,
                       u16 offset)
 {
+       u32 lo, hi;
+
        switch (bus->bustype) {
        case SSB_BUSTYPE_SSB:
                offset += current_coreidx * SSB_CORE_SIZE;
@@ -174,7 +176,9 @@ static u32 scan_read32(struct ssb_bus *bus, u8 current_coreidx,
                        offset -= 0x800;
                } else
                        ssb_pcmcia_switch_segment(bus, 0);
-               break;
+               lo = readw(bus->mmio + offset);
+               hi = readw(bus->mmio + offset + 2);
+               return lo | (hi << 16);
        case SSB_BUSTYPE_SDIO:
                offset += current_coreidx * SSB_CORE_SIZE;
                return ssb_sdio_scan_read32(bus, offset);
index 80c0df8656f317d5517d49bd2df494a95fb10f13..39923cb388be5053c09a3e3b4e3ce28ffa72b51f 100644 (file)
@@ -141,37 +141,14 @@ static int das16cs_timer_insn_config(struct comedi_device *dev,
                                     struct comedi_insn *insn,
                                     unsigned int *data);
 
-static int get_prodid(struct comedi_device *dev, struct pcmcia_device *link)
-{
-       tuple_t tuple;
-       u_short buf[128];
-       int prodid = 0;
-
-       tuple.TupleData = (cisdata_t *) buf;
-       tuple.TupleOffset = 0;
-       tuple.TupleDataMax = 255;
-       tuple.DesiredTuple = CISTPL_MANFID;
-       tuple.Attributes = TUPLE_RETURN_COMMON;
-       if ((pcmcia_get_first_tuple(link, &tuple) == 0) &&
-           (pcmcia_get_tuple_data(link, &tuple) == 0)) {
-               prodid = le16_to_cpu(buf[1]);
-       }
-
-       return prodid;
-}
-
 static const struct das16cs_board *das16cs_probe(struct comedi_device *dev,
                                                 struct pcmcia_device *link)
 {
-       int id;
        int i;
 
-       id = get_prodid(dev, link);
-
        for (i = 0; i < n_boards; i++) {
-               if (das16cs_boards[i].device_id == id) {
+               if (das16cs_boards[i].device_id == link->card_id)
                        return das16cs_boards + i;
-               }
        }
 
        printk("unknown board!\n");
@@ -660,27 +637,8 @@ static int das16cs_timer_insn_config(struct comedi_device *dev,
 
 ======================================================================*/
 
-/*
-   All the PCMCIA modules use PCMCIA_DEBUG to control debugging.  If
-   you do not define PCMCIA_DEBUG at all, all the debug code will be
-   left out.  If you compile with PCMCIA_DEBUG=0, the debug code will
-   be present but disabled -- but it can then be enabled for specific
-   modules at load time with a 'pc_debug=#' option to insmod.
-*/
 #if defined(CONFIG_PCMCIA) || defined(CONFIG_PCMCIA_MODULE)
 
-#ifdef PCMCIA_DEBUG
-static int pc_debug = PCMCIA_DEBUG;
-module_param(pc_debug, int, 0644);
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
-static char *version =
-    "cb_das16_cs.c pcmcia code (David Schleef), modified from dummy_cs.c 1.31 2001/08/24 12:13:13 (David Hinds)";
-#else
-#define DEBUG(n, args...)
-#endif
-
-/*====================================================================*/
-
 static void das16cs_pcmcia_config(struct pcmcia_device *link);
 static void das16cs_pcmcia_release(struct pcmcia_device *link);
 static int das16cs_pcmcia_suspend(struct pcmcia_device *p_dev);
@@ -733,7 +691,7 @@ static int das16cs_pcmcia_attach(struct pcmcia_device *link)
 {
        struct local_info_t *local;
 
-       DEBUG(0, "das16cs_pcmcia_attach()\n");
+       dev_dbg(&link->dev, "das16cs_pcmcia_attach()\n");
 
        /* Allocate space for private device-specific data */
        local = kzalloc(sizeof(struct local_info_t), GFP_KERNEL);
@@ -745,7 +703,6 @@ static int das16cs_pcmcia_attach(struct pcmcia_device *link)
        /* Initialize the pcmcia_device structure */
        /* Interrupt setup */
        link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
-       link->irq.IRQInfo1 = IRQ_LEVEL_ID;
        link->irq.Handler = NULL;
 
        link->conf.Attributes = 0;
@@ -760,7 +717,7 @@ static int das16cs_pcmcia_attach(struct pcmcia_device *link)
 
 static void das16cs_pcmcia_detach(struct pcmcia_device *link)
 {
-       DEBUG(0, "das16cs_pcmcia_detach(0x%p)\n", link);
+       dev_dbg(&link->dev, "das16cs_pcmcia_detach\n");
 
        if (link->dev_node) {
                ((struct local_info_t *)link->priv)->stop = 1;
@@ -771,118 +728,55 @@ static void das16cs_pcmcia_detach(struct pcmcia_device *link)
                kfree(link->priv);
 }                              /* das16cs_pcmcia_detach */
 
-static void das16cs_pcmcia_config(struct pcmcia_device *link)
-{
-       struct local_info_t *dev = link->priv;
-       tuple_t tuple;
-       cisparse_t parse;
-       int last_fn, last_ret;
-       u_char buf[64];
-       cistpl_cftable_entry_t dflt = { 0 };
 
-       DEBUG(0, "das16cs_pcmcia_config(0x%p)\n", link);
-
-       /*
-          This reads the card's CONFIG tuple to find its configuration
-          registers.
-        */
-       tuple.DesiredTuple = CISTPL_CONFIG;
-       tuple.Attributes = 0;
-       tuple.TupleData = buf;
-       tuple.TupleDataMax = sizeof(buf);
-       tuple.TupleOffset = 0;
-
-       last_fn = GetFirstTuple;
-       last_ret = pcmcia_get_first_tuple(link, &tuple);
-       if (last_ret != 0)
-               goto cs_failed;
-
-       last_fn = GetTupleData;
-       last_ret = pcmcia_get_tuple_data(link, &tuple);
-       if (last_ret != 0)
-               goto cs_failed;
-
-       last_fn = ParseTuple;
-       last_ret = pcmcia_parse_tuple(&tuple, &parse);
-       if (last_ret != 0)
-               goto cs_failed;
-
-       link->conf.ConfigBase = parse.config.base;
-       link->conf.Present = parse.config.rmask[0];
+static int das16cs_pcmcia_config_loop(struct pcmcia_device *p_dev,
+                               cistpl_cftable_entry_t *cfg,
+                               cistpl_cftable_entry_t *dflt,
+                               unsigned int vcc,
+                               void *priv_data)
+{
+       if (cfg->index == 0)
+               return -EINVAL;
 
-       /*
-          In this loop, we scan the CIS for configuration table entries,
-          each of which describes a valid card configuration, including
-          voltage, IO window, memory window, and interrupt settings.
-
-          We make no assumptions about the card to be configured: we use
-          just the information available in the CIS.  In an ideal world,
-          this would work for any PCMCIA card, but it requires a complete
-          and accurate CIS.  In practice, a driver usually "knows" most of
-          these things without consulting the CIS, and most client drivers
-          will only use the CIS to fill in implementation-defined details.
-        */
-       tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
-       last_fn = GetFirstTuple;
-
-       last_ret = pcmcia_get_first_tuple(link, &tuple);
-       if (last_ret)
-               goto cs_failed;
-
-       while (1) {
-               cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
-               if (pcmcia_get_tuple_data(link, &tuple))
-                       goto next_entry;
-               if (pcmcia_parse_tuple(&tuple, &parse))
-                       goto next_entry;
-
-               if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
-                       dflt = *cfg;
-               if (cfg->index == 0)
-                       goto next_entry;
-               link->conf.ConfigIndex = cfg->index;
-
-               /* Does this card need audio output? */
-/*     if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
-               link->conf.Attributes |= CONF_ENABLE_SPKR;
-               link->conf.Status = CCSR_AUDIO_ENA;
-       }
-*/
-               /* Do we need to allocate an interrupt? */
-               if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1)
-                       link->conf.Attributes |= CONF_ENABLE_IRQ;
-
-               /* IO window settings */
-               link->io.NumPorts1 = link->io.NumPorts2 = 0;
-               if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
-                       cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
-                       link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
-                       if (!(io->flags & CISTPL_IO_8BIT))
-                               link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
-                       if (!(io->flags & CISTPL_IO_16BIT))
-                               link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
-                       link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
-                       link->io.BasePort1 = io->win[0].base;
-                       link->io.NumPorts1 = io->win[0].len;
-                       if (io->nwin > 1) {
-                               link->io.Attributes2 = link->io.Attributes1;
-                               link->io.BasePort2 = io->win[1].base;
-                               link->io.NumPorts2 = io->win[1].len;
-                       }
-                       /* This reserves IO space but doesn't actually enable it */
-                       if (pcmcia_request_io(link, &link->io))
-                               goto next_entry;
+       /* Do we need to allocate an interrupt? */
+       if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1)
+               p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
+
+       /* IO window settings */
+       p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
+       if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
+               cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
+               p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
+               if (!(io->flags & CISTPL_IO_8BIT))
+                       p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
+               if (!(io->flags & CISTPL_IO_16BIT))
+                       p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
+               p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
+               p_dev->io.BasePort1 = io->win[0].base;
+               p_dev->io.NumPorts1 = io->win[0].len;
+               if (io->nwin > 1) {
+                       p_dev->io.Attributes2 = p_dev->io.Attributes1;
+                       p_dev->io.BasePort2 = io->win[1].base;
+                       p_dev->io.NumPorts2 = io->win[1].len;
                }
+               /* This reserves IO space but doesn't actually enable it */
+               return pcmcia_request_io(p_dev, &p_dev->io);
+       }
 
-               /* If we got this far, we're cool! */
-               break;
+       return 0;
+}
+
+static void das16cs_pcmcia_config(struct pcmcia_device *link)
+{
+       struct local_info_t *dev = link->priv;
+       int ret;
 
-next_entry:
-               last_fn = GetNextTuple;
+       dev_dbg(&link->dev, "das16cs_pcmcia_config\n");
 
-               last_ret = pcmcia_get_next_tuple(link, &tuple);
-               if (last_ret)
-                       goto cs_failed;
+       ret = pcmcia_loop_config(link, das16cs_pcmcia_config_loop, NULL);
+       if (ret) {
+               dev_warn(&link->dev, "no configuration found\n");
+               goto failed;
        }
 
        /*
@@ -891,21 +785,18 @@ next_entry:
           irq structure is initialized.
         */
        if (link->conf.Attributes & CONF_ENABLE_IRQ) {
-               last_fn = RequestIRQ;
-
-               last_ret = pcmcia_request_irq(link, &link->irq);
-               if (last_ret)
-                       goto cs_failed;
+               ret = pcmcia_request_irq(link, &link->irq);
+               if (ret)
+                       goto failed;
        }
        /*
           This actually configures the PCMCIA socket -- setting up
           the I/O windows and the interrupt mapping, and putting the
           card and host interface into "Memory and IO" mode.
         */
-       last_fn = RequestConfiguration;
-       last_ret = pcmcia_request_configuration(link, &link->conf);
-       if (last_ret)
-               goto cs_failed;
+       ret = pcmcia_request_configuration(link, &link->conf);
+       if (ret)
+               goto failed;
 
        /*
           At this point, the dev_node_t structure(s) need to be
@@ -930,14 +821,13 @@ next_entry:
 
        return;
 
-cs_failed:
-       cs_error(link, last_fn, last_ret);
+failed:
        das16cs_pcmcia_release(link);
 }                              /* das16cs_pcmcia_config */
 
 static void das16cs_pcmcia_release(struct pcmcia_device *link)
 {
-       DEBUG(0, "das16cs_pcmcia_release(0x%p)\n", link);
+       dev_dbg(&link->dev, "das16cs_pcmcia_release\n");
        pcmcia_disable_device(link);
 }                              /* das16cs_pcmcia_release */
 
@@ -983,14 +873,13 @@ struct pcmcia_driver das16cs_driver = {
 
 static int __init init_das16cs_pcmcia_cs(void)
 {
-       DEBUG(0, "%s\n", version);
        pcmcia_register_driver(&das16cs_driver);
        return 0;
 }
 
 static void __exit exit_das16cs_pcmcia_cs(void)
 {
-       DEBUG(0, "das16cs_pcmcia_cs: unloading\n");
+       pr_debug("das16cs_pcmcia_cs: unloading\n");
        pcmcia_unregister_driver(&das16cs_driver);
 }
 
index 9cab21eaaa186f23e8179f22e13b578dffa34f7f..9b945e5fdd32a026b3c713aaa58b0b9022ac1391 100644 (file)
@@ -110,25 +110,6 @@ static int das08_cs_attach(struct comedi_device *dev,
 
 ======================================================================*/
 
-/*
-   All the PCMCIA modules use PCMCIA_DEBUG to control debugging.  If
-   you do not define PCMCIA_DEBUG at all, all the debug code will be
-   left out.  If you compile with PCMCIA_DEBUG=0, the debug code will
-   be present but disabled -- but it can then be enabled for specific
-   modules at load time with a 'pc_debug=#' option to insmod.
-*/
-
-#ifdef PCMCIA_DEBUG
-static int pc_debug = PCMCIA_DEBUG;
-module_param(pc_debug, int, 0644);
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
-static const char *version =
-    "das08.c pcmcia code (Frank Hess), modified from dummy_cs.c 1.31 2001/08/24 12:13:13 (David Hinds)";
-#else
-#define DEBUG(n, args...)
-#endif
-
-/*====================================================================*/
 static void das08_pcmcia_config(struct pcmcia_device *link);
 static void das08_pcmcia_release(struct pcmcia_device *link);
 static int das08_pcmcia_suspend(struct pcmcia_device *p_dev);
@@ -181,7 +162,7 @@ static int das08_pcmcia_attach(struct pcmcia_device *link)
 {
        struct local_info_t *local;
 
-       DEBUG(0, "das08_pcmcia_attach()\n");
+       dev_dbg(&link->dev, "das08_pcmcia_attach()\n");
 
        /* Allocate space for private device-specific data */
        local = kzalloc(sizeof(struct local_info_t), GFP_KERNEL);
@@ -192,7 +173,6 @@ static int das08_pcmcia_attach(struct pcmcia_device *link)
 
        /* Interrupt setup */
        link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
-       link->irq.IRQInfo1 = IRQ_LEVEL_ID;
        link->irq.Handler = NULL;
 
        /*
@@ -224,7 +204,7 @@ static int das08_pcmcia_attach(struct pcmcia_device *link)
 static void das08_pcmcia_detach(struct pcmcia_device *link)
 {
 
-       DEBUG(0, "das08_pcmcia_detach(0x%p)\n", link);
+       dev_dbg(&link->dev, "das08_pcmcia_detach\n");
 
        if (link->dev_node) {
                ((struct local_info_t *)link->priv)->stop = 1;
@@ -237,6 +217,44 @@ static void das08_pcmcia_detach(struct pcmcia_device *link)
 
 }                              /* das08_pcmcia_detach */
 
+
+static int das08_pcmcia_config_loop(struct pcmcia_device *p_dev,
+                               cistpl_cftable_entry_t *cfg,
+                               cistpl_cftable_entry_t *dflt,
+                               unsigned int vcc,
+                               void *priv_data)
+{
+       if (cfg->index == 0)
+               return -ENODEV;
+
+       /* Do we need to allocate an interrupt? */
+       if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1)
+               p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
+
+       /* IO window settings */
+       p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
+       if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
+               cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
+               p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
+               if (!(io->flags & CISTPL_IO_8BIT))
+                       p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
+               if (!(io->flags & CISTPL_IO_16BIT))
+                       p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
+               p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
+               p_dev->io.BasePort1 = io->win[0].base;
+               p_dev->io.NumPorts1 = io->win[0].len;
+               if (io->nwin > 1) {
+                       p_dev->io.Attributes2 = p_dev->io.Attributes1;
+                       p_dev->io.BasePort2 = io->win[1].base;
+                       p_dev->io.NumPorts2 = io->win[1].len;
+               }
+               /* This reserves IO space but doesn't actually enable it */
+               return pcmcia_request_io(p_dev, &p_dev->io);
+       }
+       return 0;
+}
+
+
 /*======================================================================
 
     das08_pcmcia_config() is scheduled to run after a CARD_INSERTION event
@@ -248,128 +266,20 @@ static void das08_pcmcia_detach(struct pcmcia_device *link)
 static void das08_pcmcia_config(struct pcmcia_device *link)
 {
        struct local_info_t *dev = link->priv;
-       tuple_t tuple;
-       cisparse_t parse;
-       int last_fn, last_ret;
-       u_char buf[64];
-       cistpl_cftable_entry_t dflt = { 0 };
-
-       DEBUG(0, "das08_pcmcia_config(0x%p)\n", link);
-
-       /*
-          This reads the card's CONFIG tuple to find its configuration
-          registers.
-        */
-       tuple.DesiredTuple = CISTPL_CONFIG;
-       tuple.Attributes = 0;
-       tuple.TupleData = buf;
-       tuple.TupleDataMax = sizeof(buf);
-       tuple.TupleOffset = 0;
-       last_fn = GetFirstTuple;
-
-       last_ret = pcmcia_get_first_tuple(link, &tuple);
-       if (last_ret)
-               goto cs_failed;
-
-       last_fn = GetTupleData;
-
-       last_ret = pcmcia_get_tuple_data(link, &tuple);
-       if (last_ret)
-               goto cs_failed;
-
-       last_fn = ParseTuple;
-
-       last_ret = pcmcia_parse_tuple(&tuple, &parse);
-       if (last_ret)
-               goto cs_failed;
-
-       link->conf.ConfigBase = parse.config.base;
-       link->conf.Present = parse.config.rmask[0];
-
-       /*
-          In this loop, we scan the CIS for configuration table entries,
-          each of which describes a valid card configuration, including
-          voltage, IO window, memory window, and interrupt settings.
-
-          We make no assumptions about the card to be configured: we use
-          just the information available in the CIS.  In an ideal world,
-          this would work for any PCMCIA card, but it requires a complete
-          and accurate CIS.  In practice, a driver usually "knows" most of
-          these things without consulting the CIS, and most client drivers
-          will only use the CIS to fill in implementation-defined details.
-        */
-       tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
-       last_fn = GetFirstTuple;
-
-       last_ret = pcmcia_get_first_tuple(link, &tuple);
-       if (last_ret)
-               goto cs_failed;
-
-       while (1) {
-               cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
-
-               last_ret = pcmcia_get_tuple_data(link, &tuple);
-               if (last_ret)
-                       goto next_entry;
-
-               last_ret = pcmcia_parse_tuple(&tuple, &parse);
-               if (last_ret)
-                       goto next_entry;
-
-               if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
-                       dflt = *cfg;
-               if (cfg->index == 0)
-                       goto next_entry;
-               link->conf.ConfigIndex = cfg->index;
-
-               /* Does this card need audio output? */
-/*     if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
-               link->conf.Attributes |= CONF_ENABLE_SPKR;
-               link->conf.Status = CCSR_AUDIO_ENA;
-       }
-*/
-               /* Do we need to allocate an interrupt? */
-               if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1)
-                       link->conf.Attributes |= CONF_ENABLE_IRQ;
-
-               /* IO window settings */
-               link->io.NumPorts1 = link->io.NumPorts2 = 0;
-               if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
-                       cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
-                       link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
-                       if (!(io->flags & CISTPL_IO_8BIT))
-                               link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
-                       if (!(io->flags & CISTPL_IO_16BIT))
-                               link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
-                       link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
-                       link->io.BasePort1 = io->win[0].base;
-                       link->io.NumPorts1 = io->win[0].len;
-                       if (io->nwin > 1) {
-                               link->io.Attributes2 = link->io.Attributes1;
-                               link->io.BasePort2 = io->win[1].base;
-                               link->io.NumPorts2 = io->win[1].len;
-                       }
-                       /* This reserves IO space but doesn't actually enable it */
-                       if (pcmcia_request_io(link, &link->io) != 0)
-                               goto next_entry;
-               }
-
-               /* If we got this far, we're cool! */
-               break;
+       int ret;
 
-next_entry:
-               last_fn = GetNextTuple;
+       dev_dbg(&link->dev, "das08_pcmcia_config\n");
 
-               last_ret = pcmcia_get_next_tuple(link, &tuple);
-               if (last_ret)
-                       goto cs_failed;
+       ret = pcmcia_loop_config(link, das08_pcmcia_config_loop, NULL);
+       if (ret) {
+               dev_warn(&link->dev, "no configuration found\n");
+               goto failed;
        }
 
        if (link->conf.Attributes & CONF_ENABLE_IRQ) {
-               last_fn = RequestIRQ;
-               last_ret = pcmcia_request_irq(link, &link->irq);
-               if (last_ret)
-                       goto cs_failed;
+               ret = pcmcia_request_irq(link, &link->irq);
+               if (ret)
+                       goto failed;
        }
 
        /*
@@ -377,10 +287,9 @@ next_entry:
           the I/O windows and the interrupt mapping, and putting the
           card and host interface into "Memory and IO" mode.
         */
-       last_fn = RequestConfiguration;
-       last_ret = pcmcia_request_configuration(link, &link->conf);
-       if (last_ret)
-               goto cs_failed;
+       ret = pcmcia_request_configuration(link, &link->conf);
+       if (ret)
+               goto failed;
 
        /*
           At this point, the dev_node_t structure(s) need to be
@@ -405,8 +314,7 @@ next_entry:
 
        return;
 
-cs_failed:
-       cs_error(link, last_fn, last_ret);
+failed:
        das08_pcmcia_release(link);
 
 }                              /* das08_pcmcia_config */
@@ -421,7 +329,7 @@ cs_failed:
 
 static void das08_pcmcia_release(struct pcmcia_device *link)
 {
-       DEBUG(0, "das08_pcmcia_release(0x%p)\n", link);
+       dev_dbg(&link->dev, "das08_pcmcia_release\n");
        pcmcia_disable_device(link);
 }                              /* das08_pcmcia_release */
 
@@ -477,14 +385,13 @@ struct pcmcia_driver das08_cs_driver = {
 
 static int __init init_das08_pcmcia_cs(void)
 {
-       DEBUG(0, "%s\n", version);
        pcmcia_register_driver(&das08_cs_driver);
        return 0;
 }
 
 static void __exit exit_das08_pcmcia_cs(void)
 {
-       DEBUG(0, "das08_pcmcia_cs: unloading\n");
+       pr_debug("das08_pcmcia_cs: unloading\n");
        pcmcia_unregister_driver(&das08_cs_driver);
 }
 
index ec31a39706648a212083d1215e9e51bf2ea75519..ef5e1183d47d30d6448bf63440cf41219ab48c52 100644 (file)
@@ -436,25 +436,7 @@ static int dio700_detach(struct comedi_device *dev)
        return 0;
 };
 
-/* PCMCIA crap */
-
-/*
-   All the PCMCIA modules use PCMCIA_DEBUG to control debugging.  If
-   you do not define PCMCIA_DEBUG at all, all the debug code will be
-   left out.  If you compile with PCMCIA_DEBUG=0, the debug code will
-   be present but disabled -- but it can then be enabled for specific
-   modules at load time with a 'pc_debug=#' option to insmod.
-*/
-#ifdef PCMCIA_DEBUG
-static int pc_debug = PCMCIA_DEBUG;
-module_param(pc_debug, int, 0644);
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
-static char *version = "ni_daq_700.c, based on dummy_cs.c";
-#else
-#define DEBUG(n, args...)
-#endif
-
-/*====================================================================*/
+/* PCMCIA crap -- watch your words, please! */
 
 static void dio700_config(struct pcmcia_device *link);
 static void dio700_release(struct pcmcia_device *link);
@@ -510,7 +492,7 @@ static int dio700_cs_attach(struct pcmcia_device *link)
 
        printk(KERN_INFO "ni_daq_700:  cs-attach\n");
 
-       DEBUG(0, "dio700_cs_attach()\n");
+       dev_dbg(&link->dev, "dio700_cs_attach()\n");
 
        /* Allocate space for private device-specific data */
        local = kzalloc(sizeof(struct local_info_t), GFP_KERNEL);
@@ -521,7 +503,6 @@ static int dio700_cs_attach(struct pcmcia_device *link)
 
        /* Interrupt setup */
        link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
-       link->irq.IRQInfo1 = IRQ_LEVEL_ID;
        link->irq.Handler = NULL;
 
        /*
@@ -555,7 +536,7 @@ static void dio700_cs_detach(struct pcmcia_device *link)
 
        printk(KERN_INFO "ni_daq_700: cs-detach!\n");
 
-       DEBUG(0, "dio700_cs_detach(0x%p)\n", link);
+       dev_dbg(&link->dev, "dio700_cs_detach\n");
 
        if (link->dev_node) {
                ((struct local_info_t *)link->priv)->stop = 1;
@@ -576,141 +557,85 @@ static void dio700_cs_detach(struct pcmcia_device *link)
 
 ======================================================================*/
 
-static void dio700_config(struct pcmcia_device *link)
+static int dio700_pcmcia_config_loop(struct pcmcia_device *p_dev,
+                               cistpl_cftable_entry_t *cfg,
+                               cistpl_cftable_entry_t *dflt,
+                               unsigned int vcc,
+                               void *priv_data)
 {
-       struct local_info_t *dev = link->priv;
-       tuple_t tuple;
-       cisparse_t parse;
-       int last_ret;
-       u_char buf[64];
-       win_req_t req;
+       win_req_t *req = priv_data;
        memreq_t map;
-       cistpl_cftable_entry_t dflt = { 0 };
 
-       printk(KERN_INFO "ni_daq_700:  cs-config\n");
-
-       DEBUG(0, "dio700_config(0x%p)\n", link);
+       if (cfg->index == 0)
+               return -ENODEV;
 
-       /*
-          This reads the card's CONFIG tuple to find its configuration
-          registers.
-        */
-       tuple.DesiredTuple = CISTPL_CONFIG;
-       tuple.Attributes = 0;
-       tuple.TupleData = buf;
-       tuple.TupleDataMax = sizeof(buf);
-       tuple.TupleOffset = 0;
-
-       last_ret = pcmcia_get_first_tuple(link, &tuple);
-       if (last_ret) {
-               cs_error(link, GetFirstTuple, last_ret);
-               goto cs_failed;
+       /* Does this card need audio output? */
+       if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
+               p_dev->conf.Attributes |= CONF_ENABLE_SPKR;
+               p_dev->conf.Status = CCSR_AUDIO_ENA;
        }
 
-       last_ret = pcmcia_get_tuple_data(link, &tuple);
-       if (last_ret) {
-               cs_error(link, GetTupleData, last_ret);
-               goto cs_failed;
+       /* Do we need to allocate an interrupt? */
+       if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1)
+               p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
+
+       /* IO window settings */
+       p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
+       if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
+               cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
+               p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
+               if (!(io->flags & CISTPL_IO_8BIT))
+                       p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
+               if (!(io->flags & CISTPL_IO_16BIT))
+                       p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
+               p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
+               p_dev->io.BasePort1 = io->win[0].base;
+               p_dev->io.NumPorts1 = io->win[0].len;
+               if (io->nwin > 1) {
+                       p_dev->io.Attributes2 = p_dev->io.Attributes1;
+                       p_dev->io.BasePort2 = io->win[1].base;
+                       p_dev->io.NumPorts2 = io->win[1].len;
+               }
+               /* This reserves IO space but doesn't actually enable it */
+               if (pcmcia_request_io(p_dev, &p_dev->io) != 0)
+                       return -ENODEV;
        }
 
-       last_ret = pcmcia_parse_tuple(&tuple, &parse);
-       if (last_ret) {
-               cs_error(link, ParseTuple, last_ret);
-               goto cs_failed;
+       if ((cfg->mem.nwin > 0) || (dflt->mem.nwin > 0)) {
+               cistpl_mem_t *mem =
+                       (cfg->mem.nwin) ? &cfg->mem : &dflt->mem;
+               req->Attributes = WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_CM;
+               req->Attributes |= WIN_ENABLE;
+               req->Base = mem->win[0].host_addr;
+               req->Size = mem->win[0].len;
+               if (req->Size < 0x1000)
+                       req->Size = 0x1000;
+               req->AccessSpeed = 0;
+               if (pcmcia_request_window(p_dev, req, &p_dev->win))
+                       return -ENODEV;
+               map.Page = 0;
+               map.CardOffset = mem->win[0].card_addr;
+               if (pcmcia_map_mem_page(p_dev, p_dev->win, &map))
+                       return -ENODEV;
        }
-       link->conf.ConfigBase = parse.config.base;
-       link->conf.Present = parse.config.rmask[0];
-
-       /*
-          In this loop, we scan the CIS for configuration table entries,
-          each of which describes a valid card configuration, including
-          voltage, IO window, memory window, and interrupt settings.
-
-          We make no assumptions about the card to be configured: we use
-          just the information available in the CIS.  In an ideal world,
-          this would work for any PCMCIA card, but it requires a complete
-          and accurate CIS.  In practice, a driver usually "knows" most of
-          these things without consulting the CIS, and most client drivers
-          will only use the CIS to fill in implementation-defined details.
-        */
-       tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
-       last_ret = pcmcia_get_first_tuple(link, &tuple);
-       if (last_ret != 0) {
-               cs_error(link, GetFirstTuple, last_ret);
-               goto cs_failed;
-       }
-       while (1) {
-               cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
-               if (pcmcia_get_tuple_data(link, &tuple) != 0)
-                       goto next_entry;
-               if (pcmcia_parse_tuple(&tuple, &parse) != 0)
-                       goto next_entry;
-
-               if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
-                       dflt = *cfg;
-               if (cfg->index == 0)
-                       goto next_entry;
-               link->conf.ConfigIndex = cfg->index;
-
-               /* Does this card need audio output? */
-               if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
-                       link->conf.Attributes |= CONF_ENABLE_SPKR;
-                       link->conf.Status = CCSR_AUDIO_ENA;
-               }
+       /* If we got this far, we're cool! */
+       return 0;
+}
 
-               /* Do we need to allocate an interrupt? */
-               if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1)
-                       link->conf.Attributes |= CONF_ENABLE_IRQ;
-
-               /* IO window settings */
-               link->io.NumPorts1 = link->io.NumPorts2 = 0;
-               if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
-                       cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
-                       link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
-                       if (!(io->flags & CISTPL_IO_8BIT))
-                               link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
-                       if (!(io->flags & CISTPL_IO_16BIT))
-                               link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
-                       link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
-                       link->io.BasePort1 = io->win[0].base;
-                       link->io.NumPorts1 = io->win[0].len;
-                       if (io->nwin > 1) {
-                               link->io.Attributes2 = link->io.Attributes1;
-                               link->io.BasePort2 = io->win[1].base;
-                               link->io.NumPorts2 = io->win[1].len;
-                       }
-                       /* This reserves IO space but doesn't actually enable it */
-                       if (pcmcia_request_io(link, &link->io) != 0)
-                               goto next_entry;
-               }
+static void dio700_config(struct pcmcia_device *link)
+{
+       struct local_info_t *dev = link->priv;
+       win_req_t req;
+       int ret;
 
-               if ((cfg->mem.nwin > 0) || (dflt.mem.nwin > 0)) {
-                       cistpl_mem_t *mem =
-                           (cfg->mem.nwin) ? &cfg->mem : &dflt.mem;
-                       req.Attributes = WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_CM;
-                       req.Attributes |= WIN_ENABLE;
-                       req.Base = mem->win[0].host_addr;
-                       req.Size = mem->win[0].len;
-                       if (req.Size < 0x1000)
-                               req.Size = 0x1000;
-                       req.AccessSpeed = 0;
-                       if (pcmcia_request_window(&link, &req, &link->win))
-                               goto next_entry;
-                       map.Page = 0;
-                       map.CardOffset = mem->win[0].card_addr;
-                       if (pcmcia_map_mem_page(link->win, &map))
-                               goto next_entry;
-               }
-               /* If we got this far, we're cool! */
-               break;
+       printk(KERN_INFO "ni_daq_700:  cs-config\n");
 
-next_entry:
+       dev_dbg(&link->dev, "dio700_config\n");
 
-               last_ret = pcmcia_get_next_tuple(link, &tuple);
-               if (last_ret) {
-                       cs_error(link, GetNextTuple, last_ret);
-                       goto cs_failed;
-               }
+       ret = pcmcia_loop_config(link, dio700_pcmcia_config_loop, &req);
+       if (ret) {
+               dev_warn(&link->dev, "no configuration found\n");
+               goto failed;
        }
 
        /*
@@ -719,11 +644,9 @@ next_entry:
           irq structure is initialized.
         */
        if (link->conf.Attributes & CONF_ENABLE_IRQ) {
-               last_ret = pcmcia_request_irq(link, &link->irq);
-               if (last_ret) {
-                       cs_error(link, RequestIRQ, last_ret);
-                       goto cs_failed;
-               }
+               ret = pcmcia_request_irq(link, &link->irq);
+               if (ret)
+                       goto failed;
        }
 
        /*
@@ -731,11 +654,9 @@ next_entry:
           the I/O windows and the interrupt mapping, and putting the
           card and host interface into "Memory and IO" mode.
         */
-       last_ret = pcmcia_request_configuration(link, &link->conf);
-       if (last_ret != 0) {
-               cs_error(link, RequestConfiguration, last_ret);
-               goto cs_failed;
-       }
+       ret = pcmcia_request_configuration(link, &link->conf);
+       if (ret != 0)
+               goto failed;
 
        /*
           At this point, the dev_node_t structure(s) need to be
@@ -763,7 +684,7 @@ next_entry:
 
        return;
 
-cs_failed:
+failed:
        printk(KERN_INFO "ni_daq_700 cs failed");
        dio700_release(link);
 
@@ -771,7 +692,7 @@ cs_failed:
 
 static void dio700_release(struct pcmcia_device *link)
 {
-       DEBUG(0, "dio700_release(0x%p)\n", link);
+       dev_dbg(&link->dev, "dio700_release\n");
 
        pcmcia_disable_device(link);
 }                              /* dio700_release */
@@ -830,15 +751,13 @@ struct pcmcia_driver dio700_cs_driver = {
 
 static int __init init_dio700_cs(void)
 {
-       printk("ni_daq_700:  cs-init \n");
-       DEBUG(0, "%s\n", version);
        pcmcia_register_driver(&dio700_cs_driver);
        return 0;
 }
 
 static void __exit exit_dio700_cs(void)
 {
-       DEBUG(0, "ni_daq_700: unloading\n");
+       pr_debug("ni_daq_700: unloading\n");
        pcmcia_unregister_driver(&dio700_cs_driver);
 }
 
index 0700a8bddd1e415d721a2815fc30521824bc7875..9017be3a92f15939e3fcd2c9123dbe2171101496 100644 (file)
@@ -187,25 +187,7 @@ static int dio24_detach(struct comedi_device *dev)
        return 0;
 };
 
-/* PCMCIA crap */
-
-/*
-   All the PCMCIA modules use PCMCIA_DEBUG to control debugging.  If
-   you do not define PCMCIA_DEBUG at all, all the debug code will be
-   left out.  If you compile with PCMCIA_DEBUG=0, the debug code will
-   be present but disabled -- but it can then be enabled for specific
-   modules at load time with a 'pc_debug=#' option to insmod.
-*/
-#ifdef PCMCIA_DEBUG
-static int pc_debug = PCMCIA_DEBUG;
-module_param(pc_debug, int, 0644);
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
-static char *version = "ni_daq_dio24.c, based on dummy_cs.c";
-#else
-#define DEBUG(n, args...)
-#endif
-
-/*====================================================================*/
+/* PCMCIA crap -- watch your words! */
 
 static void dio24_config(struct pcmcia_device *link);
 static void dio24_release(struct pcmcia_device *link);
@@ -261,7 +243,7 @@ static int dio24_cs_attach(struct pcmcia_device *link)
 
        printk(KERN_INFO "ni_daq_dio24: HOLA SOY YO - CS-attach!\n");
 
-       DEBUG(0, "dio24_cs_attach()\n");
+       dev_dbg(&link->dev, "dio24_cs_attach()\n");
 
        /* Allocate space for private device-specific data */
        local = kzalloc(sizeof(struct local_info_t), GFP_KERNEL);
@@ -272,7 +254,6 @@ static int dio24_cs_attach(struct pcmcia_device *link)
 
        /* Interrupt setup */
        link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
-       link->irq.IRQInfo1 = IRQ_LEVEL_ID;
        link->irq.Handler = NULL;
 
        /*
@@ -306,7 +287,7 @@ static void dio24_cs_detach(struct pcmcia_device *link)
 
        printk(KERN_INFO "ni_daq_dio24: HOLA SOY YO - cs-detach!\n");
 
-       DEBUG(0, "dio24_cs_detach(0x%p)\n", link);
+       dev_dbg(&link->dev, "dio24_cs_detach\n");
 
        if (link->dev_node) {
                ((struct local_info_t *)link->priv)->stop = 1;
@@ -327,142 +308,85 @@ static void dio24_cs_detach(struct pcmcia_device *link)
 
 ======================================================================*/
 
-static void dio24_config(struct pcmcia_device *link)
+static int dio24_pcmcia_config_loop(struct pcmcia_device *p_dev,
+                               cistpl_cftable_entry_t *cfg,
+                               cistpl_cftable_entry_t *dflt,
+                               unsigned int vcc,
+                               void *priv_data)
 {
-       struct local_info_t *dev = link->priv;
-       tuple_t tuple;
-       cisparse_t parse;
-       int last_ret;
-       u_char buf[64];
-       win_req_t req;
+       win_req_t *req = priv_data;
        memreq_t map;
-       cistpl_cftable_entry_t dflt = { 0 };
 
-       printk(KERN_INFO "ni_daq_dio24: HOLA SOY YO! - config\n");
-
-       DEBUG(0, "dio24_config(0x%p)\n", link);
-
-       /*
-          This reads the card's CONFIG tuple to find its configuration
-          registers.
-        */
-       tuple.DesiredTuple = CISTPL_CONFIG;
-       tuple.Attributes = 0;
-       tuple.TupleData = buf;
-       tuple.TupleDataMax = sizeof(buf);
-       tuple.TupleOffset = 0;
-
-       last_ret = pcmcia_get_first_tuple(link, &tuple);
-       if (last_ret) {
-               cs_error(link, GetFirstTuple, last_ret);
-               goto cs_failed;
-       }
+       if (cfg->index == 0)
+               return -ENODEV;
 
-       last_ret = pcmcia_get_tuple_data(link, &tuple);
-       if (last_ret) {
-               cs_error(link, GetTupleData, last_ret);
-               goto cs_failed;
+       /* Does this card need audio output? */
+       if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
+               p_dev->conf.Attributes |= CONF_ENABLE_SPKR;
+               p_dev->conf.Status = CCSR_AUDIO_ENA;
        }
 
-       last_ret = pcmcia_parse_tuple(&tuple, &parse);
-       if (last_ret) {
-               cs_error(link, ParseTuple, last_ret);
-               goto cs_failed;
+       /* Do we need to allocate an interrupt? */
+       if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1)
+               p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
+
+       /* IO window settings */
+       p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
+       if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
+               cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
+               p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
+               if (!(io->flags & CISTPL_IO_8BIT))
+                       p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
+               if (!(io->flags & CISTPL_IO_16BIT))
+                       p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
+               p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
+               p_dev->io.BasePort1 = io->win[0].base;
+               p_dev->io.NumPorts1 = io->win[0].len;
+               if (io->nwin > 1) {
+                       p_dev->io.Attributes2 = p_dev->io.Attributes1;
+                       p_dev->io.BasePort2 = io->win[1].base;
+                       p_dev->io.NumPorts2 = io->win[1].len;
+               }
+               /* This reserves IO space but doesn't actually enable it */
+               if (pcmcia_request_io(p_dev, &p_dev->io) != 0)
+                       return -ENODEV;
        }
-       link->conf.ConfigBase = parse.config.base;
-       link->conf.Present = parse.config.rmask[0];
-
-       /*
-          In this loop, we scan the CIS for configuration table entries,
-          each of which describes a valid card configuration, including
-          voltage, IO window, memory window, and interrupt settings.
-
-          We make no assumptions about the card to be configured: we use
-          just the information available in the CIS.  In an ideal world,
-          this would work for any PCMCIA card, but it requires a complete
-          and accurate CIS.  In practice, a driver usually "knows" most of
-          these things without consulting the CIS, and most client drivers
-          will only use the CIS to fill in implementation-defined details.
-        */
-       tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
 
-       last_ret = pcmcia_get_first_tuple(link, &tuple);
-       if (last_ret) {
-               cs_error(link, GetFirstTuple, last_ret);
-               goto cs_failed;
+       if ((cfg->mem.nwin > 0) || (dflt->mem.nwin > 0)) {
+               cistpl_mem_t *mem =
+                       (cfg->mem.nwin) ? &cfg->mem : &dflt->mem;
+               req->Attributes = WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_CM;
+               req->Attributes |= WIN_ENABLE;
+               req->Base = mem->win[0].host_addr;
+               req->Size = mem->win[0].len;
+               if (req->Size < 0x1000)
+                       req->Size = 0x1000;
+               req->AccessSpeed = 0;
+               if (pcmcia_request_window(p_dev, req, &p_dev->win))
+                       return -ENODEV;
+               map.Page = 0;
+               map.CardOffset = mem->win[0].card_addr;
+               if (pcmcia_map_mem_page(p_dev, p_dev->win, &map))
+                       return -ENODEV;
        }
-       while (1) {
-               cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
-               if (pcmcia_get_tuple_data(link, &tuple) != 0)
-                       goto next_entry;
-               if (pcmcia_parse_tuple(&tuple, &parse) != 0)
-                       goto next_entry;
-
-               if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
-                       dflt = *cfg;
-               if (cfg->index == 0)
-                       goto next_entry;
-               link->conf.ConfigIndex = cfg->index;
-
-               /* Does this card need audio output? */
-               if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
-                       link->conf.Attributes |= CONF_ENABLE_SPKR;
-                       link->conf.Status = CCSR_AUDIO_ENA;
-               }
+       /* If we got this far, we're cool! */
+       return 0;
+}
 
-               /* Do we need to allocate an interrupt? */
-               if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1)
-                       link->conf.Attributes |= CONF_ENABLE_IRQ;
-
-               /* IO window settings */
-               link->io.NumPorts1 = link->io.NumPorts2 = 0;
-               if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
-                       cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
-                       link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
-                       if (!(io->flags & CISTPL_IO_8BIT))
-                               link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
-                       if (!(io->flags & CISTPL_IO_16BIT))
-                               link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
-                       link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
-                       link->io.BasePort1 = io->win[0].base;
-                       link->io.NumPorts1 = io->win[0].len;
-                       if (io->nwin > 1) {
-                               link->io.Attributes2 = link->io.Attributes1;
-                               link->io.BasePort2 = io->win[1].base;
-                               link->io.NumPorts2 = io->win[1].len;
-                       }
-                       /* This reserves IO space but doesn't actually enable it */
-                       if (pcmcia_request_io(link, &link->io) != 0)
-                               goto next_entry;
-               }
+static void dio24_config(struct pcmcia_device *link)
+{
+       struct local_info_t *dev = link->priv;
+       int ret;
+       win_req_t req;
 
-               if ((cfg->mem.nwin > 0) || (dflt.mem.nwin > 0)) {
-                       cistpl_mem_t *mem =
-                           (cfg->mem.nwin) ? &cfg->mem : &dflt.mem;
-                       req.Attributes = WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_CM;
-                       req.Attributes |= WIN_ENABLE;
-                       req.Base = mem->win[0].host_addr;
-                       req.Size = mem->win[0].len;
-                       if (req.Size < 0x1000)
-                               req.Size = 0x1000;
-                       req.AccessSpeed = 0;
-                       if (pcmcia_request_window(&link, &req, &link->win))
-                               goto next_entry;
-                       map.Page = 0;
-                       map.CardOffset = mem->win[0].card_addr;
-                       if (pcmcia_map_mem_page(link->win, &map))
-                               goto next_entry;
-               }
-               /* If we got this far, we're cool! */
-               break;
+       printk(KERN_INFO "ni_daq_dio24: HOLA SOY YO! - config\n");
 
-next_entry:
+       dev_dbg(&link->dev, "dio24_config\n");
 
-               last_ret = pcmcia_get_next_tuple(link, &tuple);
-               if (last_ret) {
-                       cs_error(link, GetNextTuple, last_ret);
-                       goto cs_failed;
-               }
+       ret = pcmcia_loop_config(link, dio24_pcmcia_config_loop, &req);
+       if (ret) {
+               dev_warn(&link->dev, "no configuration found\n");
+               goto failed;
        }
 
        /*
@@ -471,11 +395,9 @@ next_entry:
           irq structure is initialized.
         */
        if (link->conf.Attributes & CONF_ENABLE_IRQ) {
-               last_ret = pcmcia_request_irq(link, &link->irq);
-               if (last_ret) {
-                       cs_error(link, RequestIRQ, last_ret);
-                       goto cs_failed;
-               }
+               ret = pcmcia_request_irq(link, &link->irq);
+               if (ret)
+                       goto failed;
        }
 
        /*
@@ -483,11 +405,9 @@ next_entry:
           the I/O windows and the interrupt mapping, and putting the
           card and host interface into "Memory and IO" mode.
         */
-       last_ret = pcmcia_request_configuration(link, &link->conf);
-       if (last_ret) {
-               cs_error(link, RequestConfiguration, last_ret);
-               goto cs_failed;
-       }
+       ret = pcmcia_request_configuration(link, &link->conf);
+       if (ret)
+               goto failed;
 
        /*
           At this point, the dev_node_t structure(s) need to be
@@ -515,7 +435,7 @@ next_entry:
 
        return;
 
-cs_failed:
+failed:
        printk(KERN_INFO "Fallo");
        dio24_release(link);
 
@@ -523,7 +443,7 @@ cs_failed:
 
 static void dio24_release(struct pcmcia_device *link)
 {
-       DEBUG(0, "dio24_release(0x%p)\n", link);
+       dev_dbg(&link->dev, "dio24_release\n");
 
        pcmcia_disable_device(link);
 }                              /* dio24_release */
@@ -582,14 +502,12 @@ struct pcmcia_driver dio24_cs_driver = {
 static int __init init_dio24_cs(void)
 {
        printk("ni_daq_dio24: HOLA SOY YO!\n");
-       DEBUG(0, "%s\n", version);
        pcmcia_register_driver(&dio24_cs_driver);
        return 0;
 }
 
 static void __exit exit_dio24_cs(void)
 {
-       DEBUG(0, "ni_dio24: unloading\n");
        pcmcia_unregister_driver(&dio24_cs_driver);
 }
 
index a3053b8da1c64c67cb6876488884c039ee3dfca4..7d514b3ee75436c5f4c8e345cd8ffdf57b15f93e 100644 (file)
@@ -153,23 +153,6 @@ static int labpc_attach(struct comedi_device *dev, struct comedi_devconfig *it)
        return labpc_common_attach(dev, iobase, irq, 0);
 }
 
-/*
-   All the PCMCIA modules use PCMCIA_DEBUG to control debugging.  If
-   you do not define PCMCIA_DEBUG at all, all the debug code will be
-   left out.  If you compile with PCMCIA_DEBUG=0, the debug code will
-   be present but disabled -- but it can then be enabled for specific
-   modules at load time with a 'pc_debug=#' option to insmod.
-*/
-#ifdef PCMCIA_DEBUG
-static int pc_debug = PCMCIA_DEBUG;
-module_param(pc_debug, int, 0644);
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
-static const char *version =
-    "ni_labpc.c, based on dummy_cs.c 1.31 2001/08/24 12:13:13";
-#else
-#define DEBUG(n, args...)
-#endif
-
 /*====================================================================*/
 
 /*
@@ -236,7 +219,7 @@ static int labpc_cs_attach(struct pcmcia_device *link)
 {
        struct local_info_t *local;
 
-       DEBUG(0, "labpc_cs_attach()\n");
+       dev_dbg(&link->dev, "labpc_cs_attach()\n");
 
        /* Allocate space for private device-specific data */
        local = kzalloc(sizeof(struct local_info_t), GFP_KERNEL);
@@ -247,7 +230,6 @@ static int labpc_cs_attach(struct pcmcia_device *link)
 
        /* Interrupt setup */
        link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_FORCED_PULSE;
-       link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_PULSE_ID;
        link->irq.Handler = NULL;
 
        /*
@@ -278,7 +260,7 @@ static int labpc_cs_attach(struct pcmcia_device *link)
 
 static void labpc_cs_detach(struct pcmcia_device *link)
 {
-       DEBUG(0, "labpc_cs_detach(0x%p)\n", link);
+       dev_dbg(&link->dev, "labpc_cs_detach\n");
 
        /*
           If the device is currently configured and active, we won't
@@ -305,135 +287,84 @@ static void labpc_cs_detach(struct pcmcia_device *link)
 
 ======================================================================*/
 
-static void labpc_config(struct pcmcia_device *link)
+static int labpc_pcmcia_config_loop(struct pcmcia_device *p_dev,
+                               cistpl_cftable_entry_t *cfg,
+                               cistpl_cftable_entry_t *dflt,
+                               unsigned int vcc,
+                               void *priv_data)
 {
-       struct local_info_t *dev = link->priv;
-       tuple_t tuple;
-       cisparse_t parse;
-       int last_ret;
-       u_char buf[64];
-       win_req_t req;
+       win_req_t *req = priv_data;
        memreq_t map;
-       cistpl_cftable_entry_t dflt = { 0 };
 
-       DEBUG(0, "labpc_config(0x%p)\n", link);
+       if (cfg->index == 0)
+               return -ENODEV;
 
-       /*
-          This reads the card's CONFIG tuple to find its configuration
-          registers.
-        */
-       tuple.DesiredTuple = CISTPL_CONFIG;
-       tuple.Attributes = 0;
-       tuple.TupleData = buf;
-       tuple.TupleDataMax = sizeof(buf);
-       tuple.TupleOffset = 0;
-
-       last_ret = pcmcia_get_first_tuple(link, &tuple);
-       if (last_ret) {
-               cs_error(link, GetFirstTuple, last_ret);
-               goto cs_failed;
+       /* Does this card need audio output? */
+       if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
+               p_dev->conf.Attributes |= CONF_ENABLE_SPKR;
+               p_dev->conf.Status = CCSR_AUDIO_ENA;
        }
 
-       last_ret = pcmcia_get_tuple_data(link, &tuple);
-       if (last_ret) {
-               cs_error(link, GetTupleData, last_ret);
-               goto cs_failed;
+       /* Do we need to allocate an interrupt? */
+       if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1)
+               p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
+
+       /* IO window settings */
+       p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
+       if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
+               cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
+               p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
+               if (!(io->flags & CISTPL_IO_8BIT))
+                       p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
+               if (!(io->flags & CISTPL_IO_16BIT))
+                       p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
+               p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
+               p_dev->io.BasePort1 = io->win[0].base;
+               p_dev->io.NumPorts1 = io->win[0].len;
+               if (io->nwin > 1) {
+                       p_dev->io.Attributes2 = p_dev->io.Attributes1;
+                       p_dev->io.BasePort2 = io->win[1].base;
+                       p_dev->io.NumPorts2 = io->win[1].len;
+               }
+               /* This reserves IO space but doesn't actually enable it */
+               if (pcmcia_request_io(p_dev, &p_dev->io) != 0)
+                       return -ENODEV;
        }
 
-       last_ret = pcmcia_parse_tuple(&tuple, &parse);
-       if (last_ret) {
-               cs_error(link, ParseTuple, last_ret);
-               goto cs_failed;
+       if ((cfg->mem.nwin > 0) || (dflt->mem.nwin > 0)) {
+               cistpl_mem_t *mem =
+                       (cfg->mem.nwin) ? &cfg->mem : &dflt->mem;
+               req->Attributes = WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_CM;
+               req->Attributes |= WIN_ENABLE;
+               req->Base = mem->win[0].host_addr;
+               req->Size = mem->win[0].len;
+               if (req->Size < 0x1000)
+                       req->Size = 0x1000;
+               req->AccessSpeed = 0;
+               if (pcmcia_request_window(p_dev, req, &p_dev->win))
+                       return -ENODEV;
+               map.Page = 0;
+               map.CardOffset = mem->win[0].card_addr;
+               if (pcmcia_map_mem_page(p_dev, p_dev->win, &map))
+                       return -ENODEV;
        }
-       link->conf.ConfigBase = parse.config.base;
-       link->conf.Present = parse.config.rmask[0];
+       /* If we got this far, we're cool! */
+       return 0;
+}
 
-       /*
-          In this loop, we scan the CIS for configuration table entries,
-          each of which describes a valid card configuration, including
-          voltage, IO window, memory window, and interrupt settings.
-
-          We make no assumptions about the card to be configured: we use
-          just the information available in the CIS.  In an ideal world,
-          this would work for any PCMCIA card, but it requires a complete
-          and accurate CIS.  In practice, a driver usually "knows" most of
-          these things without consulting the CIS, and most client drivers
-          will only use the CIS to fill in implementation-defined details.
-        */
-       tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
-       last_ret = pcmcia_get_first_tuple(link, &tuple);
-       if (last_ret) {
-               cs_error(link, GetFirstTuple, last_ret);
-               goto cs_failed;
-       }
-       while (1) {
-               cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
-               if (pcmcia_get_tuple_data(link, &tuple))
-                       goto next_entry;
-               if (pcmcia_parse_tuple(&tuple, &parse))
-                       goto next_entry;
-
-               if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
-                       dflt = *cfg;
-               if (cfg->index == 0)
-                       goto next_entry;
-               link->conf.ConfigIndex = cfg->index;
-
-               /* Does this card need audio output? */
-               if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
-                       link->conf.Attributes |= CONF_ENABLE_SPKR;
-                       link->conf.Status = CCSR_AUDIO_ENA;
-               }
 
-               /* Do we need to allocate an interrupt? */
-               if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1)
-                       link->conf.Attributes |= CONF_ENABLE_IRQ;
-
-               /* IO window settings */
-               link->io.NumPorts1 = link->io.NumPorts2 = 0;
-               if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
-                       cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
-                       link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
-                       link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
-                       link->io.BasePort1 = io->win[0].base;
-                       link->io.NumPorts1 = io->win[0].len;
-                       if (io->nwin > 1) {
-                               link->io.Attributes2 = link->io.Attributes1;
-                               link->io.BasePort2 = io->win[1].base;
-                               link->io.NumPorts2 = io->win[1].len;
-                       }
-                       /* This reserves IO space but doesn't actually enable it */
-                       if (pcmcia_request_io(link, &link->io))
-                               goto next_entry;
-               }
+static void labpc_config(struct pcmcia_device *link)
+{
+       struct local_info_t *dev = link->priv;
+       int ret;
+       win_req_t req;
 
-               if ((cfg->mem.nwin > 0) || (dflt.mem.nwin > 0)) {
-                       cistpl_mem_t *mem =
-                           (cfg->mem.nwin) ? &cfg->mem : &dflt.mem;
-                       req.Attributes = WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_CM;
-                       req.Attributes |= WIN_ENABLE;
-                       req.Base = mem->win[0].host_addr;
-                       req.Size = mem->win[0].len;
-                       if (req.Size < 0x1000)
-                               req.Size = 0x1000;
-                       req.AccessSpeed = 0;
-                       link->win = (window_handle_t) link;
-                       if (pcmcia_request_window(&link, &req, &link->win))
-                               goto next_entry;
-                       map.Page = 0;
-                       map.CardOffset = mem->win[0].card_addr;
-                       if (pcmcia_map_mem_page(link->win, &map))
-                               goto next_entry;
-               }
-               /* If we got this far, we're cool! */
-               break;
+       dev_dbg(&link->dev, "labpc_config\n");
 
-next_entry:
-               last_ret = pcmcia_get_next_tuple(link, &tuple);
-               if (last_ret) {
-                       cs_error(link, GetNextTuple, last_ret);
-                       goto cs_failed;
-               }
+       ret = pcmcia_loop_config(link, labpc_pcmcia_config_loop, &req);
+       if (ret) {
+               dev_warn(&link->dev, "no configuration found\n");
+               goto failed;
        }
 
        /*
@@ -442,11 +373,9 @@ next_entry:
           irq structure is initialized.
         */
        if (link->conf.Attributes & CONF_ENABLE_IRQ) {
-               last_ret = pcmcia_request_irq(link, &link->irq);
-               if (last_ret) {
-                       cs_error(link, RequestIRQ, last_ret);
-                       goto cs_failed;
-               }
+               ret = pcmcia_request_irq(link, &link->irq);
+               if (ret)
+                       goto failed;
        }
 
        /*
@@ -454,11 +383,9 @@ next_entry:
           the I/O windows and the interrupt mapping, and putting the
           card and host interface into "Memory and IO" mode.
         */
-       last_ret = pcmcia_request_configuration(link, &link->conf);
-       if (last_ret) {
-               cs_error(link, RequestConfiguration, last_ret);
-               goto cs_failed;
-       }
+       ret = pcmcia_request_configuration(link, &link->conf);
+       if (ret)
+               goto failed;
 
        /*
           At this point, the dev_node_t structure(s) need to be
@@ -486,14 +413,14 @@ next_entry:
 
        return;
 
-cs_failed:
+failed:
        labpc_release(link);
 
 }                              /* labpc_config */
 
 static void labpc_release(struct pcmcia_device *link)
 {
-       DEBUG(0, "labpc_release(0x%p)\n", link);
+       dev_dbg(&link->dev, "labpc_release\n");
 
        pcmcia_disable_device(link);
 }                              /* labpc_release */
@@ -551,14 +478,12 @@ struct pcmcia_driver labpc_cs_driver = {
 
 static int __init init_labpc_cs(void)
 {
-       DEBUG(0, "%s\n", version);
        pcmcia_register_driver(&labpc_cs_driver);
        return 0;
 }
 
 static void __exit exit_labpc_cs(void)
 {
-       DEBUG(0, "ni_labpc: unloading\n");
        pcmcia_unregister_driver(&labpc_cs_driver);
 }
 
index 9aef87fc81dcd3560cda172fef89471b87b14bec..d692f4bb47eaed1bd9930d152e584e0a968ef42a 100644 (file)
@@ -274,7 +274,6 @@ static int cs_attach(struct pcmcia_device *link)
        link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
        link->io.NumPorts1 = 16;
        link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
-       link->irq.IRQInfo1 = IRQ_LEVEL_ID;
        link->conf.Attributes = CONF_ENABLE_IRQ;
        link->conf.IntType = INT_MEMORY_AND_IO;
 
@@ -312,96 +311,47 @@ static int mio_cs_resume(struct pcmcia_device *link)
        return 0;
 }
 
-static void mio_cs_config(struct pcmcia_device *link)
-{
-       tuple_t tuple;
-       u_short buf[128];
-       cisparse_t parse;
-       int manfid = 0, prodid = 0;
-       int ret;
-
-       DPRINTK("mio_cs_config(link=%p)\n", link);
 
-       tuple.TupleData = (cisdata_t *) buf;
-       tuple.TupleOffset = 0;
-       tuple.TupleDataMax = 255;
-       tuple.Attributes = 0;
+static int mio_pcmcia_config_loop(struct pcmcia_device *p_dev,
+                               cistpl_cftable_entry_t *cfg,
+                               cistpl_cftable_entry_t *dflt,
+                               unsigned int vcc,
+                               void *priv_data)
+{
+       int base, ret;
 
-       tuple.DesiredTuple = CISTPL_CONFIG;
-       ret = pcmcia_get_first_tuple(link, &tuple);
-       ret = pcmcia_get_tuple_data(link, &tuple);
-       ret = pcmcia_parse_tuple(&tuple, &parse);
-       link->conf.ConfigBase = parse.config.base;
-       link->conf.Present = parse.config.rmask[0];
+       p_dev->io.NumPorts1 = cfg->io.win[0].len;
+       p_dev->io.IOAddrLines = cfg->io.flags & CISTPL_IO_LINES_MASK;
+       p_dev->io.NumPorts2 = 0;
 
-#if 0
-       tuple.DesiredTuple = CISTPL_LONGLINK_MFC;
-       tuple.Attributes = TUPLE_RETURN_COMMON | TUPLE_RETURN_LINK;
-       info->multi(first_tuple(link, &tuple, &parse) == 0);
-#endif
-
-       tuple.DesiredTuple = CISTPL_MANFID;
-       tuple.Attributes = TUPLE_RETURN_COMMON;
-       if ((pcmcia_get_first_tuple(link, &tuple) == 0) &&
-           (pcmcia_get_tuple_data(link, &tuple) == 0)) {
-               manfid = le16_to_cpu(buf[0]);
-               prodid = le16_to_cpu(buf[1]);
+       for (base = 0x000; base < 0x400; base += 0x20) {
+               p_dev->io.BasePort1 = base;
+               ret = pcmcia_request_io(p_dev, &p_dev->io);
+               if (!ret)
+                       return 0;
        }
-       /* printk("manfid = 0x%04x, 0x%04x\n",manfid,prodid); */
+       return -ENODEV;
+}
 
-       tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
-       tuple.Attributes = 0;
-       ret = pcmcia_get_first_tuple(link, &tuple);
-       ret = pcmcia_get_tuple_data(link, &tuple);
-       ret = pcmcia_parse_tuple(&tuple, &parse);
 
-#if 0
-       printk(" index: 0x%x\n", parse.cftable_entry.index);
-       printk(" flags: 0x%x\n", parse.cftable_entry.flags);
-       printk(" io flags: 0x%x\n", parse.cftable_entry.io.flags);
-       printk(" io nwin: 0x%x\n", parse.cftable_entry.io.nwin);
-       printk(" io base: 0x%x\n", parse.cftable_entry.io.win[0].base);
-       printk(" io len: 0x%x\n", parse.cftable_entry.io.win[0].len);
-       printk(" irq1: 0x%x\n", parse.cftable_entry.irq.IRQInfo1);
-       printk(" irq2: 0x%x\n", parse.cftable_entry.irq.IRQInfo2);
-       printk(" mem flags: 0x%x\n", parse.cftable_entry.mem.flags);
-       printk(" mem nwin: 0x%x\n", parse.cftable_entry.mem.nwin);
-       printk(" subtuples: 0x%x\n", parse.cftable_entry.subtuples);
-#endif
+static void mio_cs_config(struct pcmcia_device *link)
+{
+       int ret;
 
-#if 0
-       link->io.NumPorts1 = 0x20;
-       link->io.IOAddrLines = 5;
-       link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
-#endif
-       link->io.NumPorts1 = parse.cftable_entry.io.win[0].len;
-       link->io.IOAddrLines =
-           parse.cftable_entry.io.flags & CISTPL_IO_LINES_MASK;
-       link->io.NumPorts2 = 0;
+       DPRINTK("mio_cs_config(link=%p)\n", link);
 
-       {
-               int base;
-               for (base = 0x000; base < 0x400; base += 0x20) {
-                       link->io.BasePort1 = base;
-                       ret = pcmcia_request_io(link, &link->io);
-                       /* printk("RequestIO 0x%02x\n",ret); */
-                       if (!ret)
-                               break;
-               }
+       ret = pcmcia_loop_config(link, mio_pcmcia_config_loop, NULL);
+       if (ret) {
+               dev_warn(&link->dev, "no configuration found\n");
+               return;
        }
 
-       link->irq.IRQInfo1 = parse.cftable_entry.irq.IRQInfo1;
-       link->irq.IRQInfo2 = parse.cftable_entry.irq.IRQInfo2;
        ret = pcmcia_request_irq(link, &link->irq);
        if (ret) {
                printk("pcmcia_request_irq() returned error: %i\n", ret);
        }
-       /* printk("RequestIRQ 0x%02x\n",ret); */
-
-       link->conf.ConfigIndex = 1;
 
        ret = pcmcia_request_configuration(link, &link->conf);
-       /* printk("RequestConfiguration %d\n",ret); */
 
        link->dev_node = &dev_node;
 }
@@ -475,40 +425,17 @@ static int mio_cs_attach(struct comedi_device *dev, struct comedi_devconfig *it)
        return 0;
 }
 
-static int get_prodid(struct comedi_device *dev, struct pcmcia_device *link)
-{
-       tuple_t tuple;
-       u_short buf[128];
-       int prodid = 0;
-
-       tuple.TupleData = (cisdata_t *) buf;
-       tuple.TupleOffset = 0;
-       tuple.TupleDataMax = 255;
-       tuple.DesiredTuple = CISTPL_MANFID;
-       tuple.Attributes = TUPLE_RETURN_COMMON;
-       if ((pcmcia_get_first_tuple(link, &tuple) == 0) &&
-           (pcmcia_get_tuple_data(link, &tuple) == 0)) {
-               prodid = le16_to_cpu(buf[1]);
-       }
-
-       return prodid;
-}
-
 static int ni_getboardtype(struct comedi_device *dev,
                           struct pcmcia_device *link)
 {
-       int id;
        int i;
 
-       id = get_prodid(dev, link);
-
        for (i = 0; i < n_ni_boards; i++) {
-               if (ni_boards[i].device_id == id) {
+               if (ni_boards[i].device_id == link->card_id)
                        return i;
-               }
        }
 
-       printk("unknown board 0x%04x -- pretend it is a ", id);
+       printk("unknown board 0x%04x -- pretend it is a ", link->card_id);
 
        return 0;
 }
index 344b82353e08ba96013c50cfc93b822d949d8aaa..5256fd9331629409b79aac5436c0cf25d32e1f81 100644 (file)
@@ -55,23 +55,6 @@ Devices: [Quatech] DAQP-208 (daqp), DAQP-308
 #include <pcmcia/cisreg.h>
 #include <pcmcia/ds.h>
 
-/*
-   All the PCMCIA modules use PCMCIA_DEBUG to control debugging.  If
-   you do not define PCMCIA_DEBUG at all, all the debug code will be
-   left out.  If you compile with PCMCIA_DEBUG=0, the debug code will
-   be present but disabled -- but it can then be enabled for specific
-   modules at load time with a 'pc_debug=#' option to insmod.
-*/
-
-#ifdef PCMCIA_DEBUG
-static int pc_debug = PCMCIA_DEBUG;
-module_param(pc_debug, int, 0644);
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
-static char *version = "quatech_daqp_cs.c 1.10 2003/04/21 (Brent Baccala)";
-#else
-#define DEBUG(n, args...)
-#endif
-
 /* Maximum number of separate DAQP devices we'll allow */
 #define MAX_DEV         4
 
@@ -863,8 +846,6 @@ static int daqp_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 {
        int ret;
        struct local_info_t *local = dev_table[it->options[0]];
-       tuple_t tuple;
-       int i;
        struct comedi_subdevice *s;
 
        if (it->options[0] < 0 || it->options[0] >= MAX_DEV || !local) {
@@ -883,29 +864,10 @@ static int daqp_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 
        strcpy(local->board_name, "DAQP");
        dev->board_name = local->board_name;
-
-       tuple.DesiredTuple = CISTPL_VERS_1;
-       if (pcmcia_get_first_tuple(local->link, &tuple) == 0) {
-               u_char buf[128];
-
-               buf[0] = buf[sizeof(buf) - 1] = 0;
-               tuple.TupleData = buf;
-               tuple.TupleDataMax = sizeof(buf);
-               tuple.TupleOffset = 2;
-               if (pcmcia_get_tuple_data(local->link, &tuple) == 0) {
-
-                       for (i = 0; i < tuple.TupleDataLen - 4; i++)
-                               if (buf[i] == 0)
-                                       break;
-                       for (i++; i < tuple.TupleDataLen - 4; i++)
-                               if (buf[i] == 0)
-                                       break;
-                       i++;
-                       if ((i < tuple.TupleDataLen - 4)
-                           && (strncmp(buf + i, "DAQP", 4) == 0)) {
-                               strncpy(local->board_name, buf + i,
-                                       sizeof(local->board_name));
-                       }
+       if (local->link->prod_id[2]) {
+               if (strncmp(local->link->prod_id[2], "DAQP", 4) == 0) {
+                       strncpy(local->board_name, local->link->prod_id[2],
+                               sizeof(local->board_name));
                }
        }
 
@@ -1058,7 +1020,7 @@ static int daqp_cs_attach(struct pcmcia_device *link)
        struct local_info_t *local;
        int i;
 
-       DEBUG(0, "daqp_cs_attach()\n");
+       dev_dbg(&link->dev, "daqp_cs_attach()\n");
 
        for (i = 0; i < MAX_DEV; i++)
                if (dev_table[i] == NULL)
@@ -1079,10 +1041,8 @@ static int daqp_cs_attach(struct pcmcia_device *link)
        link->priv = local;
 
        /* Interrupt setup */
-       link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
-       link->irq.IRQInfo1 = IRQ_LEVEL_ID;
+       link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
        link->irq.Handler = daqp_interrupt;
-       link->irq.Instance = local;
 
        /*
           General socket configuration defaults can go here.  In this
@@ -1112,7 +1072,7 @@ static void daqp_cs_detach(struct pcmcia_device *link)
 {
        struct local_info_t *dev = link->priv;
 
-       DEBUG(0, "daqp_cs_detach(0x%p)\n", link);
+       dev_dbg(&link->dev, "daqp_cs_detach\n");
 
        if (link->dev_node) {
                dev->stop = 1;
@@ -1134,115 +1094,54 @@ static void daqp_cs_detach(struct pcmcia_device *link)
 
 ======================================================================*/
 
-static void daqp_cs_config(struct pcmcia_device *link)
-{
-       struct local_info_t *dev = link->priv;
-       tuple_t tuple;
-       cisparse_t parse;
-       int last_ret;
-       u_char buf[64];
-
-       DEBUG(0, "daqp_cs_config(0x%p)\n", link);
-
-       /*
-          This reads the card's CONFIG tuple to find its configuration
-          registers.
-        */
-       tuple.DesiredTuple = CISTPL_CONFIG;
-       tuple.Attributes = 0;
-       tuple.TupleData = buf;
-       tuple.TupleDataMax = sizeof(buf);
-       tuple.TupleOffset = 0;
-
-       last_ret = pcmcia_get_first_tuple(link, &tuple);
-       if (last_ret) {
-               cs_error(link, GetFirstTuple, last_ret);
-               goto cs_failed;
-       }
 
-       last_ret = pcmcia_get_tuple_data(link, &tuple);
-       if (last_ret) {
-               cs_error(link, GetTupleData, last_ret);
-               goto cs_failed;
-       }
-
-       last_ret = pcmcia_parse_tuple(&tuple, &parse);
-       if (last_ret) {
-               cs_error(link, ParseTuple, last_ret);
-               goto cs_failed;
-       }
-       link->conf.ConfigBase = parse.config.base;
-       link->conf.Present = parse.config.rmask[0];
+static int daqp_pcmcia_config_loop(struct pcmcia_device *p_dev,
+                               cistpl_cftable_entry_t *cfg,
+                               cistpl_cftable_entry_t *dflt,
+                               unsigned int vcc,
+                               void *priv_data)
+{
+       if (cfg->index == 0)
+               return -ENODEV;
 
-       /*
-          In this loop, we scan the CIS for configuration table entries,
-          each of which describes a valid card configuration, including
-          voltage, IO window, memory window, and interrupt settings.
-
-          We make no assumptions about the card to be configured: we use
-          just the information available in the CIS.  In an ideal world,
-          this would work for any PCMCIA card, but it requires a complete
-          and accurate CIS.  In practice, a driver usually "knows" most of
-          these things without consulting the CIS, and most client drivers
-          will only use the CIS to fill in implementation-defined details.
-        */
-       tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
-       last_ret = pcmcia_get_first_tuple(link, &tuple);
-       if (last_ret) {
-               cs_error(link, GetFirstTuple, last_ret);
-               goto cs_failed;
+       /* Do we need to allocate an interrupt? */
+       if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1)
+               p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
+
+       /* IO window settings */
+       p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
+       if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
+               cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
+               p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
+               if (!(io->flags & CISTPL_IO_8BIT))
+                       p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
+               if (!(io->flags & CISTPL_IO_16BIT))
+                       p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
+               p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
+               p_dev->io.BasePort1 = io->win[0].base;
+               p_dev->io.NumPorts1 = io->win[0].len;
+               if (io->nwin > 1) {
+                       p_dev->io.Attributes2 = p_dev->io.Attributes1;
+                       p_dev->io.BasePort2 = io->win[1].base;
+                       p_dev->io.NumPorts2 = io->win[1].len;
+               }
        }
 
-       while (1) {
-               cistpl_cftable_entry_t dflt = { 0 };
-               cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
-               if (pcmcia_get_tuple_data(link, &tuple))
-                       goto next_entry;
-               if (pcmcia_parse_tuple(&tuple, &parse))
-                       goto next_entry;
-
-               if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
-                       dflt = *cfg;
-               if (cfg->index == 0)
-                       goto next_entry;
-               link->conf.ConfigIndex = cfg->index;
-
-               /* Do we need to allocate an interrupt? */
-               if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1)
-                       link->conf.Attributes |= CONF_ENABLE_IRQ;
-
-               /* IO window settings */
-               link->io.NumPorts1 = link->io.NumPorts2 = 0;
-               if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
-                       cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
-                       link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
-                       if (!(io->flags & CISTPL_IO_8BIT))
-                               link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
-                       if (!(io->flags & CISTPL_IO_16BIT))
-                               link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
-                       link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
-                       link->io.BasePort1 = io->win[0].base;
-                       link->io.NumPorts1 = io->win[0].len;
-                       if (io->nwin > 1) {
-                               link->io.Attributes2 = link->io.Attributes1;
-                               link->io.BasePort2 = io->win[1].base;
-                               link->io.NumPorts2 = io->win[1].len;
-                       }
-               }
+       /* This reserves IO space but doesn't actually enable it */
+       return pcmcia_request_io(p_dev, &p_dev->io);
+}
 
-               /* This reserves IO space but doesn't actually enable it */
-               if (pcmcia_request_io(link, &link->io))
-                       goto next_entry;
+static void daqp_cs_config(struct pcmcia_device *link)
+{
+       struct local_info_t *dev = link->priv;
+       int ret;
 
-               /* If we got this far, we're cool! */
-               break;
+       dev_dbg(&link->dev, "daqp_cs_config\n");
 
-next_entry:
-               last_ret = pcmcia_get_next_tuple(link, &tuple);
-               if (last_ret) {
-                       cs_error(link, GetNextTuple, last_ret);
-                       goto cs_failed;
-               }
+       ret = pcmcia_loop_config(link, daqp_pcmcia_config_loop, NULL);
+       if (ret) {
+               dev_warn(&link->dev, "no configuration found\n");
+               goto failed;
        }
 
        /*
@@ -1251,11 +1150,9 @@ next_entry:
           irq structure is initialized.
         */
        if (link->conf.Attributes & CONF_ENABLE_IRQ) {
-               last_ret = pcmcia_request_irq(link, &link->irq);
-               if (last_ret) {
-                       cs_error(link, RequestIRQ, last_ret);
-                       goto cs_failed;
-               }
+               ret = pcmcia_request_irq(link, &link->irq);
+               if (ret)
+                       goto failed;
        }
 
        /*
@@ -1263,11 +1160,9 @@ next_entry:
           the I/O windows and the interrupt mapping, and putting the
           card and host interface into "Memory and IO" mode.
         */
-       last_ret = pcmcia_request_configuration(link, &link->conf);
-       if (last_ret) {
-               cs_error(link, RequestConfiguration, last_ret);
-               goto cs_failed;
-       }
+       ret = pcmcia_request_configuration(link, &link->conf);
+       if (ret)
+               goto failed;
 
        /*
           At this point, the dev_node_t structure(s) need to be
@@ -1296,14 +1191,14 @@ next_entry:
 
        return;
 
-cs_failed:
+failed:
        daqp_cs_release(link);
 
 }                              /* daqp_cs_config */
 
 static void daqp_cs_release(struct pcmcia_device *link)
 {
-       DEBUG(0, "daqp_cs_release(0x%p)\n", link);
+       dev_dbg(&link->dev, "daqp_cs_release\n");
 
        pcmcia_disable_device(link);
 }                              /* daqp_cs_release */
@@ -1363,7 +1258,6 @@ struct pcmcia_driver daqp_cs_driver = {
 
 int __init init_module(void)
 {
-       DEBUG(0, "%s\n", version);
        pcmcia_register_driver(&daqp_cs_driver);
        comedi_driver_register(&driver_daqp);
        return 0;
@@ -1371,7 +1265,6 @@ int __init init_module(void)
 
 void __exit cleanup_module(void)
 {
-       DEBUG(0, "daqp_cs: unloading\n");
        comedi_driver_unregister(&driver_daqp);
        pcmcia_unregister_driver(&daqp_cs_driver);
 }
index 8c85a9c3665a4a37d01fdebd478e827f65239ff8..f4a6541c3e60ffcdffa1166a353e45929b4d25d7 100644 (file)
@@ -261,7 +261,7 @@ static int read_reg_fp(struct i2c_client *client, u16 addr, u16 *val)
 
        memset(buf, 0xcd, 6);
        usb = go->hpi_context;
-       if (down_interruptible(&usb->i2c_lock) != 0) {
+       if (mutex_lock_interruptible(&usb->i2c_lock) != 0) {
                printk(KERN_INFO "i2c lock failed\n");
                kfree(buf);
                return -EINTR;
@@ -270,7 +270,7 @@ static int read_reg_fp(struct i2c_client *client, u16 addr, u16 *val)
                kfree(buf);
                return -EFAULT;
        }
-       up(&usb->i2c_lock);
+       mutex_unlock(&usb->i2c_lock);
 
        *val = (buf[0] << 8) | buf[1];
        kfree(buf);
diff --git a/drivers/staging/go7007/s2250-loader.h b/drivers/staging/go7007/s2250-loader.h
new file mode 100644 (file)
index 0000000..b7c301a
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2005-2006 Micronas USA Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ */
+
+#ifndef _S2250_LOADER_H_
+#define _S2250_LOADER_H_
+
+extern int s2250loader_init(void);
+extern void s2250loader_cleanup(void);
+
+#endif
index 51aa861292fc5ff0539baaaee69eee698923d72c..a48ee3a126466957290ae86d0a35e2a0e7212b75 100644 (file)
@@ -16,6 +16,7 @@
  * Place - Suite 330, Boston, MA 02111-1307 USA.
  *
  * Authors:
+ *   Haiyang Zhang <haiyangz@microsoft.com>
  *   Hank Janssen  <hjanssen@microsoft.com>
  *
  */
index d649ee169d953ae3129c0ff377dd5ee866ed968f..746370e82115ce30ea1b99973dc3016d5d9cd862 100644 (file)
@@ -611,7 +611,7 @@ void VmbusChannelClose(struct vmbus_channel *Channel)
 
        /* Stop callback and cancel the timer asap */
        Channel->OnChannelCallback = NULL;
-       del_timer(&Channel->poll_timer);
+       del_timer_sync(&Channel->poll_timer);
 
        /* Send a closing message */
        info = kmalloc(sizeof(*info) +
@@ -978,14 +978,10 @@ void VmbusChannelOnChannelEvent(struct vmbus_channel *Channel)
 {
        DumpVmbusChannel(Channel);
        ASSERT(Channel->OnChannelCallback);
-#ifdef ENABLE_POLLING
-       del_timer(&Channel->poll_timer);
-       Channel->OnChannelCallback(Channel->ChannelCallbackContext);
-       channel->poll_timer.expires(jiffies + usecs_to_jiffies(100);
-       add_timer(&channel->poll_timer);
-#else
+
        Channel->OnChannelCallback(Channel->ChannelCallbackContext);
-#endif
+
+       mod_timer(&Channel->poll_timer, jiffies + usecs_to_jiffies(100));
 }
 
 /**
@@ -997,10 +993,6 @@ void VmbusChannelOnTimer(unsigned long data)
 
        if (channel->OnChannelCallback) {
                channel->OnChannelCallback(channel->ChannelCallbackContext);
-#ifdef ENABLE_POLLING
-               channel->poll_timer.expires(jiffies + usecs_to_jiffies(100);
-               add_timer(&channel->poll_timer);
-#endif
        }
 }
 
index 3db62caedcffda0b06d9e37b1ce66f7a95ab15ae..ef38467ed4e20d51ce71033265717d1ebc3023dd 100644 (file)
@@ -119,7 +119,7 @@ static inline void ReleaseVmbusChannel(void *context)
  */
 void FreeVmbusChannel(struct vmbus_channel *Channel)
 {
-       del_timer(&Channel->poll_timer);
+       del_timer_sync(&Channel->poll_timer);
 
        /*
         * We have to release the channel's workqueue/thread in the vmbus's
index d384c0ddf06916275a666ea8b8fa8bf054b2c258..1c717f9a554ef36cc1dd43725f54989b99db5b9f 100644 (file)
@@ -15,6 +15,7 @@
  * Place - Suite 330, Boston, MA 02111-1307 USA.
  *
  * Authors:
+ *   Haiyang Zhang <haiyangz@microsoft.com>
  *   Hank Janssen  <hjanssen@microsoft.com>
  */
 #include <linux/kernel.h>
index 3e7112f7c75536bb9c0b990c39da6180aaf10d97..6e0e0349412675675f2ce0c65053ffb9bbde18d5 100644 (file)
@@ -16,6 +16,7 @@
  * Place - Suite 330, Boston, MA 02111-1307 USA.
  *
  * Authors:
+ *   Haiyang Zhang <haiyangz@microsoft.com>
  *   Hank Janssen  <hjanssen@microsoft.com>
  *
  */
index 14015c9279400436ab558e68ae6d30a5f730fa41..2f7c425896f7a6c81163ec80ba72488b5a737fe6 100644 (file)
@@ -196,7 +196,7 @@ static int StorVscChannelInit(struct hv_device *Device)
         * Now, initiate the vsc/vsp initialization protocol on the open
         * channel
         */
-       memset(request, sizeof(struct storvsc_request_extension), 0);
+       memset(request, 0, sizeof(struct storvsc_request_extension));
        request->WaitEvent = osd_WaitEventCreate();
 
        vstorPacket->Operation = VStorOperationBeginInitialization;
@@ -233,7 +233,7 @@ static int StorVscChannelInit(struct hv_device *Device)
        DPRINT_INFO(STORVSC, "QUERY_PROTOCOL_VERSION_OPERATION...");
 
        /* reuse the packet for version range supported */
-       memset(vstorPacket, sizeof(struct vstor_packet), 0);
+       memset(vstorPacket, 0, sizeof(struct vstor_packet));
        vstorPacket->Operation = VStorOperationQueryProtocolVersion;
        vstorPacket->Flags = REQUEST_COMPLETION_FLAG;
 
@@ -266,7 +266,7 @@ static int StorVscChannelInit(struct hv_device *Device)
        /* Query channel properties */
        DPRINT_INFO(STORVSC, "QUERY_PROPERTIES_OPERATION...");
 
-       memset(vstorPacket, sizeof(struct vstor_packet), 0);
+       memset(vstorPacket, 0, sizeof(struct vstor_packet));
        vstorPacket->Operation = VStorOperationQueryProperties;
        vstorPacket->Flags = REQUEST_COMPLETION_FLAG;
        vstorPacket->StorageChannelProperties.PortNumber =
@@ -305,7 +305,7 @@ static int StorVscChannelInit(struct hv_device *Device)
 
        DPRINT_INFO(STORVSC, "END_INITIALIZATION_OPERATION...");
 
-       memset(vstorPacket, sizeof(struct vstor_packet), 0);
+       memset(vstorPacket, 0, sizeof(struct vstor_packet));
        vstorPacket->Operation = VStorOperationEndInitialization;
        vstorPacket->Flags = REQUEST_COMPLETION_FLAG;
 
@@ -508,7 +508,7 @@ static int StorVscConnectToVsp(struct hv_device *Device)
        int ret;
 
        storDriver = (struct storvsc_driver_object *)Device->Driver;
-       memset(&props, sizeof(struct vmstorage_channel_properties), 0);
+       memset(&props, 0, sizeof(struct vmstorage_channel_properties));
 
        /* Open the channel */
        ret = Device->Driver->VmbusChannelInterface.Open(Device,
index 99c49261a8b4f125b9c05b8fa8cf1604ea70358b..62b282844a53eb2e29ff96e418d95d778b1fc700 100644 (file)
@@ -15,6 +15,7 @@
  * Place - Suite 330, Boston, MA 02111-1307 USA.
  *
  * Authors:
+ *   Haiyang Zhang <haiyangz@microsoft.com>
  *   Hank Janssen  <hjanssen@microsoft.com>
  */
 #include <linux/init.h>
index 3192d50f72511a897627191babeb5e7b6c97e3fd..0d7459e2d0360b8996b104e1385df56bd9fd8150 100644 (file)
@@ -15,6 +15,7 @@
  * Place - Suite 330, Boston, MA 02111-1307 USA.
  *
  * Authors:
+ *   Haiyang Zhang <haiyangz@microsoft.com>
  *   Hank Janssen  <hjanssen@microsoft.com>
  */
 #include <linux/init.h>
index 42230e62a2227b9bf1297ff575a2c618b98902de..31a58e50892417b57f58b28374e6a320eaff5c43 100644 (file)
@@ -170,7 +170,7 @@ static u32 cvm_oct_get_link(struct net_device *dev)
        return ret;
 }
 
-struct const ethtool_ops cvm_oct_ethtool_ops = {
+const struct ethtool_ops cvm_oct_ethtool_ops = {
        .get_drvinfo = cvm_oct_get_drvinfo,
        .get_settings = cvm_oct_get_settings,
        .set_settings = cvm_oct_set_settings,
index 66190b0cb68f355c6f482bba828cdcc6c4228017..00dc0f4bad19933b0dd2d48ce9c1bc61faf3f173 100644 (file)
@@ -317,6 +317,6 @@ void cvm_oct_spi_uninit(struct net_device *dev)
                        cvmx_write_csr(CVMX_SPXX_INT_MSK(interface), 0);
                        cvmx_write_csr(CVMX_STXX_INT_MSK(interface), 0);
                }
-               free_irq(8 + 46, &number_spi_ports);
+               free_irq(OCTEON_IRQ_RML, &number_spi_ports);
        }
 }
index b8479517dce28b9fa76af52c532c8af556cb54e5..492c5029992de65c9b35e854fd141d9fd8c5969a 100644 (file)
@@ -111,6 +111,16 @@ MODULE_PARM_DESC(disable_core_queueing, "\n"
        "\tallows packets to be sent without lock contention in the packet\n"
        "\tscheduler resulting in some cases in improved throughput.\n");
 
+
+/*
+ * The offset from mac_addr_base that should be used for the next port
+ * that is configured.  By convention, if any mgmt ports exist on the
+ * chip, they get the first mac addresses, The ports controlled by
+ * this driver are numbered sequencially following any mgmt addresses
+ * that may exist.
+ */
+static unsigned int cvm_oct_mac_addr_offset;
+
 /**
  * Periodic timer to check auto negotiation
  */
@@ -474,16 +484,30 @@ static int cvm_oct_common_set_mac_address(struct net_device *dev, void *addr)
  */
 int cvm_oct_common_init(struct net_device *dev)
 {
-       static int count;
-       char mac[8] = { 0x00, 0x00,
-               octeon_bootinfo->mac_addr_base[0],
-               octeon_bootinfo->mac_addr_base[1],
-               octeon_bootinfo->mac_addr_base[2],
-               octeon_bootinfo->mac_addr_base[3],
-               octeon_bootinfo->mac_addr_base[4],
-               octeon_bootinfo->mac_addr_base[5] + count
-       };
        struct octeon_ethernet *priv = netdev_priv(dev);
+       struct sockaddr sa;
+       u64 mac = ((u64)(octeon_bootinfo->mac_addr_base[0] & 0xff) << 40) |
+               ((u64)(octeon_bootinfo->mac_addr_base[1] & 0xff) << 32) |
+               ((u64)(octeon_bootinfo->mac_addr_base[2] & 0xff) << 24) |
+               ((u64)(octeon_bootinfo->mac_addr_base[3] & 0xff) << 16) |
+               ((u64)(octeon_bootinfo->mac_addr_base[4] & 0xff) << 8) |
+               (u64)(octeon_bootinfo->mac_addr_base[5] & 0xff);
+
+       mac += cvm_oct_mac_addr_offset;
+       sa.sa_data[0] = (mac >> 40) & 0xff;
+       sa.sa_data[1] = (mac >> 32) & 0xff;
+       sa.sa_data[2] = (mac >> 24) & 0xff;
+       sa.sa_data[3] = (mac >> 16) & 0xff;
+       sa.sa_data[4] = (mac >> 8) & 0xff;
+       sa.sa_data[5] = mac & 0xff;
+
+       if (cvm_oct_mac_addr_offset >= octeon_bootinfo->mac_addr_count)
+               printk(KERN_DEBUG "%s: Using MAC outside of the assigned range:"
+                       " %02x:%02x:%02x:%02x:%02x:%02x\n", dev->name,
+                       sa.sa_data[0] & 0xff, sa.sa_data[1] & 0xff,
+                       sa.sa_data[2] & 0xff, sa.sa_data[3] & 0xff,
+                       sa.sa_data[4] & 0xff, sa.sa_data[5] & 0xff);
+       cvm_oct_mac_addr_offset++;
 
        /*
         * Force the interface to use the POW send if always_use_pow
@@ -496,14 +520,12 @@ int cvm_oct_common_init(struct net_device *dev)
        if (priv->queue != -1 && USE_HW_TCPUDP_CHECKSUM)
                dev->features |= NETIF_F_IP_CSUM;
 
-       count++;
-
        /* We do our own locking, Linux doesn't need to */
        dev->features |= NETIF_F_LLTX;
        SET_ETHTOOL_OPS(dev, &cvm_oct_ethtool_ops);
 
        cvm_oct_mdio_setup_device(dev);
-       dev->netdev_ops->ndo_set_mac_address(dev, mac);
+       dev->netdev_ops->ndo_set_mac_address(dev, &sa);
        dev->netdev_ops->ndo_change_mtu(dev, dev->mtu);
 
        /*
@@ -620,6 +642,13 @@ static int __init cvm_oct_init_module(void)
 
        pr_notice("cavium-ethernet %s\n", OCTEON_ETHERNET_VERSION);
 
+       if (OCTEON_IS_MODEL(OCTEON_CN52XX))
+               cvm_oct_mac_addr_offset = 2; /* First two are the mgmt ports. */
+       else if (OCTEON_IS_MODEL(OCTEON_CN56XX))
+               cvm_oct_mac_addr_offset = 1; /* First one is the mgmt port. */
+       else
+               cvm_oct_mac_addr_offset = 0;
+
        cvm_oct_proc_initialize();
        cvm_oct_rx_initialize();
        cvm_oct_configure_common_hw();
index c09a9160739dc087e8eeacd07ceb8fbd727dc50a..a762e79873e978fe1a62067c2409643bd16bf218 100644 (file)
@@ -11,5 +11,4 @@ TODO:
 - sparse fixes
 - integrate with drivers/net/wireless/rtl818x
 
-Please send any patches to Greg Kroah-Hartman <greg@kroah.com> and
-Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>.
+Please send any patches to Greg Kroah-Hartman <greg@kroah.com>.
index b13be9edb278597bd22531fb20d09e88853ad0f3..f11eec700030112e2f4cbfa699a5ddf7d1e57978 100644 (file)
@@ -14,5 +14,4 @@ TODO:
 - sparse fixes
 - integrate with drivers/net/wireless/rtl818x
 
-Please send any patches to Greg Kroah-Hartman <greg@kroah.com> and
-Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>.
+Please send any patches to Greg Kroah-Hartman <greg@kroah.com>.
index 8462cd17eb61777805ffa235806cf8d4cebec332..cb04aaafc46f1810e111a356c11823bb53ffcd8e 100644 (file)
@@ -16,6 +16,5 @@ TODO:
 - sparse fixes
 - integrate with drivers/net/wireless
 
-Please send any patches to Greg Kroah-Hartman <greg@kroah.com>,
-Forest Bond <forest@alittletooquiet.net> and Bartlomiej Zolnierkiewicz
-<bzolnier@gmail.com>.
+Please send any patches to Greg Kroah-Hartman <greg@kroah.com>
+and Forest Bond <forest@alittletooquiet.net>.
index 17cf50c6735e42c3a709c67b4cabb74091cddf96..a318995ba07f471032d46885e0303fdf66e94d50 100644 (file)
@@ -15,6 +15,5 @@ TODO:
 - sparse fixes
 - integrate with drivers/net/wireless
 
-Please send any patches to Greg Kroah-Hartman <greg@kroah.com>,
-Forest Bond <forest@alittletooquiet.net> and Bartlomiej Zolnierkiewicz
-<bzolnier@gmail.com>.
+Please send any patches to Greg Kroah-Hartman <greg@kroah.com>
+and Forest Bond <forest@alittletooquiet.net>.
index 347c3ed1d9f15fbe1edd10944b6b44b72ace07ac..d442fd35620a1b9667d81547e65cb5d7f3bde7e7 100644 (file)
  *     PCMCIA service support for Quicknet cards
  */
  
-#ifdef PCMCIA_DEBUG
-static int pc_debug = PCMCIA_DEBUG;
-module_param(pc_debug, int, 0644);
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
-#else
-#define DEBUG(n, args...)
-#endif
 
 typedef struct ixj_info_t {
        int ndev;
@@ -39,7 +32,7 @@ static void ixj_cs_release(struct pcmcia_device * link);
 
 static int ixj_probe(struct pcmcia_device *p_dev)
 {
-       DEBUG(0, "ixj_attach()\n");
+       dev_dbg(&p_dev->dev, "ixj_attach()\n");
        /* Create new ixj device */
        p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
        p_dev->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
@@ -55,33 +48,30 @@ static int ixj_probe(struct pcmcia_device *p_dev)
 
 static void ixj_detach(struct pcmcia_device *link)
 {
-       DEBUG(0, "ixj_detach(0x%p)\n", link);
+       dev_dbg(&link->dev, "ixj_detach\n");
 
        ixj_cs_release(link);
 
         kfree(link->priv);
 }
 
-#define CS_CHECK(fn, ret) \
-do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
-
 static void ixj_get_serial(struct pcmcia_device * link, IXJ * j)
 {
        char *str;
        int i, place;
-       DEBUG(0, "ixj_get_serial(0x%p)\n", link);
+       dev_dbg(&link->dev, "ixj_get_serial\n");
 
        str = link->prod_id[0];
        if (!str)
-               goto cs_failed;
+               goto failed;
        printk("%s", str);
        str = link->prod_id[1];
        if (!str)
-               goto cs_failed;
+               goto failed;
        printk(" %s", str);
        str = link->prod_id[2];
        if (!str)
-               goto cs_failed;
+               goto failed;
        place = 1;
        for (i = strlen(str) - 1; i >= 0; i--) {
                switch (str[i]) {
@@ -118,9 +108,9 @@ static void ixj_get_serial(struct pcmcia_device * link, IXJ * j)
        }
        str = link->prod_id[3];
        if (!str)
-               goto cs_failed;
+               goto failed;
        printk(" version %s\n", str);
-      cs_failed:
+failed:
        return;
 }
 
@@ -151,13 +141,13 @@ static int ixj_config(struct pcmcia_device * link)
        cistpl_cftable_entry_t dflt = { 0 };
 
        info = link->priv;
-       DEBUG(0, "ixj_config(0x%p)\n", link);
+       dev_dbg(&link->dev, "ixj_config\n");
 
        if (pcmcia_loop_config(link, ixj_config_check, &dflt))
-               goto cs_failed;
+               goto failed;
 
        if (pcmcia_request_configuration(link, &link->conf))
-               goto cs_failed;
+               goto failed;
 
        /*
         *      Register the card with the core.
@@ -170,7 +160,7 @@ static int ixj_config(struct pcmcia_device * link)
        ixj_get_serial(link, j);
        return 0;
 
-      cs_failed:
+failed:
        ixj_cs_release(link);
        return -ENODEV;
 }
@@ -178,7 +168,7 @@ static int ixj_config(struct pcmcia_device * link)
 static void ixj_cs_release(struct pcmcia_device *link)
 {
        ixj_info_t *info = link->priv;
-       DEBUG(0, "ixj_cs_release(0x%p)\n", link);
+       dev_dbg(&link->dev, "ixj_cs_release\n");
        info->ndev = 0;
        pcmcia_disable_device(link);
 }
index 02347c57357d20511e3e0e25f34572ab053078c0..aa53db9f2e88309d739809adf10928fd0a6d1a57 100644 (file)
@@ -178,6 +178,7 @@ static int uio_pdrv_genirq_probe(struct platform_device *pdev)
        return 0;
  bad1:
        kfree(priv);
+       pm_runtime_disable(&pdev->dev);
  bad0:
        return ret;
 }
index e3861b21e776600fb721699c8ede4e62dc51f8fc..e4eca7810bcf1bed6821086e4bab6130525e3c17 100644 (file)
@@ -609,9 +609,9 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp)
 
        acm->throttle = 0;
 
-       tasklet_schedule(&acm->urb_task);
        set_bit(ASYNCB_INITIALIZED, &acm->port.flags);
        rv = tty_port_block_til_ready(&acm->port, tty, filp);
+       tasklet_schedule(&acm->urb_task);
 done:
        mutex_unlock(&acm->mutex);
 err_out:
@@ -686,15 +686,21 @@ static void acm_tty_close(struct tty_struct *tty, struct file *filp)
 
        /* Perform the closing process and see if we need to do the hardware
           shutdown */
-       if (!acm || tty_port_close_start(&acm->port, tty, filp) == 0)
+       if (!acm)
+               return;
+       if (tty_port_close_start(&acm->port, tty, filp) == 0) {
+               mutex_lock(&open_mutex);
+               if (!acm->dev) {
+                       tty_port_tty_set(&acm->port, NULL);
+                       acm_tty_unregister(acm);
+                       tty->driver_data = NULL;
+               }
+               mutex_unlock(&open_mutex);
                return;
+       }
        acm_port_down(acm, 0);
        tty_port_close_end(&acm->port, tty);
-       mutex_lock(&open_mutex);
        tty_port_tty_set(&acm->port, NULL);
-       if (!acm->dev)
-               acm_tty_unregister(acm);
-       mutex_unlock(&open_mutex);
 }
 
 static int acm_tty_write(struct tty_struct *tty,
index 5ce839137ad6a8350b4a6053f5076582ce076487..0f857e6450581159a261fc59d0403b7300fc8b24 100644 (file)
@@ -444,7 +444,7 @@ resubmit:
 static inline int
 hub_clear_tt_buffer (struct usb_device *hdev, u16 devinfo, u16 tt)
 {
-       return usb_control_msg(hdev, usb_rcvctrlpipe(hdev, 0),
+       return usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0),
                               HUB_CLEAR_TT_BUFFER, USB_RT_PORT, devinfo,
                               tt, NULL, 0, 1000);
 }
index d5b65962dd36a0bf9050cd61c51140979f9ca3d2..731150d4b1d9d0e646e34ca03f7cbaa0ac85e398 100644 (file)
@@ -1213,7 +1213,12 @@ udc_queue(struct usb_ep *usbep, struct usb_request *usbreq, gfp_t gfp)
                                tmp &= AMD_UNMASK_BIT(ep->num);
                                writel(tmp, &dev->regs->ep_irqmsk);
                        }
-               }
+               } else if (ep->in) {
+                               /* enable ep irq */
+                               tmp = readl(&dev->regs->ep_irqmsk);
+                               tmp &= AMD_UNMASK_BIT(ep->num);
+                               writel(tmp, &dev->regs->ep_irqmsk);
+                       }
 
        } else if (ep->dma) {
 
@@ -2005,18 +2010,17 @@ __acquires(dev->lock)
 {
        int tmp;
 
-       /* empty queues and init hardware */
-       udc_basic_init(dev);
-       for (tmp = 0; tmp < UDC_EP_NUM; tmp++) {
-               empty_req_queue(&dev->ep[tmp]);
-       }
-
        if (dev->gadget.speed != USB_SPEED_UNKNOWN) {
                spin_unlock(&dev->lock);
                driver->disconnect(&dev->gadget);
                spin_lock(&dev->lock);
        }
-       /* init */
+
+       /* empty queues and init hardware */
+       udc_basic_init(dev);
+       for (tmp = 0; tmp < UDC_EP_NUM; tmp++)
+               empty_req_queue(&dev->ep[tmp]);
+
        udc_setup_endpoints(dev);
 }
 
@@ -2472,6 +2476,13 @@ static irqreturn_t udc_data_in_isr(struct udc *dev, int ep_ix)
                                }
                        }
 
+               } else if (!use_dma && ep->in) {
+                       /* disable interrupt */
+                       tmp = readl(
+                               &dev->regs->ep_irqmsk);
+                       tmp |= AMD_BIT(ep->num);
+                       writel(tmp,
+                               &dev->regs->ep_irqmsk);
                }
        }
        /* clear status bits */
@@ -3279,6 +3290,17 @@ static int udc_pci_probe(
                goto finished;
        }
 
+       spin_lock_init(&dev->lock);
+       /* udc csr registers base */
+       dev->csr = dev->virt_addr + UDC_CSR_ADDR;
+       /* dev registers base */
+       dev->regs = dev->virt_addr + UDC_DEVCFG_ADDR;
+       /* ep registers base */
+       dev->ep_regs = dev->virt_addr + UDC_EPREGS_ADDR;
+       /* fifo's base */
+       dev->rxfifo = (u32 __iomem *)(dev->virt_addr + UDC_RXFIFO_ADDR);
+       dev->txfifo = (u32 __iomem *)(dev->virt_addr + UDC_TXFIFO_ADDR);
+
        if (request_irq(pdev->irq, udc_irq, IRQF_SHARED, name, dev) != 0) {
                dev_dbg(&dev->pdev->dev, "request_irq(%d) fail\n", pdev->irq);
                kfree(dev);
@@ -3331,7 +3353,6 @@ static int udc_probe(struct udc *dev)
        udc_pollstall_timer.data = 0;
 
        /* device struct setup */
-       spin_lock_init(&dev->lock);
        dev->gadget.ops = &udc_ops;
 
        dev_set_name(&dev->gadget.dev, "gadget");
@@ -3340,16 +3361,6 @@ static int udc_probe(struct udc *dev)
        dev->gadget.name = name;
        dev->gadget.is_dualspeed = 1;
 
-       /* udc csr registers base */
-       dev->csr = dev->virt_addr + UDC_CSR_ADDR;
-       /* dev registers base */
-       dev->regs = dev->virt_addr + UDC_DEVCFG_ADDR;
-       /* ep registers base */
-       dev->ep_regs = dev->virt_addr + UDC_EPREGS_ADDR;
-       /* fifo's base */
-       dev->rxfifo = (u32 __iomem *)(dev->virt_addr + UDC_RXFIFO_ADDR);
-       dev->txfifo = (u32 __iomem *)(dev->virt_addr + UDC_TXFIFO_ADDR);
-
        /* init registers, interrupts, ... */
        startup_registers(dev);
 
index 9835e0713943397fde9b5200f58fa36ab7db547a..f5f5601701c9b2c38168ddc0052e5cf6818a07c5 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/errno.h>
 #include <linux/init.h>
 #include <linux/timer.h>
+#include <linux/ktime.h>
 #include <linux/list.h>
 #include <linux/interrupt.h>
 #include <linux/usb.h>
@@ -676,6 +677,7 @@ static int ehci_run (struct usb_hcd *hcd)
        ehci_readl(ehci, &ehci->regs->command); /* unblock posted writes */
        msleep(5);
        up_write(&ehci_cf_port_reset_rwsem);
+       ehci->last_periodic_enable = ktime_get_real();
 
        temp = HC_VERSION(ehci_readl(ehci, &ehci->caps->hc_capbase));
        ehci_info (ehci,
index 378861b9d79a96fe926dcf86755c984646528a22..ead5f4f2aa5a43ecf189000e9b0322888675d1a0 100644 (file)
@@ -111,6 +111,10 @@ static int ehci_pci_setup(struct usb_hcd *hcd)
        switch (pdev->vendor) {
        case PCI_VENDOR_ID_INTEL:
                ehci->need_io_watchdog = 0;
+               if (pdev->device == 0x27cc) {
+                       ehci->broken_periodic = 1;
+                       ehci_info(ehci, "using broken periodic workaround\n");
+               }
                break;
        case PCI_VENDOR_ID_TDI:
                if (pdev->device == PCI_DEVICE_ID_TDI_EHCI) {
index 00ad9ce392ed6871c35a31b429865909874f33e5..139a2cc3f6410a3381936d3820c0cb37030ef8c6 100644 (file)
@@ -487,8 +487,20 @@ halt:
                         * we must clear the TT buffer (11.17.5).
                         */
                        if (unlikely(last_status != -EINPROGRESS &&
-                                       last_status != -EREMOTEIO))
-                               ehci_clear_tt_buffer(ehci, qh, urb, token);
+                                       last_status != -EREMOTEIO)) {
+                               /* The TT's in some hubs malfunction when they
+                                * receive this request following a STALL (they
+                                * stop sending isochronous packets).  Since a
+                                * STALL can't leave the TT buffer in a busy
+                                * state (if you believe Figures 11-48 - 11-51
+                                * in the USB 2.0 spec), we won't clear the TT
+                                * buffer in this case.  Strictly speaking this
+                                * is a violation of the spec.
+                                */
+                               if (last_status != -EPIPE)
+                                       ehci_clear_tt_buffer(ehci, qh, urb,
+                                                       token);
+                       }
                }
 
                /* if we're removing something not at the queue head,
index b25cdea93a1f7101da89b0e85f7183366e7468a6..a5535b5e3fe27860caebb3d50f228ea6d85fd1b8 100644 (file)
@@ -475,6 +475,8 @@ static int enable_periodic (struct ehci_hcd *ehci)
        /* make sure ehci_work scans these */
        ehci->next_uframe = ehci_readl(ehci, &ehci->regs->frame_index)
                % (ehci->periodic_size << 3);
+       if (unlikely(ehci->broken_periodic))
+               ehci->last_periodic_enable = ktime_get_real();
        return 0;
 }
 
@@ -486,6 +488,16 @@ static int disable_periodic (struct ehci_hcd *ehci)
        if (--ehci->periodic_sched)
                return 0;
 
+       if (unlikely(ehci->broken_periodic)) {
+               /* delay experimentally determined */
+               ktime_t safe = ktime_add_us(ehci->last_periodic_enable, 1000);
+               ktime_t now = ktime_get_real();
+               s64 delay = ktime_us_delta(safe, now);
+
+               if (unlikely(delay > 0))
+                       udelay(delay);
+       }
+
        /* did setting PSE not take effect yet?
         * takes effect only at frame boundaries...
         */
index 064e76821ff5852e557b9c9dd5de9a297e79caf2..2d85e21ff282e9199be521fe630588cf8b3e01fb 100644 (file)
@@ -118,6 +118,7 @@ struct ehci_hcd {                   /* one per controller */
        unsigned                stamp;
        unsigned                random_frame;
        unsigned long           next_statechange;
+       ktime_t                 last_periodic_enable;
        u32                     command;
 
        /* SILICON QUIRKS */
@@ -127,6 +128,7 @@ struct ehci_hcd {                   /* one per controller */
        unsigned                big_endian_desc:1;
        unsigned                has_amcc_usb23:1;
        unsigned                need_io_watchdog:1;
+       unsigned                broken_periodic:1;
 
        /* required for usb32 quirk */
        #define OHCI_CTRL_HCFS          (3 << 6)
index 78bb7710f36d9ef641f7857b3f688b5c2c9640af..24eb74781919d58ed4454a4e7c1dd7999e04ade1 100644 (file)
@@ -87,6 +87,7 @@ static int ohci_restart (struct ohci_hcd *ohci);
 #ifdef CONFIG_PCI
 static void quirk_amd_pll(int state);
 static void amd_iso_dev_put(void);
+static void sb800_prefetch(struct ohci_hcd *ohci, int on);
 #else
 static inline void quirk_amd_pll(int state)
 {
@@ -96,6 +97,10 @@ static inline void amd_iso_dev_put(void)
 {
        return;
 }
+static inline void sb800_prefetch(struct ohci_hcd *ohci, int on)
+{
+       return;
+}
 #endif
 
 
index d2ba04dd785e4942d69ad28f4b2a3a727d3efd54..b8a1148f248e4faeb404fbcedf76e6c36d0e6ea2 100644 (file)
@@ -177,6 +177,13 @@ static int ohci_quirk_amd700(struct usb_hcd *hcd)
                return 0;
 
        pci_read_config_byte(amd_smbus_dev, PCI_REVISION_ID, &rev);
+
+       /* SB800 needs pre-fetch fix */
+       if ((rev >= 0x40) && (rev <= 0x4f)) {
+               ohci->flags |= OHCI_QUIRK_AMD_PREFETCH;
+               ohci_dbg(ohci, "enabled AMD prefetch quirk\n");
+       }
+
        if ((rev > 0x3b) || (rev < 0x30)) {
                pci_dev_put(amd_smbus_dev);
                amd_smbus_dev = NULL;
@@ -262,6 +269,19 @@ static void amd_iso_dev_put(void)
 
 }
 
+static void sb800_prefetch(struct ohci_hcd *ohci, int on)
+{
+       struct pci_dev *pdev;
+       u16 misc;
+
+       pdev = to_pci_dev(ohci_to_hcd(ohci)->self.controller);
+       pci_read_config_word(pdev, 0x50, &misc);
+       if (on == 0)
+               pci_write_config_word(pdev, 0x50, misc & 0xfcff);
+       else
+               pci_write_config_word(pdev, 0x50, misc | 0x0300);
+}
+
 /* List of quirks for OHCI */
 static const struct pci_device_id ohci_pci_quirks[] = {
        {
index 16fecb8ecc39dde0360153ac4f1637c036fd0ab5..35288bcae0dbc10ccc04fe380e36ba8026f1220a 100644 (file)
@@ -49,9 +49,12 @@ __acquires(ohci->lock)
        switch (usb_pipetype (urb->pipe)) {
        case PIPE_ISOCHRONOUS:
                ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs--;
-               if (ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs == 0
-                               && quirk_amdiso(ohci))
-                       quirk_amd_pll(1);
+               if (ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs == 0) {
+                       if (quirk_amdiso(ohci))
+                               quirk_amd_pll(1);
+                       if (quirk_amdprefetch(ohci))
+                               sb800_prefetch(ohci, 0);
+               }
                break;
        case PIPE_INTERRUPT:
                ohci_to_hcd(ohci)->self.bandwidth_int_reqs--;
@@ -680,9 +683,12 @@ static void td_submit_urb (
                                data + urb->iso_frame_desc [cnt].offset,
                                urb->iso_frame_desc [cnt].length, urb, cnt);
                }
-               if (ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs == 0
-                               && quirk_amdiso(ohci))
-                       quirk_amd_pll(0);
+               if (ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs == 0) {
+                       if (quirk_amdiso(ohci))
+                               quirk_amd_pll(0);
+                       if (quirk_amdprefetch(ohci))
+                               sb800_prefetch(ohci, 1);
+               }
                periodic = ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs++ == 0
                        && ohci_to_hcd(ohci)->self.bandwidth_int_reqs == 0;
                break;
index 222011f6172cbccd23b199e85319730f72f7bb52..5bf15fed0d9fcd4f4654bb51c7ae38ea82cf905c 100644 (file)
@@ -402,6 +402,7 @@ struct ohci_hcd {
 #define        OHCI_QUIRK_FRAME_NO     0x80                    /* no big endian frame_no shift */
 #define        OHCI_QUIRK_HUB_POWER    0x100                   /* distrust firmware power/oc setup */
 #define        OHCI_QUIRK_AMD_ISO      0x200                   /* ISO transfers*/
+#define        OHCI_QUIRK_AMD_PREFETCH 0x400                   /* pre-fetch for ISO transfer */
        // there are also chip quirks/bugs in init logic
 
        struct work_struct      nec_work;       /* Worker for NEC quirk */
@@ -433,6 +434,10 @@ static inline int quirk_amdiso(struct ohci_hcd *ohci)
 {
        return ohci->flags & OHCI_QUIRK_AMD_ISO;
 }
+static inline int quirk_amdprefetch(struct ohci_hcd *ohci)
+{
+       return ohci->flags & OHCI_QUIRK_AMD_PREFETCH;
+}
 #else
 static inline int quirk_nec(struct ohci_hcd *ohci)
 {
@@ -446,6 +451,10 @@ static inline int quirk_amdiso(struct ohci_hcd *ohci)
 {
        return 0;
 }
+static inline int quirk_amdprefetch(struct ohci_hcd *ohci)
+{
+       return 0;
+}
 #endif
 
 /* convert between an hcd pointer and the corresponding ohci_hcd */
index 516848dd9b48b2aed0193c77d8b0cbcbc765b7a6..39d253e841f6412f3aa7d8bd08e54ba28d37bb05 100644 (file)
@@ -37,28 +37,8 @@ MODULE_LICENSE("GPL");
 /* MACROS                                                             */
 /*====================================================================*/
 
-#if defined(DEBUG) || defined(PCMCIA_DEBUG)
-
-static int pc_debug = 0;
-module_param(pc_debug, int, 0644);
-
-#define DBG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG "sl811_cs: " args)
-
-#else
-#define DBG(n, args...) do{}while(0)
-#endif /* no debugging */
-
 #define INFO(args...) printk(KERN_INFO "sl811_cs: " args)
 
-#define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0444)
-
-#define CS_CHECK(fn, ret) \
-       do { \
-               last_fn = (fn); \
-               if ((last_ret = (ret)) != 0) \
-                       goto cs_failed; \
-       } while (0)
-
 /*====================================================================*/
 /* VARIABLES                                                          */
 /*====================================================================*/
@@ -76,7 +56,7 @@ static void sl811_cs_release(struct pcmcia_device * link);
 
 static void release_platform_dev(struct device * dev)
 {
-       DBG(0, "sl811_cs platform_dev release\n");
+       dev_dbg(dev, "sl811_cs platform_dev release\n");
        dev->parent = NULL;
 }
 
@@ -140,7 +120,7 @@ static int sl811_hc_init(struct device *parent, resource_size_t base_addr,
 
 static void sl811_cs_detach(struct pcmcia_device *link)
 {
-       DBG(0, "sl811_cs_detach(0x%p)\n", link);
+       dev_dbg(&link->dev, "sl811_cs_detach\n");
 
        sl811_cs_release(link);
 
@@ -150,7 +130,7 @@ static void sl811_cs_detach(struct pcmcia_device *link)
 
 static void sl811_cs_release(struct pcmcia_device * link)
 {
-       DBG(0, "sl811_cs_release(0x%p)\n", link);
+       dev_dbg(&link->dev, "sl811_cs_release\n");
 
        pcmcia_disable_device(link);
        platform_device_unregister(&platform_dev);
@@ -205,11 +185,11 @@ static int sl811_cs_config_check(struct pcmcia_device *p_dev,
 
 static int sl811_cs_config(struct pcmcia_device *link)
 {
-       struct device           *parent = &handle_to_dev(link);
+       struct device           *parent = &link->dev;
        local_info_t            *dev = link->priv;
-       int                     last_fn, last_ret;
+       int                     ret;
 
-       DBG(0, "sl811_cs_config(0x%p)\n", link);
+       dev_dbg(&link->dev, "sl811_cs_config\n");
 
        if (pcmcia_loop_config(link, sl811_cs_config_check, NULL))
                goto failed;
@@ -217,14 +197,16 @@ static int sl811_cs_config(struct pcmcia_device *link)
        /* require an IRQ and two registers */
        if (!link->io.NumPorts1 || link->io.NumPorts1 < 2)
                goto failed;
-       if (link->conf.Attributes & CONF_ENABLE_IRQ)
-               CS_CHECK(RequestIRQ,
-                       pcmcia_request_irq(link, &link->irq));
-       else
+       if (link->conf.Attributes & CONF_ENABLE_IRQ) {
+               ret = pcmcia_request_irq(link, &link->irq);
+               if (ret)
+                       goto failed;
+       } else
                goto failed;
 
-       CS_CHECK(RequestConfiguration,
-               pcmcia_request_configuration(link, &link->conf));
+       ret = pcmcia_request_configuration(link, &link->conf);
+       if (ret)
+               goto failed;
 
        sprintf(dev->node.dev_name, driver_name);
        dev->node.major = dev->node.minor = 0;
@@ -241,8 +223,6 @@ static int sl811_cs_config(struct pcmcia_device *link)
 
        if (sl811_hc_init(parent, link->io.BasePort1, link->irq.AssignedIRQ)
                        < 0) {
-cs_failed:
-               cs_error(link, last_fn, last_ret);
 failed:
                printk(KERN_WARNING "sl811_cs_config failed\n");
                sl811_cs_release(link);
@@ -263,7 +243,6 @@ static int sl811_cs_probe(struct pcmcia_device *link)
 
        /* Initialize */
        link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
-       link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID;
        link->irq.Handler = NULL;
 
        link->conf.Attributes = 0;
index 1db4fea8c1704e62cdc33ddfeacc353f70273a09..b8fd270a8b0d5f2630ed87dbcf6d24f8a566c86e 100644 (file)
@@ -802,9 +802,11 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci)
        int i;
 
        /* Free the Event Ring Segment Table and the actual Event Ring */
-       xhci_writel(xhci, 0, &xhci->ir_set->erst_size);
-       xhci_write_64(xhci, 0, &xhci->ir_set->erst_base);
-       xhci_write_64(xhci, 0, &xhci->ir_set->erst_dequeue);
+       if (xhci->ir_set) {
+               xhci_writel(xhci, 0, &xhci->ir_set->erst_size);
+               xhci_write_64(xhci, 0, &xhci->ir_set->erst_base);
+               xhci_write_64(xhci, 0, &xhci->ir_set->erst_dequeue);
+       }
        size = sizeof(struct xhci_erst_entry)*(xhci->erst.num_entries);
        if (xhci->erst.entries)
                pci_free_consistent(pdev, size,
@@ -841,9 +843,9 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci)
                                xhci->dcbaa, xhci->dcbaa->dma);
        xhci->dcbaa = NULL;
 
+       scratchpad_free(xhci);
        xhci->page_size = 0;
        xhci->page_shift = 0;
-       scratchpad_free(xhci);
 }
 
 int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
index 173c39c7648912a1e63ef53a38881c4091094a07..821b7b4709de6531b28afb78c428ad4f5379ff81 100644 (file)
@@ -864,9 +864,11 @@ static struct xhci_segment *trb_in_td(
        cur_seg = start_seg;
 
        do {
+               if (start_dma == 0)
+                       return 0;
                /* We may get an event for a Link TRB in the middle of a TD */
                end_seg_dma = xhci_trb_virt_to_dma(cur_seg,
-                               &start_seg->trbs[TRBS_PER_SEGMENT - 1]);
+                               &cur_seg->trbs[TRBS_PER_SEGMENT - 1]);
                /* If the end TRB isn't in this segment, this is set to 0 */
                end_trb_dma = xhci_trb_virt_to_dma(cur_seg, end_trb);
 
@@ -893,8 +895,9 @@ static struct xhci_segment *trb_in_td(
                }
                cur_seg = cur_seg->next;
                start_dma = xhci_trb_virt_to_dma(cur_seg, &cur_seg->trbs[0]);
-       } while (1);
+       } while (cur_seg != start_seg);
 
+       return 0;
 }
 
 /*
index 9ed3e741bee160c7f2d71906810146f95f1da59a..10f3205798e880ce4f1351735666bac903e34398 100644 (file)
@@ -348,12 +348,12 @@ static unsigned int mon_buff_area_alloc_contiguous(struct mon_reader_bin *rp,
 
 /*
  * Return a few (kilo-)bytes to the head of the buffer.
- * This is used if a DMA fetch fails.
+ * This is used if a data fetch fails.
  */
 static void mon_buff_area_shrink(struct mon_reader_bin *rp, unsigned int size)
 {
 
-       size = (size + PKT_ALIGN-1) & ~(PKT_ALIGN-1);
+       /* size &= ~(PKT_ALIGN-1);  -- we're called with aligned size */
        rp->b_cnt -= size;
        if (rp->b_in < size)
                rp->b_in += rp->b_size;
@@ -433,6 +433,7 @@ static void mon_bin_event(struct mon_reader_bin *rp, struct urb *urb,
        unsigned int urb_length;
        unsigned int offset;
        unsigned int length;
+       unsigned int delta;
        unsigned int ndesc, lendesc;
        unsigned char dir;
        struct mon_bin_hdr *ep;
@@ -537,8 +538,10 @@ static void mon_bin_event(struct mon_reader_bin *rp, struct urb *urb,
        if (length != 0) {
                ep->flag_data = mon_bin_get_data(rp, offset, urb, length);
                if (ep->flag_data != 0) {       /* Yes, it's 0x00, not '0' */
-                       ep->len_cap = 0;
-                       mon_buff_area_shrink(rp, length);
+                       delta = (ep->len_cap + PKT_ALIGN-1) & ~(PKT_ALIGN-1);
+                       ep->len_cap -= length;
+                       delta -= (ep->len_cap + PKT_ALIGN-1) & ~(PKT_ALIGN-1);
+                       mon_buff_area_shrink(rp, delta);
                }
        } else {
                ep->flag_data = data_tag;
index c3577bbbae6c76722b5d9e7699f6045c8baf6cbc..ef2332a9941dec7a39c25d52a69b4fce3943771d 100644 (file)
@@ -1442,11 +1442,6 @@ static int cppi_channel_abort(struct dma_channel *channel)
                musb_writew(regs, MUSB_TXCSR, value);
                musb_writew(regs, MUSB_TXCSR, value);
 
-               /* re-enable interrupt */
-               if (enabled)
-                       musb_writel(tibase, DAVINCI_TXCPPI_INTENAB_REG,
-                                       (1 << cppi_ch->index));
-
                /* While we scrub the TX state RAM, ensure that we clean
                 * up any interrupt that's currently asserted:
                 * 1. Write to completion Ptr value 0x1(bit 0 set)
@@ -1459,6 +1454,11 @@ static int cppi_channel_abort(struct dma_channel *channel)
                cppi_reset_tx(tx_ram, 1);
                musb_writel(&tx_ram->tx_complete, 0, 0);
 
+               /* re-enable interrupt */
+               if (enabled)
+                       musb_writel(tibase, DAVINCI_TXCPPI_INTENAB_REG,
+                                       (1 << cppi_ch->index));
+
                cppi_dump_tx(5, cppi_ch, " (done teardown)");
 
                /* REVISIT tx side _should_ clean up the same way
index 3a61ddb62bd28a45947a1e4d198fe6304c2d0d5b..547e0e3907268cc0d6f1b6b71d45d0a14e1129a8 100644 (file)
@@ -1450,7 +1450,7 @@ static int __init musb_core_init(u16 musb_type, struct musb *musb)
 #endif
 
                if (hw_ep->max_packet_sz_tx) {
-                       printk(KERN_DEBUG
+                       DBG(1,
                                "%s: hw_ep %d%s, %smax %d\n",
                                musb_driver_name, i,
                                hw_ep->is_shared_fifo ? "shared" : "tx",
@@ -1459,7 +1459,7 @@ static int __init musb_core_init(u16 musb_type, struct musb *musb)
                                hw_ep->max_packet_sz_tx);
                }
                if (hw_ep->max_packet_sz_rx && !hw_ep->is_shared_fifo) {
-                       printk(KERN_DEBUG
+                       DBG(1,
                                "%s: hw_ep %d%s, %smax %d\n",
                                musb_driver_name, i,
                                "rx",
index 8b3c4e2ed7b865aab0636bf18c6d5b7d0138da0f..74073f9a43f09cafc6afed82e5a9cadd17304d62 100644 (file)
@@ -4,6 +4,7 @@
  * Copyright 2005 Mentor Graphics Corporation
  * Copyright (C) 2005-2006 by Texas Instruments
  * Copyright (C) 2006-2007 Nokia Corporation
+ * Copyright (C) 2009 MontaVista Software, Inc. <source@mvista.com>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -436,14 +437,6 @@ void musb_g_tx(struct musb *musb, u8 epnum)
                        csr |= MUSB_TXCSR_P_WZC_BITS;
                        csr &= ~MUSB_TXCSR_P_SENTSTALL;
                        musb_writew(epio, MUSB_TXCSR, csr);
-                       if (dma_channel_status(dma) == MUSB_DMA_STATUS_BUSY) {
-                               dma->status = MUSB_DMA_STATUS_CORE_ABORT;
-                               musb->dma_controller->channel_abort(dma);
-                       }
-
-                       if (request)
-                               musb_g_giveback(musb_ep, request, -EPIPE);
-
                        break;
                }
 
@@ -582,15 +575,25 @@ void musb_g_tx(struct musb *musb, u8 epnum)
  */
 static void rxstate(struct musb *musb, struct musb_request *req)
 {
-       u16                     csr = 0;
        const u8                epnum = req->epnum;
        struct usb_request      *request = &req->request;
        struct musb_ep          *musb_ep = &musb->endpoints[epnum].ep_out;
        void __iomem            *epio = musb->endpoints[epnum].regs;
        unsigned                fifo_count = 0;
        u16                     len = musb_ep->packet_sz;
+       u16                     csr = musb_readw(epio, MUSB_RXCSR);
 
-       csr = musb_readw(epio, MUSB_RXCSR);
+       /* We shouldn't get here while DMA is active, but we do... */
+       if (dma_channel_status(musb_ep->dma) == MUSB_DMA_STATUS_BUSY) {
+               DBG(4, "DMA pending...\n");
+               return;
+       }
+
+       if (csr & MUSB_RXCSR_P_SENDSTALL) {
+               DBG(5, "%s stalling, RXCSR %04x\n",
+                   musb_ep->end_point.name, csr);
+               return;
+       }
 
        if (is_cppi_enabled() && musb_ep->dma) {
                struct dma_controller   *c = musb->dma_controller;
@@ -761,19 +764,10 @@ void musb_g_rx(struct musb *musb, u8 epnum)
                        csr, dma ? " (dma)" : "", request);
 
        if (csr & MUSB_RXCSR_P_SENTSTALL) {
-               if (dma_channel_status(dma) == MUSB_DMA_STATUS_BUSY) {
-                       dma->status = MUSB_DMA_STATUS_CORE_ABORT;
-                       (void) musb->dma_controller->channel_abort(dma);
-                       request->actual += musb_ep->dma->actual_len;
-               }
-
                csr |= MUSB_RXCSR_P_WZC_BITS;
                csr &= ~MUSB_RXCSR_P_SENTSTALL;
                musb_writew(epio, MUSB_RXCSR, csr);
-
-               if (request)
-                       musb_g_giveback(musb_ep, request, -EPIPE);
-               goto done;
+               return;
        }
 
        if (csr & MUSB_RXCSR_P_OVERRUN) {
@@ -795,7 +789,7 @@ void musb_g_rx(struct musb *musb, u8 epnum)
                DBG((csr & MUSB_RXCSR_DMAENAB) ? 4 : 1,
                        "%s busy, csr %04x\n",
                        musb_ep->end_point.name, csr);
-               goto done;
+               return;
        }
 
        if (dma && (csr & MUSB_RXCSR_DMAENAB)) {
@@ -826,22 +820,15 @@ void musb_g_rx(struct musb *musb, u8 epnum)
                if ((request->actual < request->length)
                                && (musb_ep->dma->actual_len
                                        == musb_ep->packet_sz))
-                       goto done;
+                       return;
 #endif
                musb_g_giveback(musb_ep, request, 0);
 
                request = next_request(musb_ep);
                if (!request)
-                       goto done;
-
-               /* don't start more i/o till the stall clears */
-               musb_ep_select(mbase, epnum);
-               csr = musb_readw(epio, MUSB_RXCSR);
-               if (csr & MUSB_RXCSR_P_SENDSTALL)
-                       goto done;
+                       return;
        }
 
-
        /* analyze request if the ep is hot */
        if (request)
                rxstate(musb, to_musb_request(request));
@@ -849,8 +836,6 @@ void musb_g_rx(struct musb *musb, u8 epnum)
                DBG(3, "packet waiting for %s%s request\n",
                                musb_ep->desc ? "" : "inactive ",
                                musb_ep->end_point.name);
-
-done:
        return;
 }
 
@@ -1244,7 +1229,7 @@ int musb_gadget_set_halt(struct usb_ep *ep, int value)
        void __iomem            *mbase;
        unsigned long           flags;
        u16                     csr;
-       struct musb_request     *request = NULL;
+       struct musb_request     *request;
        int                     status = 0;
 
        if (!ep)
@@ -1260,24 +1245,29 @@ int musb_gadget_set_halt(struct usb_ep *ep, int value)
 
        musb_ep_select(mbase, epnum);
 
-       /* cannot portably stall with non-empty FIFO */
        request = to_musb_request(next_request(musb_ep));
-       if (value && musb_ep->is_in) {
-               csr = musb_readw(epio, MUSB_TXCSR);
-               if (csr & MUSB_TXCSR_FIFONOTEMPTY) {
-                       DBG(3, "%s fifo busy, cannot halt\n", ep->name);
-                       spin_unlock_irqrestore(&musb->lock, flags);
-                       return -EAGAIN;
+       if (value) {
+               if (request) {
+                       DBG(3, "request in progress, cannot halt %s\n",
+                           ep->name);
+                       status = -EAGAIN;
+                       goto done;
+               }
+               /* Cannot portably stall with non-empty FIFO */
+               if (musb_ep->is_in) {
+                       csr = musb_readw(epio, MUSB_TXCSR);
+                       if (csr & MUSB_TXCSR_FIFONOTEMPTY) {
+                               DBG(3, "FIFO busy, cannot halt %s\n", ep->name);
+                               status = -EAGAIN;
+                               goto done;
+                       }
                }
-
        }
 
        /* set/clear the stall and toggle bits */
        DBG(2, "%s: %s stall\n", ep->name, value ? "set" : "clear");
        if (musb_ep->is_in) {
                csr = musb_readw(epio, MUSB_TXCSR);
-               if (csr & MUSB_TXCSR_FIFONOTEMPTY)
-                       csr |= MUSB_TXCSR_FLUSHFIFO;
                csr |= MUSB_TXCSR_P_WZC_BITS
                        | MUSB_TXCSR_CLRDATATOG;
                if (value)
@@ -1300,14 +1290,13 @@ int musb_gadget_set_halt(struct usb_ep *ep, int value)
                musb_writew(epio, MUSB_RXCSR, csr);
        }
 
-done:
-
        /* maybe start the first request in the queue */
        if (!musb_ep->busy && !value && request) {
                DBG(3, "restarting the request\n");
                musb_ep_restart(musb, request);
        }
 
+done:
        spin_unlock_irqrestore(&musb->lock, flags);
        return status;
 }
index 7a6778675ad3a8d5a76d1f8de9477a8c48309d12..522efb31b56b5304a0f2d52b4e232749f8c6a319 100644 (file)
@@ -511,7 +511,8 @@ static void ep0_txstate(struct musb *musb)
 
        /* update the flags */
        if (fifo_count < MUSB_MAX_END0_PACKET
-                       || request->actual == request->length) {
+                       || (request->actual == request->length
+                               && !request->zero)) {
                musb->ep0_state = MUSB_EP0_STAGE_STATUSOUT;
                csr |= MUSB_CSR0_P_DATAEND;
        } else
index cf94511485f258a07d60186d43e3687fcf959a87..e3ab40a966eb4ce4f5b9a35eecdbf1ed49e48477 100644 (file)
@@ -1301,8 +1301,11 @@ void musb_host_tx(struct musb *musb, u8 epnum)
                return;
        } else  if (usb_pipeisoc(pipe) && dma) {
                if (musb_tx_dma_program(musb->dma_controller, hw_ep, qh, urb,
-                               offset, length))
+                               offset, length)) {
+                       if (is_cppi_enabled() || tusb_dma_omap())
+                               musb_h_tx_dma_start(hw_ep);
                        return;
+               }
        } else  if (tx_csr & MUSB_TXCSR_DMAENAB) {
                DBG(1, "not complete, but DMA enabled?\n");
                return;
index 698252a4dc5d9b59878a26b64a9a5caf00c8efef..bd254ec97d14be6d9b9e4db7e64bfbbca1f7d14c 100644 (file)
@@ -50,6 +50,8 @@ static int cp210x_tiocmset_port(struct usb_serial_port *port, struct file *,
 static void cp210x_break_ctl(struct tty_struct *, int);
 static int cp210x_startup(struct usb_serial *);
 static void cp210x_disconnect(struct usb_serial *);
+static void cp210x_dtr_rts(struct usb_serial_port *p, int on);
+static int cp210x_carrier_raised(struct usb_serial_port *p);
 
 static int debug;
 
@@ -143,6 +145,8 @@ static struct usb_serial_driver cp210x_device = {
        .tiocmset               = cp210x_tiocmset,
        .attach                 = cp210x_startup,
        .disconnect             = cp210x_disconnect,
+       .dtr_rts                = cp210x_dtr_rts,
+       .carrier_raised         = cp210x_carrier_raised
 };
 
 /* Config request types */
@@ -746,6 +750,14 @@ static int cp210x_tiocmset_port(struct usb_serial_port *port, struct file *file,
        return cp210x_set_config(port, CP210X_SET_MHS, &control, 2);
 }
 
+static void cp210x_dtr_rts(struct usb_serial_port *p, int on)
+{
+       if (on)
+               cp210x_tiocmset_port(p, NULL,  TIOCM_DTR|TIOCM_RTS, 0);
+       else
+               cp210x_tiocmset_port(p, NULL,  0, TIOCM_DTR|TIOCM_RTS);
+}
+
 static int cp210x_tiocmget (struct tty_struct *tty, struct file *file)
 {
        struct usb_serial_port *port = tty->driver_data;
@@ -768,6 +780,15 @@ static int cp210x_tiocmget (struct tty_struct *tty, struct file *file)
        return result;
 }
 
+static int cp210x_carrier_raised(struct usb_serial_port *p)
+{
+       unsigned int control;
+       cp210x_get_config(p, CP210X_GET_MDMSTS, &control, 1);
+       if (control & CONTROL_DCD)
+               return 1;
+       return 0;
+}
+
 static void cp210x_break_ctl (struct tty_struct *tty, int break_state)
 {
        struct usb_serial_port *port = tty->driver_data;
index 9c60d6d4908a411019f61e7ce73e2a27877a9912..ebcc6d0e2e91ec48d355a020e6da86f34c727508 100644 (file)
@@ -1937,7 +1937,7 @@ static void ftdi_write_bulk_callback(struct urb *urb)
                return;
        }
        /* account for transferred data */
-       countback = urb->actual_length;
+       countback = urb->transfer_buffer_length;
        data_offset = priv->write_offset;
        if (data_offset > 0) {
                /* Subtract the control bytes */
@@ -1950,7 +1950,6 @@ static void ftdi_write_bulk_callback(struct urb *urb)
 
        if (status) {
                dbg("nonzero write bulk status received: %d", status);
-               return;
        }
 
        usb_serial_port_softint(port);
index cd44c68954df55e65dff18ae6f89c007d698b938..0577e4b611147806203ebf1e0864167cfc98d0c3 100644 (file)
@@ -308,6 +308,7 @@ static int  option_resume(struct usb_serial *serial);
 
 #define DLINK_VENDOR_ID                                0x1186
 #define DLINK_PRODUCT_DWM_652                  0x3e04
+#define DLINK_PRODUCT_DWM_652_U5               0xce16
 
 #define QISDA_VENDOR_ID                                0x1da5
 #define QISDA_PRODUCT_H21_4512                 0x4512
@@ -335,6 +336,10 @@ static int  option_resume(struct usb_serial *serial);
 #define AIRPLUS_VENDOR_ID                      0x1011
 #define AIRPLUS_PRODUCT_MCD650                 0x3198
 
+/* 4G Systems products */
+#define FOUR_G_SYSTEMS_VENDOR_ID               0x1c9e
+#define FOUR_G_SYSTEMS_PRODUCT_W14             0x9603
+
 static struct usb_device_id option_ids[] = {
        { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) },
        { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) },
@@ -586,6 +591,7 @@ static struct usb_device_id option_ids[] = {
        { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC2726, 0xff, 0xff, 0xff) },
        { USB_DEVICE(BENQ_VENDOR_ID, BENQ_PRODUCT_H10) },
        { USB_DEVICE(DLINK_VENDOR_ID, DLINK_PRODUCT_DWM_652) },
+       { USB_DEVICE(ALINK_VENDOR_ID, DLINK_PRODUCT_DWM_652_U5) }, /* Yes, ALINK_VENDOR_ID */
        { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H21_4512) },
        { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H21_4523) },
        { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H20_4515) },
@@ -597,6 +603,7 @@ static struct usb_device_id option_ids[] = {
        { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X060S) },
        { USB_DEVICE(AIRPLUS_VENDOR_ID, AIRPLUS_PRODUCT_MCD650) },
        { USB_DEVICE(TLAYTECH_VENDOR_ID, TLAYTECH_PRODUCT_TEU800) },
+       { USB_DEVICE(FOUR_G_SYSTEMS_VENDOR_ID, FOUR_G_SYSTEMS_PRODUCT_W14) },
        { } /* Terminating entry */
 };
 MODULE_DEVICE_TABLE(usb, option_ids);
index 2211a852af9cfbfa01bb0af08fd88d492456afdb..96774949cd30ba3964ea1340e47a3524f841c08b 100644 (file)
@@ -433,8 +433,9 @@ static int corgi_bl_update_status(struct backlight_device *bd)
 
        if (corgibl_flags & CORGIBL_SUSPENDED)
                intensity = 0;
-       if (corgibl_flags & CORGIBL_BATTLOW)
-               intensity &= lcd->limit_mask;
+
+       if ((corgibl_flags & CORGIBL_BATTLOW) && intensity > lcd->limit_mask)
+               intensity = lcd->limit_mask;
 
        return corgi_bl_set_intensity(lcd, intensity);
 }
index b6449470106cd47e8db704edfd074c53dde8ec4b..a482dd7b0311bcd5eacdd1ca8cfaf49d5ff0eac8 100644 (file)
@@ -56,7 +56,7 @@ static int fb_notifier_callback(struct notifier_block *self,
 
 static int lcd_register_fb(struct lcd_device *ld)
 {
-       memset(&ld->fb_notif, 0, sizeof(&ld->fb_notif));
+       memset(&ld->fb_notif, 0, sizeof(ld->fb_notif));
        ld->fb_notif.notifier_call = fb_notifier_callback;
        return fb_register_client(&ld->fb_notif);
 }
index d065894ce38fbf952a46d2da87da67b34374289a..ea1fd3f475115746a84ceef6a048fa6b09489cd3 100644 (file)
@@ -554,11 +554,11 @@ static int fb_check_var(struct fb_var_screeninfo *var,
                var->transp.length = 0;
                break;
        case 16:                /* RGB 565 */
-               var->red.offset = 0;
+               var->red.offset = 11;
                var->red.length = 5;
                var->green.offset = 5;
                var->green.length = 6;
-               var->blue.offset = 11;
+               var->blue.offset = 0;
                var->blue.length = 5;
                var->transp.offset = 0;
                var->transp.length = 0;
@@ -591,7 +591,7 @@ static int __devexit fb_remove(struct platform_device *dev)
                unregister_framebuffer(info);
                fb_dealloc_cmap(&info->cmap);
                dma_free_coherent(NULL, par->databuf_sz + PAGE_SIZE,
-                                       info->screen_base,
+                                       info->screen_base - PAGE_SIZE,
                                        info->fix.smem_start);
                free_irq(par->irq, par);
                clk_disable(par->lcdc_clk);
@@ -704,7 +704,7 @@ static int __init fb_probe(struct platform_device *device)
 
        if (i == ARRAY_SIZE(known_lcd_panels)) {
                dev_err(&device->dev, "GLCD: No valid panel found\n");
-               ret = ENODEV;
+               ret = -ENODEV;
                goto err_clk_disable;
        } else
                dev_info(&device->dev, "GLCD: Found %s panel\n",
@@ -749,6 +749,7 @@ static int __init fb_probe(struct platform_device *device)
                                (PAGE_SIZE - par->palette_sz);
 
        /* the rest of the frame buffer is pixel data */
+       da8xx_fb_info->screen_base = par->v_palette_base + par->palette_sz;
        da8xx_fb_fix.smem_start = par->p_palette_base + par->palette_sz;
        da8xx_fb_fix.smem_len = par->databuf_sz - par->palette_sz;
        da8xx_fb_fix.line_length = (lcdc_info->width * lcd_cfg->bpp) / 8;
@@ -787,6 +788,8 @@ static int __init fb_probe(struct platform_device *device)
        da8xx_fb_info->var = da8xx_fb_var;
        da8xx_fb_info->fbops = &da8xx_fb_ops;
        da8xx_fb_info->pseudo_palette = par->pseudo_palette;
+       da8xx_fb_info->fix.visual = (da8xx_fb_info->var.bits_per_pixel <= 8) ?
+                               FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR;
 
        ret = fb_alloc_cmap(&da8xx_fb_info->cmap, PALETTE_SIZE, 0);
        if (ret)
@@ -825,7 +828,7 @@ err_free_irq:
 
 err_release_fb_mem:
        dma_free_coherent(NULL, par->databuf_sz + PAGE_SIZE,
-                               da8xx_fb_info->screen_base,
+                               da8xx_fb_info->screen_base - PAGE_SIZE,
                                da8xx_fb_info->fix.smem_start);
 
 err_release_fb:
index 1a83709f96116374207bfba6c4fbc3ba825c47de..f67db4268374298b8b762353194e8fa873f315c3 100644 (file)
@@ -1147,7 +1147,7 @@ static int __init gbefb_probe(struct platform_device *p_dev)
        gbefb_setup(options);
 #endif
 
-       if (!request_region(GBE_BASE, sizeof(struct sgi_gbe), "GBE")) {
+       if (!request_mem_region(GBE_BASE, sizeof(struct sgi_gbe), "GBE")) {
                printk(KERN_ERR "gbefb: couldn't reserve mmio region\n");
                ret = -EBUSY;
                goto out_release_framebuffer;
index f24d04132eda85252615a11d2907dbb8c5631362..4d227b15200118468be1a355f37ba8e1cc28adf0 100644 (file)
@@ -317,7 +317,7 @@ static int __devexit pnx4008_wdt_remove(struct platform_device *pdev)
 
 static struct platform_driver platform_wdt_driver = {
        .driver = {
-               .name = "watchdog",
+               .name = "pnx4008-watchdog",
                .owner  = THIS_MODULE,
        },
        .probe = pnx4008_wdt_probe,
@@ -352,4 +352,4 @@ MODULE_PARM_DESC(nowayout,
 
 MODULE_LICENSE("GPL");
 MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
-MODULE_ALIAS("platform:watchdog");
+MODULE_ALIAS("platform:pnx4008-watchdog");
index f6cccc9df022cbb55b04aa5fac43fcfd6413964c..bf12d06b587774ff1a576619427f73e9380195ae 100644 (file)
@@ -62,7 +62,7 @@ extern unsigned int idt_cpu_freq;
 static int timeout = WATCHDOG_TIMEOUT;
 module_param(timeout, int, 0);
 MODULE_PARM_DESC(timeout, "Watchdog timeout value, in seconds (default="
-               WATCHDOG_TIMEOUT ")");
+               __MODULE_STRING(WATCHDOG_TIMEOUT) ")");
 
 static int nowayout = WATCHDOG_NOWAYOUT;
 module_param(nowayout, int, 0);
@@ -276,7 +276,7 @@ static int __devinit rc32434_wdt_probe(struct platform_device *pdev)
                return -ENODEV;
        }
 
-       wdt_reg = ioremap_nocache(r->start, r->end - r->start);
+       wdt_reg = ioremap_nocache(r->start, resource_size(r));
        if (!wdt_reg) {
                printk(KERN_ERR PFX "failed to remap I/O resources\n");
                return -ENXIO;
index 51c94e26a346f1de790e4f3cac3e039d097c5494..e777961939f3e6ed0354560c3e256247f6d24f66 100644 (file)
@@ -343,18 +343,7 @@ int __v9fs_fscache_release_page(struct page *page, gfp_t gfp)
 
        BUG_ON(!vcookie->fscache);
 
-       if (PageFsCache(page)) {
-               if (fscache_check_page_write(vcookie->fscache, page)) {
-                       if (!(gfp & __GFP_WAIT))
-                               return 0;
-                       fscache_wait_on_page_write(vcookie->fscache, page);
-               }
-
-               fscache_uncache_page(vcookie->fscache, page);
-               ClearPageFsCache(page);
-       }
-
-       return 1;
+       return fscache_maybe_release_page(vcookie->fscache, page, gfp);
 }
 
 void __v9fs_fscache_invalidate_page(struct page *page)
@@ -368,7 +357,6 @@ void __v9fs_fscache_invalidate_page(struct page *page)
                fscache_wait_on_page_write(vcookie->fscache, page);
                BUG_ON(!PageLocked(page));
                fscache_uncache_page(vcookie->fscache, page);
-               ClearPageFsCache(page);
        }
 }
 
index 681c2a7b013fc3c06bfa2d0d75d05804eafb8ffb..39b301662f22449e0896e77bf9a964e68bd9a9f0 100644 (file)
@@ -315,7 +315,6 @@ static void afs_invalidatepage(struct page *page, unsigned long offset)
                        struct afs_vnode *vnode = AFS_FS_I(page->mapping->host);
                        fscache_wait_on_page_write(vnode->cache, page);
                        fscache_uncache_page(vnode->cache, page);
-                       ClearPageFsCache(page);
                }
 #endif
 
@@ -349,17 +348,9 @@ static int afs_releasepage(struct page *page, gfp_t gfp_flags)
        /* deny if page is being written to the cache and the caller hasn't
         * elected to wait */
 #ifdef CONFIG_AFS_FSCACHE
-       if (PageFsCache(page)) {
-               if (fscache_check_page_write(vnode->cache, page)) {
-                       if (!(gfp_flags & __GFP_WAIT)) {
-                               _leave(" = F [cache busy]");
-                               return 0;
-                       }
-                       fscache_wait_on_page_write(vnode->cache, page);
-               }
-
-               fscache_uncache_page(vnode->cache, page);
-               ClearPageFsCache(page);
+       if (!fscache_maybe_release_page(vnode->cache, page, gfp_flags)) {
+               _leave(" = F [cache busy]");
+               return 0;
        }
 #endif
 
index 431accd475a73aba67ad8d24a80b31da2c94db24..27089311fbea467b4ca6ec7d6522ae0525231c6f 100644 (file)
@@ -114,8 +114,9 @@ nomem_lookup_data:
 
 /*
  * attempt to look up the nominated node in this cache
+ * - return -ETIMEDOUT to be scheduled again
  */
-static void cachefiles_lookup_object(struct fscache_object *_object)
+static int cachefiles_lookup_object(struct fscache_object *_object)
 {
        struct cachefiles_lookup_data *lookup_data;
        struct cachefiles_object *parent, *object;
@@ -145,13 +146,15 @@ static void cachefiles_lookup_object(struct fscache_object *_object)
            object->fscache.cookie->def->type != FSCACHE_COOKIE_TYPE_INDEX)
                cachefiles_attr_changed(&object->fscache);
 
-       if (ret < 0) {
-               printk(KERN_WARNING "CacheFiles: Lookup failed error %d\n",
-                      ret);
+       if (ret < 0 && ret != -ETIMEDOUT) {
+               if (ret != -ENOBUFS)
+                       printk(KERN_WARNING
+                              "CacheFiles: Lookup failed error %d\n", ret);
                fscache_object_lookup_error(&object->fscache);
        }
 
        _leave(" [%d]", ret);
+       return ret;
 }
 
 /*
@@ -331,6 +334,7 @@ static void cachefiles_put_object(struct fscache_object *_object)
                }
 
                cache = object->fscache.cache;
+               fscache_object_destroy(&object->fscache);
                kmem_cache_free(cachefiles_object_jar, object);
                fscache_object_destroyed(cache);
        }
@@ -403,12 +407,26 @@ static int cachefiles_attr_changed(struct fscache_object *_object)
        if (oi_size == ni_size)
                return 0;
 
-       newattrs.ia_size = ni_size;
-       newattrs.ia_valid = ATTR_SIZE;
-
        cachefiles_begin_secure(cache, &saved_cred);
        mutex_lock(&object->backer->d_inode->i_mutex);
+
+       /* if there's an extension to a partial page at the end of the backing
+        * file, we need to discard the partial page so that we pick up new
+        * data after it */
+       if (oi_size & ~PAGE_MASK && ni_size > oi_size) {
+               _debug("discard tail %llx", oi_size);
+               newattrs.ia_valid = ATTR_SIZE;
+               newattrs.ia_size = oi_size & PAGE_MASK;
+               ret = notify_change(object->backer, &newattrs);
+               if (ret < 0)
+                       goto truncate_failed;
+       }
+
+       newattrs.ia_valid = ATTR_SIZE;
+       newattrs.ia_size = ni_size;
        ret = notify_change(object->backer, &newattrs);
+
+truncate_failed:
        mutex_unlock(&object->backer->d_inode->i_mutex);
        cachefiles_end_secure(cache, saved_cred);
 
index 4ce818ae39ea8d6ae10f9777b089f75b018f201f..14ac4806e2913f8c37e76d95dc1d0274f4bbd027 100644 (file)
 #include <linux/security.h>
 #include "internal.h"
 
-static int cachefiles_wait_bit(void *flags)
+#define CACHEFILES_KEYBUF_SIZE 512
+
+/*
+ * dump debugging info about an object
+ */
+static noinline
+void __cachefiles_printk_object(struct cachefiles_object *object,
+                               const char *prefix,
+                               u8 *keybuf)
 {
-       schedule();
-       return 0;
+       struct fscache_cookie *cookie;
+       unsigned keylen, loop;
+
+       printk(KERN_ERR "%sobject: OBJ%x\n",
+              prefix, object->fscache.debug_id);
+       printk(KERN_ERR "%sobjstate=%s fl=%lx swfl=%lx ev=%lx[%lx]\n",
+              prefix, fscache_object_states[object->fscache.state],
+              object->fscache.flags, object->fscache.work.flags,
+              object->fscache.events,
+              object->fscache.event_mask & FSCACHE_OBJECT_EVENTS_MASK);
+       printk(KERN_ERR "%sops=%u inp=%u exc=%u\n",
+              prefix, object->fscache.n_ops, object->fscache.n_in_progress,
+              object->fscache.n_exclusive);
+       printk(KERN_ERR "%sparent=%p\n",
+              prefix, object->fscache.parent);
+
+       spin_lock(&object->fscache.lock);
+       cookie = object->fscache.cookie;
+       if (cookie) {
+               printk(KERN_ERR "%scookie=%p [pr=%p nd=%p fl=%lx]\n",
+                      prefix,
+                      object->fscache.cookie,
+                      object->fscache.cookie->parent,
+                      object->fscache.cookie->netfs_data,
+                      object->fscache.cookie->flags);
+               if (keybuf)
+                       keylen = cookie->def->get_key(cookie->netfs_data, keybuf,
+                                                     CACHEFILES_KEYBUF_SIZE);
+               else
+                       keylen = 0;
+       } else {
+               printk(KERN_ERR "%scookie=NULL\n", prefix);
+               keylen = 0;
+       }
+       spin_unlock(&object->fscache.lock);
+
+       if (keylen) {
+               printk(KERN_ERR "%skey=[%u] '", prefix, keylen);
+               for (loop = 0; loop < keylen; loop++)
+                       printk("%02x", keybuf[loop]);
+               printk("'\n");
+       }
+}
+
+/*
+ * dump debugging info about a pair of objects
+ */
+static noinline void cachefiles_printk_object(struct cachefiles_object *object,
+                                             struct cachefiles_object *xobject)
+{
+       u8 *keybuf;
+
+       keybuf = kmalloc(CACHEFILES_KEYBUF_SIZE, GFP_NOIO);
+       if (object)
+               __cachefiles_printk_object(object, "", keybuf);
+       if (xobject)
+               __cachefiles_printk_object(xobject, "x", keybuf);
+       kfree(keybuf);
 }
 
 /*
  * record the fact that an object is now active
  */
-static void cachefiles_mark_object_active(struct cachefiles_cache *cache,
-                                         struct cachefiles_object *object)
+static int cachefiles_mark_object_active(struct cachefiles_cache *cache,
+                                        struct cachefiles_object *object)
 {
        struct cachefiles_object *xobject;
        struct rb_node **_p, *_parent = NULL;
@@ -42,8 +106,11 @@ static void cachefiles_mark_object_active(struct cachefiles_cache *cache,
 try_again:
        write_lock(&cache->active_lock);
 
-       if (test_and_set_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags))
+       if (test_and_set_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags)) {
+               printk(KERN_ERR "CacheFiles: Error: Object already active\n");
+               cachefiles_printk_object(object, NULL);
                BUG();
+       }
 
        dentry = object->dentry;
        _p = &cache->active_nodes.rb_node;
@@ -66,8 +133,8 @@ try_again:
        rb_insert_color(&object->active_node, &cache->active_nodes);
 
        write_unlock(&cache->active_lock);
-       _leave("");
-       return;
+       _leave(" = 0");
+       return 0;
 
        /* an old object from a previous incarnation is hogging the slot - we
         * need to wait for it to be destroyed */
@@ -76,44 +143,70 @@ wait_for_old_object:
                printk(KERN_ERR "\n");
                printk(KERN_ERR "CacheFiles: Error:"
                       " Unexpected object collision\n");
-               printk(KERN_ERR "xobject: OBJ%x\n",
-                      xobject->fscache.debug_id);
-               printk(KERN_ERR "xobjstate=%s\n",
-                      fscache_object_states[xobject->fscache.state]);
-               printk(KERN_ERR "xobjflags=%lx\n", xobject->fscache.flags);
-               printk(KERN_ERR "xobjevent=%lx [%lx]\n",
-                      xobject->fscache.events, xobject->fscache.event_mask);
-               printk(KERN_ERR "xops=%u inp=%u exc=%u\n",
-                      xobject->fscache.n_ops, xobject->fscache.n_in_progress,
-                      xobject->fscache.n_exclusive);
-               printk(KERN_ERR "xcookie=%p [pr=%p nd=%p fl=%lx]\n",
-                      xobject->fscache.cookie,
-                      xobject->fscache.cookie->parent,
-                      xobject->fscache.cookie->netfs_data,
-                      xobject->fscache.cookie->flags);
-               printk(KERN_ERR "xparent=%p\n",
-                      xobject->fscache.parent);
-               printk(KERN_ERR "object: OBJ%x\n",
-                      object->fscache.debug_id);
-               printk(KERN_ERR "cookie=%p [pr=%p nd=%p fl=%lx]\n",
-                      object->fscache.cookie,
-                      object->fscache.cookie->parent,
-                      object->fscache.cookie->netfs_data,
-                      object->fscache.cookie->flags);
-               printk(KERN_ERR "parent=%p\n",
-                      object->fscache.parent);
+               cachefiles_printk_object(object, xobject);
                BUG();
        }
        atomic_inc(&xobject->usage);
        write_unlock(&cache->active_lock);
 
-       _debug(">>> wait");
-       wait_on_bit(&xobject->flags, CACHEFILES_OBJECT_ACTIVE,
-                   cachefiles_wait_bit, TASK_UNINTERRUPTIBLE);
-       _debug("<<< waited");
+       if (test_bit(CACHEFILES_OBJECT_ACTIVE, &xobject->flags)) {
+               wait_queue_head_t *wq;
+
+               signed long timeout = 60 * HZ;
+               wait_queue_t wait;
+               bool requeue;
+
+               /* if the object we're waiting for is queued for processing,
+                * then just put ourselves on the queue behind it */
+               if (slow_work_is_queued(&xobject->fscache.work)) {
+                       _debug("queue OBJ%x behind OBJ%x immediately",
+                              object->fscache.debug_id,
+                              xobject->fscache.debug_id);
+                       goto requeue;
+               }
+
+               /* otherwise we sleep until either the object we're waiting for
+                * is done, or the slow-work facility wants the thread back to
+                * do other work */
+               wq = bit_waitqueue(&xobject->flags, CACHEFILES_OBJECT_ACTIVE);
+               init_wait(&wait);
+               requeue = false;
+               do {
+                       prepare_to_wait(wq, &wait, TASK_UNINTERRUPTIBLE);
+                       if (!test_bit(CACHEFILES_OBJECT_ACTIVE, &xobject->flags))
+                               break;
+                       requeue = slow_work_sleep_till_thread_needed(
+                               &object->fscache.work, &timeout);
+               } while (timeout > 0 && !requeue);
+               finish_wait(wq, &wait);
+
+               if (requeue &&
+                   test_bit(CACHEFILES_OBJECT_ACTIVE, &xobject->flags)) {
+                       _debug("queue OBJ%x behind OBJ%x after wait",
+                              object->fscache.debug_id,
+                              xobject->fscache.debug_id);
+                       goto requeue;
+               }
+
+               if (timeout <= 0) {
+                       printk(KERN_ERR "\n");
+                       printk(KERN_ERR "CacheFiles: Error: Overlong"
+                              " wait for old active object to go away\n");
+                       cachefiles_printk_object(object, xobject);
+                       goto requeue;
+               }
+       }
+
+       ASSERT(!test_bit(CACHEFILES_OBJECT_ACTIVE, &xobject->flags));
 
        cache->cache.ops->put_object(&xobject->fscache);
        goto try_again;
+
+requeue:
+       clear_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags);
+       cache->cache.ops->put_object(&xobject->fscache);
+       _leave(" = -ETIMEDOUT");
+       return -ETIMEDOUT;
 }
 
 /*
@@ -254,7 +347,7 @@ int cachefiles_delete_object(struct cachefiles_cache *cache,
 
        dir = dget_parent(object->dentry);
 
-       mutex_lock(&dir->d_inode->i_mutex);
+       mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_PARENT);
        ret = cachefiles_bury_object(cache, dir, object->dentry);
 
        dput(dir);
@@ -307,7 +400,7 @@ lookup_again:
        /* search the current directory for the element name */
        _debug("lookup '%s'", name);
 
-       mutex_lock(&dir->d_inode->i_mutex);
+       mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_PARENT);
 
        start = jiffies;
        next = lookup_one_len(name, dir, nlen);
@@ -418,12 +511,15 @@ lookup_again:
        }
 
        /* note that we're now using this object */
-       cachefiles_mark_object_active(cache, object);
+       ret = cachefiles_mark_object_active(cache, object);
 
        mutex_unlock(&dir->d_inode->i_mutex);
        dput(dir);
        dir = NULL;
 
+       if (ret == -ETIMEDOUT)
+               goto mark_active_timed_out;
+
        _debug("=== OBTAINED_OBJECT ===");
 
        if (object->new) {
@@ -467,6 +563,10 @@ create_error:
                cachefiles_io_error(cache, "Create/mkdir failed");
        goto error;
 
+mark_active_timed_out:
+       _debug("mark active timed out");
+       goto release_dentry;
+
 check_error:
        _debug("check error %d", ret);
        write_lock(&cache->active_lock);
@@ -474,7 +574,7 @@ check_error:
        clear_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags);
        wake_up_bit(&object->flags, CACHEFILES_OBJECT_ACTIVE);
        write_unlock(&cache->active_lock);
-
+release_dentry:
        dput(object->dentry);
        object->dentry = NULL;
        goto error_out;
@@ -495,9 +595,6 @@ error:
 error_out2:
        dput(dir);
 error_out:
-       if (ret == -ENOSPC)
-               ret = -ENOBUFS;
-
        _leave(" = error %d", -ret);
        return ret;
 }
index a69787e7dd964b2c57c016b6d6aa87b987285ace..a6c8c6fe8df9ca5d54625a07496c8b2b42dd771f 100644 (file)
@@ -11,6 +11,7 @@
 
 #include <linux/mount.h>
 #include <linux/file.h>
+#include <linux/ima.h>
 #include "internal.h"
 
 /*
@@ -40,8 +41,10 @@ static int cachefiles_read_waiter(wait_queue_t *wait, unsigned mode,
 
        _debug("--- monitor %p %lx ---", page, page->flags);
 
-       if (!PageUptodate(page) && !PageError(page))
-               dump_stack();
+       if (!PageUptodate(page) && !PageError(page)) {
+               /* unlocked, not uptodate and not erronous? */
+               _debug("page probably truncated");
+       }
 
        /* remove from the waitqueue */
        list_del(&wait->task_list);
@@ -60,6 +63,84 @@ static int cachefiles_read_waiter(wait_queue_t *wait, unsigned mode,
        return 0;
 }
 
+/*
+ * handle a probably truncated page
+ * - check to see if the page is still relevant and reissue the read if
+ *   possible
+ * - return -EIO on error, -ENODATA if the page is gone, -EINPROGRESS if we
+ *   must wait again and 0 if successful
+ */
+static int cachefiles_read_reissue(struct cachefiles_object *object,
+                                  struct cachefiles_one_read *monitor)
+{
+       struct address_space *bmapping = object->backer->d_inode->i_mapping;
+       struct page *backpage = monitor->back_page, *backpage2;
+       int ret;
+
+       kenter("{ino=%lx},{%lx,%lx}",
+              object->backer->d_inode->i_ino,
+              backpage->index, backpage->flags);
+
+       /* skip if the page was truncated away completely */
+       if (backpage->mapping != bmapping) {
+               kleave(" = -ENODATA [mapping]");
+               return -ENODATA;
+       }
+
+       backpage2 = find_get_page(bmapping, backpage->index);
+       if (!backpage2) {
+               kleave(" = -ENODATA [gone]");
+               return -ENODATA;
+       }
+
+       if (backpage != backpage2) {
+               put_page(backpage2);
+               kleave(" = -ENODATA [different]");
+               return -ENODATA;
+       }
+
+       /* the page is still there and we already have a ref on it, so we don't
+        * need a second */
+       put_page(backpage2);
+
+       INIT_LIST_HEAD(&monitor->op_link);
+       add_page_wait_queue(backpage, &monitor->monitor);
+
+       if (trylock_page(backpage)) {
+               ret = -EIO;
+               if (PageError(backpage))
+                       goto unlock_discard;
+               ret = 0;
+               if (PageUptodate(backpage))
+                       goto unlock_discard;
+
+               kdebug("reissue read");
+               ret = bmapping->a_ops->readpage(NULL, backpage);
+               if (ret < 0)
+                       goto unlock_discard;
+       }
+
+       /* but the page may have been read before the monitor was installed, so
+        * the monitor may miss the event - so we have to ensure that we do get
+        * one in such a case */
+       if (trylock_page(backpage)) {
+               _debug("jumpstart %p {%lx}", backpage, backpage->flags);
+               unlock_page(backpage);
+       }
+
+       /* it'll reappear on the todo list */
+       kleave(" = -EINPROGRESS");
+       return -EINPROGRESS;
+
+unlock_discard:
+       unlock_page(backpage);
+       spin_lock_irq(&object->work_lock);
+       list_del(&monitor->op_link);
+       spin_unlock_irq(&object->work_lock);
+       kleave(" = %d", ret);
+       return ret;
+}
+
 /*
  * copy data from backing pages to netfs pages to complete a read operation
  * - driven by FS-Cache's thread pool
@@ -92,20 +173,26 @@ static void cachefiles_read_copier(struct fscache_operation *_op)
 
                _debug("- copy {%lu}", monitor->back_page->index);
 
-               error = -EIO;
+       recheck:
                if (PageUptodate(monitor->back_page)) {
                        copy_highpage(monitor->netfs_page, monitor->back_page);
 
                        pagevec_add(&pagevec, monitor->netfs_page);
                        fscache_mark_pages_cached(monitor->op, &pagevec);
                        error = 0;
-               }
-
-               if (error)
+               } else if (!PageError(monitor->back_page)) {
+                       /* the page has probably been truncated */
+                       error = cachefiles_read_reissue(object, monitor);
+                       if (error == -EINPROGRESS)
+                               goto next;
+                       goto recheck;
+               } else {
                        cachefiles_io_error_obj(
                                object,
                                "Readpage failed on backing file %lx",
                                (unsigned long) monitor->back_page->flags);
+                       error = -EIO;
+               }
 
                page_cache_release(monitor->back_page);
 
@@ -114,6 +201,7 @@ static void cachefiles_read_copier(struct fscache_operation *_op)
                fscache_put_retrieval(op);
                kfree(monitor);
 
+       next:
                /* let the thread pool have some air occasionally */
                max--;
                if (max < 0 || need_resched()) {
@@ -333,7 +421,8 @@ int cachefiles_read_or_alloc_page(struct fscache_retrieval *op,
 
        shift = PAGE_SHIFT - inode->i_sb->s_blocksize_bits;
 
-       op->op.flags = FSCACHE_OP_FAST;
+       op->op.flags &= FSCACHE_OP_KEEP_FLAGS;
+       op->op.flags |= FSCACHE_OP_FAST;
        op->op.processor = cachefiles_read_copier;
 
        pagevec_init(&pagevec, 0);
@@ -639,7 +728,8 @@ int cachefiles_read_or_alloc_pages(struct fscache_retrieval *op,
 
        pagevec_init(&pagevec, 0);
 
-       op->op.flags = FSCACHE_OP_FAST;
+       op->op.flags &= FSCACHE_OP_KEEP_FLAGS;
+       op->op.flags |= FSCACHE_OP_FAST;
        op->op.processor = cachefiles_read_copier;
 
        INIT_LIST_HEAD(&backpages);
@@ -801,7 +891,8 @@ int cachefiles_write_page(struct fscache_storage *op, struct page *page)
        struct cachefiles_cache *cache;
        mm_segment_t old_fs;
        struct file *file;
-       loff_t pos;
+       loff_t pos, eof;
+       size_t len;
        void *data;
        int ret;
 
@@ -832,18 +923,33 @@ int cachefiles_write_page(struct fscache_storage *op, struct page *page)
        if (IS_ERR(file)) {
                ret = PTR_ERR(file);
        } else {
+               ima_counts_get(file);
                ret = -EIO;
                if (file->f_op->write) {
                        pos = (loff_t) page->index << PAGE_SHIFT;
+
+                       /* we mustn't write more data than we have, so we have
+                        * to beware of a partial page at EOF */
+                       eof = object->fscache.store_limit_l;
+                       len = PAGE_SIZE;
+                       if (eof & ~PAGE_MASK) {
+                               ASSERTCMP(pos, <, eof);
+                               if (eof - pos < PAGE_SIZE) {
+                                       _debug("cut short %llx to %llx",
+                                              pos, eof);
+                                       len = eof - pos;
+                                       ASSERTCMP(pos + len, ==, eof);
+                               }
+                       }
+
                        data = kmap(page);
                        old_fs = get_fs();
                        set_fs(KERNEL_DS);
                        ret = file->f_op->write(
-                               file, (const void __user *) data, PAGE_SIZE,
-                               &pos);
+                               file, (const void __user *) data, len, &pos);
                        set_fs(old_fs);
                        kunmap(page);
-                       if (ret != PAGE_SIZE)
+                       if (ret != len)
                                ret = -EIO;
                }
                fput(file);
index 145540a316ab4497be3c60814d05137aca4f0568..094ea65afc85354f029a2c3be38d01b684441156 100644 (file)
@@ -1,3 +1,12 @@
+Version 1.61
+------------
+Fix append problem to Samba servers (files opened with O_APPEND could
+have duplicated data). Fix oops in cifs_lookup. Workaround problem
+mounting to OS/400 Netserve. Fix oops in cifs_get_tcp_session.
+Disable use of server inode numbers when server only
+partially supports them (e.g. for one server querying inode numbers on
+FindFirst fails but QPathInfo queries works).
+
 Version 1.60
 -------------
 Fix memory leak in reconnect.  Fix oops in DFS mount error path.
index 9a5e4f5f312272af2f06d7243a43c37fe37f3210..29f1da761bbf10fc948f16e0c77a0d75dea22125 100644 (file)
@@ -1037,7 +1037,7 @@ init_cifs(void)
        if (rc)
                goto out_unregister_key_type;
 #endif
-       rc = slow_work_register_user();
+       rc = slow_work_register_user(THIS_MODULE);
        if (rc)
                goto out_unregister_resolver_key;
 
index 627a60a6c1b11078c33c37503afcd8061f4ff428..1f42f772865a54f1f45b516b090533a4a4715bf4 100644 (file)
@@ -214,8 +214,6 @@ int cifs_posix_open(char *full_path, struct inode **pinode,
                posix_flags |= SMB_O_EXCL;
        if (oflags & O_TRUNC)
                posix_flags |= SMB_O_TRUNC;
-       if (oflags & O_APPEND)
-               posix_flags |= SMB_O_APPEND;
        if (oflags & O_SYNC)
                posix_flags |= SMB_O_SYNC;
        if (oflags & O_DIRECTORY)
@@ -643,9 +641,9 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
         * O_EXCL: optimize away the lookup, but don't hash the dentry. Let
         * the VFS handle the create.
         */
-       if (nd->flags & LOOKUP_EXCL) {
+       if (nd && (nd->flags & LOOKUP_EXCL)) {
                d_instantiate(direntry, NULL);
-               return 0;
+               return NULL;
        }
 
        /* can not grab the rename sem here since it would
@@ -675,7 +673,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
         * reduction in network traffic in the other paths.
         */
        if (pTcon->unix_ext) {
-               if (!(nd->flags & (LOOKUP_PARENT | LOOKUP_DIRECTORY)) &&
+               if (nd && !(nd->flags & (LOOKUP_PARENT | LOOKUP_DIRECTORY)) &&
                     (nd->flags & LOOKUP_OPEN) && !pTcon->broken_posix_open &&
                     (nd->intent.open.flags & O_CREAT)) {
                        rc = cifs_posix_open(full_path, &newInode, nd->path.mnt,
index 1e25efcb55c8cb43ac0a7c15a22c8aa3e9b935f4..d27d4ec6579bb41d296b4796b163cd6110ea7158 100644 (file)
@@ -720,7 +720,7 @@ void
 cifs_autodisable_serverino(struct cifs_sb_info *cifs_sb)
 {
        if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) {
-               cifs_sb->mnt_cifs_flags &= CIFS_MOUNT_SERVER_INUM;
+               cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_SERVER_INUM;
                cERROR(1, ("Autodisabling the use of server inode numbers on "
                           "%s. This server doesn't seem to support them "
                           "properly. Hardlinks will not be recognized on this "
index ba112bd4a339c93995b66bd639175a37c95a084b..c0c636e34f60f5b347407f1c43599e088d7fedca 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -46,7 +46,6 @@
 #include <linux/proc_fs.h>
 #include <linux/mount.h>
 #include <linux/security.h>
-#include <linux/ima.h>
 #include <linux/syscalls.h>
 #include <linux/tsacct_kern.h>
 #include <linux/cn_proc.h>
@@ -1207,9 +1206,6 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs)
        struct linux_binfmt *fmt;
 
        retval = security_bprm_check(bprm);
-       if (retval)
-               return retval;
-       retval = ima_bprm_check(bprm);
        if (retval)
                return retval;
 
index fc089f2f7f56ccbbd5662eb63e2ec9832d768004..2cf93ec40a677f1e4569f5dbd37ca979e8fc31ef 100644 (file)
@@ -284,7 +284,7 @@ static int f_setown_ex(struct file *filp, unsigned long arg)
                type = PIDTYPE_PID;
                break;
 
-       case F_OWNER_GID:
+       case F_OWNER_PGRP:
                type = PIDTYPE_PGID;
                break;
 
@@ -321,7 +321,7 @@ static int f_getown_ex(struct file *filp, unsigned long arg)
                break;
 
        case PIDTYPE_PGID:
-               owner.type = F_OWNER_GID;
+               owner.type = F_OWNER_PGRP;
                break;
 
        default:
index 8eb44042e00934dbe1fe13c2af1fd659ddd8c296..4bef4c01ec6ff4b0ef7ce00816f3c124517031c0 100644 (file)
@@ -13,7 +13,6 @@
 #include <linux/module.h>
 #include <linux/fs.h>
 #include <linux/security.h>
-#include <linux/ima.h>
 #include <linux/eventpoll.h>
 #include <linux/rcupdate.h>
 #include <linux/mount.h>
@@ -280,7 +279,6 @@ void __fput(struct file *file)
        if (file->f_op && file->f_op->release)
                file->f_op->release(inode, file);
        security_file_free(file);
-       ima_file_free(file);
        if (unlikely(S_ISCHR(inode->i_mode) && inode->i_cdev != NULL))
                cdev_put(inode->i_cdev);
        fops_put(file->f_op);
index 9bbb8ce7bea02bad5cf1c8aab1fe1093ac92e855..864dac20a242a4e2b56de366646dfbe37d3112a5 100644 (file)
@@ -54,3 +54,10 @@ config FSCACHE_DEBUG
          enabled by setting bits in /sys/modules/fscache/parameter/debug.
 
          See Documentation/filesystems/caching/fscache.txt for more information.
+
+config FSCACHE_OBJECT_LIST
+       bool "Maintain global object list for debugging purposes"
+       depends on FSCACHE && PROC_FS
+       help
+         Maintain a global list of active fscache objects that can be
+         retrieved through /proc/fs/fscache/objects for debugging purposes
index 91571b95aacc38029f006f02bebcfaec671f5dc7..6d561531cb36c661355fa060e0b6f60a67509e15 100644 (file)
@@ -15,5 +15,6 @@ fscache-y := \
 fscache-$(CONFIG_PROC_FS) += proc.o
 fscache-$(CONFIG_FSCACHE_STATS) += stats.o
 fscache-$(CONFIG_FSCACHE_HISTOGRAM) += histogram.o
+fscache-$(CONFIG_FSCACHE_OBJECT_LIST) += object-list.o
 
 obj-$(CONFIG_FSCACHE) := fscache.o
index e21985bbb1fb00eedb38b6d5e7f829952c3eb066..6a3c48abd677f52eb2bd10a5bb89108cd5d89d0a 100644 (file)
@@ -263,6 +263,7 @@ int fscache_add_cache(struct fscache_cache *cache,
        spin_lock(&cache->object_list_lock);
        list_add_tail(&ifsdef->cache_link, &cache->object_list);
        spin_unlock(&cache->object_list_lock);
+       fscache_objlist_add(ifsdef);
 
        /* add the cache's netfs definition index object to the top level index
         * cookie as a known backing object */
@@ -380,11 +381,15 @@ void fscache_withdraw_cache(struct fscache_cache *cache)
 
        /* make sure all pages pinned by operations on behalf of the netfs are
         * written to disk */
+       fscache_stat(&fscache_n_cop_sync_cache);
        cache->ops->sync_cache(cache);
+       fscache_stat_d(&fscache_n_cop_sync_cache);
 
        /* dissociate all the netfs pages backed by this cache from the block
         * mappings in the cache */
+       fscache_stat(&fscache_n_cop_dissociate_pages);
        cache->ops->dissociate_pages(cache);
+       fscache_stat_d(&fscache_n_cop_dissociate_pages);
 
        /* we now have to destroy all the active objects pertaining to this
         * cache - which we do by passing them off to thread pool to be
index 72fd18f6c71f49fa79434e78e36aa5dc4598b60d..990535071a8aeadf4a67e646b6fdcad86403d63b 100644 (file)
@@ -36,6 +36,7 @@ void fscache_cookie_init_once(void *_cookie)
 
        memset(cookie, 0, sizeof(*cookie));
        spin_lock_init(&cookie->lock);
+       spin_lock_init(&cookie->stores_lock);
        INIT_HLIST_HEAD(&cookie->backing_objects);
 }
 
@@ -102,7 +103,9 @@ struct fscache_cookie *__fscache_acquire_cookie(
        cookie->netfs_data      = netfs_data;
        cookie->flags           = 0;
 
-       INIT_RADIX_TREE(&cookie->stores, GFP_NOFS);
+       /* radix tree insertion won't use the preallocation pool unless it's
+        * told it may not wait */
+       INIT_RADIX_TREE(&cookie->stores, GFP_NOFS & ~__GFP_WAIT);
 
        switch (cookie->def->type) {
        case FSCACHE_COOKIE_TYPE_INDEX:
@@ -249,7 +252,9 @@ static int fscache_alloc_object(struct fscache_cache *cache,
 
        /* ask the cache to allocate an object (we may end up with duplicate
         * objects at this stage, but we sort that out later) */
+       fscache_stat(&fscache_n_cop_alloc_object);
        object = cache->ops->alloc_object(cache, cookie);
+       fscache_stat_d(&fscache_n_cop_alloc_object);
        if (IS_ERR(object)) {
                fscache_stat(&fscache_n_object_no_alloc);
                ret = PTR_ERR(object);
@@ -270,8 +275,11 @@ static int fscache_alloc_object(struct fscache_cache *cache,
        /* only attach if we managed to allocate all we needed, otherwise
         * discard the object we just allocated and instead use the one
         * attached to the cookie */
-       if (fscache_attach_object(cookie, object) < 0)
+       if (fscache_attach_object(cookie, object) < 0) {
+               fscache_stat(&fscache_n_cop_put_object);
                cache->ops->put_object(object);
+               fscache_stat_d(&fscache_n_cop_put_object);
+       }
 
        _leave(" = 0");
        return 0;
@@ -287,7 +295,9 @@ object_already_extant:
        return 0;
 
 error_put:
+       fscache_stat(&fscache_n_cop_put_object);
        cache->ops->put_object(object);
+       fscache_stat_d(&fscache_n_cop_put_object);
 error:
        _leave(" = %d", ret);
        return ret;
@@ -349,6 +359,8 @@ static int fscache_attach_object(struct fscache_cookie *cookie,
        object->cookie = cookie;
        atomic_inc(&cookie->usage);
        hlist_add_head(&object->cookie_link, &cookie->backing_objects);
+
+       fscache_objlist_add(object);
        ret = 0;
 
 cant_attach_object:
@@ -403,6 +415,8 @@ void __fscache_relinquish_cookie(struct fscache_cookie *cookie, int retire)
        unsigned long event;
 
        fscache_stat(&fscache_n_relinquishes);
+       if (retire)
+               fscache_stat(&fscache_n_relinquishes_retire);
 
        if (!cookie) {
                fscache_stat(&fscache_n_relinquishes_null);
@@ -428,12 +442,8 @@ void __fscache_relinquish_cookie(struct fscache_cookie *cookie, int retire)
 
        event = retire ? FSCACHE_OBJECT_EV_RETIRE : FSCACHE_OBJECT_EV_RELEASE;
 
-       /* detach pointers back to the netfs */
        spin_lock(&cookie->lock);
 
-       cookie->netfs_data      = NULL;
-       cookie->def             = NULL;
-
        /* break links with all the active objects */
        while (!hlist_empty(&cookie->backing_objects)) {
                object = hlist_entry(cookie->backing_objects.first,
@@ -456,6 +466,10 @@ void __fscache_relinquish_cookie(struct fscache_cookie *cookie, int retire)
                        BUG();
        }
 
+       /* detach pointers back to the netfs */
+       cookie->netfs_data      = NULL;
+       cookie->def             = NULL;
+
        spin_unlock(&cookie->lock);
 
        if (cookie->parent) {
index 1c341304621fc7b132b0f2fffa91ab283f758779..edd7434ab6e5eb5ff3a8b3b9f38b127a3e2753cf 100644 (file)
@@ -17,6 +17,7 @@
  * - cache->object_list_lock
  * - object->lock
  * - object->parent->lock
+ * - cookie->stores_lock
  * - fscache_thread_lock
  *
  */
@@ -88,10 +89,23 @@ extern int fscache_wait_bit_interruptible(void *);
 /*
  * object.c
  */
+extern const char fscache_object_states_short[FSCACHE_OBJECT__NSTATES][5];
+
 extern void fscache_withdrawing_object(struct fscache_cache *,
                                       struct fscache_object *);
 extern void fscache_enqueue_object(struct fscache_object *);
 
+/*
+ * object-list.c
+ */
+#ifdef CONFIG_FSCACHE_OBJECT_LIST
+extern const struct file_operations fscache_objlist_fops;
+
+extern void fscache_objlist_add(struct fscache_object *);
+#else
+#define fscache_objlist_add(object) do {} while(0)
+#endif
+
 /*
  * operation.c
  */
@@ -99,6 +113,7 @@ extern int fscache_submit_exclusive_op(struct fscache_object *,
                                       struct fscache_operation *);
 extern int fscache_submit_op(struct fscache_object *,
                             struct fscache_operation *);
+extern int fscache_cancel_op(struct fscache_operation *);
 extern void fscache_abort_object(struct fscache_object *);
 extern void fscache_start_operations(struct fscache_object *);
 extern void fscache_operation_gc(struct work_struct *);
@@ -127,6 +142,8 @@ extern atomic_t fscache_n_op_enqueue;
 extern atomic_t fscache_n_op_deferred_release;
 extern atomic_t fscache_n_op_release;
 extern atomic_t fscache_n_op_gc;
+extern atomic_t fscache_n_op_cancelled;
+extern atomic_t fscache_n_op_rejected;
 
 extern atomic_t fscache_n_attr_changed;
 extern atomic_t fscache_n_attr_changed_ok;
@@ -138,6 +155,8 @@ extern atomic_t fscache_n_allocs;
 extern atomic_t fscache_n_allocs_ok;
 extern atomic_t fscache_n_allocs_wait;
 extern atomic_t fscache_n_allocs_nobufs;
+extern atomic_t fscache_n_allocs_intr;
+extern atomic_t fscache_n_allocs_object_dead;
 extern atomic_t fscache_n_alloc_ops;
 extern atomic_t fscache_n_alloc_op_waits;
 
@@ -148,6 +167,7 @@ extern atomic_t fscache_n_retrievals_nodata;
 extern atomic_t fscache_n_retrievals_nobufs;
 extern atomic_t fscache_n_retrievals_intr;
 extern atomic_t fscache_n_retrievals_nomem;
+extern atomic_t fscache_n_retrievals_object_dead;
 extern atomic_t fscache_n_retrieval_ops;
 extern atomic_t fscache_n_retrieval_op_waits;
 
@@ -158,6 +178,14 @@ extern atomic_t fscache_n_stores_nobufs;
 extern atomic_t fscache_n_stores_oom;
 extern atomic_t fscache_n_store_ops;
 extern atomic_t fscache_n_store_calls;
+extern atomic_t fscache_n_store_pages;
+extern atomic_t fscache_n_store_radix_deletes;
+extern atomic_t fscache_n_store_pages_over_limit;
+
+extern atomic_t fscache_n_store_vmscan_not_storing;
+extern atomic_t fscache_n_store_vmscan_gone;
+extern atomic_t fscache_n_store_vmscan_busy;
+extern atomic_t fscache_n_store_vmscan_cancelled;
 
 extern atomic_t fscache_n_marks;
 extern atomic_t fscache_n_uncaches;
@@ -176,6 +204,7 @@ extern atomic_t fscache_n_updates_run;
 extern atomic_t fscache_n_relinquishes;
 extern atomic_t fscache_n_relinquishes_null;
 extern atomic_t fscache_n_relinquishes_waitcrt;
+extern atomic_t fscache_n_relinquishes_retire;
 
 extern atomic_t fscache_n_cookie_index;
 extern atomic_t fscache_n_cookie_data;
@@ -186,6 +215,7 @@ extern atomic_t fscache_n_object_no_alloc;
 extern atomic_t fscache_n_object_lookups;
 extern atomic_t fscache_n_object_lookups_negative;
 extern atomic_t fscache_n_object_lookups_positive;
+extern atomic_t fscache_n_object_lookups_timed_out;
 extern atomic_t fscache_n_object_created;
 extern atomic_t fscache_n_object_avail;
 extern atomic_t fscache_n_object_dead;
@@ -195,15 +225,41 @@ extern atomic_t fscache_n_checkaux_okay;
 extern atomic_t fscache_n_checkaux_update;
 extern atomic_t fscache_n_checkaux_obsolete;
 
+extern atomic_t fscache_n_cop_alloc_object;
+extern atomic_t fscache_n_cop_lookup_object;
+extern atomic_t fscache_n_cop_lookup_complete;
+extern atomic_t fscache_n_cop_grab_object;
+extern atomic_t fscache_n_cop_update_object;
+extern atomic_t fscache_n_cop_drop_object;
+extern atomic_t fscache_n_cop_put_object;
+extern atomic_t fscache_n_cop_sync_cache;
+extern atomic_t fscache_n_cop_attr_changed;
+extern atomic_t fscache_n_cop_read_or_alloc_page;
+extern atomic_t fscache_n_cop_read_or_alloc_pages;
+extern atomic_t fscache_n_cop_allocate_page;
+extern atomic_t fscache_n_cop_allocate_pages;
+extern atomic_t fscache_n_cop_write_page;
+extern atomic_t fscache_n_cop_uncache_page;
+extern atomic_t fscache_n_cop_dissociate_pages;
+
 static inline void fscache_stat(atomic_t *stat)
 {
        atomic_inc(stat);
 }
 
+static inline void fscache_stat_d(atomic_t *stat)
+{
+       atomic_dec(stat);
+}
+
+#define __fscache_stat(stat) (stat)
+
 extern const struct file_operations fscache_stats_fops;
 #else
 
+#define __fscache_stat(stat) (NULL)
 #define fscache_stat(stat) do {} while (0)
+#define fscache_stat_d(stat) do {} while (0)
 #endif
 
 /*
index 4de41b5974991f05b6a1fc4f07fe40ac746770d8..add6bdb53f04400779ca899370d07bd2480e108a 100644 (file)
@@ -48,7 +48,7 @@ static int __init fscache_init(void)
 {
        int ret;
 
-       ret = slow_work_register_user();
+       ret = slow_work_register_user(THIS_MODULE);
        if (ret < 0)
                goto error_slow_work;
 
@@ -80,7 +80,7 @@ error_kobj:
 error_cookie_jar:
        fscache_proc_cleanup();
 error_proc:
-       slow_work_unregister_user();
+       slow_work_unregister_user(THIS_MODULE);
 error_slow_work:
        return ret;
 }
@@ -97,7 +97,7 @@ static void __exit fscache_exit(void)
        kobject_put(fscache_root);
        kmem_cache_destroy(fscache_cookie_jar);
        fscache_proc_cleanup();
-       slow_work_unregister_user();
+       slow_work_unregister_user(THIS_MODULE);
        printk(KERN_NOTICE "FS-Cache: Unloaded\n");
 }
 
diff --git a/fs/fscache/object-list.c b/fs/fscache/object-list.c
new file mode 100644 (file)
index 0000000..e590242
--- /dev/null
@@ -0,0 +1,432 @@
+/* Global fscache object list maintainer and viewer
+ *
+ * Copyright (C) 2009 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#define FSCACHE_DEBUG_LEVEL COOKIE
+#include <linux/module.h>
+#include <linux/seq_file.h>
+#include <linux/key.h>
+#include <keys/user-type.h>
+#include "internal.h"
+
+static struct rb_root fscache_object_list;
+static DEFINE_RWLOCK(fscache_object_list_lock);
+
+struct fscache_objlist_data {
+       unsigned long   config;         /* display configuration */
+#define FSCACHE_OBJLIST_CONFIG_KEY     0x00000001      /* show object keys */
+#define FSCACHE_OBJLIST_CONFIG_AUX     0x00000002      /* show object auxdata */
+#define FSCACHE_OBJLIST_CONFIG_COOKIE  0x00000004      /* show objects with cookies */
+#define FSCACHE_OBJLIST_CONFIG_NOCOOKIE        0x00000008      /* show objects without cookies */
+#define FSCACHE_OBJLIST_CONFIG_BUSY    0x00000010      /* show busy objects */
+#define FSCACHE_OBJLIST_CONFIG_IDLE    0x00000020      /* show idle objects */
+#define FSCACHE_OBJLIST_CONFIG_PENDWR  0x00000040      /* show objects with pending writes */
+#define FSCACHE_OBJLIST_CONFIG_NOPENDWR        0x00000080      /* show objects without pending writes */
+#define FSCACHE_OBJLIST_CONFIG_READS   0x00000100      /* show objects with active reads */
+#define FSCACHE_OBJLIST_CONFIG_NOREADS 0x00000200      /* show objects without active reads */
+#define FSCACHE_OBJLIST_CONFIG_EVENTS  0x00000400      /* show objects with events */
+#define FSCACHE_OBJLIST_CONFIG_NOEVENTS        0x00000800      /* show objects without no events */
+#define FSCACHE_OBJLIST_CONFIG_WORK    0x00001000      /* show objects with slow work */
+#define FSCACHE_OBJLIST_CONFIG_NOWORK  0x00002000      /* show objects without slow work */
+
+       u8              buf[512];       /* key and aux data buffer */
+};
+
+/*
+ * Add an object to the object list
+ * - we use the address of the fscache_object structure as the key into the
+ *   tree
+ */
+void fscache_objlist_add(struct fscache_object *obj)
+{
+       struct fscache_object *xobj;
+       struct rb_node **p = &fscache_object_list.rb_node, *parent = NULL;
+
+       write_lock(&fscache_object_list_lock);
+
+       while (*p) {
+               parent = *p;
+               xobj = rb_entry(parent, struct fscache_object, objlist_link);
+
+               if (obj < xobj)
+                       p = &(*p)->rb_left;
+               else if (obj > xobj)
+                       p = &(*p)->rb_right;
+               else
+                       BUG();
+       }
+
+       rb_link_node(&obj->objlist_link, parent, p);
+       rb_insert_color(&obj->objlist_link, &fscache_object_list);
+
+       write_unlock(&fscache_object_list_lock);
+}
+
+/**
+ * fscache_object_destroy - Note that a cache object is about to be destroyed
+ * @object: The object to be destroyed
+ *
+ * Note the imminent destruction and deallocation of a cache object record.
+ */
+void fscache_object_destroy(struct fscache_object *obj)
+{
+       write_lock(&fscache_object_list_lock);
+
+       BUG_ON(RB_EMPTY_ROOT(&fscache_object_list));
+       rb_erase(&obj->objlist_link, &fscache_object_list);
+
+       write_unlock(&fscache_object_list_lock);
+}
+EXPORT_SYMBOL(fscache_object_destroy);
+
+/*
+ * find the object in the tree on or after the specified index
+ */
+static struct fscache_object *fscache_objlist_lookup(loff_t *_pos)
+{
+       struct fscache_object *pobj, *obj, *minobj = NULL;
+       struct rb_node *p;
+       unsigned long pos;
+
+       if (*_pos >= (unsigned long) ERR_PTR(-ENOENT))
+               return NULL;
+       pos = *_pos;
+
+       /* banners (can't represent line 0 by pos 0 as that would involve
+        * returning a NULL pointer) */
+       if (pos == 0)
+               return (struct fscache_object *) ++(*_pos);
+       if (pos < 3)
+               return (struct fscache_object *)pos;
+
+       pobj = (struct fscache_object *)pos;
+       p = fscache_object_list.rb_node;
+       while (p) {
+               obj = rb_entry(p, struct fscache_object, objlist_link);
+               if (pobj < obj) {
+                       if (!minobj || minobj > obj)
+                               minobj = obj;
+                       p = p->rb_left;
+               } else if (pobj > obj) {
+                       p = p->rb_right;
+               } else {
+                       minobj = obj;
+                       break;
+               }
+               obj = NULL;
+       }
+
+       if (!minobj)
+               *_pos = (unsigned long) ERR_PTR(-ENOENT);
+       else if (minobj != obj)
+               *_pos = (unsigned long) minobj;
+       return minobj;
+}
+
+/*
+ * set up the iterator to start reading from the first line
+ */
+static void *fscache_objlist_start(struct seq_file *m, loff_t *_pos)
+       __acquires(&fscache_object_list_lock)
+{
+       read_lock(&fscache_object_list_lock);
+       return fscache_objlist_lookup(_pos);
+}
+
+/*
+ * move to the next line
+ */
+static void *fscache_objlist_next(struct seq_file *m, void *v, loff_t *_pos)
+{
+       (*_pos)++;
+       return fscache_objlist_lookup(_pos);
+}
+
+/*
+ * clean up after reading
+ */
+static void fscache_objlist_stop(struct seq_file *m, void *v)
+       __releases(&fscache_object_list_lock)
+{
+       read_unlock(&fscache_object_list_lock);
+}
+
+/*
+ * display an object
+ */
+static int fscache_objlist_show(struct seq_file *m, void *v)
+{
+       struct fscache_objlist_data *data = m->private;
+       struct fscache_object *obj = v;
+       unsigned long config = data->config;
+       uint16_t keylen, auxlen;
+       char _type[3], *type;
+       bool no_cookie;
+       u8 *buf = data->buf, *p;
+
+       if ((unsigned long) v == 1) {
+               seq_puts(m, "OBJECT   PARENT   STAT CHLDN OPS OOP IPR EX READS"
+                        " EM EV F S"
+                        " | NETFS_COOKIE_DEF TY FL NETFS_DATA");
+               if (config & (FSCACHE_OBJLIST_CONFIG_KEY |
+                             FSCACHE_OBJLIST_CONFIG_AUX))
+                       seq_puts(m, "       ");
+               if (config & FSCACHE_OBJLIST_CONFIG_KEY)
+                       seq_puts(m, "OBJECT_KEY");
+               if ((config & (FSCACHE_OBJLIST_CONFIG_KEY |
+                              FSCACHE_OBJLIST_CONFIG_AUX)) ==
+                   (FSCACHE_OBJLIST_CONFIG_KEY | FSCACHE_OBJLIST_CONFIG_AUX))
+                       seq_puts(m, ", ");
+               if (config & FSCACHE_OBJLIST_CONFIG_AUX)
+                       seq_puts(m, "AUX_DATA");
+               seq_puts(m, "\n");
+               return 0;
+       }
+
+       if ((unsigned long) v == 2) {
+               seq_puts(m, "======== ======== ==== ===== === === === == ====="
+                        " == == = ="
+                        " | ================ == == ================");
+               if (config & (FSCACHE_OBJLIST_CONFIG_KEY |
+                             FSCACHE_OBJLIST_CONFIG_AUX))
+                       seq_puts(m, " ================");
+               seq_puts(m, "\n");
+               return 0;
+       }
+
+       /* filter out any unwanted objects */
+#define FILTER(criterion, _yes, _no)                                   \
+       do {                                                            \
+               unsigned long yes = FSCACHE_OBJLIST_CONFIG_##_yes;      \
+               unsigned long no = FSCACHE_OBJLIST_CONFIG_##_no;        \
+               if (criterion) {                                        \
+                       if (!(config & yes))                            \
+                               return 0;                               \
+               } else {                                                \
+                       if (!(config & no))                             \
+                               return 0;                               \
+               }                                                       \
+       } while(0)
+
+       if (~config) {
+               FILTER(obj->cookie,
+                      COOKIE, NOCOOKIE);
+               FILTER(obj->state != FSCACHE_OBJECT_ACTIVE ||
+                      obj->n_ops != 0 ||
+                      obj->n_obj_ops != 0 ||
+                      obj->flags ||
+                      !list_empty(&obj->dependents),
+                      BUSY, IDLE);
+               FILTER(test_bit(FSCACHE_OBJECT_PENDING_WRITE, &obj->flags),
+                      PENDWR, NOPENDWR);
+               FILTER(atomic_read(&obj->n_reads),
+                      READS, NOREADS);
+               FILTER(obj->events & obj->event_mask,
+                      EVENTS, NOEVENTS);
+               FILTER(obj->work.flags & ~(1UL << SLOW_WORK_VERY_SLOW),
+                      WORK, NOWORK);
+       }
+
+       seq_printf(m,
+                  "%8x %8x %s %5u %3u %3u %3u %2u %5u %2lx %2lx %1lx %1lx | ",
+                  obj->debug_id,
+                  obj->parent ? obj->parent->debug_id : -1,
+                  fscache_object_states_short[obj->state],
+                  obj->n_children,
+                  obj->n_ops,
+                  obj->n_obj_ops,
+                  obj->n_in_progress,
+                  obj->n_exclusive,
+                  atomic_read(&obj->n_reads),
+                  obj->event_mask & FSCACHE_OBJECT_EVENTS_MASK,
+                  obj->events,
+                  obj->flags,
+                  obj->work.flags);
+
+       no_cookie = true;
+       keylen = auxlen = 0;
+       if (obj->cookie) {
+               spin_lock(&obj->lock);
+               if (obj->cookie) {
+                       switch (obj->cookie->def->type) {
+                       case 0:
+                               type = "IX";
+                               break;
+                       case 1:
+                               type = "DT";
+                               break;
+                       default:
+                               sprintf(_type, "%02u",
+                                       obj->cookie->def->type);
+                               type = _type;
+                               break;
+                       }
+
+                       seq_printf(m, "%-16s %s %2lx %16p",
+                                  obj->cookie->def->name,
+                                  type,
+                                  obj->cookie->flags,
+                                  obj->cookie->netfs_data);
+
+                       if (obj->cookie->def->get_key &&
+                           config & FSCACHE_OBJLIST_CONFIG_KEY)
+                               keylen = obj->cookie->def->get_key(
+                                       obj->cookie->netfs_data,
+                                       buf, 400);
+
+                       if (obj->cookie->def->get_aux &&
+                           config & FSCACHE_OBJLIST_CONFIG_AUX)
+                               auxlen = obj->cookie->def->get_aux(
+                                       obj->cookie->netfs_data,
+                                       buf + keylen, 512 - keylen);
+
+                       no_cookie = false;
+               }
+               spin_unlock(&obj->lock);
+
+               if (!no_cookie && (keylen > 0 || auxlen > 0)) {
+                       seq_printf(m, " ");
+                       for (p = buf; keylen > 0; keylen--)
+                               seq_printf(m, "%02x", *p++);
+                       if (auxlen > 0) {
+                               if (config & FSCACHE_OBJLIST_CONFIG_KEY)
+                                       seq_printf(m, ", ");
+                               for (; auxlen > 0; auxlen--)
+                                       seq_printf(m, "%02x", *p++);
+                       }
+               }
+       }
+
+       if (no_cookie)
+               seq_printf(m, "<no_cookie>\n");
+       else
+               seq_printf(m, "\n");
+       return 0;
+}
+
+static const struct seq_operations fscache_objlist_ops = {
+       .start          = fscache_objlist_start,
+       .stop           = fscache_objlist_stop,
+       .next           = fscache_objlist_next,
+       .show           = fscache_objlist_show,
+};
+
+/*
+ * get the configuration for filtering the list
+ */
+static void fscache_objlist_config(struct fscache_objlist_data *data)
+{
+#ifdef CONFIG_KEYS
+       struct user_key_payload *confkey;
+       unsigned long config;
+       struct key *key;
+       const char *buf;
+       int len;
+
+       key = request_key(&key_type_user, "fscache:objlist", NULL);
+       if (IS_ERR(key))
+               goto no_config;
+
+       config = 0;
+       rcu_read_lock();
+
+       confkey = key->payload.data;
+       buf = confkey->data;
+
+       for (len = confkey->datalen - 1; len >= 0; len--) {
+               switch (buf[len]) {
+               case 'K': config |= FSCACHE_OBJLIST_CONFIG_KEY;         break;
+               case 'A': config |= FSCACHE_OBJLIST_CONFIG_AUX;         break;
+               case 'C': config |= FSCACHE_OBJLIST_CONFIG_COOKIE;      break;
+               case 'c': config |= FSCACHE_OBJLIST_CONFIG_NOCOOKIE;    break;
+               case 'B': config |= FSCACHE_OBJLIST_CONFIG_BUSY;        break;
+               case 'b': config |= FSCACHE_OBJLIST_CONFIG_IDLE;        break;
+               case 'W': config |= FSCACHE_OBJLIST_CONFIG_PENDWR;      break;
+               case 'w': config |= FSCACHE_OBJLIST_CONFIG_NOPENDWR;    break;
+               case 'R': config |= FSCACHE_OBJLIST_CONFIG_READS;       break;
+               case 'r': config |= FSCACHE_OBJLIST_CONFIG_NOREADS;     break;
+               case 'S': config |= FSCACHE_OBJLIST_CONFIG_WORK;        break;
+               case 's': config |= FSCACHE_OBJLIST_CONFIG_NOWORK;      break;
+               }
+       }
+
+       rcu_read_unlock();
+       key_put(key);
+
+       if (!(config & (FSCACHE_OBJLIST_CONFIG_COOKIE | FSCACHE_OBJLIST_CONFIG_NOCOOKIE)))
+           config   |= FSCACHE_OBJLIST_CONFIG_COOKIE | FSCACHE_OBJLIST_CONFIG_NOCOOKIE;
+       if (!(config & (FSCACHE_OBJLIST_CONFIG_BUSY | FSCACHE_OBJLIST_CONFIG_IDLE)))
+           config   |= FSCACHE_OBJLIST_CONFIG_BUSY | FSCACHE_OBJLIST_CONFIG_IDLE;
+       if (!(config & (FSCACHE_OBJLIST_CONFIG_PENDWR | FSCACHE_OBJLIST_CONFIG_NOPENDWR)))
+           config   |= FSCACHE_OBJLIST_CONFIG_PENDWR | FSCACHE_OBJLIST_CONFIG_NOPENDWR;
+       if (!(config & (FSCACHE_OBJLIST_CONFIG_READS | FSCACHE_OBJLIST_CONFIG_NOREADS)))
+           config   |= FSCACHE_OBJLIST_CONFIG_READS | FSCACHE_OBJLIST_CONFIG_NOREADS;
+       if (!(config & (FSCACHE_OBJLIST_CONFIG_EVENTS | FSCACHE_OBJLIST_CONFIG_NOEVENTS)))
+           config   |= FSCACHE_OBJLIST_CONFIG_EVENTS | FSCACHE_OBJLIST_CONFIG_NOEVENTS;
+       if (!(config & (FSCACHE_OBJLIST_CONFIG_WORK | FSCACHE_OBJLIST_CONFIG_NOWORK)))
+           config   |= FSCACHE_OBJLIST_CONFIG_WORK | FSCACHE_OBJLIST_CONFIG_NOWORK;
+
+       data->config = config;
+       return;
+
+no_config:
+#endif
+       data->config = ULONG_MAX;
+}
+
+/*
+ * open "/proc/fs/fscache/objects" to provide a list of active objects
+ * - can be configured by a user-defined key added to the caller's keyrings
+ */
+static int fscache_objlist_open(struct inode *inode, struct file *file)
+{
+       struct fscache_objlist_data *data;
+       struct seq_file *m;
+       int ret;
+
+       ret = seq_open(file, &fscache_objlist_ops);
+       if (ret < 0)
+               return ret;
+
+       m = file->private_data;
+
+       /* buffer for key extraction */
+       data = kmalloc(sizeof(struct fscache_objlist_data), GFP_KERNEL);
+       if (!data) {
+               seq_release(inode, file);
+               return -ENOMEM;
+       }
+
+       /* get the configuration key */
+       fscache_objlist_config(data);
+
+       m->private = data;
+       return 0;
+}
+
+/*
+ * clean up on close
+ */
+static int fscache_objlist_release(struct inode *inode, struct file *file)
+{
+       struct seq_file *m = file->private_data;
+
+       kfree(m->private);
+       m->private = NULL;
+       return seq_release(inode, file);
+}
+
+const struct file_operations fscache_objlist_fops = {
+       .owner          = THIS_MODULE,
+       .open           = fscache_objlist_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = fscache_objlist_release,
+};
index 392a41b1b79d417324f4cc41dd94e670d6272400..e513ac599c8e9b587c8646e33485be20d2ce1c4e 100644 (file)
 
 #define FSCACHE_DEBUG_LEVEL COOKIE
 #include <linux/module.h>
+#include <linux/seq_file.h>
 #include "internal.h"
 
-const char *fscache_object_states[] = {
+const char *fscache_object_states[FSCACHE_OBJECT__NSTATES] = {
        [FSCACHE_OBJECT_INIT]           = "OBJECT_INIT",
        [FSCACHE_OBJECT_LOOKING_UP]     = "OBJECT_LOOKING_UP",
        [FSCACHE_OBJECT_CREATING]       = "OBJECT_CREATING",
@@ -33,9 +34,28 @@ const char *fscache_object_states[] = {
 };
 EXPORT_SYMBOL(fscache_object_states);
 
+const char fscache_object_states_short[FSCACHE_OBJECT__NSTATES][5] = {
+       [FSCACHE_OBJECT_INIT]           = "INIT",
+       [FSCACHE_OBJECT_LOOKING_UP]     = "LOOK",
+       [FSCACHE_OBJECT_CREATING]       = "CRTN",
+       [FSCACHE_OBJECT_AVAILABLE]      = "AVBL",
+       [FSCACHE_OBJECT_ACTIVE]         = "ACTV",
+       [FSCACHE_OBJECT_UPDATING]       = "UPDT",
+       [FSCACHE_OBJECT_DYING]          = "DYNG",
+       [FSCACHE_OBJECT_LC_DYING]       = "LCDY",
+       [FSCACHE_OBJECT_ABORT_INIT]     = "ABTI",
+       [FSCACHE_OBJECT_RELEASING]      = "RELS",
+       [FSCACHE_OBJECT_RECYCLING]      = "RCYC",
+       [FSCACHE_OBJECT_WITHDRAWING]    = "WTHD",
+       [FSCACHE_OBJECT_DEAD]           = "DEAD",
+};
+
 static void fscache_object_slow_work_put_ref(struct slow_work *);
 static int  fscache_object_slow_work_get_ref(struct slow_work *);
 static void fscache_object_slow_work_execute(struct slow_work *);
+#ifdef CONFIG_SLOW_WORK_PROC
+static void fscache_object_slow_work_desc(struct slow_work *, struct seq_file *);
+#endif
 static void fscache_initialise_object(struct fscache_object *);
 static void fscache_lookup_object(struct fscache_object *);
 static void fscache_object_available(struct fscache_object *);
@@ -45,9 +65,13 @@ static void fscache_enqueue_dependents(struct fscache_object *);
 static void fscache_dequeue_object(struct fscache_object *);
 
 const struct slow_work_ops fscache_object_slow_work_ops = {
+       .owner          = THIS_MODULE,
        .get_ref        = fscache_object_slow_work_get_ref,
        .put_ref        = fscache_object_slow_work_put_ref,
        .execute        = fscache_object_slow_work_execute,
+#ifdef CONFIG_SLOW_WORK_PROC
+       .desc           = fscache_object_slow_work_desc,
+#endif
 };
 EXPORT_SYMBOL(fscache_object_slow_work_ops);
 
@@ -81,6 +105,7 @@ static inline void fscache_done_parent_op(struct fscache_object *object)
 static void fscache_object_state_machine(struct fscache_object *object)
 {
        enum fscache_object_state new_state;
+       struct fscache_cookie *cookie;
 
        ASSERT(object != NULL);
 
@@ -120,20 +145,31 @@ static void fscache_object_state_machine(struct fscache_object *object)
        case FSCACHE_OBJECT_UPDATING:
                clear_bit(FSCACHE_OBJECT_EV_UPDATE, &object->events);
                fscache_stat(&fscache_n_updates_run);
+               fscache_stat(&fscache_n_cop_update_object);
                object->cache->ops->update_object(object);
+               fscache_stat_d(&fscache_n_cop_update_object);
                goto active_transit;
 
                /* handle an object dying during lookup or creation */
        case FSCACHE_OBJECT_LC_DYING:
                object->event_mask &= ~(1 << FSCACHE_OBJECT_EV_UPDATE);
+               fscache_stat(&fscache_n_cop_lookup_complete);
                object->cache->ops->lookup_complete(object);
+               fscache_stat_d(&fscache_n_cop_lookup_complete);
 
                spin_lock(&object->lock);
                object->state = FSCACHE_OBJECT_DYING;
-               if (test_and_clear_bit(FSCACHE_COOKIE_CREATING,
-                                      &object->cookie->flags))
-                       wake_up_bit(&object->cookie->flags,
-                                   FSCACHE_COOKIE_CREATING);
+               cookie = object->cookie;
+               if (cookie) {
+                       if (test_and_clear_bit(FSCACHE_COOKIE_LOOKING_UP,
+                                              &cookie->flags))
+                               wake_up_bit(&cookie->flags,
+                                           FSCACHE_COOKIE_LOOKING_UP);
+                       if (test_and_clear_bit(FSCACHE_COOKIE_CREATING,
+                                              &cookie->flags))
+                               wake_up_bit(&cookie->flags,
+                                           FSCACHE_COOKIE_CREATING);
+               }
                spin_unlock(&object->lock);
 
                fscache_done_parent_op(object);
@@ -165,6 +201,7 @@ static void fscache_object_state_machine(struct fscache_object *object)
                }
                spin_unlock(&object->lock);
                fscache_enqueue_dependents(object);
+               fscache_start_operations(object);
                goto terminal_transit;
 
                /* handle an abort during initialisation */
@@ -316,14 +353,29 @@ static void fscache_object_slow_work_execute(struct slow_work *work)
 
        _enter("{OBJ%x}", object->debug_id);
 
-       clear_bit(FSCACHE_OBJECT_EV_REQUEUE, &object->events);
-
        start = jiffies;
        fscache_object_state_machine(object);
        fscache_hist(fscache_objs_histogram, start);
        if (object->events & object->event_mask)
                fscache_enqueue_object(object);
+       clear_bit(FSCACHE_OBJECT_EV_REQUEUE, &object->events);
+}
+
+/*
+ * describe an object for slow-work debugging
+ */
+#ifdef CONFIG_SLOW_WORK_PROC
+static void fscache_object_slow_work_desc(struct slow_work *work,
+                                         struct seq_file *m)
+{
+       struct fscache_object *object =
+               container_of(work, struct fscache_object, work);
+
+       seq_printf(m, "FSC: OBJ%x: %s",
+                  object->debug_id,
+                  fscache_object_states_short[object->state]);
 }
+#endif
 
 /*
  * initialise an object
@@ -376,7 +428,9 @@ static void fscache_initialise_object(struct fscache_object *object)
                         * binding on to us, so we need to make sure we don't
                         * add ourself to the list multiple times */
                        if (list_empty(&object->dep_link)) {
+                               fscache_stat(&fscache_n_cop_grab_object);
                                object->cache->ops->grab_object(object);
+                               fscache_stat_d(&fscache_n_cop_grab_object);
                                list_add(&object->dep_link,
                                         &parent->dependents);
 
@@ -414,6 +468,7 @@ static void fscache_lookup_object(struct fscache_object *object)
 {
        struct fscache_cookie *cookie = object->cookie;
        struct fscache_object *parent;
+       int ret;
 
        _enter("");
 
@@ -438,11 +493,20 @@ static void fscache_lookup_object(struct fscache_object *object)
               object->cache->tag->name);
 
        fscache_stat(&fscache_n_object_lookups);
-       object->cache->ops->lookup_object(object);
+       fscache_stat(&fscache_n_cop_lookup_object);
+       ret = object->cache->ops->lookup_object(object);
+       fscache_stat_d(&fscache_n_cop_lookup_object);
 
        if (test_bit(FSCACHE_OBJECT_EV_ERROR, &object->events))
                set_bit(FSCACHE_COOKIE_UNAVAILABLE, &cookie->flags);
 
+       if (ret == -ETIMEDOUT) {
+               /* probably stuck behind another object, so move this one to
+                * the back of the queue */
+               fscache_stat(&fscache_n_object_lookups_timed_out);
+               set_bit(FSCACHE_OBJECT_EV_REQUEUE, &object->events);
+       }
+
        _leave("");
 }
 
@@ -546,7 +610,8 @@ static void fscache_object_available(struct fscache_object *object)
 
        spin_lock(&object->lock);
 
-       if (test_and_clear_bit(FSCACHE_COOKIE_CREATING, &object->cookie->flags))
+       if (object->cookie &&
+           test_and_clear_bit(FSCACHE_COOKIE_CREATING, &object->cookie->flags))
                wake_up_bit(&object->cookie->flags, FSCACHE_COOKIE_CREATING);
 
        fscache_done_parent_op(object);
@@ -562,7 +627,9 @@ static void fscache_object_available(struct fscache_object *object)
        }
        spin_unlock(&object->lock);
 
+       fscache_stat(&fscache_n_cop_lookup_complete);
        object->cache->ops->lookup_complete(object);
+       fscache_stat_d(&fscache_n_cop_lookup_complete);
        fscache_enqueue_dependents(object);
 
        fscache_hist(fscache_obj_instantiate_histogram, object->lookup_jif);
@@ -581,11 +648,16 @@ static void fscache_drop_object(struct fscache_object *object)
 
        _enter("{OBJ%x,%d}", object->debug_id, object->n_children);
 
+       ASSERTCMP(object->cookie, ==, NULL);
+       ASSERT(hlist_unhashed(&object->cookie_link));
+
        spin_lock(&cache->object_list_lock);
        list_del_init(&object->cache_link);
        spin_unlock(&cache->object_list_lock);
 
+       fscache_stat(&fscache_n_cop_drop_object);
        cache->ops->drop_object(object);
+       fscache_stat_d(&fscache_n_cop_drop_object);
 
        if (parent) {
                _debug("release parent OBJ%x {%d}",
@@ -600,7 +672,9 @@ static void fscache_drop_object(struct fscache_object *object)
        }
 
        /* this just shifts the object release to the slow work processor */
+       fscache_stat(&fscache_n_cop_put_object);
        object->cache->ops->put_object(object);
+       fscache_stat_d(&fscache_n_cop_put_object);
 
        _leave("");
 }
@@ -690,8 +764,12 @@ static int fscache_object_slow_work_get_ref(struct slow_work *work)
 {
        struct fscache_object *object =
                container_of(work, struct fscache_object, work);
+       int ret;
 
-       return object->cache->ops->grab_object(object) ? 0 : -EAGAIN;
+       fscache_stat(&fscache_n_cop_grab_object);
+       ret = object->cache->ops->grab_object(object) ? 0 : -EAGAIN;
+       fscache_stat_d(&fscache_n_cop_grab_object);
+       return ret;
 }
 
 /*
@@ -702,7 +780,9 @@ static void fscache_object_slow_work_put_ref(struct slow_work *work)
        struct fscache_object *object =
                container_of(work, struct fscache_object, work);
 
-       return object->cache->ops->put_object(object);
+       fscache_stat(&fscache_n_cop_put_object);
+       object->cache->ops->put_object(object);
+       fscache_stat_d(&fscache_n_cop_put_object);
 }
 
 /*
@@ -739,7 +819,9 @@ static void fscache_enqueue_dependents(struct fscache_object *object)
 
                /* sort onto appropriate lists */
                fscache_enqueue_object(dep);
+               fscache_stat(&fscache_n_cop_put_object);
                dep->cache->ops->put_object(dep);
+               fscache_stat_d(&fscache_n_cop_put_object);
 
                if (!list_empty(&object->dependents))
                        cond_resched_lock(&object->lock);
index e7f8d53b8b6ba90af4bf057a204e03775efb12ef..313e79a14266e69e2a47aafdffefc89b29f510df 100644 (file)
@@ -13,6 +13,7 @@
 
 #define FSCACHE_DEBUG_LEVEL OPERATION
 #include <linux/module.h>
+#include <linux/seq_file.h>
 #include "internal.h"
 
 atomic_t fscache_op_debug_id;
@@ -31,32 +32,33 @@ void fscache_enqueue_operation(struct fscache_operation *op)
        _enter("{OBJ%x OP%x,%u}",
               op->object->debug_id, op->debug_id, atomic_read(&op->usage));
 
+       fscache_set_op_state(op, "EnQ");
+
+       ASSERT(list_empty(&op->pend_link));
        ASSERT(op->processor != NULL);
        ASSERTCMP(op->object->state, >=, FSCACHE_OBJECT_AVAILABLE);
        ASSERTCMP(atomic_read(&op->usage), >, 0);
 
-       if (list_empty(&op->pend_link)) {
-               switch (op->flags & FSCACHE_OP_TYPE) {
-               case FSCACHE_OP_FAST:
-                       _debug("queue fast");
-                       atomic_inc(&op->usage);
-                       if (!schedule_work(&op->fast_work))
-                               fscache_put_operation(op);
-                       break;
-               case FSCACHE_OP_SLOW:
-                       _debug("queue slow");
-                       slow_work_enqueue(&op->slow_work);
-                       break;
-               case FSCACHE_OP_MYTHREAD:
-                       _debug("queue for caller's attention");
-                       break;
-               default:
-                       printk(KERN_ERR "FS-Cache: Unexpected op type %lx",
-                              op->flags);
-                       BUG();
-                       break;
-               }
-               fscache_stat(&fscache_n_op_enqueue);
+       fscache_stat(&fscache_n_op_enqueue);
+       switch (op->flags & FSCACHE_OP_TYPE) {
+       case FSCACHE_OP_FAST:
+               _debug("queue fast");
+               atomic_inc(&op->usage);
+               if (!schedule_work(&op->fast_work))
+                       fscache_put_operation(op);
+               break;
+       case FSCACHE_OP_SLOW:
+               _debug("queue slow");
+               slow_work_enqueue(&op->slow_work);
+               break;
+       case FSCACHE_OP_MYTHREAD:
+               _debug("queue for caller's attention");
+               break;
+       default:
+               printk(KERN_ERR "FS-Cache: Unexpected op type %lx",
+                      op->flags);
+               BUG();
+               break;
        }
 }
 EXPORT_SYMBOL(fscache_enqueue_operation);
@@ -67,6 +69,8 @@ EXPORT_SYMBOL(fscache_enqueue_operation);
 static void fscache_run_op(struct fscache_object *object,
                           struct fscache_operation *op)
 {
+       fscache_set_op_state(op, "Run");
+
        object->n_in_progress++;
        if (test_and_clear_bit(FSCACHE_OP_WAITING, &op->flags))
                wake_up_bit(&op->flags, FSCACHE_OP_WAITING);
@@ -87,9 +91,12 @@ int fscache_submit_exclusive_op(struct fscache_object *object,
 
        _enter("{OBJ%x OP%x},", object->debug_id, op->debug_id);
 
+       fscache_set_op_state(op, "SubmitX");
+
        spin_lock(&object->lock);
        ASSERTCMP(object->n_ops, >=, object->n_in_progress);
        ASSERTCMP(object->n_ops, >=, object->n_exclusive);
+       ASSERT(list_empty(&op->pend_link));
 
        ret = -ENOBUFS;
        if (fscache_object_is_active(object)) {
@@ -190,9 +197,12 @@ int fscache_submit_op(struct fscache_object *object,
 
        ASSERTCMP(atomic_read(&op->usage), >, 0);
 
+       fscache_set_op_state(op, "Submit");
+
        spin_lock(&object->lock);
        ASSERTCMP(object->n_ops, >=, object->n_in_progress);
        ASSERTCMP(object->n_ops, >=, object->n_exclusive);
+       ASSERT(list_empty(&op->pend_link));
 
        ostate = object->state;
        smp_rmb();
@@ -222,6 +232,11 @@ int fscache_submit_op(struct fscache_object *object,
                list_add_tail(&op->pend_link, &object->pending_ops);
                fscache_stat(&fscache_n_op_pend);
                ret = 0;
+       } else if (object->state == FSCACHE_OBJECT_DYING ||
+                  object->state == FSCACHE_OBJECT_LC_DYING ||
+                  object->state == FSCACHE_OBJECT_WITHDRAWING) {
+               fscache_stat(&fscache_n_op_rejected);
+               ret = -ENOBUFS;
        } else if (!test_bit(FSCACHE_IOERROR, &object->cache->flags)) {
                fscache_report_unexpected_submission(object, op, ostate);
                ASSERT(!fscache_object_is_active(object));
@@ -264,12 +279,7 @@ void fscache_start_operations(struct fscache_object *object)
                        stop = true;
                }
                list_del_init(&op->pend_link);
-               object->n_in_progress++;
-
-               if (test_and_clear_bit(FSCACHE_OP_WAITING, &op->flags))
-                       wake_up_bit(&op->flags, FSCACHE_OP_WAITING);
-               if (op->processor)
-                       fscache_enqueue_operation(op);
+               fscache_run_op(object, op);
 
                /* the pending queue was holding a ref on the object */
                fscache_put_operation(op);
@@ -281,6 +291,36 @@ void fscache_start_operations(struct fscache_object *object)
               object->n_in_progress, object->debug_id);
 }
 
+/*
+ * cancel an operation that's pending on an object
+ */
+int fscache_cancel_op(struct fscache_operation *op)
+{
+       struct fscache_object *object = op->object;
+       int ret;
+
+       _enter("OBJ%x OP%x}", op->object->debug_id, op->debug_id);
+
+       spin_lock(&object->lock);
+
+       ret = -EBUSY;
+       if (!list_empty(&op->pend_link)) {
+               fscache_stat(&fscache_n_op_cancelled);
+               list_del_init(&op->pend_link);
+               object->n_ops--;
+               if (test_bit(FSCACHE_OP_EXCLUSIVE, &op->flags))
+                       object->n_exclusive--;
+               if (test_and_clear_bit(FSCACHE_OP_WAITING, &op->flags))
+                       wake_up_bit(&op->flags, FSCACHE_OP_WAITING);
+               fscache_put_operation(op);
+               ret = 0;
+       }
+
+       spin_unlock(&object->lock);
+       _leave(" = %d", ret);
+       return ret;
+}
+
 /*
  * release an operation
  * - queues pending ops if this is the last in-progress op
@@ -298,6 +338,8 @@ void fscache_put_operation(struct fscache_operation *op)
        if (!atomic_dec_and_test(&op->usage))
                return;
 
+       fscache_set_op_state(op, "Put");
+
        _debug("PUT OP");
        if (test_and_set_bit(FSCACHE_OP_DEAD, &op->flags))
                BUG();
@@ -311,6 +353,9 @@ void fscache_put_operation(struct fscache_operation *op)
 
        object = op->object;
 
+       if (test_bit(FSCACHE_OP_DEC_READ_CNT, &op->flags))
+               atomic_dec(&object->n_reads);
+
        /* now... we may get called with the object spinlock held, so we
         * complete the cleanup here only if we can immediately acquire the
         * lock, and defer it otherwise */
@@ -452,8 +497,27 @@ static void fscache_op_execute(struct slow_work *work)
        _leave("");
 }
 
+/*
+ * describe an operation for slow-work debugging
+ */
+#ifdef CONFIG_SLOW_WORK_PROC
+static void fscache_op_desc(struct slow_work *work, struct seq_file *m)
+{
+       struct fscache_operation *op =
+               container_of(work, struct fscache_operation, slow_work);
+
+       seq_printf(m, "FSC: OBJ%x OP%x: %s/%s fl=%lx",
+                  op->object->debug_id, op->debug_id,
+                  op->name, op->state, op->flags);
+}
+#endif
+
 const struct slow_work_ops fscache_op_slow_work_ops = {
+       .owner          = THIS_MODULE,
        .get_ref        = fscache_op_get_ref,
        .put_ref        = fscache_op_put_ref,
        .execute        = fscache_op_execute,
+#ifdef CONFIG_SLOW_WORK_PROC
+       .desc           = fscache_op_desc,
+#endif
 };
index 2568e0eb644f67453d2acca6e3aac584a513ea2c..c598ea4c4e7d580d9046e1cb8ccb42e1d14db6c6 100644 (file)
@@ -43,18 +43,102 @@ void __fscache_wait_on_page_write(struct fscache_cookie *cookie, struct page *pa
 EXPORT_SYMBOL(__fscache_wait_on_page_write);
 
 /*
- * note that a page has finished being written to the cache
+ * decide whether a page can be released, possibly by cancelling a store to it
+ * - we're allowed to sleep if __GFP_WAIT is flagged
  */
-static void fscache_end_page_write(struct fscache_cookie *cookie, struct page *page)
+bool __fscache_maybe_release_page(struct fscache_cookie *cookie,
+                                 struct page *page,
+                                 gfp_t gfp)
 {
        struct page *xpage;
+       void *val;
+
+       _enter("%p,%p,%x", cookie, page, gfp);
+
+       rcu_read_lock();
+       val = radix_tree_lookup(&cookie->stores, page->index);
+       if (!val) {
+               rcu_read_unlock();
+               fscache_stat(&fscache_n_store_vmscan_not_storing);
+               __fscache_uncache_page(cookie, page);
+               return true;
+       }
+
+       /* see if the page is actually undergoing storage - if so we can't get
+        * rid of it till the cache has finished with it */
+       if (radix_tree_tag_get(&cookie->stores, page->index,
+                              FSCACHE_COOKIE_STORING_TAG)) {
+               rcu_read_unlock();
+               goto page_busy;
+       }
+
+       /* the page is pending storage, so we attempt to cancel the store and
+        * discard the store request so that the page can be reclaimed */
+       spin_lock(&cookie->stores_lock);
+       rcu_read_unlock();
+
+       if (radix_tree_tag_get(&cookie->stores, page->index,
+                              FSCACHE_COOKIE_STORING_TAG)) {
+               /* the page started to undergo storage whilst we were looking,
+                * so now we can only wait or return */
+               spin_unlock(&cookie->stores_lock);
+               goto page_busy;
+       }
 
-       spin_lock(&cookie->lock);
        xpage = radix_tree_delete(&cookie->stores, page->index);
-       spin_unlock(&cookie->lock);
-       ASSERT(xpage != NULL);
+       spin_unlock(&cookie->stores_lock);
+
+       if (xpage) {
+               fscache_stat(&fscache_n_store_vmscan_cancelled);
+               fscache_stat(&fscache_n_store_radix_deletes);
+               ASSERTCMP(xpage, ==, page);
+       } else {
+               fscache_stat(&fscache_n_store_vmscan_gone);
+       }
 
        wake_up_bit(&cookie->flags, 0);
+       if (xpage)
+               page_cache_release(xpage);
+       __fscache_uncache_page(cookie, page);
+       return true;
+
+page_busy:
+       /* we might want to wait here, but that could deadlock the allocator as
+        * the slow-work threads writing to the cache may all end up sleeping
+        * on memory allocation */
+       fscache_stat(&fscache_n_store_vmscan_busy);
+       return false;
+}
+EXPORT_SYMBOL(__fscache_maybe_release_page);
+
+/*
+ * note that a page has finished being written to the cache
+ */
+static void fscache_end_page_write(struct fscache_object *object,
+                                  struct page *page)
+{
+       struct fscache_cookie *cookie;
+       struct page *xpage = NULL;
+
+       spin_lock(&object->lock);
+       cookie = object->cookie;
+       if (cookie) {
+               /* delete the page from the tree if it is now no longer
+                * pending */
+               spin_lock(&cookie->stores_lock);
+               radix_tree_tag_clear(&cookie->stores, page->index,
+                                    FSCACHE_COOKIE_STORING_TAG);
+               if (!radix_tree_tag_get(&cookie->stores, page->index,
+                                       FSCACHE_COOKIE_PENDING_TAG)) {
+                       fscache_stat(&fscache_n_store_radix_deletes);
+                       xpage = radix_tree_delete(&cookie->stores, page->index);
+               }
+               spin_unlock(&cookie->stores_lock);
+               wake_up_bit(&cookie->flags, 0);
+       }
+       spin_unlock(&object->lock);
+       if (xpage)
+               page_cache_release(xpage);
 }
 
 /*
@@ -63,14 +147,21 @@ static void fscache_end_page_write(struct fscache_cookie *cookie, struct page *p
 static void fscache_attr_changed_op(struct fscache_operation *op)
 {
        struct fscache_object *object = op->object;
+       int ret;
 
        _enter("{OBJ%x OP%x}", object->debug_id, op->debug_id);
 
        fscache_stat(&fscache_n_attr_changed_calls);
 
-       if (fscache_object_is_active(object) &&
-           object->cache->ops->attr_changed(object) < 0)
-               fscache_abort_object(object);
+       if (fscache_object_is_active(object)) {
+               fscache_set_op_state(op, "CallFS");
+               fscache_stat(&fscache_n_cop_attr_changed);
+               ret = object->cache->ops->attr_changed(object);
+               fscache_stat_d(&fscache_n_cop_attr_changed);
+               fscache_set_op_state(op, "Done");
+               if (ret < 0)
+                       fscache_abort_object(object);
+       }
 
        _leave("");
 }
@@ -99,6 +190,7 @@ int __fscache_attr_changed(struct fscache_cookie *cookie)
        fscache_operation_init(op, NULL);
        fscache_operation_init_slow(op, fscache_attr_changed_op);
        op->flags = FSCACHE_OP_SLOW | (1 << FSCACHE_OP_EXCLUSIVE);
+       fscache_set_op_name(op, "Attr");
 
        spin_lock(&cookie->lock);
 
@@ -184,6 +276,7 @@ static struct fscache_retrieval *fscache_alloc_retrieval(
        op->start_time  = jiffies;
        INIT_WORK(&op->op.fast_work, fscache_retrieval_work);
        INIT_LIST_HEAD(&op->to_do);
+       fscache_set_op_name(&op->op, "Retr");
        return op;
 }
 
@@ -220,6 +313,43 @@ static int fscache_wait_for_deferred_lookup(struct fscache_cookie *cookie)
        return 0;
 }
 
+/*
+ * wait for an object to become active (or dead)
+ */
+static int fscache_wait_for_retrieval_activation(struct fscache_object *object,
+                                                struct fscache_retrieval *op,
+                                                atomic_t *stat_op_waits,
+                                                atomic_t *stat_object_dead)
+{
+       int ret;
+
+       if (!test_bit(FSCACHE_OP_WAITING, &op->op.flags))
+               goto check_if_dead;
+
+       _debug(">>> WT");
+       fscache_stat(stat_op_waits);
+       if (wait_on_bit(&op->op.flags, FSCACHE_OP_WAITING,
+                       fscache_wait_bit_interruptible,
+                       TASK_INTERRUPTIBLE) < 0) {
+               ret = fscache_cancel_op(&op->op);
+               if (ret == 0)
+                       return -ERESTARTSYS;
+
+               /* it's been removed from the pending queue by another party,
+                * so we should get to run shortly */
+               wait_on_bit(&op->op.flags, FSCACHE_OP_WAITING,
+                           fscache_wait_bit, TASK_UNINTERRUPTIBLE);
+       }
+       _debug("<<< GO");
+
+check_if_dead:
+       if (unlikely(fscache_object_is_dead(object))) {
+               fscache_stat(stat_object_dead);
+               return -ENOBUFS;
+       }
+       return 0;
+}
+
 /*
  * read a page from the cache or allocate a block in which to store it
  * - we return:
@@ -257,6 +387,7 @@ int __fscache_read_or_alloc_page(struct fscache_cookie *cookie,
                _leave(" = -ENOMEM");
                return -ENOMEM;
        }
+       fscache_set_op_name(&op->op, "RetrRA1");
 
        spin_lock(&cookie->lock);
 
@@ -267,6 +398,9 @@ int __fscache_read_or_alloc_page(struct fscache_cookie *cookie,
 
        ASSERTCMP(object->state, >, FSCACHE_OBJECT_LOOKING_UP);
 
+       atomic_inc(&object->n_reads);
+       set_bit(FSCACHE_OP_DEC_READ_CNT, &op->op.flags);
+
        if (fscache_submit_op(object, &op->op) < 0)
                goto nobufs_unlock;
        spin_unlock(&cookie->lock);
@@ -279,23 +413,27 @@ int __fscache_read_or_alloc_page(struct fscache_cookie *cookie,
 
        /* we wait for the operation to become active, and then process it
         * *here*, in this thread, and not in the thread pool */
-       if (test_bit(FSCACHE_OP_WAITING, &op->op.flags)) {
-               _debug(">>> WT");
-               fscache_stat(&fscache_n_retrieval_op_waits);
-               wait_on_bit(&op->op.flags, FSCACHE_OP_WAITING,
-                           fscache_wait_bit, TASK_UNINTERRUPTIBLE);
-               _debug("<<< GO");
-       }
+       ret = fscache_wait_for_retrieval_activation(
+               object, op,
+               __fscache_stat(&fscache_n_retrieval_op_waits),
+               __fscache_stat(&fscache_n_retrievals_object_dead));
+       if (ret < 0)
+               goto error;
 
        /* ask the cache to honour the operation */
        if (test_bit(FSCACHE_COOKIE_NO_DATA_YET, &object->cookie->flags)) {
+               fscache_stat(&fscache_n_cop_allocate_page);
                ret = object->cache->ops->allocate_page(op, page, gfp);
+               fscache_stat_d(&fscache_n_cop_allocate_page);
                if (ret == 0)
                        ret = -ENODATA;
        } else {
+               fscache_stat(&fscache_n_cop_read_or_alloc_page);
                ret = object->cache->ops->read_or_alloc_page(op, page, gfp);
+               fscache_stat_d(&fscache_n_cop_read_or_alloc_page);
        }
 
+error:
        if (ret == -ENOMEM)
                fscache_stat(&fscache_n_retrievals_nomem);
        else if (ret == -ERESTARTSYS)
@@ -347,7 +485,6 @@ int __fscache_read_or_alloc_pages(struct fscache_cookie *cookie,
                                  void *context,
                                  gfp_t gfp)
 {
-       fscache_pages_retrieval_func_t func;
        struct fscache_retrieval *op;
        struct fscache_object *object;
        int ret;
@@ -369,6 +506,7 @@ int __fscache_read_or_alloc_pages(struct fscache_cookie *cookie,
        op = fscache_alloc_retrieval(mapping, end_io_func, context);
        if (!op)
                return -ENOMEM;
+       fscache_set_op_name(&op->op, "RetrRAN");
 
        spin_lock(&cookie->lock);
 
@@ -377,6 +515,9 @@ int __fscache_read_or_alloc_pages(struct fscache_cookie *cookie,
        object = hlist_entry(cookie->backing_objects.first,
                             struct fscache_object, cookie_link);
 
+       atomic_inc(&object->n_reads);
+       set_bit(FSCACHE_OP_DEC_READ_CNT, &op->op.flags);
+
        if (fscache_submit_op(object, &op->op) < 0)
                goto nobufs_unlock;
        spin_unlock(&cookie->lock);
@@ -389,21 +530,27 @@ int __fscache_read_or_alloc_pages(struct fscache_cookie *cookie,
 
        /* we wait for the operation to become active, and then process it
         * *here*, in this thread, and not in the thread pool */
-       if (test_bit(FSCACHE_OP_WAITING, &op->op.flags)) {
-               _debug(">>> WT");
-               fscache_stat(&fscache_n_retrieval_op_waits);
-               wait_on_bit(&op->op.flags, FSCACHE_OP_WAITING,
-                           fscache_wait_bit, TASK_UNINTERRUPTIBLE);
-               _debug("<<< GO");
-       }
+       ret = fscache_wait_for_retrieval_activation(
+               object, op,
+               __fscache_stat(&fscache_n_retrieval_op_waits),
+               __fscache_stat(&fscache_n_retrievals_object_dead));
+       if (ret < 0)
+               goto error;
 
        /* ask the cache to honour the operation */
-       if (test_bit(FSCACHE_COOKIE_NO_DATA_YET, &object->cookie->flags))
-               func = object->cache->ops->allocate_pages;
-       else
-               func = object->cache->ops->read_or_alloc_pages;
-       ret = func(op, pages, nr_pages, gfp);
+       if (test_bit(FSCACHE_COOKIE_NO_DATA_YET, &object->cookie->flags)) {
+               fscache_stat(&fscache_n_cop_allocate_pages);
+               ret = object->cache->ops->allocate_pages(
+                       op, pages, nr_pages, gfp);
+               fscache_stat_d(&fscache_n_cop_allocate_pages);
+       } else {
+               fscache_stat(&fscache_n_cop_read_or_alloc_pages);
+               ret = object->cache->ops->read_or_alloc_pages(
+                       op, pages, nr_pages, gfp);
+               fscache_stat_d(&fscache_n_cop_read_or_alloc_pages);
+       }
 
+error:
        if (ret == -ENOMEM)
                fscache_stat(&fscache_n_retrievals_nomem);
        else if (ret == -ERESTARTSYS)
@@ -461,6 +608,7 @@ int __fscache_alloc_page(struct fscache_cookie *cookie,
        op = fscache_alloc_retrieval(page->mapping, NULL, NULL);
        if (!op)
                return -ENOMEM;
+       fscache_set_op_name(&op->op, "RetrAL1");
 
        spin_lock(&cookie->lock);
 
@@ -475,18 +623,22 @@ int __fscache_alloc_page(struct fscache_cookie *cookie,
 
        fscache_stat(&fscache_n_alloc_ops);
 
-       if (test_bit(FSCACHE_OP_WAITING, &op->op.flags)) {
-               _debug(">>> WT");
-               fscache_stat(&fscache_n_alloc_op_waits);
-               wait_on_bit(&op->op.flags, FSCACHE_OP_WAITING,
-                           fscache_wait_bit, TASK_UNINTERRUPTIBLE);
-               _debug("<<< GO");
-       }
+       ret = fscache_wait_for_retrieval_activation(
+               object, op,
+               __fscache_stat(&fscache_n_alloc_op_waits),
+               __fscache_stat(&fscache_n_allocs_object_dead));
+       if (ret < 0)
+               goto error;
 
        /* ask the cache to honour the operation */
+       fscache_stat(&fscache_n_cop_allocate_page);
        ret = object->cache->ops->allocate_page(op, page, gfp);
+       fscache_stat_d(&fscache_n_cop_allocate_page);
 
-       if (ret < 0)
+error:
+       if (ret == -ERESTARTSYS)
+               fscache_stat(&fscache_n_allocs_intr);
+       else if (ret < 0)
                fscache_stat(&fscache_n_allocs_nobufs);
        else
                fscache_stat(&fscache_n_allocs_ok);
@@ -521,7 +673,7 @@ static void fscache_write_op(struct fscache_operation *_op)
        struct fscache_storage *op =
                container_of(_op, struct fscache_storage, op);
        struct fscache_object *object = op->op.object;
-       struct fscache_cookie *cookie = object->cookie;
+       struct fscache_cookie *cookie;
        struct page *page;
        unsigned n;
        void *results[1];
@@ -529,16 +681,19 @@ static void fscache_write_op(struct fscache_operation *_op)
 
        _enter("{OP%x,%d}", op->op.debug_id, atomic_read(&op->op.usage));
 
-       spin_lock(&cookie->lock);
+       fscache_set_op_state(&op->op, "GetPage");
+
        spin_lock(&object->lock);
+       cookie = object->cookie;
 
-       if (!fscache_object_is_active(object)) {
+       if (!fscache_object_is_active(object) || !cookie) {
                spin_unlock(&object->lock);
-               spin_unlock(&cookie->lock);
                _leave("");
                return;
        }
 
+       spin_lock(&cookie->stores_lock);
+
        fscache_stat(&fscache_n_store_calls);
 
        /* find a page to store */
@@ -549,23 +704,35 @@ static void fscache_write_op(struct fscache_operation *_op)
                goto superseded;
        page = results[0];
        _debug("gang %d [%lx]", n, page->index);
-       if (page->index > op->store_limit)
+       if (page->index > op->store_limit) {
+               fscache_stat(&fscache_n_store_pages_over_limit);
                goto superseded;
+       }
 
-       radix_tree_tag_clear(&cookie->stores, page->index,
-                            FSCACHE_COOKIE_PENDING_TAG);
+       if (page) {
+               radix_tree_tag_set(&cookie->stores, page->index,
+                                  FSCACHE_COOKIE_STORING_TAG);
+               radix_tree_tag_clear(&cookie->stores, page->index,
+                                    FSCACHE_COOKIE_PENDING_TAG);
+       }
 
+       spin_unlock(&cookie->stores_lock);
        spin_unlock(&object->lock);
-       spin_unlock(&cookie->lock);
 
        if (page) {
+               fscache_set_op_state(&op->op, "Store");
+               fscache_stat(&fscache_n_store_pages);
+               fscache_stat(&fscache_n_cop_write_page);
                ret = object->cache->ops->write_page(op, page);
-               fscache_end_page_write(cookie, page);
-               page_cache_release(page);
-               if (ret < 0)
+               fscache_stat_d(&fscache_n_cop_write_page);
+               fscache_set_op_state(&op->op, "EndWrite");
+               fscache_end_page_write(object, page);
+               if (ret < 0) {
+                       fscache_set_op_state(&op->op, "Abort");
                        fscache_abort_object(object);
-               else
+               } else {
                        fscache_enqueue_operation(&op->op);
+               }
        }
 
        _leave("");
@@ -575,9 +742,9 @@ superseded:
        /* this writer is going away and there aren't any more things to
         * write */
        _debug("cease");
+       spin_unlock(&cookie->stores_lock);
        clear_bit(FSCACHE_OBJECT_PENDING_WRITE, &object->flags);
        spin_unlock(&object->lock);
-       spin_unlock(&cookie->lock);
        _leave("");
 }
 
@@ -634,6 +801,7 @@ int __fscache_write_page(struct fscache_cookie *cookie,
        fscache_operation_init(&op->op, fscache_release_write_op);
        fscache_operation_init_slow(&op->op, fscache_write_op);
        op->op.flags = FSCACHE_OP_SLOW | (1 << FSCACHE_OP_WAITING);
+       fscache_set_op_name(&op->op, "Write1");
 
        ret = radix_tree_preload(gfp & ~__GFP_HIGHMEM);
        if (ret < 0)
@@ -652,6 +820,7 @@ int __fscache_write_page(struct fscache_cookie *cookie,
        /* add the page to the pending-storage radix tree on the backing
         * object */
        spin_lock(&object->lock);
+       spin_lock(&cookie->stores_lock);
 
        _debug("store limit %llx", (unsigned long long) object->store_limit);
 
@@ -672,6 +841,7 @@ int __fscache_write_page(struct fscache_cookie *cookie,
        if (test_and_set_bit(FSCACHE_OBJECT_PENDING_WRITE, &object->flags))
                goto already_pending;
 
+       spin_unlock(&cookie->stores_lock);
        spin_unlock(&object->lock);
 
        op->op.debug_id = atomic_inc_return(&fscache_op_debug_id);
@@ -693,6 +863,7 @@ int __fscache_write_page(struct fscache_cookie *cookie,
 already_queued:
        fscache_stat(&fscache_n_stores_again);
 already_pending:
+       spin_unlock(&cookie->stores_lock);
        spin_unlock(&object->lock);
        spin_unlock(&cookie->lock);
        radix_tree_preload_end();
@@ -702,7 +873,9 @@ already_pending:
        return 0;
 
 submit_failed:
+       spin_lock(&cookie->stores_lock);
        radix_tree_delete(&cookie->stores, page->index);
+       spin_unlock(&cookie->stores_lock);
        page_cache_release(page);
        ret = -ENOBUFS;
        goto nobufs;
@@ -763,7 +936,9 @@ void __fscache_uncache_page(struct fscache_cookie *cookie, struct page *page)
        if (TestClearPageFsCache(page) &&
            object->cache->ops->uncache_page) {
                /* the cache backend releases the cookie lock */
+               fscache_stat(&fscache_n_cop_uncache_page);
                object->cache->ops->uncache_page(object, page);
+               fscache_stat_d(&fscache_n_cop_uncache_page);
                goto done;
        }
 
index beeab44bc31a2f987267c898150244c7dee0e9a2..1d9e4951a5979817951eb81180f037a01ef0a026 100644 (file)
@@ -37,10 +37,20 @@ int __init fscache_proc_init(void)
                goto error_histogram;
 #endif
 
+#ifdef CONFIG_FSCACHE_OBJECT_LIST
+       if (!proc_create("fs/fscache/objects", S_IFREG | 0444, NULL,
+                        &fscache_objlist_fops))
+               goto error_objects;
+#endif
+
        _leave(" = 0");
        return 0;
 
+#ifdef CONFIG_FSCACHE_OBJECT_LIST
+error_objects:
+#endif
 #ifdef CONFIG_FSCACHE_HISTOGRAM
+       remove_proc_entry("fs/fscache/histogram", NULL);
 error_histogram:
 #endif
 #ifdef CONFIG_FSCACHE_STATS
@@ -58,6 +68,9 @@ error_dir:
  */
 void fscache_proc_cleanup(void)
 {
+#ifdef CONFIG_FSCACHE_OBJECT_LIST
+       remove_proc_entry("fs/fscache/objects", NULL);
+#endif
 #ifdef CONFIG_FSCACHE_HISTOGRAM
        remove_proc_entry("fs/fscache/histogram", NULL);
 #endif
index 65deb99e756b023836d1b71728aa7162d72e98ee..46435f3aae689936404bf1ecd5e3c6d6094a214b 100644 (file)
@@ -25,6 +25,8 @@ atomic_t fscache_n_op_requeue;
 atomic_t fscache_n_op_deferred_release;
 atomic_t fscache_n_op_release;
 atomic_t fscache_n_op_gc;
+atomic_t fscache_n_op_cancelled;
+atomic_t fscache_n_op_rejected;
 
 atomic_t fscache_n_attr_changed;
 atomic_t fscache_n_attr_changed_ok;
@@ -36,6 +38,8 @@ atomic_t fscache_n_allocs;
 atomic_t fscache_n_allocs_ok;
 atomic_t fscache_n_allocs_wait;
 atomic_t fscache_n_allocs_nobufs;
+atomic_t fscache_n_allocs_intr;
+atomic_t fscache_n_allocs_object_dead;
 atomic_t fscache_n_alloc_ops;
 atomic_t fscache_n_alloc_op_waits;
 
@@ -46,6 +50,7 @@ atomic_t fscache_n_retrievals_nodata;
 atomic_t fscache_n_retrievals_nobufs;
 atomic_t fscache_n_retrievals_intr;
 atomic_t fscache_n_retrievals_nomem;
+atomic_t fscache_n_retrievals_object_dead;
 atomic_t fscache_n_retrieval_ops;
 atomic_t fscache_n_retrieval_op_waits;
 
@@ -56,6 +61,14 @@ atomic_t fscache_n_stores_nobufs;
 atomic_t fscache_n_stores_oom;
 atomic_t fscache_n_store_ops;
 atomic_t fscache_n_store_calls;
+atomic_t fscache_n_store_pages;
+atomic_t fscache_n_store_radix_deletes;
+atomic_t fscache_n_store_pages_over_limit;
+
+atomic_t fscache_n_store_vmscan_not_storing;
+atomic_t fscache_n_store_vmscan_gone;
+atomic_t fscache_n_store_vmscan_busy;
+atomic_t fscache_n_store_vmscan_cancelled;
 
 atomic_t fscache_n_marks;
 atomic_t fscache_n_uncaches;
@@ -74,6 +87,7 @@ atomic_t fscache_n_updates_run;
 atomic_t fscache_n_relinquishes;
 atomic_t fscache_n_relinquishes_null;
 atomic_t fscache_n_relinquishes_waitcrt;
+atomic_t fscache_n_relinquishes_retire;
 
 atomic_t fscache_n_cookie_index;
 atomic_t fscache_n_cookie_data;
@@ -84,6 +98,7 @@ atomic_t fscache_n_object_no_alloc;
 atomic_t fscache_n_object_lookups;
 atomic_t fscache_n_object_lookups_negative;
 atomic_t fscache_n_object_lookups_positive;
+atomic_t fscache_n_object_lookups_timed_out;
 atomic_t fscache_n_object_created;
 atomic_t fscache_n_object_avail;
 atomic_t fscache_n_object_dead;
@@ -93,6 +108,23 @@ atomic_t fscache_n_checkaux_okay;
 atomic_t fscache_n_checkaux_update;
 atomic_t fscache_n_checkaux_obsolete;
 
+atomic_t fscache_n_cop_alloc_object;
+atomic_t fscache_n_cop_lookup_object;
+atomic_t fscache_n_cop_lookup_complete;
+atomic_t fscache_n_cop_grab_object;
+atomic_t fscache_n_cop_update_object;
+atomic_t fscache_n_cop_drop_object;
+atomic_t fscache_n_cop_put_object;
+atomic_t fscache_n_cop_sync_cache;
+atomic_t fscache_n_cop_attr_changed;
+atomic_t fscache_n_cop_read_or_alloc_page;
+atomic_t fscache_n_cop_read_or_alloc_pages;
+atomic_t fscache_n_cop_allocate_page;
+atomic_t fscache_n_cop_allocate_pages;
+atomic_t fscache_n_cop_write_page;
+atomic_t fscache_n_cop_uncache_page;
+atomic_t fscache_n_cop_dissociate_pages;
+
 /*
  * display the general statistics
  */
@@ -129,10 +161,11 @@ static int fscache_stats_show(struct seq_file *m, void *v)
                   atomic_read(&fscache_n_acquires_nobufs),
                   atomic_read(&fscache_n_acquires_oom));
 
-       seq_printf(m, "Lookups: n=%u neg=%u pos=%u crt=%u\n",
+       seq_printf(m, "Lookups: n=%u neg=%u pos=%u crt=%u tmo=%u\n",
                   atomic_read(&fscache_n_object_lookups),
                   atomic_read(&fscache_n_object_lookups_negative),
                   atomic_read(&fscache_n_object_lookups_positive),
+                  atomic_read(&fscache_n_object_lookups_timed_out),
                   atomic_read(&fscache_n_object_created));
 
        seq_printf(m, "Updates: n=%u nul=%u run=%u\n",
@@ -140,10 +173,11 @@ static int fscache_stats_show(struct seq_file *m, void *v)
                   atomic_read(&fscache_n_updates_null),
                   atomic_read(&fscache_n_updates_run));
 
-       seq_printf(m, "Relinqs: n=%u nul=%u wcr=%u\n",
+       seq_printf(m, "Relinqs: n=%u nul=%u wcr=%u rtr=%u\n",
                   atomic_read(&fscache_n_relinquishes),
                   atomic_read(&fscache_n_relinquishes_null),
-                  atomic_read(&fscache_n_relinquishes_waitcrt));
+                  atomic_read(&fscache_n_relinquishes_waitcrt),
+                  atomic_read(&fscache_n_relinquishes_retire));
 
        seq_printf(m, "AttrChg: n=%u ok=%u nbf=%u oom=%u run=%u\n",
                   atomic_read(&fscache_n_attr_changed),
@@ -152,14 +186,16 @@ static int fscache_stats_show(struct seq_file *m, void *v)
                   atomic_read(&fscache_n_attr_changed_nomem),
                   atomic_read(&fscache_n_attr_changed_calls));
 
-       seq_printf(m, "Allocs : n=%u ok=%u wt=%u nbf=%u\n",
+       seq_printf(m, "Allocs : n=%u ok=%u wt=%u nbf=%u int=%u\n",
                   atomic_read(&fscache_n_allocs),
                   atomic_read(&fscache_n_allocs_ok),
                   atomic_read(&fscache_n_allocs_wait),
-                  atomic_read(&fscache_n_allocs_nobufs));
-       seq_printf(m, "Allocs : ops=%u owt=%u\n",
+                  atomic_read(&fscache_n_allocs_nobufs),
+                  atomic_read(&fscache_n_allocs_intr));
+       seq_printf(m, "Allocs : ops=%u owt=%u abt=%u\n",
                   atomic_read(&fscache_n_alloc_ops),
-                  atomic_read(&fscache_n_alloc_op_waits));
+                  atomic_read(&fscache_n_alloc_op_waits),
+                  atomic_read(&fscache_n_allocs_object_dead));
 
        seq_printf(m, "Retrvls: n=%u ok=%u wt=%u nod=%u nbf=%u"
                   " int=%u oom=%u\n",
@@ -170,9 +206,10 @@ static int fscache_stats_show(struct seq_file *m, void *v)
                   atomic_read(&fscache_n_retrievals_nobufs),
                   atomic_read(&fscache_n_retrievals_intr),
                   atomic_read(&fscache_n_retrievals_nomem));
-       seq_printf(m, "Retrvls: ops=%u owt=%u\n",
+       seq_printf(m, "Retrvls: ops=%u owt=%u abt=%u\n",
                   atomic_read(&fscache_n_retrieval_ops),
-                  atomic_read(&fscache_n_retrieval_op_waits));
+                  atomic_read(&fscache_n_retrieval_op_waits),
+                  atomic_read(&fscache_n_retrievals_object_dead));
 
        seq_printf(m, "Stores : n=%u ok=%u agn=%u nbf=%u oom=%u\n",
                   atomic_read(&fscache_n_stores),
@@ -180,18 +217,49 @@ static int fscache_stats_show(struct seq_file *m, void *v)
                   atomic_read(&fscache_n_stores_again),
                   atomic_read(&fscache_n_stores_nobufs),
                   atomic_read(&fscache_n_stores_oom));
-       seq_printf(m, "Stores : ops=%u run=%u\n",
+       seq_printf(m, "Stores : ops=%u run=%u pgs=%u rxd=%u olm=%u\n",
                   atomic_read(&fscache_n_store_ops),
-                  atomic_read(&fscache_n_store_calls));
+                  atomic_read(&fscache_n_store_calls),
+                  atomic_read(&fscache_n_store_pages),
+                  atomic_read(&fscache_n_store_radix_deletes),
+                  atomic_read(&fscache_n_store_pages_over_limit));
 
-       seq_printf(m, "Ops    : pend=%u run=%u enq=%u\n",
+       seq_printf(m, "VmScan : nos=%u gon=%u bsy=%u can=%u\n",
+                  atomic_read(&fscache_n_store_vmscan_not_storing),
+                  atomic_read(&fscache_n_store_vmscan_gone),
+                  atomic_read(&fscache_n_store_vmscan_busy),
+                  atomic_read(&fscache_n_store_vmscan_cancelled));
+
+       seq_printf(m, "Ops    : pend=%u run=%u enq=%u can=%u rej=%u\n",
                   atomic_read(&fscache_n_op_pend),
                   atomic_read(&fscache_n_op_run),
-                  atomic_read(&fscache_n_op_enqueue));
+                  atomic_read(&fscache_n_op_enqueue),
+                  atomic_read(&fscache_n_op_cancelled),
+                  atomic_read(&fscache_n_op_rejected));
        seq_printf(m, "Ops    : dfr=%u rel=%u gc=%u\n",
                   atomic_read(&fscache_n_op_deferred_release),
                   atomic_read(&fscache_n_op_release),
                   atomic_read(&fscache_n_op_gc));
+
+       seq_printf(m, "CacheOp: alo=%d luo=%d luc=%d gro=%d\n",
+                  atomic_read(&fscache_n_cop_alloc_object),
+                  atomic_read(&fscache_n_cop_lookup_object),
+                  atomic_read(&fscache_n_cop_lookup_complete),
+                  atomic_read(&fscache_n_cop_grab_object));
+       seq_printf(m, "CacheOp: upo=%d dro=%d pto=%d atc=%d syn=%d\n",
+                  atomic_read(&fscache_n_cop_update_object),
+                  atomic_read(&fscache_n_cop_drop_object),
+                  atomic_read(&fscache_n_cop_put_object),
+                  atomic_read(&fscache_n_cop_attr_changed),
+                  atomic_read(&fscache_n_cop_sync_cache));
+       seq_printf(m, "CacheOp: rap=%d ras=%d alp=%d als=%d wrp=%d ucp=%d dsp=%d\n",
+                  atomic_read(&fscache_n_cop_read_or_alloc_page),
+                  atomic_read(&fscache_n_cop_read_or_alloc_pages),
+                  atomic_read(&fscache_n_cop_allocate_page),
+                  atomic_read(&fscache_n_cop_allocate_pages),
+                  atomic_read(&fscache_n_cop_write_page),
+                  atomic_read(&fscache_n_cop_uncache_page),
+                  atomic_read(&fscache_n_cop_dissociate_pages));
        return 0;
 }
 
index 8ada78aade58353d67b3fb161fb63fedd39f8ad7..4787ae6c5c1c5aac632c871502ca4a99823dd3bb 100644 (file)
@@ -385,6 +385,9 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode,
        if (fc->no_create)
                return -ENOSYS;
 
+       if (flags & O_DIRECT)
+               return -EINVAL;
+
        forget_req = fuse_get_req(fc);
        if (IS_ERR(forget_req))
                return PTR_ERR(forget_req);
index 5971359d2090d2107f6b96c27255c39c08420ea4..4dcddf83326f45f7dd874587ef915b7844d60b0b 100644 (file)
@@ -8,6 +8,8 @@ config GFS2_FS
        select FS_POSIX_ACL
        select CRC32
        select SLOW_WORK
+       select QUOTA
+       select QUOTACTL
        help
          A cluster filesystem.
 
index 3fc4e3ac7d84efdc76b4ddbae91f82f90f8c257d..3eb1ea846173548a7bf266936deae21296fad9ad 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/spinlock.h>
 #include <linux/completion.h>
 #include <linux/buffer_head.h>
+#include <linux/xattr.h>
 #include <linux/posix_acl.h>
 #include <linux/posix_acl_xattr.h>
 #include <linux/gfs2_ondisk.h>
 #include "trans.h"
 #include "util.h"
 
-#define ACL_ACCESS 1
-#define ACL_DEFAULT 0
-
-int gfs2_acl_validate_set(struct gfs2_inode *ip, int access,
-                         struct gfs2_ea_request *er, int *remove, mode_t *mode)
+static const char *gfs2_acl_name(int type)
 {
-       struct posix_acl *acl;
-       int error;
-
-       error = gfs2_acl_validate_remove(ip, access);
-       if (error)
-               return error;
-
-       if (!er->er_data)
-               return -EINVAL;
-
-       acl = posix_acl_from_xattr(er->er_data, er->er_data_len);
-       if (IS_ERR(acl))
-               return PTR_ERR(acl);
-       if (!acl) {
-               *remove = 1;
-               return 0;
-       }
-
-       error = posix_acl_valid(acl);
-       if (error)
-               goto out;
-
-       if (access) {
-               error = posix_acl_equiv_mode(acl, mode);
-               if (!error)
-                       *remove = 1;
-               else if (error > 0)
-                       error = 0;
+       switch (type) {
+       case ACL_TYPE_ACCESS:
+               return GFS2_POSIX_ACL_ACCESS;
+       case ACL_TYPE_DEFAULT:
+               return GFS2_POSIX_ACL_DEFAULT;
        }
-
-out:
-       posix_acl_release(acl);
-       return error;
-}
-
-int gfs2_acl_validate_remove(struct gfs2_inode *ip, int access)
-{
-       if (!GFS2_SB(&ip->i_inode)->sd_args.ar_posix_acl)
-               return -EOPNOTSUPP;
-       if (!is_owner_or_cap(&ip->i_inode))
-               return -EPERM;
-       if (S_ISLNK(ip->i_inode.i_mode))
-               return -EOPNOTSUPP;
-       if (!access && !S_ISDIR(ip->i_inode.i_mode))
-               return -EACCES;
-
-       return 0;
+       return NULL;
 }
 
-static int acl_get(struct gfs2_inode *ip, const char *name,
-                  struct posix_acl **acl, struct gfs2_ea_location *el,
-                  char **datap, unsigned int *lenp)
+static struct posix_acl *gfs2_acl_get(struct gfs2_inode *ip, int type)
 {
+       struct posix_acl *acl;
+       const char *name;
        char *data;
-       unsigned int len;
-       int error;
-
-       el->el_bh = NULL;
+       int len;
 
        if (!ip->i_eattr)
-               return 0;
-
-       error = gfs2_ea_find(ip, GFS2_EATYPE_SYS, name, el);
-       if (error)
-               return error;
-       if (!el->el_ea)
-               return 0;
-       if (!GFS2_EA_DATA_LEN(el->el_ea))
-               goto out;
+               return NULL;
 
-       len = GFS2_EA_DATA_LEN(el->el_ea);
-       data = kmalloc(len, GFP_NOFS);
-       error = -ENOMEM;
-       if (!data)
-               goto out;
+       acl = get_cached_acl(&ip->i_inode, type);
+       if (acl != ACL_NOT_CACHED)
+               return acl;
 
-       error = gfs2_ea_get_copy(ip, el, data, len);
-       if (error < 0)
-               goto out_kfree;
-       error = 0;
+       name = gfs2_acl_name(type);
+       if (name == NULL)
+               return ERR_PTR(-EINVAL);
 
-       if (acl) {
-               *acl = posix_acl_from_xattr(data, len);
-               if (IS_ERR(*acl))
-                       error = PTR_ERR(*acl);
-       }
+       len = gfs2_xattr_acl_get(ip, name, &data);
+       if (len < 0)
+               return ERR_PTR(len);
+       if (len == 0)
+               return NULL;
 
-out_kfree:
-       if (error || !datap) {
-               kfree(data);
-       } else {
-               *datap = data;
-               *lenp = len;
-       }
-out:
-       return error;
+       acl = posix_acl_from_xattr(data, len);
+       kfree(data);
+       return acl;
 }
 
 /**
@@ -140,14 +77,12 @@ out:
 
 int gfs2_check_acl(struct inode *inode, int mask)
 {
-       struct gfs2_ea_location el;
-       struct posix_acl *acl = NULL;
+       struct posix_acl *acl;
        int error;
 
-       error = acl_get(GFS2_I(inode), GFS2_POSIX_ACL_ACCESS, &acl, &el, NULL, NULL);
-       brelse(el.el_bh);
-       if (error)
-               return error;
+       acl = gfs2_acl_get(GFS2_I(inode), ACL_TYPE_ACCESS);
+       if (IS_ERR(acl))
+               return PTR_ERR(acl);
 
        if (acl) {
                error = posix_acl_permission(inode, acl, mask);
@@ -158,57 +93,75 @@ int gfs2_check_acl(struct inode *inode, int mask)
        return -EAGAIN;
 }
 
-static int munge_mode(struct gfs2_inode *ip, mode_t mode)
+static int gfs2_set_mode(struct inode *inode, mode_t mode)
 {
-       struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
-       struct buffer_head *dibh;
-       int error;
+       int error = 0;
 
-       error = gfs2_trans_begin(sdp, RES_DINODE, 0);
-       if (error)
-               return error;
+       if (mode != inode->i_mode) {
+               struct iattr iattr;
 
-       error = gfs2_meta_inode_buffer(ip, &dibh);
-       if (!error) {
-               gfs2_assert_withdraw(sdp,
-                               (ip->i_inode.i_mode & S_IFMT) == (mode & S_IFMT));
-               ip->i_inode.i_mode = mode;
-               gfs2_trans_add_bh(ip->i_gl, dibh, 1);
-               gfs2_dinode_out(ip, dibh->b_data);
-               brelse(dibh);
+               iattr.ia_valid = ATTR_MODE;
+               iattr.ia_mode = mode;
+
+               error = gfs2_setattr_simple(GFS2_I(inode), &iattr);
        }
 
-       gfs2_trans_end(sdp);
+       return error;
+}
+
+static int gfs2_acl_set(struct inode *inode, int type, struct posix_acl *acl)
+{
+       int error;
+       int len;
+       char *data;
+       const char *name = gfs2_acl_name(type);
 
-       return 0;
+       BUG_ON(name == NULL);
+       len = posix_acl_to_xattr(acl, NULL, 0);
+       if (len == 0)
+               return 0;
+       data = kmalloc(len, GFP_NOFS);
+       if (data == NULL)
+               return -ENOMEM;
+       error = posix_acl_to_xattr(acl, data, len);
+       if (error < 0)
+               goto out;
+       error = gfs2_xattr_set(inode, GFS2_EATYPE_SYS, name, data, len, 0);
+       if (!error)
+               set_cached_acl(inode, type, acl);
+out:
+       kfree(data);
+       return error;
 }
 
-int gfs2_acl_create(struct gfs2_inode *dip, struct gfs2_inode *ip)
+int gfs2_acl_create(struct gfs2_inode *dip, struct inode *inode)
 {
-       struct gfs2_ea_location el;
        struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode);
-       struct posix_acl *acl = NULL, *clone;
-       mode_t mode = ip->i_inode.i_mode;
-       char *data = NULL;
-       unsigned int len;
-       int error;
+       struct posix_acl *acl, *clone;
+       mode_t mode = inode->i_mode;
+       int error = 0;
 
        if (!sdp->sd_args.ar_posix_acl)
                return 0;
-       if (S_ISLNK(ip->i_inode.i_mode))
+       if (S_ISLNK(inode->i_mode))
                return 0;
 
-       error = acl_get(dip, GFS2_POSIX_ACL_DEFAULT, &acl, &el, &data, &len);
-       brelse(el.el_bh);
-       if (error)
-               return error;
+       acl = gfs2_acl_get(dip, ACL_TYPE_DEFAULT);
+       if (IS_ERR(acl))
+               return PTR_ERR(acl);
        if (!acl) {
                mode &= ~current_umask();
-               if (mode != ip->i_inode.i_mode)
-                       error = munge_mode(ip, mode);
+               if (mode != inode->i_mode)
+                       error = gfs2_set_mode(inode, mode);
                return error;
        }
 
+       if (S_ISDIR(inode->i_mode)) {
+               error = gfs2_acl_set(inode, ACL_TYPE_DEFAULT, acl);
+               if (error)
+                       goto out;
+       }
+
        clone = posix_acl_clone(acl, GFP_NOFS);
        error = -ENOMEM;
        if (!clone)
@@ -216,43 +169,32 @@ int gfs2_acl_create(struct gfs2_inode *dip, struct gfs2_inode *ip)
        posix_acl_release(acl);
        acl = clone;
 
-       if (S_ISDIR(ip->i_inode.i_mode)) {
-               error = gfs2_xattr_set(&ip->i_inode, GFS2_EATYPE_SYS,
-                                      GFS2_POSIX_ACL_DEFAULT, data, len, 0);
-               if (error)
-                       goto out;
-       }
-
        error = posix_acl_create_masq(acl, &mode);
        if (error < 0)
                goto out;
        if (error == 0)
                goto munge;
 
-       posix_acl_to_xattr(acl, data, len);
-       error = gfs2_xattr_set(&ip->i_inode, GFS2_EATYPE_SYS,
-                              GFS2_POSIX_ACL_ACCESS, data, len, 0);
+       error = gfs2_acl_set(inode, ACL_TYPE_ACCESS, acl);
        if (error)
                goto out;
 munge:
-       error = munge_mode(ip, mode);
+       error = gfs2_set_mode(inode, mode);
 out:
        posix_acl_release(acl);
-       kfree(data);
        return error;
 }
 
 int gfs2_acl_chmod(struct gfs2_inode *ip, struct iattr *attr)
 {
-       struct posix_acl *acl = NULL, *clone;
-       struct gfs2_ea_location el;
+       struct posix_acl *acl, *clone;
        char *data;
        unsigned int len;
        int error;
 
-       error = acl_get(ip, GFS2_POSIX_ACL_ACCESS, &acl, &el, &data, &len);
-       if (error)
-               goto out_brelse;
+       acl = gfs2_acl_get(ip, ACL_TYPE_ACCESS);
+       if (IS_ERR(acl))
+               return PTR_ERR(acl);
        if (!acl)
                return gfs2_setattr_simple(ip, attr);
 
@@ -265,15 +207,134 @@ int gfs2_acl_chmod(struct gfs2_inode *ip, struct iattr *attr)
 
        error = posix_acl_chmod_masq(acl, attr->ia_mode);
        if (!error) {
+               len = posix_acl_to_xattr(acl, NULL, 0);
+               data = kmalloc(len, GFP_NOFS);
+               error = -ENOMEM;
+               if (data == NULL)
+                       goto out;
                posix_acl_to_xattr(acl, data, len);
-               error = gfs2_ea_acl_chmod(ip, &el, attr, data);
+               error = gfs2_xattr_acl_chmod(ip, attr, data);
+               kfree(data);
+               set_cached_acl(&ip->i_inode, ACL_TYPE_ACCESS, acl);
        }
 
 out:
        posix_acl_release(acl);
-       kfree(data);
-out_brelse:
-       brelse(el.el_bh);
        return error;
 }
 
+static int gfs2_acl_type(const char *name)
+{
+       if (strcmp(name, GFS2_POSIX_ACL_ACCESS) == 0)
+               return ACL_TYPE_ACCESS;
+       if (strcmp(name, GFS2_POSIX_ACL_DEFAULT) == 0)
+               return ACL_TYPE_DEFAULT;
+       return -EINVAL;
+}
+
+static int gfs2_xattr_system_get(struct inode *inode, const char *name,
+                                void *buffer, size_t size)
+{
+       struct posix_acl *acl;
+       int type;
+       int error;
+
+       type = gfs2_acl_type(name);
+       if (type < 0)
+               return type;
+
+       acl = gfs2_acl_get(GFS2_I(inode), type);
+       if (IS_ERR(acl))
+               return PTR_ERR(acl);
+       if (acl == NULL)
+               return -ENODATA;
+
+       error = posix_acl_to_xattr(acl, buffer, size);
+       posix_acl_release(acl);
+
+       return error;
+}
+
+static int gfs2_xattr_system_set(struct inode *inode, const char *name,
+                                const void *value, size_t size, int flags)
+{
+       struct gfs2_sbd *sdp = GFS2_SB(inode);
+       struct posix_acl *acl = NULL;
+       int error = 0, type;
+
+       if (!sdp->sd_args.ar_posix_acl)
+               return -EOPNOTSUPP;
+
+       type = gfs2_acl_type(name);
+       if (type < 0)
+               return type;
+       if (flags & XATTR_CREATE)
+               return -EINVAL;
+       if (type == ACL_TYPE_DEFAULT && !S_ISDIR(inode->i_mode))
+               return value ? -EACCES : 0;
+       if ((current_fsuid() != inode->i_uid) && !capable(CAP_FOWNER))
+               return -EPERM;
+       if (S_ISLNK(inode->i_mode))
+               return -EOPNOTSUPP;
+
+       if (!value)
+               goto set_acl;
+
+       acl = posix_acl_from_xattr(value, size);
+       if (!acl) {
+               /*
+                * acl_set_file(3) may request that we set default ACLs with
+                * zero length -- defend (gracefully) against that here.
+                */
+               goto out;
+       }
+       if (IS_ERR(acl)) {
+               error = PTR_ERR(acl);
+               goto out;
+       }
+
+       error = posix_acl_valid(acl);
+       if (error)
+               goto out_release;
+
+       error = -EINVAL;
+       if (acl->a_count > GFS2_ACL_MAX_ENTRIES)
+               goto out_release;
+
+       if (type == ACL_TYPE_ACCESS) {
+               mode_t mode = inode->i_mode;
+               error = posix_acl_equiv_mode(acl, &mode);
+
+               if (error <= 0) {
+                       posix_acl_release(acl);
+                       acl = NULL;
+
+                       if (error < 0)
+                               return error;
+               }
+
+               error = gfs2_set_mode(inode, mode);
+               if (error)
+                       goto out_release;
+       }
+
+set_acl:
+       error = gfs2_xattr_set(inode, GFS2_EATYPE_SYS, name, value, size, 0);
+       if (!error) {
+               if (acl)
+                       set_cached_acl(inode, type, acl);
+               else
+                       forget_cached_acl(inode, type);
+       }
+out_release:
+       posix_acl_release(acl);
+out:
+       return error;
+}
+
+struct xattr_handler gfs2_xattr_system_handler = {
+       .prefix = XATTR_SYSTEM_PREFIX,
+       .get    = gfs2_xattr_system_get,
+       .set    = gfs2_xattr_system_set,
+};
+
index 6751930bfb648e809eb90e028c0caa8458e1e5e8..9306a2e6620c7111b55ed5ee5f9bf9a5c13cca2e 100644 (file)
 #include "incore.h"
 
 #define GFS2_POSIX_ACL_ACCESS          "posix_acl_access"
-#define GFS2_POSIX_ACL_ACCESS_LEN      16
 #define GFS2_POSIX_ACL_DEFAULT         "posix_acl_default"
-#define GFS2_POSIX_ACL_DEFAULT_LEN     17
+#define GFS2_ACL_MAX_ENTRIES           25
 
-#define GFS2_ACL_IS_ACCESS(name, len) \
-         ((len) == GFS2_POSIX_ACL_ACCESS_LEN && \
-         !memcmp(GFS2_POSIX_ACL_ACCESS, (name), (len)))
-
-#define GFS2_ACL_IS_DEFAULT(name, len) \
-         ((len) == GFS2_POSIX_ACL_DEFAULT_LEN && \
-         !memcmp(GFS2_POSIX_ACL_DEFAULT, (name), (len)))
-
-struct gfs2_ea_request;
-
-int gfs2_acl_validate_set(struct gfs2_inode *ip, int access,
-                         struct gfs2_ea_request *er,
-                         int *remove, mode_t *mode);
-int gfs2_acl_validate_remove(struct gfs2_inode *ip, int access);
-int gfs2_check_acl(struct inode *inode, int mask);
-int gfs2_acl_create(struct gfs2_inode *dip, struct gfs2_inode *ip);
-int gfs2_acl_chmod(struct gfs2_inode *ip, struct iattr *attr);
+extern int gfs2_check_acl(struct inode *inode, int mask);
+extern int gfs2_acl_create(struct gfs2_inode *dip, struct inode *inode);
+extern int gfs2_acl_chmod(struct gfs2_inode *ip, struct iattr *attr);
+extern struct xattr_handler gfs2_xattr_system_handler;
 
 #endif /* __ACL_DOT_H__ */
index 694b5d48f0366e1b535abb102cbf456f3ae2e2c6..7b8da941526749c9b4a566bf1d3fe7b76f417dd8 100644 (file)
@@ -269,7 +269,6 @@ static int gfs2_write_jdata_pagevec(struct address_space *mapping,
        pgoff_t end_index = i_size >> PAGE_CACHE_SHIFT;
        unsigned offset = i_size & (PAGE_CACHE_SIZE-1);
        unsigned nrblocks = nr_pages * (PAGE_CACHE_SIZE/inode->i_sb->s_blocksize);
-       struct backing_dev_info *bdi = mapping->backing_dev_info;
        int i;
        int ret;
 
@@ -313,11 +312,6 @@ static int gfs2_write_jdata_pagevec(struct address_space *mapping,
 
                if (ret || (--(wbc->nr_to_write) <= 0))
                        ret = 1;
-               if (wbc->nonblocking && bdi_write_congested(bdi)) {
-                       wbc->encountered_congestion = 1;
-                       ret = 1;
-               }
-
        }
        gfs2_trans_end(sdp);
        return ret;
@@ -338,7 +332,6 @@ static int gfs2_write_jdata_pagevec(struct address_space *mapping,
 static int gfs2_write_cache_jdata(struct address_space *mapping,
                                  struct writeback_control *wbc)
 {
-       struct backing_dev_info *bdi = mapping->backing_dev_info;
        int ret = 0;
        int done = 0;
        struct pagevec pvec;
@@ -348,11 +341,6 @@ static int gfs2_write_cache_jdata(struct address_space *mapping,
        int scanned = 0;
        int range_whole = 0;
 
-       if (wbc->nonblocking && bdi_write_congested(bdi)) {
-               wbc->encountered_congestion = 1;
-               return 0;
-       }
-
        pagevec_init(&pvec, 0);
        if (wbc->range_cyclic) {
                index = mapping->writeback_index; /* Start from prev offset */
@@ -819,8 +807,10 @@ static int gfs2_stuffed_write_end(struct inode *inode, struct buffer_head *dibh,
                mark_inode_dirty(inode);
        }
 
-       if (inode == sdp->sd_rindex)
+       if (inode == sdp->sd_rindex) {
                adjust_fs_space(inode);
+               ip->i_gh.gh_flags |= GL_NOCACHE;
+       }
 
        brelse(dibh);
        gfs2_trans_end(sdp);
@@ -889,8 +879,10 @@ static int gfs2_write_end(struct file *file, struct address_space *mapping,
                mark_inode_dirty(inode);
        }
 
-       if (inode == sdp->sd_rindex)
+       if (inode == sdp->sd_rindex) {
                adjust_fs_space(inode);
+               ip->i_gh.gh_flags |= GL_NOCACHE;
+       }
 
        brelse(dibh);
        gfs2_trans_end(sdp);
index 297d7e5cebad8d283a9360ad86cf3a96a2028f02..25fddc100f18959882e24f730085ead9916818c9 100644 (file)
@@ -525,38 +525,6 @@ consist_inode:
        return ERR_PTR(-EIO);
 }
 
-
-/**
- * dirent_first - Return the first dirent
- * @dip: the directory
- * @bh: The buffer
- * @dent: Pointer to list of dirents
- *
- * return first dirent whether bh points to leaf or stuffed dinode
- *
- * Returns: IS_LEAF, IS_DINODE, or -errno
- */
-
-static int dirent_first(struct gfs2_inode *dip, struct buffer_head *bh,
-                       struct gfs2_dirent **dent)
-{
-       struct gfs2_meta_header *h = (struct gfs2_meta_header *)bh->b_data;
-
-       if (be32_to_cpu(h->mh_type) == GFS2_METATYPE_LF) {
-               if (gfs2_meta_check(GFS2_SB(&dip->i_inode), bh))
-                       return -EIO;
-               *dent = (struct gfs2_dirent *)(bh->b_data +
-                                              sizeof(struct gfs2_leaf));
-               return IS_LEAF;
-       } else {
-               if (gfs2_metatype_check(GFS2_SB(&dip->i_inode), bh, GFS2_METATYPE_DI))
-                       return -EIO;
-               *dent = (struct gfs2_dirent *)(bh->b_data +
-                                              sizeof(struct gfs2_dinode));
-               return IS_DINODE;
-       }
-}
-
 static int dirent_check_reclen(struct gfs2_inode *dip,
                               const struct gfs2_dirent *d, const void *end_p)
 {
@@ -1006,7 +974,7 @@ static int dir_split_leaf(struct inode *inode, const struct qstr *name)
        divider = (start + half_len) << (32 - dip->i_depth);
 
        /*  Copy the entries  */
-       dirent_first(dip, obh, &dent);
+       dent = (struct gfs2_dirent *)(obh->b_data + sizeof(struct gfs2_leaf));
 
        do {
                next = dent;
index 8b674b1f3a554d4300e7965328f750c13b34bbe1..f455a03a09e29d0394d996bc7302f2888081fbf8 100644 (file)
@@ -241,15 +241,14 @@ int gfs2_glock_put(struct gfs2_glock *gl)
        int rv = 0;
 
        write_lock(gl_lock_addr(gl->gl_hash));
-       if (atomic_dec_and_test(&gl->gl_ref)) {
+       if (atomic_dec_and_lock(&gl->gl_ref, &lru_lock)) {
                hlist_del(&gl->gl_list);
-               write_unlock(gl_lock_addr(gl->gl_hash));
-               spin_lock(&lru_lock);
                if (!list_empty(&gl->gl_lru)) {
                        list_del_init(&gl->gl_lru);
                        atomic_dec(&lru_count);
                }
                spin_unlock(&lru_lock);
+               write_unlock(gl_lock_addr(gl->gl_hash));
                GLOCK_BUG_ON(gl, !list_empty(&gl->gl_holders));
                glock_free(gl);
                rv = 1;
@@ -513,7 +512,6 @@ retry:
                        GLOCK_BUG_ON(gl, 1);
                }
                spin_unlock(&gl->gl_spin);
-               gfs2_glock_put(gl);
                return;
        }
 
@@ -524,8 +522,6 @@ retry:
                if (glops->go_xmote_bh) {
                        spin_unlock(&gl->gl_spin);
                        rv = glops->go_xmote_bh(gl, gh);
-                       if (rv == -EAGAIN)
-                               return;
                        spin_lock(&gl->gl_spin);
                        if (rv) {
                                do_error(gl, rv);
@@ -540,7 +536,6 @@ out:
        clear_bit(GLF_LOCK, &gl->gl_flags);
 out_locked:
        spin_unlock(&gl->gl_spin);
-       gfs2_glock_put(gl);
 }
 
 static unsigned int gfs2_lm_lock(struct gfs2_sbd *sdp, void *lock,
@@ -600,7 +595,6 @@ __acquires(&gl->gl_spin)
 
        if (!(ret & LM_OUT_ASYNC)) {
                finish_xmote(gl, ret);
-               gfs2_glock_hold(gl);
                if (queue_delayed_work(glock_workqueue, &gl->gl_work, 0) == 0)
                        gfs2_glock_put(gl);
        } else {
@@ -672,12 +666,17 @@ out:
        return;
 
 out_sched:
+       clear_bit(GLF_LOCK, &gl->gl_flags);
+       smp_mb__after_clear_bit();
        gfs2_glock_hold(gl);
        if (queue_delayed_work(glock_workqueue, &gl->gl_work, 0) == 0)
                gfs2_glock_put_nolock(gl);
+       return;
+
 out_unlock:
        clear_bit(GLF_LOCK, &gl->gl_flags);
-       goto out;
+       smp_mb__after_clear_bit();
+       return;
 }
 
 static void delete_work_func(struct work_struct *work)
@@ -707,9 +706,12 @@ static void glock_work_func(struct work_struct *work)
 {
        unsigned long delay = 0;
        struct gfs2_glock *gl = container_of(work, struct gfs2_glock, gl_work.work);
+       int drop_ref = 0;
 
-       if (test_and_clear_bit(GLF_REPLY_PENDING, &gl->gl_flags))
+       if (test_and_clear_bit(GLF_REPLY_PENDING, &gl->gl_flags)) {
                finish_xmote(gl, gl->gl_reply);
+               drop_ref = 1;
+       }
        down_read(&gfs2_umount_flush_sem);
        spin_lock(&gl->gl_spin);
        if (test_and_clear_bit(GLF_PENDING_DEMOTE, &gl->gl_flags) &&
@@ -727,6 +729,8 @@ static void glock_work_func(struct work_struct *work)
        if (!delay ||
            queue_delayed_work(glock_workqueue, &gl->gl_work, delay) == 0)
                gfs2_glock_put(gl);
+       if (drop_ref)
+               gfs2_glock_put(gl);
 }
 
 /**
@@ -1361,10 +1365,6 @@ static int gfs2_shrink_glock_memory(int nr, gfp_t gfp_mask)
                list_del_init(&gl->gl_lru);
                atomic_dec(&lru_count);
 
-               /* Check if glock is about to be freed */
-               if (atomic_read(&gl->gl_ref) == 0)
-                       continue;
-
                /* Test for being demotable */
                if (!test_and_set_bit(GLF_LOCK, &gl->gl_flags)) {
                        gfs2_glock_hold(gl);
@@ -1375,10 +1375,11 @@ static int gfs2_shrink_glock_memory(int nr, gfp_t gfp_mask)
                                handle_callback(gl, LM_ST_UNLOCKED, 0);
                                nr--;
                        }
+                       clear_bit(GLF_LOCK, &gl->gl_flags);
+                       smp_mb__after_clear_bit();
                        if (queue_delayed_work(glock_workqueue, &gl->gl_work, 0) == 0)
                                gfs2_glock_put_nolock(gl);
                        spin_unlock(&gl->gl_spin);
-                       clear_bit(GLF_LOCK, &gl->gl_flags);
                        spin_lock(&lru_lock);
                        continue;
                }
index c609894ec0d03a0831456379367d381393daca22..13f0bd228132a4539442f396e95cd6b256fd2961 100644 (file)
@@ -180,15 +180,6 @@ static inline int gfs2_glock_is_held_shrd(struct gfs2_glock *gl)
        return gl->gl_state == LM_ST_SHARED;
 }
 
-static inline int gfs2_glock_is_blocking(struct gfs2_glock *gl)
-{
-       int ret;
-       spin_lock(&gl->gl_spin);
-       ret = test_bit(GLF_DEMOTE, &gl->gl_flags);
-       spin_unlock(&gl->gl_spin);
-       return ret;
-}
-
 int gfs2_glock_get(struct gfs2_sbd *sdp,
                   u64 number, const struct gfs2_glock_operations *glops,
                   int create, struct gfs2_glock **glp);
index 6985eef06c392c79e4bd90340f60979776ecea1a..78554acc060562f66de530363a623616bb3c9732 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/buffer_head.h>
 #include <linux/gfs2_ondisk.h>
 #include <linux/bio.h>
+#include <linux/posix_acl.h>
 
 #include "gfs2.h"
 #include "incore.h"
@@ -184,8 +185,10 @@ static void inode_go_inval(struct gfs2_glock *gl, int flags)
        if (flags & DIO_METADATA) {
                struct address_space *mapping = gl->gl_aspace->i_mapping;
                truncate_inode_pages(mapping, 0);
-               if (ip)
+               if (ip) {
                        set_bit(GIF_INVALID, &ip->i_flags);
+                       forget_all_cached_acls(&ip->i_inode);
+               }
        }
 
        if (ip == GFS2_I(gl->gl_sbd->sd_rindex))
index 6edb423f90b325697aaf8eaa36ad010d506ac83b..4792200978c82ef16378a81487016814251fe1ae 100644 (file)
@@ -429,7 +429,11 @@ struct gfs2_args {
        unsigned int ar_meta:1;                 /* mount metafs */
        unsigned int ar_discard:1;              /* discard requests */
        unsigned int ar_errors:2;               /* errors=withdraw | panic */
+       unsigned int ar_nobarrier:1;            /* do not send barriers */
        int ar_commit;                          /* Commit interval */
+       int ar_statfs_quantum;                  /* The fast statfs interval */
+       int ar_quota_quantum;                   /* The quota interval */
+       int ar_statfs_percent;                  /* The % change to force sync */
 };
 
 struct gfs2_tune {
@@ -558,6 +562,7 @@ struct gfs2_sbd {
        spinlock_t sd_statfs_spin;
        struct gfs2_statfs_change_host sd_statfs_master;
        struct gfs2_statfs_change_host sd_statfs_local;
+       int sd_statfs_force_sync;
 
        /* Resource group stuff */
 
index fb15d3b1f409de393137676c6d350604e2fc712b..26ba2a4c4a2dafb84a19af6a87a2da965cd18591 100644 (file)
@@ -871,7 +871,7 @@ struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name,
        if (error)
                goto fail_gunlock2;
 
-       error = gfs2_acl_create(dip, GFS2_I(inode));
+       error = gfs2_acl_create(dip, inode);
        if (error)
                goto fail_gunlock2;
 
@@ -947,9 +947,7 @@ void gfs2_dinode_out(const struct gfs2_inode *ip, void *buf)
 
        str->di_header.mh_magic = cpu_to_be32(GFS2_MAGIC);
        str->di_header.mh_type = cpu_to_be32(GFS2_METATYPE_DI);
-       str->di_header.__pad0 = 0;
        str->di_header.mh_format = cpu_to_be32(GFS2_FORMAT_DI);
-       str->di_header.__pad1 = 0;
        str->di_num.no_addr = cpu_to_be64(ip->i_no_addr);
        str->di_num.no_formal_ino = cpu_to_be64(ip->i_no_formal_ino);
        str->di_mode = cpu_to_be32(ip->i_inode.i_mode);
index 13c6237c5f678222a40a4d0e7f67a7707e3c38bc..4511b08fc451586444c78379575203e20d7d72cc 100644 (file)
@@ -596,7 +596,9 @@ static void log_write_header(struct gfs2_sbd *sdp, u32 flags, int pull)
        memset(lh, 0, sizeof(struct gfs2_log_header));
        lh->lh_header.mh_magic = cpu_to_be32(GFS2_MAGIC);
        lh->lh_header.mh_type = cpu_to_be32(GFS2_METATYPE_LH);
+       lh->lh_header.__pad0 = cpu_to_be64(0);
        lh->lh_header.mh_format = cpu_to_be32(GFS2_FORMAT_LH);
+       lh->lh_header.mh_jid = cpu_to_be32(sdp->sd_jdesc->jd_jid);
        lh->lh_sequence = cpu_to_be64(sdp->sd_log_sequence++);
        lh->lh_flags = cpu_to_be32(flags);
        lh->lh_tail = cpu_to_be32(tail);
index 9969ff062c5b82b9d518b1b841c0aac602f01280..de97632ba32fbcb9fa7023e0ddd19f7bf9907f12 100644 (file)
@@ -132,6 +132,7 @@ static struct buffer_head *gfs2_get_log_desc(struct gfs2_sbd *sdp, u32 ld_type)
 static void buf_lo_add(struct gfs2_sbd *sdp, struct gfs2_log_element *le)
 {
        struct gfs2_bufdata *bd = container_of(le, struct gfs2_bufdata, bd_le);
+       struct gfs2_meta_header *mh;
        struct gfs2_trans *tr;
 
        lock_buffer(bd->bd_bh);
@@ -148,6 +149,9 @@ static void buf_lo_add(struct gfs2_sbd *sdp, struct gfs2_log_element *le)
        set_bit(GLF_DIRTY, &bd->bd_gl->gl_flags);
        gfs2_meta_check(sdp, bd->bd_bh);
        gfs2_pin(sdp, bd->bd_bh);
+       mh = (struct gfs2_meta_header *)bd->bd_bh->b_data;
+       mh->__pad0 = cpu_to_be64(0);
+       mh->mh_jid = cpu_to_be32(sdp->sd_jdesc->jd_jid);
        sdp->sd_log_num_buf++;
        list_add(&le->le_list, &sdp->sd_log_le_buf);
        tr->tr_num_buf_new++;
index eacd78a5d0827c3e0d7c37fb89eace335b400eca..5b31f7741a8f83c694db681076d534a7970e1a73 100644 (file)
@@ -114,7 +114,7 @@ static int __init init_gfs2_fs(void)
        if (error)
                goto fail_unregister;
 
-       error = slow_work_register_user();
+       error = slow_work_register_user(THIS_MODULE);
        if (error)
                goto fail_slow;
 
@@ -163,7 +163,7 @@ static void __exit exit_gfs2_fs(void)
        gfs2_unregister_debugfs();
        unregister_filesystem(&gfs2_fs_type);
        unregister_filesystem(&gfs2meta_fs_type);
-       slow_work_unregister_user();
+       slow_work_unregister_user(THIS_MODULE);
 
        kmem_cache_destroy(gfs2_quotad_cachep);
        kmem_cache_destroy(gfs2_rgrpd_cachep);
index 52fb6c048981e1a09ffb4718995b7e03a2b6ff6f..edfee24f3636d9c6db41cc756622b20cfabb1c3c 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/mount.h>
 #include <linux/gfs2_ondisk.h>
 #include <linux/slow-work.h>
+#include <linux/quotaops.h>
 
 #include "gfs2.h"
 #include "incore.h"
@@ -62,13 +63,10 @@ static void gfs2_tune_init(struct gfs2_tune *gt)
        gt->gt_quota_warn_period = 10;
        gt->gt_quota_scale_num = 1;
        gt->gt_quota_scale_den = 1;
-       gt->gt_quota_quantum = 60;
        gt->gt_new_files_jdata = 0;
        gt->gt_max_readahead = 1 << 18;
        gt->gt_stall_secs = 600;
        gt->gt_complain_secs = 10;
-       gt->gt_statfs_quantum = 30;
-       gt->gt_statfs_slow = 0;
 }
 
 static struct gfs2_sbd *init_sbd(struct super_block *sb)
@@ -1114,7 +1112,7 @@ void gfs2_online_uevent(struct gfs2_sbd *sdp)
  * Returns: errno
  */
 
-static int fill_super(struct super_block *sb, void *data, int silent)
+static int fill_super(struct super_block *sb, struct gfs2_args *args, int silent)
 {
        struct gfs2_sbd *sdp;
        struct gfs2_holder mount_gh;
@@ -1125,17 +1123,7 @@ static int fill_super(struct super_block *sb, void *data, int silent)
                printk(KERN_WARNING "GFS2: can't alloc struct gfs2_sbd\n");
                return -ENOMEM;
        }
-
-       sdp->sd_args.ar_quota = GFS2_QUOTA_DEFAULT;
-       sdp->sd_args.ar_data = GFS2_DATA_DEFAULT;
-       sdp->sd_args.ar_commit = 60;
-       sdp->sd_args.ar_errors = GFS2_ERRORS_DEFAULT;
-
-       error = gfs2_mount_args(sdp, &sdp->sd_args, data);
-       if (error) {
-               printk(KERN_WARNING "GFS2: can't parse mount arguments\n");
-               goto fail;
-       }
+       sdp->sd_args = *args;
 
        if (sdp->sd_args.ar_spectator) {
                 sb->s_flags |= MS_RDONLY;
@@ -1143,11 +1131,15 @@ static int fill_super(struct super_block *sb, void *data, int silent)
        }
        if (sdp->sd_args.ar_posix_acl)
                sb->s_flags |= MS_POSIXACL;
+       if (sdp->sd_args.ar_nobarrier)
+               set_bit(SDF_NOBARRIERS, &sdp->sd_flags);
 
        sb->s_magic = GFS2_MAGIC;
        sb->s_op = &gfs2_super_ops;
        sb->s_export_op = &gfs2_export_ops;
        sb->s_xattr = gfs2_xattr_handlers;
+       sb->s_qcop = &gfs2_quotactl_ops;
+       sb_dqopt(sb)->flags |= DQUOT_QUOTA_SYS_FILE;
        sb->s_time_gran = 1;
        sb->s_maxbytes = MAX_LFS_FILESIZE;
 
@@ -1160,6 +1152,15 @@ static int fill_super(struct super_block *sb, void *data, int silent)
        sdp->sd_fsb2bb = 1 << sdp->sd_fsb2bb_shift;
 
        sdp->sd_tune.gt_log_flush_secs = sdp->sd_args.ar_commit;
+       sdp->sd_tune.gt_quota_quantum = sdp->sd_args.ar_quota_quantum;
+       if (sdp->sd_args.ar_statfs_quantum) {
+               sdp->sd_tune.gt_statfs_slow = 0;
+               sdp->sd_tune.gt_statfs_quantum = sdp->sd_args.ar_statfs_quantum;
+       }
+       else {
+               sdp->sd_tune.gt_statfs_slow = 1;
+               sdp->sd_tune.gt_statfs_quantum = 30;
+       }
 
        error = init_names(sdp, silent);
        if (error)
@@ -1243,18 +1244,127 @@ fail:
        return error;
 }
 
-static int gfs2_get_sb(struct file_system_type *fs_type, int flags,
-                      const char *dev_name, void *data, struct vfsmount *mnt)
+static int set_gfs2_super(struct super_block *s, void *data)
 {
-       return get_sb_bdev(fs_type, flags, dev_name, data, fill_super, mnt);
+       s->s_bdev = data;
+       s->s_dev = s->s_bdev->bd_dev;
+
+       /*
+        * We set the bdi here to the queue backing, file systems can
+        * overwrite this in ->fill_super()
+        */
+       s->s_bdi = &bdev_get_queue(s->s_bdev)->backing_dev_info;
+       return 0;
 }
 
-static int test_meta_super(struct super_block *s, void *ptr)
+static int test_gfs2_super(struct super_block *s, void *ptr)
 {
        struct block_device *bdev = ptr;
        return (bdev == s->s_bdev);
 }
 
+/**
+ * gfs2_get_sb - Get the GFS2 superblock
+ * @fs_type: The GFS2 filesystem type
+ * @flags: Mount flags
+ * @dev_name: The name of the device
+ * @data: The mount arguments
+ * @mnt: The vfsmnt for this mount
+ *
+ * Q. Why not use get_sb_bdev() ?
+ * A. We need to select one of two root directories to mount, independent
+ *    of whether this is the initial, or subsequent, mount of this sb
+ *
+ * Returns: 0 or -ve on error
+ */
+
+static int gfs2_get_sb(struct file_system_type *fs_type, int flags,
+                      const char *dev_name, void *data, struct vfsmount *mnt)
+{
+       struct block_device *bdev;
+       struct super_block *s;
+       fmode_t mode = FMODE_READ;
+       int error;
+       struct gfs2_args args;
+       struct gfs2_sbd *sdp;
+
+       if (!(flags & MS_RDONLY))
+               mode |= FMODE_WRITE;
+
+       bdev = open_bdev_exclusive(dev_name, mode, fs_type);
+       if (IS_ERR(bdev))
+               return PTR_ERR(bdev);
+
+       /*
+        * once the super is inserted into the list by sget, s_umount
+        * will protect the lockfs code from trying to start a snapshot
+        * while we are mounting
+        */
+       mutex_lock(&bdev->bd_fsfreeze_mutex);
+       if (bdev->bd_fsfreeze_count > 0) {
+               mutex_unlock(&bdev->bd_fsfreeze_mutex);
+               error = -EBUSY;
+               goto error_bdev;
+       }
+       s = sget(fs_type, test_gfs2_super, set_gfs2_super, bdev);
+       mutex_unlock(&bdev->bd_fsfreeze_mutex);
+       error = PTR_ERR(s);
+       if (IS_ERR(s))
+               goto error_bdev;
+
+       memset(&args, 0, sizeof(args));
+       args.ar_quota = GFS2_QUOTA_DEFAULT;
+       args.ar_data = GFS2_DATA_DEFAULT;
+       args.ar_commit = 60;
+       args.ar_statfs_quantum = 30;
+       args.ar_quota_quantum = 60;
+       args.ar_errors = GFS2_ERRORS_DEFAULT;
+
+       error = gfs2_mount_args(&args, data);
+       if (error) {
+               printk(KERN_WARNING "GFS2: can't parse mount arguments\n");
+               if (s->s_root)
+                       goto error_super;
+               deactivate_locked_super(s);
+               return error;
+       }
+
+       if (s->s_root) {
+               error = -EBUSY;
+               if ((flags ^ s->s_flags) & MS_RDONLY)
+                       goto error_super;
+               close_bdev_exclusive(bdev, mode);
+       } else {
+               char b[BDEVNAME_SIZE];
+
+               s->s_flags = flags;
+               s->s_mode = mode;
+               strlcpy(s->s_id, bdevname(bdev, b), sizeof(s->s_id));
+               sb_set_blocksize(s, block_size(bdev));
+               error = fill_super(s, &args, flags & MS_SILENT ? 1 : 0);
+               if (error) {
+                       deactivate_locked_super(s);
+                       return error;
+               }
+               s->s_flags |= MS_ACTIVE;
+               bdev->bd_super = s;
+       }
+
+       sdp = s->s_fs_info;
+       mnt->mnt_sb = s;
+       if (args.ar_meta)
+               mnt->mnt_root = dget(sdp->sd_master_dir);
+       else
+               mnt->mnt_root = dget(sdp->sd_root_dir);
+       return 0;
+
+error_super:
+       deactivate_locked_super(s);
+error_bdev:
+       close_bdev_exclusive(bdev, mode);
+       return error;
+}
+
 static int set_meta_super(struct super_block *s, void *ptr)
 {
        return -EINVAL;
@@ -1274,13 +1384,17 @@ static int gfs2_get_sb_meta(struct file_system_type *fs_type, int flags,
                       dev_name, error);
                return error;
        }
-       s = sget(&gfs2_fs_type, test_meta_super, set_meta_super,
+       s = sget(&gfs2_fs_type, test_gfs2_super, set_meta_super,
                 path.dentry->d_inode->i_sb->s_bdev);
        path_put(&path);
        if (IS_ERR(s)) {
                printk(KERN_WARNING "GFS2: gfs2 mount does not exist\n");
                return PTR_ERR(s);
        }
+       if ((flags ^ s->s_flags) & MS_RDONLY) {
+               deactivate_locked_super(s);
+               return -EBUSY;
+       }
        sdp = s->s_fs_info;
        mnt->mnt_sb = s;
        mnt->mnt_root = dget(sdp->sd_master_dir);
index 2e9b9326bfc96bfe2efbbedf410aae992cd5aa58..e3bf6eab8750011a9e582a0f465bbf3dc49b8612 100644 (file)
@@ -15,7 +15,7 @@
  * fuzziness in the current usage value of IDs that are being used on different
  * nodes in the cluster simultaneously.  So, it is possible for a user on
  * multiple nodes to overrun their quota, but that overrun is controlable.
- * Since quota tags are part of transactions, there is no need to a quota check
+ * Since quota tags are part of transactions, there is no need for a quota check
  * program to be run on node crashes or anything like that.
  *
  * There are couple of knobs that let the administrator manage the quota
@@ -47,6 +47,8 @@
 #include <linux/gfs2_ondisk.h>
 #include <linux/kthread.h>
 #include <linux/freezer.h>
+#include <linux/quota.h>
+#include <linux/dqblk_xfs.h>
 
 #include "gfs2.h"
 #include "incore.h"
 #define QUOTA_USER 1
 #define QUOTA_GROUP 0
 
-struct gfs2_quota_host {
-       u64 qu_limit;
-       u64 qu_warn;
-       s64 qu_value;
-       u32 qu_ll_next;
-};
-
 struct gfs2_quota_change_host {
        u64 qc_change;
        u32 qc_flags; /* GFS2_QCF_... */
@@ -164,7 +159,7 @@ fail:
        return error;
 }
 
-static int qd_get(struct gfs2_sbd *sdp, int user, u32 id, int create,
+static int qd_get(struct gfs2_sbd *sdp, int user, u32 id,
                  struct gfs2_quota_data **qdp)
 {
        struct gfs2_quota_data *qd = NULL, *new_qd = NULL;
@@ -202,7 +197,7 @@ static int qd_get(struct gfs2_sbd *sdp, int user, u32 id, int create,
 
                spin_unlock(&qd_lru_lock);
 
-               if (qd || !create) {
+               if (qd) {
                        if (new_qd) {
                                gfs2_glock_put(new_qd->qd_gl);
                                kmem_cache_free(gfs2_quotad_cachep, new_qd);
@@ -461,12 +456,12 @@ static void qd_unlock(struct gfs2_quota_data *qd)
        qd_put(qd);
 }
 
-static int qdsb_get(struct gfs2_sbd *sdp, int user, u32 id, int create,
+static int qdsb_get(struct gfs2_sbd *sdp, int user, u32 id,
                    struct gfs2_quota_data **qdp)
 {
        int error;
 
-       error = qd_get(sdp, user, id, create, qdp);
+       error = qd_get(sdp, user, id, qdp);
        if (error)
                return error;
 
@@ -508,20 +503,20 @@ int gfs2_quota_hold(struct gfs2_inode *ip, u32 uid, u32 gid)
        if (sdp->sd_args.ar_quota == GFS2_QUOTA_OFF)
                return 0;
 
-       error = qdsb_get(sdp, QUOTA_USER, ip->i_inode.i_uid, CREATE, qd);
+       error = qdsb_get(sdp, QUOTA_USER, ip->i_inode.i_uid, qd);
        if (error)
                goto out;
        al->al_qd_num++;
        qd++;
 
-       error = qdsb_get(sdp, QUOTA_GROUP, ip->i_inode.i_gid, CREATE, qd);
+       error = qdsb_get(sdp, QUOTA_GROUP, ip->i_inode.i_gid, qd);
        if (error)
                goto out;
        al->al_qd_num++;
        qd++;
 
        if (uid != NO_QUOTA_CHANGE && uid != ip->i_inode.i_uid) {
-               error = qdsb_get(sdp, QUOTA_USER, uid, CREATE, qd);
+               error = qdsb_get(sdp, QUOTA_USER, uid, qd);
                if (error)
                        goto out;
                al->al_qd_num++;
@@ -529,7 +524,7 @@ int gfs2_quota_hold(struct gfs2_inode *ip, u32 uid, u32 gid)
        }
 
        if (gid != NO_QUOTA_CHANGE && gid != ip->i_inode.i_gid) {
-               error = qdsb_get(sdp, QUOTA_GROUP, gid, CREATE, qd);
+               error = qdsb_get(sdp, QUOTA_GROUP, gid, qd);
                if (error)
                        goto out;
                al->al_qd_num++;
@@ -617,48 +612,36 @@ static void do_qc(struct gfs2_quota_data *qd, s64 change)
        mutex_unlock(&sdp->sd_quota_mutex);
 }
 
-static void gfs2_quota_in(struct gfs2_quota_host *qu, const void *buf)
-{
-       const struct gfs2_quota *str = buf;
-
-       qu->qu_limit = be64_to_cpu(str->qu_limit);
-       qu->qu_warn = be64_to_cpu(str->qu_warn);
-       qu->qu_value = be64_to_cpu(str->qu_value);
-       qu->qu_ll_next = be32_to_cpu(str->qu_ll_next);
-}
-
-static void gfs2_quota_out(const struct gfs2_quota_host *qu, void *buf)
-{
-       struct gfs2_quota *str = buf;
-
-       str->qu_limit = cpu_to_be64(qu->qu_limit);
-       str->qu_warn = cpu_to_be64(qu->qu_warn);
-       str->qu_value = cpu_to_be64(qu->qu_value);
-       str->qu_ll_next = cpu_to_be32(qu->qu_ll_next);
-       memset(&str->qu_reserved, 0, sizeof(str->qu_reserved));
-}
-
 /**
- * gfs2_adjust_quota
+ * gfs2_adjust_quota - adjust record of current block usage
+ * @ip: The quota inode
+ * @loc: Offset of the entry in the quota file
+ * @change: The amount of usage change to record
+ * @qd: The quota data
+ * @fdq: The updated limits to record
  *
  * This function was mostly borrowed from gfs2_block_truncate_page which was
  * in turn mostly borrowed from ext3
+ *
+ * Returns: 0 or -ve on error
  */
+
 static int gfs2_adjust_quota(struct gfs2_inode *ip, loff_t loc,
-                            s64 change, struct gfs2_quota_data *qd)
+                            s64 change, struct gfs2_quota_data *qd,
+                            struct fs_disk_quota *fdq)
 {
        struct inode *inode = &ip->i_inode;
        struct address_space *mapping = inode->i_mapping;
        unsigned long index = loc >> PAGE_CACHE_SHIFT;
        unsigned offset = loc & (PAGE_CACHE_SIZE - 1);
        unsigned blocksize, iblock, pos;
-       struct buffer_head *bh;
+       struct buffer_head *bh, *dibh;
        struct page *page;
        void *kaddr;
-       char *ptr;
-       struct gfs2_quota_host qp;
+       struct gfs2_quota *qp;
        s64 value;
        int err = -EIO;
+       u64 size;
 
        if (gfs2_is_stuffed(ip))
                gfs2_unstuff_dinode(ip, NULL);
@@ -700,18 +683,38 @@ static int gfs2_adjust_quota(struct gfs2_inode *ip, loff_t loc,
        gfs2_trans_add_bh(ip->i_gl, bh, 0);
 
        kaddr = kmap_atomic(page, KM_USER0);
-       ptr = kaddr + offset;
-       gfs2_quota_in(&qp, ptr);
-       qp.qu_value += change;
-       value = qp.qu_value;
-       gfs2_quota_out(&qp, ptr);
+       qp = kaddr + offset;
+       value = (s64)be64_to_cpu(qp->qu_value) + change;
+       qp->qu_value = cpu_to_be64(value);
+       qd->qd_qb.qb_value = qp->qu_value;
+       if (fdq) {
+               if (fdq->d_fieldmask & FS_DQ_BSOFT) {
+                       qp->qu_warn = cpu_to_be64(fdq->d_blk_softlimit);
+                       qd->qd_qb.qb_warn = qp->qu_warn;
+               }
+               if (fdq->d_fieldmask & FS_DQ_BHARD) {
+                       qp->qu_limit = cpu_to_be64(fdq->d_blk_hardlimit);
+                       qd->qd_qb.qb_limit = qp->qu_limit;
+               }
+       }
        flush_dcache_page(page);
        kunmap_atomic(kaddr, KM_USER0);
-       err = 0;
-       qd->qd_qb.qb_magic = cpu_to_be32(GFS2_MAGIC);
-       qd->qd_qb.qb_value = cpu_to_be64(value);
-       ((struct gfs2_quota_lvb*)(qd->qd_gl->gl_lvb))->qb_magic = cpu_to_be32(GFS2_MAGIC);
-       ((struct gfs2_quota_lvb*)(qd->qd_gl->gl_lvb))->qb_value = cpu_to_be64(value);
+
+       err = gfs2_meta_inode_buffer(ip, &dibh);
+       if (err)
+               goto unlock;
+
+       size = loc + sizeof(struct gfs2_quota);
+       if (size > inode->i_size) {
+               ip->i_disksize = size;
+               i_size_write(inode, size);
+       }
+       inode->i_mtime = inode->i_atime = CURRENT_TIME;
+       gfs2_trans_add_bh(ip->i_gl, dibh, 1);
+       gfs2_dinode_out(ip, dibh->b_data);
+       brelse(dibh);
+       mark_inode_dirty(inode);
+
 unlock:
        unlock_page(page);
        page_cache_release(page);
@@ -739,9 +742,9 @@ static int do_sync(unsigned int num_qd, struct gfs2_quota_data **qda)
                return -ENOMEM;
 
        sort(qda, num_qd, sizeof(struct gfs2_quota_data *), sort_qd, NULL);
+       mutex_lock_nested(&ip->i_inode.i_mutex, I_MUTEX_QUOTA);
        for (qx = 0; qx < num_qd; qx++) {
-               error = gfs2_glock_nq_init(qda[qx]->qd_gl,
-                                          LM_ST_EXCLUSIVE,
+               error = gfs2_glock_nq_init(qda[qx]->qd_gl, LM_ST_EXCLUSIVE,
                                           GL_NOCACHE, &ghs[qx]);
                if (error)
                        goto out;
@@ -795,9 +798,7 @@ static int do_sync(unsigned int num_qd, struct gfs2_quota_data **qda)
        for (x = 0; x < num_qd; x++) {
                qd = qda[x];
                offset = qd2offset(qd);
-               error = gfs2_adjust_quota(ip, offset, qd->qd_change_sync,
-                                         (struct gfs2_quota_data *)
-                                         qd);
+               error = gfs2_adjust_quota(ip, offset, qd->qd_change_sync, qd, NULL);
                if (error)
                        goto out_end_trans;
 
@@ -817,21 +818,44 @@ out_gunlock:
 out:
        while (qx--)
                gfs2_glock_dq_uninit(&ghs[qx]);
+       mutex_unlock(&ip->i_inode.i_mutex);
        kfree(ghs);
        gfs2_log_flush(ip->i_gl->gl_sbd, ip->i_gl);
        return error;
 }
 
+static int update_qd(struct gfs2_sbd *sdp, struct gfs2_quota_data *qd)
+{
+       struct gfs2_inode *ip = GFS2_I(sdp->sd_quota_inode);
+       struct gfs2_quota q;
+       struct gfs2_quota_lvb *qlvb;
+       loff_t pos;
+       int error;
+
+       memset(&q, 0, sizeof(struct gfs2_quota));
+       pos = qd2offset(qd);
+       error = gfs2_internal_read(ip, NULL, (char *)&q, &pos, sizeof(q));
+       if (error < 0)
+               return error;
+
+       qlvb = (struct gfs2_quota_lvb *)qd->qd_gl->gl_lvb;
+       qlvb->qb_magic = cpu_to_be32(GFS2_MAGIC);
+       qlvb->__pad = 0;
+       qlvb->qb_limit = q.qu_limit;
+       qlvb->qb_warn = q.qu_warn;
+       qlvb->qb_value = q.qu_value;
+       qd->qd_qb = *qlvb;
+
+       return 0;
+}
+
 static int do_glock(struct gfs2_quota_data *qd, int force_refresh,
                    struct gfs2_holder *q_gh)
 {
        struct gfs2_sbd *sdp = qd->qd_gl->gl_sbd;
        struct gfs2_inode *ip = GFS2_I(sdp->sd_quota_inode);
        struct gfs2_holder i_gh;
-       struct gfs2_quota_host q;
-       char buf[sizeof(struct gfs2_quota)];
        int error;
-       struct gfs2_quota_lvb *qlvb;
 
 restart:
        error = gfs2_glock_nq_init(qd->qd_gl, LM_ST_SHARED, 0, q_gh);
@@ -841,11 +865,9 @@ restart:
        qd->qd_qb = *(struct gfs2_quota_lvb *)qd->qd_gl->gl_lvb;
 
        if (force_refresh || qd->qd_qb.qb_magic != cpu_to_be32(GFS2_MAGIC)) {
-               loff_t pos;
                gfs2_glock_dq_uninit(q_gh);
-               error = gfs2_glock_nq_init(qd->qd_gl,
-                                          LM_ST_EXCLUSIVE, GL_NOCACHE,
-                                          q_gh);
+               error = gfs2_glock_nq_init(qd->qd_gl, LM_ST_EXCLUSIVE,
+                                          GL_NOCACHE, q_gh);
                if (error)
                        return error;
 
@@ -853,29 +875,14 @@ restart:
                if (error)
                        goto fail;
 
-               memset(buf, 0, sizeof(struct gfs2_quota));
-               pos = qd2offset(qd);
-               error = gfs2_internal_read(ip, NULL, buf, &pos,
-                                          sizeof(struct gfs2_quota));
-               if (error < 0)
+               error = update_qd(sdp, qd);
+               if (error)
                        goto fail_gunlock;
 
                gfs2_glock_dq_uninit(&i_gh);
-
-               gfs2_quota_in(&q, buf);
-               qlvb = (struct gfs2_quota_lvb *)qd->qd_gl->gl_lvb;
-               qlvb->qb_magic = cpu_to_be32(GFS2_MAGIC);
-               qlvb->__pad = 0;
-               qlvb->qb_limit = cpu_to_be64(q.qu_limit);
-               qlvb->qb_warn = cpu_to_be64(q.qu_warn);
-               qlvb->qb_value = cpu_to_be64(q.qu_value);
-               qd->qd_qb = *qlvb;
-
-               if (gfs2_glock_is_blocking(qd->qd_gl)) {
-                       gfs2_glock_dq_uninit(q_gh);
-                       force_refresh = 0;
-                       goto restart;
-               }
+               gfs2_glock_dq_uninit(q_gh);
+               force_refresh = 0;
+               goto restart;
        }
 
        return 0;
@@ -995,7 +1002,7 @@ static int print_message(struct gfs2_quota_data *qd, char *type)
 {
        struct gfs2_sbd *sdp = qd->qd_gl->gl_sbd;
 
-       printk(KERN_INFO "GFS2: fsid=%s: quota %s for %s %u\r\n",
+       printk(KERN_INFO "GFS2: fsid=%s: quota %s for %s %u\n",
               sdp->sd_fsname, type,
               (test_bit(QDF_USER, &qd->qd_flags)) ? "user" : "group",
               qd->qd_id);
@@ -1032,6 +1039,10 @@ int gfs2_quota_check(struct gfs2_inode *ip, u32 uid, u32 gid)
 
                if (be64_to_cpu(qd->qd_qb.qb_limit) && (s64)be64_to_cpu(qd->qd_qb.qb_limit) < value) {
                        print_message(qd, "exceeded");
+                       quota_send_warning(test_bit(QDF_USER, &qd->qd_flags) ?
+                                          USRQUOTA : GRPQUOTA, qd->qd_id,
+                                          sdp->sd_vfs->s_dev, QUOTA_NL_BHARDWARN);
+
                        error = -EDQUOT;
                        break;
                } else if (be64_to_cpu(qd->qd_qb.qb_warn) &&
@@ -1039,6 +1050,9 @@ int gfs2_quota_check(struct gfs2_inode *ip, u32 uid, u32 gid)
                           time_after_eq(jiffies, qd->qd_last_warn +
                                         gfs2_tune_get(sdp,
                                                gt_quota_warn_period) * HZ)) {
+                       quota_send_warning(test_bit(QDF_USER, &qd->qd_flags) ?
+                                          USRQUOTA : GRPQUOTA, qd->qd_id,
+                                          sdp->sd_vfs->s_dev, QUOTA_NL_BSOFTWARN);
                        error = print_message(qd, "warning");
                        qd->qd_last_warn = jiffies;
                }
@@ -1069,8 +1083,9 @@ void gfs2_quota_change(struct gfs2_inode *ip, s64 change,
        }
 }
 
-int gfs2_quota_sync(struct gfs2_sbd *sdp)
+int gfs2_quota_sync(struct super_block *sb, int type)
 {
+       struct gfs2_sbd *sdp = sb->s_fs_info;
        struct gfs2_quota_data **qda;
        unsigned int max_qd = gfs2_tune_get(sdp, gt_quota_simul_sync);
        unsigned int num_qd;
@@ -1118,7 +1133,7 @@ int gfs2_quota_refresh(struct gfs2_sbd *sdp, int user, u32 id)
        struct gfs2_holder q_gh;
        int error;
 
-       error = qd_get(sdp, user, id, CREATE, &qd);
+       error = qd_get(sdp, user, id, &qd);
        if (error)
                return error;
 
@@ -1127,7 +1142,6 @@ int gfs2_quota_refresh(struct gfs2_sbd *sdp, int user, u32 id)
                gfs2_glock_dq_uninit(&q_gh);
 
        qd_put(qd);
-
        return error;
 }
 
@@ -1298,12 +1312,12 @@ static void quotad_error(struct gfs2_sbd *sdp, const char *msg, int error)
 }
 
 static void quotad_check_timeo(struct gfs2_sbd *sdp, const char *msg,
-                              int (*fxn)(struct gfs2_sbd *sdp),
+                              int (*fxn)(struct super_block *sb, int type),
                               unsigned long t, unsigned long *timeo,
                               unsigned int *new_timeo)
 {
        if (t >= *timeo) {
-               int error = fxn(sdp);
+               int error = fxn(sdp->sd_vfs, 0);
                quotad_error(sdp, msg, error);
                *timeo = gfs2_tune_get_i(&sdp->sd_tune, new_timeo) * HZ;
        } else {
@@ -1330,6 +1344,14 @@ static void quotad_check_trunc_list(struct gfs2_sbd *sdp)
        }
 }
 
+void gfs2_wake_up_statfs(struct gfs2_sbd *sdp) {
+       if (!sdp->sd_statfs_force_sync) {
+               sdp->sd_statfs_force_sync = 1;
+               wake_up(&sdp->sd_quota_wait);
+       }
+}
+
+
 /**
  * gfs2_quotad - Write cached quota changes into the quota file
  * @sdp: Pointer to GFS2 superblock
@@ -1349,8 +1371,15 @@ int gfs2_quotad(void *data)
        while (!kthread_should_stop()) {
 
                /* Update the master statfs file */
-               quotad_check_timeo(sdp, "statfs", gfs2_statfs_sync, t,
-                                  &statfs_timeo, &tune->gt_statfs_quantum);
+               if (sdp->sd_statfs_force_sync) {
+                       int error = gfs2_statfs_sync(sdp->sd_vfs, 0);
+                       quotad_error(sdp, "statfs", error);
+                       statfs_timeo = gfs2_tune_get(sdp, gt_statfs_quantum) * HZ;
+               }
+               else
+                       quotad_check_timeo(sdp, "statfs", gfs2_statfs_sync, t,
+                                          &statfs_timeo,
+                                          &tune->gt_statfs_quantum);
 
                /* Update quota file */
                quotad_check_timeo(sdp, "sync", gfs2_quota_sync, t,
@@ -1367,7 +1396,7 @@ int gfs2_quotad(void *data)
                spin_lock(&sdp->sd_trunc_lock);
                empty = list_empty(&sdp->sd_trunc_list);
                spin_unlock(&sdp->sd_trunc_lock);
-               if (empty)
+               if (empty && !sdp->sd_statfs_force_sync)
                        t -= schedule_timeout(t);
                else
                        t = 0;
@@ -1377,3 +1406,181 @@ int gfs2_quotad(void *data)
        return 0;
 }
 
+static int gfs2_quota_get_xstate(struct super_block *sb,
+                                struct fs_quota_stat *fqs)
+{
+       struct gfs2_sbd *sdp = sb->s_fs_info;
+
+       memset(fqs, 0, sizeof(struct fs_quota_stat));
+       fqs->qs_version = FS_QSTAT_VERSION;
+       if (sdp->sd_args.ar_quota == GFS2_QUOTA_ON)
+               fqs->qs_flags = (XFS_QUOTA_UDQ_ENFD | XFS_QUOTA_GDQ_ENFD);
+       else if (sdp->sd_args.ar_quota == GFS2_QUOTA_ACCOUNT)
+               fqs->qs_flags = (XFS_QUOTA_UDQ_ACCT | XFS_QUOTA_GDQ_ACCT);
+       if (sdp->sd_quota_inode) {
+               fqs->qs_uquota.qfs_ino = GFS2_I(sdp->sd_quota_inode)->i_no_addr;
+               fqs->qs_uquota.qfs_nblks = sdp->sd_quota_inode->i_blocks;
+       }
+       fqs->qs_uquota.qfs_nextents = 1; /* unsupported */
+       fqs->qs_gquota = fqs->qs_uquota; /* its the same inode in both cases */
+       fqs->qs_incoredqs = atomic_read(&qd_lru_count);
+       return 0;
+}
+
+static int gfs2_xquota_get(struct super_block *sb, int type, qid_t id,
+                          struct fs_disk_quota *fdq)
+{
+       struct gfs2_sbd *sdp = sb->s_fs_info;
+       struct gfs2_quota_lvb *qlvb;
+       struct gfs2_quota_data *qd;
+       struct gfs2_holder q_gh;
+       int error;
+
+       memset(fdq, 0, sizeof(struct fs_disk_quota));
+
+       if (sdp->sd_args.ar_quota == GFS2_QUOTA_OFF)
+               return -ESRCH; /* Crazy XFS error code */
+
+       if (type == USRQUOTA)
+               type = QUOTA_USER;
+       else if (type == GRPQUOTA)
+               type = QUOTA_GROUP;
+       else
+               return -EINVAL;
+
+       error = qd_get(sdp, type, id, &qd);
+       if (error)
+               return error;
+       error = do_glock(qd, FORCE, &q_gh);
+       if (error)
+               goto out;
+
+       qlvb = (struct gfs2_quota_lvb *)qd->qd_gl->gl_lvb;
+       fdq->d_version = FS_DQUOT_VERSION;
+       fdq->d_flags = (type == QUOTA_USER) ? XFS_USER_QUOTA : XFS_GROUP_QUOTA;
+       fdq->d_id = id;
+       fdq->d_blk_hardlimit = be64_to_cpu(qlvb->qb_limit);
+       fdq->d_blk_softlimit = be64_to_cpu(qlvb->qb_warn);
+       fdq->d_bcount = be64_to_cpu(qlvb->qb_value);
+
+       gfs2_glock_dq_uninit(&q_gh);
+out:
+       qd_put(qd);
+       return error;
+}
+
+/* GFS2 only supports a subset of the XFS fields */
+#define GFS2_FIELDMASK (FS_DQ_BSOFT|FS_DQ_BHARD)
+
+static int gfs2_xquota_set(struct super_block *sb, int type, qid_t id,
+                          struct fs_disk_quota *fdq)
+{
+       struct gfs2_sbd *sdp = sb->s_fs_info;
+       struct gfs2_inode *ip = GFS2_I(sdp->sd_quota_inode);
+       struct gfs2_quota_data *qd;
+       struct gfs2_holder q_gh, i_gh;
+       unsigned int data_blocks, ind_blocks;
+       unsigned int blocks = 0;
+       int alloc_required;
+       struct gfs2_alloc *al;
+       loff_t offset;
+       int error;
+
+       if (sdp->sd_args.ar_quota == GFS2_QUOTA_OFF)
+               return -ESRCH; /* Crazy XFS error code */
+
+       switch(type) {
+       case USRQUOTA:
+               type = QUOTA_USER;
+               if (fdq->d_flags != XFS_USER_QUOTA)
+                       return -EINVAL;
+               break;
+       case GRPQUOTA:
+               type = QUOTA_GROUP;
+               if (fdq->d_flags != XFS_GROUP_QUOTA)
+                       return -EINVAL;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       if (fdq->d_fieldmask & ~GFS2_FIELDMASK)
+               return -EINVAL;
+       if (fdq->d_id != id)
+               return -EINVAL;
+
+       error = qd_get(sdp, type, id, &qd);
+       if (error)
+               return error;
+
+       mutex_lock(&ip->i_inode.i_mutex);
+       error = gfs2_glock_nq_init(qd->qd_gl, LM_ST_EXCLUSIVE, 0, &q_gh);
+       if (error)
+               goto out_put;
+       error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &i_gh);
+       if (error)
+               goto out_q;
+
+       /* Check for existing entry, if none then alloc new blocks */
+       error = update_qd(sdp, qd);
+       if (error)
+               goto out_i;
+
+       /* If nothing has changed, this is a no-op */
+       if ((fdq->d_fieldmask & FS_DQ_BSOFT) &&
+           (fdq->d_blk_softlimit == be64_to_cpu(qd->qd_qb.qb_warn)))
+               fdq->d_fieldmask ^= FS_DQ_BSOFT;
+       if ((fdq->d_fieldmask & FS_DQ_BHARD) &&
+           (fdq->d_blk_hardlimit == be64_to_cpu(qd->qd_qb.qb_limit)))
+               fdq->d_fieldmask ^= FS_DQ_BHARD;
+       if (fdq->d_fieldmask == 0)
+               goto out_i;
+
+       offset = qd2offset(qd);
+       error = gfs2_write_alloc_required(ip, offset, sizeof(struct gfs2_quota),
+                                         &alloc_required);
+       if (error)
+               goto out_i;
+       if (alloc_required) {
+               al = gfs2_alloc_get(ip);
+               if (al == NULL)
+                       goto out_i;
+               gfs2_write_calc_reserv(ip, sizeof(struct gfs2_quota),
+                                      &data_blocks, &ind_blocks);
+               blocks = al->al_requested = 1 + data_blocks + ind_blocks;
+               error = gfs2_inplace_reserve(ip);
+               if (error)
+                       goto out_alloc;
+       }
+
+       error = gfs2_trans_begin(sdp, blocks + RES_DINODE + 1, 0);
+       if (error)
+               goto out_release;
+
+       /* Apply changes */
+       error = gfs2_adjust_quota(ip, offset, 0, qd, fdq);
+
+       gfs2_trans_end(sdp);
+out_release:
+       if (alloc_required) {
+               gfs2_inplace_release(ip);
+out_alloc:
+               gfs2_alloc_put(ip);
+       }
+out_i:
+       gfs2_glock_dq_uninit(&i_gh);
+out_q:
+       gfs2_glock_dq_uninit(&q_gh);
+out_put:
+       mutex_unlock(&ip->i_inode.i_mutex);
+       qd_put(qd);
+       return error;
+}
+
+const struct quotactl_ops gfs2_quotactl_ops = {
+       .quota_sync     = gfs2_quota_sync,
+       .get_xstate     = gfs2_quota_get_xstate,
+       .get_xquota     = gfs2_xquota_get,
+       .set_xquota     = gfs2_xquota_set,
+};
+
index 0fa5fa63d0e8fce00a37c2ea4cbdc7a476fe5c3e..e271fa07ad0206dfbda9cb33ad01c9cbd0d7c3ef 100644 (file)
@@ -25,13 +25,15 @@ extern int gfs2_quota_check(struct gfs2_inode *ip, u32 uid, u32 gid);
 extern void gfs2_quota_change(struct gfs2_inode *ip, s64 change,
                              u32 uid, u32 gid);
 
-extern int gfs2_quota_sync(struct gfs2_sbd *sdp);
+extern int gfs2_quota_sync(struct super_block *sb, int type);
 extern int gfs2_quota_refresh(struct gfs2_sbd *sdp, int user, u32 id);
 
 extern int gfs2_quota_init(struct gfs2_sbd *sdp);
 extern void gfs2_quota_cleanup(struct gfs2_sbd *sdp);
 extern int gfs2_quotad(void *data);
 
+extern void gfs2_wake_up_statfs(struct gfs2_sbd *sdp);
+
 static inline int gfs2_quota_lock_check(struct gfs2_inode *ip)
 {
        struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
@@ -50,5 +52,6 @@ static inline int gfs2_quota_lock_check(struct gfs2_inode *ip)
 }
 
 extern int gfs2_shrink_qd_memory(int nr, gfp_t gfp_mask);
+extern const struct quotactl_ops gfs2_quotactl_ops;
 
 #endif /* __QUOTA_DOT_H__ */
index 59d2695509d30c0fd876175f32fe34ec96f29582..4b9bece3d4372e323135156bd029d94877da5949 100644 (file)
@@ -7,6 +7,7 @@
  * of the GNU General Public License version 2.
  */
 
+#include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/completion.h>
@@ -409,7 +410,9 @@ static int clean_journal(struct gfs2_jdesc *jd, struct gfs2_log_header_host *hea
        memset(lh, 0, sizeof(struct gfs2_log_header));
        lh->lh_header.mh_magic = cpu_to_be32(GFS2_MAGIC);
        lh->lh_header.mh_type = cpu_to_be32(GFS2_METATYPE_LH);
+       lh->lh_header.__pad0 = cpu_to_be64(0);
        lh->lh_header.mh_format = cpu_to_be32(GFS2_FORMAT_LH);
+       lh->lh_header.mh_jid = cpu_to_be32(sdp->sd_jdesc->jd_jid);
        lh->lh_sequence = cpu_to_be64(head->lh_sequence + 1);
        lh->lh_flags = cpu_to_be32(GFS2_LOG_HEAD_UNMOUNT);
        lh->lh_blkno = cpu_to_be32(lblock);
@@ -593,6 +596,7 @@ fail:
 }
 
 struct slow_work_ops gfs2_recover_ops = {
+       .owner   = THIS_MODULE,
        .get_ref = gfs2_recover_get_ref,
        .put_ref = gfs2_recover_put_ref,
        .execute = gfs2_recover_work,
index 8f1cfb02a6cb2ffef145e02ee07279d7196169d6..0608f490c295dae79b49cf496bffd0fa79e2c849 100644 (file)
@@ -1710,11 +1710,16 @@ int gfs2_check_blk_type(struct gfs2_sbd *sdp, u64 no_addr, unsigned int type)
 {
        struct gfs2_rgrpd *rgd;
        struct gfs2_holder ri_gh, rgd_gh;
+       struct gfs2_inode *ip = GFS2_I(sdp->sd_rindex);
+       int ri_locked = 0;
        int error;
 
-       error = gfs2_rindex_hold(sdp, &ri_gh);
-       if (error)
-               goto fail;
+       if (!gfs2_glock_is_locked_by_me(ip->i_gl)) {
+               error = gfs2_rindex_hold(sdp, &ri_gh);
+               if (error)
+                       goto fail;
+               ri_locked = 1;
+       }
 
        error = -EINVAL;
        rgd = gfs2_blk2rgrpd(sdp, no_addr);
@@ -1730,7 +1735,8 @@ int gfs2_check_blk_type(struct gfs2_sbd *sdp, u64 no_addr, unsigned int type)
 
        gfs2_glock_dq_uninit(&rgd_gh);
 fail_rindex:
-       gfs2_glock_dq_uninit(&ri_gh);
+       if (ri_locked)
+               gfs2_glock_dq_uninit(&ri_gh);
 fail:
        return error;
 }
index 0ec3ec672de18321153673d5a41660d5305c3fb5..c282ad41f3d1860bba4301495a7303de40b57d06 100644 (file)
@@ -70,6 +70,11 @@ enum {
        Opt_commit,
        Opt_err_withdraw,
        Opt_err_panic,
+       Opt_statfs_quantum,
+       Opt_statfs_percent,
+       Opt_quota_quantum,
+       Opt_barrier,
+       Opt_nobarrier,
        Opt_error,
 };
 
@@ -101,18 +106,23 @@ static const match_table_t tokens = {
        {Opt_commit, "commit=%d"},
        {Opt_err_withdraw, "errors=withdraw"},
        {Opt_err_panic, "errors=panic"},
+       {Opt_statfs_quantum, "statfs_quantum=%d"},
+       {Opt_statfs_percent, "statfs_percent=%d"},
+       {Opt_quota_quantum, "quota_quantum=%d"},
+       {Opt_barrier, "barrier"},
+       {Opt_nobarrier, "nobarrier"},
        {Opt_error, NULL}
 };
 
 /**
  * gfs2_mount_args - Parse mount options
- * @sdp:
- * @data:
+ * @args: The structure into which the parsed options will be written
+ * @options: The options to parse
  *
  * Return: errno
  */
 
-int gfs2_mount_args(struct gfs2_sbd *sdp, struct gfs2_args *args, char *options)
+int gfs2_mount_args(struct gfs2_args *args, char *options)
 {
        char *o;
        int token;
@@ -157,7 +167,7 @@ int gfs2_mount_args(struct gfs2_sbd *sdp, struct gfs2_args *args, char *options)
                        break;
                case Opt_debug:
                        if (args->ar_errors == GFS2_ERRORS_PANIC) {
-                               fs_info(sdp, "-o debug and -o errors=panic "
+                               printk(KERN_WARNING "GFS2: -o debug and -o errors=panic "
                                       "are mutually exclusive.\n");
                                return -EINVAL;
                        }
@@ -210,7 +220,29 @@ int gfs2_mount_args(struct gfs2_sbd *sdp, struct gfs2_args *args, char *options)
                case Opt_commit:
                        rv = match_int(&tmp[0], &args->ar_commit);
                        if (rv || args->ar_commit <= 0) {
-                               fs_info(sdp, "commit mount option requires a positive numeric argument\n");
+                               printk(KERN_WARNING "GFS2: commit mount option requires a positive numeric argument\n");
+                               return rv ? rv : -EINVAL;
+                       }
+                       break;
+               case Opt_statfs_quantum:
+                       rv = match_int(&tmp[0], &args->ar_statfs_quantum);
+                       if (rv || args->ar_statfs_quantum < 0) {
+                               printk(KERN_WARNING "GFS2: statfs_quantum mount option requires a non-negative numeric argument\n");
+                               return rv ? rv : -EINVAL;
+                       }
+                       break;
+               case Opt_quota_quantum:
+                       rv = match_int(&tmp[0], &args->ar_quota_quantum);
+                       if (rv || args->ar_quota_quantum <= 0) {
+                               printk(KERN_WARNING "GFS2: quota_quantum mount option requires a positive numeric argument\n");
+                               return rv ? rv : -EINVAL;
+                       }
+                       break;
+               case Opt_statfs_percent:
+                       rv = match_int(&tmp[0], &args->ar_statfs_percent);
+                       if (rv || args->ar_statfs_percent < 0 ||
+                           args->ar_statfs_percent > 100) {
+                               printk(KERN_WARNING "statfs_percent mount option requires a numeric argument between 0 and 100\n");
                                return rv ? rv : -EINVAL;
                        }
                        break;
@@ -219,15 +251,21 @@ int gfs2_mount_args(struct gfs2_sbd *sdp, struct gfs2_args *args, char *options)
                        break;
                case Opt_err_panic:
                        if (args->ar_debug) {
-                               fs_info(sdp, "-o debug and -o errors=panic "
+                               printk(KERN_WARNING "GFS2: -o debug and -o errors=panic "
                                        "are mutually exclusive.\n");
                                return -EINVAL;
                        }
                        args->ar_errors = GFS2_ERRORS_PANIC;
                        break;
+               case Opt_barrier:
+                       args->ar_nobarrier = 0;
+                       break;
+               case Opt_nobarrier:
+                       args->ar_nobarrier = 1;
+                       break;
                case Opt_error:
                default:
-                       fs_info(sdp, "invalid mount option: %s\n", o);
+                       printk(KERN_WARNING "GFS2: invalid mount option: %s\n", o);
                        return -EINVAL;
                }
        }
@@ -442,7 +480,10 @@ void gfs2_statfs_change(struct gfs2_sbd *sdp, s64 total, s64 free,
 {
        struct gfs2_inode *l_ip = GFS2_I(sdp->sd_sc_inode);
        struct gfs2_statfs_change_host *l_sc = &sdp->sd_statfs_local;
+       struct gfs2_statfs_change_host *m_sc = &sdp->sd_statfs_master;
        struct buffer_head *l_bh;
+       s64 x, y;
+       int need_sync = 0;
        int error;
 
        error = gfs2_meta_inode_buffer(l_ip, &l_bh);
@@ -456,9 +497,17 @@ void gfs2_statfs_change(struct gfs2_sbd *sdp, s64 total, s64 free,
        l_sc->sc_free += free;
        l_sc->sc_dinodes += dinodes;
        gfs2_statfs_change_out(l_sc, l_bh->b_data + sizeof(struct gfs2_dinode));
+       if (sdp->sd_args.ar_statfs_percent) {
+               x = 100 * l_sc->sc_free;
+               y = m_sc->sc_free * sdp->sd_args.ar_statfs_percent;
+               if (x >= y || x <= -y)
+                       need_sync = 1;
+       }
        spin_unlock(&sdp->sd_statfs_spin);
 
        brelse(l_bh);
+       if (need_sync)
+               gfs2_wake_up_statfs(sdp);
 }
 
 void update_statfs(struct gfs2_sbd *sdp, struct buffer_head *m_bh,
@@ -484,8 +533,9 @@ void update_statfs(struct gfs2_sbd *sdp, struct buffer_head *m_bh,
        gfs2_statfs_change_out(m_sc, m_bh->b_data + sizeof(struct gfs2_dinode));
 }
 
-int gfs2_statfs_sync(struct gfs2_sbd *sdp)
+int gfs2_statfs_sync(struct super_block *sb, int type)
 {
+       struct gfs2_sbd *sdp = sb->s_fs_info;
        struct gfs2_inode *m_ip = GFS2_I(sdp->sd_statfs_inode);
        struct gfs2_inode *l_ip = GFS2_I(sdp->sd_sc_inode);
        struct gfs2_statfs_change_host *m_sc = &sdp->sd_statfs_master;
@@ -521,6 +571,7 @@ int gfs2_statfs_sync(struct gfs2_sbd *sdp)
                goto out_bh2;
 
        update_statfs(sdp, m_bh, l_bh);
+       sdp->sd_statfs_force_sync = 0;
 
        gfs2_trans_end(sdp);
 
@@ -712,8 +763,8 @@ static int gfs2_make_fs_ro(struct gfs2_sbd *sdp)
        int error;
 
        flush_workqueue(gfs2_delete_workqueue);
-       gfs2_quota_sync(sdp);
-       gfs2_statfs_sync(sdp);
+       gfs2_quota_sync(sdp->sd_vfs, 0);
+       gfs2_statfs_sync(sdp->sd_vfs, 0);
 
        error = gfs2_glock_nq_init(sdp->sd_trans_gl, LM_ST_SHARED, GL_NOCACHE,
                                   &t_gh);
@@ -1061,8 +1112,13 @@ static int gfs2_remount_fs(struct super_block *sb, int *flags, char *data)
 
        spin_lock(&gt->gt_spin);
        args.ar_commit = gt->gt_log_flush_secs;
+       args.ar_quota_quantum = gt->gt_quota_quantum;
+       if (gt->gt_statfs_slow)
+               args.ar_statfs_quantum = 0;
+       else
+               args.ar_statfs_quantum = gt->gt_statfs_quantum;
        spin_unlock(&gt->gt_spin);
-       error = gfs2_mount_args(sdp, &args, data);
+       error = gfs2_mount_args(&args, data);
        if (error)
                return error;
 
@@ -1097,8 +1153,21 @@ static int gfs2_remount_fs(struct super_block *sb, int *flags, char *data)
                sb->s_flags |= MS_POSIXACL;
        else
                sb->s_flags &= ~MS_POSIXACL;
+       if (sdp->sd_args.ar_nobarrier)
+               set_bit(SDF_NOBARRIERS, &sdp->sd_flags);
+       else
+               clear_bit(SDF_NOBARRIERS, &sdp->sd_flags);
        spin_lock(&gt->gt_spin);
        gt->gt_log_flush_secs = args.ar_commit;
+       gt->gt_quota_quantum = args.ar_quota_quantum;
+       if (args.ar_statfs_quantum) {
+               gt->gt_statfs_slow = 0;
+               gt->gt_statfs_quantum = args.ar_statfs_quantum;
+       }
+       else {
+               gt->gt_statfs_slow = 1;
+               gt->gt_statfs_quantum = 30;
+       }
        spin_unlock(&gt->gt_spin);
 
        gfs2_online_uevent(sdp);
@@ -1179,7 +1248,7 @@ static int gfs2_show_options(struct seq_file *s, struct vfsmount *mnt)
 {
        struct gfs2_sbd *sdp = mnt->mnt_sb->s_fs_info;
        struct gfs2_args *args = &sdp->sd_args;
-       int lfsecs;
+       int val;
 
        if (is_ancestor(mnt->mnt_root, sdp->sd_master_dir))
                seq_printf(s, ",meta");
@@ -1240,9 +1309,17 @@ static int gfs2_show_options(struct seq_file *s, struct vfsmount *mnt)
        }
        if (args->ar_discard)
                seq_printf(s, ",discard");
-       lfsecs = sdp->sd_tune.gt_log_flush_secs;
-       if (lfsecs != 60)
-               seq_printf(s, ",commit=%d", lfsecs);
+       val = sdp->sd_tune.gt_log_flush_secs;
+       if (val != 60)
+               seq_printf(s, ",commit=%d", val);
+       val = sdp->sd_tune.gt_statfs_quantum;
+       if (val != 30)
+               seq_printf(s, ",statfs_quantum=%d", val);
+       val = sdp->sd_tune.gt_quota_quantum;
+       if (val != 60)
+               seq_printf(s, ",quota_quantum=%d", val);
+       if (args->ar_statfs_percent)
+               seq_printf(s, ",statfs_percent=%d", args->ar_statfs_percent);
        if (args->ar_errors != GFS2_ERRORS_DEFAULT) {
                const char *state;
 
@@ -1259,6 +1336,9 @@ static int gfs2_show_options(struct seq_file *s, struct vfsmount *mnt)
                }
                seq_printf(s, ",errors=%s", state);
        }
+       if (test_bit(SDF_NOBARRIERS, &sdp->sd_flags))
+               seq_printf(s, ",nobarrier");
+
        return 0;
 }
 
index 235db36828850a5ef555a2da30346f1eb1f47048..3df60f2d84e36b31058102ba836af87d2463f1d9 100644 (file)
@@ -27,7 +27,7 @@ static inline unsigned int gfs2_jindex_size(struct gfs2_sbd *sdp)
 
 extern void gfs2_jindex_free(struct gfs2_sbd *sdp);
 
-extern int gfs2_mount_args(struct gfs2_sbd *sdp, struct gfs2_args *args, char *data);
+extern int gfs2_mount_args(struct gfs2_args *args, char *data);
 
 extern struct gfs2_jdesc *gfs2_jdesc_find(struct gfs2_sbd *sdp, unsigned int jid);
 extern int gfs2_jdesc_check(struct gfs2_jdesc *jd);
@@ -44,7 +44,7 @@ extern void gfs2_statfs_change_in(struct gfs2_statfs_change_host *sc,
                                  const void *buf);
 extern void update_statfs(struct gfs2_sbd *sdp, struct buffer_head *m_bh,
                          struct buffer_head *l_bh);
-extern int gfs2_statfs_sync(struct gfs2_sbd *sdp);
+extern int gfs2_statfs_sync(struct super_block *sb, int type);
 
 extern int gfs2_freeze_fs(struct gfs2_sbd *sdp);
 extern void gfs2_unfreeze_fs(struct gfs2_sbd *sdp);
index 446329728d5278174a3cfebee3827d0cd9cd2e06..c5dad1eb7b916d34884883abe192b9cb89134746 100644 (file)
@@ -158,7 +158,7 @@ static ssize_t statfs_sync_store(struct gfs2_sbd *sdp, const char *buf,
        if (simple_strtol(buf, NULL, 0) != 1)
                return -EINVAL;
 
-       gfs2_statfs_sync(sdp);
+       gfs2_statfs_sync(sdp->sd_vfs, 0);
        return len;
 }
 
@@ -171,13 +171,14 @@ static ssize_t quota_sync_store(struct gfs2_sbd *sdp, const char *buf,
        if (simple_strtol(buf, NULL, 0) != 1)
                return -EINVAL;
 
-       gfs2_quota_sync(sdp);
+       gfs2_quota_sync(sdp->sd_vfs, 0);
        return len;
 }
 
 static ssize_t quota_refresh_user_store(struct gfs2_sbd *sdp, const char *buf,
                                        size_t len)
 {
+       int error;
        u32 id;
 
        if (!capable(CAP_SYS_ADMIN))
@@ -185,13 +186,14 @@ static ssize_t quota_refresh_user_store(struct gfs2_sbd *sdp, const char *buf,
 
        id = simple_strtoul(buf, NULL, 0);
 
-       gfs2_quota_refresh(sdp, 1, id);
-       return len;
+       error = gfs2_quota_refresh(sdp, 1, id);
+       return error ? error : len;
 }
 
 static ssize_t quota_refresh_group_store(struct gfs2_sbd *sdp, const char *buf,
                                         size_t len)
 {
+       int error;
        u32 id;
 
        if (!capable(CAP_SYS_ADMIN))
@@ -199,8 +201,8 @@ static ssize_t quota_refresh_group_store(struct gfs2_sbd *sdp, const char *buf,
 
        id = simple_strtoul(buf, NULL, 0);
 
-       gfs2_quota_refresh(sdp, 0, id);
-       return len;
+       error = gfs2_quota_refresh(sdp, 0, id);
+       return error ? error : len;
 }
 
 static ssize_t demote_rq_store(struct gfs2_sbd *sdp, const char *buf, size_t len)
index 8a0f8ef6ee2700cc5ef62f5090b11d602b9f8b20..912f5cbc4740170e32c56f63ac2d6ecf2ec9d4ac 100644 (file)
@@ -186,8 +186,8 @@ static int ea_find_i(struct gfs2_inode *ip, struct buffer_head *bh,
        return 0;
 }
 
-int gfs2_ea_find(struct gfs2_inode *ip, int type, const char *name,
-                struct gfs2_ea_location *el)
+static int gfs2_ea_find(struct gfs2_inode *ip, int type, const char *name,
+                       struct gfs2_ea_location *el)
 {
        struct ea_find ef;
        int error;
@@ -516,8 +516,8 @@ out:
        return error;
 }
 
-int gfs2_ea_get_copy(struct gfs2_inode *ip, struct gfs2_ea_location *el,
-                    char *data, size_t size)
+static int gfs2_ea_get_copy(struct gfs2_inode *ip, struct gfs2_ea_location *el,
+                           char *data, size_t size)
 {
        int ret;
        size_t len = GFS2_EA_DATA_LEN(el->el_ea);
@@ -534,6 +534,36 @@ int gfs2_ea_get_copy(struct gfs2_inode *ip, struct gfs2_ea_location *el,
        return len;
 }
 
+int gfs2_xattr_acl_get(struct gfs2_inode *ip, const char *name, char **ppdata)
+{
+       struct gfs2_ea_location el;
+       int error;
+       int len;
+       char *data;
+
+       error = gfs2_ea_find(ip, GFS2_EATYPE_SYS, name, &el);
+       if (error)
+               return error;
+       if (!el.el_ea)
+               goto out;
+       if (!GFS2_EA_DATA_LEN(el.el_ea))
+               goto out;
+
+       len = GFS2_EA_DATA_LEN(el.el_ea);
+       data = kmalloc(len, GFP_NOFS);
+       error = -ENOMEM;
+       if (data == NULL)
+               goto out;
+
+       error = gfs2_ea_get_copy(ip, &el, data, len);
+       if (error == 0)
+               error = len;
+       *ppdata = data;
+out:
+       brelse(el.el_bh);
+       return error;
+}
+
 /**
  * gfs2_xattr_get - Get a GFS2 extended attribute
  * @inode: The inode
@@ -1259,22 +1289,26 @@ fail:
        return error;
 }
 
-int gfs2_ea_acl_chmod(struct gfs2_inode *ip, struct gfs2_ea_location *el,
-                     struct iattr *attr, char *data)
+int gfs2_xattr_acl_chmod(struct gfs2_inode *ip, struct iattr *attr, char *data)
 {
+       struct gfs2_ea_location el;
        struct buffer_head *dibh;
        int error;
 
-       if (GFS2_EA_IS_STUFFED(el->el_ea)) {
+       error = gfs2_ea_find(ip, GFS2_EATYPE_SYS, GFS2_POSIX_ACL_ACCESS, &el);
+       if (error)
+               return error;
+
+       if (GFS2_EA_IS_STUFFED(el.el_ea)) {
                error = gfs2_trans_begin(GFS2_SB(&ip->i_inode), RES_DINODE + RES_EATTR, 0);
                if (error)
                        return error;
 
-               gfs2_trans_add_bh(ip->i_gl, el->el_bh, 1);
-               memcpy(GFS2_EA2DATA(el->el_ea), data,
-                      GFS2_EA_DATA_LEN(el->el_ea));
+               gfs2_trans_add_bh(ip->i_gl, el.el_bh, 1);
+               memcpy(GFS2_EA2DATA(el.el_ea), data,
+                      GFS2_EA_DATA_LEN(el.el_ea));
        } else
-               error = ea_acl_chmod_unstuffed(ip, el->el_ea, data);
+               error = ea_acl_chmod_unstuffed(ip, el.el_ea, data);
 
        if (error)
                return error;
@@ -1507,18 +1541,6 @@ static int gfs2_xattr_user_set(struct inode *inode, const char *name,
        return gfs2_xattr_set(inode, GFS2_EATYPE_USR, name, value, size, flags);
 }
 
-static int gfs2_xattr_system_get(struct inode *inode, const char *name,
-                                void *buffer, size_t size)
-{
-       return gfs2_xattr_get(inode, GFS2_EATYPE_SYS, name, buffer, size);
-}
-
-static int gfs2_xattr_system_set(struct inode *inode, const char *name,
-                                const void *value, size_t size, int flags)
-{
-       return gfs2_xattr_set(inode, GFS2_EATYPE_SYS, name, value, size, flags);
-}
-
 static int gfs2_xattr_security_get(struct inode *inode, const char *name,
                                   void *buffer, size_t size)
 {
@@ -1543,12 +1565,6 @@ static struct xattr_handler gfs2_xattr_security_handler = {
        .set    = gfs2_xattr_security_set,
 };
 
-static struct xattr_handler gfs2_xattr_system_handler = {
-       .prefix = XATTR_SYSTEM_PREFIX,
-       .get    = gfs2_xattr_system_get,
-       .set    = gfs2_xattr_system_set,
-};
-
 struct xattr_handler *gfs2_xattr_handlers[] = {
        &gfs2_xattr_user_handler,
        &gfs2_xattr_security_handler,
index cbdfd7743733dad39f891ac42b9bff4cc5f7e9fc..8d6ae5813c4d42317d10600f37d41c708c27d1cb 100644 (file)
@@ -62,11 +62,7 @@ extern int gfs2_ea_dealloc(struct gfs2_inode *ip);
 
 /* Exported to acl.c */
 
-extern int gfs2_ea_find(struct gfs2_inode *ip, int type, const char *name,
-                       struct gfs2_ea_location *el);
-extern int gfs2_ea_get_copy(struct gfs2_inode *ip, struct gfs2_ea_location *el,
-                           char *data, size_t size);
-extern int gfs2_ea_acl_chmod(struct gfs2_inode *ip, struct gfs2_ea_location *el,
-                            struct iattr *attr, char *data);
+extern int gfs2_xattr_acl_get(struct gfs2_inode *ip, const char *name, char **data);
+extern int gfs2_xattr_acl_chmod(struct gfs2_inode *ip, struct iattr *attr, char *data);
 
 #endif /* __EATTR_DOT_H__ */
index 4d8e3be55976272732f6f42610ab7813f66b8133..06c1f02de611d51bc8d4218b29e083bc15eb9c43 100644 (file)
@@ -18,7 +18,6 @@
 #include <linux/hash.h>
 #include <linux/swap.h>
 #include <linux/security.h>
-#include <linux/ima.h>
 #include <linux/pagemap.h>
 #include <linux/cdev.h>
 #include <linux/bootmem.h>
@@ -157,11 +156,6 @@ int inode_init_always(struct super_block *sb, struct inode *inode)
 
        if (security_inode_alloc(inode))
                goto out;
-
-       /* allocate and initialize an i_integrity */
-       if (ima_inode_alloc(inode))
-               goto out_free_security;
-
        spin_lock_init(&inode->i_lock);
        lockdep_set_class(&inode->i_lock, &sb->s_type->i_lock_key);
 
@@ -201,9 +195,6 @@ int inode_init_always(struct super_block *sb, struct inode *inode)
 #endif
 
        return 0;
-
-out_free_security:
-       security_inode_free(inode);
 out:
        return -ENOMEM;
 }
@@ -235,7 +226,6 @@ static struct inode *alloc_inode(struct super_block *sb)
 void __destroy_inode(struct inode *inode)
 {
        BUG_ON(inode_has_buffers(inode));
-       ima_inode_free(inode);
        security_inode_free(inode);
        fsnotify_inode_delete(inode);
 #ifdef CONFIG_FS_POSIX_ACL
index cfe05c1966a582140986e33cf25940683abdafb5..3f39be1b0455a03be83b8cb08bfa224a6dd75d7b 100644 (file)
@@ -164,12 +164,15 @@ int jffs2_read_inode_range(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
 
        /* XXX FIXME: Where a single physical node actually shows up in two
           frags, we read it twice. Don't do that. */
-       /* Now we're pointing at the first frag which overlaps our page */
+       /* Now we're pointing at the first frag which overlaps our page
+        * (or perhaps is before it, if we've been asked to read off the
+        * end of the file). */
        while(offset < end) {
                D2(printk(KERN_DEBUG "jffs2_read_inode_range: offset %d, end %d\n", offset, end));
-               if (unlikely(!frag || frag->ofs > offset)) {
+               if (unlikely(!frag || frag->ofs > offset ||
+                            frag->ofs + frag->size <= offset)) {
                        uint32_t holesize = end - offset;
-                       if (frag) {
+                       if (frag && frag->ofs > offset) {
                                D1(printk(KERN_NOTICE "Eep. Hole in ino #%u fraglist. frag->ofs = 0x%08x, offset = 0x%08x\n", f->inocache->ino, frag->ofs, offset));
                                holesize = min(holesize, frag->ofs - offset);
                        }
index bdc3cb4fd2220c6fde0f35159a902768a75d60f6..7d70d63ceb2948c6b8e25ef7628314a4c0eab3b8 100644 (file)
@@ -1921,6 +1921,16 @@ long do_mount(char *dev_name, char *dir_name, char *type_page,
        if (data_page)
                ((char *)data_page)[PAGE_SIZE - 1] = 0;
 
+       /* ... and get the mountpoint */
+       retval = kern_path(dir_name, LOOKUP_FOLLOW, &path);
+       if (retval)
+               return retval;
+
+       retval = security_sb_mount(dev_name, &path,
+                                  type_page, flags, data_page);
+       if (retval)
+               goto dput_out;
+
        /* Default to relatime unless overriden */
        if (!(flags & MS_NOATIME))
                mnt_flags |= MNT_RELATIME;
@@ -1945,16 +1955,6 @@ long do_mount(char *dev_name, char *dir_name, char *type_page,
                   MS_NOATIME | MS_NODIRATIME | MS_RELATIME| MS_KERNMOUNT |
                   MS_STRICTATIME);
 
-       /* ... and get the mountpoint */
-       retval = kern_path(dir_name, LOOKUP_FOLLOW, &path);
-       if (retval)
-               return retval;
-
-       retval = security_sb_mount(dev_name, &path,
-                                  type_page, flags, data_page);
-       if (retval)
-               goto dput_out;
-
        if (flags & MS_REMOUNT)
                retval = do_remount(&path, flags & ~MS_REMOUNT, mnt_flags,
                                    data_page);
index 70fad69eb9593a41894102164e26db60eb13fa56..fa588006588dd3403bb9a883eedc79ddc4588655 100644 (file)
@@ -359,17 +359,13 @@ int nfs_fscache_release_page(struct page *page, gfp_t gfp)
 
        BUG_ON(!cookie);
 
-       if (fscache_check_page_write(cookie, page)) {
-               if (!(gfp & __GFP_WAIT))
-                       return 0;
-               fscache_wait_on_page_write(cookie, page);
-       }
-
        if (PageFsCache(page)) {
                dfprintk(FSCACHE, "NFS: fscache releasepage (0x%p/0x%p/0x%p)\n",
                         cookie, page, nfsi);
 
-               fscache_uncache_page(cookie, page);
+               if (!fscache_maybe_release_page(cookie, page, gfp))
+                       return 0;
+
                nfs_add_fscache_stats(page->mapping->host,
                                      NFSIOS_FSCACHE_PAGES_UNCACHED, 1);
        }
index ff37454fa783f42196b733a9723dba7567c37f72..741a562177fc3f587dcd1e1019f3cfe53c367de8 100644 (file)
@@ -2767,7 +2767,7 @@ static int _nfs4_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
                .pages = &page,
                .pgbase = 0,
                .count = count,
-               .bitmask = NFS_SERVER(dentry->d_inode)->cache_consistency_bitmask,
+               .bitmask = NFS_SERVER(dentry->d_inode)->attr_bitmask,
        };
        struct nfs4_readdir_res res;
        struct rpc_message msg = {
index edf926e1062f8be520b4b64de72e9f26e7aaa0f6..d0a2ce1b43248a6eacbff2b4804314c57b898cbc 100644 (file)
@@ -958,7 +958,7 @@ encode_entry(struct readdir_cd *ccd, const char *name, int namlen,
                p1 = encode_entry_baggage(cd, p1, name, namlen, ino);
 
                if (plus)
-                       p = encode_entryplus_baggage(cd, p1, name, namlen);
+                       p1 = encode_entryplus_baggage(cd, p1, name, namlen);
 
                /* determine entry word length and lengths to go in pages */
                num_entry_words = p1 - tmp;
index 1c6cfb59128d6b522139cd26274efe76ca054415..3f5d5d06f53c32990cdaf817b0008fa6386bbdb7 100644 (file)
@@ -871,7 +871,6 @@ int nilfs_cpfile_change_cpmode(struct inode *cpfile, __u64 cno, int mode)
                 * exclusive with a new mount job.  Though it doesn't cover
                 * umount, it's enough for the purpose.
                 */
-               mutex_lock(&nilfs->ns_mount_mutex);
                if (nilfs_checkpoint_is_mounted(nilfs, cno, 1)) {
                        /* Current implementation does not have to protect
                           plain read-only mounts since they are exclusive
@@ -880,7 +879,6 @@ int nilfs_cpfile_change_cpmode(struct inode *cpfile, __u64 cno, int mode)
                        ret = -EBUSY;
                } else
                        ret = nilfs_cpfile_clear_snapshot(cpfile, cno);
-               mutex_unlock(&nilfs->ns_mount_mutex);
                return ret;
        case NILFS_SNAPSHOT:
                return nilfs_cpfile_set_snapshot(cpfile, cno);
index 5040220c3732866ad2f9bd7b4c79a81ee8c5883f..2a0a5a3ac1346826b6f1c7ca668a5859b16a00dc 100644 (file)
@@ -664,7 +664,6 @@ int nilfs_load_inode_block(struct nilfs_sb_info *sbi, struct inode *inode,
        int err;
 
        spin_lock(&sbi->s_inode_lock);
-       /* Caller of this function MUST lock s_inode_lock */
        if (ii->i_bh == NULL) {
                spin_unlock(&sbi->s_inode_lock);
                err = nilfs_ifile_get_inode_block(sbi->s_ifile, inode->i_ino,
index d24057d58f173e7f09e88a9993ce5ad879f0cbc9..f6af76042d80fe8f7278bb2fa791fdc7b2551a21 100644 (file)
@@ -99,7 +99,8 @@ static int nilfs_ioctl_wrap_copy(struct the_nilfs *nilfs,
 static int nilfs_ioctl_change_cpmode(struct inode *inode, struct file *filp,
                                     unsigned int cmd, void __user *argp)
 {
-       struct inode *cpfile = NILFS_SB(inode->i_sb)->s_nilfs->ns_cpfile;
+       struct the_nilfs *nilfs = NILFS_SB(inode->i_sb)->s_nilfs;
+       struct inode *cpfile = nilfs->ns_cpfile;
        struct nilfs_transaction_info ti;
        struct nilfs_cpmode cpmode;
        int ret;
@@ -109,14 +110,17 @@ static int nilfs_ioctl_change_cpmode(struct inode *inode, struct file *filp,
        if (copy_from_user(&cpmode, argp, sizeof(cpmode)))
                return -EFAULT;
 
+       mutex_lock(&nilfs->ns_mount_mutex);
        nilfs_transaction_begin(inode->i_sb, &ti, 0);
        ret = nilfs_cpfile_change_cpmode(
                cpfile, cpmode.cm_cno, cpmode.cm_mode);
        if (unlikely(ret < 0)) {
                nilfs_transaction_abort(inode->i_sb);
+               mutex_unlock(&nilfs->ns_mount_mutex);
                return ret;
        }
        nilfs_transaction_commit(inode->i_sb); /* never fails */
+       mutex_unlock(&nilfs->ns_mount_mutex);
        return ret;
 }
 
index 89fc8ee1f5a5932ea40bba6537bd9a8e319f1c84..de059f49058694b7887c49f5d907deb32760bb82 100644 (file)
@@ -1712,7 +1712,8 @@ int ocfs2_check_range_for_refcount(struct inode *inode, loff_t pos,
        struct super_block *sb = inode->i_sb;
 
        if (!ocfs2_refcount_tree(OCFS2_SB(inode->i_sb)) ||
-           !(OCFS2_I(inode)->ip_dyn_features & OCFS2_HAS_REFCOUNT_FL))
+           !(OCFS2_I(inode)->ip_dyn_features & OCFS2_HAS_REFCOUNT_FL) ||
+           OCFS2_I(inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL)
                return 0;
 
        cpos = pos >> OCFS2_SB(sb)->s_clustersize_bits;
index eae4046024241131eb948a9d8539fc5158878c44..d963d863870994075b8af17c84484c09cb0b84d8 100644 (file)
 #include <linux/kref.h>
 #include <linux/mutex.h>
 #include <linux/lockdep.h>
-#ifndef CONFIG_OCFS2_COMPAT_JBD
-# include <linux/jbd2.h>
-#else
-# include <linux/jbd.h>
-# include "ocfs2_jbd_compat.h"
-#endif
+#include <linux/jbd2.h>
 
 /* For union ocfs2_dlm_lksb */
 #include "stackglue.h"
index 60287fc56bcb3a73eb53612539effc28eece9e4c..3a0df7a1b8109666b92dea616c1b45ce57a2add9 100644 (file)
@@ -3743,6 +3743,9 @@ static int ocfs2_attach_refcount_tree(struct inode *inode,
                goto out;
        }
 
+       if (oi->ip_dyn_features & OCFS2_INLINE_DATA_FL)
+               goto attach_xattr;
+
        ocfs2_init_dinode_extent_tree(&di_et, INODE_CACHE(inode), di_bh);
 
        size = i_size_read(inode);
@@ -3769,6 +3772,7 @@ static int ocfs2_attach_refcount_tree(struct inode *inode,
                cpos += num_clusters;
        }
 
+attach_xattr:
        if (oi->ip_dyn_features & OCFS2_HAS_XATTR_FL) {
                ret = ocfs2_xattr_attach_refcount_tree(inode, di_bh,
                                                       &ref_tree->rf_ci,
@@ -3858,6 +3862,49 @@ out:
        return ret;
 }
 
+static int ocfs2_duplicate_inline_data(struct inode *s_inode,
+                                      struct buffer_head *s_bh,
+                                      struct inode *t_inode,
+                                      struct buffer_head *t_bh)
+{
+       int ret;
+       handle_t *handle;
+       struct ocfs2_super *osb = OCFS2_SB(s_inode->i_sb);
+       struct ocfs2_dinode *s_di = (struct ocfs2_dinode *)s_bh->b_data;
+       struct ocfs2_dinode *t_di = (struct ocfs2_dinode *)t_bh->b_data;
+
+       BUG_ON(!(OCFS2_I(s_inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL));
+
+       handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS);
+       if (IS_ERR(handle)) {
+               ret = PTR_ERR(handle);
+               mlog_errno(ret);
+               goto out;
+       }
+
+       ret = ocfs2_journal_access_di(handle, INODE_CACHE(t_inode), t_bh,
+                                     OCFS2_JOURNAL_ACCESS_WRITE);
+       if (ret) {
+               mlog_errno(ret);
+               goto out_commit;
+       }
+
+       t_di->id2.i_data.id_count = s_di->id2.i_data.id_count;
+       memcpy(t_di->id2.i_data.id_data, s_di->id2.i_data.id_data,
+              le16_to_cpu(s_di->id2.i_data.id_count));
+       spin_lock(&OCFS2_I(t_inode)->ip_lock);
+       OCFS2_I(t_inode)->ip_dyn_features |= OCFS2_INLINE_DATA_FL;
+       t_di->i_dyn_features = cpu_to_le16(OCFS2_I(t_inode)->ip_dyn_features);
+       spin_unlock(&OCFS2_I(t_inode)->ip_lock);
+
+       ocfs2_journal_dirty(handle, t_bh);
+
+out_commit:
+       ocfs2_commit_trans(osb, handle);
+out:
+       return ret;
+}
+
 static int ocfs2_duplicate_extent_list(struct inode *s_inode,
                                struct inode *t_inode,
                                struct buffer_head *t_bh,
@@ -3997,6 +4044,14 @@ static int ocfs2_create_reflink_node(struct inode *s_inode,
                goto out;
        }
 
+       if (OCFS2_I(s_inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL) {
+               ret = ocfs2_duplicate_inline_data(s_inode, s_bh,
+                                                 t_inode, t_bh);
+               if (ret)
+                       mlog_errno(ret);
+               goto out;
+       }
+
        ret = ocfs2_lock_refcount_tree(osb, le64_to_cpu(di->i_refcount_loc),
                                       1, &ref_tree, &ref_root_bh);
        if (ret) {
@@ -4013,10 +4068,6 @@ static int ocfs2_create_reflink_node(struct inode *s_inode,
                goto out_unlock_refcount;
        }
 
-       ret = ocfs2_complete_reflink(s_inode, s_bh, t_inode, t_bh, preserve);
-       if (ret)
-               mlog_errno(ret);
-
 out_unlock_refcount:
        ocfs2_unlock_refcount_tree(osb, ref_tree, 1);
        brelse(ref_root_bh);
@@ -4068,9 +4119,17 @@ static int __ocfs2_reflink(struct dentry *old_dentry,
                ret = ocfs2_reflink_xattrs(inode, old_bh,
                                           new_inode, new_bh,
                                           preserve);
-               if (ret)
+               if (ret) {
                        mlog_errno(ret);
+                       goto inode_unlock;
+               }
        }
+
+       ret = ocfs2_complete_reflink(inode, old_bh,
+                                    new_inode, new_bh, preserve);
+       if (ret)
+               mlog_errno(ret);
+
 inode_unlock:
        ocfs2_inode_unlock(new_inode, 1);
        brelse(new_bh);
index c0e48aeebb1c3877862853ec1761bed05e6f9355..14f47d2bfe02eb6500666e8a63a227a2d4ee10f2 100644 (file)
@@ -773,18 +773,20 @@ static int ocfs2_sb_probe(struct super_block *sb,
                if (tmpstat < 0) {
                        status = tmpstat;
                        mlog_errno(status);
-                       goto bail;
+                       break;
                }
                di = (struct ocfs2_dinode *) (*bh)->b_data;
                memset(stats, 0, sizeof(struct ocfs2_blockcheck_stats));
                spin_lock_init(&stats->b_lock);
-               status = ocfs2_verify_volume(di, *bh, blksize, stats);
-               if (status >= 0)
-                       goto bail;
-               brelse(*bh);
-               *bh = NULL;
-               if (status != -EAGAIN)
+               tmpstat = ocfs2_verify_volume(di, *bh, blksize, stats);
+               if (tmpstat < 0) {
+                       brelse(*bh);
+                       *bh = NULL;
+               }
+               if (tmpstat != -EAGAIN) {
+                       status = tmpstat;
                        break;
+               }
        }
 
 bail:
@@ -1645,6 +1647,10 @@ static int ocfs2_statfs(struct dentry *dentry, struct kstatfs *buf)
        buf->f_bavail = buf->f_bfree;
        buf->f_files = numbits;
        buf->f_ffree = freebits;
+       buf->f_fsid.val[0] = crc32_le(0, osb->uuid_str, OCFS2_VOL_UUID_LEN)
+                               & 0xFFFFFFFFUL;
+       buf->f_fsid.val[1] = crc32_le(0, osb->uuid_str + OCFS2_VOL_UUID_LEN,
+                               OCFS2_VOL_UUID_LEN) & 0xFFFFFFFFUL;
 
        brelse(bh);
 
index b6284f235d2ff9e54e15834014ebc8f3e059851d..c61369342a276e17a6e35fcc79df544a2bd4419c 100644 (file)
 #include <linux/highmem.h>
 #include <linux/buffer_head.h>
 #include <linux/rbtree.h>
-#ifndef CONFIG_OCFS2_COMPAT_JBD
-# include <linux/jbd2.h>
-#else
-# include <linux/jbd.h>
-#endif
 
 #define MLOG_MASK_PREFIX ML_UPTODATE
 
index 4f01e06227c69190525944d4a6da07b850715172..b4b31d277f3aa537efe1ebaa9d847dca86835214 100644 (file)
--- a/fs/open.c
+++ b/fs/open.c
@@ -587,6 +587,9 @@ SYSCALL_DEFINE1(chroot, const char __user *, filename)
        error = -EPERM;
        if (!capable(CAP_SYS_CHROOT))
                goto dput_and_out;
+       error = security_path_chroot(&path);
+       if (error)
+               goto dput_and_out;
 
        set_fs_root(current->fs, &path);
        error = 0;
@@ -617,11 +620,15 @@ SYSCALL_DEFINE2(fchmod, unsigned int, fd, mode_t, mode)
        if (err)
                goto out_putf;
        mutex_lock(&inode->i_mutex);
+       err = security_path_chmod(dentry, file->f_vfsmnt, mode);
+       if (err)
+               goto out_unlock;
        if (mode == (mode_t) -1)
                mode = inode->i_mode;
        newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
        newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
        err = notify_change(dentry, &newattrs);
+out_unlock:
        mutex_unlock(&inode->i_mutex);
        mnt_drop_write(file->f_path.mnt);
 out_putf:
@@ -646,11 +653,15 @@ SYSCALL_DEFINE3(fchmodat, int, dfd, const char __user *, filename, mode_t, mode)
        if (error)
                goto dput_and_out;
        mutex_lock(&inode->i_mutex);
+       error = security_path_chmod(path.dentry, path.mnt, mode);
+       if (error)
+               goto out_unlock;
        if (mode == (mode_t) -1)
                mode = inode->i_mode;
        newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
        newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
        error = notify_change(path.dentry, &newattrs);
+out_unlock:
        mutex_unlock(&inode->i_mutex);
        mnt_drop_write(path.mnt);
 dput_and_out:
@@ -664,9 +675,9 @@ SYSCALL_DEFINE2(chmod, const char __user *, filename, mode_t, mode)
        return sys_fchmodat(AT_FDCWD, filename, mode);
 }
 
-static int chown_common(struct dentry * dentry, uid_t user, gid_t group)
+static int chown_common(struct path *path, uid_t user, gid_t group)
 {
-       struct inode *inode = dentry->d_inode;
+       struct inode *inode = path->dentry->d_inode;
        int error;
        struct iattr newattrs;
 
@@ -683,7 +694,9 @@ static int chown_common(struct dentry * dentry, uid_t user, gid_t group)
                newattrs.ia_valid |=
                        ATTR_KILL_SUID | ATTR_KILL_SGID | ATTR_KILL_PRIV;
        mutex_lock(&inode->i_mutex);
-       error = notify_change(dentry, &newattrs);
+       error = security_path_chown(path, user, group);
+       if (!error)
+               error = notify_change(path->dentry, &newattrs);
        mutex_unlock(&inode->i_mutex);
 
        return error;
@@ -700,7 +713,7 @@ SYSCALL_DEFINE3(chown, const char __user *, filename, uid_t, user, gid_t, group)
        error = mnt_want_write(path.mnt);
        if (error)
                goto out_release;
-       error = chown_common(path.dentry, user, group);
+       error = chown_common(&path, user, group);
        mnt_drop_write(path.mnt);
 out_release:
        path_put(&path);
@@ -725,7 +738,7 @@ SYSCALL_DEFINE5(fchownat, int, dfd, const char __user *, filename, uid_t, user,
        error = mnt_want_write(path.mnt);
        if (error)
                goto out_release;
-       error = chown_common(path.dentry, user, group);
+       error = chown_common(&path, user, group);
        mnt_drop_write(path.mnt);
 out_release:
        path_put(&path);
@@ -744,7 +757,7 @@ SYSCALL_DEFINE3(lchown, const char __user *, filename, uid_t, user, gid_t, group
        error = mnt_want_write(path.mnt);
        if (error)
                goto out_release;
-       error = chown_common(path.dentry, user, group);
+       error = chown_common(&path, user, group);
        mnt_drop_write(path.mnt);
 out_release:
        path_put(&path);
@@ -767,7 +780,7 @@ SYSCALL_DEFINE3(fchown, unsigned int, fd, uid_t, user, gid_t, group)
                goto out_fput;
        dentry = file->f_path.dentry;
        audit_inode(NULL, dentry);
-       error = chown_common(dentry, user, group);
+       error = chown_common(&file->f_path, user, group);
        mnt_drop_write(file->f_path.mnt);
 out_fput:
        fput(file);
index 07f77a7945c320e7b9ac133e523f83b9824691e2..822c2d5065189906cd6a63bedd27875290964e04 100644 (file)
@@ -571,7 +571,7 @@ static int do_task_stat(struct seq_file *m, struct pid_namespace *ns,
                rsslim,
                mm ? mm->start_code : 0,
                mm ? mm->end_code : 0,
-               (permitted) ? task->stack_start : 0,
+               (permitted && mm) ? task->stack_start : 0,
                esp,
                eip,
                /* The signal information here is obsolete.
index 8047e01ef46bf996410255e3da9dcf97a45eed30..353e78a9ebeec6067573895764fbc5d3d64965b7 100644 (file)
@@ -17,7 +17,7 @@ config QUOTA
 
 config QUOTA_NETLINK_INTERFACE
        bool "Report quota messages through netlink interface"
-       depends on QUOTA && NET
+       depends on QUOTACTL && NET
        help
          If you say Y here, quota warnings (about exceeding softlimit, reaching
          hardlimit, etc.) will be reported through netlink interface. If unsure,
index 39b49c42a7ed85ace513954d411bcbea72d5fb8f..9b6ad908dcb24719baa8dd5e3f25117e29c9c46c 100644 (file)
 #include <linux/capability.h>
 #include <linux/quotaops.h>
 #include <linux/writeback.h> /* for inode_lock, oddly enough.. */
-#ifdef CONFIG_QUOTA_NETLINK_INTERFACE
-#include <net/netlink.h>
-#include <net/genetlink.h>
-#endif
 
 #include <asm/uaccess.h>
 
@@ -1071,73 +1067,6 @@ static void print_warning(struct dquot *dquot, const int warntype)
 }
 #endif
 
-#ifdef CONFIG_QUOTA_NETLINK_INTERFACE
-
-/* Netlink family structure for quota */
-static struct genl_family quota_genl_family = {
-       .id = GENL_ID_GENERATE,
-       .hdrsize = 0,
-       .name = "VFS_DQUOT",
-       .version = 1,
-       .maxattr = QUOTA_NL_A_MAX,
-};
-
-/* Send warning to userspace about user which exceeded quota */
-static void send_warning(const struct dquot *dquot, const char warntype)
-{
-       static atomic_t seq;
-       struct sk_buff *skb;
-       void *msg_head;
-       int ret;
-       int msg_size = 4 * nla_total_size(sizeof(u32)) +
-                      2 * nla_total_size(sizeof(u64));
-
-       /* We have to allocate using GFP_NOFS as we are called from a
-        * filesystem performing write and thus further recursion into
-        * the fs to free some data could cause deadlocks. */
-       skb = genlmsg_new(msg_size, GFP_NOFS);
-       if (!skb) {
-               printk(KERN_ERR
-                 "VFS: Not enough memory to send quota warning.\n");
-               return;
-       }
-       msg_head = genlmsg_put(skb, 0, atomic_add_return(1, &seq),
-                       &quota_genl_family, 0, QUOTA_NL_C_WARNING);
-       if (!msg_head) {
-               printk(KERN_ERR
-                 "VFS: Cannot store netlink header in quota warning.\n");
-               goto err_out;
-       }
-       ret = nla_put_u32(skb, QUOTA_NL_A_QTYPE, dquot->dq_type);
-       if (ret)
-               goto attr_err_out;
-       ret = nla_put_u64(skb, QUOTA_NL_A_EXCESS_ID, dquot->dq_id);
-       if (ret)
-               goto attr_err_out;
-       ret = nla_put_u32(skb, QUOTA_NL_A_WARNING, warntype);
-       if (ret)
-               goto attr_err_out;
-       ret = nla_put_u32(skb, QUOTA_NL_A_DEV_MAJOR,
-               MAJOR(dquot->dq_sb->s_dev));
-       if (ret)
-               goto attr_err_out;
-       ret = nla_put_u32(skb, QUOTA_NL_A_DEV_MINOR,
-               MINOR(dquot->dq_sb->s_dev));
-       if (ret)
-               goto attr_err_out;
-       ret = nla_put_u64(skb, QUOTA_NL_A_CAUSED_ID, current_uid());
-       if (ret)
-               goto attr_err_out;
-       genlmsg_end(skb, msg_head);
-
-       genlmsg_multicast(skb, 0, quota_genl_family.id, GFP_NOFS);
-       return;
-attr_err_out:
-       printk(KERN_ERR "VFS: Not enough space to compose quota message!\n");
-err_out:
-       kfree_skb(skb);
-}
-#endif
 /*
  * Write warnings to the console and send warning messages over netlink.
  *
@@ -1145,18 +1074,20 @@ err_out:
  */
 static void flush_warnings(struct dquot *const *dquots, char *warntype)
 {
+       struct dquot *dq;
        int i;
 
-       for (i = 0; i < MAXQUOTAS; i++)
-               if (dquots[i] && warntype[i] != QUOTA_NL_NOWARN &&
-                   !warning_issued(dquots[i], warntype[i])) {
+       for (i = 0; i < MAXQUOTAS; i++) {
+               dq = dquots[i];
+               if (dq && warntype[i] != QUOTA_NL_NOWARN &&
+                   !warning_issued(dq, warntype[i])) {
 #ifdef CONFIG_PRINT_QUOTA_WARNING
-                       print_warning(dquots[i], warntype[i]);
-#endif
-#ifdef CONFIG_QUOTA_NETLINK_INTERFACE
-                       send_warning(dquots[i], warntype[i]);
+                       print_warning(dq, warntype[i]);
 #endif
+                       quota_send_warning(dq->dq_type, dq->dq_id,
+                                          dq->dq_sb->s_dev, warntype[i]);
                }
+       }
 }
 
 static int ignore_hardlimit(struct dquot *dquot)
@@ -2607,12 +2538,6 @@ static int __init dquot_init(void)
 
        register_shrinker(&dqcache_shrinker);
 
-#ifdef CONFIG_QUOTA_NETLINK_INTERFACE
-       if (genl_register_family(&quota_genl_family) != 0)
-               printk(KERN_ERR
-                      "VFS: Failed to create quota netlink interface.\n");
-#endif
-
        return 0;
 }
 module_init(dquot_init);
index 95c5b42384b29367aab4483872eaa66e06bfcd68..ee91e2756950eedc62e3f44934a23601cc8de6ea 100644 (file)
@@ -18,6 +18,8 @@
 #include <linux/capability.h>
 #include <linux/quotaops.h>
 #include <linux/types.h>
+#include <net/netlink.h>
+#include <net/genetlink.h>
 
 /* Check validity of generic quotactl commands */
 static int generic_quotactl_valid(struct super_block *sb, int type, int cmd,
@@ -525,3 +527,94 @@ asmlinkage long sys32_quotactl(unsigned int cmd, const char __user *special,
        return ret;
 }
 #endif
+
+
+#ifdef CONFIG_QUOTA_NETLINK_INTERFACE
+
+/* Netlink family structure for quota */
+static struct genl_family quota_genl_family = {
+       .id = GENL_ID_GENERATE,
+       .hdrsize = 0,
+       .name = "VFS_DQUOT",
+       .version = 1,
+       .maxattr = QUOTA_NL_A_MAX,
+};
+
+/**
+ * quota_send_warning - Send warning to userspace about exceeded quota
+ * @type: The quota type: USRQQUOTA, GRPQUOTA,...
+ * @id: The user or group id of the quota that was exceeded
+ * @dev: The device on which the fs is mounted (sb->s_dev)
+ * @warntype: The type of the warning: QUOTA_NL_...
+ *
+ * This can be used by filesystems (including those which don't use
+ * dquot) to send a message to userspace relating to quota limits.
+ *
+ */
+
+void quota_send_warning(short type, unsigned int id, dev_t dev,
+                       const char warntype)
+{
+       static atomic_t seq;
+       struct sk_buff *skb;
+       void *msg_head;
+       int ret;
+       int msg_size = 4 * nla_total_size(sizeof(u32)) +
+                      2 * nla_total_size(sizeof(u64));
+
+       /* We have to allocate using GFP_NOFS as we are called from a
+        * filesystem performing write and thus further recursion into
+        * the fs to free some data could cause deadlocks. */
+       skb = genlmsg_new(msg_size, GFP_NOFS);
+       if (!skb) {
+               printk(KERN_ERR
+                 "VFS: Not enough memory to send quota warning.\n");
+               return;
+       }
+       msg_head = genlmsg_put(skb, 0, atomic_add_return(1, &seq),
+                       &quota_genl_family, 0, QUOTA_NL_C_WARNING);
+       if (!msg_head) {
+               printk(KERN_ERR
+                 "VFS: Cannot store netlink header in quota warning.\n");
+               goto err_out;
+       }
+       ret = nla_put_u32(skb, QUOTA_NL_A_QTYPE, type);
+       if (ret)
+               goto attr_err_out;
+       ret = nla_put_u64(skb, QUOTA_NL_A_EXCESS_ID, id);
+       if (ret)
+               goto attr_err_out;
+       ret = nla_put_u32(skb, QUOTA_NL_A_WARNING, warntype);
+       if (ret)
+               goto attr_err_out;
+       ret = nla_put_u32(skb, QUOTA_NL_A_DEV_MAJOR, MAJOR(dev));
+       if (ret)
+               goto attr_err_out;
+       ret = nla_put_u32(skb, QUOTA_NL_A_DEV_MINOR, MINOR(dev));
+       if (ret)
+               goto attr_err_out;
+       ret = nla_put_u64(skb, QUOTA_NL_A_CAUSED_ID, current_uid());
+       if (ret)
+               goto attr_err_out;
+       genlmsg_end(skb, msg_head);
+
+       genlmsg_multicast(skb, 0, quota_genl_family.id, GFP_NOFS);
+       return;
+attr_err_out:
+       printk(KERN_ERR "VFS: Not enough space to compose quota message!\n");
+err_out:
+       kfree_skb(skb);
+}
+EXPORT_SYMBOL(quota_send_warning);
+
+static int __init quota_init(void)
+{
+       if (genl_register_family(&quota_genl_family) != 0)
+               printk(KERN_ERR
+                      "VFS: Failed to create quota netlink interface.\n");
+       return 0;
+};
+
+module_init(quota_init);
+#endif
+
index c6ad7c7e3ee9eaa58c4a7994c316f4f4a24fd45a..05ac0fe9c4d3cb7e62dab0510c398e5e026935eb 100644 (file)
@@ -36,7 +36,7 @@ posix_acl_from_xattr(const void *value, size_t size)
        if (count == 0)
                return NULL;
        
-       acl = posix_acl_alloc(count, GFP_KERNEL);
+       acl = posix_acl_alloc(count, GFP_NOFS);
        if (!acl)
                return ERR_PTR(-ENOMEM);
        acl_e = acl->a_entries;
index 1099395d7d6c1cc5250adec130da128a1469ab64..fb17f8226b0955eddc3ee3130708750f72fa3f29 100644 (file)
@@ -1980,7 +1980,7 @@ xlog_recover_do_reg_buffer(
                                        "XFS: NULL dquot in %s.", __func__);
                                goto next;
                        }
-                       if (item->ri_buf[i].i_len < sizeof(xfs_dqblk_t)) {
+                       if (item->ri_buf[i].i_len < sizeof(xfs_disk_dquot_t)) {
                                cmn_err(CE_ALERT,
                                        "XFS: dquot too small (%d) in %s.",
                                        item->ri_buf[i].i_len, __func__);
@@ -2635,7 +2635,7 @@ xlog_recover_do_dquot_trans(
                        "XFS: NULL dquot in %s.", __func__);
                return XFS_ERROR(EIO);
        }
-       if (item->ri_buf[1].i_len < sizeof(xfs_dqblk_t)) {
+       if (item->ri_buf[1].i_len < sizeof(xfs_disk_dquot_t)) {
                cmn_err(CE_ALERT,
                        "XFS: dquot too small (%d) in %s.",
                        item->ri_buf[1].i_len, __func__);
index f31271c30de9bc6edf1b2ac575195585f6f99f3a..2ffc570679bef017199f59fafa64b9e9c9433797 100644 (file)
@@ -467,6 +467,7 @@ xfs_trans_ail_update(
 {
        xfs_log_item_t          *dlip = NULL;
        xfs_log_item_t          *mlip;  /* ptr to minimum lip */
+       xfs_lsn_t               tail_lsn;
 
        mlip = xfs_ail_min(ailp);
 
@@ -483,8 +484,16 @@ xfs_trans_ail_update(
 
        if (mlip == dlip) {
                mlip = xfs_ail_min(ailp);
+               /*
+                * It is not safe to access mlip after the AIL lock is
+                * dropped, so we must get a copy of li_lsn before we do
+                * so.  This is especially important on 32-bit platforms
+                * where accessing and updating 64-bit values like li_lsn
+                * is not atomic.
+                */
+               tail_lsn = mlip->li_lsn;
                spin_unlock(&ailp->xa_lock);
-               xfs_log_move_tail(ailp->xa_mount, mlip->li_lsn);
+               xfs_log_move_tail(ailp->xa_mount, tail_lsn);
        } else {
                spin_unlock(&ailp->xa_lock);
        }
@@ -514,6 +523,7 @@ xfs_trans_ail_delete(
 {
        xfs_log_item_t          *dlip;
        xfs_log_item_t          *mlip;
+       xfs_lsn_t               tail_lsn;
 
        if (lip->li_flags & XFS_LI_IN_AIL) {
                mlip = xfs_ail_min(ailp);
@@ -527,9 +537,16 @@ xfs_trans_ail_delete(
 
                if (mlip == dlip) {
                        mlip = xfs_ail_min(ailp);
+                       /*
+                        * It is not safe to access mlip after the AIL lock
+                        * is dropped, so we must get a copy of li_lsn
+                        * before we do so.  This is especially important
+                        * on 32-bit platforms where accessing and updating
+                        * 64-bit values like li_lsn is not atomic.
+                        */
+                       tail_lsn = mlip ? mlip->li_lsn : 0;
                        spin_unlock(&ailp->xa_lock);
-                       xfs_log_move_tail(ailp->xa_mount,
-                                               (mlip ? mlip->li_lsn : 0));
+                       xfs_log_move_tail(ailp->xa_mount, tail_lsn);
                } else {
                        spin_unlock(&ailp->xa_lock);
                }
index cd2d7896e34baede0f7e3f37c1c25f91057d18db..495dc8af4044fa1cb15898dc5c1450f8ecfb19a8 100644 (file)
@@ -89,7 +89,7 @@
 
 #define F_OWNER_TID    0
 #define F_OWNER_PID    1
-#define F_OWNER_GID    2
+#define F_OWNER_PGRP   2
 
 struct f_owner_ex {
        int     type;
index 1feed71551c9676b6863cf1bc96ef4c2cd86ea60..5a5385749e1636a5c327c1c728243eadad25e0af 100644 (file)
@@ -330,6 +330,7 @@ unifdef-y += scc.h
 unifdef-y += sched.h
 unifdef-y += screen_info.h
 unifdef-y += sdla.h
+unifdef-y += securebits.h
 unifdef-y += selinux_netlink.h
 unifdef-y += sem.h
 unifdef-y += serial_core.h
index dd97fb8408a87afe15c4c671e908a255562286d4..b10ec49ee2dda23a50a237e44912e42e4c82599f 100644 (file)
@@ -53,6 +53,7 @@ extern void free_bootmem_node(pg_data_t *pgdat,
                              unsigned long addr,
                              unsigned long size);
 extern void free_bootmem(unsigned long addr, unsigned long size);
+extern void free_bootmem_late(unsigned long addr, unsigned long size);
 
 /*
  * Flags for reserve_bootmem (also if CONFIG_HAVE_ARCH_BOOTMEM_NODE,
index c8f2a5f70ed5b45817243ab5d1bb0413094a2bf7..39e5ff512fbeab16280345eb3e54beb78e8ed0e7 100644 (file)
@@ -92,9 +92,7 @@ struct vfs_cap_data {
 #define _KERNEL_CAPABILITY_VERSION _LINUX_CAPABILITY_VERSION_3
 #define _KERNEL_CAPABILITY_U32S    _LINUX_CAPABILITY_U32S_3
 
-#ifdef CONFIG_SECURITY_FILE_CAPABILITIES
 extern int file_caps_enabled;
-#endif
 
 typedef struct kernel_cap_struct {
        __u32 cap[_KERNEL_CAPABILITY_U32S];
index a3ed7cb8ca346e7fba7170022c46928480b896a6..73dcf804bc940e6738f5f0f553f3cf2045f78fd7 100644 (file)
@@ -79,6 +79,7 @@
 #define  noinline                      __attribute__((noinline))
 #define __attribute_const__            __attribute__((__const__))
 #define __maybe_unused                 __attribute__((unused))
+#define __always_unused                        __attribute__((unused))
 
 #define __gcc_header(x) #x
 #define _gcc_header(x) __gcc_header(linux/compiler-gcc##x.h)
index 450fa597c94d22dce8cf28d6387d04145c046f97..ab3af40a53c6d6ffbc4b296fa46ed656e9099dc7 100644 (file)
    the kernel context */
 #define __cold                 __attribute__((__cold__))
 
+
+#if __GNUC_MINOR__ >= 5
+/*
+ * Mark a position in code as unreachable.  This can be used to
+ * suppress control flow warnings after asm blocks that transfer
+ * control elsewhere.
+ *
+ * Early snapshots of gcc 4.5 don't support this and we can't detect
+ * this in the preprocessor, but we can live with this because they're
+ * unreleased.  Really, we need to have autoconf for the kernel.
+ */
+#define unreachable() __builtin_unreachable()
+#endif
+
 #endif
index 04fb5135b4e16eea28e3e847d2ed36c01c78a88a..acbd654cc850beec15eae58fc6f1ed1cec7ac0cf 100644 (file)
@@ -144,6 +144,11 @@ void ftrace_likely_update(struct ftrace_branch_data *f, int val, int expect);
 # define barrier() __memory_barrier()
 #endif
 
+/* Unreachable code */
+#ifndef unreachable
+# define unreachable() do { } while (1)
+#endif
+
 #ifndef RELOC_HIDE
 # define RELOC_HIDE(ptr, off)                                  \
   ({ unsigned long __ptr;                                      \
@@ -213,6 +218,10 @@ void ftrace_likely_update(struct ftrace_branch_data *f, int val, int expect);
 # define __maybe_unused                /* unimplemented */
 #endif
 
+#ifndef __always_unused
+# define __always_unused       /* unimplemented */
+#endif
+
 #ifndef noinline
 #define noinline
 #endif
index 4a2b162c256aac373afa166638fbed5938b773db..5de4c9e5856d52d670cd3160d038d94ae9a976ee 100644 (file)
@@ -208,16 +208,9 @@ struct dmar_atsr_unit {
        u8 include_all:1;               /* include all ports */
 };
 
-/* Intel DMAR  initialization functions */
 extern int intel_iommu_init(void);
-#else
-static inline int intel_iommu_init(void)
-{
-#ifdef CONFIG_INTR_REMAP
-       return dmar_dev_scope_init();
-#else
-       return -ENODEV;
-#endif
-}
-#endif /* !CONFIG_DMAR */
+#else /* !CONFIG_DMAR: */
+static inline int intel_iommu_init(void) { return -ENODEV; }
+#endif /* CONFIG_DMAR */
+
 #endif /* __DMAR_H__ */
index 84d3532dd3eada229bb0f3642092c73675cc7a12..7be0c6fbe8808be086d884939c7c621e3f5d78cf 100644 (file)
@@ -91,6 +91,8 @@ struct fscache_operation {
 #define FSCACHE_OP_WAITING     4       /* cleared when op is woken */
 #define FSCACHE_OP_EXCLUSIVE   5       /* exclusive op, other ops must wait */
 #define FSCACHE_OP_DEAD                6       /* op is now dead */
+#define FSCACHE_OP_DEC_READ_CNT        7       /* decrement object->n_reads on destruction */
+#define FSCACHE_OP_KEEP_FLAGS  0xc0    /* flags to keep when repurposing an op */
 
        atomic_t                usage;
        unsigned                debug_id;       /* debugging ID */
@@ -102,6 +104,16 @@ struct fscache_operation {
 
        /* operation releaser */
        fscache_operation_release_t release;
+
+#ifdef CONFIG_SLOW_WORK_PROC
+       const char *name;               /* operation name */
+       const char *state;              /* operation state */
+#define fscache_set_op_name(OP, N)     do { (OP)->name  = (N); } while(0)
+#define fscache_set_op_state(OP, S)    do { (OP)->state = (S); } while(0)
+#else
+#define fscache_set_op_name(OP, N)     do { } while(0)
+#define fscache_set_op_state(OP, S)    do { } while(0)
+#endif
 };
 
 extern atomic_t fscache_op_debug_id;
@@ -125,6 +137,7 @@ static inline void fscache_operation_init(struct fscache_operation *op,
        op->debug_id = atomic_inc_return(&fscache_op_debug_id);
        op->release = release;
        INIT_LIST_HEAD(&op->pend_link);
+       fscache_set_op_state(op, "Init");
 }
 
 /**
@@ -221,8 +234,10 @@ struct fscache_cache_ops {
        struct fscache_object *(*alloc_object)(struct fscache_cache *cache,
                                               struct fscache_cookie *cookie);
 
-       /* look up the object for a cookie */
-       void (*lookup_object)(struct fscache_object *object);
+       /* look up the object for a cookie
+        * - return -ETIMEDOUT to be requeued
+        */
+       int (*lookup_object)(struct fscache_object *object);
 
        /* finished looking up */
        void (*lookup_complete)(struct fscache_object *object);
@@ -297,12 +312,14 @@ struct fscache_cookie {
        atomic_t                        usage;          /* number of users of this cookie */
        atomic_t                        n_children;     /* number of children of this cookie */
        spinlock_t                      lock;
+       spinlock_t                      stores_lock;    /* lock on page store tree */
        struct hlist_head               backing_objects; /* object(s) backing this file/index */
        const struct fscache_cookie_def *def;           /* definition */
        struct fscache_cookie           *parent;        /* parent of this entry */
        void                            *netfs_data;    /* back pointer to netfs */
        struct radix_tree_root          stores;         /* pages to be stored on this cookie */
 #define FSCACHE_COOKIE_PENDING_TAG     0               /* pages tag: pending write to cache */
+#define FSCACHE_COOKIE_STORING_TAG     1               /* pages tag: writing to cache */
 
        unsigned long                   flags;
 #define FSCACHE_COOKIE_LOOKING_UP      0       /* T if non-index cookie being looked up still */
@@ -337,6 +354,7 @@ struct fscache_object {
                FSCACHE_OBJECT_RECYCLING,       /* retiring object */
                FSCACHE_OBJECT_WITHDRAWING,     /* withdrawing object */
                FSCACHE_OBJECT_DEAD,            /* object is now dead */
+               FSCACHE_OBJECT__NSTATES
        } state;
 
        int                     debug_id;       /* debugging ID */
@@ -345,6 +363,7 @@ struct fscache_object {
        int                     n_obj_ops;      /* number of object ops outstanding on object */
        int                     n_in_progress;  /* number of ops in progress */
        int                     n_exclusive;    /* number of exclusive ops queued */
+       atomic_t                n_reads;        /* number of read ops in progress */
        spinlock_t              lock;           /* state and operations lock */
 
        unsigned long           lookup_jif;     /* time at which lookup started */
@@ -358,6 +377,7 @@ struct fscache_object {
 #define FSCACHE_OBJECT_EV_RELEASE      4       /* T if netfs requested object release */
 #define FSCACHE_OBJECT_EV_RETIRE       5       /* T if netfs requested object retirement */
 #define FSCACHE_OBJECT_EV_WITHDRAW     6       /* T if cache requested object withdrawal */
+#define FSCACHE_OBJECT_EVENTS_MASK     0x7f    /* mask of all events*/
 
        unsigned long           flags;
 #define FSCACHE_OBJECT_LOCK            0       /* T if object is busy being processed */
@@ -373,7 +393,11 @@ struct fscache_object {
        struct list_head        dependents;     /* FIFO of dependent objects */
        struct list_head        dep_link;       /* link in parent's dependents list */
        struct list_head        pending_ops;    /* unstarted operations on this object */
+#ifdef CONFIG_FSCACHE_OBJECT_LIST
+       struct rb_node          objlist_link;   /* link in global object list */
+#endif
        pgoff_t                 store_limit;    /* current storage limit */
+       loff_t                  store_limit_l;  /* current storage limit */
 };
 
 extern const char *fscache_object_states[];
@@ -383,6 +407,10 @@ extern const char *fscache_object_states[];
         (obj)->state >= FSCACHE_OBJECT_AVAILABLE &&          \
         (obj)->state < FSCACHE_OBJECT_DYING)
 
+#define fscache_object_is_dead(obj)                            \
+       (test_bit(FSCACHE_IOERROR, &(obj)->cache->flags) &&     \
+        (obj)->state >= FSCACHE_OBJECT_DYING)
+
 extern const struct slow_work_ops fscache_object_slow_work_ops;
 
 /**
@@ -414,6 +442,7 @@ void fscache_object_init(struct fscache_object *object,
        object->events = object->event_mask = 0;
        object->flags = 0;
        object->store_limit = 0;
+       object->store_limit_l = 0;
        object->cache = cache;
        object->cookie = cookie;
        object->parent = NULL;
@@ -422,6 +451,12 @@ void fscache_object_init(struct fscache_object *object,
 extern void fscache_object_lookup_negative(struct fscache_object *object);
 extern void fscache_obtained_object(struct fscache_object *object);
 
+#ifdef CONFIG_FSCACHE_OBJECT_LIST
+extern void fscache_object_destroy(struct fscache_object *object);
+#else
+#define fscache_object_destroy(object) do {} while(0)
+#endif
+
 /**
  * fscache_object_destroyed - Note destruction of an object in a cache
  * @cache: The cache from which the object came
@@ -460,6 +495,7 @@ static inline void fscache_object_lookup_error(struct fscache_object *object)
 static inline
 void fscache_set_store_limit(struct fscache_object *object, loff_t i_size)
 {
+       object->store_limit_l = i_size;
        object->store_limit = i_size >> PAGE_SHIFT;
        if (i_size & ~PAGE_MASK)
                object->store_limit++;
index 6d8ee466e0a00a8b3f4e98927a373869dfee9726..595ce49288b7807f0f42c40a6c2dcde9ed354d36 100644 (file)
@@ -202,6 +202,8 @@ extern int __fscache_write_page(struct fscache_cookie *, struct page *, gfp_t);
 extern void __fscache_uncache_page(struct fscache_cookie *, struct page *);
 extern bool __fscache_check_page_write(struct fscache_cookie *, struct page *);
 extern void __fscache_wait_on_page_write(struct fscache_cookie *, struct page *);
+extern bool __fscache_maybe_release_page(struct fscache_cookie *, struct page *,
+                                        gfp_t);
 
 /**
  * fscache_register_netfs - Register a filesystem as desiring caching services
@@ -615,4 +617,29 @@ void fscache_wait_on_page_write(struct fscache_cookie *cookie,
                __fscache_wait_on_page_write(cookie, page);
 }
 
+/**
+ * fscache_maybe_release_page - Consider releasing a page, cancelling a store
+ * @cookie: The cookie representing the cache object
+ * @page: The netfs page that is being cached.
+ * @gfp: The gfp flags passed to releasepage()
+ *
+ * Consider releasing a page for the vmscan algorithm, on behalf of the netfs's
+ * releasepage() call.  A storage request on the page may cancelled if it is
+ * not currently being processed.
+ *
+ * The function returns true if the page no longer has a storage request on it,
+ * and false if a storage request is left in place.  If true is returned, the
+ * page will have been passed to fscache_uncache_page().  If false is returned
+ * the page cannot be freed yet.
+ */
+static inline
+bool fscache_maybe_release_page(struct fscache_cookie *cookie,
+                               struct page *page,
+                               gfp_t gfp)
+{
+       if (fscache_cookie_valid(cookie) && PageFsCache(page))
+               return __fscache_maybe_release_page(cookie, page, gfp);
+       return false;
+}
+
 #endif /* _LINUX_FSCACHE_H */
index b80c88dedbbb419a6e93792b601e496f7470ba50..81f90a59cda6d6ffd347cdc6757b5c4e98dfcc14 100644 (file)
@@ -81,7 +81,11 @@ struct gfs2_meta_header {
        __be32 mh_type;
        __be64 __pad0;          /* Was generation number in gfs1 */
        __be32 mh_format;
-       __be32 __pad1;          /* Was incarnation number in gfs1 */
+       /* This union is to keep userspace happy */
+       union {
+               __be32 mh_jid;          /* Was incarnation number in gfs1 */
+               __be32 __pad1;
+       };
 };
 
 /*
index 6d527ee82b2b2904b2d30f978da8f31a61783d6a..d5b387669dab1f044406826847fdfa7646ab829d 100644 (file)
@@ -139,10 +139,34 @@ static inline void account_system_vtime(struct task_struct *tsk)
 #endif
 
 #if defined(CONFIG_NO_HZ)
+#if defined(CONFIG_TINY_RCU)
+extern void rcu_enter_nohz(void);
+extern void rcu_exit_nohz(void);
+
+static inline void rcu_irq_enter(void)
+{
+       rcu_exit_nohz();
+}
+
+static inline void rcu_irq_exit(void)
+{
+       rcu_enter_nohz();
+}
+
+static inline void rcu_nmi_enter(void)
+{
+}
+
+static inline void rcu_nmi_exit(void)
+{
+}
+
+#else
 extern void rcu_irq_enter(void);
 extern void rcu_irq_exit(void);
 extern void rcu_nmi_enter(void);
 extern void rcu_nmi_exit(void);
+#endif
 #else
 # define rcu_irq_enter() do { } while (0)
 # define rcu_irq_exit() do { } while (0)
index f13255e06406aa9eb7a8c60485599b960a976f8b..9eb07bbc6522bb4508797a7468a22ba465894e34 100644 (file)
@@ -21,7 +21,7 @@ struct i2c_pnx_mif {
        int                     mode;           /* Interface mode */
        struct completion       complete;       /* I/O completion */
        struct timer_list       timer;          /* Timeout */
-       char *                  buf;            /* Data buffer */
+       u8 *                    buf;            /* Data buffer */
        int                     len;            /* Length of data buffer */
 };
 
index 21a6f5d9af22d92e37f10d7ceab14be22fede177..8d10aa7fd4c983c6efec569096f82092c837ea3d 100644 (file)
@@ -83,16 +83,12 @@ extern struct group_info init_groups;
 #define INIT_IDS
 #endif
 
-#ifdef CONFIG_SECURITY_FILE_CAPABILITIES
 /*
  * Because of the reduced scope of CAP_SETPCAP when filesystem
  * capabilities are in effect, it is safe to allow CAP_SETPCAP to
  * be available in the default configuration.
  */
 # define CAP_INIT_BSET  CAP_FULL_SET
-#else
-# define CAP_INIT_BSET  CAP_INIT_EFF_SET
-#endif
 
 #ifdef CONFIG_TREE_PREEMPT_RCU
 #define INIT_TASK_RCU_PREEMPT(tsk)                                     \
index 0ccfc30cd40f7696e0b9e863272f82fb8e42e0f0..c2b1a7d244d918f9127aaf557b6127a2b12486c7 100644 (file)
@@ -1377,6 +1377,10 @@ extern struct class input_class;
  * methods; erase() is optional. set_gain() and set_autocenter() need
  * only be implemented if driver sets up FF_GAIN and FF_AUTOCENTER
  * bits.
+ *
+ * Note that playback(), set_gain() and set_autocenter() are called with
+ * dev->event_lock spinlock held and interrupts off and thus may not
+ * sleep.
  */
 struct ff_device {
        int (*upload)(struct input_dev *dev, struct ff_effect *effect,
index 7ca72b74eec7e4142866f44debf96f594c70037f..75f3f00ac1e56b1b1d3fb352d096668a0051d53f 100644 (file)
@@ -603,12 +603,6 @@ static inline void init_irq_proc(void)
 }
 #endif
 
-#if defined(CONFIG_GENERIC_HARDIRQS) && defined(CONFIG_DEBUG_SHIRQ)
-extern void debug_poll_all_shared_irqs(void);
-#else
-static inline void debug_poll_all_shared_irqs(void) { }
-#endif
-
 struct seq_file;
 int show_interrupts(struct seq_file *p, void *v);
 
index b02a3f1d46a0595788b86220bcbee174171ad78c..006bf45eae30e5777ece188a997736cd5ff509cf 100644 (file)
        typecheck(unsigned long, flags);        \
        raw_irqs_disabled_flags(flags);         \
 })
-#endif         /* CONFIG_X86 */
+#endif /* CONFIG_TRACE_IRQFLAGS_SUPPORT */
 
 #endif
index 4c218ee7587ad47c83c5b7d7375181ee6c2ec9ea..8687a7dc0632378c4828b2c58664ec638227919d 100644 (file)
@@ -157,7 +157,7 @@ typedef struct {
 
 typedef struct {
   int mp_mrru;                        /* unused                             */
-  struct sk_buff_head frags;   /* fragments sl list */
+  struct sk_buff * frags;      /* fragments sl list -- use skb->next */
   long frames;                 /* number of frames in the frame list */
   unsigned int seq;            /* last processed packet seq #: any packets
                                 * with smaller seq # will be dropped
index f4e3184fa0540724d7777d0f140fc189cd806941..3fa4c590cf12de7aef9dd89cf3af1c5dc9661c88 100644 (file)
@@ -15,7 +15,6 @@
 #include <linux/bitops.h>
 #include <linux/log2.h>
 #include <linux/typecheck.h>
-#include <linux/ratelimit.h>
 #include <linux/dynamic_debug.h>
 #include <asm/byteorder.h>
 #include <asm/bug.h>
@@ -241,8 +240,8 @@ asmlinkage int vprintk(const char *fmt, va_list args)
 asmlinkage int printk(const char * fmt, ...)
        __attribute__ ((format (printf, 1, 2))) __cold;
 
-extern struct ratelimit_state printk_ratelimit_state;
-extern int printk_ratelimit(void);
+extern int __printk_ratelimit(const char *func);
+#define printk_ratelimit() __printk_ratelimit(__func__)
 extern bool printk_timed_ratelimit(unsigned long *caller_jiffies,
                                   unsigned int interval_msec);
 
index 190c37854870f4cf201dbe8c7970eab8b2788cac..f78f83d7663f7bad084b304c8a8f71a169db019e 100644 (file)
 
 /* Auxiliary data to use in generating the audit record. */
 struct common_audit_data {
-       char    type;
-#define LSM_AUDIT_DATA_FS      1
-#define LSM_AUDIT_DATA_NET     2
-#define LSM_AUDIT_DATA_CAP     3
-#define LSM_AUDIT_DATA_IPC     4
-#define LSM_AUDIT_DATA_TASK    5
-#define LSM_AUDIT_DATA_KEY     6
-#define LSM_AUDIT_NO_AUDIT     7
+       char type;
+#define LSM_AUDIT_DATA_FS      1
+#define LSM_AUDIT_DATA_NET     2
+#define LSM_AUDIT_DATA_CAP     3
+#define LSM_AUDIT_DATA_IPC     4
+#define LSM_AUDIT_DATA_TASK    5
+#define LSM_AUDIT_DATA_KEY     6
+#define LSM_AUDIT_NO_AUDIT     7
+#define LSM_AUDIT_DATA_KMOD    8
        struct task_struct *tsk;
        union   {
                struct {
@@ -66,6 +67,7 @@ struct common_audit_data {
                        char *key_desc;
                } key_struct;
 #endif
+               char *kmod_name;
        } u;
        /* this union contains LSM specific data */
        union {
index f95466343fb2dd77fc7fe4bce8ea417ccb113703..955d30fc6a274aef932ac8c619e672453508b229 100644 (file)
 #define WM831X_LDO1_OK_SHIFT                         0  /* LDO1_OK */
 #define WM831X_LDO1_OK_WIDTH                         1  /* LDO1_OK */
 
-#define WM831X_ISINK_MAX_ISEL 56
-extern int wm831x_isinkv_values[WM831X_ISINK_MAX_ISEL];
+#define WM831X_ISINK_MAX_ISEL 55
+extern int wm831x_isinkv_values[WM831X_ISINK_MAX_ISEL + 1];
 
 #endif
index 529a0931711da5875cc70e88953dbe9621afd5d3..d7e26e30c8c2685e2f3410cba32e9c6ccfed6e3a 100644 (file)
@@ -358,6 +358,7 @@ static const struct proto_ops name##_ops = {                        \
 
 #ifdef CONFIG_SYSCTL
 #include <linux/sysctl.h>
+#include <linux/ratelimit.h>
 extern struct ratelimit_state net_ratelimit_state;
 #endif
 
index 79fec6af3f9f805800d7bfdce69bc15301215dc2..ce520402e840e7b46760b9655133da1cbc4f0700 100644 (file)
@@ -424,15 +424,6 @@ struct nilfs_dat_entry {
        __le64 de_rsv;
 };
 
-/**
- * struct nilfs_dat_group_desc - block group descriptor
- * @dg_nfrees: number of free virtual block numbers in block group
- */
-struct nilfs_dat_group_desc {
-       __le32 dg_nfrees;
-};
-
-
 /**
  * struct nilfs_snapshot_list - snapshot list
  * @ssl_next: next checkpoint number on snapshot list
index 84cf1f3b7838e70d30c8d010e0a964b82a2b785b..daecca3c83008f480359878bf9b9f4ce80ee1748 100644 (file)
 #define PCI_DEVICE_ID_O2_6730          0x673a
 #define PCI_DEVICE_ID_O2_6832          0x6832
 #define PCI_DEVICE_ID_O2_6836          0x6836
+#define PCI_DEVICE_ID_O2_6812          0x6872
+#define PCI_DEVICE_ID_O2_6933          0x6933
 
 #define PCI_VENDOR_ID_3DFX             0x121a
 #define PCI_DEVICE_ID_3DFX_VOODOO      0x0001
index 065a3652a3eaf92a8381db3f35e78f86e470a488..67608161df6b574eb5e382678d58e9683e30a6a6 100644 (file)
@@ -147,6 +147,20 @@ static inline void forget_cached_acl(struct inode *inode, int type)
        if (old != ACL_NOT_CACHED)
                posix_acl_release(old);
 }
+
+static inline void forget_all_cached_acls(struct inode *inode)
+{
+       struct posix_acl *old_access, *old_default;
+       spin_lock(&inode->i_lock);
+       old_access = inode->i_acl;
+       old_default = inode->i_default_acl;
+       inode->i_acl = inode->i_default_acl = ACL_NOT_CACHED;
+       spin_unlock(&inode->i_lock);
+       if (old_access != ACL_NOT_CACHED)
+               posix_acl_release(old_access);
+       if (old_default != ACL_NOT_CACHED)
+               posix_acl_release(old_default);
+}
 #endif
 
 static inline void cache_no_acl(struct inode *inode)
index 78c48895b12a9bae5f64e2627b61f4bd92f4fce0..ce9a9b2e5cd44fffbc9afcd8f4f90b692343a88c 100644 (file)
@@ -376,6 +376,17 @@ static inline unsigned int dquot_generic_flag(unsigned int flags, int type)
        return flags >> _DQUOT_STATE_FLAGS;
 }
 
+#ifdef CONFIG_QUOTA_NETLINK_INTERFACE
+extern void quota_send_warning(short type, unsigned int id, dev_t dev,
+                              const char warntype);
+#else
+static inline void quota_send_warning(short type, unsigned int id, dev_t dev,
+                                     const char warntype)
+{
+       return;
+}
+#endif /* CONFIG_QUOTA_NETLINK_INTERFACE */
+
 struct quota_info {
        unsigned int flags;                     /* Flags for diskquotas on this device */
        struct mutex dqio_mutex;                /* lock device while I/O in progress */
index 00044b856453f45bf886ddc3b237ac3744323ac3..668cf1bef030ee2c38ca0de23575f815babea9d6 100644 (file)
@@ -1,20 +1,31 @@
 #ifndef _LINUX_RATELIMIT_H
 #define _LINUX_RATELIMIT_H
+
 #include <linux/param.h>
+#include <linux/spinlock_types.h>
 
-#define DEFAULT_RATELIMIT_INTERVAL (5 * HZ)
-#define DEFAULT_RATELIMIT_BURST 10
+#define DEFAULT_RATELIMIT_INTERVAL     (5 * HZ)
+#define DEFAULT_RATELIMIT_BURST                10
 
 struct ratelimit_state {
-       int interval;
-       int burst;
-       int printed;
-       int missed;
-       unsigned long begin;
+       spinlock_t      lock;           /* protect the state */
+
+       int             interval;
+       int             burst;
+       int             printed;
+       int             missed;
+       unsigned long   begin;
 };
 
-#define DEFINE_RATELIMIT_STATE(name, interval, burst)          \
-               struct ratelimit_state name = {interval, burst,}
+#define DEFINE_RATELIMIT_STATE(name, interval_init, burst_init)                \
+                                                                       \
+       struct ratelimit_state name = {                                 \
+               .lock           = __SPIN_LOCK_UNLOCKED(name.lock),      \
+               .interval       = interval_init,                        \
+               .burst          = burst_init,                           \
+       }
+
+extern int ___ratelimit(struct ratelimit_state *rs, const char *func);
+#define __ratelimit(state) ___ratelimit(state, __func__)
 
-extern int __ratelimit(struct ratelimit_state *rs);
-#endif
+#endif /* _LINUX_RATELIMIT_H */
index 3ebd0b7bcb08430e80d56dfa717785e186c90495..24440f4bf476cf6083b34b8cb9d1a06f57bcfd82 100644 (file)
@@ -52,11 +52,6 @@ struct rcu_head {
 };
 
 /* Exported common interfaces */
-#ifdef CONFIG_TREE_PREEMPT_RCU
-extern void synchronize_rcu(void);
-#else /* #ifdef CONFIG_TREE_PREEMPT_RCU */
-#define synchronize_rcu synchronize_sched
-#endif /* #else #ifdef CONFIG_TREE_PREEMPT_RCU */
 extern void synchronize_rcu_bh(void);
 extern void synchronize_sched(void);
 extern void rcu_barrier(void);
@@ -67,12 +62,11 @@ extern int sched_expedited_torture_stats(char *page);
 
 /* Internal to kernel */
 extern void rcu_init(void);
-extern void rcu_scheduler_starting(void);
-extern int rcu_needs_cpu(int cpu);
-extern int rcu_scheduler_active;
 
 #if defined(CONFIG_TREE_RCU) || defined(CONFIG_TREE_PREEMPT_RCU)
 #include <linux/rcutree.h>
+#elif defined(CONFIG_TINY_RCU)
+#include <linux/rcutiny.h>
 #else
 #error "Unknown RCU implementation specified to kernel configuration"
 #endif
diff --git a/include/linux/rcutiny.h b/include/linux/rcutiny.h
new file mode 100644 (file)
index 0000000..c4ba9a7
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+ * Read-Copy Update mechanism for mutual exclusion, the Bloatwatch edition.
+ *
+ * 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.
+ *
+ * Copyright IBM Corporation, 2008
+ *
+ * Author: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
+ *
+ * For detailed explanation of Read-Copy Update mechanism see -
+ *             Documentation/RCU
+ */
+#ifndef __LINUX_TINY_H
+#define __LINUX_TINY_H
+
+#include <linux/cache.h>
+
+void rcu_sched_qs(int cpu);
+void rcu_bh_qs(int cpu);
+
+#define __rcu_read_lock()      preempt_disable()
+#define __rcu_read_unlock()    preempt_enable()
+#define __rcu_read_lock_bh()   local_bh_disable()
+#define __rcu_read_unlock_bh() local_bh_enable()
+#define call_rcu_sched         call_rcu
+
+#define rcu_init_sched()       do { } while (0)
+extern void rcu_check_callbacks(int cpu, int user);
+
+static inline int rcu_needs_cpu(int cpu)
+{
+       return 0;
+}
+
+/*
+ * Return the number of grace periods.
+ */
+static inline long rcu_batches_completed(void)
+{
+       return 0;
+}
+
+/*
+ * Return the number of bottom-half grace periods.
+ */
+static inline long rcu_batches_completed_bh(void)
+{
+       return 0;
+}
+
+extern int rcu_expedited_torture_stats(char *page);
+
+#define synchronize_rcu synchronize_sched
+
+static inline void synchronize_rcu_expedited(void)
+{
+       synchronize_sched();
+}
+
+static inline void synchronize_rcu_bh_expedited(void)
+{
+       synchronize_sched();
+}
+
+struct notifier_block;
+
+#ifdef CONFIG_NO_HZ
+
+extern void rcu_enter_nohz(void);
+extern void rcu_exit_nohz(void);
+
+#else /* #ifdef CONFIG_NO_HZ */
+
+static inline void rcu_enter_nohz(void)
+{
+}
+
+static inline void rcu_exit_nohz(void)
+{
+}
+
+#endif /* #else #ifdef CONFIG_NO_HZ */
+
+static inline void rcu_scheduler_starting(void)
+{
+}
+
+static inline void exit_rcu(void)
+{
+}
+
+#endif /* __LINUX_RCUTINY_H */
index 9642c6bcb399439f5b36bb45f3df5a66f7d17ca1..c93eee5911b0760ab81ae3791a31c7c340f800eb 100644 (file)
@@ -34,15 +34,15 @@ struct notifier_block;
 
 extern void rcu_sched_qs(int cpu);
 extern void rcu_bh_qs(int cpu);
-extern int rcu_cpu_notify(struct notifier_block *self,
-                         unsigned long action, void *hcpu);
 extern int rcu_needs_cpu(int cpu);
+extern void rcu_scheduler_starting(void);
 extern int rcu_expedited_torture_stats(char *page);
 
 #ifdef CONFIG_TREE_PREEMPT_RCU
 
 extern void __rcu_read_lock(void);
 extern void __rcu_read_unlock(void);
+extern void synchronize_rcu(void);
 extern void exit_rcu(void);
 
 #else /* #ifdef CONFIG_TREE_PREEMPT_RCU */
@@ -57,7 +57,7 @@ static inline void __rcu_read_unlock(void)
        preempt_enable();
 }
 
-#define __synchronize_sched() synchronize_rcu()
+#define synchronize_rcu synchronize_sched
 
 static inline void exit_rcu(void)
 {
@@ -83,7 +83,6 @@ static inline void synchronize_rcu_bh_expedited(void)
        synchronize_sched_expedited();
 }
 
-extern void __rcu_init(void);
 extern void rcu_check_callbacks(int cpu, int user);
 
 extern long rcu_batches_completed(void);
index 75e6e60bf583bb89a7784d4476a32766d10db420..882dc48163b4c4a12749cf3e6fb001ff82201980 100644 (file)
@@ -1421,17 +1421,17 @@ struct task_struct {
 #endif
 #ifdef CONFIG_TRACE_IRQFLAGS
        unsigned int irq_events;
-       int hardirqs_enabled;
        unsigned long hardirq_enable_ip;
-       unsigned int hardirq_enable_event;
        unsigned long hardirq_disable_ip;
+       unsigned int hardirq_enable_event;
        unsigned int hardirq_disable_event;
-       int softirqs_enabled;
+       int hardirqs_enabled;
+       int hardirq_context;
        unsigned long softirq_disable_ip;
-       unsigned int softirq_disable_event;
        unsigned long softirq_enable_ip;
+       unsigned int softirq_disable_event;
        unsigned int softirq_enable_event;
-       int hardirq_context;
+       int softirqs_enabled;
        int softirq_context;
 #endif
 #ifdef CONFIG_LOCKDEP
@@ -2086,11 +2086,18 @@ static inline int is_si_special(const struct siginfo *info)
        return info <= SEND_SIG_FORCED;
 }
 
-/* True if we are on the alternate signal stack.  */
-
+/*
+ * True if we are on the alternate signal stack.
+ */
 static inline int on_sig_stack(unsigned long sp)
 {
-       return (sp - current->sas_ss_sp < current->sas_ss_size);
+#ifdef CONFIG_STACK_GROWSUP
+       return sp >= current->sas_ss_sp &&
+               sp - current->sas_ss_sp < current->sas_ss_size;
+#else
+       return sp > current->sas_ss_sp &&
+               sp - current->sas_ss_sp <= current->sas_ss_size;
+#endif
 }
 
 static inline int sas_ss_flags(unsigned long sp)
index d2c5ed845bcc4a740b4e30b22bd0995f821a1ed9..33406174cbe8429d8be9531c029993891059958b 100644 (file)
@@ -1,6 +1,15 @@
 #ifndef _LINUX_SECUREBITS_H
 #define _LINUX_SECUREBITS_H 1
 
+/* Each securesetting is implemented using two bits. One bit specifies
+   whether the setting is on or off. The other bit specify whether the
+   setting is locked or not. A setting which is locked cannot be
+   changed from user-level. */
+#define issecure_mask(X)       (1 << (X))
+#ifdef __KERNEL__
+#define issecure(X)            (issecure_mask(X) & current_cred_xxx(securebits))
+#endif
+
 #define SECUREBITS_DEFAULT 0x00000000
 
 /* When set UID 0 has no special privileges. When unset, we support
@@ -12,6 +21,9 @@
 #define SECURE_NOROOT                  0
 #define SECURE_NOROOT_LOCKED           1  /* make bit-0 immutable */
 
+#define SECBIT_NOROOT          (issecure_mask(SECURE_NOROOT))
+#define SECBIT_NOROOT_LOCKED   (issecure_mask(SECURE_NOROOT_LOCKED))
+
 /* When set, setuid to/from uid 0 does not trigger capability-"fixup".
    When unset, to provide compatiblility with old programs relying on
    set*uid to gain/lose privilege, transitions to/from uid 0 cause
 #define SECURE_NO_SETUID_FIXUP         2
 #define SECURE_NO_SETUID_FIXUP_LOCKED  3  /* make bit-2 immutable */
 
+#define SECBIT_NO_SETUID_FIXUP (issecure_mask(SECURE_NO_SETUID_FIXUP))
+#define SECBIT_NO_SETUID_FIXUP_LOCKED \
+                       (issecure_mask(SECURE_NO_SETUID_FIXUP_LOCKED))
+
 /* When set, a process can retain its capabilities even after
    transitioning to a non-root user (the set-uid fixup suppressed by
    bit 2). Bit-4 is cleared when a process calls exec(); setting both
 #define SECURE_KEEP_CAPS               4
 #define SECURE_KEEP_CAPS_LOCKED                5  /* make bit-4 immutable */
 
-/* Each securesetting is implemented using two bits. One bit specifies
-   whether the setting is on or off. The other bit specify whether the
-   setting is locked or not. A setting which is locked cannot be
-   changed from user-level. */
-#define issecure_mask(X)       (1 << (X))
-#define issecure(X)            (issecure_mask(X) & current_cred_xxx(securebits))
+#define SECBIT_KEEP_CAPS       (issecure_mask(SECURE_KEEP_CAPS))
+#define SECBIT_KEEP_CAPS_LOCKED (issecure_mask(SECURE_KEEP_CAPS_LOCKED))
 
 #define SECURE_ALL_BITS                (issecure_mask(SECURE_NOROOT) | \
                                 issecure_mask(SECURE_NO_SETUID_FIXUP) | \
index 239e40d0450bc02380b30c08e8854ecc3d4ba638..466cbadbd1efe1b5daa543d7bb99dd91d39aab08 100644 (file)
@@ -447,6 +447,22 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
  *     @new_dir contains the path structure for parent of the new link.
  *     @new_dentry contains the dentry structure of the new link.
  *     Return 0 if permission is granted.
+ * @path_chmod:
+ *     Check for permission to change DAC's permission of a file or directory.
+ *     @dentry contains the dentry structure.
+ *     @mnt contains the vfsmnt structure.
+ *     @mode contains DAC's mode.
+ *     Return 0 if permission is granted.
+ * @path_chown:
+ *     Check for permission to change owner/group of a file or directory.
+ *     @path contains the path structure.
+ *     @uid contains new owner's ID.
+ *     @gid contains new group's ID.
+ *     Return 0 if permission is granted.
+ * @path_chroot:
+ *     Check for permission to change root directory.
+ *     @path contains the path structure.
+ *     Return 0 if permission is granted.
  * @inode_readlink:
  *     Check the permission to read the symbolic link.
  *     @dentry contains the dentry structure for the file link.
@@ -690,6 +706,7 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
  * @kernel_module_request:
  *     Ability to trigger the kernel to automatically upcall to userspace for
  *     userspace to load a kernel module with the given name.
+ *     @kmod_name name of the module requested by the kernel
  *     Return 0 if successful.
  * @task_setuid:
  *     Check permission before setting one or more of the user identity
@@ -1488,6 +1505,10 @@ struct security_operations {
                          struct dentry *new_dentry);
        int (*path_rename) (struct path *old_dir, struct dentry *old_dentry,
                            struct path *new_dir, struct dentry *new_dentry);
+       int (*path_chmod) (struct dentry *dentry, struct vfsmount *mnt,
+                          mode_t mode);
+       int (*path_chown) (struct path *path, uid_t uid, gid_t gid);
+       int (*path_chroot) (struct path *path);
 #endif
 
        int (*inode_alloc_security) (struct inode *inode);
@@ -1557,7 +1578,7 @@ struct security_operations {
        void (*cred_transfer)(struct cred *new, const struct cred *old);
        int (*kernel_act_as)(struct cred *new, u32 secid);
        int (*kernel_create_files_as)(struct cred *new, struct inode *inode);
-       int (*kernel_module_request)(void);
+       int (*kernel_module_request)(char *kmod_name);
        int (*task_setuid) (uid_t id0, uid_t id1, uid_t id2, int flags);
        int (*task_fix_setuid) (struct cred *new, const struct cred *old,
                                int flags);
@@ -1822,7 +1843,7 @@ void security_commit_creds(struct cred *new, const struct cred *old);
 void security_transfer_creds(struct cred *new, const struct cred *old);
 int security_kernel_act_as(struct cred *new, u32 secid);
 int security_kernel_create_files_as(struct cred *new, struct inode *inode);
-int security_kernel_module_request(void);
+int security_kernel_module_request(char *kmod_name);
 int security_task_setuid(uid_t id0, uid_t id1, uid_t id2, int flags);
 int security_task_fix_setuid(struct cred *new, const struct cred *old,
                             int flags);
@@ -2387,7 +2408,7 @@ static inline int security_kernel_create_files_as(struct cred *cred,
        return 0;
 }
 
-static inline int security_kernel_module_request(void)
+static inline int security_kernel_module_request(char *kmod_name)
 {
        return 0;
 }
@@ -2952,6 +2973,10 @@ int security_path_link(struct dentry *old_dentry, struct path *new_dir,
                       struct dentry *new_dentry);
 int security_path_rename(struct path *old_dir, struct dentry *old_dentry,
                         struct path *new_dir, struct dentry *new_dentry);
+int security_path_chmod(struct dentry *dentry, struct vfsmount *mnt,
+                       mode_t mode);
+int security_path_chown(struct path *path, uid_t uid, gid_t gid);
+int security_path_chroot(struct path *path);
 #else  /* CONFIG_SECURITY_PATH */
 static inline int security_path_unlink(struct path *dir, struct dentry *dentry)
 {
@@ -3001,6 +3026,23 @@ static inline int security_path_rename(struct path *old_dir,
 {
        return 0;
 }
+
+static inline int security_path_chmod(struct dentry *dentry,
+                                     struct vfsmount *mnt,
+                                     mode_t mode)
+{
+       return 0;
+}
+
+static inline int security_path_chown(struct path *path, uid_t uid, gid_t gid)
+{
+       return 0;
+}
+
+static inline int security_path_chroot(struct path *path)
+{
+       return 0;
+}
 #endif /* CONFIG_SECURITY_PATH */
 
 #ifdef CONFIG_KEYS
index b65c8881f07acae832e16a8dca1dae7380f1a3c4..13337bf6c3f5de19b84068ba945463c0cbc9d028 100644 (file)
 #ifdef CONFIG_SLOW_WORK
 
 #include <linux/sysctl.h>
+#include <linux/timer.h>
 
 struct slow_work;
+#ifdef CONFIG_SLOW_WORK_DEBUG
+struct seq_file;
+#endif
 
 /*
  * The operations used to support slow work items
  */
 struct slow_work_ops {
+       /* owner */
+       struct module *owner;
+
        /* get a ref on a work item
         * - return 0 if successful, -ve if not
         */
@@ -34,6 +41,11 @@ struct slow_work_ops {
 
        /* execute a work item */
        void (*execute)(struct slow_work *work);
+
+#ifdef CONFIG_SLOW_WORK_DEBUG
+       /* describe a work item for debugfs */
+       void (*desc)(struct slow_work *work, struct seq_file *m);
+#endif
 };
 
 /*
@@ -42,13 +54,24 @@ struct slow_work_ops {
  *   queued
  */
 struct slow_work {
+       struct module           *owner; /* the owning module */
        unsigned long           flags;
 #define SLOW_WORK_PENDING      0       /* item pending (further) execution */
 #define SLOW_WORK_EXECUTING    1       /* item currently executing */
 #define SLOW_WORK_ENQ_DEFERRED 2       /* item enqueue deferred */
 #define SLOW_WORK_VERY_SLOW    3       /* item is very slow */
+#define SLOW_WORK_CANCELLING   4       /* item is being cancelled, don't enqueue */
+#define SLOW_WORK_DELAYED      5       /* item is struct delayed_slow_work with active timer */
        const struct slow_work_ops *ops; /* operations table for this item */
        struct list_head        link;   /* link in queue */
+#ifdef CONFIG_SLOW_WORK_DEBUG
+       struct timespec         mark;   /* jiffies at which queued or exec begun */
+#endif
+};
+
+struct delayed_slow_work {
+       struct slow_work        work;
+       struct timer_list       timer;
 };
 
 /**
@@ -66,6 +89,20 @@ static inline void slow_work_init(struct slow_work *work,
        INIT_LIST_HEAD(&work->link);
 }
 
+/**
+ * slow_work_init - Initialise a delayed slow work item
+ * @work: The work item to initialise
+ * @ops: The operations to use to handle the slow work item
+ *
+ * Initialise a delayed slow work item.
+ */
+static inline void delayed_slow_work_init(struct delayed_slow_work *dwork,
+                                         const struct slow_work_ops *ops)
+{
+       init_timer(&dwork->timer);
+       slow_work_init(&dwork->work, ops);
+}
+
 /**
  * vslow_work_init - Initialise a very slow work item
  * @work: The work item to initialise
@@ -83,9 +120,40 @@ static inline void vslow_work_init(struct slow_work *work,
        INIT_LIST_HEAD(&work->link);
 }
 
+/**
+ * slow_work_is_queued - Determine if a slow work item is on the work queue
+ * work: The work item to test
+ *
+ * Determine if the specified slow-work item is on the work queue.  This
+ * returns true if it is actually on the queue.
+ *
+ * If the item is executing and has been marked for requeue when execution
+ * finishes, then false will be returned.
+ *
+ * Anyone wishing to wait for completion of execution can wait on the
+ * SLOW_WORK_EXECUTING bit.
+ */
+static inline bool slow_work_is_queued(struct slow_work *work)
+{
+       unsigned long flags = work->flags;
+       return flags & SLOW_WORK_PENDING && !(flags & SLOW_WORK_EXECUTING);
+}
+
 extern int slow_work_enqueue(struct slow_work *work);
-extern int slow_work_register_user(void);
-extern void slow_work_unregister_user(void);
+extern void slow_work_cancel(struct slow_work *work);
+extern int slow_work_register_user(struct module *owner);
+extern void slow_work_unregister_user(struct module *owner);
+
+extern int delayed_slow_work_enqueue(struct delayed_slow_work *dwork,
+                                    unsigned long delay);
+
+static inline void delayed_slow_work_cancel(struct delayed_slow_work *dwork)
+{
+       slow_work_cancel(&dwork->work);
+}
+
+extern bool slow_work_sleep_till_thread_needed(struct slow_work *work,
+                                              signed long *_timeout);
 
 #ifdef CONFIG_SYSCTL
 extern ctl_table slow_work_sysctls[];
index 39c64bae776d86069518e4e00017bc75e6aae53c..7a0570e6a5960cfedd82fcc16c38fb6c99947680 100644 (file)
@@ -76,6 +76,9 @@ void smp_call_function_many(const struct cpumask *mask,
 void __smp_call_function_single(int cpuid, struct call_single_data *data,
                                int wait);
 
+int smp_call_function_any(const struct cpumask *mask,
+                         void (*func)(void *info), void *info, int wait);
+
 /*
  * Generic and arch helpers
  */
@@ -137,9 +140,15 @@ static inline void smp_send_reschedule(int cpu) { }
 #define smp_prepare_boot_cpu()                 do {} while (0)
 #define smp_call_function_many(mask, func, info, wait) \
                        (up_smp_call_function(func, info))
-static inline void init_call_single_data(void)
+static inline void init_call_single_data(void) { }
+
+static inline int
+smp_call_function_any(const struct cpumask *mask, void (*func)(void *info),
+                     void *info, int wait)
 {
+       return smp_call_function_single(0, func, info, wait);
 }
+
 #endif /* !SMP */
 
 /*
index f0ca7a7a17572f5843d27a782e4d882f4152aea7..71dccfeb0d88de34d2a84ed34d2e587e17a11616 100644 (file)
@@ -79,8 +79,6 @@
  */
 #include <linux/spinlock_types.h>
 
-extern int __lockfunc generic__raw_read_trylock(raw_rwlock_t *lock);
-
 /*
  * Pull the __raw*() functions/declarations (UP-nondebug doesnt need them):
  */
@@ -102,7 +100,7 @@ do {                                                                \
 
 #else
 # define spin_lock_init(lock)                                  \
-       do { *(lock) = SPIN_LOCK_UNLOCKED; } while (0)
+       do { *(lock) = __SPIN_LOCK_UNLOCKED(lock); } while (0)
 #endif
 
 #ifdef CONFIG_DEBUG_SPINLOCK
@@ -116,7 +114,7 @@ do {                                                                \
 } while (0)
 #else
 # define rwlock_init(lock)                                     \
-       do { *(lock) = RW_LOCK_UNLOCKED; } while (0)
+       do { *(lock) = __RW_LOCK_UNLOCKED(lock); } while (0)
 #endif
 
 #define spin_is_locked(lock)   __raw_spin_is_locked(&(lock)->raw_lock)
index 7a7e18fc2415e86c4a9fea767a0e43a001b51bcd..8264a7f459bc578d5988759c285868a75c0e91e5 100644 (file)
@@ -60,137 +60,118 @@ void __lockfunc _read_unlock_irqrestore(rwlock_t *lock, unsigned long flags)
 void __lockfunc _write_unlock_irqrestore(rwlock_t *lock, unsigned long flags)
                                                        __releases(lock);
 
-/*
- * We inline the unlock functions in the nondebug case:
- */
-#if !defined(CONFIG_DEBUG_SPINLOCK) && !defined(CONFIG_PREEMPT)
-#define __always_inline__spin_unlock
-#define __always_inline__read_unlock
-#define __always_inline__write_unlock
-#define __always_inline__spin_unlock_irq
-#define __always_inline__read_unlock_irq
-#define __always_inline__write_unlock_irq
-#endif
-
-#ifndef CONFIG_DEBUG_SPINLOCK
-#ifndef CONFIG_GENERIC_LOCKBREAK
-
-#ifdef __always_inline__spin_lock
+#ifdef CONFIG_INLINE_SPIN_LOCK
 #define _spin_lock(lock) __spin_lock(lock)
 #endif
 
-#ifdef __always_inline__read_lock
+#ifdef CONFIG_INLINE_READ_LOCK
 #define _read_lock(lock) __read_lock(lock)
 #endif
 
-#ifdef __always_inline__write_lock
+#ifdef CONFIG_INLINE_WRITE_LOCK
 #define _write_lock(lock) __write_lock(lock)
 #endif
 
-#ifdef __always_inline__spin_lock_bh
+#ifdef CONFIG_INLINE_SPIN_LOCK_BH
 #define _spin_lock_bh(lock) __spin_lock_bh(lock)
 #endif
 
-#ifdef __always_inline__read_lock_bh
+#ifdef CONFIG_INLINE_READ_LOCK_BH
 #define _read_lock_bh(lock) __read_lock_bh(lock)
 #endif
 
-#ifdef __always_inline__write_lock_bh
+#ifdef CONFIG_INLINE_WRITE_LOCK_BH
 #define _write_lock_bh(lock) __write_lock_bh(lock)
 #endif
 
-#ifdef __always_inline__spin_lock_irq
+#ifdef CONFIG_INLINE_SPIN_LOCK_IRQ
 #define _spin_lock_irq(lock) __spin_lock_irq(lock)
 #endif
 
-#ifdef __always_inline__read_lock_irq
+#ifdef CONFIG_INLINE_READ_LOCK_IRQ
 #define _read_lock_irq(lock) __read_lock_irq(lock)
 #endif
 
-#ifdef __always_inline__write_lock_irq
+#ifdef CONFIG_INLINE_WRITE_LOCK_IRQ
 #define _write_lock_irq(lock) __write_lock_irq(lock)
 #endif
 
-#ifdef __always_inline__spin_lock_irqsave
+#ifdef CONFIG_INLINE_SPIN_LOCK_IRQSAVE
 #define _spin_lock_irqsave(lock) __spin_lock_irqsave(lock)
 #endif
 
-#ifdef __always_inline__read_lock_irqsave
+#ifdef CONFIG_INLINE_READ_LOCK_IRQSAVE
 #define _read_lock_irqsave(lock) __read_lock_irqsave(lock)
 #endif
 
-#ifdef __always_inline__write_lock_irqsave
+#ifdef CONFIG_INLINE_WRITE_LOCK_IRQSAVE
 #define _write_lock_irqsave(lock) __write_lock_irqsave(lock)
 #endif
 
-#endif /* !CONFIG_GENERIC_LOCKBREAK */
-
-#ifdef __always_inline__spin_trylock
+#ifdef CONFIG_INLINE_SPIN_TRYLOCK
 #define _spin_trylock(lock) __spin_trylock(lock)
 #endif
 
-#ifdef __always_inline__read_trylock
+#ifdef CONFIG_INLINE_READ_TRYLOCK
 #define _read_trylock(lock) __read_trylock(lock)
 #endif
 
-#ifdef __always_inline__write_trylock
+#ifdef CONFIG_INLINE_WRITE_TRYLOCK
 #define _write_trylock(lock) __write_trylock(lock)
 #endif
 
-#ifdef __always_inline__spin_trylock_bh
+#ifdef CONFIG_INLINE_SPIN_TRYLOCK_BH
 #define _spin_trylock_bh(lock) __spin_trylock_bh(lock)
 #endif
 
-#ifdef __always_inline__spin_unlock
+#ifdef CONFIG_INLINE_SPIN_UNLOCK
 #define _spin_unlock(lock) __spin_unlock(lock)
 #endif
 
-#ifdef __always_inline__read_unlock
+#ifdef CONFIG_INLINE_READ_UNLOCK
 #define _read_unlock(lock) __read_unlock(lock)
 #endif
 
-#ifdef __always_inline__write_unlock
+#ifdef CONFIG_INLINE_WRITE_UNLOCK
 #define _write_unlock(lock) __write_unlock(lock)
 #endif
 
-#ifdef __always_inline__spin_unlock_bh
+#ifdef CONFIG_INLINE_SPIN_UNLOCK_BH
 #define _spin_unlock_bh(lock) __spin_unlock_bh(lock)
 #endif
 
-#ifdef __always_inline__read_unlock_bh
+#ifdef CONFIG_INLINE_READ_UNLOCK_BH
 #define _read_unlock_bh(lock) __read_unlock_bh(lock)
 #endif
 
-#ifdef __always_inline__write_unlock_bh
+#ifdef CONFIG_INLINE_WRITE_UNLOCK_BH
 #define _write_unlock_bh(lock) __write_unlock_bh(lock)
 #endif
 
-#ifdef __always_inline__spin_unlock_irq
+#ifdef CONFIG_INLINE_SPIN_UNLOCK_IRQ
 #define _spin_unlock_irq(lock) __spin_unlock_irq(lock)
 #endif
 
-#ifdef __always_inline__read_unlock_irq
+#ifdef CONFIG_INLINE_READ_UNLOCK_IRQ
 #define _read_unlock_irq(lock) __read_unlock_irq(lock)
 #endif
 
-#ifdef __always_inline__write_unlock_irq
+#ifdef CONFIG_INLINE_WRITE_UNLOCK_IRQ
 #define _write_unlock_irq(lock) __write_unlock_irq(lock)
 #endif
 
-#ifdef __always_inline__spin_unlock_irqrestore
+#ifdef CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE
 #define _spin_unlock_irqrestore(lock, flags) __spin_unlock_irqrestore(lock, flags)
 #endif
 
-#ifdef __always_inline__read_unlock_irqrestore
+#ifdef CONFIG_INLINE_READ_UNLOCK_IRQRESTORE
 #define _read_unlock_irqrestore(lock, flags) __read_unlock_irqrestore(lock, flags)
 #endif
 
-#ifdef __always_inline__write_unlock_irqrestore
+#ifdef CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE
 #define _write_unlock_irqrestore(lock, flags) __write_unlock_irqrestore(lock, flags)
 #endif
 
-#endif /* CONFIG_DEBUG_SPINLOCK */
-
 static inline int __spin_trylock(spinlock_t *lock)
 {
        preempt_disable();
index aca0eee53930f5014fc1037caab46d46cd16a855..4765d97dcafb98a5e8fde93684f9293c08d88804 100644 (file)
@@ -48,6 +48,7 @@ void cleanup_srcu_struct(struct srcu_struct *sp);
 int srcu_read_lock(struct srcu_struct *sp) __acquires(sp);
 void srcu_read_unlock(struct srcu_struct *sp, int idx) __releases(sp);
 void synchronize_srcu(struct srcu_struct *sp);
+void synchronize_srcu_expedited(struct srcu_struct *sp);
 long srcu_batches_completed(struct srcu_struct *sp);
 
 #endif
index cd15df6c63cdc07f51d2823ccb2a7e77b070c8ee..5e781d824e6d1680466479bdd6d726195203c55a 100644 (file)
@@ -301,6 +301,8 @@ static inline int unregister_pm_notifier(struct notifier_block *nb)
 #define pm_notifier(fn, pri)   do { (void)(fn); } while (0)
 #endif /* !CONFIG_PM_SLEEP */
 
+extern struct mutex pm_mutex;
+
 #ifndef CONFIG_HIBERNATION
 static inline void register_nosave_region(unsigned long b, unsigned long e)
 {
@@ -308,8 +310,23 @@ static inline void register_nosave_region(unsigned long b, unsigned long e)
 static inline void register_nosave_region_late(unsigned long b, unsigned long e)
 {
 }
-#endif
 
-extern struct mutex pm_mutex;
+static inline void lock_system_sleep(void) {}
+static inline void unlock_system_sleep(void) {}
+
+#else
+
+/* Let some subsystems like memory hotadd exclude hibernation */
+
+static inline void lock_system_sleep(void)
+{
+       mutex_lock(&pm_mutex);
+}
+
+static inline void unlock_system_sleep(void)
+{
+       mutex_unlock(&pm_mutex);
+}
+#endif
 
 #endif /* _LINUX_SUSPEND_H */
index 73b1f1cec423e8905db463c32a6fb8d96cf9fa0f..febedcf67c7ec38464add407881e0351f6352ca5 100644 (file)
@@ -7,6 +7,8 @@ struct device;
 struct dma_attrs;
 struct scatterlist;
 
+extern int swiotlb_force;
+
 /*
  * Maximum allowable number of contiguous slabs to map,
  * must be a power of 2.  What is the appropriate value ?
@@ -20,8 +22,7 @@ struct scatterlist;
  */
 #define IO_TLB_SHIFT 11
 
-extern void
-swiotlb_init(void);
+extern void swiotlb_init(int verbose);
 
 extern void
 *swiotlb_alloc_coherent(struct device *hwdev, size_t size,
@@ -88,4 +89,11 @@ swiotlb_dma_mapping_error(struct device *hwdev, dma_addr_t dma_addr);
 extern int
 swiotlb_dma_supported(struct device *hwdev, u64 mask);
 
+#ifdef CONFIG_SWIOTLB
+extern void __init swiotlb_free(void);
+#else
+static inline void swiotlb_free(void) { }
+#endif
+
+extern void swiotlb_print_info(void);
 #endif /* __LINUX_SWIOTLB_H */
index 3338b3f5c21a0122ff530cee83f0b813ebc20b17..ac5d1c1285d9ef674e6a4630747ad4b58b3aa171 100644 (file)
  */
 #define        TPM_ANY_NUM 0xFFFF
 
-#if defined(CONFIG_TCG_TPM)
+#if defined(CONFIG_TCG_TPM) || defined(CONFIG_TCG_TPM_MODULE)
 
 extern int tpm_pcr_read(u32 chip_num, int pcr_idx, u8 *res_buf);
 extern int tpm_pcr_extend(u32 chip_num, int pcr_idx, const u8 *hash);
+#else
+static inline int tpm_pcr_read(u32 chip_num, int pcr_idx, u8 *res_buf) {
+       return -ENODEV;
+}
+static inline int tpm_pcr_extend(u32 chip_num, int pcr_idx, const u8 *hash) {
+       return -ENODEV;
+}
 #endif
 #endif
index 7afca0d72139f4993b089b5b1761c16f846f3434..7ffa11f062324de1b79bb0d3093dac8523aaee0c 100644 (file)
@@ -70,8 +70,8 @@ struct vt_event {
 #define VT_EVENT_UNBLANK       0x0004  /* Screen unblank */
 #define VT_EVENT_RESIZE                0x0008  /* Resize display */
 #define VT_MAX_EVENT           0x000F
-       unsigned int old;               /* Old console */
-       unsigned int new;               /* New console (if changing) */
+       unsigned int oldev;             /* Old console */
+       unsigned int newev;             /* New console (if changing) */
        unsigned int pad[4];            /* Padding for expansion */
 };
 
index c75b960c8ac8e0e954c400f43c4c163cc360caea..998c30fc89819f2d48140dd83ad82feb40e6f99b 100644 (file)
@@ -1283,6 +1283,12 @@ enum ieee80211_filter_flags {
  *
  * These flags are used with the ampdu_action() callback in
  * &struct ieee80211_ops to indicate which action is needed.
+ *
+ * Note that drivers MUST be able to deal with a TX aggregation
+ * session being stopped even before they OK'ed starting it by
+ * calling ieee80211_start_tx_ba_cb(_irqsafe), because the peer
+ * might receive the addBA frame and send a delBA right away!
+ *
  * @IEEE80211_AMPDU_RX_START: start Rx aggregation
  * @IEEE80211_AMPDU_RX_STOP: stop Rx aggregation
  * @IEEE80211_AMPDU_TX_START: start Tx aggregation
index 6e5f0e0c7967e9f78589ba4f5d1f56ab09c2e2aa..0a474568b003053686f98e27d4102d34148a8ade 100644 (file)
@@ -893,7 +893,6 @@ struct sctp_transport {
         */
        /* RTO         : The current retransmission timeout value.  */
        unsigned long rto;
-       unsigned long last_rto;
 
        __u32 rtt;              /* This is the most recent RTT.  */
 
@@ -1980,7 +1979,7 @@ void sctp_assoc_set_primary(struct sctp_association *,
 void sctp_assoc_del_nonprimary_peers(struct sctp_association *,
                                    struct sctp_transport *);
 int sctp_assoc_set_bind_addr_from_ep(struct sctp_association *,
-                                    gfp_t);
+                                    sctp_scope_t, gfp_t);
 int sctp_assoc_set_bind_addr_from_cookie(struct sctp_association *,
                                         struct sctp_cookie*,
                                         gfp_t gfp);
index 904468a191ef43c46c8a7fa091967a4f9f09e1c5..afc2bfb9e917bcb63ebda29847b00e848111d8be 100644 (file)
 #ifndef _LINUX_CS_H
 #define _LINUX_CS_H
 
+#ifdef __KERNEL__
+#include <linux/interrupt.h>
+#endif
+
 /* For AccessConfigurationRegister */
 typedef struct conf_reg_t {
     u_char     Function;
@@ -111,11 +115,9 @@ typedef struct io_req_t {
 
 /* For RequestIRQ and ReleaseIRQ */
 typedef struct irq_req_t {
-    u_int      Attributes;
-    u_int      AssignedIRQ;
-    u_int      IRQInfo1, IRQInfo2; /* IRQInfo2 is ignored */
-    void       *Handler;
-    void       *Instance;
+       u_int           Attributes;
+       u_int           AssignedIRQ;
+       irq_handler_t   Handler;
 } irq_req_t;
 
 /* Attributes for RequestIRQ and ReleaseIRQ */
@@ -125,7 +127,7 @@ typedef struct irq_req_t {
 #define IRQ_TYPE_DYNAMIC_SHARING       0x02
 #define IRQ_FORCED_PULSE               0x04
 #define IRQ_FIRST_SHARED               0x08
-#define IRQ_HANDLE_PRESENT             0x10
+//#define IRQ_HANDLE_PRESENT           0x10
 #define IRQ_PULSE_ALLOCATED            0x100
 
 /* Bits in IRQInfo1 field */
index 315965a37930099f6ffed2a672b303ba694b9bc6..f5e3b8386c8ffc90eef4f6a98daa9f77a68e4f87 100644 (file)
@@ -26,8 +26,7 @@ typedef u_int event_t;
 typedef u_char cisdata_t;
 typedef u_short        page_t;
 
-struct window_t;
-typedef struct window_t *window_handle_t;
+typedef unsigned long window_handle_t;
 
 struct region_t;
 typedef struct region_t *memory_handle_t;
index a2be80b9a095fcd1bb955af8d2eacd75eafdddec..d403c12f797820928bb040ff166e9469c532ba81 100644 (file)
@@ -34,6 +34,7 @@
 struct pcmcia_socket;
 struct pcmcia_device;
 struct config_t;
+struct net_device;
 
 /* dynamic device IDs for PCMCIA device drivers. See
  * Documentation/pcmcia/driver.txt for details.
@@ -137,65 +138,39 @@ struct pcmcia_device {
 #define to_pcmcia_dev(n) container_of(n, struct pcmcia_device, dev)
 #define to_pcmcia_drv(n) container_of(n, struct pcmcia_driver, drv)
 
-/* deprecated -- don't use! */
-#define handle_to_dev(handle) (handle->dev)
 
-
-/* (deprecated) error reporting by PCMCIA devices. Use dev_printk()
- * or dev_dbg() directly in the driver, without referring to pcmcia_error_func()
- * and/or pcmcia_error_ret() for those functions will go away soon.
- */
-enum service {
-    AccessConfigurationRegister, AddSocketServices,
-    AdjustResourceInfo, CheckEraseQueue, CloseMemory, CopyMemory,
-    DeregisterClient, DeregisterEraseQueue, GetCardServicesInfo,
-    GetClientInfo, GetConfigurationInfo, GetEventMask,
-    GetFirstClient, GetFirstPartion, GetFirstRegion, GetFirstTuple,
-    GetNextClient, GetNextPartition, GetNextRegion, GetNextTuple,
-    GetStatus, GetTupleData, MapLogSocket, MapLogWindow, MapMemPage,
-    MapPhySocket, MapPhyWindow, ModifyConfiguration, ModifyWindow,
-    OpenMemory, ParseTuple, ReadMemory, RegisterClient,
-    RegisterEraseQueue, RegisterMTD, RegisterTimer,
-    ReleaseConfiguration, ReleaseExclusive, ReleaseIO, ReleaseIRQ,
-    ReleaseSocketMask, ReleaseWindow, ReplaceSocketServices,
-    RequestConfiguration, RequestExclusive, RequestIO, RequestIRQ,
-    RequestSocketMask, RequestWindow, ResetCard, ReturnSSEntry,
-    SetEventMask, SetRegion, ValidateCIS, VendorSpecific,
-    WriteMemory, BindDevice, BindMTD, ReportError,
-    SuspendCard, ResumeCard, EjectCard, InsertCard, ReplaceCIS,
-    GetFirstWindow, GetNextWindow, GetMemPage
-};
-const char *pcmcia_error_func(int func);
-const char *pcmcia_error_ret(int ret);
-
-#define cs_error(p_dev, func, ret)                     \
-       {                                               \
-               dev_printk(KERN_NOTICE, &p_dev->dev,    \
-                          "%s : %s\n",                 \
-                          pcmcia_error_func(func),     \
-                          pcmcia_error_ret(ret));      \
-       }
-
-/* CIS access.
- * Use the pcmcia_* versions in PCMCIA drivers
+/*
+ * CIS access.
+ *
+ * Please use the following functions to access CIS tuples:
+ * - pcmcia_get_tuple()
+ * - pcmcia_loop_tuple()
+ * - pcmcia_get_mac_from_cis()
+ *
+ * To parse a tuple_t, pcmcia_parse_tuple() exists. Its interface
+ * might change in future.
  */
-int pcmcia_parse_tuple(tuple_t *tuple, cisparse_t *parse);
 
-int pccard_get_first_tuple(struct pcmcia_socket *s, unsigned int function,
-                          tuple_t *tuple);
-#define pcmcia_get_first_tuple(p_dev, tuple) \
-               pccard_get_first_tuple(p_dev->socket, p_dev->func, tuple)
+/* get the very first CIS entry of type @code. Note that buf is pointer
+ * to u8 *buf; and that you need to kfree(buf) afterwards. */
+size_t pcmcia_get_tuple(struct pcmcia_device *p_dev, cisdata_t code,
+                       u8 **buf);
 
-int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int function,
-                         tuple_t *tuple);
-#define pcmcia_get_next_tuple(p_dev, tuple) \
-               pccard_get_next_tuple(p_dev->socket, p_dev->func, tuple)
+/* loop over CIS entries */
+int pcmcia_loop_tuple(struct pcmcia_device *p_dev, cisdata_t code,
+                     int (*loop_tuple) (struct pcmcia_device *p_dev,
+                                        tuple_t *tuple,
+                                        void *priv_data),
+                     void *priv_data);
 
-int pccard_get_tuple_data(struct pcmcia_socket *s, tuple_t *tuple);
-#define pcmcia_get_tuple_data(p_dev, tuple) \
-               pccard_get_tuple_data(p_dev->socket, tuple)
+/* get the MAC address from CISTPL_FUNCE */
+int pcmcia_get_mac_from_cis(struct pcmcia_device *p_dev,
+                           struct net_device *dev);
 
 
+/* parse a tuple_t */
+int pcmcia_parse_tuple(tuple_t *tuple, cisparse_t *parse);
+
 /* loop CIS entries for valid configuration */
 int pcmcia_loop_config(struct pcmcia_device *p_dev,
                       int      (*conf_check)   (struct pcmcia_device *p_dev,
@@ -221,12 +196,11 @@ int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req);
 int pcmcia_request_configuration(struct pcmcia_device *p_dev,
                                 config_req_t *req);
 
-int pcmcia_request_window(struct pcmcia_device **p_dev, win_req_t *req,
+int pcmcia_request_window(struct pcmcia_device *p_dev, win_req_t *req,
                          window_handle_t *wh);
-int pcmcia_release_window(window_handle_t win);
-
-int pcmcia_get_mem_page(window_handle_t win, memreq_t *req);
-int pcmcia_map_mem_page(window_handle_t win, memreq_t *req);
+int pcmcia_release_window(struct pcmcia_device *p_dev, window_handle_t win);
+int pcmcia_map_mem_page(struct pcmcia_device *p_dev, window_handle_t win,
+                       memreq_t *req);
 
 int pcmcia_modify_configuration(struct pcmcia_device *p_dev, modconf_t *mod);
 void pcmcia_disable_device(struct pcmcia_device *p_dev);
index e0f6feb8588c0e062161431b31681542bb58450b..7c23be706f128bbc02365e868687aa3dbcc73047 100644 (file)
@@ -107,15 +107,6 @@ typedef struct io_window_t {
        struct resource         *res;
 } io_window_t;
 
-#define WINDOW_MAGIC   0xB35C
-typedef struct window_t {
-       u_short                 magic;
-       u_short                 index;
-       struct pcmcia_device    *handle;
-       struct pcmcia_socket    *sock;
-       pccard_mem_map          ctl;
-} window_t;
-
 /* Maximum number of IO windows per socket */
 #define MAX_IO_WIN 2
 
@@ -155,7 +146,7 @@ struct pcmcia_socket {
                u_int                   Config;
        } irq;
        io_window_t                     io[MAX_IO_WIN];
-       window_t                        win[MAX_WIN];
+       pccard_mem_map                  win[MAX_WIN];
        struct list_head                cis_cache;
        size_t                          fake_cis_len;
        u8                              *fake_cis;
@@ -172,7 +163,7 @@ struct pcmcia_socket {
        u_int                           irq_mask;
        u_int                           map_size;
        u_int                           io_offset;
-       u_char                          pci_irq;
+       u_int                           pci_irq;
        struct pci_dev *                cb_dev;
 
 
index 9af48cbf0036782386e6cfdf403476b8b159d563..f097ae340bc19f486a7ff5a287acf1c4a8fd72e0 100644 (file)
@@ -145,6 +145,7 @@ struct scsi_device {
        unsigned retry_hwerror:1;       /* Retry HARDWARE_ERROR */
        unsigned last_sector_bug:1;     /* do not use multisector accesses on
                                           SD_LAST_BUGGY_SECTORS */
+       unsigned is_visible:1;  /* is the device visible in sysfs */
 
        DECLARE_BITMAP(supported_events, SDEV_EVT_MAXBITS); /* supported events */
        struct list_head event_list;    /* asserted events */
index 6e728b176904664abb12f132fa63aaced2a4aa00..47941fc5aba753e2de036f8fb79f06588f73c9ff 100644 (file)
@@ -797,30 +797,23 @@ static inline unsigned int scsi_host_get_prot(struct Scsi_Host *shost)
 
 static inline unsigned int scsi_host_dif_capable(struct Scsi_Host *shost, unsigned int target_type)
 {
-       switch (target_type) {
-       case 1:
-               if (shost->prot_capabilities & SHOST_DIF_TYPE1_PROTECTION)
-                       return target_type;
-       case 2:
-               if (shost->prot_capabilities & SHOST_DIF_TYPE2_PROTECTION)
-                       return target_type;
-       case 3:
-               if (shost->prot_capabilities & SHOST_DIF_TYPE3_PROTECTION)
-                       return target_type;
-       }
+       static unsigned char cap[] = { 0,
+                                      SHOST_DIF_TYPE1_PROTECTION,
+                                      SHOST_DIF_TYPE2_PROTECTION,
+                                      SHOST_DIF_TYPE3_PROTECTION };
 
-       return 0;
+       return shost->prot_capabilities & cap[target_type] ? target_type : 0;
 }
 
 static inline unsigned int scsi_host_dix_capable(struct Scsi_Host *shost, unsigned int target_type)
 {
 #if defined(CONFIG_BLK_DEV_INTEGRITY)
-       switch (target_type) {
-       case 0: return shost->prot_capabilities & SHOST_DIX_TYPE0_PROTECTION;
-       case 1: return shost->prot_capabilities & SHOST_DIX_TYPE1_PROTECTION;
-       case 2: return shost->prot_capabilities & SHOST_DIX_TYPE2_PROTECTION;
-       case 3: return shost->prot_capabilities & SHOST_DIX_TYPE3_PROTECTION;
-       }
+       static unsigned char cap[] = { SHOST_DIX_TYPE0_PROTECTION,
+                                      SHOST_DIX_TYPE1_PROTECTION,
+                                      SHOST_DIX_TYPE2_PROTECTION,
+                                      SHOST_DIX_TYPE3_PROTECTION };
+
+       return shost->prot_capabilities & cap[target_type];
 #endif
        return 0;
 }
index 397dff2dbd5acd7a2f23332bbecbf84ce5e93b37..fb726ac7caee4f465033ff5d314d788db929ded5 100644 (file)
@@ -1,5 +1,6 @@
 #undef TRACE_SYSTEM
-#define TRACE_SYSTEM syscalls
+#define TRACE_SYSTEM raw_syscalls
+#define TRACE_INCLUDE_FILE syscalls
 
 #if !defined(_TRACE_EVENTS_SYSCALLS_H) || defined(TRACE_HEADER_MULTI_READ)
 #define _TRACE_EVENTS_SYSCALLS_H
index 2c9c073e45ad1662ee5f88dc80fe7aff757f3042..d1b3de9c1a714f7624956c01fb60bd22898d4c6a 100644 (file)
 #undef __get_str
 
 #undef TP_printk
-#define TP_printk(fmt, args...) "%s, %s\n", #fmt, __stringify(args)
+#define TP_printk(fmt, args...) "\"%s\", %s\n", fmt, __stringify(args)
 
 #undef TP_fast_assign
 #define TP_fast_assign(args...) args
diff --git a/include/trace/power.h b/include/trace/power.h
deleted file mode 100644 (file)
index ef20466..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-#ifndef _TRACE_POWER_H
-#define _TRACE_POWER_H
-
-#include <linux/ktime.h>
-#include <linux/tracepoint.h>
-
-enum {
-       POWER_NONE = 0,
-       POWER_CSTATE = 1,
-       POWER_PSTATE = 2,
-};
-
-struct power_trace {
-       ktime_t                 stamp;
-       ktime_t                 end;
-       int                     type;
-       int                     state;
-};
-
-DECLARE_TRACE(power_start,
-       TP_PROTO(struct power_trace *it, unsigned int type, unsigned int state),
-             TP_ARGS(it, type, state));
-
-DECLARE_TRACE(power_mark,
-       TP_PROTO(struct power_trace *it, unsigned int type, unsigned int state),
-             TP_ARGS(it, type, state));
-
-DECLARE_TRACE(power_end,
-       TP_PROTO(struct power_trace *it),
-             TP_ARGS(it));
-
-#endif /* _TRACE_POWER_H */
index 9e03ef8b311ec303b7fd1f70cc21021620100171..9ee7782947561831509157409b9860a200dff205 100644 (file)
@@ -334,6 +334,15 @@ config TREE_PREEMPT_RCU
          is also required.  It also scales down nicely to
          smaller systems.
 
+config TINY_RCU
+       bool "UP-only small-memory-footprint RCU"
+       depends on !SMP
+       help
+         This option selects the RCU implementation that is
+         designed for UP systems from which real-time response
+         is not required.  This option greatly reduces the
+         memory footprint of RCU.
+
 endchoice
 
 config RCU_TRACE
@@ -606,7 +615,7 @@ config SYSFS_DEPRECATED
        bool
 
 config SYSFS_DEPRECATED_V2
-       bool "remove sysfs features which may confuse old userspace tools"
+       bool "enable deprecated sysfs features which may confuse old userspace tools"
        depends on SYSFS
        default n
        select SYSFS_DEPRECATED
@@ -1098,6 +1107,16 @@ config SLOW_WORK
 
          See Documentation/slow-work.txt.
 
+config SLOW_WORK_DEBUG
+       bool "Slow work debugging through debugfs"
+       default n
+       depends on SLOW_WORK && DEBUG_FS
+       help
+         Display the contents of the slow work run queue through debugfs,
+         including items currently executing.
+
+         See Documentation/slow-work.txt.
+
 endmenu                # General setup
 
 config HAVE_GENERIC_DMA_COHERENT
@@ -1210,3 +1229,4 @@ source "block/Kconfig"
 config PREEMPT_NOTIFIERS
        bool
 
+source "kernel/Kconfig.locks"
index 5988debfc505c84c8c5f7abeb0b5fb1e2d88f1fc..4051d75dd2d64e765b5d2856eac0da7fa796ef95 100644 (file)
@@ -251,7 +251,7 @@ early_param("loglevel", loglevel);
 
 /*
  * Unknown boot options get handed to init, unless they look like
- * failed parameters
+ * unused parameters (modprobe will find them in /proc/cmdline).
  */
 static int __init unknown_bootoption(char *param, char *val)
 {
@@ -272,14 +272,9 @@ static int __init unknown_bootoption(char *param, char *val)
        if (obsolete_checksetup(param))
                return 0;
 
-       /*
-        * Preemptive maintenance for "why didn't my misspelled command
-        * line work?"
-        */
-       if (strchr(param, '.') && (!val || strchr(param, '.') < val)) {
-               printk(KERN_ERR "Unknown boot option `%s': ignoring\n", param);
+       /* Unused module parameter. */
+       if (strchr(param, '.') && (!val || strchr(param, '.') < val))
                return 0;
-       }
 
        if (panic_later)
                return 0;
diff --git a/kernel/Kconfig.locks b/kernel/Kconfig.locks
new file mode 100644 (file)
index 0000000..88c92fb
--- /dev/null
@@ -0,0 +1,202 @@
+#
+# The ARCH_INLINE foo is necessary because select ignores "depends on"
+#
+config ARCH_INLINE_SPIN_TRYLOCK
+       bool
+
+config ARCH_INLINE_SPIN_TRYLOCK_BH
+       bool
+
+config ARCH_INLINE_SPIN_LOCK
+       bool
+
+config ARCH_INLINE_SPIN_LOCK_BH
+       bool
+
+config ARCH_INLINE_SPIN_LOCK_IRQ
+       bool
+
+config ARCH_INLINE_SPIN_LOCK_IRQSAVE
+       bool
+
+config ARCH_INLINE_SPIN_UNLOCK
+       bool
+
+config ARCH_INLINE_SPIN_UNLOCK_BH
+       bool
+
+config ARCH_INLINE_SPIN_UNLOCK_IRQ
+       bool
+
+config ARCH_INLINE_SPIN_UNLOCK_IRQRESTORE
+       bool
+
+
+config ARCH_INLINE_READ_TRYLOCK
+       bool
+
+config ARCH_INLINE_READ_LOCK
+       bool
+
+config ARCH_INLINE_READ_LOCK_BH
+       bool
+
+config ARCH_INLINE_READ_LOCK_IRQ
+       bool
+
+config ARCH_INLINE_READ_LOCK_IRQSAVE
+       bool
+
+config ARCH_INLINE_READ_UNLOCK
+       bool
+
+config ARCH_INLINE_READ_UNLOCK_BH
+       bool
+
+config ARCH_INLINE_READ_UNLOCK_IRQ
+       bool
+
+config ARCH_INLINE_READ_UNLOCK_IRQRESTORE
+       bool
+
+
+config ARCH_INLINE_WRITE_TRYLOCK
+       bool
+
+config ARCH_INLINE_WRITE_LOCK
+       bool
+
+config ARCH_INLINE_WRITE_LOCK_BH
+       bool
+
+config ARCH_INLINE_WRITE_LOCK_IRQ
+       bool
+
+config ARCH_INLINE_WRITE_LOCK_IRQSAVE
+       bool
+
+config ARCH_INLINE_WRITE_UNLOCK
+       bool
+
+config ARCH_INLINE_WRITE_UNLOCK_BH
+       bool
+
+config ARCH_INLINE_WRITE_UNLOCK_IRQ
+       bool
+
+config ARCH_INLINE_WRITE_UNLOCK_IRQRESTORE
+       bool
+
+#
+# lock_* functions are inlined when:
+#   - DEBUG_SPINLOCK=n and GENERIC_LOCKBREAK=n and ARCH_INLINE_*LOCK=y
+#
+# trylock_* functions are inlined when:
+#   - DEBUG_SPINLOCK=n and ARCH_INLINE_*LOCK=y
+#
+# unlock and unlock_irq functions are inlined when:
+#   - DEBUG_SPINLOCK=n and ARCH_INLINE_*LOCK=y
+#  or
+#   - DEBUG_SPINLOCK=n and PREEMPT=n
+#
+# unlock_bh and unlock_irqrestore functions are inlined when:
+#   - DEBUG_SPINLOCK=n and ARCH_INLINE_*LOCK=y
+#
+
+config INLINE_SPIN_TRYLOCK
+       def_bool !DEBUG_SPINLOCK && ARCH_INLINE_SPIN_TRYLOCK
+
+config INLINE_SPIN_TRYLOCK_BH
+       def_bool !DEBUG_SPINLOCK && ARCH_INLINE_SPIN_TRYLOCK_BH
+
+config INLINE_SPIN_LOCK
+       def_bool !DEBUG_SPINLOCK && !GENERIC_LOCKBREAK && ARCH_INLINE_SPIN_LOCK
+
+config INLINE_SPIN_LOCK_BH
+       def_bool !DEBUG_SPINLOCK && !GENERIC_LOCKBREAK && \
+                ARCH_INLINE_SPIN_LOCK_BH
+
+config INLINE_SPIN_LOCK_IRQ
+       def_bool !DEBUG_SPINLOCK && !GENERIC_LOCKBREAK && \
+                ARCH_INLINE_SPIN_LOCK_IRQ
+
+config INLINE_SPIN_LOCK_IRQSAVE
+       def_bool !DEBUG_SPINLOCK && !GENERIC_LOCKBREAK && \
+                ARCH_INLINE_SPIN_LOCK_IRQSAVE
+
+config INLINE_SPIN_UNLOCK
+       def_bool !DEBUG_SPINLOCK && (!PREEMPT || ARCH_INLINE_SPIN_UNLOCK)
+
+config INLINE_SPIN_UNLOCK_BH
+       def_bool !DEBUG_SPINLOCK && ARCH_INLINE_SPIN_UNLOCK_BH
+
+config INLINE_SPIN_UNLOCK_IRQ
+       def_bool !DEBUG_SPINLOCK && (!PREEMPT || ARCH_INLINE_SPIN_UNLOCK_BH)
+
+config INLINE_SPIN_UNLOCK_IRQRESTORE
+       def_bool !DEBUG_SPINLOCK && ARCH_INLINE_SPIN_UNLOCK_IRQRESTORE
+
+
+config INLINE_READ_TRYLOCK
+       def_bool !DEBUG_SPINLOCK && ARCH_INLINE_READ_TRYLOCK
+
+config INLINE_READ_LOCK
+       def_bool !DEBUG_SPINLOCK && !GENERIC_LOCKBREAK && ARCH_INLINE_READ_LOCK
+
+config INLINE_READ_LOCK_BH
+       def_bool !DEBUG_SPINLOCK && !GENERIC_LOCKBREAK && \
+                ARCH_INLINE_READ_LOCK_BH
+
+config INLINE_READ_LOCK_IRQ
+       def_bool !DEBUG_SPINLOCK && !GENERIC_LOCKBREAK && \
+                ARCH_INLINE_READ_LOCK_IRQ
+
+config INLINE_READ_LOCK_IRQSAVE
+       def_bool !DEBUG_SPINLOCK && !GENERIC_LOCKBREAK && \
+                ARCH_INLINE_READ_LOCK_IRQSAVE
+
+config INLINE_READ_UNLOCK
+       def_bool !DEBUG_SPINLOCK && (!PREEMPT || ARCH_INLINE_READ_UNLOCK)
+
+config INLINE_READ_UNLOCK_BH
+       def_bool !DEBUG_SPINLOCK && ARCH_INLINE_READ_UNLOCK_BH
+
+config INLINE_READ_UNLOCK_IRQ
+       def_bool !DEBUG_SPINLOCK && (!PREEMPT || ARCH_INLINE_READ_UNLOCK_BH)
+
+config INLINE_READ_UNLOCK_IRQRESTORE
+       def_bool !DEBUG_SPINLOCK && ARCH_INLINE_READ_UNLOCK_IRQRESTORE
+
+
+config INLINE_WRITE_TRYLOCK
+       def_bool !DEBUG_SPINLOCK && ARCH_INLINE_WRITE_TRYLOCK
+
+config INLINE_WRITE_LOCK
+       def_bool !DEBUG_SPINLOCK && !GENERIC_LOCKBREAK && ARCH_INLINE_WRITE_LOCK
+
+config INLINE_WRITE_LOCK_BH
+       def_bool !DEBUG_SPINLOCK && !GENERIC_LOCKBREAK && \
+                ARCH_INLINE_WRITE_LOCK_BH
+
+config INLINE_WRITE_LOCK_IRQ
+       def_bool !DEBUG_SPINLOCK && !GENERIC_LOCKBREAK && \
+                ARCH_INLINE_WRITE_LOCK_IRQ
+
+config INLINE_WRITE_LOCK_IRQSAVE
+       def_bool !DEBUG_SPINLOCK && !GENERIC_LOCKBREAK && \
+                ARCH_INLINE_WRITE_LOCK_IRQSAVE
+
+config INLINE_WRITE_UNLOCK
+       def_bool !DEBUG_SPINLOCK && (!PREEMPT || ARCH_INLINE_WRITE_UNLOCK)
+
+config INLINE_WRITE_UNLOCK_BH
+       def_bool !DEBUG_SPINLOCK && ARCH_INLINE_WRITE_UNLOCK_BH
+
+config INLINE_WRITE_UNLOCK_IRQ
+       def_bool !DEBUG_SPINLOCK && (!PREEMPT || ARCH_INLINE_WRITE_UNLOCK_BH)
+
+config INLINE_WRITE_UNLOCK_IRQRESTORE
+       def_bool !DEBUG_SPINLOCK && ARCH_INLINE_WRITE_UNLOCK_IRQRESTORE
+
+config MUTEX_SPIN_ON_OWNER
+       def_bool SMP && !DEBUG_MUTEXES && !HAVE_DEFAULT_NO_SPIN_MUTEXES
index 6b7ce8173dfdc063676dd6d2a565fbcc56cc7603..982c50e2ce534df9a3bf5a704580fd0e13fe7f5b 100644 (file)
@@ -83,6 +83,7 @@ obj-$(CONFIG_RCU_TORTURE_TEST) += rcutorture.o
 obj-$(CONFIG_TREE_RCU) += rcutree.o
 obj-$(CONFIG_TREE_PREEMPT_RCU) += rcutree.o
 obj-$(CONFIG_TREE_RCU_TRACE) += rcutree_trace.o
+obj-$(CONFIG_TINY_RCU) += rcutiny.o
 obj-$(CONFIG_RELAY) += relay.o
 obj-$(CONFIG_SYSCTL) += utsname_sysctl.o
 obj-$(CONFIG_TASK_DELAY_ACCT) += delayacct.o
@@ -95,6 +96,7 @@ obj-$(CONFIG_X86_DS) += trace/
 obj-$(CONFIG_RING_BUFFER) += trace/
 obj-$(CONFIG_SMP) += sched_cpupri.o
 obj-$(CONFIG_SLOW_WORK) += slow-work.o
+obj-$(CONFIG_SLOW_WORK_DEBUG) += slow-work-debugfs.o
 obj-$(CONFIG_PERF_EVENTS) += perf_event.o
 obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o
 
index 4e17041963f57073a4fb3836c415b9a681e40383..7f876e60521f0f3f5cda063db39be0177bf50f3f 100644 (file)
@@ -29,7 +29,6 @@ EXPORT_SYMBOL(__cap_empty_set);
 EXPORT_SYMBOL(__cap_full_set);
 EXPORT_SYMBOL(__cap_init_eff_set);
 
-#ifdef CONFIG_SECURITY_FILE_CAPABILITIES
 int file_caps_enabled = 1;
 
 static int __init file_caps_disable(char *str)
@@ -38,7 +37,6 @@ static int __init file_caps_disable(char *str)
        return 1;
 }
 __setup("no_file_caps", file_caps_disable);
-#endif
 
 /*
  * More recent versions of libcap are available from:
@@ -169,8 +167,8 @@ SYSCALL_DEFINE2(capget, cap_user_header_t, header, cap_user_data_t, dataptr)
        kernel_cap_t pE, pI, pP;
 
        ret = cap_validate_magic(header, &tocopy);
-       if (ret != 0)
-               return ret;
+       if ((dataptr == NULL) || (ret != 0))
+               return ((dataptr == NULL) && (ret == -EINVAL)) ? 0 : ret;
 
        if (get_user(pid, &header->pid))
                return -EFAULT;
@@ -238,7 +236,7 @@ SYSCALL_DEFINE2(capget, cap_user_header_t, header, cap_user_data_t, dataptr)
 SYSCALL_DEFINE2(capset, cap_user_header_t, header, const cap_user_data_t, data)
 {
        struct __user_cap_data_struct kdata[_KERNEL_CAPABILITY_U32S];
-       unsigned i, tocopy;
+       unsigned i, tocopy, copybytes;
        kernel_cap_t inheritable, permitted, effective;
        struct cred *new;
        int ret;
@@ -255,8 +253,11 @@ SYSCALL_DEFINE2(capset, cap_user_header_t, header, const cap_user_data_t, data)
        if (pid != 0 && pid != task_pid_vnr(current))
                return -EPERM;
 
-       if (copy_from_user(&kdata, data,
-                          tocopy * sizeof(struct __user_cap_data_struct)))
+       copybytes = tocopy * sizeof(struct __user_cap_data_struct);
+       if (copybytes > sizeof(kdata))
+               return -EFAULT;
+
+       if (copy_from_user(&kdata, data, copybytes))
                return -EFAULT;
 
        for (i = 0; i < tocopy; i++) {
index d4e84174740018f30bdf8aa02d62e8799676a938..0c642d51aac2d8ab82c782a786eb13b90c0985c1 100644 (file)
@@ -144,7 +144,7 @@ static void check_hung_uninterruptible_tasks(unsigned long timeout)
 
        rcu_read_lock();
        do_each_thread(g, t) {
-               if (!--max_count)
+               if (!max_count--)
                        goto unlock;
                if (!--batch_count) {
                        batch_count = HUNG_TASK_BATCHING;
index c1660194d1153a4b55adda2263b752547daa8563..ba566c261adc3dc3fbf001af3d630fd7e4a9c771 100644 (file)
@@ -166,11 +166,11 @@ int set_irq_data(unsigned int irq, void *data)
 EXPORT_SYMBOL(set_irq_data);
 
 /**
- *     set_irq_data - set irq type data for an irq
+ *     set_irq_msi - set MSI descriptor data for an irq
  *     @irq:   Interrupt number
  *     @entry: Pointer to MSI descriptor data
  *
- *     Set the hardware irq controller data for an irq
+ *     Set the MSI descriptor entry for an irq
  */
 int set_irq_msi(unsigned int irq, struct msi_desc *entry)
 {
@@ -590,7 +590,7 @@ out_unlock:
 }
 
 /**
- *     handle_percpu_IRQ - Per CPU local irq handler
+ *     handle_percpu_irq - Per CPU local irq handler
  *     @irq:   the interrupt number
  *     @desc:  the interrupt description structure for this irq
  *
index 692363dd591f0c447d26b36318889f43bbe20ac3..0832145fea977546db87a1b69887c9b24a685b8c 100644 (file)
@@ -136,7 +136,7 @@ out:
 
 static int default_affinity_open(struct inode *inode, struct file *file)
 {
-       return single_open(file, default_affinity_show, NULL);
+       return single_open(file, default_affinity_show, PDE(inode)->data);
 }
 
 static const struct file_operations default_affinity_proc_fops = {
@@ -148,18 +148,28 @@ static const struct file_operations default_affinity_proc_fops = {
 };
 #endif
 
-static int irq_spurious_read(char *page, char **start, off_t off,
-                                 int count, int *eof, void *data)
+static int irq_spurious_proc_show(struct seq_file *m, void *v)
 {
-       struct irq_desc *desc = irq_to_desc((long) data);
-       return sprintf(page, "count %u\n"
-                            "unhandled %u\n"
-                            "last_unhandled %u ms\n",
-                       desc->irq_count,
-                       desc->irqs_unhandled,
-                       jiffies_to_msecs(desc->last_unhandled));
+       struct irq_desc *desc = irq_to_desc((long) m->private);
+
+       seq_printf(m, "count %u\n" "unhandled %u\n" "last_unhandled %u ms\n",
+                  desc->irq_count, desc->irqs_unhandled,
+                  jiffies_to_msecs(desc->last_unhandled));
+       return 0;
+}
+
+static int irq_spurious_proc_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, irq_spurious_proc_show, NULL);
 }
 
+static const struct file_operations irq_spurious_proc_fops = {
+       .open           = irq_spurious_proc_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+};
+
 #define MAX_NAMELEN 128
 
 static int name_unique(unsigned int irq, struct irqaction *new_action)
@@ -204,7 +214,6 @@ void register_handler_proc(unsigned int irq, struct irqaction *action)
 void register_irq_proc(unsigned int irq, struct irq_desc *desc)
 {
        char name [MAX_NAMELEN];
-       struct proc_dir_entry *entry;
 
        if (!root_irq_dir || (desc->chip == &no_irq_chip) || desc->dir)
                return;
@@ -214,6 +223,8 @@ void register_irq_proc(unsigned int irq, struct irq_desc *desc)
 
        /* create /proc/irq/1234 */
        desc->dir = proc_mkdir(name, root_irq_dir);
+       if (!desc->dir)
+               return;
 
 #ifdef CONFIG_SMP
        /* create /proc/irq/<irq>/smp_affinity */
@@ -221,11 +232,8 @@ void register_irq_proc(unsigned int irq, struct irq_desc *desc)
                         &irq_affinity_proc_fops, (void *)(long)irq);
 #endif
 
-       entry = create_proc_entry("spurious", 0444, desc->dir);
-       if (entry) {
-               entry->data = (void *)(long)irq;
-               entry->read_proc = irq_spurious_read;
-       }
+       proc_create_data("spurious", 0444, desc->dir,
+                        &irq_spurious_proc_fops, (void *)(long)irq);
 }
 
 #undef MAX_NAMELEN
index bd7273e6282ecf65a015c1e02239959497753a06..22b0a6eedf2427c4b2a7addb23c65cd1fea1c285 100644 (file)
@@ -104,7 +104,7 @@ static int misrouted_irq(int irq)
        return ok;
 }
 
-static void poll_all_shared_irqs(void)
+static void poll_spurious_irqs(unsigned long dummy)
 {
        struct irq_desc *desc;
        int i;
@@ -125,23 +125,11 @@ static void poll_all_shared_irqs(void)
                try_one_irq(i, desc);
                local_irq_enable();
        }
-}
-
-static void poll_spurious_irqs(unsigned long dummy)
-{
-       poll_all_shared_irqs();
 
        mod_timer(&poll_spurious_irq_timer,
                  jiffies + POLL_SPURIOUS_IRQ_INTERVAL);
 }
 
-#ifdef CONFIG_DEBUG_SHIRQ
-void debug_poll_all_shared_irqs(void)
-{
-       poll_all_shared_irqs();
-}
-#endif
-
 /*
  * If 99,900 of the previous 100,000 interrupts have not been handled
  * then assume that the IRQ is stuck in some manner. Drop a diagnostic
index 9fcb53a11f872e958c95bcf37f8558e9bb148d77..25b1031903642654eb43043ee016d78eebbb26dd 100644 (file)
@@ -80,16 +80,16 @@ int __request_module(bool wait, const char *fmt, ...)
 #define MAX_KMOD_CONCURRENT 50 /* Completely arbitrary value - KAO */
        static int kmod_loop_msg;
 
-       ret = security_kernel_module_request();
-       if (ret)
-               return ret;
-
        va_start(args, fmt);
        ret = vsnprintf(module_name, MODULE_NAME_LEN, fmt, args);
        va_end(args);
        if (ret >= MODULE_NAME_LEN)
                return -ENAMETOOLONG;
 
+       ret = security_kernel_module_request(module_name);
+       if (ret)
+               return ret;
+
        /* If modprobe needs a service that is in a module, we get a recursive
         * loop.  Limit the number of running kmod threads to max_threads/2 or
         * MAX_KMOD_CONCURRENT, whichever is the smaller.  A cleaner method
index 84495958e703366eef86906d1e0ff4aa1cb2d2cd..e5342a344c43bee9140d9127f1fe907b21149e8d 100644 (file)
@@ -1035,9 +1035,9 @@ int __kprobes register_kretprobe(struct kretprobe *rp)
        /* Pre-allocate memory for max kretprobe instances */
        if (rp->maxactive <= 0) {
 #ifdef CONFIG_PREEMPT
-               rp->maxactive = max(10, 2 * NR_CPUS);
+               rp->maxactive = max(10, 2 * num_possible_cpus());
 #else
-               rp->maxactive = NR_CPUS;
+               rp->maxactive = num_possible_cpus();
 #endif
        }
        spin_lock_init(&rp->lock);
index 8b7d8805819d07d998467db967c777c04021ec9e..5842a71cf0527163c960cc8c41d549a5033e3443 100644 (file)
@@ -1187,7 +1187,8 @@ static void add_sect_attrs(struct module *mod, unsigned int nsect,
 
        /* Count loaded sections and allocate structures */
        for (i = 0; i < nsect; i++)
-               if (sechdrs[i].sh_flags & SHF_ALLOC)
+               if (sechdrs[i].sh_flags & SHF_ALLOC
+                   && sechdrs[i].sh_size)
                        nloaded++;
        size[0] = ALIGN(sizeof(*sect_attrs)
                        + nloaded * sizeof(sect_attrs->attrs[0]),
@@ -1207,6 +1208,8 @@ static void add_sect_attrs(struct module *mod, unsigned int nsect,
        for (i = 0; i < nsect; i++) {
                if (! (sechdrs[i].sh_flags & SHF_ALLOC))
                        continue;
+               if (!sechdrs[i].sh_size)
+                       continue;
                sattr->address = sechdrs[i].sh_addr;
                sattr->name = kstrdup(secstrings + sechdrs[i].sh_name,
                                        GFP_KERNEL);
index 947b3ad551f8a925c39ef6f53f4f37c16f8a3ea3..632f04c57d82b0207608f10a57f95582833489c1 100644 (file)
@@ -148,8 +148,8 @@ __mutex_lock_common(struct mutex *lock, long state, unsigned int subclass,
 
        preempt_disable();
        mutex_acquire(&lock->dep_map, subclass, 0, ip);
-#if defined(CONFIG_SMP) && !defined(CONFIG_DEBUG_MUTEXES) && \
-    !defined(CONFIG_HAVE_DEFAULT_NO_SPIN_MUTEXES)
+
+#ifdef CONFIG_MUTEX_SPIN_ON_OWNER
        /*
         * Optimistic spinning.
         *
index f38b07f78a4e864da8fb2c7bcc5a0641bd04e7b5..b5ac4d99c667c96ba55542f69963baf7b151f838 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/bootmem.h>
 #include <linux/syscalls.h>
 #include <linux/kexec.h>
+#include <linux/ratelimit.h>
 
 #include <asm/uaccess.h>
 
@@ -1376,11 +1377,11 @@ late_initcall(disable_boot_consoles);
  */
 DEFINE_RATELIMIT_STATE(printk_ratelimit_state, 5 * HZ, 10);
 
-int printk_ratelimit(void)
+int __printk_ratelimit(const char *func)
 {
-       return __ratelimit(&printk_ratelimit_state);
+       return ___ratelimit(&printk_ratelimit_state, func);
 }
-EXPORT_SYMBOL(printk_ratelimit);
+EXPORT_SYMBOL(__printk_ratelimit);
 
 /**
  * printk_timed_ratelimit - caller-controlled printk ratelimiting
index 400183346ad22b0e216d21a429295e2cb28b123b..9b7fd4723878da6c3b5d2526cd0bc15550cce9a9 100644 (file)
@@ -44,7 +44,6 @@
 #include <linux/cpu.h>
 #include <linux/mutex.h>
 #include <linux/module.h>
-#include <linux/kernel_stat.h>
 
 #ifdef CONFIG_DEBUG_LOCK_ALLOC
 static struct lock_class_key rcu_lock_key;
@@ -53,8 +52,6 @@ struct lockdep_map rcu_lock_map =
 EXPORT_SYMBOL_GPL(rcu_lock_map);
 #endif
 
-int rcu_scheduler_active __read_mostly;
-
 /*
  * Awaken the corresponding synchronize_rcu() instance now that a
  * grace period has elapsed.
@@ -66,122 +63,3 @@ void wakeme_after_rcu(struct rcu_head  *head)
        rcu = container_of(head, struct rcu_synchronize, head);
        complete(&rcu->completion);
 }
-
-#ifdef CONFIG_TREE_PREEMPT_RCU
-
-/**
- * synchronize_rcu - wait until a grace period has elapsed.
- *
- * Control will return to the caller some time after a full grace
- * period has elapsed, in other words after all currently executing RCU
- * read-side critical sections have completed.  RCU read-side critical
- * sections are delimited by rcu_read_lock() and rcu_read_unlock(),
- * and may be nested.
- */
-void synchronize_rcu(void)
-{
-       struct rcu_synchronize rcu;
-
-       if (!rcu_scheduler_active)
-               return;
-
-       init_completion(&rcu.completion);
-       /* Will wake me after RCU finished. */
-       call_rcu(&rcu.head, wakeme_after_rcu);
-       /* Wait for it. */
-       wait_for_completion(&rcu.completion);
-}
-EXPORT_SYMBOL_GPL(synchronize_rcu);
-
-#endif /* #ifdef CONFIG_TREE_PREEMPT_RCU */
-
-/**
- * synchronize_sched - wait until an rcu-sched grace period has elapsed.
- *
- * Control will return to the caller some time after a full rcu-sched
- * grace period has elapsed, in other words after all currently executing
- * rcu-sched read-side critical sections have completed.   These read-side
- * critical sections are delimited by rcu_read_lock_sched() and
- * rcu_read_unlock_sched(), and may be nested.  Note that preempt_disable(),
- * local_irq_disable(), and so on may be used in place of
- * rcu_read_lock_sched().
- *
- * This means that all preempt_disable code sequences, including NMI and
- * hardware-interrupt handlers, in progress on entry will have completed
- * before this primitive returns.  However, this does not guarantee that
- * softirq handlers will have completed, since in some kernels, these
- * handlers can run in process context, and can block.
- *
- * This primitive provides the guarantees made by the (now removed)
- * synchronize_kernel() API.  In contrast, synchronize_rcu() only
- * guarantees that rcu_read_lock() sections will have completed.
- * In "classic RCU", these two guarantees happen to be one and
- * the same, but can differ in realtime RCU implementations.
- */
-void synchronize_sched(void)
-{
-       struct rcu_synchronize rcu;
-
-       if (rcu_blocking_is_gp())
-               return;
-
-       init_completion(&rcu.completion);
-       /* Will wake me after RCU finished. */
-       call_rcu_sched(&rcu.head, wakeme_after_rcu);
-       /* Wait for it. */
-       wait_for_completion(&rcu.completion);
-}
-EXPORT_SYMBOL_GPL(synchronize_sched);
-
-/**
- * synchronize_rcu_bh - wait until an rcu_bh grace period has elapsed.
- *
- * Control will return to the caller some time after a full rcu_bh grace
- * period has elapsed, in other words after all currently executing rcu_bh
- * read-side critical sections have completed.  RCU read-side critical
- * sections are delimited by rcu_read_lock_bh() and rcu_read_unlock_bh(),
- * and may be nested.
- */
-void synchronize_rcu_bh(void)
-{
-       struct rcu_synchronize rcu;
-
-       if (rcu_blocking_is_gp())
-               return;
-
-       init_completion(&rcu.completion);
-       /* Will wake me after RCU finished. */
-       call_rcu_bh(&rcu.head, wakeme_after_rcu);
-       /* Wait for it. */
-       wait_for_completion(&rcu.completion);
-}
-EXPORT_SYMBOL_GPL(synchronize_rcu_bh);
-
-static int __cpuinit rcu_barrier_cpu_hotplug(struct notifier_block *self,
-               unsigned long action, void *hcpu)
-{
-       return rcu_cpu_notify(self, action, hcpu);
-}
-
-void __init rcu_init(void)
-{
-       int i;
-
-       __rcu_init();
-       cpu_notifier(rcu_barrier_cpu_hotplug, 0);
-
-       /*
-        * We don't need protection against CPU-hotplug here because
-        * this is called early in boot, before either interrupts
-        * or the scheduler are operational.
-        */
-       for_each_online_cpu(i)
-               rcu_barrier_cpu_hotplug(NULL, CPU_UP_PREPARE, (void *)(long)i);
-}
-
-void rcu_scheduler_starting(void)
-{
-       WARN_ON(num_online_cpus() != 1);
-       WARN_ON(nr_context_switches() > 0);
-       rcu_scheduler_active = 1;
-}
diff --git a/kernel/rcutiny.c b/kernel/rcutiny.c
new file mode 100644 (file)
index 0000000..9f6d9ff
--- /dev/null
@@ -0,0 +1,282 @@
+/*
+ * Read-Copy Update mechanism for mutual exclusion, the Bloatwatch edition.
+ *
+ * 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.
+ *
+ * Copyright IBM Corporation, 2008
+ *
+ * Author: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
+ *
+ * For detailed explanation of Read-Copy Update mechanism see -
+ *             Documentation/RCU
+ */
+#include <linux/moduleparam.h>
+#include <linux/completion.h>
+#include <linux/interrupt.h>
+#include <linux/notifier.h>
+#include <linux/rcupdate.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/time.h>
+#include <linux/cpu.h>
+
+/* Global control variables for rcupdate callback mechanism. */
+struct rcu_ctrlblk {
+       struct rcu_head *rcucblist;     /* List of pending callbacks (CBs). */
+       struct rcu_head **donetail;     /* ->next pointer of last "done" CB. */
+       struct rcu_head **curtail;      /* ->next pointer of last CB. */
+};
+
+/* Definition for rcupdate control block. */
+static struct rcu_ctrlblk rcu_ctrlblk = {
+       .donetail       = &rcu_ctrlblk.rcucblist,
+       .curtail        = &rcu_ctrlblk.rcucblist,
+};
+
+static struct rcu_ctrlblk rcu_bh_ctrlblk = {
+       .donetail       = &rcu_bh_ctrlblk.rcucblist,
+       .curtail        = &rcu_bh_ctrlblk.rcucblist,
+};
+
+#ifdef CONFIG_NO_HZ
+
+static long rcu_dynticks_nesting = 1;
+
+/*
+ * Enter dynticks-idle mode, which is an extended quiescent state
+ * if we have fully entered that mode (i.e., if the new value of
+ * dynticks_nesting is zero).
+ */
+void rcu_enter_nohz(void)
+{
+       if (--rcu_dynticks_nesting == 0)
+               rcu_sched_qs(0); /* implies rcu_bh_qsctr_inc(0) */
+}
+
+/*
+ * Exit dynticks-idle mode, so that we are no longer in an extended
+ * quiescent state.
+ */
+void rcu_exit_nohz(void)
+{
+       rcu_dynticks_nesting++;
+}
+
+#endif /* #ifdef CONFIG_NO_HZ */
+
+/*
+ * Helper function for rcu_qsctr_inc() and rcu_bh_qsctr_inc().
+ * Also disable irqs to avoid confusion due to interrupt handlers
+ * invoking call_rcu().
+ */
+static int rcu_qsctr_help(struct rcu_ctrlblk *rcp)
+{
+       unsigned long flags;
+
+       local_irq_save(flags);
+       if (rcp->rcucblist != NULL &&
+           rcp->donetail != rcp->curtail) {
+               rcp->donetail = rcp->curtail;
+               local_irq_restore(flags);
+               return 1;
+       }
+       local_irq_restore(flags);
+
+       return 0;
+}
+
+/*
+ * Record an rcu quiescent state.  And an rcu_bh quiescent state while we
+ * are at it, given that any rcu quiescent state is also an rcu_bh
+ * quiescent state.  Use "+" instead of "||" to defeat short circuiting.
+ */
+void rcu_sched_qs(int cpu)
+{
+       if (rcu_qsctr_help(&rcu_ctrlblk) + rcu_qsctr_help(&rcu_bh_ctrlblk))
+               raise_softirq(RCU_SOFTIRQ);
+}
+
+/*
+ * Record an rcu_bh quiescent state.
+ */
+void rcu_bh_qs(int cpu)
+{
+       if (rcu_qsctr_help(&rcu_bh_ctrlblk))
+               raise_softirq(RCU_SOFTIRQ);
+}
+
+/*
+ * Check to see if the scheduling-clock interrupt came from an extended
+ * quiescent state, and, if so, tell RCU about it.
+ */
+void rcu_check_callbacks(int cpu, int user)
+{
+       if (user ||
+           (idle_cpu(cpu) &&
+            !in_softirq() &&
+            hardirq_count() <= (1 << HARDIRQ_SHIFT)))
+               rcu_sched_qs(cpu);
+       else if (!in_softirq())
+               rcu_bh_qs(cpu);
+}
+
+/*
+ * Helper function for rcu_process_callbacks() that operates on the
+ * specified rcu_ctrlkblk structure.
+ */
+static void __rcu_process_callbacks(struct rcu_ctrlblk *rcp)
+{
+       struct rcu_head *next, *list;
+       unsigned long flags;
+
+       /* If no RCU callbacks ready to invoke, just return. */
+       if (&rcp->rcucblist == rcp->donetail)
+               return;
+
+       /* Move the ready-to-invoke callbacks to a local list. */
+       local_irq_save(flags);
+       list = rcp->rcucblist;
+       rcp->rcucblist = *rcp->donetail;
+       *rcp->donetail = NULL;
+       if (rcp->curtail == rcp->donetail)
+               rcp->curtail = &rcp->rcucblist;
+       rcp->donetail = &rcp->rcucblist;
+       local_irq_restore(flags);
+
+       /* Invoke the callbacks on the local list. */
+       while (list) {
+               next = list->next;
+               prefetch(next);
+               list->func(list);
+               list = next;
+       }
+}
+
+/*
+ * Invoke any callbacks whose grace period has completed.
+ */
+static void rcu_process_callbacks(struct softirq_action *unused)
+{
+       __rcu_process_callbacks(&rcu_ctrlblk);
+       __rcu_process_callbacks(&rcu_bh_ctrlblk);
+}
+
+/*
+ * Wait for a grace period to elapse.  But it is illegal to invoke
+ * synchronize_sched() from within an RCU read-side critical section.
+ * Therefore, any legal call to synchronize_sched() is a quiescent
+ * state, and so on a UP system, synchronize_sched() need do nothing.
+ * Ditto for synchronize_rcu_bh().  (But Lai Jiangshan points out the
+ * benefits of doing might_sleep() to reduce latency.)
+ *
+ * Cool, huh?  (Due to Josh Triplett.)
+ *
+ * But we want to make this a static inline later.
+ */
+void synchronize_sched(void)
+{
+       cond_resched();
+}
+EXPORT_SYMBOL_GPL(synchronize_sched);
+
+void synchronize_rcu_bh(void)
+{
+       synchronize_sched();
+}
+EXPORT_SYMBOL_GPL(synchronize_rcu_bh);
+
+/*
+ * Helper function for call_rcu() and call_rcu_bh().
+ */
+static void __call_rcu(struct rcu_head *head,
+                      void (*func)(struct rcu_head *rcu),
+                      struct rcu_ctrlblk *rcp)
+{
+       unsigned long flags;
+
+       head->func = func;
+       head->next = NULL;
+
+       local_irq_save(flags);
+       *rcp->curtail = head;
+       rcp->curtail = &head->next;
+       local_irq_restore(flags);
+}
+
+/*
+ * Post an RCU callback to be invoked after the end of an RCU grace
+ * period.  But since we have but one CPU, that would be after any
+ * quiescent state.
+ */
+void call_rcu(struct rcu_head *head, void (*func)(struct rcu_head *rcu))
+{
+       __call_rcu(head, func, &rcu_ctrlblk);
+}
+EXPORT_SYMBOL_GPL(call_rcu);
+
+/*
+ * Post an RCU bottom-half callback to be invoked after any subsequent
+ * quiescent state.
+ */
+void call_rcu_bh(struct rcu_head *head, void (*func)(struct rcu_head *rcu))
+{
+       __call_rcu(head, func, &rcu_bh_ctrlblk);
+}
+EXPORT_SYMBOL_GPL(call_rcu_bh);
+
+void rcu_barrier(void)
+{
+       struct rcu_synchronize rcu;
+
+       init_completion(&rcu.completion);
+       /* Will wake me after RCU finished. */
+       call_rcu(&rcu.head, wakeme_after_rcu);
+       /* Wait for it. */
+       wait_for_completion(&rcu.completion);
+}
+EXPORT_SYMBOL_GPL(rcu_barrier);
+
+void rcu_barrier_bh(void)
+{
+       struct rcu_synchronize rcu;
+
+       init_completion(&rcu.completion);
+       /* Will wake me after RCU finished. */
+       call_rcu_bh(&rcu.head, wakeme_after_rcu);
+       /* Wait for it. */
+       wait_for_completion(&rcu.completion);
+}
+EXPORT_SYMBOL_GPL(rcu_barrier_bh);
+
+void rcu_barrier_sched(void)
+{
+       struct rcu_synchronize rcu;
+
+       init_completion(&rcu.completion);
+       /* Will wake me after RCU finished. */
+       call_rcu_sched(&rcu.head, wakeme_after_rcu);
+       /* Wait for it. */
+       wait_for_completion(&rcu.completion);
+}
+EXPORT_SYMBOL_GPL(rcu_barrier_sched);
+
+void __init rcu_init(void)
+{
+       open_softirq(RCU_SOFTIRQ, rcu_process_callbacks);
+}
index 697c0a0229d47026c07434910d7dc231e2d1bb97..a621a67ef4e3bd5e4aa97522cdff8b443db15e32 100644 (file)
@@ -327,6 +327,11 @@ rcu_torture_cb(struct rcu_head *p)
                cur_ops->deferred_free(rp);
 }
 
+static int rcu_no_completed(void)
+{
+       return 0;
+}
+
 static void rcu_torture_deferred_free(struct rcu_torture *p)
 {
        call_rcu(&p->rtort_rcu, rcu_torture_cb);
@@ -388,6 +393,21 @@ static struct rcu_torture_ops rcu_sync_ops = {
        .name           = "rcu_sync"
 };
 
+static struct rcu_torture_ops rcu_expedited_ops = {
+       .init           = rcu_sync_torture_init,
+       .cleanup        = NULL,
+       .readlock       = rcu_torture_read_lock,
+       .read_delay     = rcu_read_delay,  /* just reuse rcu's version. */
+       .readunlock     = rcu_torture_read_unlock,
+       .completed      = rcu_no_completed,
+       .deferred_free  = rcu_sync_torture_deferred_free,
+       .sync           = synchronize_rcu_expedited,
+       .cb_barrier     = NULL,
+       .stats          = NULL,
+       .irq_capable    = 1,
+       .name           = "rcu_expedited"
+};
+
 /*
  * Definitions for rcu_bh torture testing.
  */
@@ -547,6 +567,25 @@ static struct rcu_torture_ops srcu_ops = {
        .name           = "srcu"
 };
 
+static void srcu_torture_synchronize_expedited(void)
+{
+       synchronize_srcu_expedited(&srcu_ctl);
+}
+
+static struct rcu_torture_ops srcu_expedited_ops = {
+       .init           = srcu_torture_init,
+       .cleanup        = srcu_torture_cleanup,
+       .readlock       = srcu_torture_read_lock,
+       .read_delay     = srcu_read_delay,
+       .readunlock     = srcu_torture_read_unlock,
+       .completed      = srcu_torture_completed,
+       .deferred_free  = rcu_sync_torture_deferred_free,
+       .sync           = srcu_torture_synchronize_expedited,
+       .cb_barrier     = NULL,
+       .stats          = srcu_torture_stats,
+       .name           = "srcu_expedited"
+};
+
 /*
  * Definitions for sched torture testing.
  */
@@ -562,11 +601,6 @@ static void sched_torture_read_unlock(int idx)
        preempt_enable();
 }
 
-static int sched_torture_completed(void)
-{
-       return 0;
-}
-
 static void rcu_sched_torture_deferred_free(struct rcu_torture *p)
 {
        call_rcu_sched(&p->rtort_rcu, rcu_torture_cb);
@@ -583,7 +617,7 @@ static struct rcu_torture_ops sched_ops = {
        .readlock       = sched_torture_read_lock,
        .read_delay     = rcu_read_delay,  /* just reuse rcu's version. */
        .readunlock     = sched_torture_read_unlock,
-       .completed      = sched_torture_completed,
+       .completed      = rcu_no_completed,
        .deferred_free  = rcu_sched_torture_deferred_free,
        .sync           = sched_torture_synchronize,
        .cb_barrier     = rcu_barrier_sched,
@@ -592,13 +626,13 @@ static struct rcu_torture_ops sched_ops = {
        .name           = "sched"
 };
 
-static struct rcu_torture_ops sched_ops_sync = {
+static struct rcu_torture_ops sched_sync_ops = {
        .init           = rcu_sync_torture_init,
        .cleanup        = NULL,
        .readlock       = sched_torture_read_lock,
        .read_delay     = rcu_read_delay,  /* just reuse rcu's version. */
        .readunlock     = sched_torture_read_unlock,
-       .completed      = sched_torture_completed,
+       .completed      = rcu_no_completed,
        .deferred_free  = rcu_sync_torture_deferred_free,
        .sync           = sched_torture_synchronize,
        .cb_barrier     = NULL,
@@ -612,7 +646,7 @@ static struct rcu_torture_ops sched_expedited_ops = {
        .readlock       = sched_torture_read_lock,
        .read_delay     = rcu_read_delay,  /* just reuse rcu's version. */
        .readunlock     = sched_torture_read_unlock,
-       .completed      = sched_torture_completed,
+       .completed      = rcu_no_completed,
        .deferred_free  = rcu_sync_torture_deferred_free,
        .sync           = synchronize_sched_expedited,
        .cb_barrier     = NULL,
@@ -1097,9 +1131,10 @@ rcu_torture_init(void)
        int cpu;
        int firsterr = 0;
        static struct rcu_torture_ops *torture_ops[] =
-               { &rcu_ops, &rcu_sync_ops, &rcu_bh_ops, &rcu_bh_sync_ops,
-                 &sched_expedited_ops,
-                 &srcu_ops, &sched_ops, &sched_ops_sync, };
+               { &rcu_ops, &rcu_sync_ops, &rcu_expedited_ops,
+                 &rcu_bh_ops, &rcu_bh_sync_ops,
+                 &srcu_ops, &srcu_expedited_ops,
+                 &sched_ops, &sched_sync_ops, &sched_expedited_ops, };
 
        mutex_lock(&fullstop_mutex);
 
@@ -1110,8 +1145,12 @@ rcu_torture_init(void)
                        break;
        }
        if (i == ARRAY_SIZE(torture_ops)) {
-               printk(KERN_ALERT "rcutorture: invalid torture type: \"%s\"\n",
+               printk(KERN_ALERT "rcu-torture: invalid torture type: \"%s\"\n",
                       torture_type);
+               printk(KERN_ALERT "rcu-torture types:");
+               for (i = 0; i < ARRAY_SIZE(torture_ops); i++)
+                       printk(KERN_ALERT " %s", torture_ops[i]->name);
+               printk(KERN_ALERT "\n");
                mutex_unlock(&fullstop_mutex);
                return -EINVAL;
        }
index f3077c0ab1813379ef4f225168280387fa89a917..53ae9598f798c61398578b39f6d5f4969601961f 100644 (file)
 #include <linux/cpu.h>
 #include <linux/mutex.h>
 #include <linux/time.h>
+#include <linux/kernel_stat.h>
 
 #include "rcutree.h"
 
 /* Data structures. */
 
+static struct lock_class_key rcu_node_class[NUM_RCU_LVLS];
+
 #define RCU_STATE_INITIALIZER(name) { \
        .level = { &name.node[0] }, \
        .levelcnt = { \
                NUM_RCU_LVL_0,  /* root of hierarchy. */ \
                NUM_RCU_LVL_1, \
                NUM_RCU_LVL_2, \
-               NUM_RCU_LVL_3, /* == MAX_RCU_LVLS */ \
+               NUM_RCU_LVL_3, \
+               NUM_RCU_LVL_4, /* == MAX_RCU_LVLS */ \
        }, \
        .signaled = RCU_GP_IDLE, \
        .gpnum = -300, \
@@ -77,6 +81,8 @@ DEFINE_PER_CPU(struct rcu_data, rcu_sched_data);
 struct rcu_state rcu_bh_state = RCU_STATE_INITIALIZER(rcu_bh_state);
 DEFINE_PER_CPU(struct rcu_data, rcu_bh_data);
 
+static int rcu_scheduler_active __read_mostly;
+
 
 /*
  * Return true if an RCU grace period is in progress.  The ACCESS_ONCE()s
@@ -98,7 +104,7 @@ void rcu_sched_qs(int cpu)
        struct rcu_data *rdp;
 
        rdp = &per_cpu(rcu_sched_data, cpu);
-       rdp->passed_quiesc_completed = rdp->completed;
+       rdp->passed_quiesc_completed = rdp->gpnum - 1;
        barrier();
        rdp->passed_quiesc = 1;
        rcu_preempt_note_context_switch(cpu);
@@ -109,7 +115,7 @@ void rcu_bh_qs(int cpu)
        struct rcu_data *rdp;
 
        rdp = &per_cpu(rcu_bh_data, cpu);
-       rdp->passed_quiesc_completed = rdp->completed;
+       rdp->passed_quiesc_completed = rdp->gpnum - 1;
        barrier();
        rdp->passed_quiesc = 1;
 }
@@ -335,27 +341,8 @@ void rcu_irq_exit(void)
                set_need_resched();
 }
 
-/*
- * Record the specified "completed" value, which is later used to validate
- * dynticks counter manipulations.  Specify "rsp->completed - 1" to
- * unconditionally invalidate any future dynticks manipulations (which is
- * useful at the beginning of a grace period).
- */
-static void dyntick_record_completed(struct rcu_state *rsp, long comp)
-{
-       rsp->dynticks_completed = comp;
-}
-
 #ifdef CONFIG_SMP
 
-/*
- * Recall the previously recorded value of the completion for dynticks.
- */
-static long dyntick_recall_completed(struct rcu_state *rsp)
-{
-       return rsp->dynticks_completed;
-}
-
 /*
  * Snapshot the specified CPU's dynticks counter so that we can later
  * credit them with an implicit quiescent state.  Return 1 if this CPU
@@ -419,24 +406,8 @@ static int rcu_implicit_dynticks_qs(struct rcu_data *rdp)
 
 #else /* #ifdef CONFIG_NO_HZ */
 
-static void dyntick_record_completed(struct rcu_state *rsp, long comp)
-{
-}
-
 #ifdef CONFIG_SMP
 
-/*
- * If there are no dynticks, then the only way that a CPU can passively
- * be in a quiescent state is to be offline.  Unlike dynticks idle, which
- * is a point in time during the prior (already finished) grace period,
- * an offline CPU is always in a quiescent state, and thus can be
- * unconditionally applied.  So just return the current value of completed.
- */
-static long dyntick_recall_completed(struct rcu_state *rsp)
-{
-       return rsp->completed;
-}
-
 static int dyntick_save_progress_counter(struct rcu_data *rdp)
 {
        return 0;
@@ -553,13 +524,33 @@ static void check_cpu_stall(struct rcu_state *rsp, struct rcu_data *rdp)
 /*
  * Update CPU-local rcu_data state to record the newly noticed grace period.
  * This is used both when we started the grace period and when we notice
- * that someone else started the grace period.
+ * that someone else started the grace period.  The caller must hold the
+ * ->lock of the leaf rcu_node structure corresponding to the current CPU,
+ *  and must have irqs disabled.
  */
+static void __note_new_gpnum(struct rcu_state *rsp, struct rcu_node *rnp, struct rcu_data *rdp)
+{
+       if (rdp->gpnum != rnp->gpnum) {
+               rdp->qs_pending = 1;
+               rdp->passed_quiesc = 0;
+               rdp->gpnum = rnp->gpnum;
+       }
+}
+
 static void note_new_gpnum(struct rcu_state *rsp, struct rcu_data *rdp)
 {
-       rdp->qs_pending = 1;
-       rdp->passed_quiesc = 0;
-       rdp->gpnum = rsp->gpnum;
+       unsigned long flags;
+       struct rcu_node *rnp;
+
+       local_irq_save(flags);
+       rnp = rdp->mynode;
+       if (rdp->gpnum == ACCESS_ONCE(rnp->gpnum) || /* outside lock. */
+           !spin_trylock(&rnp->lock)) { /* irqs already off, retry later. */
+               local_irq_restore(flags);
+               return;
+       }
+       __note_new_gpnum(rsp, rnp, rdp);
+       spin_unlock_irqrestore(&rnp->lock, flags);
 }
 
 /*
@@ -582,6 +573,79 @@ check_for_new_grace_period(struct rcu_state *rsp, struct rcu_data *rdp)
        return ret;
 }
 
+/*
+ * Advance this CPU's callbacks, but only if the current grace period
+ * has ended.  This may be called only from the CPU to whom the rdp
+ * belongs.  In addition, the corresponding leaf rcu_node structure's
+ * ->lock must be held by the caller, with irqs disabled.
+ */
+static void
+__rcu_process_gp_end(struct rcu_state *rsp, struct rcu_node *rnp, struct rcu_data *rdp)
+{
+       /* Did another grace period end? */
+       if (rdp->completed != rnp->completed) {
+
+               /* Advance callbacks.  No harm if list empty. */
+               rdp->nxttail[RCU_DONE_TAIL] = rdp->nxttail[RCU_WAIT_TAIL];
+               rdp->nxttail[RCU_WAIT_TAIL] = rdp->nxttail[RCU_NEXT_READY_TAIL];
+               rdp->nxttail[RCU_NEXT_READY_TAIL] = rdp->nxttail[RCU_NEXT_TAIL];
+
+               /* Remember that we saw this grace-period completion. */
+               rdp->completed = rnp->completed;
+       }
+}
+
+/*
+ * Advance this CPU's callbacks, but only if the current grace period
+ * has ended.  This may be called only from the CPU to whom the rdp
+ * belongs.
+ */
+static void
+rcu_process_gp_end(struct rcu_state *rsp, struct rcu_data *rdp)
+{
+       unsigned long flags;
+       struct rcu_node *rnp;
+
+       local_irq_save(flags);
+       rnp = rdp->mynode;
+       if (rdp->completed == ACCESS_ONCE(rnp->completed) || /* outside lock. */
+           !spin_trylock(&rnp->lock)) { /* irqs already off, retry later. */
+               local_irq_restore(flags);
+               return;
+       }
+       __rcu_process_gp_end(rsp, rnp, rdp);
+       spin_unlock_irqrestore(&rnp->lock, flags);
+}
+
+/*
+ * Do per-CPU grace-period initialization for running CPU.  The caller
+ * must hold the lock of the leaf rcu_node structure corresponding to
+ * this CPU.
+ */
+static void
+rcu_start_gp_per_cpu(struct rcu_state *rsp, struct rcu_node *rnp, struct rcu_data *rdp)
+{
+       /* Prior grace period ended, so advance callbacks for current CPU. */
+       __rcu_process_gp_end(rsp, rnp, rdp);
+
+       /*
+        * Because this CPU just now started the new grace period, we know
+        * that all of its callbacks will be covered by this upcoming grace
+        * period, even the ones that were registered arbitrarily recently.
+        * Therefore, advance all outstanding callbacks to RCU_WAIT_TAIL.
+        *
+        * Other CPUs cannot be sure exactly when the grace period started.
+        * Therefore, their recently registered callbacks must pass through
+        * an additional RCU_NEXT_READY stage, so that they will be handled
+        * by the next RCU grace period.
+        */
+       rdp->nxttail[RCU_NEXT_READY_TAIL] = rdp->nxttail[RCU_NEXT_TAIL];
+       rdp->nxttail[RCU_WAIT_TAIL] = rdp->nxttail[RCU_NEXT_TAIL];
+
+       /* Set state so that this CPU will detect the next quiescent state. */
+       __note_new_gpnum(rsp, rnp, rdp);
+}
+
 /*
  * Start a new RCU grace period if warranted, re-initializing the hierarchy
  * in preparation for detecting the next grace period.  The caller must hold
@@ -596,7 +660,23 @@ rcu_start_gp(struct rcu_state *rsp, unsigned long flags)
        struct rcu_node *rnp = rcu_get_root(rsp);
 
        if (!cpu_needs_another_gp(rsp, rdp)) {
-               spin_unlock_irqrestore(&rnp->lock, flags);
+               if (rnp->completed == rsp->completed) {
+                       spin_unlock_irqrestore(&rnp->lock, flags);
+                       return;
+               }
+               spin_unlock(&rnp->lock);         /* irqs remain disabled. */
+
+               /*
+                * Propagate new ->completed value to rcu_node structures
+                * so that other CPUs don't have to wait until the start
+                * of the next grace period to process their callbacks.
+                */
+               rcu_for_each_node_breadth_first(rsp, rnp) {
+                       spin_lock(&rnp->lock);   /* irqs already disabled. */
+                       rnp->completed = rsp->completed;
+                       spin_unlock(&rnp->lock); /* irqs remain disabled. */
+               }
+               local_irq_restore(flags);
                return;
        }
 
@@ -606,29 +686,15 @@ rcu_start_gp(struct rcu_state *rsp, unsigned long flags)
        rsp->signaled = RCU_GP_INIT; /* Hold off force_quiescent_state. */
        rsp->jiffies_force_qs = jiffies + RCU_JIFFIES_TILL_FORCE_QS;
        record_gp_stall_check_time(rsp);
-       dyntick_record_completed(rsp, rsp->completed - 1);
-       note_new_gpnum(rsp, rdp);
-
-       /*
-        * Because this CPU just now started the new grace period, we know
-        * that all of its callbacks will be covered by this upcoming grace
-        * period, even the ones that were registered arbitrarily recently.
-        * Therefore, advance all outstanding callbacks to RCU_WAIT_TAIL.
-        *
-        * Other CPUs cannot be sure exactly when the grace period started.
-        * Therefore, their recently registered callbacks must pass through
-        * an additional RCU_NEXT_READY stage, so that they will be handled
-        * by the next RCU grace period.
-        */
-       rdp->nxttail[RCU_NEXT_READY_TAIL] = rdp->nxttail[RCU_NEXT_TAIL];
-       rdp->nxttail[RCU_WAIT_TAIL] = rdp->nxttail[RCU_NEXT_TAIL];
 
        /* Special-case the common single-level case. */
        if (NUM_RCU_NODES == 1) {
                rcu_preempt_check_blocked_tasks(rnp);
                rnp->qsmask = rnp->qsmaskinit;
                rnp->gpnum = rsp->gpnum;
+               rnp->completed = rsp->completed;
                rsp->signaled = RCU_SIGNAL_INIT; /* force_quiescent_state OK. */
+               rcu_start_gp_per_cpu(rsp, rnp, rdp);
                spin_unlock_irqrestore(&rnp->lock, flags);
                return;
        }
@@ -661,6 +727,9 @@ rcu_start_gp(struct rcu_state *rsp, unsigned long flags)
                rcu_preempt_check_blocked_tasks(rnp);
                rnp->qsmask = rnp->qsmaskinit;
                rnp->gpnum = rsp->gpnum;
+               rnp->completed = rsp->completed;
+               if (rnp == rdp->mynode)
+                       rcu_start_gp_per_cpu(rsp, rnp, rdp);
                spin_unlock(&rnp->lock);        /* irqs remain disabled. */
        }
 
@@ -672,58 +741,32 @@ rcu_start_gp(struct rcu_state *rsp, unsigned long flags)
 }
 
 /*
- * Advance this CPU's callbacks, but only if the current grace period
- * has ended.  This may be called only from the CPU to whom the rdp
- * belongs.
+ * Report a full set of quiescent states to the specified rcu_state
+ * data structure.  This involves cleaning up after the prior grace
+ * period and letting rcu_start_gp() start up the next grace period
+ * if one is needed.  Note that the caller must hold rnp->lock, as
+ * required by rcu_start_gp(), which will release it.
  */
-static void
-rcu_process_gp_end(struct rcu_state *rsp, struct rcu_data *rdp)
-{
-       long completed_snap;
-       unsigned long flags;
-
-       local_irq_save(flags);
-       completed_snap = ACCESS_ONCE(rsp->completed);  /* outside of lock. */
-
-       /* Did another grace period end? */
-       if (rdp->completed != completed_snap) {
-
-               /* Advance callbacks.  No harm if list empty. */
-               rdp->nxttail[RCU_DONE_TAIL] = rdp->nxttail[RCU_WAIT_TAIL];
-               rdp->nxttail[RCU_WAIT_TAIL] = rdp->nxttail[RCU_NEXT_READY_TAIL];
-               rdp->nxttail[RCU_NEXT_READY_TAIL] = rdp->nxttail[RCU_NEXT_TAIL];
-
-               /* Remember that we saw this grace-period completion. */
-               rdp->completed = completed_snap;
-       }
-       local_irq_restore(flags);
-}
-
-/*
- * Clean up after the prior grace period and let rcu_start_gp() start up
- * the next grace period if one is needed.  Note that the caller must
- * hold rnp->lock, as required by rcu_start_gp(), which will release it.
- */
-static void cpu_quiet_msk_finish(struct rcu_state *rsp, unsigned long flags)
+static void rcu_report_qs_rsp(struct rcu_state *rsp, unsigned long flags)
        __releases(rcu_get_root(rsp)->lock)
 {
        WARN_ON_ONCE(!rcu_gp_in_progress(rsp));
        rsp->completed = rsp->gpnum;
        rsp->signaled = RCU_GP_IDLE;
-       rcu_process_gp_end(rsp, rsp->rda[smp_processor_id()]);
        rcu_start_gp(rsp, flags);  /* releases root node's rnp->lock. */
 }
 
 /*
- * Similar to cpu_quiet(), for which it is a helper function.  Allows
- * a group of CPUs to be quieted at one go, though all the CPUs in the
- * group must be represented by the same leaf rcu_node structure.
- * That structure's lock must be held upon entry, and it is released
- * before return.
+ * Similar to rcu_report_qs_rdp(), for which it is a helper function.
+ * Allows quiescent states for a group of CPUs to be reported at one go
+ * to the specified rcu_node structure, though all the CPUs in the group
+ * must be represented by the same rcu_node structure (which need not be
+ * a leaf rcu_node structure, though it often will be).  That structure's
+ * lock must be held upon entry, and it is released before return.
  */
 static void
-cpu_quiet_msk(unsigned long mask, struct rcu_state *rsp, struct rcu_node *rnp,
-             unsigned long flags)
+rcu_report_qs_rnp(unsigned long mask, struct rcu_state *rsp,
+                 struct rcu_node *rnp, unsigned long flags)
        __releases(rnp->lock)
 {
        struct rcu_node *rnp_c;
@@ -759,21 +802,23 @@ cpu_quiet_msk(unsigned long mask, struct rcu_state *rsp, struct rcu_node *rnp,
 
        /*
         * Get here if we are the last CPU to pass through a quiescent
-        * state for this grace period.  Invoke cpu_quiet_msk_finish()
+        * state for this grace period.  Invoke rcu_report_qs_rsp()
         * to clean up and start the next grace period if one is needed.
         */
-       cpu_quiet_msk_finish(rsp, flags); /* releases rnp->lock. */
+       rcu_report_qs_rsp(rsp, flags); /* releases rnp->lock. */
 }
 
 /*
- * Record a quiescent state for the specified CPU, which must either be
- * the current CPU.  The lastcomp argument is used to make sure we are
- * still in the grace period of interest.  We don't want to end the current
- * grace period based on quiescent states detected in an earlier grace
- * period!
+ * Record a quiescent state for the specified CPU to that CPU's rcu_data
+ * structure.  This must be either called from the specified CPU, or
+ * called when the specified CPU is known to be offline (and when it is
+ * also known that no other CPU is concurrently trying to help the offline
+ * CPU).  The lastcomp argument is used to make sure we are still in the
+ * grace period of interest.  We don't want to end the current grace period
+ * based on quiescent states detected in an earlier grace period!
  */
 static void
-cpu_quiet(int cpu, struct rcu_state *rsp, struct rcu_data *rdp, long lastcomp)
+rcu_report_qs_rdp(int cpu, struct rcu_state *rsp, struct rcu_data *rdp, long lastcomp)
 {
        unsigned long flags;
        unsigned long mask;
@@ -781,15 +826,15 @@ cpu_quiet(int cpu, struct rcu_state *rsp, struct rcu_data *rdp, long lastcomp)
 
        rnp = rdp->mynode;
        spin_lock_irqsave(&rnp->lock, flags);
-       if (lastcomp != ACCESS_ONCE(rsp->completed)) {
+       if (lastcomp != rnp->completed) {
 
                /*
                 * Someone beat us to it for this grace period, so leave.
                 * The race with GP start is resolved by the fact that we
                 * hold the leaf rcu_node lock, so that the per-CPU bits
                 * cannot yet be initialized -- so we would simply find our
-                * CPU's bit already cleared in cpu_quiet_msk() if this race
-                * occurred.
+                * CPU's bit already cleared in rcu_report_qs_rnp() if this
+                * race occurred.
                 */
                rdp->passed_quiesc = 0; /* try again later! */
                spin_unlock_irqrestore(&rnp->lock, flags);
@@ -807,7 +852,7 @@ cpu_quiet(int cpu, struct rcu_state *rsp, struct rcu_data *rdp, long lastcomp)
                 */
                rdp->nxttail[RCU_NEXT_READY_TAIL] = rdp->nxttail[RCU_NEXT_TAIL];
 
-               cpu_quiet_msk(mask, rsp, rnp, flags); /* releases rnp->lock */
+               rcu_report_qs_rnp(mask, rsp, rnp, flags); /* rlses rnp->lock */
        }
 }
 
@@ -838,8 +883,11 @@ rcu_check_quiescent_state(struct rcu_state *rsp, struct rcu_data *rdp)
        if (!rdp->passed_quiesc)
                return;
 
-       /* Tell RCU we are done (but cpu_quiet() will be the judge of that). */
-       cpu_quiet(rdp->cpu, rsp, rdp, rdp->passed_quiesc_completed);
+       /*
+        * Tell RCU we are done (but rcu_report_qs_rdp() will be the
+        * judge of that).
+        */
+       rcu_report_qs_rdp(rdp->cpu, rsp, rdp, rdp->passed_quiesc_completed);
 }
 
 #ifdef CONFIG_HOTPLUG_CPU
@@ -899,8 +947,8 @@ static void rcu_adopt_orphan_cbs(struct rcu_state *rsp)
 static void __rcu_offline_cpu(int cpu, struct rcu_state *rsp)
 {
        unsigned long flags;
-       long lastcomp;
        unsigned long mask;
+       int need_report = 0;
        struct rcu_data *rdp = rsp->rda[cpu];
        struct rcu_node *rnp;
 
@@ -914,30 +962,32 @@ static void __rcu_offline_cpu(int cpu, struct rcu_state *rsp)
                spin_lock(&rnp->lock);          /* irqs already disabled. */
                rnp->qsmaskinit &= ~mask;
                if (rnp->qsmaskinit != 0) {
-                       spin_unlock(&rnp->lock); /* irqs remain disabled. */
+                       if (rnp != rdp->mynode)
+                               spin_unlock(&rnp->lock); /* irqs remain disabled. */
                        break;
                }
-
-               /*
-                * If there was a task blocking the current grace period,
-                * and if all CPUs have checked in, we need to propagate
-                * the quiescent state up the rcu_node hierarchy.  But that
-                * is inconvenient at the moment due to deadlock issues if
-                * this should end the current grace period.  So set the
-                * offlined CPU's bit in ->qsmask in order to force the
-                * next force_quiescent_state() invocation to clean up this
-                * mess in a deadlock-free manner.
-                */
-               if (rcu_preempt_offline_tasks(rsp, rnp, rdp) && !rnp->qsmask)
-                       rnp->qsmask |= mask;
-
+               if (rnp == rdp->mynode)
+                       need_report = rcu_preempt_offline_tasks(rsp, rnp, rdp);
+               else
+                       spin_unlock(&rnp->lock); /* irqs remain disabled. */
                mask = rnp->grpmask;
-               spin_unlock(&rnp->lock);        /* irqs remain disabled. */
                rnp = rnp->parent;
        } while (rnp != NULL);
-       lastcomp = rsp->completed;
 
-       spin_unlock_irqrestore(&rsp->onofflock, flags);
+       /*
+        * We still hold the leaf rcu_node structure lock here, and
+        * irqs are still disabled.  The reason for this subterfuge is
+        * because invoking rcu_report_unblock_qs_rnp() with ->onofflock
+        * held leads to deadlock.
+        */
+       spin_unlock(&rsp->onofflock); /* irqs remain disabled. */
+       rnp = rdp->mynode;
+       if (need_report & RCU_OFL_TASKS_NORM_GP)
+               rcu_report_unblock_qs_rnp(rnp, flags);
+       else
+               spin_unlock_irqrestore(&rnp->lock, flags);
+       if (need_report & RCU_OFL_TASKS_EXP_GP)
+               rcu_report_exp_rnp(rsp, rnp);
 
        rcu_adopt_orphan_cbs(rsp);
 }
@@ -1109,7 +1159,7 @@ static int rcu_process_dyntick(struct rcu_state *rsp, long lastcomp,
        rcu_for_each_leaf_node(rsp, rnp) {
                mask = 0;
                spin_lock_irqsave(&rnp->lock, flags);
-               if (rsp->completed != lastcomp) {
+               if (rnp->completed != lastcomp) {
                        spin_unlock_irqrestore(&rnp->lock, flags);
                        return 1;
                }
@@ -1123,10 +1173,10 @@ static int rcu_process_dyntick(struct rcu_state *rsp, long lastcomp,
                        if ((rnp->qsmask & bit) != 0 && f(rsp->rda[cpu]))
                                mask |= bit;
                }
-               if (mask != 0 && rsp->completed == lastcomp) {
+               if (mask != 0 && rnp->completed == lastcomp) {
 
-                       /* cpu_quiet_msk() releases rnp->lock. */
-                       cpu_quiet_msk(mask, rsp, rnp, flags);
+                       /* rcu_report_qs_rnp() releases rnp->lock. */
+                       rcu_report_qs_rnp(mask, rsp, rnp, flags);
                        continue;
                }
                spin_unlock_irqrestore(&rnp->lock, flags);
@@ -1144,6 +1194,7 @@ static void force_quiescent_state(struct rcu_state *rsp, int relaxed)
        long lastcomp;
        struct rcu_node *rnp = rcu_get_root(rsp);
        u8 signaled;
+       u8 forcenow;
 
        if (!rcu_gp_in_progress(rsp))
                return;  /* No grace period in progress, nothing to force. */
@@ -1156,10 +1207,10 @@ static void force_quiescent_state(struct rcu_state *rsp, int relaxed)
                goto unlock_ret; /* no emergency and done recently. */
        rsp->n_force_qs++;
        spin_lock(&rnp->lock);
-       lastcomp = rsp->completed;
+       lastcomp = rsp->gpnum - 1;
        signaled = rsp->signaled;
        rsp->jiffies_force_qs = jiffies + RCU_JIFFIES_TILL_FORCE_QS;
-       if (lastcomp == rsp->gpnum) {
+       if(!rcu_gp_in_progress(rsp)) {
                rsp->n_force_qs_ngp++;
                spin_unlock(&rnp->lock);
                goto unlock_ret;  /* no GP in progress, time updated. */
@@ -1180,21 +1231,29 @@ static void force_quiescent_state(struct rcu_state *rsp, int relaxed)
                if (rcu_process_dyntick(rsp, lastcomp,
                                        dyntick_save_progress_counter))
                        goto unlock_ret;
+               /* fall into next case. */
+
+       case RCU_SAVE_COMPLETED:
 
                /* Update state, record completion counter. */
+               forcenow = 0;
                spin_lock(&rnp->lock);
-               if (lastcomp == rsp->completed &&
-                   rsp->signaled == RCU_SAVE_DYNTICK) {
+               if (lastcomp + 1 == rsp->gpnum &&
+                   lastcomp == rsp->completed &&
+                   rsp->signaled == signaled) {
                        rsp->signaled = RCU_FORCE_QS;
-                       dyntick_record_completed(rsp, lastcomp);
+                       rsp->completed_fqs = lastcomp;
+                       forcenow = signaled == RCU_SAVE_COMPLETED;
                }
                spin_unlock(&rnp->lock);
-               break;
+               if (!forcenow)
+                       break;
+               /* fall into next case. */
 
        case RCU_FORCE_QS:
 
                /* Check dyntick-idle state, send IPI to laggarts. */
-               if (rcu_process_dyntick(rsp, dyntick_recall_completed(rsp),
+               if (rcu_process_dyntick(rsp, rsp->completed_fqs,
                                        rcu_implicit_dynticks_qs))
                        goto unlock_ret;
 
@@ -1351,6 +1410,68 @@ void call_rcu_bh(struct rcu_head *head, void (*func)(struct rcu_head *rcu))
 }
 EXPORT_SYMBOL_GPL(call_rcu_bh);
 
+/**
+ * synchronize_sched - wait until an rcu-sched grace period has elapsed.
+ *
+ * Control will return to the caller some time after a full rcu-sched
+ * grace period has elapsed, in other words after all currently executing
+ * rcu-sched read-side critical sections have completed.   These read-side
+ * critical sections are delimited by rcu_read_lock_sched() and
+ * rcu_read_unlock_sched(), and may be nested.  Note that preempt_disable(),
+ * local_irq_disable(), and so on may be used in place of
+ * rcu_read_lock_sched().
+ *
+ * This means that all preempt_disable code sequences, including NMI and
+ * hardware-interrupt handlers, in progress on entry will have completed
+ * before this primitive returns.  However, this does not guarantee that
+ * softirq handlers will have completed, since in some kernels, these
+ * handlers can run in process context, and can block.
+ *
+ * This primitive provides the guarantees made by the (now removed)
+ * synchronize_kernel() API.  In contrast, synchronize_rcu() only
+ * guarantees that rcu_read_lock() sections will have completed.
+ * In "classic RCU", these two guarantees happen to be one and
+ * the same, but can differ in realtime RCU implementations.
+ */
+void synchronize_sched(void)
+{
+       struct rcu_synchronize rcu;
+
+       if (rcu_blocking_is_gp())
+               return;
+
+       init_completion(&rcu.completion);
+       /* Will wake me after RCU finished. */
+       call_rcu_sched(&rcu.head, wakeme_after_rcu);
+       /* Wait for it. */
+       wait_for_completion(&rcu.completion);
+}
+EXPORT_SYMBOL_GPL(synchronize_sched);
+
+/**
+ * synchronize_rcu_bh - wait until an rcu_bh grace period has elapsed.
+ *
+ * Control will return to the caller some time after a full rcu_bh grace
+ * period has elapsed, in other words after all currently executing rcu_bh
+ * read-side critical sections have completed.  RCU read-side critical
+ * sections are delimited by rcu_read_lock_bh() and rcu_read_unlock_bh(),
+ * and may be nested.
+ */
+void synchronize_rcu_bh(void)
+{
+       struct rcu_synchronize rcu;
+
+       if (rcu_blocking_is_gp())
+               return;
+
+       init_completion(&rcu.completion);
+       /* Will wake me after RCU finished. */
+       call_rcu_bh(&rcu.head, wakeme_after_rcu);
+       /* Wait for it. */
+       wait_for_completion(&rcu.completion);
+}
+EXPORT_SYMBOL_GPL(synchronize_rcu_bh);
+
 /*
  * Check to see if there is any immediate RCU-related work to be done
  * by the current CPU, for the specified type of RCU, returning 1 if so.
@@ -1360,6 +1481,8 @@ EXPORT_SYMBOL_GPL(call_rcu_bh);
  */
 static int __rcu_pending(struct rcu_state *rsp, struct rcu_data *rdp)
 {
+       struct rcu_node *rnp = rdp->mynode;
+
        rdp->n_rcu_pending++;
 
        /* Check for CPU stalls, if enabled. */
@@ -1384,13 +1507,13 @@ static int __rcu_pending(struct rcu_state *rsp, struct rcu_data *rdp)
        }
 
        /* Has another RCU grace period completed?  */
-       if (ACCESS_ONCE(rsp->completed) != rdp->completed) { /* outside lock */
+       if (ACCESS_ONCE(rnp->completed) != rdp->completed) { /* outside lock */
                rdp->n_rp_gp_completed++;
                return 1;
        }
 
        /* Has a new RCU grace period started? */
-       if (ACCESS_ONCE(rsp->gpnum) != rdp->gpnum) { /* outside lock */
+       if (ACCESS_ONCE(rnp->gpnum) != rdp->gpnum) { /* outside lock */
                rdp->n_rp_gp_started++;
                return 1;
        }
@@ -1433,6 +1556,21 @@ int rcu_needs_cpu(int cpu)
               rcu_preempt_needs_cpu(cpu);
 }
 
+/*
+ * This function is invoked towards the end of the scheduler's initialization
+ * process.  Before this is called, the idle task might contain
+ * RCU read-side critical sections (during which time, this idle
+ * task is booting the system).  After this function is called, the
+ * idle tasks are prohibited from containing RCU read-side critical
+ * sections.
+ */
+void rcu_scheduler_starting(void)
+{
+       WARN_ON(num_online_cpus() != 1);
+       WARN_ON(nr_context_switches() > 0);
+       rcu_scheduler_active = 1;
+}
+
 static DEFINE_PER_CPU(struct rcu_head, rcu_barrier_head) = {NULL};
 static atomic_t rcu_barrier_cpu_count;
 static DEFINE_MUTEX(rcu_barrier_mutex);
@@ -1544,21 +1682,16 @@ static void __cpuinit
 rcu_init_percpu_data(int cpu, struct rcu_state *rsp, int preemptable)
 {
        unsigned long flags;
-       long lastcomp;
        unsigned long mask;
        struct rcu_data *rdp = rsp->rda[cpu];
        struct rcu_node *rnp = rcu_get_root(rsp);
 
        /* Set up local state, ensuring consistent view of global state. */
        spin_lock_irqsave(&rnp->lock, flags);
-       lastcomp = rsp->completed;
-       rdp->completed = lastcomp;
-       rdp->gpnum = lastcomp;
        rdp->passed_quiesc = 0;  /* We could be racing with new GP, */
        rdp->qs_pending = 1;     /*  so set up to respond to current GP. */
        rdp->beenonline = 1;     /* We have now been online. */
        rdp->preemptable = preemptable;
-       rdp->passed_quiesc_completed = lastcomp - 1;
        rdp->qlen_last_fqs_check = 0;
        rdp->n_force_qs_snap = rsp->n_force_qs;
        rdp->blimit = blimit;
@@ -1580,6 +1713,11 @@ rcu_init_percpu_data(int cpu, struct rcu_state *rsp, int preemptable)
                spin_lock(&rnp->lock);  /* irqs already disabled. */
                rnp->qsmaskinit |= mask;
                mask = rnp->grpmask;
+               if (rnp == rdp->mynode) {
+                       rdp->gpnum = rnp->completed; /* if GP in progress... */
+                       rdp->completed = rnp->completed;
+                       rdp->passed_quiesc_completed = rnp->completed - 1;
+               }
                spin_unlock(&rnp->lock); /* irqs already disabled. */
                rnp = rnp->parent;
        } while (rnp != NULL && !(rnp->qsmaskinit & mask));
@@ -1597,8 +1735,8 @@ static void __cpuinit rcu_online_cpu(int cpu)
 /*
  * Handle CPU online/offline notification events.
  */
-int __cpuinit rcu_cpu_notify(struct notifier_block *self,
-                            unsigned long action, void *hcpu)
+static int __cpuinit rcu_cpu_notify(struct notifier_block *self,
+                                   unsigned long action, void *hcpu)
 {
        long cpu = (long)hcpu;
 
@@ -1685,8 +1823,8 @@ static void __init rcu_init_one(struct rcu_state *rsp)
                cpustride *= rsp->levelspread[i];
                rnp = rsp->level[i];
                for (j = 0; j < rsp->levelcnt[i]; j++, rnp++) {
-                       if (rnp != rcu_get_root(rsp))
-                               spin_lock_init(&rnp->lock);
+                       spin_lock_init(&rnp->lock);
+                       lockdep_set_class(&rnp->lock, &rcu_node_class[i]);
                        rnp->gpnum = 0;
                        rnp->qsmask = 0;
                        rnp->qsmaskinit = 0;
@@ -1707,9 +1845,10 @@ static void __init rcu_init_one(struct rcu_state *rsp)
                        rnp->level = i;
                        INIT_LIST_HEAD(&rnp->blocked_tasks[0]);
                        INIT_LIST_HEAD(&rnp->blocked_tasks[1]);
+                       INIT_LIST_HEAD(&rnp->blocked_tasks[2]);
+                       INIT_LIST_HEAD(&rnp->blocked_tasks[3]);
                }
        }
-       spin_lock_init(&rcu_get_root(rsp)->lock);
 }
 
 /*
@@ -1735,16 +1874,30 @@ do { \
        } \
 } while (0)
 
-void __init __rcu_init(void)
+void __init rcu_init(void)
 {
+       int i;
+
        rcu_bootup_announce();
 #ifdef CONFIG_RCU_CPU_STALL_DETECTOR
        printk(KERN_INFO "RCU-based detection of stalled CPUs is enabled.\n");
 #endif /* #ifdef CONFIG_RCU_CPU_STALL_DETECTOR */
+#if NUM_RCU_LVL_4 != 0
+       printk(KERN_INFO "Experimental four-level hierarchy is enabled.\n");
+#endif /* #if NUM_RCU_LVL_4 != 0 */
        RCU_INIT_FLAVOR(&rcu_sched_state, rcu_sched_data);
        RCU_INIT_FLAVOR(&rcu_bh_state, rcu_bh_data);
        __rcu_init_preempt();
        open_softirq(RCU_SOFTIRQ, rcu_process_callbacks);
+
+       /*
+        * We don't need protection against CPU-hotplug here because
+        * this is called early in boot, before either interrupts
+        * or the scheduler are operational.
+        */
+       cpu_notifier(rcu_cpu_notify, 0);
+       for_each_online_cpu(i)
+               rcu_cpu_notify(NULL, CPU_UP_PREPARE, (void *)(long)i);
 }
 
 #include "rcutree_plugin.h"
index 1899023b0962adec0968bb32a7bdfd5dbebc577e..d2a0046f63b297b41e4605b25ae178ee57883367 100644 (file)
  * In practice, this has not been tested, so there is probably some
  * bug somewhere.
  */
-#define MAX_RCU_LVLS 3
+#define MAX_RCU_LVLS 4
 #define RCU_FANOUT           (CONFIG_RCU_FANOUT)
 #define RCU_FANOUT_SQ        (RCU_FANOUT * RCU_FANOUT)
 #define RCU_FANOUT_CUBE              (RCU_FANOUT_SQ * RCU_FANOUT)
+#define RCU_FANOUT_FOURTH     (RCU_FANOUT_CUBE * RCU_FANOUT)
 
 #if NR_CPUS <= RCU_FANOUT
 #  define NUM_RCU_LVLS       1
 #  define NUM_RCU_LVL_1              (NR_CPUS)
 #  define NUM_RCU_LVL_2              0
 #  define NUM_RCU_LVL_3              0
+#  define NUM_RCU_LVL_4              0
 #elif NR_CPUS <= RCU_FANOUT_SQ
 #  define NUM_RCU_LVLS       2
 #  define NUM_RCU_LVL_0              1
 #  define NUM_RCU_LVL_1              DIV_ROUND_UP(NR_CPUS, RCU_FANOUT)
 #  define NUM_RCU_LVL_2              (NR_CPUS)
 #  define NUM_RCU_LVL_3              0
+#  define NUM_RCU_LVL_4              0
 #elif NR_CPUS <= RCU_FANOUT_CUBE
 #  define NUM_RCU_LVLS       3
 #  define NUM_RCU_LVL_0              1
 #  define NUM_RCU_LVL_1              DIV_ROUND_UP(NR_CPUS, RCU_FANOUT_SQ)
 #  define NUM_RCU_LVL_2              DIV_ROUND_UP(NR_CPUS, RCU_FANOUT)
 #  define NUM_RCU_LVL_3              NR_CPUS
+#  define NUM_RCU_LVL_4              0
+#elif NR_CPUS <= RCU_FANOUT_FOURTH
+#  define NUM_RCU_LVLS       4
+#  define NUM_RCU_LVL_0              1
+#  define NUM_RCU_LVL_1              DIV_ROUND_UP(NR_CPUS, RCU_FANOUT_CUBE)
+#  define NUM_RCU_LVL_2              DIV_ROUND_UP(NR_CPUS, RCU_FANOUT_SQ)
+#  define NUM_RCU_LVL_3              DIV_ROUND_UP(NR_CPUS, RCU_FANOUT)
+#  define NUM_RCU_LVL_4              NR_CPUS
 #else
 # error "CONFIG_RCU_FANOUT insufficient for NR_CPUS"
 #endif /* #if (NR_CPUS) <= RCU_FANOUT */
 
-#define RCU_SUM (NUM_RCU_LVL_0 + NUM_RCU_LVL_1 + NUM_RCU_LVL_2 + NUM_RCU_LVL_3)
+#define RCU_SUM (NUM_RCU_LVL_0 + NUM_RCU_LVL_1 + NUM_RCU_LVL_2 + NUM_RCU_LVL_3 + NUM_RCU_LVL_4)
 #define NUM_RCU_NODES (RCU_SUM - NR_CPUS)
 
 /*
@@ -84,14 +95,21 @@ struct rcu_node {
        long    gpnum;          /* Current grace period for this node. */
                                /*  This will either be equal to or one */
                                /*  behind the root rcu_node's gpnum. */
+       long    completed;      /* Last grace period completed for this node. */
+                               /*  This will either be equal to or one */
+                               /*  behind the root rcu_node's gpnum. */
        unsigned long qsmask;   /* CPUs or groups that need to switch in */
                                /*  order for current grace period to proceed.*/
                                /*  In leaf rcu_node, each bit corresponds to */
                                /*  an rcu_data structure, otherwise, each */
                                /*  bit corresponds to a child rcu_node */
                                /*  structure. */
+       unsigned long expmask;  /* Groups that have ->blocked_tasks[] */
+                               /*  elements that need to drain to allow the */
+                               /*  current expedited grace period to */
+                               /*  complete (only for TREE_PREEMPT_RCU). */
        unsigned long qsmaskinit;
-                               /* Per-GP initialization for qsmask. */
+                               /* Per-GP initial value for qsmask & expmask. */
        unsigned long grpmask;  /* Mask to apply to parent qsmask. */
                                /*  Only one bit will be set in this mask. */
        int     grplo;          /* lowest-numbered CPU or group here. */
@@ -99,7 +117,7 @@ struct rcu_node {
        u8      grpnum;         /* CPU/group number for next level up. */
        u8      level;          /* root is at level 0. */
        struct rcu_node *parent;
-       struct list_head blocked_tasks[2];
+       struct list_head blocked_tasks[4];
                                /* Tasks blocked in RCU read-side critsect. */
                                /*  Grace period number (->gpnum) x blocked */
                                /*  by tasks on the (x & 0x1) element of the */
@@ -114,6 +132,21 @@ struct rcu_node {
        for ((rnp) = &(rsp)->node[0]; \
             (rnp) < &(rsp)->node[NUM_RCU_NODES]; (rnp)++)
 
+/*
+ * Do a breadth-first scan of the non-leaf rcu_node structures for the
+ * specified rcu_state structure.  Note that if there is a singleton
+ * rcu_node tree with but one rcu_node structure, this loop is a no-op.
+ */
+#define rcu_for_each_nonleaf_node_breadth_first(rsp, rnp) \
+       for ((rnp) = &(rsp)->node[0]; \
+            (rnp) < (rsp)->level[NUM_RCU_LVLS - 1]; (rnp)++)
+
+/*
+ * Scan the leaves of the rcu_node hierarchy for the specified rcu_state
+ * structure.  Note that if there is a singleton rcu_node tree with but
+ * one rcu_node structure, this loop -will- visit the rcu_node structure.
+ * It is still a leaf node, even if it is also the root node.
+ */
 #define rcu_for_each_leaf_node(rsp, rnp) \
        for ((rnp) = (rsp)->level[NUM_RCU_LVLS - 1]; \
             (rnp) < &(rsp)->node[NUM_RCU_NODES]; (rnp)++)
@@ -204,11 +237,12 @@ struct rcu_data {
 #define RCU_GP_IDLE            0       /* No grace period in progress. */
 #define RCU_GP_INIT            1       /* Grace period being initialized. */
 #define RCU_SAVE_DYNTICK       2       /* Need to scan dyntick state. */
-#define RCU_FORCE_QS           3       /* Need to force quiescent state. */
+#define RCU_SAVE_COMPLETED     3       /* Need to save rsp->completed. */
+#define RCU_FORCE_QS           4       /* Need to force quiescent state. */
 #ifdef CONFIG_NO_HZ
 #define RCU_SIGNAL_INIT                RCU_SAVE_DYNTICK
 #else /* #ifdef CONFIG_NO_HZ */
-#define RCU_SIGNAL_INIT                RCU_FORCE_QS
+#define RCU_SIGNAL_INIT                RCU_SAVE_COMPLETED
 #endif /* #else #ifdef CONFIG_NO_HZ */
 
 #define RCU_JIFFIES_TILL_FORCE_QS       3      /* for rsp->jiffies_force_qs */
@@ -246,7 +280,7 @@ struct rcu_state {
        long    gpnum;                          /* Current gp number. */
        long    completed;                      /* # of last completed gp. */
 
-       /* End  of fields guarded by root rcu_node's lock. */
+       /* End of fields guarded by root rcu_node's lock. */
 
        spinlock_t onofflock;                   /* exclude on/offline and */
                                                /*  starting new GP.  Also */
@@ -260,6 +294,8 @@ struct rcu_state {
        long orphan_qlen;                       /* Number of orphaned cbs. */
        spinlock_t fqslock;                     /* Only one task forcing */
                                                /*  quiescent states. */
+       long    completed_fqs;                  /* Value of completed @ snap. */
+                                               /*  Protected by fqslock. */
        unsigned long jiffies_force_qs;         /* Time at which to invoke */
                                                /*  force_quiescent_state(). */
        unsigned long n_force_qs;               /* Number of calls to */
@@ -274,11 +310,15 @@ struct rcu_state {
        unsigned long jiffies_stall;            /* Time at which to check */
                                                /*  for CPU stalls. */
 #endif /* #ifdef CONFIG_RCU_CPU_STALL_DETECTOR */
-#ifdef CONFIG_NO_HZ
-       long dynticks_completed;                /* Value of completed @ snap. */
-#endif /* #ifdef CONFIG_NO_HZ */
 };
 
+/* Return values for rcu_preempt_offline_tasks(). */
+
+#define RCU_OFL_TASKS_NORM_GP  0x1             /* Tasks blocking normal */
+                                               /*  GP were moved to root. */
+#define RCU_OFL_TASKS_EXP_GP   0x2             /* Tasks blocking expedited */
+                                               /*  GP were moved to root. */
+
 #ifdef RCU_TREE_NONCORE
 
 /*
@@ -298,10 +338,14 @@ DECLARE_PER_CPU(struct rcu_data, rcu_preempt_data);
 #else /* #ifdef RCU_TREE_NONCORE */
 
 /* Forward declarations for rcutree_plugin.h */
-static inline void rcu_bootup_announce(void);
+static void rcu_bootup_announce(void);
 long rcu_batches_completed(void);
 static void rcu_preempt_note_context_switch(int cpu);
 static int rcu_preempted_readers(struct rcu_node *rnp);
+#ifdef CONFIG_HOTPLUG_CPU
+static void rcu_report_unblock_qs_rnp(struct rcu_node *rnp,
+                                     unsigned long flags);
+#endif /* #ifdef CONFIG_HOTPLUG_CPU */
 #ifdef CONFIG_RCU_CPU_STALL_DETECTOR
 static void rcu_print_task_stall(struct rcu_node *rnp);
 #endif /* #ifdef CONFIG_RCU_CPU_STALL_DETECTOR */
@@ -315,6 +359,9 @@ static void rcu_preempt_offline_cpu(int cpu);
 static void rcu_preempt_check_callbacks(int cpu);
 static void rcu_preempt_process_callbacks(void);
 void call_rcu(struct rcu_head *head, void (*func)(struct rcu_head *rcu));
+#if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_TREE_PREEMPT_RCU)
+static void rcu_report_exp_rnp(struct rcu_state *rsp, struct rcu_node *rnp);
+#endif /* #if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_TREE_PREEMPT_RCU) */
 static int rcu_preempt_pending(int cpu);
 static int rcu_preempt_needs_cpu(int cpu);
 static void __cpuinit rcu_preempt_init_percpu_data(int cpu);
index ef2a58c2b9d5f977665329a07ef2ceda61677b3b..37fbccdf41d58d4dda85cc1788d972b6602d79b2 100644 (file)
  *        Paul E. McKenney <paulmck@linux.vnet.ibm.com>
  */
 
+#include <linux/delay.h>
 
 #ifdef CONFIG_TREE_PREEMPT_RCU
 
 struct rcu_state rcu_preempt_state = RCU_STATE_INITIALIZER(rcu_preempt_state);
 DEFINE_PER_CPU(struct rcu_data, rcu_preempt_data);
 
+static int rcu_preempted_readers_exp(struct rcu_node *rnp);
+
 /*
  * Tell them what RCU they are running.
  */
-static inline void rcu_bootup_announce(void)
+static void __init rcu_bootup_announce(void)
 {
        printk(KERN_INFO
               "Experimental preemptable hierarchical RCU implementation.\n");
@@ -67,7 +70,7 @@ EXPORT_SYMBOL_GPL(rcu_batches_completed);
 static void rcu_preempt_qs(int cpu)
 {
        struct rcu_data *rdp = &per_cpu(rcu_preempt_data, cpu);
-       rdp->passed_quiesc_completed = rdp->completed;
+       rdp->passed_quiesc_completed = rdp->gpnum - 1;
        barrier();
        rdp->passed_quiesc = 1;
 }
@@ -157,14 +160,58 @@ EXPORT_SYMBOL_GPL(__rcu_read_lock);
  */
 static int rcu_preempted_readers(struct rcu_node *rnp)
 {
-       return !list_empty(&rnp->blocked_tasks[rnp->gpnum & 0x1]);
+       int phase = rnp->gpnum & 0x1;
+
+       return !list_empty(&rnp->blocked_tasks[phase]) ||
+              !list_empty(&rnp->blocked_tasks[phase + 2]);
+}
+
+/*
+ * Record a quiescent state for all tasks that were previously queued
+ * on the specified rcu_node structure and that were blocking the current
+ * RCU grace period.  The caller must hold the specified rnp->lock with
+ * irqs disabled, and this lock is released upon return, but irqs remain
+ * disabled.
+ */
+static void rcu_report_unblock_qs_rnp(struct rcu_node *rnp, unsigned long flags)
+       __releases(rnp->lock)
+{
+       unsigned long mask;
+       struct rcu_node *rnp_p;
+
+       if (rnp->qsmask != 0 || rcu_preempted_readers(rnp)) {
+               spin_unlock_irqrestore(&rnp->lock, flags);
+               return;  /* Still need more quiescent states! */
+       }
+
+       rnp_p = rnp->parent;
+       if (rnp_p == NULL) {
+               /*
+                * Either there is only one rcu_node in the tree,
+                * or tasks were kicked up to root rcu_node due to
+                * CPUs going offline.
+                */
+               rcu_report_qs_rsp(&rcu_preempt_state, flags);
+               return;
+       }
+
+       /* Report up the rest of the hierarchy. */
+       mask = rnp->grpmask;
+       spin_unlock(&rnp->lock);        /* irqs remain disabled. */
+       spin_lock(&rnp_p->lock);        /* irqs already disabled. */
+       rcu_report_qs_rnp(mask, &rcu_preempt_state, rnp_p, flags);
 }
 
+/*
+ * Handle special cases during rcu_read_unlock(), such as needing to
+ * notify RCU core processing or task having blocked during the RCU
+ * read-side critical section.
+ */
 static void rcu_read_unlock_special(struct task_struct *t)
 {
        int empty;
+       int empty_exp;
        unsigned long flags;
-       unsigned long mask;
        struct rcu_node *rnp;
        int special;
 
@@ -207,36 +254,30 @@ static void rcu_read_unlock_special(struct task_struct *t)
                        spin_unlock(&rnp->lock);  /* irqs remain disabled. */
                }
                empty = !rcu_preempted_readers(rnp);
+               empty_exp = !rcu_preempted_readers_exp(rnp);
+               smp_mb(); /* ensure expedited fastpath sees end of RCU c-s. */
                list_del_init(&t->rcu_node_entry);
                t->rcu_blocked_node = NULL;
 
                /*
                 * If this was the last task on the current list, and if
                 * we aren't waiting on any CPUs, report the quiescent state.
-                * Note that both cpu_quiet_msk_finish() and cpu_quiet_msk()
-                * drop rnp->lock and restore irq.
+                * Note that rcu_report_unblock_qs_rnp() releases rnp->lock.
                 */
-               if (!empty && rnp->qsmask == 0 &&
-                   !rcu_preempted_readers(rnp)) {
-                       struct rcu_node *rnp_p;
-
-                       if (rnp->parent == NULL) {
-                               /* Only one rcu_node in the tree. */
-                               cpu_quiet_msk_finish(&rcu_preempt_state, flags);
-                               return;
-                       }
-                       /* Report up the rest of the hierarchy. */
-                       mask = rnp->grpmask;
+               if (empty)
                        spin_unlock_irqrestore(&rnp->lock, flags);
-                       rnp_p = rnp->parent;
-                       spin_lock_irqsave(&rnp_p->lock, flags);
-                       WARN_ON_ONCE(rnp->qsmask);
-                       cpu_quiet_msk(mask, &rcu_preempt_state, rnp_p, flags);
-                       return;
-               }
-               spin_unlock(&rnp->lock);
+               else
+                       rcu_report_unblock_qs_rnp(rnp, flags);
+
+               /*
+                * If this was the last task on the expedited lists,
+                * then we need to report up the rcu_node hierarchy.
+                */
+               if (!empty_exp && !rcu_preempted_readers_exp(rnp))
+                       rcu_report_exp_rnp(&rcu_preempt_state, rnp);
+       } else {
+               local_irq_restore(flags);
        }
-       local_irq_restore(flags);
 }
 
 /*
@@ -303,6 +344,8 @@ static void rcu_preempt_check_blocked_tasks(struct rcu_node *rnp)
  * rcu_node.  The reason for not just moving them to the immediate
  * parent is to remove the need for rcu_read_unlock_special() to
  * make more than two attempts to acquire the target rcu_node's lock.
+ * Returns true if there were tasks blocking the current RCU grace
+ * period.
  *
  * Returns 1 if there was previously a task blocking the current grace
  * period on the specified rcu_node structure.
@@ -316,7 +359,7 @@ static int rcu_preempt_offline_tasks(struct rcu_state *rsp,
        int i;
        struct list_head *lp;
        struct list_head *lp_root;
-       int retval = rcu_preempted_readers(rnp);
+       int retval = 0;
        struct rcu_node *rnp_root = rcu_get_root(rsp);
        struct task_struct *tp;
 
@@ -326,7 +369,9 @@ static int rcu_preempt_offline_tasks(struct rcu_state *rsp,
        }
        WARN_ON_ONCE(rnp != rdp->mynode &&
                     (!list_empty(&rnp->blocked_tasks[0]) ||
-                     !list_empty(&rnp->blocked_tasks[1])));
+                     !list_empty(&rnp->blocked_tasks[1]) ||
+                     !list_empty(&rnp->blocked_tasks[2]) ||
+                     !list_empty(&rnp->blocked_tasks[3])));
 
        /*
         * Move tasks up to root rcu_node.  Rely on the fact that the
@@ -334,7 +379,11 @@ static int rcu_preempt_offline_tasks(struct rcu_state *rsp,
         * rcu_nodes in terms of gp_num value.  This fact allows us to
         * move the blocked_tasks[] array directly, element by element.
         */
-       for (i = 0; i < 2; i++) {
+       if (rcu_preempted_readers(rnp))
+               retval |= RCU_OFL_TASKS_NORM_GP;
+       if (rcu_preempted_readers_exp(rnp))
+               retval |= RCU_OFL_TASKS_EXP_GP;
+       for (i = 0; i < 4; i++) {
                lp = &rnp->blocked_tasks[i];
                lp_root = &rnp_root->blocked_tasks[i];
                while (!list_empty(lp)) {
@@ -346,7 +395,6 @@ static int rcu_preempt_offline_tasks(struct rcu_state *rsp,
                        spin_unlock(&rnp_root->lock); /* irqs remain disabled */
                }
        }
-
        return retval;
 }
 
@@ -398,14 +446,183 @@ void call_rcu(struct rcu_head *head, void (*func)(struct rcu_head *rcu))
 }
 EXPORT_SYMBOL_GPL(call_rcu);
 
+/**
+ * synchronize_rcu - wait until a grace period has elapsed.
+ *
+ * Control will return to the caller some time after a full grace
+ * period has elapsed, in other words after all currently executing RCU
+ * read-side critical sections have completed.  RCU read-side critical
+ * sections are delimited by rcu_read_lock() and rcu_read_unlock(),
+ * and may be nested.
+ */
+void synchronize_rcu(void)
+{
+       struct rcu_synchronize rcu;
+
+       if (!rcu_scheduler_active)
+               return;
+
+       init_completion(&rcu.completion);
+       /* Will wake me after RCU finished. */
+       call_rcu(&rcu.head, wakeme_after_rcu);
+       /* Wait for it. */
+       wait_for_completion(&rcu.completion);
+}
+EXPORT_SYMBOL_GPL(synchronize_rcu);
+
+static DECLARE_WAIT_QUEUE_HEAD(sync_rcu_preempt_exp_wq);
+static long sync_rcu_preempt_exp_count;
+static DEFINE_MUTEX(sync_rcu_preempt_exp_mutex);
+
 /*
- * Wait for an rcu-preempt grace period.  We are supposed to expedite the
- * grace period, but this is the crude slow compatability hack, so just
- * invoke synchronize_rcu().
+ * Return non-zero if there are any tasks in RCU read-side critical
+ * sections blocking the current preemptible-RCU expedited grace period.
+ * If there is no preemptible-RCU expedited grace period currently in
+ * progress, returns zero unconditionally.
+ */
+static int rcu_preempted_readers_exp(struct rcu_node *rnp)
+{
+       return !list_empty(&rnp->blocked_tasks[2]) ||
+              !list_empty(&rnp->blocked_tasks[3]);
+}
+
+/*
+ * return non-zero if there is no RCU expedited grace period in progress
+ * for the specified rcu_node structure, in other words, if all CPUs and
+ * tasks covered by the specified rcu_node structure have done their bit
+ * for the current expedited grace period.  Works only for preemptible
+ * RCU -- other RCU implementation use other means.
+ *
+ * Caller must hold sync_rcu_preempt_exp_mutex.
+ */
+static int sync_rcu_preempt_exp_done(struct rcu_node *rnp)
+{
+       return !rcu_preempted_readers_exp(rnp) &&
+              ACCESS_ONCE(rnp->expmask) == 0;
+}
+
+/*
+ * Report the exit from RCU read-side critical section for the last task
+ * that queued itself during or before the current expedited preemptible-RCU
+ * grace period.  This event is reported either to the rcu_node structure on
+ * which the task was queued or to one of that rcu_node structure's ancestors,
+ * recursively up the tree.  (Calm down, calm down, we do the recursion
+ * iteratively!)
+ *
+ * Caller must hold sync_rcu_preempt_exp_mutex.
+ */
+static void rcu_report_exp_rnp(struct rcu_state *rsp, struct rcu_node *rnp)
+{
+       unsigned long flags;
+       unsigned long mask;
+
+       spin_lock_irqsave(&rnp->lock, flags);
+       for (;;) {
+               if (!sync_rcu_preempt_exp_done(rnp))
+                       break;
+               if (rnp->parent == NULL) {
+                       wake_up(&sync_rcu_preempt_exp_wq);
+                       break;
+               }
+               mask = rnp->grpmask;
+               spin_unlock(&rnp->lock); /* irqs remain disabled */
+               rnp = rnp->parent;
+               spin_lock(&rnp->lock); /* irqs already disabled */
+               rnp->expmask &= ~mask;
+       }
+       spin_unlock_irqrestore(&rnp->lock, flags);
+}
+
+/*
+ * Snapshot the tasks blocking the newly started preemptible-RCU expedited
+ * grace period for the specified rcu_node structure.  If there are no such
+ * tasks, report it up the rcu_node hierarchy.
+ *
+ * Caller must hold sync_rcu_preempt_exp_mutex and rsp->onofflock.
+ */
+static void
+sync_rcu_preempt_exp_init(struct rcu_state *rsp, struct rcu_node *rnp)
+{
+       int must_wait;
+
+       spin_lock(&rnp->lock); /* irqs already disabled */
+       list_splice_init(&rnp->blocked_tasks[0], &rnp->blocked_tasks[2]);
+       list_splice_init(&rnp->blocked_tasks[1], &rnp->blocked_tasks[3]);
+       must_wait = rcu_preempted_readers_exp(rnp);
+       spin_unlock(&rnp->lock); /* irqs remain disabled */
+       if (!must_wait)
+               rcu_report_exp_rnp(rsp, rnp);
+}
+
+/*
+ * Wait for an rcu-preempt grace period, but expedite it.  The basic idea
+ * is to invoke synchronize_sched_expedited() to push all the tasks to
+ * the ->blocked_tasks[] lists, move all entries from the first set of
+ * ->blocked_tasks[] lists to the second set, and finally wait for this
+ * second set to drain.
  */
 void synchronize_rcu_expedited(void)
 {
-       synchronize_rcu();
+       unsigned long flags;
+       struct rcu_node *rnp;
+       struct rcu_state *rsp = &rcu_preempt_state;
+       long snap;
+       int trycount = 0;
+
+       smp_mb(); /* Caller's modifications seen first by other CPUs. */
+       snap = ACCESS_ONCE(sync_rcu_preempt_exp_count) + 1;
+       smp_mb(); /* Above access cannot bleed into critical section. */
+
+       /*
+        * Acquire lock, falling back to synchronize_rcu() if too many
+        * lock-acquisition failures.  Of course, if someone does the
+        * expedited grace period for us, just leave.
+        */
+       while (!mutex_trylock(&sync_rcu_preempt_exp_mutex)) {
+               if (trycount++ < 10)
+                       udelay(trycount * num_online_cpus());
+               else {
+                       synchronize_rcu();
+                       return;
+               }
+               if ((ACCESS_ONCE(sync_rcu_preempt_exp_count) - snap) > 0)
+                       goto mb_ret; /* Others did our work for us. */
+       }
+       if ((ACCESS_ONCE(sync_rcu_preempt_exp_count) - snap) > 0)
+               goto unlock_mb_ret; /* Others did our work for us. */
+
+       /* force all RCU readers onto blocked_tasks[]. */
+       synchronize_sched_expedited();
+
+       spin_lock_irqsave(&rsp->onofflock, flags);
+
+       /* Initialize ->expmask for all non-leaf rcu_node structures. */
+       rcu_for_each_nonleaf_node_breadth_first(rsp, rnp) {
+               spin_lock(&rnp->lock); /* irqs already disabled. */
+               rnp->expmask = rnp->qsmaskinit;
+               spin_unlock(&rnp->lock); /* irqs remain disabled. */
+       }
+
+       /* Snapshot current state of ->blocked_tasks[] lists. */
+       rcu_for_each_leaf_node(rsp, rnp)
+               sync_rcu_preempt_exp_init(rsp, rnp);
+       if (NUM_RCU_NODES > 1)
+               sync_rcu_preempt_exp_init(rsp, rcu_get_root(rsp));
+
+       spin_unlock_irqrestore(&rsp->onofflock, flags);
+
+       /* Wait for snapshotted ->blocked_tasks[] lists to drain. */
+       rnp = rcu_get_root(rsp);
+       wait_event(sync_rcu_preempt_exp_wq,
+                  sync_rcu_preempt_exp_done(rnp));
+
+       /* Clean up and exit. */
+       smp_mb(); /* ensure expedited GP seen before counter increment. */
+       ACCESS_ONCE(sync_rcu_preempt_exp_count)++;
+unlock_mb_ret:
+       mutex_unlock(&sync_rcu_preempt_exp_mutex);
+mb_ret:
+       smp_mb(); /* ensure subsequent action seen after grace period. */
 }
 EXPORT_SYMBOL_GPL(synchronize_rcu_expedited);
 
@@ -481,7 +698,7 @@ void exit_rcu(void)
 /*
  * Tell them what RCU they are running.
  */
-static inline void rcu_bootup_announce(void)
+static void __init rcu_bootup_announce(void)
 {
        printk(KERN_INFO "Hierarchical RCU implementation.\n");
 }
@@ -512,6 +729,16 @@ static int rcu_preempted_readers(struct rcu_node *rnp)
        return 0;
 }
 
+#ifdef CONFIG_HOTPLUG_CPU
+
+/* Because preemptible RCU does not exist, no quieting of tasks. */
+static void rcu_report_unblock_qs_rnp(struct rcu_node *rnp, unsigned long flags)
+{
+       spin_unlock_irqrestore(&rnp->lock, flags);
+}
+
+#endif /* #ifdef CONFIG_HOTPLUG_CPU */
+
 #ifdef CONFIG_RCU_CPU_STALL_DETECTOR
 
 /*
@@ -594,6 +821,20 @@ void synchronize_rcu_expedited(void)
 }
 EXPORT_SYMBOL_GPL(synchronize_rcu_expedited);
 
+#ifdef CONFIG_HOTPLUG_CPU
+
+/*
+ * Because preemptable RCU does not exist, there is never any need to
+ * report on tasks preempted in RCU read-side critical sections during
+ * expedited RCU grace periods.
+ */
+static void rcu_report_exp_rnp(struct rcu_state *rsp, struct rcu_node *rnp)
+{
+       return;
+}
+
+#endif /* #ifdef CONFIG_HOTPLUG_CPU */
+
 /*
  * Because preemptable RCU does not exist, it never has any work to do.
  */
index 4b31c779e62e6bff126c270c1e8dae3578fd6932..9d2c88423b31abfd6a0a350659a9f3ddf98cbd0e 100644 (file)
@@ -155,12 +155,15 @@ static const struct file_operations rcudata_csv_fops = {
 
 static void print_one_rcu_state(struct seq_file *m, struct rcu_state *rsp)
 {
+       long gpnum;
        int level = 0;
+       int phase;
        struct rcu_node *rnp;
 
+       gpnum = rsp->gpnum;
        seq_printf(m, "c=%ld g=%ld s=%d jfq=%ld j=%x "
                      "nfqs=%lu/nfqsng=%lu(%lu) fqlh=%lu oqlen=%ld\n",
-                  rsp->completed, rsp->gpnum, rsp->signaled,
+                  rsp->completed, gpnum, rsp->signaled,
                   (long)(rsp->jiffies_force_qs - jiffies),
                   (int)(jiffies & 0xffff),
                   rsp->n_force_qs, rsp->n_force_qs_ngp,
@@ -171,8 +174,13 @@ static void print_one_rcu_state(struct seq_file *m, struct rcu_state *rsp)
                        seq_puts(m, "\n");
                        level = rnp->level;
                }
-               seq_printf(m, "%lx/%lx %d:%d ^%d    ",
+               phase = gpnum & 0x1;
+               seq_printf(m, "%lx/%lx %c%c>%c%c %d:%d ^%d    ",
                           rnp->qsmask, rnp->qsmaskinit,
+                          "T."[list_empty(&rnp->blocked_tasks[phase])],
+                          "E."[list_empty(&rnp->blocked_tasks[phase + 2])],
+                          "T."[list_empty(&rnp->blocked_tasks[!phase])],
+                          "E."[list_empty(&rnp->blocked_tasks[!phase + 2])],
                           rnp->grplo, rnp->grphi, rnp->grpnum);
        }
        seq_puts(m, "\n");
index 3c11ae0a948d9337732ce9d0e37076d84c324ff6..6ae2739b8f193b590155683665b8943a882f6493 100644 (file)
@@ -5481,7 +5481,7 @@ need_resched_nonpreemptible:
 }
 EXPORT_SYMBOL(schedule);
 
-#ifdef CONFIG_SMP
+#ifdef CONFIG_MUTEX_SPIN_ON_OWNER
 /*
  * Look out! "owner" is an entirely speculative pointer
  * access and not reliable.
@@ -10901,6 +10901,7 @@ void synchronize_sched_expedited(void)
                spin_unlock_irqrestore(&rq->lock, flags);
        }
        rcu_expedited_state = RCU_EXPEDITED_STATE_IDLE;
+       synchronize_sched_expedited_count++;
        mutex_unlock(&rcu_sched_expedited_mutex);
        put_online_cpus();
        if (need_full_sync)
index 93e72e5feae63bc0e9b6bb9e6da3ba3d57b8fcb4..6b982f2cf524d82e6b72f276f7d9010df9007e47 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/ptrace.h>
 #include <linux/signal.h>
 #include <linux/signalfd.h>
+#include <linux/ratelimit.h>
 #include <linux/tracehook.h>
 #include <linux/capability.h>
 #include <linux/freezer.h>
@@ -42,6 +43,8 @@
 
 static struct kmem_cache *sigqueue_cachep;
 
+int print_fatal_signals __read_mostly;
+
 static void __user *sig_handler(struct task_struct *t, int sig)
 {
        return t->sighand->action[sig - 1].sa.sa_handler;
@@ -160,7 +163,7 @@ int next_signal(struct sigpending *pending, sigset_t *mask)
 {
        unsigned long i, *s, *m, x;
        int sig = 0;
-       
+
        s = pending->signal.sig;
        m = mask->sig;
        switch (_NSIG_WORDS) {
@@ -185,17 +188,31 @@ int next_signal(struct sigpending *pending, sigset_t *mask)
                        sig = ffz(~x) + 1;
                break;
        }
-       
+
        return sig;
 }
 
+static inline void print_dropped_signal(int sig)
+{
+       static DEFINE_RATELIMIT_STATE(ratelimit_state, 5 * HZ, 10);
+
+       if (!print_fatal_signals)
+               return;
+
+       if (!__ratelimit(&ratelimit_state))
+               return;
+
+       printk(KERN_INFO "%s/%d: reached RLIMIT_SIGPENDING, dropped signal %d\n",
+                               current->comm, current->pid, sig);
+}
+
 /*
  * allocate a new signal queue record
  * - this may be called without locks if and only if t == current, otherwise an
  *   appopriate lock must be held to stop the target task from exiting
  */
-static struct sigqueue *__sigqueue_alloc(struct task_struct *t, gfp_t flags,
-                                        int override_rlimit)
+static struct sigqueue *
+__sigqueue_alloc(int sig, struct task_struct *t, gfp_t flags, int override_rlimit)
 {
        struct sigqueue *q = NULL;
        struct user_struct *user;
@@ -208,10 +225,15 @@ static struct sigqueue *__sigqueue_alloc(struct task_struct *t, gfp_t flags,
         */
        user = get_uid(__task_cred(t)->user);
        atomic_inc(&user->sigpending);
+
        if (override_rlimit ||
            atomic_read(&user->sigpending) <=
-                       t->signal->rlim[RLIMIT_SIGPENDING].rlim_cur)
+                       t->signal->rlim[RLIMIT_SIGPENDING].rlim_cur) {
                q = kmem_cache_alloc(sigqueue_cachep, flags);
+       } else {
+               print_dropped_signal(sig);
+       }
+
        if (unlikely(q == NULL)) {
                atomic_dec(&user->sigpending);
                free_uid(user);
@@ -870,7 +892,7 @@ static int __send_signal(int sig, struct siginfo *info, struct task_struct *t,
        else
                override_rlimit = 0;
 
-       q = __sigqueue_alloc(t, GFP_ATOMIC | __GFP_NOTRACK_FALSE_POSITIVE,
+       q = __sigqueue_alloc(sig, t, GFP_ATOMIC | __GFP_NOTRACK_FALSE_POSITIVE,
                override_rlimit);
        if (q) {
                list_add_tail(&q->list, &pending->list);
@@ -935,8 +957,6 @@ static int send_signal(int sig, struct siginfo *info, struct task_struct *t,
        return __send_signal(sig, info, t, group, from_ancestor_ns);
 }
 
-int print_fatal_signals;
-
 static void print_fatal_signal(struct pt_regs *regs, int signr)
 {
        printk("%s/%d: potentially unexpected fatal signal %d.\n",
@@ -1303,19 +1323,19 @@ EXPORT_SYMBOL(kill_pid);
  * These functions support sending signals using preallocated sigqueue
  * structures.  This is needed "because realtime applications cannot
  * afford to lose notifications of asynchronous events, like timer
- * expirations or I/O completions".  In the case of Posix Timers 
+ * expirations or I/O completions".  In the case of Posix Timers
  * we allocate the sigqueue structure from the timer_create.  If this
  * allocation fails we are able to report the failure to the application
  * with an EAGAIN error.
  */
 struct sigqueue *sigqueue_alloc(void)
 {
-       struct sigqueue *q;
+       struct sigqueue *q = __sigqueue_alloc(-1, current, GFP_KERNEL, 0);
 
-       if ((q = __sigqueue_alloc(current, GFP_KERNEL, 0)))
+       if (q)
                q->flags |= SIGQUEUE_PREALLOC;
-       return(q);
+
+       return q;
 }
 
 void sigqueue_free(struct sigqueue *q)
diff --git a/kernel/slow-work-debugfs.c b/kernel/slow-work-debugfs.c
new file mode 100644 (file)
index 0000000..e45c436
--- /dev/null
@@ -0,0 +1,227 @@
+/* Slow work debugging
+ *
+ * Copyright (C) 2009 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/slow-work.h>
+#include <linux/fs.h>
+#include <linux/time.h>
+#include <linux/seq_file.h>
+#include "slow-work.h"
+
+#define ITERATOR_SHIFT         (BITS_PER_LONG - 4)
+#define ITERATOR_SELECTOR      (0xfUL << ITERATOR_SHIFT)
+#define ITERATOR_COUNTER       (~ITERATOR_SELECTOR)
+
+void slow_work_new_thread_desc(struct slow_work *work, struct seq_file *m)
+{
+       seq_puts(m, "Slow-work: New thread");
+}
+
+/*
+ * Render the time mark field on a work item into a 5-char time with units plus
+ * a space
+ */
+static void slow_work_print_mark(struct seq_file *m, struct slow_work *work)
+{
+       struct timespec now, diff;
+
+       now = CURRENT_TIME;
+       diff = timespec_sub(now, work->mark);
+
+       if (diff.tv_sec < 0)
+               seq_puts(m, "  -ve ");
+       else if (diff.tv_sec == 0 && diff.tv_nsec < 1000)
+               seq_printf(m, "%3luns ", diff.tv_nsec);
+       else if (diff.tv_sec == 0 && diff.tv_nsec < 1000000)
+               seq_printf(m, "%3luus ", diff.tv_nsec / 1000);
+       else if (diff.tv_sec == 0 && diff.tv_nsec < 1000000000)
+               seq_printf(m, "%3lums ", diff.tv_nsec / 1000000);
+       else if (diff.tv_sec <= 1)
+               seq_puts(m, "   1s ");
+       else if (diff.tv_sec < 60)
+               seq_printf(m, "%4lus ", diff.tv_sec);
+       else if (diff.tv_sec < 60 * 60)
+               seq_printf(m, "%4lum ", diff.tv_sec / 60);
+       else if (diff.tv_sec < 60 * 60 * 24)
+               seq_printf(m, "%4luh ", diff.tv_sec / 3600);
+       else
+               seq_puts(m, "exces ");
+}
+
+/*
+ * Describe a slow work item for debugfs
+ */
+static int slow_work_runqueue_show(struct seq_file *m, void *v)
+{
+       struct slow_work *work;
+       struct list_head *p = v;
+       unsigned long id;
+
+       switch ((unsigned long) v) {
+       case 1:
+               seq_puts(m, "THR PID   ITEM ADDR        FL MARK  DESC\n");
+               return 0;
+       case 2:
+               seq_puts(m, "=== ===== ================ == ===== ==========\n");
+               return 0;
+
+       case 3 ... 3 + SLOW_WORK_THREAD_LIMIT - 1:
+               id = (unsigned long) v - 3;
+
+               read_lock(&slow_work_execs_lock);
+               work = slow_work_execs[id];
+               if (work) {
+                       smp_read_barrier_depends();
+
+                       seq_printf(m, "%3lu %5d %16p %2lx ",
+                                  id, slow_work_pids[id], work, work->flags);
+                       slow_work_print_mark(m, work);
+
+                       if (work->ops->desc)
+                               work->ops->desc(work, m);
+                       seq_putc(m, '\n');
+               }
+               read_unlock(&slow_work_execs_lock);
+               return 0;
+
+       default:
+               work = list_entry(p, struct slow_work, link);
+               seq_printf(m, "%3s     - %16p %2lx ",
+                          work->flags & SLOW_WORK_VERY_SLOW ? "vsq" : "sq",
+                          work, work->flags);
+               slow_work_print_mark(m, work);
+
+               if (work->ops->desc)
+                       work->ops->desc(work, m);
+               seq_putc(m, '\n');
+               return 0;
+       }
+}
+
+/*
+ * map the iterator to a work item
+ */
+static void *slow_work_runqueue_index(struct seq_file *m, loff_t *_pos)
+{
+       struct list_head *p;
+       unsigned long count, id;
+
+       switch (*_pos >> ITERATOR_SHIFT) {
+       case 0x0:
+               if (*_pos == 0)
+                       *_pos = 1;
+               if (*_pos < 3)
+                       return (void *)(unsigned long) *_pos;
+               if (*_pos < 3 + SLOW_WORK_THREAD_LIMIT)
+                       for (id = *_pos - 3;
+                            id < SLOW_WORK_THREAD_LIMIT;
+                            id++, (*_pos)++)
+                               if (slow_work_execs[id])
+                                       return (void *)(unsigned long) *_pos;
+               *_pos = 0x1UL << ITERATOR_SHIFT;
+
+       case 0x1:
+               count = *_pos & ITERATOR_COUNTER;
+               list_for_each(p, &slow_work_queue) {
+                       if (count == 0)
+                               return p;
+                       count--;
+               }
+               *_pos = 0x2UL << ITERATOR_SHIFT;
+
+       case 0x2:
+               count = *_pos & ITERATOR_COUNTER;
+               list_for_each(p, &vslow_work_queue) {
+                       if (count == 0)
+                               return p;
+                       count--;
+               }
+               *_pos = 0x3UL << ITERATOR_SHIFT;
+
+       default:
+               return NULL;
+       }
+}
+
+/*
+ * set up the iterator to start reading from the first line
+ */
+static void *slow_work_runqueue_start(struct seq_file *m, loff_t *_pos)
+{
+       spin_lock_irq(&slow_work_queue_lock);
+       return slow_work_runqueue_index(m, _pos);
+}
+
+/*
+ * move to the next line
+ */
+static void *slow_work_runqueue_next(struct seq_file *m, void *v, loff_t *_pos)
+{
+       struct list_head *p = v;
+       unsigned long selector = *_pos >> ITERATOR_SHIFT;
+
+       (*_pos)++;
+       switch (selector) {
+       case 0x0:
+               return slow_work_runqueue_index(m, _pos);
+
+       case 0x1:
+               if (*_pos >> ITERATOR_SHIFT == 0x1) {
+                       p = p->next;
+                       if (p != &slow_work_queue)
+                               return p;
+               }
+               *_pos = 0x2UL << ITERATOR_SHIFT;
+               p = &vslow_work_queue;
+
+       case 0x2:
+               if (*_pos >> ITERATOR_SHIFT == 0x2) {
+                       p = p->next;
+                       if (p != &vslow_work_queue)
+                               return p;
+               }
+               *_pos = 0x3UL << ITERATOR_SHIFT;
+
+       default:
+               return NULL;
+       }
+}
+
+/*
+ * clean up after reading
+ */
+static void slow_work_runqueue_stop(struct seq_file *m, void *v)
+{
+       spin_unlock_irq(&slow_work_queue_lock);
+}
+
+static const struct seq_operations slow_work_runqueue_ops = {
+       .start          = slow_work_runqueue_start,
+       .stop           = slow_work_runqueue_stop,
+       .next           = slow_work_runqueue_next,
+       .show           = slow_work_runqueue_show,
+};
+
+/*
+ * open "/sys/kernel/debug/slow_work/runqueue" to list queue contents
+ */
+static int slow_work_runqueue_open(struct inode *inode, struct file *file)
+{
+       return seq_open(file, &slow_work_runqueue_ops);
+}
+
+const struct file_operations slow_work_runqueue_fops = {
+       .owner          = THIS_MODULE,
+       .open           = slow_work_runqueue_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = seq_release,
+};
index 0d31135efbf4cab0b98babcaa05355eaf5130dfa..00889bd3c5903812ed89d722135b15330b513dbb 100644 (file)
 #include <linux/kthread.h>
 #include <linux/freezer.h>
 #include <linux/wait.h>
-
-#define SLOW_WORK_CULL_TIMEOUT (5 * HZ)        /* cull threads 5s after running out of
-                                        * things to do */
-#define SLOW_WORK_OOM_TIMEOUT (5 * HZ) /* can't start new threads for 5s after
-                                        * OOM */
+#include <linux/debugfs.h>
+#include "slow-work.h"
 
 static void slow_work_cull_timeout(unsigned long);
 static void slow_work_oom_timeout(unsigned long);
@@ -46,7 +43,7 @@ static unsigned vslow_work_proportion = 50; /* % of threads that may process
 
 #ifdef CONFIG_SYSCTL
 static const int slow_work_min_min_threads = 2;
-static int slow_work_max_max_threads = 255;
+static int slow_work_max_max_threads = SLOW_WORK_THREAD_LIMIT;
 static const int slow_work_min_vslow = 1;
 static const int slow_work_max_vslow = 99;
 
@@ -97,6 +94,56 @@ static DEFINE_TIMER(slow_work_cull_timer, slow_work_cull_timeout, 0, 0);
 static DEFINE_TIMER(slow_work_oom_timer, slow_work_oom_timeout, 0, 0);
 static struct slow_work slow_work_new_thread; /* new thread starter */
 
+/*
+ * slow work ID allocation (use slow_work_queue_lock)
+ */
+static DECLARE_BITMAP(slow_work_ids, SLOW_WORK_THREAD_LIMIT);
+
+/*
+ * Unregistration tracking to prevent put_ref() from disappearing during module
+ * unload
+ */
+#ifdef CONFIG_MODULES
+static struct module *slow_work_thread_processing[SLOW_WORK_THREAD_LIMIT];
+static struct module *slow_work_unreg_module;
+static struct slow_work *slow_work_unreg_work_item;
+static DECLARE_WAIT_QUEUE_HEAD(slow_work_unreg_wq);
+static DEFINE_MUTEX(slow_work_unreg_sync_lock);
+
+static void slow_work_set_thread_processing(int id, struct slow_work *work)
+{
+       if (work)
+               slow_work_thread_processing[id] = work->owner;
+}
+static void slow_work_done_thread_processing(int id, struct slow_work *work)
+{
+       struct module *module = slow_work_thread_processing[id];
+
+       slow_work_thread_processing[id] = NULL;
+       smp_mb();
+       if (slow_work_unreg_work_item == work ||
+           slow_work_unreg_module == module)
+               wake_up_all(&slow_work_unreg_wq);
+}
+static void slow_work_clear_thread_processing(int id)
+{
+       slow_work_thread_processing[id] = NULL;
+}
+#else
+static void slow_work_set_thread_processing(int id, struct slow_work *work) {}
+static void slow_work_done_thread_processing(int id, struct slow_work *work) {}
+static void slow_work_clear_thread_processing(int id) {}
+#endif
+
+/*
+ * Data for tracking currently executing items for indication through /proc
+ */
+#ifdef CONFIG_SLOW_WORK_DEBUG
+struct slow_work *slow_work_execs[SLOW_WORK_THREAD_LIMIT];
+pid_t slow_work_pids[SLOW_WORK_THREAD_LIMIT];
+DEFINE_RWLOCK(slow_work_execs_lock);
+#endif
+
 /*
  * The queues of work items and the lock governing access to them.  These are
  * shared between all the CPUs.  It doesn't make sense to have per-CPU queues
@@ -105,9 +152,18 @@ static struct slow_work slow_work_new_thread; /* new thread starter */
  * There are two queues of work items: one for slow work items, and one for
  * very slow work items.
  */
-static LIST_HEAD(slow_work_queue);
-static LIST_HEAD(vslow_work_queue);
-static DEFINE_SPINLOCK(slow_work_queue_lock);
+LIST_HEAD(slow_work_queue);
+LIST_HEAD(vslow_work_queue);
+DEFINE_SPINLOCK(slow_work_queue_lock);
+
+/*
+ * The following are two wait queues that get pinged when a work item is placed
+ * on an empty queue.  These allow work items that are hogging a thread by
+ * sleeping in a way that could be deferred to yield their thread and enqueue
+ * themselves.
+ */
+static DECLARE_WAIT_QUEUE_HEAD(slow_work_queue_waits_for_occupation);
+static DECLARE_WAIT_QUEUE_HEAD(vslow_work_queue_waits_for_occupation);
 
 /*
  * The thread controls.  A variable used to signal to the threads that they
@@ -126,6 +182,20 @@ static DECLARE_COMPLETION(slow_work_last_thread_exited);
 static int slow_work_user_count;
 static DEFINE_MUTEX(slow_work_user_lock);
 
+static inline int slow_work_get_ref(struct slow_work *work)
+{
+       if (work->ops->get_ref)
+               return work->ops->get_ref(work);
+
+       return 0;
+}
+
+static inline void slow_work_put_ref(struct slow_work *work)
+{
+       if (work->ops->put_ref)
+               work->ops->put_ref(work);
+}
+
 /*
  * Calculate the maximum number of active threads in the pool that are
  * permitted to process very slow work items.
@@ -149,7 +219,7 @@ static unsigned slow_work_calc_vsmax(void)
  * Attempt to execute stuff queued on a slow thread.  Return true if we managed
  * it, false if there was nothing to do.
  */
-static bool slow_work_execute(void)
+static noinline bool slow_work_execute(int id)
 {
        struct slow_work *work = NULL;
        unsigned vsmax;
@@ -186,6 +256,13 @@ static bool slow_work_execute(void)
        } else {
                very_slow = false; /* avoid the compiler warning */
        }
+
+       slow_work_set_thread_processing(id, work);
+       if (work) {
+               slow_work_mark_time(work);
+               slow_work_begin_exec(id, work);
+       }
+
        spin_unlock_irq(&slow_work_queue_lock);
 
        if (!work)
@@ -194,12 +271,19 @@ static bool slow_work_execute(void)
        if (!test_and_clear_bit(SLOW_WORK_PENDING, &work->flags))
                BUG();
 
-       work->ops->execute(work);
+       /* don't execute if the work is in the process of being cancelled */
+       if (!test_bit(SLOW_WORK_CANCELLING, &work->flags))
+               work->ops->execute(work);
 
        if (very_slow)
                atomic_dec(&vslow_work_executing_count);
        clear_bit_unlock(SLOW_WORK_EXECUTING, &work->flags);
 
+       /* wake up anyone waiting for this work to be complete */
+       wake_up_bit(&work->flags, SLOW_WORK_EXECUTING);
+
+       slow_work_end_exec(id, work);
+
        /* if someone tried to enqueue the item whilst we were executing it,
         * then it'll be left unenqueued to avoid multiple threads trying to
         * execute it simultaneously
@@ -219,7 +303,10 @@ static bool slow_work_execute(void)
                spin_unlock_irq(&slow_work_queue_lock);
        }
 
-       work->ops->put_ref(work);
+       /* sort out the race between module unloading and put_ref() */
+       slow_work_put_ref(work);
+       slow_work_done_thread_processing(id, work);
+
        return true;
 
 auto_requeue:
@@ -227,14 +314,60 @@ auto_requeue:
         * - we transfer our ref on the item back to the appropriate queue
         * - don't wake another thread up as we're awake already
         */
+       slow_work_mark_time(work);
        if (test_bit(SLOW_WORK_VERY_SLOW, &work->flags))
                list_add_tail(&work->link, &vslow_work_queue);
        else
                list_add_tail(&work->link, &slow_work_queue);
        spin_unlock_irq(&slow_work_queue_lock);
+       slow_work_clear_thread_processing(id);
        return true;
 }
 
+/**
+ * slow_work_sleep_till_thread_needed - Sleep till thread needed by other work
+ * work: The work item under execution that wants to sleep
+ * _timeout: Scheduler sleep timeout
+ *
+ * Allow a requeueable work item to sleep on a slow-work processor thread until
+ * that thread is needed to do some other work or the sleep is interrupted by
+ * some other event.
+ *
+ * The caller must set up a wake up event before calling this and must have set
+ * the appropriate sleep mode (such as TASK_UNINTERRUPTIBLE) and tested its own
+ * condition before calling this function as no test is made here.
+ *
+ * False is returned if there is nothing on the queue; true is returned if the
+ * work item should be requeued
+ */
+bool slow_work_sleep_till_thread_needed(struct slow_work *work,
+                                       signed long *_timeout)
+{
+       wait_queue_head_t *wfo_wq;
+       struct list_head *queue;
+
+       DEFINE_WAIT(wait);
+
+       if (test_bit(SLOW_WORK_VERY_SLOW, &work->flags)) {
+               wfo_wq = &vslow_work_queue_waits_for_occupation;
+               queue = &vslow_work_queue;
+       } else {
+               wfo_wq = &slow_work_queue_waits_for_occupation;
+               queue = &slow_work_queue;
+       }
+
+       if (!list_empty(queue))
+               return true;
+
+       add_wait_queue_exclusive(wfo_wq, &wait);
+       if (list_empty(queue))
+               *_timeout = schedule_timeout(*_timeout);
+       finish_wait(wfo_wq, &wait);
+
+       return !list_empty(queue);
+}
+EXPORT_SYMBOL(slow_work_sleep_till_thread_needed);
+
 /**
  * slow_work_enqueue - Schedule a slow work item for processing
  * @work: The work item to queue
@@ -260,16 +393,22 @@ auto_requeue:
  * allowed to pick items to execute.  This ensures that very slow items won't
  * overly block ones that are just ordinarily slow.
  *
- * Returns 0 if successful, -EAGAIN if not.
+ * Returns 0 if successful, -EAGAIN if not (or -ECANCELED if cancelled work is
+ * attempted queued)
  */
 int slow_work_enqueue(struct slow_work *work)
 {
+       wait_queue_head_t *wfo_wq;
+       struct list_head *queue;
        unsigned long flags;
+       int ret;
+
+       if (test_bit(SLOW_WORK_CANCELLING, &work->flags))
+               return -ECANCELED;
 
        BUG_ON(slow_work_user_count <= 0);
        BUG_ON(!work);
        BUG_ON(!work->ops);
-       BUG_ON(!work->ops->get_ref);
 
        /* when honouring an enqueue request, we only promise that we will run
         * the work function in the future; we do not promise to run it once
@@ -280,8 +419,19 @@ int slow_work_enqueue(struct slow_work *work)
         * maintaining our promise
         */
        if (!test_and_set_bit_lock(SLOW_WORK_PENDING, &work->flags)) {
+               if (test_bit(SLOW_WORK_VERY_SLOW, &work->flags)) {
+                       wfo_wq = &vslow_work_queue_waits_for_occupation;
+                       queue = &vslow_work_queue;
+               } else {
+                       wfo_wq = &slow_work_queue_waits_for_occupation;
+                       queue = &slow_work_queue;
+               }
+
                spin_lock_irqsave(&slow_work_queue_lock, flags);
 
+               if (unlikely(test_bit(SLOW_WORK_CANCELLING, &work->flags)))
+                       goto cancelled;
+
                /* we promise that we will not attempt to execute the work
                 * function in more than one thread simultaneously
                 *
@@ -299,25 +449,221 @@ int slow_work_enqueue(struct slow_work *work)
                if (test_bit(SLOW_WORK_EXECUTING, &work->flags)) {
                        set_bit(SLOW_WORK_ENQ_DEFERRED, &work->flags);
                } else {
-                       if (work->ops->get_ref(work) < 0)
-                               goto cant_get_ref;
-                       if (test_bit(SLOW_WORK_VERY_SLOW, &work->flags))
-                               list_add_tail(&work->link, &vslow_work_queue);
-                       else
-                               list_add_tail(&work->link, &slow_work_queue);
+                       ret = slow_work_get_ref(work);
+                       if (ret < 0)
+                               goto failed;
+                       slow_work_mark_time(work);
+                       list_add_tail(&work->link, queue);
                        wake_up(&slow_work_thread_wq);
+
+                       /* if someone who could be requeued is sleeping on a
+                        * thread, then ask them to yield their thread */
+                       if (work->link.prev == queue)
+                               wake_up(wfo_wq);
                }
 
                spin_unlock_irqrestore(&slow_work_queue_lock, flags);
        }
        return 0;
 
-cant_get_ref:
+cancelled:
+       ret = -ECANCELED;
+failed:
        spin_unlock_irqrestore(&slow_work_queue_lock, flags);
-       return -EAGAIN;
+       return ret;
 }
 EXPORT_SYMBOL(slow_work_enqueue);
 
+static int slow_work_wait(void *word)
+{
+       schedule();
+       return 0;
+}
+
+/**
+ * slow_work_cancel - Cancel a slow work item
+ * @work: The work item to cancel
+ *
+ * This function will cancel a previously enqueued work item. If we cannot
+ * cancel the work item, it is guarenteed to have run when this function
+ * returns.
+ */
+void slow_work_cancel(struct slow_work *work)
+{
+       bool wait = true, put = false;
+
+       set_bit(SLOW_WORK_CANCELLING, &work->flags);
+       smp_mb();
+
+       /* if the work item is a delayed work item with an active timer, we
+        * need to wait for the timer to finish _before_ getting the spinlock,
+        * lest we deadlock against the timer routine
+        *
+        * the timer routine will leave DELAYED set if it notices the
+        * CANCELLING flag in time
+        */
+       if (test_bit(SLOW_WORK_DELAYED, &work->flags)) {
+               struct delayed_slow_work *dwork =
+                       container_of(work, struct delayed_slow_work, work);
+               del_timer_sync(&dwork->timer);
+       }
+
+       spin_lock_irq(&slow_work_queue_lock);
+
+       if (test_bit(SLOW_WORK_DELAYED, &work->flags)) {
+               /* the timer routine aborted or never happened, so we are left
+                * holding the timer's reference on the item and should just
+                * drop the pending flag and wait for any ongoing execution to
+                * finish */
+               struct delayed_slow_work *dwork =
+                       container_of(work, struct delayed_slow_work, work);
+
+               BUG_ON(timer_pending(&dwork->timer));
+               BUG_ON(!list_empty(&work->link));
+
+               clear_bit(SLOW_WORK_DELAYED, &work->flags);
+               put = true;
+               clear_bit(SLOW_WORK_PENDING, &work->flags);
+
+       } else if (test_bit(SLOW_WORK_PENDING, &work->flags) &&
+                  !list_empty(&work->link)) {
+               /* the link in the pending queue holds a reference on the item
+                * that we will need to release */
+               list_del_init(&work->link);
+               wait = false;
+               put = true;
+               clear_bit(SLOW_WORK_PENDING, &work->flags);
+
+       } else if (test_and_clear_bit(SLOW_WORK_ENQ_DEFERRED, &work->flags)) {
+               /* the executor is holding our only reference on the item, so
+                * we merely need to wait for it to finish executing */
+               clear_bit(SLOW_WORK_PENDING, &work->flags);
+       }
+
+       spin_unlock_irq(&slow_work_queue_lock);
+
+       /* the EXECUTING flag is set by the executor whilst the spinlock is set
+        * and before the item is dequeued - so assuming the above doesn't
+        * actually dequeue it, simply waiting for the EXECUTING flag to be
+        * released here should be sufficient */
+       if (wait)
+               wait_on_bit(&work->flags, SLOW_WORK_EXECUTING, slow_work_wait,
+                           TASK_UNINTERRUPTIBLE);
+
+       clear_bit(SLOW_WORK_CANCELLING, &work->flags);
+       if (put)
+               slow_work_put_ref(work);
+}
+EXPORT_SYMBOL(slow_work_cancel);
+
+/*
+ * Handle expiry of the delay timer, indicating that a delayed slow work item
+ * should now be queued if not cancelled
+ */
+static void delayed_slow_work_timer(unsigned long data)
+{
+       wait_queue_head_t *wfo_wq;
+       struct list_head *queue;
+       struct slow_work *work = (struct slow_work *) data;
+       unsigned long flags;
+       bool queued = false, put = false, first = false;
+
+       if (test_bit(SLOW_WORK_VERY_SLOW, &work->flags)) {
+               wfo_wq = &vslow_work_queue_waits_for_occupation;
+               queue = &vslow_work_queue;
+       } else {
+               wfo_wq = &slow_work_queue_waits_for_occupation;
+               queue = &slow_work_queue;
+       }
+
+       spin_lock_irqsave(&slow_work_queue_lock, flags);
+       if (likely(!test_bit(SLOW_WORK_CANCELLING, &work->flags))) {
+               clear_bit(SLOW_WORK_DELAYED, &work->flags);
+
+               if (test_bit(SLOW_WORK_EXECUTING, &work->flags)) {
+                       /* we discard the reference the timer was holding in
+                        * favour of the one the executor holds */
+                       set_bit(SLOW_WORK_ENQ_DEFERRED, &work->flags);
+                       put = true;
+               } else {
+                       slow_work_mark_time(work);
+                       list_add_tail(&work->link, queue);
+                       queued = true;
+                       if (work->link.prev == queue)
+                               first = true;
+               }
+       }
+
+       spin_unlock_irqrestore(&slow_work_queue_lock, flags);
+       if (put)
+               slow_work_put_ref(work);
+       if (first)
+               wake_up(wfo_wq);
+       if (queued)
+               wake_up(&slow_work_thread_wq);
+}
+
+/**
+ * delayed_slow_work_enqueue - Schedule a delayed slow work item for processing
+ * @dwork: The delayed work item to queue
+ * @delay: When to start executing the work, in jiffies from now
+ *
+ * This is similar to slow_work_enqueue(), but it adds a delay before the work
+ * is actually queued for processing.
+ *
+ * The item can have delayed processing requested on it whilst it is being
+ * executed.  The delay will begin immediately, and if it expires before the
+ * item finishes executing, the item will be placed back on the queue when it
+ * has done executing.
+ */
+int delayed_slow_work_enqueue(struct delayed_slow_work *dwork,
+                             unsigned long delay)
+{
+       struct slow_work *work = &dwork->work;
+       unsigned long flags;
+       int ret;
+
+       if (delay == 0)
+               return slow_work_enqueue(&dwork->work);
+
+       BUG_ON(slow_work_user_count <= 0);
+       BUG_ON(!work);
+       BUG_ON(!work->ops);
+
+       if (test_bit(SLOW_WORK_CANCELLING, &work->flags))
+               return -ECANCELED;
+
+       if (!test_and_set_bit_lock(SLOW_WORK_PENDING, &work->flags)) {
+               spin_lock_irqsave(&slow_work_queue_lock, flags);
+
+               if (test_bit(SLOW_WORK_CANCELLING, &work->flags))
+                       goto cancelled;
+
+               /* the timer holds a reference whilst it is pending */
+               ret = work->ops->get_ref(work);
+               if (ret < 0)
+                       goto cant_get_ref;
+
+               if (test_and_set_bit(SLOW_WORK_DELAYED, &work->flags))
+                       BUG();
+               dwork->timer.expires = jiffies + delay;
+               dwork->timer.data = (unsigned long) work;
+               dwork->timer.function = delayed_slow_work_timer;
+               add_timer(&dwork->timer);
+
+               spin_unlock_irqrestore(&slow_work_queue_lock, flags);
+       }
+
+       return 0;
+
+cancelled:
+       ret = -ECANCELED;
+cant_get_ref:
+       spin_unlock_irqrestore(&slow_work_queue_lock, flags);
+       return ret;
+}
+EXPORT_SYMBOL(delayed_slow_work_enqueue);
+
 /*
  * Schedule a cull of the thread pool at some time in the near future
  */
@@ -368,13 +714,23 @@ static inline bool slow_work_available(int vsmax)
  */
 static int slow_work_thread(void *_data)
 {
-       int vsmax;
+       int vsmax, id;
 
        DEFINE_WAIT(wait);
 
        set_freezable();
        set_user_nice(current, -5);
 
+       /* allocate ourselves an ID */
+       spin_lock_irq(&slow_work_queue_lock);
+       id = find_first_zero_bit(slow_work_ids, SLOW_WORK_THREAD_LIMIT);
+       BUG_ON(id < 0 || id >= SLOW_WORK_THREAD_LIMIT);
+       __set_bit(id, slow_work_ids);
+       slow_work_set_thread_pid(id, current->pid);
+       spin_unlock_irq(&slow_work_queue_lock);
+
+       sprintf(current->comm, "kslowd%03u", id);
+
        for (;;) {
                vsmax = vslow_work_proportion;
                vsmax *= atomic_read(&slow_work_thread_count);
@@ -395,7 +751,7 @@ static int slow_work_thread(void *_data)
                vsmax *= atomic_read(&slow_work_thread_count);
                vsmax /= 100;
 
-               if (slow_work_available(vsmax) && slow_work_execute()) {
+               if (slow_work_available(vsmax) && slow_work_execute(id)) {
                        cond_resched();
                        if (list_empty(&slow_work_queue) &&
                            list_empty(&vslow_work_queue) &&
@@ -412,6 +768,11 @@ static int slow_work_thread(void *_data)
                        break;
        }
 
+       spin_lock_irq(&slow_work_queue_lock);
+       slow_work_set_thread_pid(id, 0);
+       __clear_bit(id, slow_work_ids);
+       spin_unlock_irq(&slow_work_queue_lock);
+
        if (atomic_dec_and_test(&slow_work_thread_count))
                complete_and_exit(&slow_work_last_thread_exited, 0);
        return 0;
@@ -426,21 +787,6 @@ static void slow_work_cull_timeout(unsigned long data)
        wake_up(&slow_work_thread_wq);
 }
 
-/*
- * Get a reference on slow work thread starter
- */
-static int slow_work_new_thread_get_ref(struct slow_work *work)
-{
-       return 0;
-}
-
-/*
- * Drop a reference on slow work thread starter
- */
-static void slow_work_new_thread_put_ref(struct slow_work *work)
-{
-}
-
 /*
  * Start a new slow work thread
  */
@@ -475,9 +821,11 @@ static void slow_work_new_thread_execute(struct slow_work *work)
 }
 
 static const struct slow_work_ops slow_work_new_thread_ops = {
-       .get_ref        = slow_work_new_thread_get_ref,
-       .put_ref        = slow_work_new_thread_put_ref,
+       .owner          = THIS_MODULE,
        .execute        = slow_work_new_thread_execute,
+#ifdef CONFIG_SLOW_WORK_DEBUG
+       .desc           = slow_work_new_thread_desc,
+#endif
 };
 
 /*
@@ -546,12 +894,13 @@ static int slow_work_max_threads_sysctl(struct ctl_table *table, int write,
 
 /**
  * slow_work_register_user - Register a user of the facility
+ * @module: The module about to make use of the facility
  *
  * Register a user of the facility, starting up the initial threads if there
  * aren't any other users at this point.  This will return 0 if successful, or
  * an error if not.
  */
-int slow_work_register_user(void)
+int slow_work_register_user(struct module *module)
 {
        struct task_struct *p;
        int loop;
@@ -598,14 +947,81 @@ error:
 }
 EXPORT_SYMBOL(slow_work_register_user);
 
+/*
+ * wait for all outstanding items from the calling module to complete
+ * - note that more items may be queued whilst we're waiting
+ */
+static void slow_work_wait_for_items(struct module *module)
+{
+#ifdef CONFIG_MODULES
+       DECLARE_WAITQUEUE(myself, current);
+       struct slow_work *work;
+       int loop;
+
+       mutex_lock(&slow_work_unreg_sync_lock);
+       add_wait_queue(&slow_work_unreg_wq, &myself);
+
+       for (;;) {
+               spin_lock_irq(&slow_work_queue_lock);
+
+               /* first of all, we wait for the last queued item in each list
+                * to be processed */
+               list_for_each_entry_reverse(work, &vslow_work_queue, link) {
+                       if (work->owner == module) {
+                               set_current_state(TASK_UNINTERRUPTIBLE);
+                               slow_work_unreg_work_item = work;
+                               goto do_wait;
+                       }
+               }
+               list_for_each_entry_reverse(work, &slow_work_queue, link) {
+                       if (work->owner == module) {
+                               set_current_state(TASK_UNINTERRUPTIBLE);
+                               slow_work_unreg_work_item = work;
+                               goto do_wait;
+                       }
+               }
+
+               /* then we wait for the items being processed to finish */
+               slow_work_unreg_module = module;
+               smp_mb();
+               for (loop = 0; loop < SLOW_WORK_THREAD_LIMIT; loop++) {
+                       if (slow_work_thread_processing[loop] == module)
+                               goto do_wait;
+               }
+               spin_unlock_irq(&slow_work_queue_lock);
+               break; /* okay, we're done */
+
+       do_wait:
+               spin_unlock_irq(&slow_work_queue_lock);
+               schedule();
+               slow_work_unreg_work_item = NULL;
+               slow_work_unreg_module = NULL;
+       }
+
+       remove_wait_queue(&slow_work_unreg_wq, &myself);
+       mutex_unlock(&slow_work_unreg_sync_lock);
+#endif /* CONFIG_MODULES */
+}
+
 /**
  * slow_work_unregister_user - Unregister a user of the facility
+ * @module: The module whose items should be cleared
  *
  * Unregister a user of the facility, killing all the threads if this was the
  * last one.
+ *
+ * This waits for all the work items belonging to the nominated module to go
+ * away before proceeding.
  */
-void slow_work_unregister_user(void)
+void slow_work_unregister_user(struct module *module)
 {
+       /* first of all, wait for all outstanding items from the calling module
+        * to complete */
+       if (module)
+               slow_work_wait_for_items(module);
+
+       /* then we can actually go about shutting down the facility if need
+        * be */
        mutex_lock(&slow_work_user_lock);
 
        BUG_ON(slow_work_user_count <= 0);
@@ -638,6 +1054,16 @@ static int __init init_slow_work(void)
 #ifdef CONFIG_SYSCTL
        if (slow_work_max_max_threads < nr_cpus * 2)
                slow_work_max_max_threads = nr_cpus * 2;
+#endif
+#ifdef CONFIG_SLOW_WORK_DEBUG
+       {
+               struct dentry *dbdir;
+
+               dbdir = debugfs_create_dir("slow_work", NULL);
+               if (dbdir && !IS_ERR(dbdir))
+                       debugfs_create_file("runqueue", S_IFREG | 0400, dbdir,
+                                           NULL, &slow_work_runqueue_fops);
+       }
 #endif
        return 0;
 }
diff --git a/kernel/slow-work.h b/kernel/slow-work.h
new file mode 100644 (file)
index 0000000..321f3c5
--- /dev/null
@@ -0,0 +1,72 @@
+/* Slow work private definitions
+ *
+ * Copyright (C) 2009 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#define SLOW_WORK_CULL_TIMEOUT (5 * HZ)        /* cull threads 5s after running out of
+                                        * things to do */
+#define SLOW_WORK_OOM_TIMEOUT (5 * HZ) /* can't start new threads for 5s after
+                                        * OOM */
+
+#define SLOW_WORK_THREAD_LIMIT 255     /* abs maximum number of slow-work threads */
+
+/*
+ * slow-work.c
+ */
+#ifdef CONFIG_SLOW_WORK_DEBUG
+extern struct slow_work *slow_work_execs[];
+extern pid_t slow_work_pids[];
+extern rwlock_t slow_work_execs_lock;
+#endif
+
+extern struct list_head slow_work_queue;
+extern struct list_head vslow_work_queue;
+extern spinlock_t slow_work_queue_lock;
+
+/*
+ * slow-work-debugfs.c
+ */
+#ifdef CONFIG_SLOW_WORK_DEBUG
+extern const struct file_operations slow_work_runqueue_fops;
+
+extern void slow_work_new_thread_desc(struct slow_work *, struct seq_file *);
+#endif
+
+/*
+ * Helper functions
+ */
+static inline void slow_work_set_thread_pid(int id, pid_t pid)
+{
+#ifdef CONFIG_SLOW_WORK_PROC
+       slow_work_pids[id] = pid;
+#endif
+}
+
+static inline void slow_work_mark_time(struct slow_work *work)
+{
+#ifdef CONFIG_SLOW_WORK_PROC
+       work->mark = CURRENT_TIME;
+#endif
+}
+
+static inline void slow_work_begin_exec(int id, struct slow_work *work)
+{
+#ifdef CONFIG_SLOW_WORK_PROC
+       slow_work_execs[id] = work;
+#endif
+}
+
+static inline void slow_work_end_exec(int id, struct slow_work *work)
+{
+#ifdef CONFIG_SLOW_WORK_PROC
+       write_lock(&slow_work_execs_lock);
+       slow_work_execs[id] = NULL;
+       write_unlock(&slow_work_execs_lock);
+#endif
+}
index c9d1c7835c2fa150e154ae95d35e16364b8e385a..a8c76069cf5042008d5b85b957a132acbeacdad6 100644 (file)
@@ -265,9 +265,7 @@ static DEFINE_PER_CPU(struct call_single_data, csd_data);
  * @info: An arbitrary pointer to pass to the function.
  * @wait: If true, wait until function has completed on other CPUs.
  *
- * Returns 0 on success, else a negative status code. Note that @wait
- * will be implicitly turned on in case of allocation failures, since
- * we fall back to on-stack allocation.
+ * Returns 0 on success, else a negative status code.
  */
 int smp_call_function_single(int cpu, void (*func) (void *info), void *info,
                             int wait)
@@ -321,6 +319,51 @@ int smp_call_function_single(int cpu, void (*func) (void *info), void *info,
 }
 EXPORT_SYMBOL(smp_call_function_single);
 
+/*
+ * smp_call_function_any - Run a function on any of the given cpus
+ * @mask: The mask of cpus it can run on.
+ * @func: The function to run. This must be fast and non-blocking.
+ * @info: An arbitrary pointer to pass to the function.
+ * @wait: If true, wait until function has completed.
+ *
+ * Returns 0 on success, else a negative status code (if no cpus were online).
+ * Note that @wait will be implicitly turned on in case of allocation failures,
+ * since we fall back to on-stack allocation.
+ *
+ * Selection preference:
+ *     1) current cpu if in @mask
+ *     2) any cpu of current node if in @mask
+ *     3) any other online cpu in @mask
+ */
+int smp_call_function_any(const struct cpumask *mask,
+                         void (*func)(void *info), void *info, int wait)
+{
+       unsigned int cpu;
+       const struct cpumask *nodemask;
+       int ret;
+
+       /* Try for same CPU (cheapest) */
+       cpu = get_cpu();
+       if (cpumask_test_cpu(cpu, mask))
+               goto call;
+
+       /* Try for same node. */
+       nodemask = cpumask_of_node(cpu);
+       for (cpu = cpumask_first_and(nodemask, mask); cpu < nr_cpu_ids;
+            cpu = cpumask_next_and(cpu, nodemask, mask)) {
+               if (cpu_online(cpu))
+                       goto call;
+       }
+
+       /* Any online will do: smp_call_function_single handles nr_cpu_ids. */
+       cpu = cpumask_any_and(mask, cpu_online_mask);
+call:
+       ret = smp_call_function_single(cpu, func, info, wait);
+       put_cpu();
+       return ret;
+}
+EXPORT_SYMBOL_GPL(smp_call_function_any);
+
 /**
  * __smp_call_function_single(): Run a function on another CPU
  * @cpu: The CPU to run on.
@@ -355,9 +398,7 @@ void __smp_call_function_single(int cpu, struct call_single_data *data,
  * @wait: If true, wait (atomically) until function has completed
  *        on other CPUs.
  *
- * If @wait is true, then returns once @func has returned. Note that @wait
- * will be implicitly turned on in case of allocation failures, since
- * we fall back to on-stack allocation.
+ * If @wait is true, then returns once @func has returned.
  *
  * You must not call this function with disabled interrupts or from a
  * hardware interrupt handler or from a bottom half handler. Preemption
@@ -443,8 +484,7 @@ EXPORT_SYMBOL(smp_call_function_many);
  * Returns 0.
  *
  * If @wait is true, then returns once @func has returned; otherwise
- * it returns just before the target cpu calls @func. In case of allocation
- * failure, @wait will be implicitly turned on.
+ * it returns just before the target cpu calls @func.
  *
  * You must not call this function with disabled interrupts or from a
  * hardware interrupt handler or from a bottom half handler.
index f8749e5216e00c0b1a719a4aa945be8454ca67c0..21939d9e830e22b040f15e5562c97b0a8b8a9e47 100644 (file)
@@ -302,9 +302,9 @@ void irq_exit(void)
        if (!in_interrupt() && local_softirq_pending())
                invoke_softirq();
 
+       rcu_irq_exit();
 #ifdef CONFIG_NO_HZ
        /* Make sure that timer wheel updates are propagated */
-       rcu_irq_exit();
        if (idle_cpu(smp_processor_id()) && !in_interrupt() && !need_resched())
                tick_nohz_stop_sched_tick(0);
 #endif
index 5ddab730cb2fb61d664a83d73792792ef9048432..41e042219ff664e23bf7697da27f50bb3bc49594 100644 (file)
 #include <linux/debug_locks.h>
 #include <linux/module.h>
 
-#ifndef _spin_trylock
-int __lockfunc _spin_trylock(spinlock_t *lock)
-{
-       return __spin_trylock(lock);
-}
-EXPORT_SYMBOL(_spin_trylock);
-#endif
-
-#ifndef _read_trylock
-int __lockfunc _read_trylock(rwlock_t *lock)
-{
-       return __read_trylock(lock);
-}
-EXPORT_SYMBOL(_read_trylock);
-#endif
-
-#ifndef _write_trylock
-int __lockfunc _write_trylock(rwlock_t *lock)
-{
-       return __write_trylock(lock);
-}
-EXPORT_SYMBOL(_write_trylock);
-#endif
-
 /*
  * If lockdep is enabled then we use the non-preemption spin-ops
  * even on CONFIG_PREEMPT, because lockdep assumes that interrupts are
  * not re-enabled during lock-acquire (which the preempt-spin-ops do):
  */
 #if !defined(CONFIG_GENERIC_LOCKBREAK) || defined(CONFIG_DEBUG_LOCK_ALLOC)
-
-#ifndef _read_lock
-void __lockfunc _read_lock(rwlock_t *lock)
-{
-       __read_lock(lock);
-}
-EXPORT_SYMBOL(_read_lock);
-#endif
-
-#ifndef _spin_lock_irqsave
-unsigned long __lockfunc _spin_lock_irqsave(spinlock_t *lock)
-{
-       return __spin_lock_irqsave(lock);
-}
-EXPORT_SYMBOL(_spin_lock_irqsave);
-#endif
-
-#ifndef _spin_lock_irq
-void __lockfunc _spin_lock_irq(spinlock_t *lock)
-{
-       __spin_lock_irq(lock);
-}
-EXPORT_SYMBOL(_spin_lock_irq);
-#endif
-
-#ifndef _spin_lock_bh
-void __lockfunc _spin_lock_bh(spinlock_t *lock)
-{
-       __spin_lock_bh(lock);
-}
-EXPORT_SYMBOL(_spin_lock_bh);
-#endif
-
-#ifndef _read_lock_irqsave
-unsigned long __lockfunc _read_lock_irqsave(rwlock_t *lock)
-{
-       return __read_lock_irqsave(lock);
-}
-EXPORT_SYMBOL(_read_lock_irqsave);
-#endif
-
-#ifndef _read_lock_irq
-void __lockfunc _read_lock_irq(rwlock_t *lock)
-{
-       __read_lock_irq(lock);
-}
-EXPORT_SYMBOL(_read_lock_irq);
-#endif
-
-#ifndef _read_lock_bh
-void __lockfunc _read_lock_bh(rwlock_t *lock)
-{
-       __read_lock_bh(lock);
-}
-EXPORT_SYMBOL(_read_lock_bh);
-#endif
-
-#ifndef _write_lock_irqsave
-unsigned long __lockfunc _write_lock_irqsave(rwlock_t *lock)
-{
-       return __write_lock_irqsave(lock);
-}
-EXPORT_SYMBOL(_write_lock_irqsave);
-#endif
-
-#ifndef _write_lock_irq
-void __lockfunc _write_lock_irq(rwlock_t *lock)
-{
-       __write_lock_irq(lock);
-}
-EXPORT_SYMBOL(_write_lock_irq);
-#endif
-
-#ifndef _write_lock_bh
-void __lockfunc _write_lock_bh(rwlock_t *lock)
-{
-       __write_lock_bh(lock);
-}
-EXPORT_SYMBOL(_write_lock_bh);
-#endif
-
-#ifndef _spin_lock
-void __lockfunc _spin_lock(spinlock_t *lock)
-{
-       __spin_lock(lock);
-}
-EXPORT_SYMBOL(_spin_lock);
-#endif
-
-#ifndef _write_lock
-void __lockfunc _write_lock(rwlock_t *lock)
-{
-       __write_lock(lock);
-}
-EXPORT_SYMBOL(_write_lock);
-#endif
-
-#else /* CONFIG_PREEMPT: */
-
 /*
+ * The __lock_function inlines are taken from
+ * include/linux/spinlock_api_smp.h
+ */
+#else
+/*
+ * We build the __lock_function inlines here. They are too large for
+ * inlining all over the place, but here is only one user per function
+ * which embedds them into the calling _lock_function below.
+ *
  * This could be a long-held lock. We both prepare to spin for a long
  * time (making _this_ CPU preemptable if possible), and we also signal
  * towards that other CPU that it should break the lock ASAP.
- *
- * (We do this in a function because inlining it would be excessive.)
  */
-
 #define BUILD_LOCK_OPS(op, locktype)                                   \
-void __lockfunc _##op##_lock(locktype##_t *lock)                       \
+void __lockfunc __##op##_lock(locktype##_t *lock)                      \
 {                                                                      \
        for (;;) {                                                      \
                preempt_disable();                                      \
@@ -175,9 +58,7 @@ void __lockfunc _##op##_lock(locktype##_t *lock)                     \
        (lock)->break_lock = 0;                                         \
 }                                                                      \
                                                                        \
-EXPORT_SYMBOL(_##op##_lock);                                           \
-                                                                       \
-unsigned long __lockfunc _##op##_lock_irqsave(locktype##_t *lock)      \
+unsigned long __lockfunc __##op##_lock_irqsave(locktype##_t *lock)     \
 {                                                                      \
        unsigned long flags;                                            \
                                                                        \
@@ -198,16 +79,12 @@ unsigned long __lockfunc _##op##_lock_irqsave(locktype##_t *lock)  \
        return flags;                                                   \
 }                                                                      \
                                                                        \
-EXPORT_SYMBOL(_##op##_lock_irqsave);                                   \
-                                                                       \
-void __lockfunc _##op##_lock_irq(locktype##_t *lock)                   \
+void __lockfunc __##op##_lock_irq(locktype##_t *lock)                  \
 {                                                                      \
        _##op##_lock_irqsave(lock);                                     \
 }                                                                      \
                                                                        \
-EXPORT_SYMBOL(_##op##_lock_irq);                                       \
-                                                                       \
-void __lockfunc _##op##_lock_bh(locktype##_t *lock)                    \
+void __lockfunc __##op##_lock_bh(locktype##_t *lock)                   \
 {                                                                      \
        unsigned long flags;                                            \
                                                                        \
@@ -220,23 +97,21 @@ void __lockfunc _##op##_lock_bh(locktype##_t *lock)                        \
        local_bh_disable();                                             \
        local_irq_restore(flags);                                       \
 }                                                                      \
-                                                                       \
-EXPORT_SYMBOL(_##op##_lock_bh)
 
 /*
  * Build preemption-friendly versions of the following
  * lock-spinning functions:
  *
- *         _[spin|read|write]_lock()
- *         _[spin|read|write]_lock_irq()
- *         _[spin|read|write]_lock_irqsave()
- *         _[spin|read|write]_lock_bh()
+ *         __[spin|read|write]_lock()
+ *         __[spin|read|write]_lock_irq()
+ *         __[spin|read|write]_lock_irqsave()
+ *         __[spin|read|write]_lock_bh()
  */
 BUILD_LOCK_OPS(spin, spinlock);
 BUILD_LOCK_OPS(read, rwlock);
 BUILD_LOCK_OPS(write, rwlock);
 
-#endif /* CONFIG_PREEMPT */
+#endif
 
 #ifdef CONFIG_DEBUG_LOCK_ALLOC
 
@@ -248,7 +123,8 @@ void __lockfunc _spin_lock_nested(spinlock_t *lock, int subclass)
 }
 EXPORT_SYMBOL(_spin_lock_nested);
 
-unsigned long __lockfunc _spin_lock_irqsave_nested(spinlock_t *lock, int subclass)
+unsigned long __lockfunc _spin_lock_irqsave_nested(spinlock_t *lock,
+                                                  int subclass)
 {
        unsigned long flags;
 
@@ -272,7 +148,127 @@ EXPORT_SYMBOL(_spin_lock_nest_lock);
 
 #endif
 
-#ifndef _spin_unlock
+#ifndef CONFIG_INLINE_SPIN_TRYLOCK
+int __lockfunc _spin_trylock(spinlock_t *lock)
+{
+       return __spin_trylock(lock);
+}
+EXPORT_SYMBOL(_spin_trylock);
+#endif
+
+#ifndef CONFIG_INLINE_READ_TRYLOCK
+int __lockfunc _read_trylock(rwlock_t *lock)
+{
+       return __read_trylock(lock);
+}
+EXPORT_SYMBOL(_read_trylock);
+#endif
+
+#ifndef CONFIG_INLINE_WRITE_TRYLOCK
+int __lockfunc _write_trylock(rwlock_t *lock)
+{
+       return __write_trylock(lock);
+}
+EXPORT_SYMBOL(_write_trylock);
+#endif
+
+#ifndef CONFIG_INLINE_READ_LOCK
+void __lockfunc _read_lock(rwlock_t *lock)
+{
+       __read_lock(lock);
+}
+EXPORT_SYMBOL(_read_lock);
+#endif
+
+#ifndef CONFIG_INLINE_SPIN_LOCK_IRQSAVE
+unsigned long __lockfunc _spin_lock_irqsave(spinlock_t *lock)
+{
+       return __spin_lock_irqsave(lock);
+}
+EXPORT_SYMBOL(_spin_lock_irqsave);
+#endif
+
+#ifndef CONFIG_INLINE_SPIN_LOCK_IRQ
+void __lockfunc _spin_lock_irq(spinlock_t *lock)
+{
+       __spin_lock_irq(lock);
+}
+EXPORT_SYMBOL(_spin_lock_irq);
+#endif
+
+#ifndef CONFIG_INLINE_SPIN_LOCK_BH
+void __lockfunc _spin_lock_bh(spinlock_t *lock)
+{
+       __spin_lock_bh(lock);
+}
+EXPORT_SYMBOL(_spin_lock_bh);
+#endif
+
+#ifndef CONFIG_INLINE_READ_LOCK_IRQSAVE
+unsigned long __lockfunc _read_lock_irqsave(rwlock_t *lock)
+{
+       return __read_lock_irqsave(lock);
+}
+EXPORT_SYMBOL(_read_lock_irqsave);
+#endif
+
+#ifndef CONFIG_INLINE_READ_LOCK_IRQ
+void __lockfunc _read_lock_irq(rwlock_t *lock)
+{
+       __read_lock_irq(lock);
+}
+EXPORT_SYMBOL(_read_lock_irq);
+#endif
+
+#ifndef CONFIG_INLINE_READ_LOCK_BH
+void __lockfunc _read_lock_bh(rwlock_t *lock)
+{
+       __read_lock_bh(lock);
+}
+EXPORT_SYMBOL(_read_lock_bh);
+#endif
+
+#ifndef CONFIG_INLINE_WRITE_LOCK_IRQSAVE
+unsigned long __lockfunc _write_lock_irqsave(rwlock_t *lock)
+{
+       return __write_lock_irqsave(lock);
+}
+EXPORT_SYMBOL(_write_lock_irqsave);
+#endif
+
+#ifndef CONFIG_INLINE_WRITE_LOCK_IRQ
+void __lockfunc _write_lock_irq(rwlock_t *lock)
+{
+       __write_lock_irq(lock);
+}
+EXPORT_SYMBOL(_write_lock_irq);
+#endif
+
+#ifndef CONFIG_INLINE_WRITE_LOCK_BH
+void __lockfunc _write_lock_bh(rwlock_t *lock)
+{
+       __write_lock_bh(lock);
+}
+EXPORT_SYMBOL(_write_lock_bh);
+#endif
+
+#ifndef CONFIG_INLINE_SPIN_LOCK
+void __lockfunc _spin_lock(spinlock_t *lock)
+{
+       __spin_lock(lock);
+}
+EXPORT_SYMBOL(_spin_lock);
+#endif
+
+#ifndef CONFIG_INLINE_WRITE_LOCK
+void __lockfunc _write_lock(rwlock_t *lock)
+{
+       __write_lock(lock);
+}
+EXPORT_SYMBOL(_write_lock);
+#endif
+
+#ifndef CONFIG_INLINE_SPIN_UNLOCK
 void __lockfunc _spin_unlock(spinlock_t *lock)
 {
        __spin_unlock(lock);
@@ -280,7 +276,7 @@ void __lockfunc _spin_unlock(spinlock_t *lock)
 EXPORT_SYMBOL(_spin_unlock);
 #endif
 
-#ifndef _write_unlock
+#ifndef CONFIG_INLINE_WRITE_UNLOCK
 void __lockfunc _write_unlock(rwlock_t *lock)
 {
        __write_unlock(lock);
@@ -288,7 +284,7 @@ void __lockfunc _write_unlock(rwlock_t *lock)
 EXPORT_SYMBOL(_write_unlock);
 #endif
 
-#ifndef _read_unlock
+#ifndef CONFIG_INLINE_READ_UNLOCK
 void __lockfunc _read_unlock(rwlock_t *lock)
 {
        __read_unlock(lock);
@@ -296,7 +292,7 @@ void __lockfunc _read_unlock(rwlock_t *lock)
 EXPORT_SYMBOL(_read_unlock);
 #endif
 
-#ifndef _spin_unlock_irqrestore
+#ifndef CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE
 void __lockfunc _spin_unlock_irqrestore(spinlock_t *lock, unsigned long flags)
 {
        __spin_unlock_irqrestore(lock, flags);
@@ -304,7 +300,7 @@ void __lockfunc _spin_unlock_irqrestore(spinlock_t *lock, unsigned long flags)
 EXPORT_SYMBOL(_spin_unlock_irqrestore);
 #endif
 
-#ifndef _spin_unlock_irq
+#ifndef CONFIG_INLINE_SPIN_UNLOCK_IRQ
 void __lockfunc _spin_unlock_irq(spinlock_t *lock)
 {
        __spin_unlock_irq(lock);
@@ -312,7 +308,7 @@ void __lockfunc _spin_unlock_irq(spinlock_t *lock)
 EXPORT_SYMBOL(_spin_unlock_irq);
 #endif
 
-#ifndef _spin_unlock_bh
+#ifndef CONFIG_INLINE_SPIN_UNLOCK_BH
 void __lockfunc _spin_unlock_bh(spinlock_t *lock)
 {
        __spin_unlock_bh(lock);
@@ -320,7 +316,7 @@ void __lockfunc _spin_unlock_bh(spinlock_t *lock)
 EXPORT_SYMBOL(_spin_unlock_bh);
 #endif
 
-#ifndef _read_unlock_irqrestore
+#ifndef CONFIG_INLINE_READ_UNLOCK_IRQRESTORE
 void __lockfunc _read_unlock_irqrestore(rwlock_t *lock, unsigned long flags)
 {
        __read_unlock_irqrestore(lock, flags);
@@ -328,7 +324,7 @@ void __lockfunc _read_unlock_irqrestore(rwlock_t *lock, unsigned long flags)
 EXPORT_SYMBOL(_read_unlock_irqrestore);
 #endif
 
-#ifndef _read_unlock_irq
+#ifndef CONFIG_INLINE_READ_UNLOCK_IRQ
 void __lockfunc _read_unlock_irq(rwlock_t *lock)
 {
        __read_unlock_irq(lock);
@@ -336,7 +332,7 @@ void __lockfunc _read_unlock_irq(rwlock_t *lock)
 EXPORT_SYMBOL(_read_unlock_irq);
 #endif
 
-#ifndef _read_unlock_bh
+#ifndef CONFIG_INLINE_READ_UNLOCK_BH
 void __lockfunc _read_unlock_bh(rwlock_t *lock)
 {
        __read_unlock_bh(lock);
@@ -344,7 +340,7 @@ void __lockfunc _read_unlock_bh(rwlock_t *lock)
 EXPORT_SYMBOL(_read_unlock_bh);
 #endif
 
-#ifndef _write_unlock_irqrestore
+#ifndef CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE
 void __lockfunc _write_unlock_irqrestore(rwlock_t *lock, unsigned long flags)
 {
        __write_unlock_irqrestore(lock, flags);
@@ -352,7 +348,7 @@ void __lockfunc _write_unlock_irqrestore(rwlock_t *lock, unsigned long flags)
 EXPORT_SYMBOL(_write_unlock_irqrestore);
 #endif
 
-#ifndef _write_unlock_irq
+#ifndef CONFIG_INLINE_WRITE_UNLOCK_IRQ
 void __lockfunc _write_unlock_irq(rwlock_t *lock)
 {
        __write_unlock_irq(lock);
@@ -360,7 +356,7 @@ void __lockfunc _write_unlock_irq(rwlock_t *lock)
 EXPORT_SYMBOL(_write_unlock_irq);
 #endif
 
-#ifndef _write_unlock_bh
+#ifndef CONFIG_INLINE_WRITE_UNLOCK_BH
 void __lockfunc _write_unlock_bh(rwlock_t *lock)
 {
        __write_unlock_bh(lock);
@@ -368,7 +364,7 @@ void __lockfunc _write_unlock_bh(rwlock_t *lock)
 EXPORT_SYMBOL(_write_unlock_bh);
 #endif
 
-#ifndef _spin_trylock_bh
+#ifndef CONFIG_INLINE_SPIN_TRYLOCK_BH
 int __lockfunc _spin_trylock_bh(spinlock_t *lock)
 {
        return __spin_trylock_bh(lock);
index b0aeeaf22ce49c8c76098aac5224b1f4c44d4c4d..818d7d9aa03c5f73a765f91dc0e56852960a93c4 100644 (file)
@@ -49,6 +49,7 @@ int init_srcu_struct(struct srcu_struct *sp)
        sp->per_cpu_ref = alloc_percpu(struct srcu_struct_array);
        return (sp->per_cpu_ref ? 0 : -ENOMEM);
 }
+EXPORT_SYMBOL_GPL(init_srcu_struct);
 
 /*
  * srcu_readers_active_idx -- returns approximate number of readers
@@ -97,6 +98,7 @@ void cleanup_srcu_struct(struct srcu_struct *sp)
        free_percpu(sp->per_cpu_ref);
        sp->per_cpu_ref = NULL;
 }
+EXPORT_SYMBOL_GPL(cleanup_srcu_struct);
 
 /**
  * srcu_read_lock - register a new reader for an SRCU-protected structure.
@@ -118,6 +120,7 @@ int srcu_read_lock(struct srcu_struct *sp)
        preempt_enable();
        return idx;
 }
+EXPORT_SYMBOL_GPL(srcu_read_lock);
 
 /**
  * srcu_read_unlock - unregister a old reader from an SRCU-protected structure.
@@ -136,22 +139,12 @@ void srcu_read_unlock(struct srcu_struct *sp, int idx)
        per_cpu_ptr(sp->per_cpu_ref, smp_processor_id())->c[idx]--;
        preempt_enable();
 }
+EXPORT_SYMBOL_GPL(srcu_read_unlock);
 
-/**
- * synchronize_srcu - wait for prior SRCU read-side critical-section completion
- * @sp: srcu_struct with which to synchronize.
- *
- * Flip the completed counter, and wait for the old count to drain to zero.
- * As with classic RCU, the updater must use some separate means of
- * synchronizing concurrent updates.  Can block; must be called from
- * process context.
- *
- * Note that it is illegal to call synchornize_srcu() from the corresponding
- * SRCU read-side critical section; doing so will result in deadlock.
- * However, it is perfectly legal to call synchronize_srcu() on one
- * srcu_struct from some other srcu_struct's read-side critical section.
+/*
+ * Helper function for synchronize_srcu() and synchronize_srcu_expedited().
  */
-void synchronize_srcu(struct srcu_struct *sp)
+void __synchronize_srcu(struct srcu_struct *sp, void (*sync_func)(void))
 {
        int idx;
 
@@ -173,7 +166,7 @@ void synchronize_srcu(struct srcu_struct *sp)
                return;
        }
 
-       synchronize_sched();  /* Force memory barrier on all CPUs. */
+       sync_func();  /* Force memory barrier on all CPUs. */
 
        /*
         * The preceding synchronize_sched() ensures that any CPU that
@@ -190,7 +183,7 @@ void synchronize_srcu(struct srcu_struct *sp)
        idx = sp->completed & 0x1;
        sp->completed++;
 
-       synchronize_sched();  /* Force memory barrier on all CPUs. */
+       sync_func();  /* Force memory barrier on all CPUs. */
 
        /*
         * At this point, because of the preceding synchronize_sched(),
@@ -203,7 +196,7 @@ void synchronize_srcu(struct srcu_struct *sp)
        while (srcu_readers_active_idx(sp, idx))
                schedule_timeout_interruptible(1);
 
-       synchronize_sched();  /* Force memory barrier on all CPUs. */
+       sync_func();  /* Force memory barrier on all CPUs. */
 
        /*
         * The preceding synchronize_sched() forces all srcu_read_unlock()
@@ -236,6 +229,47 @@ void synchronize_srcu(struct srcu_struct *sp)
        mutex_unlock(&sp->mutex);
 }
 
+/**
+ * synchronize_srcu - wait for prior SRCU read-side critical-section completion
+ * @sp: srcu_struct with which to synchronize.
+ *
+ * Flip the completed counter, and wait for the old count to drain to zero.
+ * As with classic RCU, the updater must use some separate means of
+ * synchronizing concurrent updates.  Can block; must be called from
+ * process context.
+ *
+ * Note that it is illegal to call synchronize_srcu() from the corresponding
+ * SRCU read-side critical section; doing so will result in deadlock.
+ * However, it is perfectly legal to call synchronize_srcu() on one
+ * srcu_struct from some other srcu_struct's read-side critical section.
+ */
+void synchronize_srcu(struct srcu_struct *sp)
+{
+       __synchronize_srcu(sp, synchronize_sched);
+}
+EXPORT_SYMBOL_GPL(synchronize_srcu);
+
+/**
+ * synchronize_srcu_expedited - like synchronize_srcu, but less patient
+ * @sp: srcu_struct with which to synchronize.
+ *
+ * Flip the completed counter, and wait for the old count to drain to zero.
+ * As with classic RCU, the updater must use some separate means of
+ * synchronizing concurrent updates.  Can block; must be called from
+ * process context.
+ *
+ * Note that it is illegal to call synchronize_srcu_expedited()
+ * from the corresponding SRCU read-side critical section; doing so
+ * will result in deadlock.  However, it is perfectly legal to call
+ * synchronize_srcu_expedited() on one srcu_struct from some other
+ * srcu_struct's read-side critical section.
+ */
+void synchronize_srcu_expedited(struct srcu_struct *sp)
+{
+       __synchronize_srcu(sp, synchronize_sched_expedited);
+}
+EXPORT_SYMBOL_GPL(synchronize_srcu_expedited);
+
 /**
  * srcu_batches_completed - return batches completed.
  * @sp: srcu_struct on which to report batch completion.
@@ -248,10 +282,4 @@ long srcu_batches_completed(struct srcu_struct *sp)
 {
        return sp->completed;
 }
-
-EXPORT_SYMBOL_GPL(init_srcu_struct);
-EXPORT_SYMBOL_GPL(cleanup_srcu_struct);
-EXPORT_SYMBOL_GPL(srcu_read_lock);
-EXPORT_SYMBOL_GPL(srcu_read_unlock);
-EXPORT_SYMBOL_GPL(synchronize_srcu);
 EXPORT_SYMBOL_GPL(srcu_batches_completed);
index 0d949c517412ee16822a5ca7d6e7c79218543741..4dbf93a52ee9f0734d694e5227e6b7f9c1b7f0b2 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/sysrq.h>
 #include <linux/highuid.h>
 #include <linux/writeback.h>
+#include <linux/ratelimit.h>
 #include <linux/hugetlb.h>
 #include <linux/initrd.h>
 #include <linux/key.h>
@@ -158,6 +159,8 @@ extern int no_unaligned_warning;
 extern int unaligned_dump_stack;
 #endif
 
+extern struct ratelimit_state printk_ratelimit_state;
+
 #ifdef CONFIG_RT_MUTEXES
 extern int max_lock_depth;
 #endif
index 7cb6f19225983a9a8f684acc8a2fe6f9b76398aa..e51a1bcb7bed3e8dc93430d37d89d2179e7e5d2a 100644 (file)
@@ -2274,7 +2274,6 @@ void ftrace_set_notrace(unsigned char *buf, int len, int reset)
 #define FTRACE_FILTER_SIZE             COMMAND_LINE_SIZE
 static char ftrace_notrace_buf[FTRACE_FILTER_SIZE] __initdata;
 static char ftrace_filter_buf[FTRACE_FILTER_SIZE] __initdata;
-static char ftrace_graph_buf[FTRACE_FILTER_SIZE] __initdata;
 
 static int __init set_ftrace_notrace(char *str)
 {
@@ -2291,6 +2290,7 @@ static int __init set_ftrace_filter(char *str)
 __setup("ftrace_filter=", set_ftrace_filter);
 
 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
+static char ftrace_graph_buf[FTRACE_FILTER_SIZE] __initdata;
 static int __init set_graph_function(char *str)
 {
        strlcpy(ftrace_graph_buf, str, FTRACE_FILTER_SIZE);
@@ -2985,7 +2985,7 @@ static ssize_t
 ftrace_pid_write(struct file *filp, const char __user *ubuf,
                   size_t cnt, loff_t *ppos)
 {
-       char buf[64];
+       char buf[64], *tmp;
        long val;
        int ret;
 
@@ -3001,11 +3001,11 @@ ftrace_pid_write(struct file *filp, const char __user *ubuf,
         * Allow "echo > set_ftrace_pid" or "echo -n '' > set_ftrace_pid"
         * to clean the filter quietly.
         */
-       strstrip(buf);
-       if (strlen(buf) == 0)
+       tmp = strstrip(buf);
+       if (strlen(tmp) == 0)
                return 1;
 
-       ret = strict_strtol(buf, 10, &val);
+       ret = strict_strtol(tmp, 10, &val);
        if (ret < 0)
                return ret;
 
@@ -3391,4 +3391,3 @@ void ftrace_graph_stop(void)
        ftrace_stop();
 }
 #endif
-
index db223fe8887fcac365391af9bbb98cb31ca41b01..a1ca4956ab5ec3673b04ddd839dd9edec26d1bf4 100644 (file)
@@ -1790,9 +1790,9 @@ rb_reset_tail(struct ring_buffer_per_cpu *cpu_buffer,
 static struct ring_buffer_event *
 rb_move_tail(struct ring_buffer_per_cpu *cpu_buffer,
             unsigned long length, unsigned long tail,
-            struct buffer_page *commit_page,
             struct buffer_page *tail_page, u64 *ts)
 {
+       struct buffer_page *commit_page = cpu_buffer->commit_page;
        struct ring_buffer *buffer = cpu_buffer->buffer;
        struct buffer_page *next_page;
        int ret;
@@ -1895,13 +1895,10 @@ static struct ring_buffer_event *
 __rb_reserve_next(struct ring_buffer_per_cpu *cpu_buffer,
                  unsigned type, unsigned long length, u64 *ts)
 {
-       struct buffer_page *tail_page, *commit_page;
+       struct buffer_page *tail_page;
        struct ring_buffer_event *event;
        unsigned long tail, write;
 
-       commit_page = cpu_buffer->commit_page;
-       /* we just need to protect against interrupts */
-       barrier();
        tail_page = cpu_buffer->tail_page;
        write = local_add_return(length, &tail_page->write);
 
@@ -1912,7 +1909,7 @@ __rb_reserve_next(struct ring_buffer_per_cpu *cpu_buffer,
        /* See if we shot pass the end of this buffer page */
        if (write > BUF_PAGE_SIZE)
                return rb_move_tail(cpu_buffer, length, tail,
-                                   commit_page, tail_page, ts);
+                                   tail_page, ts);
 
        /* We reserved something on the buffer */
 
index 573d3cc762c3ece15d74558691d8e018070c5c99..b2477caf09c2dce12890147bd4a57bfd12cd3010 100644 (file)
@@ -35,6 +35,28 @@ static int disable_reader;
 module_param(disable_reader, uint, 0644);
 MODULE_PARM_DESC(disable_reader, "only run producer");
 
+static int write_iteration = 50;
+module_param(write_iteration, uint, 0644);
+MODULE_PARM_DESC(write_iteration, "# of writes between timestamp readings");
+
+static int producer_nice = 19;
+static int consumer_nice = 19;
+
+static int producer_fifo = -1;
+static int consumer_fifo = -1;
+
+module_param(producer_nice, uint, 0644);
+MODULE_PARM_DESC(producer_nice, "nice prio for producer");
+
+module_param(consumer_nice, uint, 0644);
+MODULE_PARM_DESC(consumer_nice, "nice prio for consumer");
+
+module_param(producer_fifo, uint, 0644);
+MODULE_PARM_DESC(producer_fifo, "fifo prio for producer");
+
+module_param(consumer_fifo, uint, 0644);
+MODULE_PARM_DESC(consumer_fifo, "fifo prio for consumer");
+
 static int read_events;
 
 static int kill_test;
@@ -208,15 +230,18 @@ static void ring_buffer_producer(void)
        do {
                struct ring_buffer_event *event;
                int *entry;
-
-               event = ring_buffer_lock_reserve(buffer, 10);
-               if (!event) {
-                       missed++;
-               } else {
-                       hit++;
-                       entry = ring_buffer_event_data(event);
-                       *entry = smp_processor_id();
-                       ring_buffer_unlock_commit(buffer, event);
+               int i;
+
+               for (i = 0; i < write_iteration; i++) {
+                       event = ring_buffer_lock_reserve(buffer, 10);
+                       if (!event) {
+                               missed++;
+                       } else {
+                               hit++;
+                               entry = ring_buffer_event_data(event);
+                               *entry = smp_processor_id();
+                               ring_buffer_unlock_commit(buffer, event);
+                       }
                }
                do_gettimeofday(&end_tv);
 
@@ -263,6 +288,27 @@ static void ring_buffer_producer(void)
 
        if (kill_test)
                trace_printk("ERROR!\n");
+
+       if (!disable_reader) {
+               if (consumer_fifo < 0)
+                       trace_printk("Running Consumer at nice: %d\n",
+                                    consumer_nice);
+               else
+                       trace_printk("Running Consumer at SCHED_FIFO %d\n",
+                                    consumer_fifo);
+       }
+       if (producer_fifo < 0)
+               trace_printk("Running Producer at nice: %d\n",
+                            producer_nice);
+       else
+               trace_printk("Running Producer at SCHED_FIFO %d\n",
+                            producer_fifo);
+
+       /* Let the user know that the test is running at low priority */
+       if (producer_fifo < 0 && consumer_fifo < 0 &&
+           producer_nice == 19 && consumer_nice == 19)
+               trace_printk("WARNING!!! This test is running at lowest priority.\n");
+
        trace_printk("Time:     %lld (usecs)\n", time);
        trace_printk("Overruns: %lld\n", overruns);
        if (disable_reader)
@@ -392,6 +438,27 @@ static int __init ring_buffer_benchmark_init(void)
        if (IS_ERR(producer))
                goto out_kill;
 
+       /*
+        * Run them as low-prio background tasks by default:
+        */
+       if (!disable_reader) {
+               if (consumer_fifo >= 0) {
+                       struct sched_param param = {
+                               .sched_priority = consumer_fifo
+                       };
+                       sched_setscheduler(consumer, SCHED_FIFO, &param);
+               } else
+                       set_user_nice(consumer, consumer_nice);
+       }
+
+       if (producer_fifo >= 0) {
+               struct sched_param param = {
+                       .sched_priority = consumer_fifo
+               };
+               sched_setscheduler(producer, SCHED_FIFO, &param);
+       } else
+               set_user_nice(producer, producer_nice);
+
        return 0;
 
  out_kill:
index 9d3067a62d4304248bb02eae0e2aa3d3aa9a8b06..874f2893cff0e1d65d97b99217feb30f9900b4f2 100644 (file)
@@ -1361,10 +1361,11 @@ int trace_array_vprintk(struct trace_array *tr,
        pause_graph_tracing();
        raw_local_irq_save(irq_flags);
        __raw_spin_lock(&trace_buf_lock);
-       len = vsnprintf(trace_buf, TRACE_BUF_SIZE, fmt, args);
-
-       len = min(len, TRACE_BUF_SIZE-1);
-       trace_buf[len] = 0;
+       if (args == NULL) {
+               strncpy(trace_buf, fmt, TRACE_BUF_SIZE);
+               len = strlen(trace_buf);
+       } else
+               len = vsnprintf(trace_buf, TRACE_BUF_SIZE, fmt, args);
 
        size = sizeof(*entry) + len + 1;
        buffer = tr->buffer;
@@ -1373,10 +1374,10 @@ int trace_array_vprintk(struct trace_array *tr,
        if (!event)
                goto out_unlock;
        entry = ring_buffer_event_data(event);
-       entry->ip                       = ip;
+       entry->ip = ip;
 
        memcpy(&entry->buf, trace_buf, len);
-       entry->buf[len] = 0;
+       entry->buf[len] = '\0';
        if (!filter_check_discard(call, entry, buffer, event))
                ring_buffer_unlock_commit(buffer, event);
 
@@ -3319,22 +3320,11 @@ tracing_entries_write(struct file *filp, const char __user *ubuf,
        return cnt;
 }
 
-static int mark_printk(const char *fmt, ...)
-{
-       int ret;
-       va_list args;
-       va_start(args, fmt);
-       ret = trace_vprintk(0, fmt, args);
-       va_end(args);
-       return ret;
-}
-
 static ssize_t
 tracing_mark_write(struct file *filp, const char __user *ubuf,
                                        size_t cnt, loff_t *fpos)
 {
        char *buf;
-       char *end;
 
        if (tracing_disabled)
                return -EINVAL;
@@ -3342,7 +3332,7 @@ tracing_mark_write(struct file *filp, const char __user *ubuf,
        if (cnt > TRACE_BUF_SIZE)
                cnt = TRACE_BUF_SIZE;
 
-       buf = kmalloc(cnt + 1, GFP_KERNEL);
+       buf = kmalloc(cnt + 2, GFP_KERNEL);
        if (buf == NULL)
                return -ENOMEM;
 
@@ -3350,14 +3340,13 @@ tracing_mark_write(struct file *filp, const char __user *ubuf,
                kfree(buf);
                return -EFAULT;
        }
+       if (buf[cnt-1] != '\n') {
+               buf[cnt] = '\n';
+               buf[cnt+1] = '\0';
+       } else
+               buf[cnt] = '\0';
 
-       /* Cut from the first nil or newline. */
-       buf[cnt] = '\0';
-       end = strchr(buf, '\n');
-       if (end)
-               *end = '\0';
-
-       cnt = mark_printk("%s\n", buf);
+       cnt = trace_vprintk(0, buf, NULL);
        kfree(buf);
        *fpos += cnt;
 
@@ -3730,7 +3719,7 @@ tracing_stats_read(struct file *filp, char __user *ubuf,
 
        s = kmalloc(sizeof(*s), GFP_KERNEL);
        if (!s)
-               return ENOMEM;
+               return -ENOMEM;
 
        trace_seq_init(s);
 
index 20c5f92e28a8864cc3ca188cc1205200a89b6c55..878c03f386baef4b998cd9e0f6a7db2d02e6d692 100644 (file)
@@ -20,6 +20,8 @@
 #include <linux/ktime.h>
 #include <linux/trace_clock.h>
 
+#include "trace.h"
+
 /*
  * trace_clock_local(): the simplest and least coherent tracing clock.
  *
  */
 u64 notrace trace_clock_local(void)
 {
-       unsigned long flags;
        u64 clock;
+       int resched;
 
        /*
         * sched_clock() is an architecture implemented, fast, scalable,
         * lockless clock. It is not guaranteed to be coherent across
         * CPUs, nor across CPU idle events.
         */
-       raw_local_irq_save(flags);
+       resched = ftrace_preempt_disable();
        clock = sched_clock();
-       raw_local_irq_restore(flags);
+       ftrace_preempt_enable(resched);
 
        return clock;
 }
index 934d81fb4ca46b2c8b654d8b7ac234b87f9ab481..dff8c84ddf17589543ca90e71af630cf7b0755b7 100644 (file)
 struct ____ftrace_##name {                                     \
        tstruct                                                 \
 };                                                             \
-static void __used ____ftrace_check_##name(void)               \
+static void __always_unused ____ftrace_check_##name(void)      \
 {                                                              \
        struct ____ftrace_##name *__entry = NULL;               \
                                                                \
-       /* force cmpile-time check on F_printk() */             \
+       /* force compile-time check on F_printk() */            \
        printk(print);                                          \
 }
 
index 12328147132c0e6e560ff2e3de39c2fda2a4f116..67e526b6ae815bbc846fd0424d43399f9fb5a0ba 100644 (file)
@@ -692,31 +692,29 @@ int schedule_on_each_cpu(work_func_t func)
        if (!works)
                return -ENOMEM;
 
+       get_online_cpus();
+
        /*
-        * when running in keventd don't schedule a work item on itself.
-        * Can just call directly because the work queue is already bound.
-        * This also is faster.
-        * Make this a generic parameter for other workqueues?
+        * When running in keventd don't schedule a work item on
+        * itself.  Can just call directly because the work queue is
+        * already bound.  This also is faster.
         */
-       if (current_is_keventd()) {
+       if (current_is_keventd())
                orig = raw_smp_processor_id();
-               INIT_WORK(per_cpu_ptr(works, orig), func);
-               func(per_cpu_ptr(works, orig));
-       }
 
-       get_online_cpus();
        for_each_online_cpu(cpu) {
                struct work_struct *work = per_cpu_ptr(works, cpu);
 
-               if (cpu == orig)
-                       continue;
                INIT_WORK(work, func);
-               schedule_work_on(cpu, work);
-       }
-       for_each_online_cpu(cpu) {
                if (cpu != orig)
-                       flush_work(per_cpu_ptr(works, cpu));
+                       schedule_work_on(cpu, work);
        }
+       if (orig >= 0)
+               func(per_cpu_ptr(works, orig));
+
+       for_each_online_cpu(cpu)
+               flush_work(per_cpu_ptr(works, cpu));
+
        put_online_cpus();
        free_percpu(works);
        return 0;
index 234ceb10861f304ba858ec9a0baa9f6b297a43a6..a79c4d0407abf7c3cf783b1112e8c78ad0148802 100644 (file)
@@ -750,7 +750,7 @@ config RCU_TORTURE_TEST_RUNNABLE
 config RCU_CPU_STALL_DETECTOR
        bool "Check for stalled CPUs delaying RCU grace periods"
        depends on TREE_RCU || TREE_PREEMPT_RCU
-       default n
+       default y
        help
          This option causes RCU to printk information on which
          CPUs are delaying the current grace period, but only when
index 23abbd93cae1fd50b87b2ed5f8ffd95d940230b1..92cdd9936e3d2797f4d9b3804ad648b6bbec3c1b 100644 (file)
@@ -200,6 +200,9 @@ radix_tree_node_free(struct radix_tree_node *node)
  * ensure that the addition of a single element in the tree cannot fail.  On
  * success, return zero, with preemption disabled.  On error, return -ENOMEM
  * with preemption not disabled.
+ *
+ * To make use of this facility, the radix tree must be initialised without
+ * __GFP_WAIT being passed to INIT_RADIX_TREE().
  */
 int radix_tree_preload(gfp_t gfp_mask)
 {
@@ -543,7 +546,6 @@ out:
 }
 EXPORT_SYMBOL(radix_tree_tag_clear);
 
-#ifndef __KERNEL__     /* Only the test harness uses this at present */
 /**
  * radix_tree_tag_get - get a tag on a radix tree node
  * @root:              radix tree root
@@ -606,7 +608,6 @@ int radix_tree_tag_get(struct radix_tree_root *root,
        }
 }
 EXPORT_SYMBOL(radix_tree_tag_get);
-#endif
 
 /**
  *     radix_tree_next_hole    -    find the next hole (not-present entry)
index 26187edcc7ead6c8c14bd69f1bb77cb3ca4640b4..09f5ce1810dcc02ddb99696d255ed3ad6436f30b 100644 (file)
@@ -7,15 +7,12 @@
  * parameter. Now every user can use their own standalone ratelimit_state.
  *
  * This file is released under the GPLv2.
- *
  */
 
-#include <linux/kernel.h>
+#include <linux/ratelimit.h>
 #include <linux/jiffies.h>
 #include <linux/module.h>
 
-static DEFINE_SPINLOCK(ratelimit_lock);
-
 /*
  * __ratelimit - rate limiting
  * @rs: ratelimit_state data
@@ -23,35 +20,43 @@ static DEFINE_SPINLOCK(ratelimit_lock);
  * This enforces a rate limit: not more than @rs->ratelimit_burst callbacks
  * in every @rs->ratelimit_jiffies
  */
-int __ratelimit(struct ratelimit_state *rs)
+int ___ratelimit(struct ratelimit_state *rs, const char *func)
 {
        unsigned long flags;
+       int ret;
 
        if (!rs->interval)
                return 1;
 
-       spin_lock_irqsave(&ratelimit_lock, flags);
+       /*
+        * If we contend on this state's lock then almost
+        * by definition we are too busy to print a message,
+        * in addition to the one that will be printed by
+        * the entity that is holding the lock already:
+        */
+       if (!spin_trylock_irqsave(&rs->lock, flags))
+               return 1;
+
        if (!rs->begin)
                rs->begin = jiffies;
 
        if (time_is_before_jiffies(rs->begin + rs->interval)) {
                if (rs->missed)
                        printk(KERN_WARNING "%s: %d callbacks suppressed\n",
-                               __func__, rs->missed);
-               rs->begin = 0;
+                               func, rs->missed);
+               rs->begin   = 0;
                rs->printed = 0;
-               rs->missed = 0;
+               rs->missed  = 0;
        }
-       if (rs->burst && rs->burst > rs->printed)
-               goto print;
-
-       rs->missed++;
-       spin_unlock_irqrestore(&ratelimit_lock, flags);
-       return 0;
+       if (rs->burst && rs->burst > rs->printed) {
+               rs->printed++;
+               ret = 1;
+       } else {
+               rs->missed++;
+               ret = 0;
+       }
+       spin_unlock_irqrestore(&rs->lock, flags);
 
-print:
-       rs->printed++;
-       spin_unlock_irqrestore(&ratelimit_lock, flags);
-       return 1;
+       return ret;
 }
-EXPORT_SYMBOL(__ratelimit);
+EXPORT_SYMBOL(___ratelimit);
index b19b87af65a3553a0650d679cabfac9fecd4eb3b..e96421ab9a9a0a1a8ddd4496e32789acdc4b0749 100644 (file)
@@ -246,13 +246,17 @@ EXPORT_SYMBOL(strlcat);
 #undef strcmp
 int strcmp(const char *cs, const char *ct)
 {
-       signed char __res;
+       unsigned char c1, c2;
 
        while (1) {
-               if ((__res = *cs - *ct++) != 0 || !*cs++)
+               c1 = *cs++;
+               c2 = *ct++;
+               if (c1 != c2)
+                       return c1 < c2 ? -1 : 1;
+               if (!c1)
                        break;
        }
-       return __res;
+       return 0;
 }
 EXPORT_SYMBOL(strcmp);
 #endif
@@ -266,14 +270,18 @@ EXPORT_SYMBOL(strcmp);
  */
 int strncmp(const char *cs, const char *ct, size_t count)
 {
-       signed char __res = 0;
+       unsigned char c1, c2;
 
        while (count) {
-               if ((__res = *cs - *ct++) != 0 || !*cs++)
+               c1 = *cs++;
+               c2 = *ct++;
+               if (c1 != c2)
+                       return c1 < c2 ? -1 : 1;
+               if (!c1)
                        break;
                count--;
        }
-       return __res;
+       return 0;
 }
 EXPORT_SYMBOL(strncmp);
 #endif
index ac25cd28e8077717263b03a179df2764acd10a50..795472d8ae24c7201a396c40be4e97f2e149f88e 100644 (file)
@@ -97,6 +97,8 @@ static phys_addr_t *io_tlb_orig_addr;
  */
 static DEFINE_SPINLOCK(io_tlb_lock);
 
+static int late_alloc;
+
 static int __init
 setup_io_tlb_npages(char *str)
 {
@@ -109,6 +111,7 @@ setup_io_tlb_npages(char *str)
                ++str;
        if (!strcmp(str, "force"))
                swiotlb_force = 1;
+
        return 1;
 }
 __setup("swiotlb=", setup_io_tlb_npages);
@@ -121,8 +124,9 @@ static dma_addr_t swiotlb_virt_to_bus(struct device *hwdev,
        return phys_to_dma(hwdev, virt_to_phys(address));
 }
 
-static void swiotlb_print_info(unsigned long bytes)
+void swiotlb_print_info(void)
 {
+       unsigned long bytes = io_tlb_nslabs << IO_TLB_SHIFT;
        phys_addr_t pstart, pend;
 
        pstart = virt_to_phys(io_tlb_start);
@@ -140,7 +144,7 @@ static void swiotlb_print_info(unsigned long bytes)
  * structures for the software IO TLB used to implement the DMA API.
  */
 void __init
-swiotlb_init_with_default_size(size_t default_size)
+swiotlb_init_with_default_size(size_t default_size, int verbose)
 {
        unsigned long i, bytes;
 
@@ -176,14 +180,14 @@ swiotlb_init_with_default_size(size_t default_size)
        io_tlb_overflow_buffer = alloc_bootmem_low(io_tlb_overflow);
        if (!io_tlb_overflow_buffer)
                panic("Cannot allocate SWIOTLB overflow buffer!\n");
-
-       swiotlb_print_info(bytes);
+       if (verbose)
+               swiotlb_print_info();
 }
 
 void __init
-swiotlb_init(void)
+swiotlb_init(int verbose)
 {
-       swiotlb_init_with_default_size(64 * (1<<20));   /* default to 64MB */
+       swiotlb_init_with_default_size(64 * (1<<20), verbose);  /* default to 64MB */
 }
 
 /*
@@ -260,7 +264,9 @@ swiotlb_late_init_with_default_size(size_t default_size)
        if (!io_tlb_overflow_buffer)
                goto cleanup4;
 
-       swiotlb_print_info(bytes);
+       swiotlb_print_info();
+
+       late_alloc = 1;
 
        return 0;
 
@@ -281,6 +287,32 @@ cleanup1:
        return -ENOMEM;
 }
 
+void __init swiotlb_free(void)
+{
+       if (!io_tlb_overflow_buffer)
+               return;
+
+       if (late_alloc) {
+               free_pages((unsigned long)io_tlb_overflow_buffer,
+                          get_order(io_tlb_overflow));
+               free_pages((unsigned long)io_tlb_orig_addr,
+                          get_order(io_tlb_nslabs * sizeof(phys_addr_t)));
+               free_pages((unsigned long)io_tlb_list, get_order(io_tlb_nslabs *
+                                                                sizeof(int)));
+               free_pages((unsigned long)io_tlb_start,
+                          get_order(io_tlb_nslabs << IO_TLB_SHIFT));
+       } else {
+               free_bootmem_late(__pa(io_tlb_overflow_buffer),
+                                 io_tlb_overflow);
+               free_bootmem_late(__pa(io_tlb_orig_addr),
+                                 io_tlb_nslabs * sizeof(phys_addr_t));
+               free_bootmem_late(__pa(io_tlb_list),
+                                 io_tlb_nslabs * sizeof(int));
+               free_bootmem_late(__pa(io_tlb_start),
+                                 io_tlb_nslabs << IO_TLB_SHIFT);
+       }
+}
+
 static int is_swiotlb_buffer(phys_addr_t paddr)
 {
        return paddr >= virt_to_phys(io_tlb_start) &&
index fd3386242cf06a9f588a363362ecc94b646ddc41..44cf6f0a3a6d34f1cdf90a0f4e65dabf3b9c0623 100644 (file)
@@ -128,12 +128,9 @@ config SPARSEMEM_VMEMMAP
 config MEMORY_HOTPLUG
        bool "Allow for memory hot-add"
        depends on SPARSEMEM || X86_64_ACPI_NUMA
-       depends on HOTPLUG && !(HIBERNATION && !S390) && ARCH_ENABLE_MEMORY_HOTPLUG
+       depends on HOTPLUG && ARCH_ENABLE_MEMORY_HOTPLUG
        depends on (IA64 || X86 || PPC_BOOK3S_64 || SUPERH || S390)
 
-comment "Memory hotplug is currently incompatible with Software Suspend"
-       depends on SPARSEMEM && HOTPLUG && HIBERNATION && !S390
-
 config MEMORY_HOTPLUG_SPARSE
        def_bool y
        depends on SPARSEMEM && MEMORY_HOTPLUG
index 11aee09dd2a611ea7529d4f1b863d383d533b7b7..67a33a5a1a93846bda0ce57ee37fe8d39486f60a 100644 (file)
@@ -604,10 +604,14 @@ static void bdi_wb_shutdown(struct backing_dev_info *bdi)
 
        /*
         * Finally, kill the kernel threads. We don't need to be RCU
-        * safe anymore, since the bdi is gone from visibility.
+        * safe anymore, since the bdi is gone from visibility. Force
+        * unfreeze of the thread before calling kthread_stop(), otherwise
+        * it would never exet if it is currently stuck in the refrigerator.
         */
-       list_for_each_entry(wb, &bdi->wb_list, list)
+       list_for_each_entry(wb, &bdi->wb_list, list) {
+               wb->task->flags &= ~PF_FROZEN;
                kthread_stop(wb->task);
+       }
 }
 
 /*
index 555d5d2731c6d963a66db15d9eb66aa03e9d6c8d..d1dc23cc7f10e78e9598c87c70337bd3d2577d6a 100644 (file)
@@ -143,6 +143,30 @@ unsigned long __init init_bootmem(unsigned long start, unsigned long pages)
        return init_bootmem_core(NODE_DATA(0)->bdata, start, 0, pages);
 }
 
+/*
+ * free_bootmem_late - free bootmem pages directly to page allocator
+ * @addr: starting address of the range
+ * @size: size of the range in bytes
+ *
+ * This is only useful when the bootmem allocator has already been torn
+ * down, but we are still initializing the system.  Pages are given directly
+ * to the page allocator, no bootmem metadata is updated because it is gone.
+ */
+void __init free_bootmem_late(unsigned long addr, unsigned long size)
+{
+       unsigned long cursor, end;
+
+       kmemleak_free_part(__va(addr), size);
+
+       cursor = PFN_UP(addr);
+       end = PFN_DOWN(addr + size);
+
+       for (; cursor < end; cursor++) {
+               __free_pages_bootmem(pfn_to_page(cursor), 0);
+               totalram_pages++;
+       }
+}
+
 static unsigned long __init free_all_bootmem_core(bootmem_data_t *bdata)
 {
        int aligned;
index 821dee596377fadcd93e2116e117eea0a0340e97..2047465cd27cf5b1829979057459857184a42b2e 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/migrate.h>
 #include <linux/page-isolation.h>
 #include <linux/pfn.h>
+#include <linux/suspend.h>
 
 #include <asm/tlbflush.h>
 
@@ -447,7 +448,8 @@ int online_pages(unsigned long pfn, unsigned long nr_pages)
 }
 #endif /* CONFIG_MEMORY_HOTPLUG_SPARSE */
 
-static pg_data_t *hotadd_new_pgdat(int nid, u64 start)
+/* we are OK calling __meminit stuff here - we have CONFIG_MEMORY_HOTPLUG */
+static pg_data_t __ref *hotadd_new_pgdat(int nid, u64 start)
 {
        struct pglist_data *pgdat;
        unsigned long zones_size[MAX_NR_ZONES] = {0};
@@ -484,14 +486,18 @@ int __ref add_memory(int nid, u64 start, u64 size)
        struct resource *res;
        int ret;
 
+       lock_system_sleep();
+
        res = register_memory_resource(start, size);
+       ret = -EEXIST;
        if (!res)
-               return -EEXIST;
+               goto out;
 
        if (!node_online(nid)) {
                pgdat = hotadd_new_pgdat(nid, start);
+               ret = -ENOMEM;
                if (!pgdat)
-                       return -ENOMEM;
+                       goto out;
                new_pgdat = 1;
        }
 
@@ -514,7 +520,8 @@ int __ref add_memory(int nid, u64 start, u64 size)
                BUG_ON(ret);
        }
 
-       return ret;
+       goto out;
+
 error:
        /* rollback pgdat allocation and others */
        if (new_pgdat)
@@ -522,6 +529,8 @@ error:
        if (res)
                release_memory_resource(res);
 
+out:
+       unlock_system_sleep();
        return ret;
 }
 EXPORT_SYMBOL_GPL(add_memory);
@@ -758,6 +767,8 @@ int offline_pages(unsigned long start_pfn,
        if (!test_pages_in_a_zone(start_pfn, end_pfn))
                return -EINVAL;
 
+       lock_system_sleep();
+
        zone = page_zone(pfn_to_page(start_pfn));
        node = zone_to_nid(zone);
        nr_pages = end_pfn - start_pfn;
@@ -765,7 +776,7 @@ int offline_pages(unsigned long start_pfn,
        /* set above range as isolated */
        ret = start_isolate_page_range(start_pfn, end_pfn);
        if (ret)
-               return ret;
+               goto out;
 
        arg.start_pfn = start_pfn;
        arg.nr_pages = nr_pages;
@@ -843,6 +854,7 @@ repeat:
        writeback_set_ratelimit();
 
        memory_notify(MEM_OFFLINE, &arg);
+       unlock_system_sleep();
        return 0;
 
 failed_removal:
@@ -852,6 +864,8 @@ failed_removal:
        /* pushback to free area */
        undo_isolate_page_range(start_pfn, end_pfn);
 
+out:
+       unlock_system_sleep();
        return ret;
 }
 
index 73f5e4b640104f356c2df4956db6324ebe28b327..292ddc3cef9cba4bf58053da23bfcae5a2e9de02 100644 (file)
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -20,7 +20,6 @@
 #include <linux/fs.h>
 #include <linux/personality.h>
 #include <linux/security.h>
-#include <linux/ima.h>
 #include <linux/hugetlb.h>
 #include <linux/profile.h>
 #include <linux/module.h>
@@ -1059,9 +1058,6 @@ unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
        }
 
        error = security_file_mmap(file, reqprot, prot, flags, addr, 0);
-       if (error)
-               return error;
-       error = ima_file_mmap(file, prot);
        if (error)
                return error;
 
index d90797160c2a7fff7be950b04ac9817292208ee0..5adfc268b408936a3d18ae9014ce70e49590738d 100644 (file)
@@ -355,62 +355,86 @@ static struct pcpu_chunk *pcpu_chunk_addr_search(void *addr)
 }
 
 /**
- * pcpu_extend_area_map - extend area map for allocation
- * @chunk: target chunk
+ * pcpu_need_to_extend - determine whether chunk area map needs to be extended
+ * @chunk: chunk of interest
  *
- * Extend area map of @chunk so that it can accomodate an allocation.
- * A single allocation can split an area into three areas, so this
- * function makes sure that @chunk->map has at least two extra slots.
+ * Determine whether area map of @chunk needs to be extended to
+ * accomodate a new allocation.
  *
  * CONTEXT:
- * pcpu_alloc_mutex, pcpu_lock.  pcpu_lock is released and reacquired
- * if area map is extended.
+ * pcpu_lock.
  *
  * RETURNS:
- * 0 if noop, 1 if successfully extended, -errno on failure.
+ * New target map allocation length if extension is necessary, 0
+ * otherwise.
  */
-static int pcpu_extend_area_map(struct pcpu_chunk *chunk, unsigned long *flags)
+static int pcpu_need_to_extend(struct pcpu_chunk *chunk)
 {
        int new_alloc;
-       int *new;
-       size_t size;
 
-       /* has enough? */
        if (chunk->map_alloc >= chunk->map_used + 2)
                return 0;
 
-       spin_unlock_irqrestore(&pcpu_lock, *flags);
-
        new_alloc = PCPU_DFL_MAP_ALLOC;
        while (new_alloc < chunk->map_used + 2)
                new_alloc *= 2;
 
-       new = pcpu_mem_alloc(new_alloc * sizeof(new[0]));
-       if (!new) {
-               spin_lock_irqsave(&pcpu_lock, *flags);
+       return new_alloc;
+}
+
+/**
+ * pcpu_extend_area_map - extend area map of a chunk
+ * @chunk: chunk of interest
+ * @new_alloc: new target allocation length of the area map
+ *
+ * Extend area map of @chunk to have @new_alloc entries.
+ *
+ * CONTEXT:
+ * Does GFP_KERNEL allocation.  Grabs and releases pcpu_lock.
+ *
+ * RETURNS:
+ * 0 on success, -errno on failure.
+ */
+static int pcpu_extend_area_map(struct pcpu_chunk *chunk, int new_alloc)
+{
+       int *old = NULL, *new = NULL;
+       size_t old_size = 0, new_size = new_alloc * sizeof(new[0]);
+       unsigned long flags;
+
+       new = pcpu_mem_alloc(new_size);
+       if (!new)
                return -ENOMEM;
-       }
 
-       /*
-        * Acquire pcpu_lock and switch to new area map.  Only free
-        * could have happened inbetween, so map_used couldn't have
-        * grown.
-        */
-       spin_lock_irqsave(&pcpu_lock, *flags);
-       BUG_ON(new_alloc < chunk->map_used + 2);
+       /* acquire pcpu_lock and switch to new area map */
+       spin_lock_irqsave(&pcpu_lock, flags);
+
+       if (new_alloc <= chunk->map_alloc)
+               goto out_unlock;
 
-       size = chunk->map_alloc * sizeof(chunk->map[0]);
-       memcpy(new, chunk->map, size);
+       old_size = chunk->map_alloc * sizeof(chunk->map[0]);
+       memcpy(new, chunk->map, old_size);
 
        /*
         * map_alloc < PCPU_DFL_MAP_ALLOC indicates that the chunk is
         * one of the first chunks and still using static map.
         */
        if (chunk->map_alloc >= PCPU_DFL_MAP_ALLOC)
-               pcpu_mem_free(chunk->map, size);
+               old = chunk->map;
 
        chunk->map_alloc = new_alloc;
        chunk->map = new;
+       new = NULL;
+
+out_unlock:
+       spin_unlock_irqrestore(&pcpu_lock, flags);
+
+       /*
+        * pcpu_mem_free() might end up calling vfree() which uses
+        * IRQ-unsafe lock and thus can't be called under pcpu_lock.
+        */
+       pcpu_mem_free(old, old_size);
+       pcpu_mem_free(new, new_size);
+
        return 0;
 }
 
@@ -1049,7 +1073,7 @@ static void *pcpu_alloc(size_t size, size_t align, bool reserved)
        static int warn_limit = 10;
        struct pcpu_chunk *chunk;
        const char *err;
-       int slot, off;
+       int slot, off, new_alloc;
        unsigned long flags;
 
        if (unlikely(!size || size > PCPU_MIN_UNIT_SIZE || align > PAGE_SIZE)) {
@@ -1064,14 +1088,25 @@ static void *pcpu_alloc(size_t size, size_t align, bool reserved)
        /* serve reserved allocations from the reserved chunk if available */
        if (reserved && pcpu_reserved_chunk) {
                chunk = pcpu_reserved_chunk;
-               if (size > chunk->contig_hint ||
-                   pcpu_extend_area_map(chunk, &flags) < 0) {
-                       err = "failed to extend area map of reserved chunk";
+
+               if (size > chunk->contig_hint) {
+                       err = "alloc from reserved chunk failed";
                        goto fail_unlock;
                }
+
+               while ((new_alloc = pcpu_need_to_extend(chunk))) {
+                       spin_unlock_irqrestore(&pcpu_lock, flags);
+                       if (pcpu_extend_area_map(chunk, new_alloc) < 0) {
+                               err = "failed to extend area map of reserved chunk";
+                               goto fail_unlock_mutex;
+                       }
+                       spin_lock_irqsave(&pcpu_lock, flags);
+               }
+
                off = pcpu_alloc_area(chunk, size, align);
                if (off >= 0)
                        goto area_found;
+
                err = "alloc from reserved chunk failed";
                goto fail_unlock;
        }
@@ -1083,14 +1118,20 @@ restart:
                        if (size > chunk->contig_hint)
                                continue;
 
-                       switch (pcpu_extend_area_map(chunk, &flags)) {
-                       case 0:
-                               break;
-                       case 1:
-                               goto restart;   /* pcpu_lock dropped, restart */
-                       default:
-                               err = "failed to extend area map";
-                               goto fail_unlock;
+                       new_alloc = pcpu_need_to_extend(chunk);
+                       if (new_alloc) {
+                               spin_unlock_irqrestore(&pcpu_lock, flags);
+                               if (pcpu_extend_area_map(chunk,
+                                                        new_alloc) < 0) {
+                                       err = "failed to extend area map";
+                                       goto fail_unlock_mutex;
+                               }
+                               spin_lock_irqsave(&pcpu_lock, flags);
+                               /*
+                                * pcpu_lock has been dropped, need to
+                                * restart cpu_slot list walking.
+                                */
+                               goto restart;
                        }
 
                        off = pcpu_alloc_area(chunk, size, align);
index 8836575f9d79dcd9b28c1cfa7d01d034dde9f0c5..a29c5ab5815cef5887f99a381a89e9bc2c312b26 100644 (file)
@@ -281,8 +281,11 @@ out_uninit_applicant:
        if (ngrp)
                vlan_gvrp_uninit_applicant(real_dev);
 out_free_group:
-       if (ngrp)
-               vlan_group_free(ngrp);
+       if (ngrp) {
+               hlist_del_rcu(&ngrp->hlist);
+               /* Free the group, after all cpu's are done. */
+               call_rcu(&ngrp->rcu, vlan_rcu_free);
+       }
        return err;
 }
 
index a9750984f772a164ebb26cb7af1da01e46ea2cd4..b7c4224f4e7dee01288dd31f4581f7a8821c7a21 100644 (file)
@@ -211,6 +211,7 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst)
        conn->type  = type;
        conn->mode  = HCI_CM_ACTIVE;
        conn->state = BT_OPEN;
+       conn->auth_type = HCI_AT_GENERAL_BONDING;
 
        conn->power_save = 1;
        conn->disc_timeout = HCI_DISCONN_TIMEOUT;
index 77e9fb130adb4bd6475c53a481f6e176bf5ec240..947f8bbb4bb34e55ca29f57ce95551bd6013306b 100644 (file)
@@ -2205,7 +2205,7 @@ static int l2cap_build_conf_req(struct sock *sk, void *data)
 {
        struct l2cap_pinfo *pi = l2cap_pi(sk);
        struct l2cap_conf_req *req = data;
-       struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_ERTM };
+       struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
        void *ptr = req->data;
 
        BT_DBG("sk %p", sk);
@@ -2394,6 +2394,10 @@ done:
                        rfc.monitor_timeout = L2CAP_DEFAULT_MONITOR_TO;
 
                        pi->conf_state |= L2CAP_CONF_MODE_DONE;
+
+                       l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
+                                       sizeof(rfc), (unsigned long) &rfc);
+
                        break;
 
                case L2CAP_MODE_STREAMING:
@@ -2401,6 +2405,10 @@ done:
                        pi->max_pdu_size = rfc.max_pdu_size;
 
                        pi->conf_state |= L2CAP_CONF_MODE_DONE;
+
+                       l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
+                                       sizeof(rfc), (unsigned long) &rfc);
+
                        break;
 
                default:
@@ -2410,9 +2418,6 @@ done:
                        rfc.mode = pi->mode;
                }
 
-               l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
-                                       sizeof(rfc), (unsigned long) &rfc);
-
                if (result == L2CAP_CONF_SUCCESS)
                        pi->conf_state |= L2CAP_CONF_OUTPUT_DONE;
        }
index b8f74cfb1bfdf1365494e87a1b712834f936f287..fe10551d3671053ea6d6a6da57de037f43ad78d0 100644 (file)
@@ -942,14 +942,15 @@ rollback:
        ret = notifier_to_errno(ret);
 
        if (ret) {
-               if (err) {
-                       printk(KERN_ERR
-                              "%s: name change rollback failed: %d.\n",
-                              dev->name, ret);
-               } else {
+               /* err >= 0 after dev_alloc_name() or stores the first errno */
+               if (err >= 0) {
                        err = ret;
                        memcpy(dev->name, oldname, IFNAMSIZ);
                        goto rollback;
+               } else {
+                       printk(KERN_ERR
+                              "%s: name change rollback failed: %d.\n",
+                              dev->name, ret);
                }
        }
 
index 6eb8d47cbf3a563f7d6479183a1b6339afc839cb..6e79e96cb4f29984b019ab0ea74820d0f1de114b 100644 (file)
@@ -363,6 +363,7 @@ struct pktgen_dev {
                                  * device name (not when the inject is
                                  * started as it used to do.)
                                  */
+       char odevname[32];
        struct flow_state *flows;
        unsigned cflows;        /* Concurrent flows (config) */
        unsigned lflow;         /* Flow length  (config) */
@@ -426,7 +427,7 @@ static const char version[] =
 static int pktgen_remove_device(struct pktgen_thread *t, struct pktgen_dev *i);
 static int pktgen_add_device(struct pktgen_thread *t, const char *ifname);
 static struct pktgen_dev *pktgen_find_dev(struct pktgen_thread *t,
-                                         const char *ifname);
+                                         const char *ifname, bool exact);
 static int pktgen_device_event(struct notifier_block *, unsigned long, void *);
 static void pktgen_run_all_threads(void);
 static void pktgen_reset_all_threads(void);
@@ -528,7 +529,7 @@ static int pktgen_if_show(struct seq_file *seq, void *v)
        seq_printf(seq,
                   "     frags: %d  delay: %llu  clone_skb: %d  ifname: %s\n",
                   pkt_dev->nfrags, (unsigned long long) pkt_dev->delay,
-                  pkt_dev->clone_skb, pkt_dev->odev->name);
+                  pkt_dev->clone_skb, pkt_dev->odevname);
 
        seq_printf(seq, "     flows: %u flowlen: %u\n", pkt_dev->cflows,
                   pkt_dev->lflow);
@@ -1688,13 +1689,13 @@ static int pktgen_thread_show(struct seq_file *seq, void *v)
        if_lock(t);
        list_for_each_entry(pkt_dev, &t->if_list, list)
                if (pkt_dev->running)
-                       seq_printf(seq, "%s ", pkt_dev->odev->name);
+                       seq_printf(seq, "%s ", pkt_dev->odevname);
 
        seq_printf(seq, "\nStopped: ");
 
        list_for_each_entry(pkt_dev, &t->if_list, list)
                if (!pkt_dev->running)
-                       seq_printf(seq, "%s ", pkt_dev->odev->name);
+                       seq_printf(seq, "%s ", pkt_dev->odevname);
 
        if (t->result[0])
                seq_printf(seq, "\nResult: %s\n", t->result);
@@ -1817,9 +1818,10 @@ static struct pktgen_dev *__pktgen_NN_threads(const char *ifname, int remove)
 {
        struct pktgen_thread *t;
        struct pktgen_dev *pkt_dev = NULL;
+       bool exact = (remove == FIND);
 
        list_for_each_entry(t, &pktgen_threads, th_list) {
-               pkt_dev = pktgen_find_dev(t, ifname);
+               pkt_dev = pktgen_find_dev(t, ifname, exact);
                if (pkt_dev) {
                        if (remove) {
                                if_lock(t);
@@ -1994,7 +1996,7 @@ static void pktgen_setup_inject(struct pktgen_dev *pkt_dev)
                       "queue_map_min (zero-based) (%d) exceeds valid range "
                       "[0 - %d] for (%d) queues on %s, resetting\n",
                       pkt_dev->queue_map_min, (ntxq ?: 1) - 1, ntxq,
-                      pkt_dev->odev->name);
+                      pkt_dev->odevname);
                pkt_dev->queue_map_min = ntxq - 1;
        }
        if (pkt_dev->queue_map_max >= ntxq) {
@@ -2002,7 +2004,7 @@ static void pktgen_setup_inject(struct pktgen_dev *pkt_dev)
                       "queue_map_max (zero-based) (%d) exceeds valid range "
                       "[0 - %d] for (%d) queues on %s, resetting\n",
                       pkt_dev->queue_map_max, (ntxq ?: 1) - 1, ntxq,
-                      pkt_dev->odev->name);
+                      pkt_dev->odevname);
                pkt_dev->queue_map_max = ntxq - 1;
        }
 
@@ -3262,7 +3264,7 @@ static int pktgen_stop_device(struct pktgen_dev *pkt_dev)
 
        if (!pkt_dev->running) {
                printk(KERN_WARNING "pktgen: interface: %s is already "
-                      "stopped\n", pkt_dev->odev->name);
+                      "stopped\n", pkt_dev->odevname);
                return -EINVAL;
        }
 
@@ -3464,7 +3466,7 @@ static void pktgen_xmit(struct pktgen_dev *pkt_dev)
        default: /* Drivers are not supposed to return other values! */
                if (net_ratelimit())
                        pr_info("pktgen: %s xmit error: %d\n",
-                               odev->name, ret);
+                               pkt_dev->odevname, ret);
                pkt_dev->errors++;
                /* fallthru */
        case NETDEV_TX_LOCKED:
@@ -3566,13 +3568,18 @@ static int pktgen_thread_worker(void *arg)
 }
 
 static struct pktgen_dev *pktgen_find_dev(struct pktgen_thread *t,
-                                         const char *ifname)
+                                         const char *ifname, bool exact)
 {
        struct pktgen_dev *p, *pkt_dev = NULL;
-       if_lock(t);
+       size_t len = strlen(ifname);
 
+       if_lock(t);
        list_for_each_entry(p, &t->if_list, list)
-               if (strncmp(p->odev->name, ifname, IFNAMSIZ) == 0) {
+               if (strncmp(p->odevname, ifname, len) == 0) {
+                       if (p->odevname[len]) {
+                               if (exact || p->odevname[len] != '@')
+                                       continue;
+                       }
                        pkt_dev = p;
                        break;
                }
@@ -3628,6 +3635,7 @@ static int pktgen_add_device(struct pktgen_thread *t, const char *ifname)
        if (!pkt_dev)
                return -ENOMEM;
 
+       strcpy(pkt_dev->odevname, ifname);
        pkt_dev->flows = vmalloc(MAX_CFLOWS * sizeof(struct flow_state));
        if (pkt_dev->flows == NULL) {
                kfree(pkt_dev);
index 80a96166df3910042a6c5b516ae77f202288f78f..ec85681a7dd83765878cd6c791538a7941732178 100644 (file)
@@ -2701,7 +2701,8 @@ int skb_gro_receive(struct sk_buff **head, struct sk_buff *skb)
 
                NAPI_GRO_CB(skb)->free = 1;
                goto done;
-       }
+       } else if (skb_gro_len(p) != pinfo->gso_size)
+               return -E2BIG;
 
        headroom = skb_headroom(p);
        nskb = netdev_alloc_skb(p->dev, headroom + skb_gro_offset(p));
index 7db1de0497c63bbde324cc354423dc11a06ef636..887c03c4e3c6d8078265c4e6ad69256dd77f0e58 100644 (file)
@@ -10,7 +10,9 @@
 #include <linux/module.h>
 #include <linux/socket.h>
 #include <linux/netdevice.h>
+#include <linux/ratelimit.h>
 #include <linux/init.h>
+
 #include <net/ip.h>
 #include <net/sock.h>
 
index 83221aee708488fdf52fc9c8a79ace483d96687d..838250241d26221f0ade44451b21697174185cab 100644 (file)
@@ -24,6 +24,8 @@
 #include <linux/types.h>
 #include <linux/percpu.h>
 #include <linux/init.h>
+#include <linux/ratelimit.h>
+
 #include <net/sock.h>
 
 #include <asm/byteorder.h>
index 575f9bd51ccdf745c62125a45611d845dc015b2b..d3fe10be721956eca29a46cdfa7d58abced87744 100644 (file)
@@ -563,7 +563,7 @@ out_oversize:
                printk(KERN_INFO "Oversized IP packet from %pI4.\n",
                        &qp->saddr);
 out_fail:
-       IP_INC_STATS_BH(dev_net(dev), IPSTATS_MIB_REASMFAILS);
+       IP_INC_STATS_BH(net, IPSTATS_MIB_REASMFAILS);
        return err;
 }
 
index 630a56df7b47ee80c9c77dcbb62048dc73ed9fc5..99508d66a64227fd532718486fa9eed924963e26 100644 (file)
@@ -483,8 +483,10 @@ static int vif_add(struct net *net, struct vifctl *vifc, int mrtsock)
                return -EINVAL;
        }
 
-       if ((in_dev = __in_dev_get_rtnl(dev)) == NULL)
+       if ((in_dev = __in_dev_get_rtnl(dev)) == NULL) {
+               dev_put(dev);
                return -EADDRNOTAVAIL;
+       }
        IPV4_DEVCONF(in_dev->cnf, MC_FORWARDING)++;
        ip_rt_multicast_event(in_dev);
 
index 98440ad82558064ce4eb7ee9ad525f9725413739..f1813bc7108811a50ff8284775ad053623903a2e 100644 (file)
@@ -1183,7 +1183,9 @@ void tcp_cleanup_rbuf(struct sock *sk, int copied)
 #if TCP_DEBUG
        struct sk_buff *skb = skb_peek(&sk->sk_receive_queue);
 
-       WARN_ON(skb && !before(tp->copied_seq, TCP_SKB_CB(skb)->end_seq));
+       WARN(skb && !before(tp->copied_seq, TCP_SKB_CB(skb)->end_seq),
+            KERN_INFO "cleanup rbuf bug: copied %X seq %X rcvnxt %X\n",
+            tp->copied_seq, TCP_SKB_CB(skb)->end_seq, tp->rcv_nxt);
 #endif
 
        if (inet_csk_ack_scheduled(sk)) {
@@ -1430,11 +1432,13 @@ int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
                        /* Now that we have two receive queues this
                         * shouldn't happen.
                         */
-                       if (before(*seq, TCP_SKB_CB(skb)->seq)) {
-                               printk(KERN_INFO "recvmsg bug: copied %X "
-                                      "seq %X\n", *seq, TCP_SKB_CB(skb)->seq);
+                       if (WARN(before(*seq, TCP_SKB_CB(skb)->seq),
+                            KERN_INFO "recvmsg bug: copied %X "
+                                      "seq %X rcvnxt %X fl %X\n", *seq,
+                                      TCP_SKB_CB(skb)->seq, tp->rcv_nxt,
+                                      flags))
                                break;
-                       }
+
                        offset = *seq - TCP_SKB_CB(skb)->seq;
                        if (tcp_hdr(skb)->syn)
                                offset--;
@@ -1443,8 +1447,9 @@ int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
                        if (tcp_hdr(skb)->fin)
                                goto found_fin_ok;
                        WARN(!(flags & MSG_PEEK), KERN_INFO "recvmsg bug 2: "
-                                       "copied %X seq %X\n", *seq,
-                                       TCP_SKB_CB(skb)->seq);
+                                       "copied %X seq %X rcvnxt %X fl %X\n",
+                                       *seq, TCP_SKB_CB(skb)->seq,
+                                       tp->rcv_nxt, flags);
                }
 
                /* Well, if we have backlog, try to process it now yet. */
index bc064d7933ff692e2728bfc68c81ded152c930c1..ce8e0e772bab773cd131ea7077a1be79af96695d 100644 (file)
@@ -85,10 +85,6 @@ void ieee80211_sta_stop_rx_ba_session(struct ieee80211_sub_if_data *sdata, u8 *r
        struct ieee80211_local *local = sdata->local;
        struct sta_info *sta;
 
-       /* stop HW Rx aggregation. ampdu_action existence
-        * already verified in session init so we add the BUG_ON */
-       BUG_ON(!local->ops->ampdu_action);
-
        rcu_read_lock();
 
        sta = sta_info_get(local, ra);
index b09948ceec4ae1c031754c08c59d425de3e5ab7b..89e238b001de936e4585f2eae73b3d09ae8cb3f7 100644 (file)
@@ -123,13 +123,18 @@ void ieee80211_send_bar(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid, u1
        ieee80211_tx_skb(sdata, skb, 0);
 }
 
-static int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
-                                          enum ieee80211_back_parties initiator)
+int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
+                                   enum ieee80211_back_parties initiator)
 {
        struct ieee80211_local *local = sta->local;
        int ret;
        u8 *state;
 
+#ifdef CONFIG_MAC80211_HT_DEBUG
+       printk(KERN_DEBUG "Tx BA session stop requested for %pM tid %u\n",
+              sta->sta.addr, tid);
+#endif /* CONFIG_MAC80211_HT_DEBUG */
+
        state = &sta->ampdu_mlme.tid_state_tx[tid];
 
        if (*state == HT_AGG_STATE_OPERATIONAL)
@@ -143,7 +148,6 @@ static int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
 
        /* HW shall not deny going back to legacy */
        if (WARN_ON(ret)) {
-               *state = HT_AGG_STATE_OPERATIONAL;
                /*
                 * We may have pending packets get stuck in this case...
                 * Not bothering with a workaround for now.
@@ -173,12 +177,14 @@ static void sta_addba_resp_timer_expired(unsigned long data)
 
        /* check if the TID waits for addBA response */
        spin_lock_bh(&sta->lock);
-       if (!(*state & HT_ADDBA_REQUESTED_MSK)) {
+       if ((*state & (HT_ADDBA_REQUESTED_MSK | HT_ADDBA_RECEIVED_MSK)) !=
+                                               HT_ADDBA_REQUESTED_MSK) {
                spin_unlock_bh(&sta->lock);
                *state = HT_AGG_STATE_IDLE;
 #ifdef CONFIG_MAC80211_HT_DEBUG
                printk(KERN_DEBUG "timer expired on tid %d but we are not "
-                               "expecting addBA response there", tid);
+                               "(or no longer) expecting addBA response there",
+                       tid);
 #endif
                return;
        }
@@ -523,11 +529,6 @@ int __ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
                goto unlock;
        }
 
-#ifdef CONFIG_MAC80211_HT_DEBUG
-       printk(KERN_DEBUG "Tx BA session stop requested for %pM tid %u\n",
-              sta->sta.addr, tid);
-#endif /* CONFIG_MAC80211_HT_DEBUG */
-
        ret = ___ieee80211_stop_tx_ba_session(sta, tid, initiator);
 
  unlock:
@@ -543,7 +544,7 @@ int ieee80211_stop_tx_ba_session(struct ieee80211_hw *hw,
        struct sta_info *sta;
        int ret = 0;
 
-       if (WARN_ON(!local->ops->ampdu_action))
+       if (!local->ops->ampdu_action)
                return -EINVAL;
 
        if (tid >= STA_TID_NUM)
@@ -666,21 +667,21 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local,
 
        state = &sta->ampdu_mlme.tid_state_tx[tid];
 
-       del_timer_sync(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer);
-
        spin_lock_bh(&sta->lock);
 
        if (!(*state & HT_ADDBA_REQUESTED_MSK))
-               goto timer_still_needed;
+               goto out;
 
        if (mgmt->u.action.u.addba_resp.dialog_token !=
                sta->ampdu_mlme.tid_tx[tid]->dialog_token) {
 #ifdef CONFIG_MAC80211_HT_DEBUG
                printk(KERN_DEBUG "wrong addBA response token, tid %d\n", tid);
 #endif /* CONFIG_MAC80211_HT_DEBUG */
-               goto timer_still_needed;
+               goto out;
        }
 
+       del_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer);
+
 #ifdef CONFIG_MAC80211_HT_DEBUG
        printk(KERN_DEBUG "switched off addBA timer for tid %d \n", tid);
 #endif /* CONFIG_MAC80211_HT_DEBUG */
@@ -699,10 +700,6 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local,
                ___ieee80211_stop_tx_ba_session(sta, tid, WLAN_BACK_INITIATOR);
        }
 
-       goto out;
-
- timer_still_needed:
-       add_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer);
  out:
        spin_unlock_bh(&sta->lock);
 }
index 48ef1a282b91b8f1cf0bf9c3149c6b66a0467c2a..cdc58e61d921737e339ad0f13701e336f29c76c4 100644 (file)
@@ -141,7 +141,6 @@ void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata,
                             struct sta_info *sta,
                             struct ieee80211_mgmt *mgmt, size_t len)
 {
-       struct ieee80211_local *local = sdata->local;
        u16 tid, params;
        u16 initiator;
 
@@ -161,10 +160,9 @@ void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata,
                                                 WLAN_BACK_INITIATOR, 0);
        else { /* WLAN_BACK_RECIPIENT */
                spin_lock_bh(&sta->lock);
-               sta->ampdu_mlme.tid_state_tx[tid] =
-                               HT_AGG_STATE_OPERATIONAL;
+               if (sta->ampdu_mlme.tid_state_tx[tid] & HT_ADDBA_REQUESTED_MSK)
+                       ___ieee80211_stop_tx_ba_session(sta, tid,
+                                                       WLAN_BACK_RECIPIENT);
                spin_unlock_bh(&sta->lock);
-               ieee80211_stop_tx_ba_session(&local->hw, sta->sta.addr, tid,
-                                            WLAN_BACK_RECIPIENT);
        }
 }
index 588005c84a6d2b34eb1ef9900ee9a6ef99fcbcd8..10d316e455de26424110df78364beb3cd12732b3 100644 (file)
@@ -661,6 +661,14 @@ struct ieee80211_local {
         */
        bool suspended;
 
+       /*
+        * Resuming is true while suspended, but when we're reprogramming the
+        * hardware -- at that time it's allowed to use ieee80211_queue_work()
+        * again even though some other parts of the stack are still suspended
+        * and we still drop received frames to avoid waking the stack.
+        */
+       bool resuming;
+
        /*
         * quiescing is true during the suspend process _only_ to
         * ease timer cancelling etc.
@@ -1083,6 +1091,8 @@ void ieee80211_process_addba_request(struct ieee80211_local *local,
 
 int __ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
                                   enum ieee80211_back_parties initiator);
+int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
+                                   enum ieee80211_back_parties initiator);
 
 /* Spectrum management */
 void ieee80211_process_measurement_req(struct ieee80211_sub_if_data *sdata,
index aeb65b3d2295a7a3c99c279a3e669e583c282e5e..e6c08da8da26de707ece65fb11bb8d45d7a309de 100644 (file)
@@ -520,9 +520,9 @@ EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces_atomic);
  */
 static bool ieee80211_can_queue_work(struct ieee80211_local *local)
 {
-        if (WARN(local->suspended, "queueing ieee80211 work while "
-                "going to suspend\n"))
-                return false;
+       if (WARN(local->suspended && !local->resuming,
+                "queueing ieee80211 work while going to suspend\n"))
+               return false;
 
        return true;
 }
@@ -1025,13 +1025,9 @@ int ieee80211_reconfig(struct ieee80211_local *local)
        struct sta_info *sta;
        unsigned long flags;
        int res;
-       bool from_suspend = local->suspended;
 
-       /*
-        * We're going to start the hardware, at that point
-        * we are no longer suspended and can RX frames.
-        */
-       local->suspended = false;
+       if (local->suspended)
+               local->resuming = true;
 
        /* restart hardware */
        if (local->open_count) {
@@ -1129,11 +1125,14 @@ int ieee80211_reconfig(struct ieee80211_local *local)
         * If this is for hw restart things are still running.
         * We may want to change that later, however.
         */
-       if (!from_suspend)
+       if (!local->suspended)
                return 0;
 
 #ifdef CONFIG_PM
+       /* first set suspended false, then resuming */
        local->suspended = false;
+       mb();
+       local->resuming = false;
 
        list_for_each_entry(sdata, &local->interfaces, list) {
                switch(sdata->vif.type) {
index c93494fef8ef3cfdc8eb22352c59554d0c751eb2..d65d3481919ce1d72a5e476c6d1d083236223a67 100644 (file)
@@ -128,9 +128,8 @@ EXPORT_SYMBOL(nf_log_packet);
 
 #ifdef CONFIG_PROC_FS
 static void *seq_start(struct seq_file *seq, loff_t *pos)
-       __acquires(RCU)
 {
-       rcu_read_lock();
+       mutex_lock(&nf_log_mutex);
 
        if (*pos >= ARRAY_SIZE(nf_loggers))
                return NULL;
@@ -149,9 +148,8 @@ static void *seq_next(struct seq_file *s, void *v, loff_t *pos)
 }
 
 static void seq_stop(struct seq_file *s, void *v)
-       __releases(RCU)
 {
-       rcu_read_unlock();
+       mutex_unlock(&nf_log_mutex);
 }
 
 static int seq_show(struct seq_file *s, void *v)
@@ -161,7 +159,7 @@ static int seq_show(struct seq_file *s, void *v)
        struct nf_logger *t;
        int ret;
 
-       logger = rcu_dereference(nf_loggers[*pos]);
+       logger = nf_loggers[*pos];
 
        if (!logger)
                ret = seq_printf(s, "%2lld NONE (", *pos);
@@ -171,22 +169,16 @@ static int seq_show(struct seq_file *s, void *v)
        if (ret < 0)
                return ret;
 
-       mutex_lock(&nf_log_mutex);
        list_for_each_entry(t, &nf_loggers_l[*pos], list[*pos]) {
                ret = seq_printf(s, "%s", t->name);
-               if (ret < 0) {
-                       mutex_unlock(&nf_log_mutex);
+               if (ret < 0)
                        return ret;
-               }
                if (&t->list[*pos] != nf_loggers_l[*pos].prev) {
                        ret = seq_printf(s, ",");
-                       if (ret < 0) {
-                               mutex_unlock(&nf_log_mutex);
+                       if (ret < 0)
                                return ret;
-                       }
                }
        }
-       mutex_unlock(&nf_log_mutex);
 
        return seq_printf(s, ")\n");
 }
index 2e8089ecd0af31b4ac17cf310a65ee5db97b6e0e..2773be6a71ddf49a2d8297a3183274472a0a7d61 100644 (file)
@@ -112,7 +112,7 @@ static bool limit_mt_check(const struct xt_mtchk_param *par)
 
        priv = kmalloc(sizeof(*priv), GFP_KERNEL);
        if (priv == NULL)
-               return -ENOMEM;
+               return false;
 
        /* For SMP, we only want to use one set of state. */
        r->master = priv;
index 63e190504656dcea83b9706c12c0954466eaa59c..4d1a41bbd5d7b735f63c7f0482472b12f9784472 100644 (file)
@@ -118,7 +118,7 @@ static int xt_osf_remove_callback(struct sock *ctnl, struct sk_buff *skb,
 {
        struct xt_osf_user_finger *f;
        struct xt_osf_finger *sf;
-       int err = ENOENT;
+       int err = -ENOENT;
 
        if (!osf_attrs[OSF_ATTR_FINGER])
                return -EINVAL;
index ba2efb960c6007ecbd9b5b0a49372d21d32ed68a..a001f7c1f71145b61eef6aaa7b6128a121751f6e 100644 (file)
@@ -1189,6 +1189,7 @@ static long rfkill_fop_ioctl(struct file *file, unsigned int cmd,
 #endif
 
 static const struct file_operations rfkill_fops = {
+       .owner          = THIS_MODULE,
        .open           = rfkill_fop_open,
        .read           = rfkill_fop_read,
        .write          = rfkill_fop_write,
index 8450960df24f2001fd79b4de547939b991b56a4a..7eed77a39d0d149a518666ab509604f2c0ac9d4f 100644 (file)
@@ -1485,15 +1485,13 @@ void sctp_assoc_rwnd_decrease(struct sctp_association *asoc, unsigned len)
  * local endpoint and the remote peer.
  */
 int sctp_assoc_set_bind_addr_from_ep(struct sctp_association *asoc,
-                                    gfp_t gfp)
+                                    sctp_scope_t scope, gfp_t gfp)
 {
-       sctp_scope_t scope;
        int flags;
 
        /* Use scoping rules to determine the subset of addresses from
         * the endpoint.
         */
-       scope = sctp_scope(&asoc->peer.active_path->ipaddr);
        flags = (PF_INET6 == asoc->base.sk->sk_family) ? SCTP_ADDR6_ALLOWED : 0;
        if (asoc->peer.ipv4_address)
                flags |= SCTP_ADDR4_PEERSUPP;
index c9f20e28521b069b17583e7120ea44ac0dd9eec5..23e5e97aa6173b5684e9e930af64c5ccce590472 100644 (file)
@@ -423,16 +423,6 @@ void sctp_retransmit_mark(struct sctp_outq *q,
                if ((reason == SCTP_RTXR_FAST_RTX  &&
                            (chunk->fast_retransmit == SCTP_NEED_FRTX)) ||
                    (reason != SCTP_RTXR_FAST_RTX  && !chunk->tsn_gap_acked)) {
-                       /* If this chunk was sent less then 1 rto ago, do not
-                        * retransmit this chunk, but give the peer time
-                        * to acknowlege it.  Do this only when
-                        * retransmitting due to T3 timeout.
-                        */
-                       if (reason == SCTP_RTXR_T3_RTX &&
-                           time_before(jiffies, chunk->sent_at +
-                                                transport->last_rto))
-                               continue;
-
                        /* RFC 2960 6.2.1 Processing a Received SACK
                         *
                         * C) Any time a DATA chunk is marked for
index 8674d49195561fc7ed33a5b086eb4014d80f46a7..efa516b47e816b43bf8e6ad974f8dc5cc16d9ad9 100644 (file)
@@ -480,7 +480,6 @@ static void sctp_do_8_2_transport_strike(struct sctp_association *asoc,
         * that indicates that we have an outstanding HB.
         */
        if (!is_hb || transport->hb_sent) {
-               transport->last_rto = transport->rto;
                transport->rto = min((transport->rto * 2), transport->asoc->rto_max);
        }
 }
index c8fae1983dd15153625d4505500a5030402524d7..d4df45022ffab8f028b45037adf0b528df8273d9 100644 (file)
@@ -384,6 +384,11 @@ sctp_disposition_t sctp_sf_do_5_1B_init(const struct sctp_endpoint *ep,
        if (!new_asoc)
                goto nomem;
 
+       if (sctp_assoc_set_bind_addr_from_ep(new_asoc,
+                                            sctp_scope(sctp_source(chunk)),
+                                            GFP_ATOMIC) < 0)
+               goto nomem_init;
+
        /* The call, sctp_process_init(), can fail on memory allocation.  */
        if (!sctp_process_init(new_asoc, chunk->chunk_hdr->type,
                               sctp_source(chunk),
@@ -401,9 +406,6 @@ sctp_disposition_t sctp_sf_do_5_1B_init(const struct sctp_endpoint *ep,
                len = ntohs(err_chunk->chunk_hdr->length) -
                        sizeof(sctp_chunkhdr_t);
 
-       if (sctp_assoc_set_bind_addr_from_ep(new_asoc, GFP_ATOMIC) < 0)
-               goto nomem_init;
-
        repl = sctp_make_init_ack(new_asoc, chunk, GFP_ATOMIC, len);
        if (!repl)
                goto nomem_init;
@@ -1452,6 +1454,10 @@ static sctp_disposition_t sctp_sf_do_unexpected_init(
        if (!new_asoc)
                goto nomem;
 
+       if (sctp_assoc_set_bind_addr_from_ep(new_asoc,
+                               sctp_scope(sctp_source(chunk)), GFP_ATOMIC) < 0)
+               goto nomem;
+
        /* In the outbound INIT ACK the endpoint MUST copy its current
         * Verification Tag and Peers Verification tag into a reserved
         * place (local tie-tag and per tie-tag) within the state cookie.
@@ -1488,9 +1494,6 @@ static sctp_disposition_t sctp_sf_do_unexpected_init(
                        sizeof(sctp_chunkhdr_t);
        }
 
-       if (sctp_assoc_set_bind_addr_from_ep(new_asoc, GFP_ATOMIC) < 0)
-               goto nomem;
-
        repl = sctp_make_init_ack(new_asoc, chunk, GFP_ATOMIC, len);
        if (!repl)
                goto nomem;
index c8d05758661d96cf09c41f3babb983c4f2194ce9..3a95fcb17a9e35c715123316cb458efde2975157 100644 (file)
@@ -1080,6 +1080,13 @@ static int __sctp_connect(struct sock* sk,
                                err = -ENOMEM;
                                goto out_free;
                        }
+
+                       err = sctp_assoc_set_bind_addr_from_ep(asoc, scope,
+                                                             GFP_KERNEL);
+                       if (err < 0) {
+                               goto out_free;
+                       }
+
                }
 
                /* Prime the peer's transport structures.  */
@@ -1095,11 +1102,6 @@ static int __sctp_connect(struct sock* sk,
                walk_size += af->sockaddr_len;
        }
 
-       err = sctp_assoc_set_bind_addr_from_ep(asoc, GFP_KERNEL);
-       if (err < 0) {
-               goto out_free;
-       }
-
        /* In case the user of sctp_connectx() wants an association
         * id back, assign one now.
         */
@@ -1274,22 +1276,30 @@ SCTP_STATIC int sctp_setsockopt_connectx(struct sock* sk,
 }
 
 /*
- * New (hopefully final) interface for the API.  The option buffer is used
- * both for the returned association id and the addresses.
+ * New (hopefully final) interface for the API.
+ * We use the sctp_getaddrs_old structure so that use-space library
+ * can avoid any unnecessary allocations.   The only defferent part
+ * is that we store the actual length of the address buffer into the
+ * addrs_num structure member.  That way we can re-use the existing
+ * code.
  */
 SCTP_STATIC int sctp_getsockopt_connectx3(struct sock* sk, int len,
                                        char __user *optval,
                                        int __user *optlen)
 {
+       struct sctp_getaddrs_old param;
        sctp_assoc_t assoc_id = 0;
        int err = 0;
 
-       if (len < sizeof(assoc_id))
+       if (len < sizeof(param))
                return -EINVAL;
 
+       if (copy_from_user(&param, optval, sizeof(param)))
+               return -EFAULT;
+
        err = __sctp_setsockopt_connectx(sk,
-                       (struct sockaddr __user *)(optval + sizeof(assoc_id)),
-                       len - sizeof(assoc_id), &assoc_id);
+                       (struct sockaddr __user *)param.addrs,
+                       param.addr_num, &assoc_id);
 
        if (err == 0 || err == -EINPROGRESS) {
                if (copy_to_user(optval, &assoc_id, sizeof(assoc_id)))
@@ -1689,6 +1699,11 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
                        goto out_unlock;
                }
                asoc = new_asoc;
+               err = sctp_assoc_set_bind_addr_from_ep(asoc, scope, GFP_KERNEL);
+               if (err < 0) {
+                       err = -ENOMEM;
+                       goto out_free;
+               }
 
                /* If the SCTP_INIT ancillary data is specified, set all
                 * the association init values accordingly.
@@ -1718,11 +1733,6 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
                        err = -ENOMEM;
                        goto out_free;
                }
-               err = sctp_assoc_set_bind_addr_from_ep(asoc, GFP_KERNEL);
-               if (err < 0) {
-                       err = -ENOMEM;
-                       goto out_free;
-               }
        }
 
        /* ASSERT: we have a valid association at this point.  */
index c256e4839316b1cadc1480a8a6b482a306882a22..37a1184d789f7fe90408120fef731e76ed6088c4 100644 (file)
@@ -74,7 +74,7 @@ static struct sctp_transport *sctp_transport_init(struct sctp_transport *peer,
         * given destination transport address, set RTO to the protocol
         * parameter 'RTO.Initial'.
         */
-       peer->last_rto = peer->rto = msecs_to_jiffies(sctp_rto_initial);
+       peer->rto = msecs_to_jiffies(sctp_rto_initial);
        peer->rtt = 0;
        peer->rttvar = 0;
        peer->srtt = 0;
@@ -308,7 +308,8 @@ void sctp_transport_route(struct sctp_transport *transport,
                /* Initialize sk->sk_rcv_saddr, if the transport is the
                 * association's active path for getsockname().
                 */
-               if (asoc && (transport == asoc->peer.active_path))
+               if (asoc && (!asoc->peer.primary_path ||
+                               (transport == asoc->peer.active_path)))
                        opt->pf->af->to_sk_saddr(&transport->saddr,
                                                 asoc->base.sk);
        } else
@@ -385,7 +386,6 @@ void sctp_transport_update_rto(struct sctp_transport *tp, __u32 rtt)
                tp->rto = tp->asoc->rto_max;
 
        tp->rtt = rtt;
-       tp->last_rto = tp->rto;
 
        /* Reset rto_pending so that a new RTT measurement is started when a
         * new data chunk is sent.
@@ -601,7 +601,7 @@ void sctp_transport_reset(struct sctp_transport *t)
         */
        t->cwnd = min(4*asoc->pathmtu, max_t(__u32, 2*asoc->pathmtu, 4380));
        t->ssthresh = asoc->peer.i.a_rwnd;
-       t->last_rto = t->rto = asoc->rto_initial;
+       t->rto = asoc->rto_initial;
        t->rtt = 0;
        t->srtt = 0;
        t->rttvar = 0;
index 22e8fd89477fd70894ff15d412d30ccf135f8acf..c7450c8f0a7c040ac756bfd28220152e9d3713b8 100644 (file)
@@ -306,24 +306,25 @@ EXPORT_SYMBOL_GPL(rpc_sockaddr2uaddr);
  * @sap: buffer into which to plant socket address
  * @salen: size of buffer
  *
+ * @uaddr does not have to be '\0'-terminated, but strict_strtoul() and
+ * rpc_pton() require proper string termination to be successful.
+ *
  * Returns the size of the socket address if successful; otherwise
  * zero is returned.
  */
 size_t rpc_uaddr2sockaddr(const char *uaddr, const size_t uaddr_len,
                          struct sockaddr *sap, const size_t salen)
 {
-       char *c, buf[RPCBIND_MAXUADDRLEN];
+       char *c, buf[RPCBIND_MAXUADDRLEN + sizeof('\0')];
        unsigned long portlo, porthi;
        unsigned short port;
 
-       if (uaddr_len > sizeof(buf))
+       if (uaddr_len > RPCBIND_MAXUADDRLEN)
                return 0;
 
        memcpy(buf, uaddr, uaddr_len);
 
-       buf[uaddr_len] = '\n';
-       buf[uaddr_len + 1] = '\0';
-
+       buf[uaddr_len] = '\0';
        c = strrchr(buf, '.');
        if (unlikely(c == NULL))
                return 0;
@@ -332,9 +333,7 @@ size_t rpc_uaddr2sockaddr(const char *uaddr, const size_t uaddr_len,
        if (unlikely(portlo > 255))
                return 0;
 
-       c[0] = '\n';
-       c[1] = '\0';
-
+       *c = '\0';
        c = strrchr(buf, '.');
        if (unlikely(c == NULL))
                return 0;
@@ -345,8 +344,7 @@ size_t rpc_uaddr2sockaddr(const char *uaddr, const size_t uaddr_len,
 
        port = (unsigned short)((porthi << 8) | portlo);
 
-       c[0] = '\0';
-
+       *c = '\0';
        if (rpc_pton(buf, strlen(buf), sap, salen) == 0)
                return 0;
 
index dd2e3d39d4c1ba941f58c0e676cb52fc6bac93a4..fe555e819bf84e298891e4717dd0a6f06bef715c 100644 (file)
@@ -217,7 +217,7 @@ struct data data_insert_at_marker(struct data d, struct marker *m,
        return d;
 }
 
-struct data data_append_markers(struct data d, struct marker *m)
+static struct data data_append_markers(struct data d, struct marker *m)
 {
        struct marker **mp = &d.markers;
 
index 44dbfd3f097650c139476571348655066a1006c2..a627bbee91d42d5acf6d59558b44d70d582397ce 100644 (file)
@@ -18,7 +18,7 @@
  *                                                                   USA
  */
 
-%option noyywrap nounput yylineno
+%option noyywrap noinput nounput yylineno
 
 %x INCLUDE
 %x BYTESTRING
index ac392cb040f613bb62b508ea27e712283459c40f..e27cc636e326ed58c92bd122c15c272b48414610 100644 (file)
@@ -9,7 +9,7 @@
 #define FLEX_SCANNER
 #define YY_FLEX_MAJOR_VERSION 2
 #define YY_FLEX_MINOR_VERSION 5
-#define YY_FLEX_SUBMINOR_VERSION 34
+#define YY_FLEX_SUBMINOR_VERSION 35
 #if YY_FLEX_SUBMINOR_VERSION > 0
 #define FLEX_BETA
 #endif
@@ -54,7 +54,6 @@ typedef int flex_int32_t;
 typedef unsigned char flex_uint8_t; 
 typedef unsigned short int flex_uint16_t;
 typedef unsigned int flex_uint32_t;
-#endif /* ! C99 */
 
 /* Limits of integral types. */
 #ifndef INT8_MIN
@@ -85,6 +84,8 @@ typedef unsigned int flex_uint32_t;
 #define UINT32_MAX             (4294967295U)
 #endif
 
+#endif /* ! C99 */
+
 #endif /* ! FLEXINT_H */
 
 #ifdef __cplusplus
@@ -141,7 +142,15 @@ typedef unsigned int flex_uint32_t;
 
 /* Size of default input buffer. */
 #ifndef YY_BUF_SIZE
+#ifdef __ia64__
+/* On IA-64, the buffer size is 16k, not 8k.
+ * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case.
+ * Ditto for the __ia64__ case accordingly.
+ */
+#define YY_BUF_SIZE 32768
+#else
 #define YY_BUF_SIZE 16384
+#endif /* __ia64__ */
 #endif
 
 /* The state buf must be large enough to hold one state per character in the main buffer.
@@ -192,13 +201,6 @@ extern FILE *yyin, *yyout;
 
 #define unput(c) yyunput( c, (yytext_ptr)  )
 
-/* The following is because we cannot portably get our hands on size_t
- * (without autoconf's help, which isn't available because we want
- * flex-generated scanners to compile on their own).
- * Given that the standard has decreed that size_t exists since 1989,
- * I guess we can afford to depend on it. Manoj.
- */
-
 #ifndef YY_TYPEDEF_YY_SIZE_T
 #define YY_TYPEDEF_YY_SIZE_T
 typedef size_t yy_size_t;
@@ -604,6 +606,7 @@ char *yytext;
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
  *                                                                   USA
  */
+#define YY_NO_INPUT 1
 
 
 
@@ -634,7 +637,7 @@ static int dts_version; /* = 0 */
 
 static void push_input_file(const char *filename);
 static int pop_input_file(void);
-#line 638 "dtc-lexer.lex.c"
+#line 641 "dtc-lexer.lex.c"
 
 #define INITIAL 0
 #define INCLUDE 1
@@ -656,6 +659,35 @@ static int pop_input_file(void);
 
 static int yy_init_globals (void );
 
+/* Accessor methods to globals.
+   These are made visible to non-reentrant scanners for convenience. */
+
+int yylex_destroy (void );
+
+int yyget_debug (void );
+
+void yyset_debug (int debug_flag  );
+
+YY_EXTRA_TYPE yyget_extra (void );
+
+void yyset_extra (YY_EXTRA_TYPE user_defined  );
+
+FILE *yyget_in (void );
+
+void yyset_in  (FILE * in_str  );
+
+FILE *yyget_out (void );
+
+void yyset_out  (FILE * out_str  );
+
+int yyget_leng (void );
+
+char *yyget_text (void );
+
+int yyget_lineno (void );
+
+void yyset_lineno (int line_number  );
+
 /* Macros after this point can all be overridden by user definitions in
  * section 1.
  */
@@ -688,7 +720,12 @@ static int input (void );
 
 /* Amount of stuff to slurp up with each read. */
 #ifndef YY_READ_BUF_SIZE
+#ifdef __ia64__
+/* On IA-64, the buffer size is 16k, not 8k */
+#define YY_READ_BUF_SIZE 16384
+#else
 #define YY_READ_BUF_SIZE 8192
+#endif /* __ia64__ */
 #endif
 
 /* Copy whatever the last rule matched to the standard output. */
@@ -696,7 +733,7 @@ static int input (void );
 /* This used to be an fputs(), but since the string might contain NUL's,
  * we now use fwrite().
  */
-#define ECHO fwrite( yytext, yyleng, 1, yyout )
+#define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0)
 #endif
 
 /* Gets input and stuffs it into "buf".  number of characters read, or YY_NULL,
@@ -707,7 +744,7 @@ static int input (void );
        if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
                { \
                int c = '*'; \
-               int n; \
+               size_t n; \
                for ( n = 0; n < max_size && \
                             (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
                        buf[n] = (char) c; \
@@ -791,7 +828,7 @@ YY_DECL
     
 #line 64 "dtc-lexer.l"
 
-#line 795 "dtc-lexer.lex.c"
+#line 832 "dtc-lexer.lex.c"
 
        if ( !(yy_init) )
                {
@@ -1116,7 +1153,7 @@ YY_RULE_SETUP
 #line 222 "dtc-lexer.l"
 ECHO;
        YY_BREAK
-#line 1120 "dtc-lexer.lex.c"
+#line 1157 "dtc-lexer.lex.c"
 
        case YY_END_OF_BUFFER:
                {
@@ -1840,8 +1877,8 @@ YY_BUFFER_STATE yy_scan_string (yyconst char * yystr )
 
 /** Setup the input buffer state to scan the given bytes. The next call to yylex() will
  * scan from a @e copy of @a bytes.
- * @param bytes the byte buffer to scan
- * @param len the number of bytes in the buffer pointed to by @a bytes.
+ * @param yybytes the byte buffer to scan
+ * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes.
  * 
  * @return the newly allocated buffer state object.
  */
index fbbba44fcd0d0ccd798b763c364df7b79aa66a72..22e692919ff9ccba391480514c66ff3e86f62c58 100644 (file)
@@ -411,7 +411,7 @@ int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle)
                                             &phandle, sizeof(phandle));
 }
 
-int _stringlist_contains(const char *strlist, int listlen, const char *str)
+static int _stringlist_contains(const char *strlist, int listlen, const char *str)
 {
        int len = strlen(str);
        const char *p;
index ebeb6eb27907db69cd113ba0de8fa9dfd856d25f..1521ff11bb972ed4c1d376b4baf0da38cd17bcf0 100644 (file)
@@ -52,7 +52,7 @@ static void write_prefix(FILE *f, int level)
                fputc('\t', f);
 }
 
-int isstring(char c)
+static int isstring(char c)
 {
        return (isprint(c)
                || (c == '\0')
index 971e0113ae7a9a52e384df3cb5b51d6be276f8fb..287467a2e8c7afe3334105e6adf61afbe75a87cb 100644 (file)
@@ -1,4 +1,4 @@
-/* ANSI-C code produced by gperf version 3.0.2 */
+/* ANSI-C code produced by gperf version 3.0.3 */
 /* Command-line: gperf -L ANSI-C -a -C -E -g -H is_reserved_hash -k '1,3,$' -N is_reserved_word -p -t scripts/genksyms/keywords.gperf  */
 
 #if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
@@ -30,7 +30,9 @@
 
 #line 1 "scripts/genksyms/keywords.gperf"
 
-#line 3 "scripts/genksyms/keywords.gperf"
+struct resword;
+static const struct resword *is_reserved_word(register const char *str, register unsigned int len);
+#line 5 "scripts/genksyms/keywords.gperf"
 struct resword { const char *name; int token; };
 /* maximum key range = 62, duplicates = 0 */
 
@@ -78,6 +80,9 @@ is_reserved_hash (register const char *str, register unsigned int len)
 
 #ifdef __GNUC__
 __inline
+#ifdef __GNUC_STDC_INLINE__
+__attribute__ ((__gnu_inline__))
+#endif
 #endif
 const struct resword *
 is_reserved_word (register const char *str, register unsigned int len)
@@ -94,105 +99,105 @@ is_reserved_word (register const char *str, register unsigned int len)
   static const struct resword wordlist[] =
     {
       {""}, {""}, {""},
-#line 26 "scripts/genksyms/keywords.gperf"
+#line 28 "scripts/genksyms/keywords.gperf"
       {"asm", ASM_KEYW},
       {""},
-#line 8 "scripts/genksyms/keywords.gperf"
+#line 10 "scripts/genksyms/keywords.gperf"
       {"__asm", ASM_KEYW},
       {""},
-#line 9 "scripts/genksyms/keywords.gperf"
+#line 11 "scripts/genksyms/keywords.gperf"
       {"__asm__", ASM_KEYW},
       {""}, {""},
-#line 52 "scripts/genksyms/keywords.gperf"
+#line 54 "scripts/genksyms/keywords.gperf"
       {"__typeof__", TYPEOF_KEYW},
       {""},
-#line 12 "scripts/genksyms/keywords.gperf"
+#line 14 "scripts/genksyms/keywords.gperf"
       {"__const", CONST_KEYW},
-#line 11 "scripts/genksyms/keywords.gperf"
-      {"__attribute__", ATTRIBUTE_KEYW},
 #line 13 "scripts/genksyms/keywords.gperf"
+      {"__attribute__", ATTRIBUTE_KEYW},
+#line 15 "scripts/genksyms/keywords.gperf"
       {"__const__", CONST_KEYW},
-#line 18 "scripts/genksyms/keywords.gperf"
+#line 20 "scripts/genksyms/keywords.gperf"
       {"__signed__", SIGNED_KEYW},
-#line 44 "scripts/genksyms/keywords.gperf"
+#line 46 "scripts/genksyms/keywords.gperf"
       {"static", STATIC_KEYW},
-#line 20 "scripts/genksyms/keywords.gperf"
+#line 22 "scripts/genksyms/keywords.gperf"
       {"__volatile__", VOLATILE_KEYW},
-#line 39 "scripts/genksyms/keywords.gperf"
+#line 41 "scripts/genksyms/keywords.gperf"
       {"int", INT_KEYW},
-#line 32 "scripts/genksyms/keywords.gperf"
+#line 34 "scripts/genksyms/keywords.gperf"
       {"char", CHAR_KEYW},
-#line 33 "scripts/genksyms/keywords.gperf"
+#line 35 "scripts/genksyms/keywords.gperf"
       {"const", CONST_KEYW},
-#line 45 "scripts/genksyms/keywords.gperf"
+#line 47 "scripts/genksyms/keywords.gperf"
       {"struct", STRUCT_KEYW},
-#line 24 "scripts/genksyms/keywords.gperf"
+#line 26 "scripts/genksyms/keywords.gperf"
       {"__restrict__", RESTRICT_KEYW},
-#line 25 "scripts/genksyms/keywords.gperf"
+#line 27 "scripts/genksyms/keywords.gperf"
       {"restrict", RESTRICT_KEYW},
-#line 23 "scripts/genksyms/keywords.gperf"
+#line 25 "scripts/genksyms/keywords.gperf"
       {"_restrict", RESTRICT_KEYW},
-#line 16 "scripts/genksyms/keywords.gperf"
+#line 18 "scripts/genksyms/keywords.gperf"
       {"__inline__", INLINE_KEYW},
-#line 10 "scripts/genksyms/keywords.gperf"
+#line 12 "scripts/genksyms/keywords.gperf"
       {"__attribute", ATTRIBUTE_KEYW},
       {""},
-#line 14 "scripts/genksyms/keywords.gperf"
+#line 16 "scripts/genksyms/keywords.gperf"
       {"__extension__", EXTENSION_KEYW},
-#line 35 "scripts/genksyms/keywords.gperf"
+#line 37 "scripts/genksyms/keywords.gperf"
       {"enum", ENUM_KEYW},
-#line 19 "scripts/genksyms/keywords.gperf"
+#line 21 "scripts/genksyms/keywords.gperf"
       {"__volatile", VOLATILE_KEYW},
-#line 36 "scripts/genksyms/keywords.gperf"
+#line 38 "scripts/genksyms/keywords.gperf"
       {"extern", EXTERN_KEYW},
       {""},
-#line 17 "scripts/genksyms/keywords.gperf"
+#line 19 "scripts/genksyms/keywords.gperf"
       {"__signed", SIGNED_KEYW},
-#line 7 "scripts/genksyms/keywords.gperf"
+#line 9 "scripts/genksyms/keywords.gperf"
       {"EXPORT_SYMBOL_GPL_FUTURE", EXPORT_SYMBOL_KEYW},
       {""},
-#line 51 "scripts/genksyms/keywords.gperf"
+#line 53 "scripts/genksyms/keywords.gperf"
       {"typeof", TYPEOF_KEYW},
-#line 46 "scripts/genksyms/keywords.gperf"
+#line 48 "scripts/genksyms/keywords.gperf"
       {"typedef", TYPEDEF_KEYW},
-#line 15 "scripts/genksyms/keywords.gperf"
+#line 17 "scripts/genksyms/keywords.gperf"
       {"__inline", INLINE_KEYW},
-#line 31 "scripts/genksyms/keywords.gperf"
+#line 33 "scripts/genksyms/keywords.gperf"
       {"auto", AUTO_KEYW},
-#line 47 "scripts/genksyms/keywords.gperf"
+#line 49 "scripts/genksyms/keywords.gperf"
       {"union", UNION_KEYW},
       {""}, {""},
-#line 48 "scripts/genksyms/keywords.gperf"
+#line 50 "scripts/genksyms/keywords.gperf"
       {"unsigned", UNSIGNED_KEYW},
-#line 49 "scripts/genksyms/keywords.gperf"
+#line 51 "scripts/genksyms/keywords.gperf"
       {"void", VOID_KEYW},
-#line 42 "scripts/genksyms/keywords.gperf"
+#line 44 "scripts/genksyms/keywords.gperf"
       {"short", SHORT_KEYW},
       {""}, {""},
-#line 50 "scripts/genksyms/keywords.gperf"
+#line 52 "scripts/genksyms/keywords.gperf"
       {"volatile", VOLATILE_KEYW},
       {""},
-#line 37 "scripts/genksyms/keywords.gperf"
+#line 39 "scripts/genksyms/keywords.gperf"
       {"float", FLOAT_KEYW},
-#line 34 "scripts/genksyms/keywords.gperf"
+#line 36 "scripts/genksyms/keywords.gperf"
       {"double", DOUBLE_KEYW},
       {""},
-#line 5 "scripts/genksyms/keywords.gperf"
+#line 7 "scripts/genksyms/keywords.gperf"
       {"EXPORT_SYMBOL", EXPORT_SYMBOL_KEYW},
       {""}, {""},
-#line 38 "scripts/genksyms/keywords.gperf"
+#line 40 "scripts/genksyms/keywords.gperf"
       {"inline", INLINE_KEYW},
-#line 6 "scripts/genksyms/keywords.gperf"
+#line 8 "scripts/genksyms/keywords.gperf"
       {"EXPORT_SYMBOL_GPL", EXPORT_SYMBOL_KEYW},
-#line 41 "scripts/genksyms/keywords.gperf"
+#line 43 "scripts/genksyms/keywords.gperf"
       {"register", REGISTER_KEYW},
       {""},
-#line 22 "scripts/genksyms/keywords.gperf"
+#line 24 "scripts/genksyms/keywords.gperf"
       {"_Bool", BOOL_KEYW},
-#line 43 "scripts/genksyms/keywords.gperf"
+#line 45 "scripts/genksyms/keywords.gperf"
       {"signed", SIGNED_KEYW},
       {""}, {""},
-#line 40 "scripts/genksyms/keywords.gperf"
+#line 42 "scripts/genksyms/keywords.gperf"
       {"long", LONG_KEYW}
     };
 
index 5ef3733225fb9831e6d9907ab6ff0f0ebc903e52..8fe977a4d57b7ada0480074e91ed01b298c61dc2 100644 (file)
@@ -1,4 +1,6 @@
 %{
+struct resword;
+static const struct resword *is_reserved_word(register const char *str, register unsigned int len);
 %}
 struct resword { const char *name; int token; }
 %%
index 6d69c7ccdcc788519efc06297678cfc50f9082d0..80599e3a7994107cfa06f04e6a70c2d3ff2acbda 100644 (file)
@@ -30,7 +30,7 @@ silentoldconfig: $(obj)/conf
        $< -s $(Kconfig)
 
 localmodconfig: $(obj)/streamline_config.pl $(obj)/conf
-       $(Q)perl $< $(Kconfig) > .tmp.config
+       $(Q)perl $< $(srctree) $(Kconfig) > .tmp.config
        $(Q)if [ -f .config ]; then                             \
                        cmp -s .tmp.config .config ||           \
                        (mv -f .config .config.old.1;           \
@@ -44,7 +44,7 @@ localmodconfig: $(obj)/streamline_config.pl $(obj)/conf
        $(Q)rm -f .tmp.config
 
 localyesconfig: $(obj)/streamline_config.pl $(obj)/conf
-       $(Q)perl $< $(Kconfig) > .tmp.config
+       $(Q)perl $< $(srctree) $(Kconfig) > .tmp.config
        $(Q)sed -i s/=m/=y/ .tmp.config
        $(Q)if [ -f .config ]; then                             \
                        cmp -s .tmp.config .config ||           \
index dc3e81807d13a41c18df6d20ce8c466e566e9853..fdc7113b08d112ae5db2c2a6a93dae5ca44ef065 100644 (file)
@@ -160,7 +160,15 @@ typedef unsigned int flex_uint32_t;
 
 /* Size of default input buffer. */
 #ifndef YY_BUF_SIZE
+#ifdef __ia64__
+/* On IA-64, the buffer size is 16k, not 8k.
+ * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case.
+ * Ditto for the __ia64__ case accordingly.
+ */
+#define YY_BUF_SIZE 32768
+#else
 #define YY_BUF_SIZE 16384
+#endif /* __ia64__ */
 #endif
 
 /* The state buf must be large enough to hold one state per character in the main buffer.
@@ -802,7 +810,7 @@ static int last_ts, first_ts;
 static void zconf_endhelp(void);
 static void zconf_endfile(void);
 
-void new_string(void)
+static void new_string(void)
 {
        text = malloc(START_STRSIZE);
        text_asize = START_STRSIZE;
@@ -810,7 +818,7 @@ void new_string(void)
        *text = 0;
 }
 
-void append_string(const char *str, int size)
+static void append_string(const char *str, int size)
 {
        int new_size = text_size + size + 1;
        if (new_size > text_asize) {
@@ -824,7 +832,7 @@ void append_string(const char *str, int size)
        text[text_size] = 0;
 }
 
-void alloc_string(const char *str, int size)
+static void alloc_string(const char *str, int size)
 {
        text = malloc(size + 1);
        memcpy(text, str, size);
@@ -914,7 +922,12 @@ static int input (void );
 
 /* Amount of stuff to slurp up with each read. */
 #ifndef YY_READ_BUF_SIZE
+#ifdef __ia64__
+/* On IA-64, the buffer size is 16k, not 8k */
+#define YY_READ_BUF_SIZE 16384
+#else
 #define YY_READ_BUF_SIZE 8192
+#endif /* __ia64__ */
 #endif
 
 /* Copy whatever the last rule matched to the standard output. */
@@ -922,7 +935,7 @@ static int input (void );
 /* This used to be an fputs(), but since the string might contain NUL's,
  * we now use fwrite().
  */
-#define ECHO fwrite( zconftext, zconfleng, 1, zconfout )
+#define ECHO do { if (fwrite( zconftext, zconfleng, 1, zconfout )) {} } while (0)
 #endif
 
 /* Gets input and stuffs it into "buf".  number of characters read, or YY_NULL,
@@ -2060,8 +2073,8 @@ YY_BUFFER_STATE zconf_scan_string (yyconst char * yystr )
 
 /** Setup the input buffer state to scan the given bytes. The next call to zconflex() will
  * scan from a @e copy of @a bytes.
- * @param bytes the byte buffer to scan
- * @param len the number of bytes in the buffer pointed to by @a bytes.
+ * @param yybytes the byte buffer to scan
+ * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes.
  * 
  * @return the newly allocated buffer state object.
  */
index 95984db8e1e097264d386910ca8d091bc5294a45..0d800820c3cd72d6408079b6dbdec96eac954515 100644 (file)
@@ -43,7 +43,6 @@
 #    make oldconfig
 #
 my $config = ".config";
-my $linuxpath = ".";
 
 my $uname = `uname -r`;
 chomp $uname;
@@ -111,7 +110,11 @@ sub find_config {
 
 find_config;
 
-my @makefiles = `find $linuxpath -name Makefile`;
+# Get the build source and top level Kconfig file (passed in)
+my $ksource = $ARGV[0];
+my $kconfig = $ARGV[1];
+
+my @makefiles = `find $ksource -name Makefile`;
 my %depends;
 my %selects;
 my %prompts;
@@ -119,9 +122,6 @@ my %objects;
 my $var;
 my $cont = 0;
 
-# Get the top level Kconfig file (passed in)
-my $kconfig = $ARGV[0];
-
 # prevent recursion
 my %read_kconfigs;
 
@@ -132,7 +132,7 @@ sub read_kconfig {
     my $config;
     my @kconfigs;
 
-    open(KIN, $kconfig) || die "Can't open $kconfig";
+    open(KIN, "$ksource/$kconfig") || die "Can't open $kconfig";
     while (<KIN>) {
        chomp;
 
index 25ef5d01c0afa961a4b5c57c0154d11b83f69e7f..d8bc7424962296f2370cba1e9a594bf9de04f6d6 100644 (file)
@@ -9,6 +9,8 @@
 
 struct kconf_id;
 
+static struct kconf_id *kconf_id_lookup(register const char *str, register unsigned int len);
+
 %%
 mainmenu,      T_MAINMENU,     TF_COMMAND
 menu,          T_MENU,         TF_COMMAND
index 5c73d51339d81b30e88cdd1010d65f273f2e62e1..c1748faf46340525706f0f25f867ffa01c3f9b19 100644 (file)
@@ -30,6 +30,8 @@
 #endif
 
 struct kconf_id;
+
+static struct kconf_id *kconf_id_lookup(register const char *str, register unsigned int len);
 /* maximum key range = 47, duplicates = 0 */
 
 #ifdef __GNUC__
index 21ff69c9ad4e846b3c409216a86434e587b22989..d8f7236cb0a376e91a0254882cdcd17d1ee91c9b 100644 (file)
@@ -39,7 +39,7 @@ static int last_ts, first_ts;
 static void zconf_endhelp(void);
 static void zconf_endfile(void);
 
-void new_string(void)
+static void new_string(void)
 {
        text = malloc(START_STRSIZE);
        text_asize = START_STRSIZE;
@@ -47,7 +47,7 @@ void new_string(void)
        *text = 0;
 }
 
-void append_string(const char *str, int size)
+static void append_string(const char *str, int size)
 {
        int new_size = text_size + size + 1;
        if (new_size > text_asize) {
@@ -61,7 +61,7 @@ void append_string(const char *str, int size)
        text[text_size] = 0;
 }
 
-void alloc_string(const char *str, int size)
+static void alloc_string(const char *str, int size)
 {
        text = malloc(size + 1);
        memcpy(text, str, size);
index 95df833b5a9d172d6a03dd682ded3513ff795017..6e9dcd59aa87c5cc53378b9a789aad92fdf1d5f6 100644 (file)
@@ -1,24 +1,23 @@
-/* A Bison parser, made by GNU Bison 2.3.  */
 
-/* Skeleton implementation for Bison's Yacc-like parsers in C
+/* A Bison parser, made by GNU Bison 2.4.1.  */
 
-   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+/* Skeleton implementation for Bison's Yacc-like parsers in C
+   
+      Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
    Free Software Foundation, Inc.
-
-   This program is free software; you can redistribute it and/or modify
+   
+   This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2, or (at your option)
-   any later version.
-
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+   
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
-
+   
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin Street, Fifth Floor,
-   Boston, MA 02110-1301, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 /* As a special exception, you may create a larger work that contains
    part or all of the Bison parser skeleton and distribute that work
@@ -29,7 +28,7 @@
    special exception, which will cause the skeleton and the resulting
    Bison output files to be licensed under the GNU General Public
    License without this special exception.
-
+   
    This special exception was added by the Free Software Foundation in
    version 2.2 of Bison.  */
 
@@ -47,7 +46,7 @@
 #define YYBISON 1
 
 /* Bison version.  */
-#define YYBISON_VERSION "2.3"
+#define YYBISON_VERSION "2.4.1"
 
 /* Skeleton name.  */
 #define YYSKELETON_NAME "yacc.c"
 /* Pure parsers.  */
 #define YYPURE 0
 
+/* Push parsers.  */
+#define YYPUSH 0
+
+/* Pull parsers.  */
+#define YYPULL 1
+
 /* Using locations.  */
 #define YYLSP_NEEDED 0
 
 /* Substitute the variable and function names.  */
-#define yyparse zconfparse
-#define yylex   zconflex
-#define yyerror zconferror
-#define yylval  zconflval
-#define yychar  zconfchar
-#define yydebug zconfdebug
-#define yynerrs zconfnerrs
-
-
-/* Tokens.  */
-#ifndef YYTOKENTYPE
-# define YYTOKENTYPE
-   /* Put the tokens into the symbol table, so that GDB and other debuggers
-      know about them.  */
-   enum yytokentype {
-     T_MAINMENU = 258,
-     T_MENU = 259,
-     T_ENDMENU = 260,
-     T_SOURCE = 261,
-     T_CHOICE = 262,
-     T_ENDCHOICE = 263,
-     T_COMMENT = 264,
-     T_CONFIG = 265,
-     T_MENUCONFIG = 266,
-     T_HELP = 267,
-     T_HELPTEXT = 268,
-     T_IF = 269,
-     T_ENDIF = 270,
-     T_DEPENDS = 271,
-     T_OPTIONAL = 272,
-     T_PROMPT = 273,
-     T_TYPE = 274,
-     T_DEFAULT = 275,
-     T_SELECT = 276,
-     T_RANGE = 277,
-     T_OPTION = 278,
-     T_ON = 279,
-     T_WORD = 280,
-     T_WORD_QUOTE = 281,
-     T_UNEQUAL = 282,
-     T_CLOSE_PAREN = 283,
-     T_OPEN_PAREN = 284,
-     T_EOL = 285,
-     T_OR = 286,
-     T_AND = 287,
-     T_EQUAL = 288,
-     T_NOT = 289
-   };
-#endif
-/* Tokens.  */
-#define T_MAINMENU 258
-#define T_MENU 259
-#define T_ENDMENU 260
-#define T_SOURCE 261
-#define T_CHOICE 262
-#define T_ENDCHOICE 263
-#define T_COMMENT 264
-#define T_CONFIG 265
-#define T_MENUCONFIG 266
-#define T_HELP 267
-#define T_HELPTEXT 268
-#define T_IF 269
-#define T_ENDIF 270
-#define T_DEPENDS 271
-#define T_OPTIONAL 272
-#define T_PROMPT 273
-#define T_TYPE 274
-#define T_DEFAULT 275
-#define T_SELECT 276
-#define T_RANGE 277
-#define T_OPTION 278
-#define T_ON 279
-#define T_WORD 280
-#define T_WORD_QUOTE 281
-#define T_UNEQUAL 282
-#define T_CLOSE_PAREN 283
-#define T_OPEN_PAREN 284
-#define T_EOL 285
-#define T_OR 286
-#define T_AND 287
-#define T_EQUAL 288
-#define T_NOT 289
-
-
+#define yyparse         zconfparse
+#define yylex           zconflex
+#define yyerror         zconferror
+#define yylval          zconflval
+#define yychar          zconfchar
+#define yydebug         zconfdebug
+#define yynerrs         zconfnerrs
 
 
 /* Copy the first part of user declarations.  */
 #define LKC_DIRECT_LINK
 #include "lkc.h"
 
-#include "zconf.hash.c"
-
 #define printd(mask, fmt...) if (cdebug & (mask)) printf(fmt)
 
 #define PRINTD         0x0001
@@ -188,6 +114,7 @@ static struct menu *current_menu, *current_entry;
 #endif
 
 
+
 /* Enabling traces.  */
 #ifndef YYDEBUG
 # define YYDEBUG 0
@@ -206,31 +133,77 @@ static struct menu *current_menu, *current_entry;
 # define YYTOKEN_TABLE 0
 #endif
 
+
+/* Tokens.  */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+   /* Put the tokens into the symbol table, so that GDB and other debuggers
+      know about them.  */
+   enum yytokentype {
+     T_MAINMENU = 258,
+     T_MENU = 259,
+     T_ENDMENU = 260,
+     T_SOURCE = 261,
+     T_CHOICE = 262,
+     T_ENDCHOICE = 263,
+     T_COMMENT = 264,
+     T_CONFIG = 265,
+     T_MENUCONFIG = 266,
+     T_HELP = 267,
+     T_HELPTEXT = 268,
+     T_IF = 269,
+     T_ENDIF = 270,
+     T_DEPENDS = 271,
+     T_OPTIONAL = 272,
+     T_PROMPT = 273,
+     T_TYPE = 274,
+     T_DEFAULT = 275,
+     T_SELECT = 276,
+     T_RANGE = 277,
+     T_OPTION = 278,
+     T_ON = 279,
+     T_WORD = 280,
+     T_WORD_QUOTE = 281,
+     T_UNEQUAL = 282,
+     T_CLOSE_PAREN = 283,
+     T_OPEN_PAREN = 284,
+     T_EOL = 285,
+     T_OR = 286,
+     T_AND = 287,
+     T_EQUAL = 288,
+     T_NOT = 289
+   };
+#endif
+
+
+
 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
 typedef union YYSTYPE
-
 {
+
+
        char *string;
        struct file *file;
        struct symbol *symbol;
        struct expr *expr;
        struct menu *menu;
        struct kconf_id *id;
-}
-/* Line 187 of yacc.c.  */
 
-       YYSTYPE;
+
+
+} YYSTYPE;
+# define YYSTYPE_IS_TRIVIAL 1
 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
 # define YYSTYPE_IS_DECLARED 1
-# define YYSTYPE_IS_TRIVIAL 1
 #endif
 
 
-
 /* Copy the second part of user declarations.  */
 
 
-/* Line 216 of yacc.c.  */
+/* Include zconf.hash.c here so it can see the token constants. */
+#include "zconf.hash.c"
+
 
 
 #ifdef short
@@ -306,14 +279,14 @@ typedef short int yytype_int16;
 #if (defined __STDC__ || defined __C99__FUNC__ \
      || defined __cplusplus || defined _MSC_VER)
 static int
-YYID (int i)
+YYID (int yyi)
 #else
 static int
-YYID (i)
-    int i;
+YYID (yyi)
+    int yyi;
 #endif
 {
-  return i;
+  return yyi;
 }
 #endif
 
@@ -394,9 +367,9 @@ void free (void *); /* INFRINGES ON USER NAME SPACE */
 /* A type that is properly aligned for any stack member.  */
 union yyalloc
 {
-  yytype_int16 yyss;
-  YYSTYPE yyvs;
-  };
+  yytype_int16 yyss_alloc;
+  YYSTYPE yyvs_alloc;
+};
 
 /* The size of the maximum gap between one aligned stack and the next.  */
 # define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
@@ -430,12 +403,12 @@ union yyalloc
    elements in the stack, and YYPTR gives the new location of the
    stack.  Advance YYPTR to a properly aligned location for the next
    stack.  */
-# define YYSTACK_RELOCATE(Stack)                                       \
+# define YYSTACK_RELOCATE(Stack_alloc, Stack)                          \
     do                                                                 \
       {                                                                        \
        YYSIZE_T yynewbytes;                                            \
-       YYCOPY (&yyptr->Stack, Stack, yysize);                          \
-       Stack = &yyptr->Stack;                                          \
+       YYCOPY (&yyptr->Stack_alloc, Stack, yysize);                    \
+       Stack = &yyptr->Stack_alloc;                                    \
        yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
        yyptr += yynewbytes / sizeof (*yyptr);                          \
       }                                                                        \
@@ -558,18 +531,18 @@ static const yytype_int8 yyrhs[] =
 /* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
 static const yytype_uint16 yyrline[] =
 {
-       0,   104,   104,   106,   108,   109,   110,   111,   112,   113,
-     114,   118,   122,   122,   122,   122,   122,   122,   122,   126,
-     127,   128,   129,   130,   131,   135,   136,   142,   150,   156,
-     164,   174,   176,   177,   178,   179,   180,   181,   184,   192,
-     198,   208,   214,   220,   223,   225,   236,   237,   242,   251,
-     256,   264,   267,   269,   270,   271,   272,   273,   276,   282,
-     293,   299,   309,   311,   316,   324,   332,   335,   337,   338,
-     339,   344,   351,   356,   364,   367,   369,   370,   371,   374,
-     382,   389,   396,   402,   409,   411,   412,   413,   416,   424,
-     426,   431,   432,   435,   436,   437,   441,   442,   445,   446,
-     449,   450,   451,   452,   453,   454,   455,   458,   459,   462,
-     463
+       0,   107,   107,   109,   111,   112,   113,   114,   115,   116,
+     117,   121,   125,   125,   125,   125,   125,   125,   125,   129,
+     130,   131,   132,   133,   134,   138,   139,   145,   153,   159,
+     167,   177,   179,   180,   181,   182,   183,   184,   187,   195,
+     201,   211,   217,   223,   226,   228,   239,   240,   245,   254,
+     259,   267,   270,   272,   273,   274,   275,   276,   279,   285,
+     296,   302,   312,   314,   319,   327,   335,   338,   340,   341,
+     342,   347,   354,   359,   367,   370,   372,   373,   374,   377,
+     385,   392,   399,   405,   412,   414,   415,   416,   419,   427,
+     429,   434,   435,   438,   439,   440,   444,   445,   448,   449,
+     452,   453,   454,   455,   456,   457,   458,   461,   462,   465,
+     466
 };
 #endif
 
@@ -985,17 +958,20 @@ yy_symbol_print (yyoutput, yytype, yyvaluep)
 #if (defined __STDC__ || defined __C99__FUNC__ \
      || defined __cplusplus || defined _MSC_VER)
 static void
-yy_stack_print (yytype_int16 *bottom, yytype_int16 *top)
+yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop)
 #else
 static void
-yy_stack_print (bottom, top)
-    yytype_int16 *bottom;
-    yytype_int16 *top;
+yy_stack_print (yybottom, yytop)
+    yytype_int16 *yybottom;
+    yytype_int16 *yytop;
 #endif
 {
   YYFPRINTF (stderr, "Stack now");
-  for (; bottom <= top; ++bottom)
-    YYFPRINTF (stderr, " %d", *bottom);
+  for (; yybottom <= yytop; yybottom++)
+    {
+      int yybot = *yybottom;
+      YYFPRINTF (stderr, " %d", yybot);
+    }
   YYFPRINTF (stderr, "\n");
 }
 
@@ -1029,11 +1005,11 @@ yy_reduce_print (yyvsp, yyrule)
   /* The symbols being reduced.  */
   for (yyi = 0; yyi < yynrhs; yyi++)
     {
-      fprintf (stderr, "   $%d = ", yyi + 1);
+      YYFPRINTF (stderr, "   $%d = ", yyi + 1);
       yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
                       &(yyvsp[(yyi + 1) - (yynrhs)])
                                       );
-      fprintf (stderr, "\n");
+      YYFPRINTF (stderr, "\n");
     }
 }
 
@@ -1343,10 +1319,8 @@ yydestruct (yymsg, yytype, yyvaluep)
        break;
     }
 }
-\f
 
 /* Prevent warnings from -Wmissing-prototypes.  */
-
 #ifdef YYPARSE_PARAM
 #if defined __STDC__ || defined __cplusplus
 int yyparse (void *YYPARSE_PARAM);
@@ -1362,11 +1336,10 @@ int yyparse ();
 #endif /* ! YYPARSE_PARAM */
 
 
-
-/* The look-ahead symbol.  */
+/* The lookahead symbol.  */
 int yychar;
 
-/* The semantic value of the look-ahead symbol.  */
+/* The semantic value of the lookahead symbol.  */
 YYSTYPE yylval;
 
 /* Number of syntax errors so far.  */
@@ -1374,9 +1347,9 @@ int yynerrs;
 
 
 
-/*----------.
-| yyparse.  |
-`----------*/
+/*-------------------------.
+| yyparse or yypush_parse.  |
+`-------------------------*/
 
 #ifdef YYPARSE_PARAM
 #if (defined __STDC__ || defined __C99__FUNC__ \
@@ -1400,66 +1373,68 @@ yyparse ()
 #endif
 #endif
 {
-  
-  int yystate;
-  int yyn;
-  int yyresult;
-  /* Number of tokens to shift before error messages enabled.  */
-  int yyerrstatus;
-  /* Look-ahead token as an internal (translated) token number.  */
-  int yytoken = 0;
-#if YYERROR_VERBOSE
-  /* Buffer for error messages, and its allocated size.  */
-  char yymsgbuf[128];
-  char *yymsg = yymsgbuf;
-  YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
-#endif
-
-  /* Three stacks and their tools:
-     `yyss': related to states,
-     `yyvs': related to semantic values,
-     `yyls': related to locations.
 
-     Refer to the stacks thru separate pointers, to allow yyoverflow
-     to reallocate them elsewhere.  */
 
-  /* The state stack.  */
-  yytype_int16 yyssa[YYINITDEPTH];
-  yytype_int16 *yyss = yyssa;
-  yytype_int16 *yyssp;
+    int yystate;
+    /* Number of tokens to shift before error messages enabled.  */
+    int yyerrstatus;
 
-  /* The semantic value stack.  */
-  YYSTYPE yyvsa[YYINITDEPTH];
-  YYSTYPE *yyvs = yyvsa;
-  YYSTYPE *yyvsp;
+    /* The stacks and their tools:
+       `yyss': related to states.
+       `yyvs': related to semantic values.
 
+       Refer to the stacks thru separate pointers, to allow yyoverflow
+       to reallocate them elsewhere.  */
 
+    /* The state stack.  */
+    yytype_int16 yyssa[YYINITDEPTH];
+    yytype_int16 *yyss;
+    yytype_int16 *yyssp;
 
-#define YYPOPSTACK(N)   (yyvsp -= (N), yyssp -= (N))
+    /* The semantic value stack.  */
+    YYSTYPE yyvsa[YYINITDEPTH];
+    YYSTYPE *yyvs;
+    YYSTYPE *yyvsp;
 
-  YYSIZE_T yystacksize = YYINITDEPTH;
+    YYSIZE_T yystacksize;
 
+  int yyn;
+  int yyresult;
+  /* Lookahead token as an internal (translated) token number.  */
+  int yytoken;
   /* The variables used to return semantic value and location from the
      action routines.  */
   YYSTYPE yyval;
 
+#if YYERROR_VERBOSE
+  /* Buffer for error messages, and its allocated size.  */
+  char yymsgbuf[128];
+  char *yymsg = yymsgbuf;
+  YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
+#endif
+
+#define YYPOPSTACK(N)   (yyvsp -= (N), yyssp -= (N))
 
   /* The number of symbols on the RHS of the reduced rule.
      Keep to zero when no symbol should be popped.  */
   int yylen = 0;
 
+  yytoken = 0;
+  yyss = yyssa;
+  yyvs = yyvsa;
+  yystacksize = YYINITDEPTH;
+
   YYDPRINTF ((stderr, "Starting parse\n"));
 
   yystate = 0;
   yyerrstatus = 0;
   yynerrs = 0;
-  yychar = YYEMPTY;            /* Cause a token to be read.  */
+  yychar = YYEMPTY; /* Cause a token to be read.  */
 
   /* Initialize stack pointers.
      Waste one element of value and location stack
      so that they stay on the same level as the state stack.
      The wasted elements are never initialized.  */
-
   yyssp = yyss;
   yyvsp = yyvs;
 
@@ -1489,7 +1464,6 @@ yyparse ()
        YYSTYPE *yyvs1 = yyvs;
        yytype_int16 *yyss1 = yyss;
 
-
        /* Each stack pointer address is followed by the size of the
           data in use in that stack, in bytes.  This used to be a
           conditional around just the two extra args, but that might
@@ -1497,7 +1471,6 @@ yyparse ()
        yyoverflow (YY_("memory exhausted"),
                    &yyss1, yysize * sizeof (*yyssp),
                    &yyvs1, yysize * sizeof (*yyvsp),
-
                    &yystacksize);
 
        yyss = yyss1;
@@ -1520,9 +1493,8 @@ yyparse ()
          (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
        if (! yyptr)
          goto yyexhaustedlab;
-       YYSTACK_RELOCATE (yyss);
-       YYSTACK_RELOCATE (yyvs);
-
+       YYSTACK_RELOCATE (yyss_alloc, yyss);
+       YYSTACK_RELOCATE (yyvs_alloc, yyvs);
 #  undef YYSTACK_RELOCATE
        if (yyss1 != yyssa)
          YYSTACK_FREE (yyss1);
@@ -1533,7 +1505,6 @@ yyparse ()
       yyssp = yyss + yysize - 1;
       yyvsp = yyvs + yysize - 1;
 
-
       YYDPRINTF ((stderr, "Stack size increased to %lu\n",
                  (unsigned long int) yystacksize));
 
@@ -1543,6 +1514,9 @@ yyparse ()
 
   YYDPRINTF ((stderr, "Entering state %d\n", yystate));
 
+  if (yystate == YYFINAL)
+    YYACCEPT;
+
   goto yybackup;
 
 /*-----------.
@@ -1551,16 +1525,16 @@ yyparse ()
 yybackup:
 
   /* Do appropriate processing given the current state.  Read a
-     look-ahead token if we need one and don't already have one.  */
+     lookahead token if we need one and don't already have one.  */
 
-  /* First try to decide what to do without reference to look-ahead token.  */
+  /* First try to decide what to do without reference to lookahead token.  */
   yyn = yypact[yystate];
   if (yyn == YYPACT_NINF)
     goto yydefault;
 
-  /* Not known => get a look-ahead token if don't already have one.  */
+  /* Not known => get a lookahead token if don't already have one.  */
 
-  /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol.  */
+  /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol.  */
   if (yychar == YYEMPTY)
     {
       YYDPRINTF ((stderr, "Reading a token: "));
@@ -1592,20 +1566,16 @@ yybackup:
       goto yyreduce;
     }
 
-  if (yyn == YYFINAL)
-    YYACCEPT;
-
   /* Count tokens shifted since error; after three, turn off error
      status.  */
   if (yyerrstatus)
     yyerrstatus--;
 
-  /* Shift the look-ahead token.  */
+  /* Shift the lookahead token.  */
   YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
 
-  /* Discard the shifted token unless it is eof.  */
-  if (yychar != YYEOF)
-    yychar = YYEMPTY;
+  /* Discard the shifted token.  */
+  yychar = YYEMPTY;
 
   yystate = yyn;
   *++yyvsp = yylval;
@@ -2029,7 +1999,6 @@ yyreduce:
     break;
 
 
-/* Line 1267 of yacc.c.  */
 
       default: break;
     }
@@ -2041,7 +2010,6 @@ yyreduce:
 
   *++yyvsp = yyval;
 
-
   /* Now `shift' the result of the reduction.  Determine what state
      that goes to, based on the state we popped back to and the rule
      number reduced by.  */
@@ -2106,7 +2074,7 @@ yyerrlab:
 
   if (yyerrstatus == 3)
     {
-      /* If just tried and failed to reuse look-ahead token after an
+      /* If just tried and failed to reuse lookahead token after an
         error, discard it.  */
 
       if (yychar <= YYEOF)
@@ -2123,7 +2091,7 @@ yyerrlab:
        }
     }
 
-  /* Else will try to reuse look-ahead token after shifting the error
+  /* Else will try to reuse lookahead token after shifting the error
      token.  */
   goto yyerrlab1;
 
@@ -2180,9 +2148,6 @@ yyerrlab1:
       YY_STACK_PRINT (yyss, yyssp);
     }
 
-  if (yyn == YYFINAL)
-    YYACCEPT;
-
   *++yyvsp = yylval;
 
 
@@ -2207,7 +2172,7 @@ yyabortlab:
   yyresult = 1;
   goto yyreturn;
 
-#ifndef yyoverflow
+#if !defined(yyoverflow) || YYERROR_VERBOSE
 /*-------------------------------------------------.
 | yyexhaustedlab -- memory exhaustion comes here.  |
 `-------------------------------------------------*/
@@ -2218,7 +2183,7 @@ yyexhaustedlab:
 #endif
 
 yyreturn:
-  if (yychar != YYEOF && yychar != YYEMPTY)
+  if (yychar != YYEMPTY)
      yydestruct ("Cleanup: discarding lookahead",
                 yytoken, &yylval);
   /* Do not reclaim the symbols of the rule which action triggered
@@ -2284,7 +2249,7 @@ void conf_parse(const char *name)
        sym_set_change_count(1);
 }
 
-const char *zconf_tokenname(int token)
+static const char *zconf_tokenname(int token)
 {
        switch (token) {
        case T_MENU:            return "menu";
@@ -2348,7 +2313,7 @@ static void zconferror(const char *err)
 #endif
 }
 
-void print_quoted_string(FILE *out, const char *str)
+static void print_quoted_string(FILE *out, const char *str)
 {
        const char *p;
        int len;
@@ -2365,7 +2330,7 @@ void print_quoted_string(FILE *out, const char *str)
        putc('"', out);
 }
 
-void print_symbol(FILE *out, struct menu *menu)
+static void print_symbol(FILE *out, struct menu *menu)
 {
        struct symbol *sym = menu->sym;
        struct property *prop;
index 9710b82466f2b13ecaa576b969dcb5568257b065..8c43491f8cc9635cde61b9f80a98598a77948d75 100644 (file)
@@ -14,8 +14,6 @@
 #define LKC_DIRECT_LINK
 #include "lkc.h"
 
-#include "zconf.hash.c"
-
 #define printd(mask, fmt...) if (cdebug & (mask)) printf(fmt)
 
 #define PRINTD         0x0001
@@ -100,6 +98,11 @@ static struct menu *current_menu, *current_entry;
                menu_end_menu();
 } if_entry menu_entry choice_entry
 
+%{
+/* Include zconf.hash.c here so it can see the token constants. */
+#include "zconf.hash.c"
+%}
+
 %%
 input: stmt_list;
 
@@ -501,7 +504,7 @@ void conf_parse(const char *name)
        sym_set_change_count(1);
 }
 
-const char *zconf_tokenname(int token)
+static const char *zconf_tokenname(int token)
 {
        switch (token) {
        case T_MENU:            return "menu";
@@ -565,7 +568,7 @@ static void zconferror(const char *err)
 #endif
 }
 
-void print_quoted_string(FILE *out, const char *str)
+static void print_quoted_string(FILE *out, const char *str)
 {
        const char *p;
        int len;
@@ -582,7 +585,7 @@ void print_quoted_string(FILE *out, const char *str)
        putc('"', out);
 }
 
-void print_symbol(FILE *out, struct menu *menu)
+static void print_symbol(FILE *out, struct menu *menu)
 {
        struct symbol *sym = menu->sym;
        struct property *prop;
index bfb8b2cdd92a2a3964960b9848e2ec60d95c116a..f0d14452632b554fa3d85681d075a729b54ebb2f 100755 (executable)
@@ -6,77 +6,93 @@
 #                   all the offsets to the calls to mcount.
 #
 #
-# What we want to end up with is a section in vmlinux called
-# __mcount_loc that contains a list of pointers to all the
-# call sites in the kernel that call mcount. Later on boot up, the kernel
-# will read this list, save the locations and turn them into nops.
-# When tracing or profiling is later enabled, these locations will then
-# be converted back to pointers to some function.
+# What we want to end up with this is that each object file will have a
+# section called __mcount_loc that will hold the list of pointers to mcount
+# callers. After final linking, the vmlinux will have within .init.data the
+# list of all callers to mcount between __start_mcount_loc and __stop_mcount_loc.
+# Later on boot up, the kernel will read this list, save the locations and turn
+# them into nops. When tracing or profiling is later enabled, these locations
+# will then be converted back to pointers to some function.
 #
 # This is no easy feat. This script is called just after the original
 # object is compiled and before it is linked.
 #
-# The references to the call sites are offsets from the section of text
-# that the call site is in. Hence, all functions in a section that
-# has a call site to mcount, will have the offset from the beginning of
-# the section and not the beginning of the function.
+# When parse this object file using 'objdump', the references to the call
+# sites are offsets from the section that the call site is in. Hence, all
+# functions in a section that has a call site to mcount, will have the
+# offset from the beginning of the section and not the beginning of the
+# function.
+#
+# But where this section will reside finally in vmlinx is undetermined at
+# this point. So we can't use this kind of offsets to record the final
+# address of this call site.
+#
+# The trick is to change the call offset referring the start of a section to
+# referring a function symbol in this section. During the link step, 'ld' will
+# compute the final address according to the information we record.
 #
-# The trick is to find a way to record the beginning of the section.
-# The way we do this is to look at the first function in the section
-# which will also be the location of that section after final link.
 # e.g.
 #
 #  .section ".sched.text", "ax"
-#  .globl my_func
-#  my_func:
 #        [...]
-#        call mcount  (offset: 0x5)
+#  func1:
+#        [...]
+#        call mcount  (offset: 0x10)
 #        [...]
 #        ret
-#  other_func:
+#  .globl fun2
+#  func2:             (offset: 0x20)
 #        [...]
-#        call mcount (offset: 0x1b)
+#        [...]
+#        ret
+#  func3:
+#        [...]
+#        call mcount (offset: 0x30)
 #        [...]
 #
 # Both relocation offsets for the mcounts in the above example will be
-# offset from .sched.text. If we make another file called tmp.s with:
+# offset from .sched.text. If we choose global symbol func2 as a reference and
+# make another file called tmp.s with the new offsets:
 #
 #  .section __mcount_loc
-#  .quad  my_func + 0x5
-#  .quad  my_func + 0x1b
+#  .quad  func2 - 0x10
+#  .quad  func2 + 0x10
 #
-# We can then compile this tmp.s into tmp.o, and link it to the original
+# We can then compile this tmp.s into tmp.o, and link it back to the original
 # object.
 #
-# But this gets hard if my_func is not globl (a static function).
-# In such a case we have:
+# In our algorithm, we will choose the first global function we meet in this
+# section as the reference. But this gets hard if there is no global functions
+# in this section. In such a case we have to select a local one. E.g. func1:
 #
 #  .section ".sched.text", "ax"
-#  my_func:
+#  func1:
 #        [...]
-#        call mcount  (offset: 0x5)
+#        call mcount  (offset: 0x10)
 #        [...]
 #        ret
-#  other_func:
+#  func2:
 #        [...]
-#        call mcount (offset: 0x1b)
+#        call mcount (offset: 0x20)
 #        [...]
+#  .section "other.section"
 #
 # If we make the tmp.s the same as above, when we link together with
-# the original object, we will end up with two symbols for my_func:
+# the original object, we will end up with two symbols for func1:
 # one local, one global.  After final compile, we will end up with
-# an undefined reference to my_func.
+# an undefined reference to func1 or a wrong reference to another global
+# func1 in other files.
 #
 # Since local objects can reference local variables, we need to find
 # a way to make tmp.o reference the local objects of the original object
-# file after it is linked together. To do this, we convert the my_func
+# file after it is linked together. To do this, we convert func1
 # into a global symbol before linking tmp.o. Then after we link tmp.o
-# we will only have a single symbol for my_func that is global.
-# We can convert my_func back into a local symbol and we are done.
+# we will only have a single symbol for func1 that is global.
+# We can convert func1 back into a local symbol and we are done.
 #
 # Here are the steps we take:
 #
-# 1) Record all the local symbols by using 'nm'
+# 1) Record all the local and weak symbols by using 'nm'
 # 2) Use objdump to find all the call site offsets and sections for
 #    mcount.
 # 3) Compile the list into its own object.
 # 6) Link together this new object with the list object.
 # 7) Convert the local functions back to local symbols and rename
 #    the result as the original object.
-#    End.
 # 8) Link the object with the list object.
 # 9) Move the result back to the original object.
-#    End.
 #
 
 use strict;
@@ -99,7 +113,7 @@ $P =~ s@.*/@@g;
 
 my $V = '0.1';
 
-if ($#ARGV < 7) {
+if ($#ARGV != 10) {
        print "usage: $P arch bits objdump objcopy cc ld nm rm mv is_module inputfile\n";
        print "version: $V\n";
        exit(1);
@@ -109,7 +123,7 @@ my ($arch, $bits, $objdump, $objcopy, $cc,
     $ld, $nm, $rm, $mv, $is_module, $inputfile) = @ARGV;
 
 # This file refers to mcount and shouldn't be ftraced, so lets' ignore it
-if ($inputfile eq "kernel/trace/ftrace.o") {
+if ($inputfile =~ m,kernel/trace/ftrace\.o$,) {
     exit(0);
 }
 
@@ -138,13 +152,47 @@ my %weak;         # List of weak functions
 my %convert;           # List of local functions used that needs conversion
 
 my $type;
-my $nm_regex;          # Find the local functions (return function)
+my $local_regex;       # Match a local function (return function)
+my $weak_regex;        # Match a weak function (return function)
 my $section_regex;     # Find the start of a section
 my $function_regex;    # Find the name of a function
                        #    (return offset and func name)
 my $mcount_regex;      # Find the call site to mcount (return offset)
 my $alignment;         # The .align value to use for $mcount_section
 my $section_type;      # Section header plus possible alignment command
+my $can_use_local = 0;         # If we can use local function references
+
+# Shut up recordmcount if user has older objcopy
+my $quiet_recordmcount = ".tmp_quiet_recordmcount";
+my $print_warning = 1;
+$print_warning = 0 if ( -f $quiet_recordmcount);
+
+##
+# check_objcopy - whether objcopy supports --globalize-symbols
+#
+#  --globalize-symbols came out in 2.17, we must test the version
+#  of objcopy, and if it is less than 2.17, then we can not
+#  record local functions.
+sub check_objcopy
+{
+    open (IN, "$objcopy --version |") or die "error running $objcopy";
+    while (<IN>) {
+       if (/objcopy.*\s(\d+)\.(\d+)/) {
+           $can_use_local = 1 if ($1 > 2 || ($1 == 2 && $2 >= 17));
+           last;
+       }
+    }
+    close (IN);
+
+    if (!$can_use_local && $print_warning) {
+       print STDERR "WARNING: could not find objcopy version or version " .
+           "is less than 2.17.\n" .
+           "\tLocal function references are disabled.\n";
+       open (QUIET, ">$quiet_recordmcount");
+       printf QUIET "Disables the warning from recordmcount.pl\n";
+       close QUIET;
+    }
+}
 
 if ($arch eq "x86") {
     if ($bits == 64) {
@@ -158,7 +206,8 @@ if ($arch eq "x86") {
 # We base the defaults off of i386, the other archs may
 # feel free to change them in the below if statements.
 #
-$nm_regex = "^[0-9a-fA-F]+\\s+t\\s+(\\S+)";
+$local_regex = "^[0-9a-fA-F]+\\s+t\\s+(\\S+)";
+$weak_regex = "^[0-9a-fA-F]+\\s+([wW])\\s+(\\S+)";
 $section_regex = "Disassembly of section\\s+(\\S+):";
 $function_regex = "^([0-9a-fA-F]+)\\s+<(.*?)>:";
 $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\smcount\$";
@@ -207,7 +256,7 @@ if ($arch eq "x86_64") {
     $cc .= " -m32";
 
 } elsif ($arch eq "powerpc") {
-    $nm_regex = "^[0-9a-fA-F]+\\s+t\\s+(\\.?\\S+)";
+    $local_regex = "^[0-9a-fA-F]+\\s+t\\s+(\\.?\\S+)";
     $function_regex = "^([0-9a-fA-F]+)\\s+<(\\.?.*?)>:";
     $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\s\\.?_mcount\$";
 
@@ -279,44 +328,17 @@ if ($filename =~ m,^(.*)(\.\S),) {
 my $mcount_s = $dirname . "/.tmp_mc_" . $prefix . ".s";
 my $mcount_o = $dirname . "/.tmp_mc_" . $prefix . ".o";
 
-#
-# --globalize-symbols came out in 2.17, we must test the version
-# of objcopy, and if it is less than 2.17, then we can not
-# record local functions.
-my $use_locals = 01;
-my $local_warn_once = 0;
-my $found_version = 0;
-
-open (IN, "$objcopy --version |") || die "error running $objcopy";
-while (<IN>) {
-    if (/objcopy.*\s(\d+)\.(\d+)/) {
-       my $major = $1;
-       my $minor = $2;
-
-       $found_version = 1;
-       if ($major < 2 ||
-           ($major == 2 && $minor < 17)) {
-           $use_locals = 0;
-       }
-       last;
-    }
-}
-close (IN);
-
-if (!$found_version) {
-    print STDERR "WARNING: could not find objcopy version.\n" .
-       "\tDisabling local function references.\n";
-}
+check_objcopy();
 
 #
 # Step 1: find all the local (static functions) and weak symbols.
-#        't' is local, 'w/W' is weak (we never use a weak function)
+#         't' is local, 'w/W' is weak
 #
 open (IN, "$nm $inputfile|") || die "error running $nm";
 while (<IN>) {
-    if (/$nm_regex/) {
+    if (/$local_regex/) {
        $locals{$1} = 1;
-    } elsif (/^[0-9a-fA-F]+\s+([wW])\s+(\S+)/) {
+    } elsif (/$weak_regex/) {
        $weak{$2} = $1;
     }
 }
@@ -334,26 +356,20 @@ my $offset = 0;           # offset of ref_func to section beginning
 #
 sub update_funcs
 {
-    return if ($#offsets < 0);
-
-    defined($ref_func) || die "No function to reference";
+    return unless ($ref_func and @offsets);
 
-    # A section only had a weak function, to represent it.
-    # Unfortunately, a weak function may be overwritten by another
-    # function of the same name, making all these offsets incorrect.
-    # To be safe, we simply print a warning and bail.
+    # Sanity check on weak function. A weak function may be overwritten by
+    # another function of the same name, making all these offsets incorrect.
     if (defined $weak{$ref_func}) {
-       print STDERR
-           "$inputfile: WARNING: referencing weak function" .
+       die "$inputfile: ERROR: referencing weak function" .
            " $ref_func for mcount\n";
-       return;
     }
 
     # is this function static? If so, note this fact.
     if (defined $locals{$ref_func}) {
 
        # only use locals if objcopy supports globalize-symbols
-       if (!$use_locals) {
+       if (!$can_use_local) {
            return;
        }
        $convert{$ref_func} = 1;
@@ -379,9 +395,27 @@ open(IN, "$objdump -hdr $inputfile|") || die "error running $objdump";
 
 my $text;
 
+
+# read headers first
 my $read_headers = 1;
 
 while (<IN>) {
+
+    if ($read_headers && /$mcount_section/) {
+       #
+       # Somehow the make process can execute this script on an
+       # object twice. If it does, we would duplicate the mcount
+       # section and it will cause the function tracer self test
+       # to fail. Check if the mcount section exists, and if it does,
+       # warn and exit.
+       #
+       print STDERR "ERROR: $mcount_section already in $inputfile\n" .
+           "\tThis may be an indication that your build is corrupted.\n" .
+           "\tDelete $inputfile and try again. If the same object file\n" .
+           "\tstill causes an issue, then disable CONFIG_DYNAMIC_FTRACE.\n";
+       exit(-1);
+    }
+
     # is it a section?
     if (/$section_regex/) {
        $read_headers = 0;
@@ -393,7 +427,7 @@ while (<IN>) {
            $read_function = 0;
        }
        # print out any recorded offsets
-       update_funcs() if (defined($ref_func));
+       update_funcs();
 
        # reset all markers and arrays
        $text_found = 0;
@@ -422,21 +456,7 @@ while (<IN>) {
                $offset = hex $1;
            }
        }
-    } elsif ($read_headers && /$mcount_section/) {
-       #
-       # Somehow the make process can execute this script on an
-       # object twice. If it does, we would duplicate the mcount
-       # section and it will cause the function tracer self test
-       # to fail. Check if the mcount section exists, and if it does,
-       # warn and exit.
-       #
-       print STDERR "ERROR: $mcount_section already in $inputfile\n" .
-           "\tThis may be an indication that your build is corrupted.\n" .
-           "\tDelete $inputfile and try again. If the same object file\n" .
-           "\tstill causes an issue, then disable CONFIG_DYNAMIC_FTRACE.\n";
-       exit(-1);
     }
-
     # is this a call site to mcount? If so, record it to print later
     if ($text_found && /$mcount_regex/) {
        $offsets[$#offsets + 1] = hex $1;
@@ -444,7 +464,7 @@ while (<IN>) {
 }
 
 # dump out anymore offsets that may have been found
-update_funcs() if (defined($ref_func));
+update_funcs();
 
 # If we did not find any mcount callers, we are done (do nothing).
 if (!$opened) {
index ca4b1ec018229b2df6ef9cdee14b163b4d513241..e8049da1831fa9bf5ed0f049792e60c70162c5f2 100644 (file)
@@ -1,2 +1,2 @@
-subdir-y := mdp
-subdir-        += mdp
+subdir-y := mdp genheaders
+subdir-        += mdp genheaders
diff --git a/scripts/selinux/genheaders/.gitignore b/scripts/selinux/genheaders/.gitignore
new file mode 100644 (file)
index 0000000..4c0b646
--- /dev/null
@@ -0,0 +1 @@
+genheaders
diff --git a/scripts/selinux/genheaders/Makefile b/scripts/selinux/genheaders/Makefile
new file mode 100644 (file)
index 0000000..417b165
--- /dev/null
@@ -0,0 +1,5 @@
+hostprogs-y    := genheaders
+HOST_EXTRACFLAGS += -Isecurity/selinux/include
+
+always         := $(hostprogs-y)
+clean-files    := $(hostprogs-y)
diff --git a/scripts/selinux/genheaders/genheaders.c b/scripts/selinux/genheaders/genheaders.c
new file mode 100644 (file)
index 0000000..2462696
--- /dev/null
@@ -0,0 +1,118 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <ctype.h>
+
+struct security_class_mapping {
+       const char *name;
+       const char *perms[sizeof(unsigned) * 8 + 1];
+};
+
+#include "classmap.h"
+#include "initial_sid_to_string.h"
+
+#define max(x, y) (((int)(x) > (int)(y)) ? x : y)
+
+const char *progname;
+
+static void usage(void)
+{
+       printf("usage: %s flask.h av_permissions.h\n", progname);
+       exit(1);
+}
+
+static char *stoupperx(const char *s)
+{
+       char *s2 = strdup(s);
+       char *p;
+
+       if (!s2) {
+               fprintf(stderr, "%s:  out of memory\n", progname);
+               exit(3);
+       }
+
+       for (p = s2; *p; p++)
+               *p = toupper(*p);
+       return s2;
+}
+
+int main(int argc, char *argv[])
+{
+       int i, j, k;
+       int isids_len;
+       FILE *fout;
+
+       progname = argv[0];
+
+       if (argc < 3)
+               usage();
+
+       fout = fopen(argv[1], "w");
+       if (!fout) {
+               fprintf(stderr, "Could not open %s for writing:  %s\n",
+                       argv[1], strerror(errno));
+               exit(2);
+       }
+
+       for (i = 0; secclass_map[i].name; i++) {
+               struct security_class_mapping *map = &secclass_map[i];
+               map->name = stoupperx(map->name);
+               for (j = 0; map->perms[j]; j++)
+                       map->perms[j] = stoupperx(map->perms[j]);
+       }
+
+       isids_len = sizeof(initial_sid_to_string) / sizeof (char *);
+       for (i = 1; i < isids_len; i++)
+               initial_sid_to_string[i] = stoupperx(initial_sid_to_string[i]);
+
+       fprintf(fout, "/* This file is automatically generated.  Do not edit. */\n");
+       fprintf(fout, "#ifndef _SELINUX_FLASK_H_\n#define _SELINUX_FLASK_H_\n\n");
+
+       for (i = 0; secclass_map[i].name; i++) {
+               struct security_class_mapping *map = &secclass_map[i];
+               fprintf(fout, "#define SECCLASS_%s", map->name);
+               for (j = 0; j < max(1, 40 - strlen(map->name)); j++)
+                       fprintf(fout, " ");
+               fprintf(fout, "%2d\n", i+1);
+       }
+
+       fprintf(fout, "\n");
+
+       for (i = 1; i < isids_len; i++) {
+               char *s = initial_sid_to_string[i];
+               fprintf(fout, "#define SECINITSID_%s", s);
+               for (j = 0; j < max(1, 40 - strlen(s)); j++)
+                       fprintf(fout, " ");
+               fprintf(fout, "%2d\n", i);
+       }
+       fprintf(fout, "\n#define SECINITSID_NUM %d\n", i-1);
+       fprintf(fout, "\n#endif\n");
+       fclose(fout);
+
+       fout = fopen(argv[2], "w");
+       if (!fout) {
+               fprintf(stderr, "Could not open %s for writing:  %s\n",
+                       argv[2], strerror(errno));
+               exit(4);
+       }
+
+       fprintf(fout, "/* This file is automatically generated.  Do not edit. */\n");
+       fprintf(fout, "#ifndef _SELINUX_AV_PERMISSIONS_H_\n#define _SELINUX_AV_PERMISSIONS_H_\n\n");
+
+       for (i = 0; secclass_map[i].name; i++) {
+               struct security_class_mapping *map = &secclass_map[i];
+               for (j = 0; map->perms[j]; j++) {
+                       fprintf(fout, "#define %s__%s", map->name,
+                               map->perms[j]);
+                       for (k = 0; k < max(1, 40 - strlen(map->name) - strlen(map->perms[j])); k++)
+                               fprintf(fout, " ");
+                       fprintf(fout, "0x%08xUL\n", (1<<j));
+               }
+       }
+
+       fprintf(fout, "\n#endif\n");
+       fclose(fout);
+       exit(0);
+}
index b4ced8562587b088f698058fb0fa185410f9987d..62b34ce1f50dd16a0aed513ad40a31baead586ac 100644 (file)
 #include <unistd.h>
 #include <string.h>
 
-#include "flask.h"
-
 static void usage(char *name)
 {
        printf("usage: %s [-m] policy_file context_file\n", name);
        exit(1);
 }
 
-static void find_common_name(char *cname, char *dest, int len)
-{
-       char *start, *end;
-
-       start = strchr(cname, '_')+1;
-       end = strchr(start, '_');
-       if (!start || !end || start-cname > len || end-start > len) {
-               printf("Error with commons defines\n");
-               exit(1);
-       }
-       strncpy(dest, start, end-start);
-       dest[end-start] = '\0';
-}
-
-#define S_(x) x,
-static char *classlist[] = {
-#include "class_to_string.h"
-       NULL
+/* Class/perm mapping support */
+struct security_class_mapping {
+       const char *name;
+       const char *perms[sizeof(unsigned) * 8 + 1];
 };
-#undef S_
 
+#include "classmap.h"
 #include "initial_sid_to_string.h"
 
-#define TB_(x) char *x[] = {
-#define TE_(x) NULL };
-#define S_(x) x,
-#include "common_perm_to_string.h"
-#undef TB_
-#undef TE_
-#undef S_
-
-struct common {
-       char *cname;
-       char **perms;
-};
-struct common common[] = {
-#define TB_(x) { #x, x },
-#define S_(x)
-#define TE_(x)
-#include "common_perm_to_string.h"
-#undef TB_
-#undef TE_
-#undef S_
-};
-
-#define S_(x, y, z) {x, #y},
-struct av_inherit {
-       int class;
-       char *common;
-};
-struct av_inherit av_inherit[] = {
-#include "av_inherit.h"
-};
-#undef S_
-
-#include "av_permissions.h"
-#define S_(x, y, z) {x, y, z},
-struct av_perms {
-       int class;
-       int perm_i;
-       char *perm_s;
-};
-struct av_perms av_perms[] = {
-#include "av_perm_to_string.h"
-};
-#undef S_
-
 int main(int argc, char *argv[])
 {
        int i, j, mls = 0;
+       int initial_sid_to_string_len;
        char **arg, *polout, *ctxout;
-       int classlist_len, initial_sid_to_string_len;
+
        FILE *fout;
 
        if (argc < 3)
@@ -127,64 +68,25 @@ int main(int argc, char *argv[])
                usage(argv[0]);
        }
 
-       classlist_len = sizeof(classlist) / sizeof(char *);
        /* print out the classes */
-       for (i=1; i < classlist_len; i++) {
-               if(classlist[i])
-                       fprintf(fout, "class %s\n", classlist[i]);
-               else
-                       fprintf(fout, "class user%d\n", i);
-       }
+       for (i = 0; secclass_map[i].name; i++)
+               fprintf(fout, "class %s\n", secclass_map[i].name);
        fprintf(fout, "\n");
 
        initial_sid_to_string_len = sizeof(initial_sid_to_string) / sizeof (char *);
        /* print out the sids */
-       for (i=1; i < initial_sid_to_string_len; i++)
+       for (i = 1; i < initial_sid_to_string_len; i++)
                fprintf(fout, "sid %s\n", initial_sid_to_string[i]);
        fprintf(fout, "\n");
 
-       /* print out the commons */
-       for (i=0; i< sizeof(common)/sizeof(struct common); i++) {
-               char cname[101];
-               find_common_name(common[i].cname, cname, 100);
-               cname[100] = '\0';
-               fprintf(fout, "common %s\n{\n", cname);
-               for (j=0; common[i].perms[j]; j++)
-                       fprintf(fout, "\t%s\n", common[i].perms[j]);
-               fprintf(fout, "}\n\n");
-       }
-       fprintf(fout, "\n");
-
        /* print out the class permissions */
-       for (i=1; i < classlist_len; i++) {
-               if (classlist[i]) {
-                       int firstperm = -1, numperms = 0;
-
-                       fprintf(fout, "class %s\n", classlist[i]);
-                       /* does it inherit from a common? */
-                       for (j=0; j < sizeof(av_inherit)/sizeof(struct av_inherit); j++)
-                               if (av_inherit[j].class == i)
-                                       fprintf(fout, "inherits %s\n", av_inherit[j].common);
-
-                       for (j=0; j < sizeof(av_perms)/sizeof(struct av_perms); j++) {
-                               if (av_perms[j].class == i) {
-                                       if (firstperm == -1)
-                                               firstperm = j;
-                                       numperms++;
-                               }
-                       }
-                       if (!numperms) {
-                               fprintf(fout, "\n");
-                               continue;
-                       }
-
-                       fprintf(fout, "{\n");
-                       /* print out the av_perms */
-                       for (j=0; j < numperms; j++) {
-                               fprintf(fout, "\t%s\n", av_perms[firstperm+j].perm_s);
-                       }
-                       fprintf(fout, "}\n\n");
-               }
+       for (i = 0; secclass_map[i].name; i++) {
+               struct security_class_mapping *map = &secclass_map[i];
+               fprintf(fout, "class %s\n", map->name);
+               fprintf(fout, "{\n");
+               for (j = 0; map->perms[j]; j++)
+                       fprintf(fout, "\t%s\n", map->perms[j]);
+               fprintf(fout, "}\n\n");
        }
        fprintf(fout, "\n");
 
@@ -197,31 +99,34 @@ int main(int argc, char *argv[])
        /* types, roles, and allows */
        fprintf(fout, "type base_t;\n");
        fprintf(fout, "role base_r types { base_t };\n");
-       for (i=1; i < classlist_len; i++) {
-               if (classlist[i])
-                       fprintf(fout, "allow base_t base_t:%s *;\n", classlist[i]);
-               else
-                       fprintf(fout, "allow base_t base_t:user%d *;\n", i);
-       }
+       for (i = 0; secclass_map[i].name; i++)
+               fprintf(fout, "allow base_t base_t:%s *;\n",
+                       secclass_map[i].name);
        fprintf(fout, "user user_u roles { base_r };\n");
        fprintf(fout, "\n");
 
        /* default sids */
-       for (i=1; i < initial_sid_to_string_len; i++)
+       for (i = 1; i < initial_sid_to_string_len; i++)
                fprintf(fout, "sid %s user_u:base_r:base_t\n", initial_sid_to_string[i]);
        fprintf(fout, "\n");
 
-
        fprintf(fout, "fs_use_xattr ext2 user_u:base_r:base_t;\n");
        fprintf(fout, "fs_use_xattr ext3 user_u:base_r:base_t;\n");
+       fprintf(fout, "fs_use_xattr ext4 user_u:base_r:base_t;\n");
        fprintf(fout, "fs_use_xattr jfs user_u:base_r:base_t;\n");
        fprintf(fout, "fs_use_xattr xfs user_u:base_r:base_t;\n");
        fprintf(fout, "fs_use_xattr reiserfs user_u:base_r:base_t;\n");
+       fprintf(fout, "fs_use_xattr jffs2 user_u:base_r:base_t;\n");
+       fprintf(fout, "fs_use_xattr gfs2 user_u:base_r:base_t;\n");
+       fprintf(fout, "fs_use_xattr lustre user_u:base_r:base_t;\n");
 
+       fprintf(fout, "fs_use_task eventpollfs user_u:base_r:base_t;\n");
        fprintf(fout, "fs_use_task pipefs user_u:base_r:base_t;\n");
        fprintf(fout, "fs_use_task sockfs user_u:base_r:base_t;\n");
 
+       fprintf(fout, "fs_use_trans mqueue user_u:base_r:base_t;\n");
        fprintf(fout, "fs_use_trans devpts user_u:base_r:base_t;\n");
+       fprintf(fout, "fs_use_trans hugetlbfs user_u:base_r:base_t;\n");
        fprintf(fout, "fs_use_trans tmpfs user_u:base_r:base_t;\n");
        fprintf(fout, "fs_use_trans shm user_u:base_r:base_t;\n");
 
index fb363cd81cf6db10753c69a3726c31143c3823b2..226b9556b25f829384c107196d0110bdf75ef876 100644 (file)
@@ -91,28 +91,6 @@ config SECURITY_PATH
          implement pathname based access controls.
          If you are unsure how to answer this question, answer N.
 
-config SECURITY_FILE_CAPABILITIES
-       bool "File POSIX Capabilities"
-       default n
-       help
-         This enables filesystem capabilities, allowing you to give
-         binaries a subset of root's powers without using setuid 0.
-
-         If in doubt, answer N.
-
-config SECURITY_ROOTPLUG
-       bool "Root Plug Support"
-       depends on USB=y && SECURITY
-       help
-         This is a sample LSM module that should only be used as such.
-         It prevents any programs running with egid == 0 if a specific
-         USB device is not present in the system.
-
-         See <http://www.linuxjournal.com/article.php?sid=6279> for
-         more information about this module.
-
-         If you are unsure how to answer this question, answer N.
-
 config INTEL_TXT
        bool "Enable Intel(R) Trusted Execution Technology (Intel(R) TXT)"
        depends on HAVE_INTEL_TXT
@@ -165,5 +143,37 @@ source security/tomoyo/Kconfig
 
 source security/integrity/ima/Kconfig
 
+choice
+       prompt "Default security module"
+       default DEFAULT_SECURITY_SELINUX if SECURITY_SELINUX
+       default DEFAULT_SECURITY_SMACK if SECURITY_SMACK
+       default DEFAULT_SECURITY_TOMOYO if SECURITY_TOMOYO
+       default DEFAULT_SECURITY_DAC
+
+       help
+         Select the security module that will be used by default if the
+         kernel parameter security= is not specified.
+
+       config DEFAULT_SECURITY_SELINUX
+               bool "SELinux" if SECURITY_SELINUX=y
+
+       config DEFAULT_SECURITY_SMACK
+               bool "Simplified Mandatory Access Control" if SECURITY_SMACK=y
+
+       config DEFAULT_SECURITY_TOMOYO
+               bool "TOMOYO" if SECURITY_TOMOYO=y
+
+       config DEFAULT_SECURITY_DAC
+               bool "Unix Discretionary Access Controls"
+
+endchoice
+
+config DEFAULT_SECURITY
+       string
+       default "selinux" if DEFAULT_SECURITY_SELINUX
+       default "smack" if DEFAULT_SECURITY_SMACK
+       default "tomoyo" if DEFAULT_SECURITY_TOMOYO
+       default "" if DEFAULT_SECURITY_DAC
+
 endmenu
 
index 95ecc06392d73bed265e63d5a1b0f8772721f051..bb44e350c6181bac5e366ee2108d62f27754556d 100644 (file)
@@ -18,7 +18,6 @@ obj-$(CONFIG_SECURITY_SELINUX)                += selinux/built-in.o
 obj-$(CONFIG_SECURITY_SMACK)           += smack/built-in.o
 obj-$(CONFIG_AUDIT)                    += lsm_audit.o
 obj-$(CONFIG_SECURITY_TOMOYO)          += tomoyo/built-in.o
-obj-$(CONFIG_SECURITY_ROOTPLUG)                += root_plug.o
 obj-$(CONFIG_CGROUP_DEVICE)            += device_cgroup.o
 
 # Object integrity file lists
index fce07a7bc8257e9e57afa2681d96d71d22cbb785..5c700e1a4fd377478fbcdc8a048022c1c6fb9ac7 100644 (file)
@@ -308,6 +308,22 @@ static int cap_path_truncate(struct path *path, loff_t length,
 {
        return 0;
 }
+
+static int cap_path_chmod(struct dentry *dentry, struct vfsmount *mnt,
+                         mode_t mode)
+{
+       return 0;
+}
+
+static int cap_path_chown(struct path *path, uid_t uid, gid_t gid)
+{
+       return 0;
+}
+
+static int cap_path_chroot(struct path *root)
+{
+       return 0;
+}
 #endif
 
 static int cap_file_permission(struct file *file, int mask)
@@ -405,7 +421,7 @@ static int cap_kernel_create_files_as(struct cred *new, struct inode *inode)
        return 0;
 }
 
-static int cap_kernel_module_request(void)
+static int cap_kernel_module_request(char *kmod_name)
 {
        return 0;
 }
@@ -977,6 +993,9 @@ void security_fixup_ops(struct security_operations *ops)
        set_to_cap_if_null(ops, path_link);
        set_to_cap_if_null(ops, path_rename);
        set_to_cap_if_null(ops, path_truncate);
+       set_to_cap_if_null(ops, path_chmod);
+       set_to_cap_if_null(ops, path_chown);
+       set_to_cap_if_null(ops, path_chroot);
 #endif
        set_to_cap_if_null(ops, file_permission);
        set_to_cap_if_null(ops, file_alloc_security);
index fe30751a6cd9cb8862fa7fcbd19a3b818264c934..f800fdb3de94136a093f51b11d0ca5e9eaf686e8 100644 (file)
@@ -1,4 +1,4 @@
-/* Common capabilities, needed by capability.o and root_plug.o
+/* Common capabilities, needed by capability.o.
  *
  *     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
@@ -173,7 +173,6 @@ int cap_capget(struct task_struct *target, kernel_cap_t *effective,
  */
 static inline int cap_inh_is_capped(void)
 {
-#ifdef CONFIG_SECURITY_FILE_CAPABILITIES
 
        /* they are so limited unless the current task has the CAP_SETPCAP
         * capability
@@ -181,7 +180,6 @@ static inline int cap_inh_is_capped(void)
        if (cap_capable(current, current_cred(), CAP_SETPCAP,
                        SECURITY_CAP_AUDIT) == 0)
                return 0;
-#endif
        return 1;
 }
 
@@ -239,8 +237,6 @@ static inline void bprm_clear_caps(struct linux_binprm *bprm)
        bprm->cap_effective = false;
 }
 
-#ifdef CONFIG_SECURITY_FILE_CAPABILITIES
-
 /**
  * cap_inode_need_killpriv - Determine if inode change affects privileges
  * @dentry: The inode/dentry in being changed with change marked ATTR_KILL_PRIV
@@ -421,49 +417,6 @@ out:
        return rc;
 }
 
-#else
-int cap_inode_need_killpriv(struct dentry *dentry)
-{
-       return 0;
-}
-
-int cap_inode_killpriv(struct dentry *dentry)
-{
-       return 0;
-}
-
-int get_vfs_caps_from_disk(const struct dentry *dentry, struct cpu_vfs_cap_data *cpu_caps)
-{
-       memset(cpu_caps, 0, sizeof(struct cpu_vfs_cap_data));
-       return -ENODATA;
-}
-
-static inline int get_file_caps(struct linux_binprm *bprm, bool *effective)
-{
-       bprm_clear_caps(bprm);
-       return 0;
-}
-#endif
-
-/*
- * Determine whether a exec'ing process's new permitted capabilities should be
- * limited to just what it already has.
- *
- * This prevents processes that are being ptraced from gaining access to
- * CAP_SETPCAP, unless the process they're tracing already has it, and the
- * binary they're executing has filecaps that elevate it.
- *
- *  Returns 1 if they should be limited, 0 if they are not.
- */
-static inline int cap_limit_ptraced_target(void)
-{
-#ifndef CONFIG_SECURITY_FILE_CAPABILITIES
-       if (capable(CAP_SETPCAP))
-               return 0;
-#endif
-       return 1;
-}
-
 /**
  * cap_bprm_set_creds - Set up the proposed credentials for execve().
  * @bprm: The execution parameters, including the proposed creds
@@ -523,9 +476,8 @@ skip:
                        new->euid = new->uid;
                        new->egid = new->gid;
                }
-               if (cap_limit_ptraced_target())
-                       new->cap_permitted = cap_intersect(new->cap_permitted,
-                                                          old->cap_permitted);
+               new->cap_permitted = cap_intersect(new->cap_permitted,
+                                                  old->cap_permitted);
        }
 
        new->suid = new->fsuid = new->euid;
@@ -739,7 +691,6 @@ int cap_task_fix_setuid(struct cred *new, const struct cred *old, int flags)
        return 0;
 }
 
-#ifdef CONFIG_SECURITY_FILE_CAPABILITIES
 /*
  * Rationale: code calling task_setscheduler, task_setioprio, and
  * task_setnice, assumes that
@@ -820,22 +771,6 @@ static long cap_prctl_drop(struct cred *new, unsigned long cap)
        return 0;
 }
 
-#else
-int cap_task_setscheduler (struct task_struct *p, int policy,
-                          struct sched_param *lp)
-{
-       return 0;
-}
-int cap_task_setioprio (struct task_struct *p, int ioprio)
-{
-       return 0;
-}
-int cap_task_setnice (struct task_struct *p, int nice)
-{
-       return 0;
-}
-#endif
-
 /**
  * cap_task_prctl - Implement process control functions for this security module
  * @option: The process control function requested
@@ -866,7 +801,6 @@ int cap_task_prctl(int option, unsigned long arg2, unsigned long arg3,
                error = !!cap_raised(new->cap_bset, arg2);
                goto no_change;
 
-#ifdef CONFIG_SECURITY_FILE_CAPABILITIES
        case PR_CAPBSET_DROP:
                error = cap_prctl_drop(new, arg2);
                if (error < 0)
@@ -917,8 +851,6 @@ int cap_task_prctl(int option, unsigned long arg2, unsigned long arg3,
                error = new->securebits;
                goto no_change;
 
-#endif /* def CONFIG_SECURITY_FILE_CAPABILITIES */
-
        case PR_GET_KEEPCAPS:
                if (issecure(SECURE_KEEP_CAPS))
                        error = 1;
index 53d9764e8f09861ae44c85042228af5028048ec1..3d7846de8069389ec96c449c9fabf058daae9657 100644 (file)
@@ -3,6 +3,7 @@
 config IMA
        bool "Integrity Measurement Architecture(IMA)"
        depends on ACPI
+       depends on SECURITY
        select SECURITYFS
        select CRYPTO
        select CRYPTO_HMAC
index b8dd693f8790a62a4ae55b848bb8398cadbe3248..a4e2b1dac943b8ed05ee39dd23df2fbe56a80844 100644 (file)
@@ -58,11 +58,11 @@ struct ima_iint_cache *ima_iint_insert(struct inode *inode)
 
        if (!ima_initialized)
                return iint;
-       iint = kmem_cache_alloc(iint_cache, GFP_KERNEL);
+       iint = kmem_cache_alloc(iint_cache, GFP_NOFS);
        if (!iint)
                return iint;
 
-       rc = radix_tree_preload(GFP_KERNEL);
+       rc = radix_tree_preload(GFP_NOFS);
        if (rc < 0)
                goto out;
 
index 3bb90b6f1dd3db9d697e02209273008eb7a73cc1..51bd0fd9c9f0b016a40cb3682bfc49a6fef8b053 100644 (file)
@@ -354,6 +354,10 @@ static void dump_common_audit_data(struct audit_buffer *ab,
                }
                break;
 #endif
+       case LSM_AUDIT_DATA_KMOD:
+               audit_log_format(ab, " kmod=");
+               audit_log_untrustedstring(ab, a->u.kmod_name);
+               break;
        } /* switch (a->type) */
 }
 
index c844eed7915d0d270c058c16d6b3db40ffa576d0..fc43c9d37084599056680e55c5e8c38491b117ba 100644 (file)
@@ -33,6 +33,9 @@ int mmap_min_addr_handler(struct ctl_table *table, int write,
 {
        int ret;
 
+       if (!capable(CAP_SYS_RAWIO))
+               return -EPERM;
+
        ret = proc_doulongvec_minmax(table, write, buffer, lenp, ppos);
 
        update_mmap_min_addr();
diff --git a/security/root_plug.c b/security/root_plug.c
deleted file mode 100644 (file)
index 2f7ffa6..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Root Plug sample LSM module
- *
- * Originally written for a Linux Journal.
- *
- * Copyright (C) 2002 Greg Kroah-Hartman <greg@kroah.com>
- *
- * Prevents any programs running with egid == 0 if a specific USB device
- * is not present in the system.  Yes, it can be gotten around, but is a
- * nice starting point for people to play with, and learn the LSM
- * interface.
- *
- * If you want to turn this into something with a semblance of security,
- * you need to hook the task_* functions also.
- *
- * See http://www.linuxjournal.com/article.php?sid=6279 for more information
- * about this code.
- *
- *     This program is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation, version 2 of the
- *     License.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/security.h>
-#include <linux/usb.h>
-#include <linux/moduleparam.h>
-
-/* default is a generic type of usb to serial converter */
-static int vendor_id = 0x0557;
-static int product_id = 0x2008;
-
-module_param(vendor_id, uint, 0400);
-module_param(product_id, uint, 0400);
-
-/* should we print out debug messages */
-static int debug = 0;
-
-module_param(debug, bool, 0600);
-
-#define MY_NAME "root_plug"
-
-#define root_dbg(fmt, arg...)                                  \
-       do {                                                    \
-               if (debug)                                      \
-                       printk(KERN_DEBUG "%s: %s: " fmt ,      \
-                               MY_NAME , __func__ ,    \
-                               ## arg);                        \
-       } while (0)
-
-static int rootplug_bprm_check_security (struct linux_binprm *bprm)
-{
-       struct usb_device *dev;
-
-       root_dbg("file %s, e_uid = %d, e_gid = %d\n",
-                bprm->filename, bprm->cred->euid, bprm->cred->egid);
-
-       if (bprm->cred->egid == 0) {
-               dev = usb_find_device(vendor_id, product_id);
-               if (!dev) {
-                       root_dbg("e_gid = 0, and device not found, "
-                                "task not allowed to run...\n");
-                       return -EPERM;
-               }
-               usb_put_dev(dev);
-       }
-
-       return 0;
-}
-
-static struct security_operations rootplug_security_ops = {
-       .bprm_check_security =          rootplug_bprm_check_security,
-};
-
-static int __init rootplug_init (void)
-{
-       /* register ourselves with the security framework */
-       if (register_security (&rootplug_security_ops)) {
-               printk (KERN_INFO 
-                       "Failure registering Root Plug module with the kernel\n");
-                       return -EINVAL;
-       }
-       printk (KERN_INFO "Root Plug module initialized, "
-               "vendor_id = %4.4x, product id = %4.4x\n", vendor_id, product_id);
-       return 0;
-}
-
-security_initcall (rootplug_init);
index c4c673240c1c6761beadc94f3746e99d09c6a703..24e060be9fa54b64994b6e5fe65674b42a90928c 100644 (file)
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/security.h>
+#include <linux/ima.h>
 
 /* Boot-time LSM user choice */
-static __initdata char chosen_lsm[SECURITY_NAME_MAX + 1];
+static __initdata char chosen_lsm[SECURITY_NAME_MAX + 1] =
+       CONFIG_DEFAULT_SECURITY;
 
 /* things that live in capability.c */
 extern struct security_operations default_security_ops;
@@ -79,8 +81,10 @@ __setup("security=", choose_lsm);
  *
  * Return true if:
  *     -The passed LSM is the one chosen by user at boot time,
- *     -or user didn't specify a specific LSM and we're the first to ask
- *      for registration permission,
+ *     -or the passed LSM is configured as the default and the user did not
+ *      choose an alternate LSM at boot time,
+ *     -or there is no default LSM set and the user didn't specify a
+ *      specific LSM and we're the first to ask for registration permission,
  *     -or the passed LSM is currently loaded.
  * Otherwise, return false.
  */
@@ -235,7 +239,12 @@ int security_bprm_set_creds(struct linux_binprm *bprm)
 
 int security_bprm_check(struct linux_binprm *bprm)
 {
-       return security_ops->bprm_check_security(bprm);
+       int ret;
+
+       ret = security_ops->bprm_check_security(bprm);
+       if (ret)
+               return ret;
+       return ima_bprm_check(bprm);
 }
 
 void security_bprm_committing_creds(struct linux_binprm *bprm)
@@ -352,12 +361,21 @@ EXPORT_SYMBOL(security_sb_parse_opts_str);
 
 int security_inode_alloc(struct inode *inode)
 {
+       int ret;
+
        inode->i_security = NULL;
-       return security_ops->inode_alloc_security(inode);
+       ret =  security_ops->inode_alloc_security(inode);
+       if (ret)
+               return ret;
+       ret = ima_inode_alloc(inode);
+       if (ret)
+               security_inode_free(inode);
+       return ret;
 }
 
 void security_inode_free(struct inode *inode)
 {
+       ima_inode_free(inode);
        security_ops->inode_free_security(inode);
 }
 
@@ -434,6 +452,26 @@ int security_path_truncate(struct path *path, loff_t length,
                return 0;
        return security_ops->path_truncate(path, length, time_attrs);
 }
+
+int security_path_chmod(struct dentry *dentry, struct vfsmount *mnt,
+                       mode_t mode)
+{
+       if (unlikely(IS_PRIVATE(dentry->d_inode)))
+               return 0;
+       return security_ops->path_chmod(dentry, mnt, mode);
+}
+
+int security_path_chown(struct path *path, uid_t uid, gid_t gid)
+{
+       if (unlikely(IS_PRIVATE(path->dentry->d_inode)))
+               return 0;
+       return security_ops->path_chown(path, uid, gid);
+}
+
+int security_path_chroot(struct path *path)
+{
+       return security_ops->path_chroot(path);
+}
 #endif
 
 int security_inode_create(struct inode *dir, struct dentry *dentry, int mode)
@@ -628,6 +666,8 @@ int security_file_alloc(struct file *file)
 void security_file_free(struct file *file)
 {
        security_ops->file_free_security(file);
+       if (file->f_dentry)
+               ima_file_free(file);
 }
 
 int security_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
@@ -639,7 +679,12 @@ int security_file_mmap(struct file *file, unsigned long reqprot,
                        unsigned long prot, unsigned long flags,
                        unsigned long addr, unsigned long addr_only)
 {
-       return security_ops->file_mmap(file, reqprot, prot, flags, addr, addr_only);
+       int ret;
+
+       ret = security_ops->file_mmap(file, reqprot, prot, flags, addr, addr_only);
+       if (ret)
+               return ret;
+       return ima_file_mmap(file, prot);
 }
 
 int security_file_mprotect(struct vm_area_struct *vma, unsigned long reqprot,
@@ -719,9 +764,9 @@ int security_kernel_create_files_as(struct cred *new, struct inode *inode)
        return security_ops->kernel_create_files_as(new, inode);
 }
 
-int security_kernel_module_request(void)
+int security_kernel_module_request(char *kmod_name)
 {
-       return security_ops->kernel_module_request();
+       return security_ops->kernel_module_request(kmod_name);
 }
 
 int security_task_setuid(uid_t id0, uid_t id1, uid_t id2, int flags)
diff --git a/security/selinux/.gitignore b/security/selinux/.gitignore
new file mode 100644 (file)
index 0000000..2e5040a
--- /dev/null
@@ -0,0 +1,2 @@
+av_permissions.h
+flask.h
index d47fc5e545e08c873bf769fe54f90cff9c952b8d..f013982df417bd1bd930dfab19c911ec21ad7d85 100644 (file)
@@ -18,5 +18,13 @@ selinux-$(CONFIG_SECURITY_NETWORK_XFRM) += xfrm.o
 
 selinux-$(CONFIG_NETLABEL) += netlabel.o
 
-EXTRA_CFLAGS += -Isecurity/selinux/include
+EXTRA_CFLAGS += -Isecurity/selinux -Isecurity/selinux/include
 
+$(obj)/avc.o: $(obj)/flask.h
+
+quiet_cmd_flask = GEN     $(obj)/flask.h $(obj)/av_permissions.h
+      cmd_flask = scripts/selinux/genheaders/genheaders $(obj)/flask.h $(obj)/av_permissions.h
+
+targets += flask.h
+$(obj)/flask.h: $(src)/include/classmap.h FORCE
+       $(call if_changed,flask)
index b4b5da1c0a421ff69a12b80312d65c456148a47d..f2dde268165ab92ec7d9373db532616f5744069c 100644 (file)
 #include <net/ipv6.h>
 #include "avc.h"
 #include "avc_ss.h"
-
-static const struct av_perm_to_string av_perm_to_string[] = {
-#define S_(c, v, s) { c, v, s },
-#include "av_perm_to_string.h"
-#undef S_
-};
-
-static const char *class_to_string[] = {
-#define S_(s) s,
-#include "class_to_string.h"
-#undef S_
-};
-
-#define TB_(s) static const char *s[] = {
-#define TE_(s) };
-#define S_(s) s,
-#include "common_perm_to_string.h"
-#undef TB_
-#undef TE_
-#undef S_
-
-static const struct av_inherit av_inherit[] = {
-#define S_(c, i, b) {  .tclass = c,\
-                       .common_pts = common_##i##_perm_to_string,\
-                       .common_base =  b },
-#include "av_inherit.h"
-#undef S_
-};
-
-const struct selinux_class_perm selinux_class_perm = {
-       .av_perm_to_string = av_perm_to_string,
-       .av_pts_len = ARRAY_SIZE(av_perm_to_string),
-       .class_to_string = class_to_string,
-       .cts_len = ARRAY_SIZE(class_to_string),
-       .av_inherit = av_inherit,
-       .av_inherit_len = ARRAY_SIZE(av_inherit)
-};
+#include "classmap.h"
 
 #define AVC_CACHE_SLOTS                        512
 #define AVC_DEF_CACHE_THRESHOLD                512
@@ -139,52 +103,28 @@ static inline int avc_hash(u32 ssid, u32 tsid, u16 tclass)
  */
 static void avc_dump_av(struct audit_buffer *ab, u16 tclass, u32 av)
 {
-       const char **common_pts = NULL;
-       u32 common_base = 0;
-       int i, i2, perm;
+       const char **perms;
+       int i, perm;
 
        if (av == 0) {
                audit_log_format(ab, " null");
                return;
        }
 
-       for (i = 0; i < ARRAY_SIZE(av_inherit); i++) {
-               if (av_inherit[i].tclass == tclass) {
-                       common_pts = av_inherit[i].common_pts;
-                       common_base = av_inherit[i].common_base;
-                       break;
-               }
-       }
+       perms = secclass_map[tclass-1].perms;
 
        audit_log_format(ab, " {");
        i = 0;
        perm = 1;
-       while (perm < common_base) {
-               if (perm & av) {
-                       audit_log_format(ab, " %s", common_pts[i]);
+       while (i < (sizeof(av) * 8)) {
+               if ((perm & av) && perms[i]) {
+                       audit_log_format(ab, " %s", perms[i]);
                        av &= ~perm;
                }
                i++;
                perm <<= 1;
        }
 
-       while (i < sizeof(av) * 8) {
-               if (perm & av) {
-                       for (i2 = 0; i2 < ARRAY_SIZE(av_perm_to_string); i2++) {
-                               if ((av_perm_to_string[i2].tclass == tclass) &&
-                                   (av_perm_to_string[i2].value == perm))
-                                       break;
-                       }
-                       if (i2 < ARRAY_SIZE(av_perm_to_string)) {
-                               audit_log_format(ab, " %s",
-                                                av_perm_to_string[i2].name);
-                               av &= ~perm;
-                       }
-               }
-               i++;
-               perm <<= 1;
-       }
-
        if (av)
                audit_log_format(ab, " 0x%x", av);
 
@@ -219,8 +159,8 @@ static void avc_dump_query(struct audit_buffer *ab, u32 ssid, u32 tsid, u16 tcla
                kfree(scontext);
        }
 
-       BUG_ON(tclass >= ARRAY_SIZE(class_to_string) || !class_to_string[tclass]);
-       audit_log_format(ab, " tclass=%s", class_to_string[tclass]);
+       BUG_ON(tclass >= ARRAY_SIZE(secclass_map));
+       audit_log_format(ab, " tclass=%s", secclass_map[tclass-1].name);
 }
 
 /**
index bb230d5d7085a9612f915edbb50124a0077db4be..c96d63ec47530691b43338f2ab086636897efe8f 100644 (file)
@@ -91,7 +91,6 @@
 
 #define NUM_SEL_MNT_OPTS 5
 
-extern unsigned int policydb_loaded_version;
 extern int selinux_nlmsg_lookup(u16 sclass, u16 nlmsg_type, u32 *perm);
 extern struct security_operations *security_ops;
 
@@ -3338,9 +3337,18 @@ static int selinux_kernel_create_files_as(struct cred *new, struct inode *inode)
        return 0;
 }
 
-static int selinux_kernel_module_request(void)
+static int selinux_kernel_module_request(char *kmod_name)
 {
-       return task_has_system(current, SYSTEM__MODULE_REQUEST);
+       u32 sid;
+       struct common_audit_data ad;
+
+       sid = task_sid(current);
+
+       COMMON_AUDIT_DATA_INIT(&ad, KMOD);
+       ad.u.kmod_name = kmod_name;
+
+       return avc_has_perm(sid, SECINITSID_KERNEL, SECCLASS_SYSTEM,
+                           SYSTEM__MODULE_REQUEST, &ad);
 }
 
 static int selinux_task_setpgid(struct task_struct *p, pid_t pgid)
@@ -4714,10 +4722,7 @@ static int selinux_netlink_send(struct sock *sk, struct sk_buff *skb)
        if (err)
                return err;
 
-       if (policydb_loaded_version >= POLICYDB_VERSION_NLCLASS)
-               err = selinux_nlmsg_perm(sk, skb);
-
-       return err;
+       return selinux_nlmsg_perm(sk, skb);
 }
 
 static int selinux_netlink_recv(struct sk_buff *skb, int capability)
@@ -5830,12 +5835,12 @@ int selinux_disable(void)
        selinux_disabled = 1;
        selinux_enabled = 0;
 
-       /* Try to destroy the avc node cache */
-       avc_disable();
-
        /* Reset security_ops to the secondary module, dummy or capability. */
        security_ops = secondary_ops;
 
+       /* Try to destroy the avc node cache */
+       avc_disable();
+
        /* Unregister netfilter hooks. */
        selinux_nf_ip_exit();
 
diff --git a/security/selinux/include/av_inherit.h b/security/selinux/include/av_inherit.h
deleted file mode 100644 (file)
index abedcd7..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-/* This file is automatically generated.  Do not edit. */
-   S_(SECCLASS_DIR, file, 0x00020000UL)
-   S_(SECCLASS_FILE, file, 0x00020000UL)
-   S_(SECCLASS_LNK_FILE, file, 0x00020000UL)
-   S_(SECCLASS_CHR_FILE, file, 0x00020000UL)
-   S_(SECCLASS_BLK_FILE, file, 0x00020000UL)
-   S_(SECCLASS_SOCK_FILE, file, 0x00020000UL)
-   S_(SECCLASS_FIFO_FILE, file, 0x00020000UL)
-   S_(SECCLASS_SOCKET, socket, 0x00400000UL)
-   S_(SECCLASS_TCP_SOCKET, socket, 0x00400000UL)
-   S_(SECCLASS_UDP_SOCKET, socket, 0x00400000UL)
-   S_(SECCLASS_RAWIP_SOCKET, socket, 0x00400000UL)
-   S_(SECCLASS_NETLINK_SOCKET, socket, 0x00400000UL)
-   S_(SECCLASS_PACKET_SOCKET, socket, 0x00400000UL)
-   S_(SECCLASS_KEY_SOCKET, socket, 0x00400000UL)
-   S_(SECCLASS_UNIX_STREAM_SOCKET, socket, 0x00400000UL)
-   S_(SECCLASS_UNIX_DGRAM_SOCKET, socket, 0x00400000UL)
-   S_(SECCLASS_TUN_SOCKET, socket, 0x00400000UL)
-   S_(SECCLASS_IPC, ipc, 0x00000200UL)
-   S_(SECCLASS_SEM, ipc, 0x00000200UL)
-   S_(SECCLASS_MSGQ, ipc, 0x00000200UL)
-   S_(SECCLASS_SHM, ipc, 0x00000200UL)
-   S_(SECCLASS_NETLINK_ROUTE_SOCKET, socket, 0x00400000UL)
-   S_(SECCLASS_NETLINK_FIREWALL_SOCKET, socket, 0x00400000UL)
-   S_(SECCLASS_NETLINK_TCPDIAG_SOCKET, socket, 0x00400000UL)
-   S_(SECCLASS_NETLINK_NFLOG_SOCKET, socket, 0x00400000UL)
-   S_(SECCLASS_NETLINK_XFRM_SOCKET, socket, 0x00400000UL)
-   S_(SECCLASS_NETLINK_SELINUX_SOCKET, socket, 0x00400000UL)
-   S_(SECCLASS_NETLINK_AUDIT_SOCKET, socket, 0x00400000UL)
-   S_(SECCLASS_NETLINK_IP6FW_SOCKET, socket, 0x00400000UL)
-   S_(SECCLASS_NETLINK_DNRT_SOCKET, socket, 0x00400000UL)
-   S_(SECCLASS_NETLINK_KOBJECT_UEVENT_SOCKET, socket, 0x00400000UL)
-   S_(SECCLASS_APPLETALK_SOCKET, socket, 0x00400000UL)
-   S_(SECCLASS_DCCP_SOCKET, socket, 0x00400000UL)
diff --git a/security/selinux/include/av_perm_to_string.h b/security/selinux/include/av_perm_to_string.h
deleted file mode 100644 (file)
index 2b683ad..0000000
+++ /dev/null
@@ -1,183 +0,0 @@
-/* This file is automatically generated.  Do not edit. */
-   S_(SECCLASS_FILESYSTEM, FILESYSTEM__MOUNT, "mount")
-   S_(SECCLASS_FILESYSTEM, FILESYSTEM__REMOUNT, "remount")
-   S_(SECCLASS_FILESYSTEM, FILESYSTEM__UNMOUNT, "unmount")
-   S_(SECCLASS_FILESYSTEM, FILESYSTEM__GETATTR, "getattr")
-   S_(SECCLASS_FILESYSTEM, FILESYSTEM__RELABELFROM, "relabelfrom")
-   S_(SECCLASS_FILESYSTEM, FILESYSTEM__RELABELTO, "relabelto")
-   S_(SECCLASS_FILESYSTEM, FILESYSTEM__TRANSITION, "transition")
-   S_(SECCLASS_FILESYSTEM, FILESYSTEM__ASSOCIATE, "associate")
-   S_(SECCLASS_FILESYSTEM, FILESYSTEM__QUOTAMOD, "quotamod")
-   S_(SECCLASS_FILESYSTEM, FILESYSTEM__QUOTAGET, "quotaget")
-   S_(SECCLASS_DIR, DIR__ADD_NAME, "add_name")
-   S_(SECCLASS_DIR, DIR__REMOVE_NAME, "remove_name")
-   S_(SECCLASS_DIR, DIR__REPARENT, "reparent")
-   S_(SECCLASS_DIR, DIR__SEARCH, "search")
-   S_(SECCLASS_DIR, DIR__RMDIR, "rmdir")
-   S_(SECCLASS_DIR, DIR__OPEN, "open")
-   S_(SECCLASS_FILE, FILE__EXECUTE_NO_TRANS, "execute_no_trans")
-   S_(SECCLASS_FILE, FILE__ENTRYPOINT, "entrypoint")
-   S_(SECCLASS_FILE, FILE__EXECMOD, "execmod")
-   S_(SECCLASS_FILE, FILE__OPEN, "open")
-   S_(SECCLASS_CHR_FILE, CHR_FILE__EXECUTE_NO_TRANS, "execute_no_trans")
-   S_(SECCLASS_CHR_FILE, CHR_FILE__ENTRYPOINT, "entrypoint")
-   S_(SECCLASS_CHR_FILE, CHR_FILE__EXECMOD, "execmod")
-   S_(SECCLASS_CHR_FILE, CHR_FILE__OPEN, "open")
-   S_(SECCLASS_BLK_FILE, BLK_FILE__OPEN, "open")
-   S_(SECCLASS_SOCK_FILE, SOCK_FILE__OPEN, "open")
-   S_(SECCLASS_FIFO_FILE, FIFO_FILE__OPEN, "open")
-   S_(SECCLASS_FD, FD__USE, "use")
-   S_(SECCLASS_TCP_SOCKET, TCP_SOCKET__CONNECTTO, "connectto")
-   S_(SECCLASS_TCP_SOCKET, TCP_SOCKET__NEWCONN, "newconn")
-   S_(SECCLASS_TCP_SOCKET, TCP_SOCKET__ACCEPTFROM, "acceptfrom")
-   S_(SECCLASS_TCP_SOCKET, TCP_SOCKET__NODE_BIND, "node_bind")
-   S_(SECCLASS_TCP_SOCKET, TCP_SOCKET__NAME_CONNECT, "name_connect")
-   S_(SECCLASS_UDP_SOCKET, UDP_SOCKET__NODE_BIND, "node_bind")
-   S_(SECCLASS_RAWIP_SOCKET, RAWIP_SOCKET__NODE_BIND, "node_bind")
-   S_(SECCLASS_NODE, NODE__TCP_RECV, "tcp_recv")
-   S_(SECCLASS_NODE, NODE__TCP_SEND, "tcp_send")
-   S_(SECCLASS_NODE, NODE__UDP_RECV, "udp_recv")
-   S_(SECCLASS_NODE, NODE__UDP_SEND, "udp_send")
-   S_(SECCLASS_NODE, NODE__RAWIP_RECV, "rawip_recv")
-   S_(SECCLASS_NODE, NODE__RAWIP_SEND, "rawip_send")
-   S_(SECCLASS_NODE, NODE__ENFORCE_DEST, "enforce_dest")
-   S_(SECCLASS_NODE, NODE__DCCP_RECV, "dccp_recv")
-   S_(SECCLASS_NODE, NODE__DCCP_SEND, "dccp_send")
-   S_(SECCLASS_NODE, NODE__RECVFROM, "recvfrom")
-   S_(SECCLASS_NODE, NODE__SENDTO, "sendto")
-   S_(SECCLASS_NETIF, NETIF__TCP_RECV, "tcp_recv")
-   S_(SECCLASS_NETIF, NETIF__TCP_SEND, "tcp_send")
-   S_(SECCLASS_NETIF, NETIF__UDP_RECV, "udp_recv")
-   S_(SECCLASS_NETIF, NETIF__UDP_SEND, "udp_send")
-   S_(SECCLASS_NETIF, NETIF__RAWIP_RECV, "rawip_recv")
-   S_(SECCLASS_NETIF, NETIF__RAWIP_SEND, "rawip_send")
-   S_(SECCLASS_NETIF, NETIF__DCCP_RECV, "dccp_recv")
-   S_(SECCLASS_NETIF, NETIF__DCCP_SEND, "dccp_send")
-   S_(SECCLASS_NETIF, NETIF__INGRESS, "ingress")
-   S_(SECCLASS_NETIF, NETIF__EGRESS, "egress")
-   S_(SECCLASS_UNIX_STREAM_SOCKET, UNIX_STREAM_SOCKET__CONNECTTO, "connectto")
-   S_(SECCLASS_UNIX_STREAM_SOCKET, UNIX_STREAM_SOCKET__NEWCONN, "newconn")
-   S_(SECCLASS_UNIX_STREAM_SOCKET, UNIX_STREAM_SOCKET__ACCEPTFROM, "acceptfrom")
-   S_(SECCLASS_PROCESS, PROCESS__FORK, "fork")
-   S_(SECCLASS_PROCESS, PROCESS__TRANSITION, "transition")
-   S_(SECCLASS_PROCESS, PROCESS__SIGCHLD, "sigchld")
-   S_(SECCLASS_PROCESS, PROCESS__SIGKILL, "sigkill")
-   S_(SECCLASS_PROCESS, PROCESS__SIGSTOP, "sigstop")
-   S_(SECCLASS_PROCESS, PROCESS__SIGNULL, "signull")
-   S_(SECCLASS_PROCESS, PROCESS__SIGNAL, "signal")
-   S_(SECCLASS_PROCESS, PROCESS__PTRACE, "ptrace")
-   S_(SECCLASS_PROCESS, PROCESS__GETSCHED, "getsched")
-   S_(SECCLASS_PROCESS, PROCESS__SETSCHED, "setsched")
-   S_(SECCLASS_PROCESS, PROCESS__GETSESSION, "getsession")
-   S_(SECCLASS_PROCESS, PROCESS__GETPGID, "getpgid")
-   S_(SECCLASS_PROCESS, PROCESS__SETPGID, "setpgid")
-   S_(SECCLASS_PROCESS, PROCESS__GETCAP, "getcap")
-   S_(SECCLASS_PROCESS, PROCESS__SETCAP, "setcap")
-   S_(SECCLASS_PROCESS, PROCESS__SHARE, "share")
-   S_(SECCLASS_PROCESS, PROCESS__GETATTR, "getattr")
-   S_(SECCLASS_PROCESS, PROCESS__SETEXEC, "setexec")
-   S_(SECCLASS_PROCESS, PROCESS__SETFSCREATE, "setfscreate")
-   S_(SECCLASS_PROCESS, PROCESS__NOATSECURE, "noatsecure")
-   S_(SECCLASS_PROCESS, PROCESS__SIGINH, "siginh")
-   S_(SECCLASS_PROCESS, PROCESS__SETRLIMIT, "setrlimit")
-   S_(SECCLASS_PROCESS, PROCESS__RLIMITINH, "rlimitinh")
-   S_(SECCLASS_PROCESS, PROCESS__DYNTRANSITION, "dyntransition")
-   S_(SECCLASS_PROCESS, PROCESS__SETCURRENT, "setcurrent")
-   S_(SECCLASS_PROCESS, PROCESS__EXECMEM, "execmem")
-   S_(SECCLASS_PROCESS, PROCESS__EXECSTACK, "execstack")
-   S_(SECCLASS_PROCESS, PROCESS__EXECHEAP, "execheap")
-   S_(SECCLASS_PROCESS, PROCESS__SETKEYCREATE, "setkeycreate")
-   S_(SECCLASS_PROCESS, PROCESS__SETSOCKCREATE, "setsockcreate")
-   S_(SECCLASS_MSGQ, MSGQ__ENQUEUE, "enqueue")
-   S_(SECCLASS_MSG, MSG__SEND, "send")
-   S_(SECCLASS_MSG, MSG__RECEIVE, "receive")
-   S_(SECCLASS_SHM, SHM__LOCK, "lock")
-   S_(SECCLASS_SECURITY, SECURITY__COMPUTE_AV, "compute_av")
-   S_(SECCLASS_SECURITY, SECURITY__COMPUTE_CREATE, "compute_create")
-   S_(SECCLASS_SECURITY, SECURITY__COMPUTE_MEMBER, "compute_member")
-   S_(SECCLASS_SECURITY, SECURITY__CHECK_CONTEXT, "check_context")
-   S_(SECCLASS_SECURITY, SECURITY__LOAD_POLICY, "load_policy")
-   S_(SECCLASS_SECURITY, SECURITY__COMPUTE_RELABEL, "compute_relabel")
-   S_(SECCLASS_SECURITY, SECURITY__COMPUTE_USER, "compute_user")
-   S_(SECCLASS_SECURITY, SECURITY__SETENFORCE, "setenforce")
-   S_(SECCLASS_SECURITY, SECURITY__SETBOOL, "setbool")
-   S_(SECCLASS_SECURITY, SECURITY__SETSECPARAM, "setsecparam")
-   S_(SECCLASS_SECURITY, SECURITY__SETCHECKREQPROT, "setcheckreqprot")
-   S_(SECCLASS_SYSTEM, SYSTEM__IPC_INFO, "ipc_info")
-   S_(SECCLASS_SYSTEM, SYSTEM__SYSLOG_READ, "syslog_read")
-   S_(SECCLASS_SYSTEM, SYSTEM__SYSLOG_MOD, "syslog_mod")
-   S_(SECCLASS_SYSTEM, SYSTEM__SYSLOG_CONSOLE, "syslog_console")
-   S_(SECCLASS_SYSTEM, SYSTEM__MODULE_REQUEST, "module_request")
-   S_(SECCLASS_CAPABILITY, CAPABILITY__CHOWN, "chown")
-   S_(SECCLASS_CAPABILITY, CAPABILITY__DAC_OVERRIDE, "dac_override")
-   S_(SECCLASS_CAPABILITY, CAPABILITY__DAC_READ_SEARCH, "dac_read_search")
-   S_(SECCLASS_CAPABILITY, CAPABILITY__FOWNER, "fowner")
-   S_(SECCLASS_CAPABILITY, CAPABILITY__FSETID, "fsetid")
-   S_(SECCLASS_CAPABILITY, CAPABILITY__KILL, "kill")
-   S_(SECCLASS_CAPABILITY, CAPABILITY__SETGID, "setgid")
-   S_(SECCLASS_CAPABILITY, CAPABILITY__SETUID, "setuid")
-   S_(SECCLASS_CAPABILITY, CAPABILITY__SETPCAP, "setpcap")
-   S_(SECCLASS_CAPABILITY, CAPABILITY__LINUX_IMMUTABLE, "linux_immutable")
-   S_(SECCLASS_CAPABILITY, CAPABILITY__NET_BIND_SERVICE, "net_bind_service")
-   S_(SECCLASS_CAPABILITY, CAPABILITY__NET_BROADCAST, "net_broadcast")
-   S_(SECCLASS_CAPABILITY, CAPABILITY__NET_ADMIN, "net_admin")
-   S_(SECCLASS_CAPABILITY, CAPABILITY__NET_RAW, "net_raw")
-   S_(SECCLASS_CAPABILITY, CAPABILITY__IPC_LOCK, "ipc_lock")
-   S_(SECCLASS_CAPABILITY, CAPABILITY__IPC_OWNER, "ipc_owner")
-   S_(SECCLASS_CAPABILITY, CAPABILITY__SYS_MODULE, "sys_module")
-   S_(SECCLASS_CAPABILITY, CAPABILITY__SYS_RAWIO, "sys_rawio")
-   S_(SECCLASS_CAPABILITY, CAPABILITY__SYS_CHROOT, "sys_chroot")
-   S_(SECCLASS_CAPABILITY, CAPABILITY__SYS_PTRACE, "sys_ptrace")
-   S_(SECCLASS_CAPABILITY, CAPABILITY__SYS_PACCT, "sys_pacct")
-   S_(SECCLASS_CAPABILITY, CAPABILITY__SYS_ADMIN, "sys_admin")
-   S_(SECCLASS_CAPABILITY, CAPABILITY__SYS_BOOT, "sys_boot")
-   S_(SECCLASS_CAPABILITY, CAPABILITY__SYS_NICE, "sys_nice")
-   S_(SECCLASS_CAPABILITY, CAPABILITY__SYS_RESOURCE, "sys_resource")
-   S_(SECCLASS_CAPABILITY, CAPABILITY__SYS_TIME, "sys_time")
-   S_(SECCLASS_CAPABILITY, CAPABILITY__SYS_TTY_CONFIG, "sys_tty_config")
-   S_(SECCLASS_CAPABILITY, CAPABILITY__MKNOD, "mknod")
-   S_(SECCLASS_CAPABILITY, CAPABILITY__LEASE, "lease")
-   S_(SECCLASS_CAPABILITY, CAPABILITY__AUDIT_WRITE, "audit_write")
-   S_(SECCLASS_CAPABILITY, CAPABILITY__AUDIT_CONTROL, "audit_control")
-   S_(SECCLASS_CAPABILITY, CAPABILITY__SETFCAP, "setfcap")
-   S_(SECCLASS_CAPABILITY2, CAPABILITY2__MAC_OVERRIDE, "mac_override")
-   S_(SECCLASS_CAPABILITY2, CAPABILITY2__MAC_ADMIN, "mac_admin")
-   S_(SECCLASS_NETLINK_ROUTE_SOCKET, NETLINK_ROUTE_SOCKET__NLMSG_READ, "nlmsg_read")
-   S_(SECCLASS_NETLINK_ROUTE_SOCKET, NETLINK_ROUTE_SOCKET__NLMSG_WRITE, "nlmsg_write")
-   S_(SECCLASS_NETLINK_FIREWALL_SOCKET, NETLINK_FIREWALL_SOCKET__NLMSG_READ, "nlmsg_read")
-   S_(SECCLASS_NETLINK_FIREWALL_SOCKET, NETLINK_FIREWALL_SOCKET__NLMSG_WRITE, "nlmsg_write")
-   S_(SECCLASS_NETLINK_TCPDIAG_SOCKET, NETLINK_TCPDIAG_SOCKET__NLMSG_READ, "nlmsg_read")
-   S_(SECCLASS_NETLINK_TCPDIAG_SOCKET, NETLINK_TCPDIAG_SOCKET__NLMSG_WRITE, "nlmsg_write")
-   S_(SECCLASS_NETLINK_XFRM_SOCKET, NETLINK_XFRM_SOCKET__NLMSG_READ, "nlmsg_read")
-   S_(SECCLASS_NETLINK_XFRM_SOCKET, NETLINK_XFRM_SOCKET__NLMSG_WRITE, "nlmsg_write")
-   S_(SECCLASS_NETLINK_AUDIT_SOCKET, NETLINK_AUDIT_SOCKET__NLMSG_READ, "nlmsg_read")
-   S_(SECCLASS_NETLINK_AUDIT_SOCKET, NETLINK_AUDIT_SOCKET__NLMSG_WRITE, "nlmsg_write")
-   S_(SECCLASS_NETLINK_AUDIT_SOCKET, NETLINK_AUDIT_SOCKET__NLMSG_RELAY, "nlmsg_relay")
-   S_(SECCLASS_NETLINK_AUDIT_SOCKET, NETLINK_AUDIT_SOCKET__NLMSG_READPRIV, "nlmsg_readpriv")
-   S_(SECCLASS_NETLINK_AUDIT_SOCKET, NETLINK_AUDIT_SOCKET__NLMSG_TTY_AUDIT, "nlmsg_tty_audit")
-   S_(SECCLASS_NETLINK_IP6FW_SOCKET, NETLINK_IP6FW_SOCKET__NLMSG_READ, "nlmsg_read")
-   S_(SECCLASS_NETLINK_IP6FW_SOCKET, NETLINK_IP6FW_SOCKET__NLMSG_WRITE, "nlmsg_write")
-   S_(SECCLASS_ASSOCIATION, ASSOCIATION__SENDTO, "sendto")
-   S_(SECCLASS_ASSOCIATION, ASSOCIATION__RECVFROM, "recvfrom")
-   S_(SECCLASS_ASSOCIATION, ASSOCIATION__SETCONTEXT, "setcontext")
-   S_(SECCLASS_ASSOCIATION, ASSOCIATION__POLMATCH, "polmatch")
-   S_(SECCLASS_PACKET, PACKET__SEND, "send")
-   S_(SECCLASS_PACKET, PACKET__RECV, "recv")
-   S_(SECCLASS_PACKET, PACKET__RELABELTO, "relabelto")
-   S_(SECCLASS_PACKET, PACKET__FLOW_IN, "flow_in")
-   S_(SECCLASS_PACKET, PACKET__FLOW_OUT, "flow_out")
-   S_(SECCLASS_PACKET, PACKET__FORWARD_IN, "forward_in")
-   S_(SECCLASS_PACKET, PACKET__FORWARD_OUT, "forward_out")
-   S_(SECCLASS_KEY, KEY__VIEW, "view")
-   S_(SECCLASS_KEY, KEY__READ, "read")
-   S_(SECCLASS_KEY, KEY__WRITE, "write")
-   S_(SECCLASS_KEY, KEY__SEARCH, "search")
-   S_(SECCLASS_KEY, KEY__LINK, "link")
-   S_(SECCLASS_KEY, KEY__SETATTR, "setattr")
-   S_(SECCLASS_KEY, KEY__CREATE, "create")
-   S_(SECCLASS_DCCP_SOCKET, DCCP_SOCKET__NODE_BIND, "node_bind")
-   S_(SECCLASS_DCCP_SOCKET, DCCP_SOCKET__NAME_CONNECT, "name_connect")
-   S_(SECCLASS_MEMPROTECT, MEMPROTECT__MMAP_ZERO, "mmap_zero")
-   S_(SECCLASS_PEER, PEER__RECV, "recv")
-   S_(SECCLASS_KERNEL_SERVICE, KERNEL_SERVICE__USE_AS_OVERRIDE, "use_as_override")
-   S_(SECCLASS_KERNEL_SERVICE, KERNEL_SERVICE__CREATE_FILES_AS, "create_files_as")
diff --git a/security/selinux/include/av_permissions.h b/security/selinux/include/av_permissions.h
deleted file mode 100644 (file)
index 0546d61..0000000
+++ /dev/null
@@ -1,870 +0,0 @@
-/* This file is automatically generated.  Do not edit. */
-#define COMMON_FILE__IOCTL                               0x00000001UL
-#define COMMON_FILE__READ                                0x00000002UL
-#define COMMON_FILE__WRITE                               0x00000004UL
-#define COMMON_FILE__CREATE                              0x00000008UL
-#define COMMON_FILE__GETATTR                             0x00000010UL
-#define COMMON_FILE__SETATTR                             0x00000020UL
-#define COMMON_FILE__LOCK                                0x00000040UL
-#define COMMON_FILE__RELABELFROM                         0x00000080UL
-#define COMMON_FILE__RELABELTO                           0x00000100UL
-#define COMMON_FILE__APPEND                              0x00000200UL
-#define COMMON_FILE__UNLINK                              0x00000400UL
-#define COMMON_FILE__LINK                                0x00000800UL
-#define COMMON_FILE__RENAME                              0x00001000UL
-#define COMMON_FILE__EXECUTE                             0x00002000UL
-#define COMMON_FILE__SWAPON                              0x00004000UL
-#define COMMON_FILE__QUOTAON                             0x00008000UL
-#define COMMON_FILE__MOUNTON                             0x00010000UL
-#define COMMON_SOCKET__IOCTL                             0x00000001UL
-#define COMMON_SOCKET__READ                              0x00000002UL
-#define COMMON_SOCKET__WRITE                             0x00000004UL
-#define COMMON_SOCKET__CREATE                            0x00000008UL
-#define COMMON_SOCKET__GETATTR                           0x00000010UL
-#define COMMON_SOCKET__SETATTR                           0x00000020UL
-#define COMMON_SOCKET__LOCK                              0x00000040UL
-#define COMMON_SOCKET__RELABELFROM                       0x00000080UL
-#define COMMON_SOCKET__RELABELTO                         0x00000100UL
-#define COMMON_SOCKET__APPEND                            0x00000200UL
-#define COMMON_SOCKET__BIND                              0x00000400UL
-#define COMMON_SOCKET__CONNECT                           0x00000800UL
-#define COMMON_SOCKET__LISTEN                            0x00001000UL
-#define COMMON_SOCKET__ACCEPT                            0x00002000UL
-#define COMMON_SOCKET__GETOPT                            0x00004000UL
-#define COMMON_SOCKET__SETOPT                            0x00008000UL
-#define COMMON_SOCKET__SHUTDOWN                          0x00010000UL
-#define COMMON_SOCKET__RECVFROM                          0x00020000UL
-#define COMMON_SOCKET__SENDTO                            0x00040000UL
-#define COMMON_SOCKET__RECV_MSG                          0x00080000UL
-#define COMMON_SOCKET__SEND_MSG                          0x00100000UL
-#define COMMON_SOCKET__NAME_BIND                         0x00200000UL
-#define COMMON_IPC__CREATE                               0x00000001UL
-#define COMMON_IPC__DESTROY                              0x00000002UL
-#define COMMON_IPC__GETATTR                              0x00000004UL
-#define COMMON_IPC__SETATTR                              0x00000008UL
-#define COMMON_IPC__READ                                 0x00000010UL
-#define COMMON_IPC__WRITE                                0x00000020UL
-#define COMMON_IPC__ASSOCIATE                            0x00000040UL
-#define COMMON_IPC__UNIX_READ                            0x00000080UL
-#define COMMON_IPC__UNIX_WRITE                           0x00000100UL
-#define FILESYSTEM__MOUNT                         0x00000001UL
-#define FILESYSTEM__REMOUNT                       0x00000002UL
-#define FILESYSTEM__UNMOUNT                       0x00000004UL
-#define FILESYSTEM__GETATTR                       0x00000008UL
-#define FILESYSTEM__RELABELFROM                   0x00000010UL
-#define FILESYSTEM__RELABELTO                     0x00000020UL
-#define FILESYSTEM__TRANSITION                    0x00000040UL
-#define FILESYSTEM__ASSOCIATE                     0x00000080UL
-#define FILESYSTEM__QUOTAMOD                      0x00000100UL
-#define FILESYSTEM__QUOTAGET                      0x00000200UL
-#define DIR__IOCTL                                0x00000001UL
-#define DIR__READ                                 0x00000002UL
-#define DIR__WRITE                                0x00000004UL
-#define DIR__CREATE                               0x00000008UL
-#define DIR__GETATTR                              0x00000010UL
-#define DIR__SETATTR                              0x00000020UL
-#define DIR__LOCK                                 0x00000040UL
-#define DIR__RELABELFROM                          0x00000080UL
-#define DIR__RELABELTO                            0x00000100UL
-#define DIR__APPEND                               0x00000200UL
-#define DIR__UNLINK                               0x00000400UL
-#define DIR__LINK                                 0x00000800UL
-#define DIR__RENAME                               0x00001000UL
-#define DIR__EXECUTE                              0x00002000UL
-#define DIR__SWAPON                               0x00004000UL
-#define DIR__QUOTAON                              0x00008000UL
-#define DIR__MOUNTON                              0x00010000UL
-#define DIR__ADD_NAME                             0x00020000UL
-#define DIR__REMOVE_NAME                          0x00040000UL
-#define DIR__REPARENT                             0x00080000UL
-#define DIR__SEARCH                               0x00100000UL
-#define DIR__RMDIR                                0x00200000UL
-#define DIR__OPEN                                 0x00400000UL
-#define FILE__IOCTL                               0x00000001UL
-#define FILE__READ                                0x00000002UL
-#define FILE__WRITE                               0x00000004UL
-#define FILE__CREATE                              0x00000008UL
-#define FILE__GETATTR                             0x00000010UL
-#define FILE__SETATTR                             0x00000020UL
-#define FILE__LOCK                                0x00000040UL
-#define FILE__RELABELFROM                         0x00000080UL
-#define FILE__RELABELTO                           0x00000100UL
-#define FILE__APPEND                              0x00000200UL
-#define FILE__UNLINK                              0x00000400UL
-#define FILE__LINK                                0x00000800UL
-#define FILE__RENAME                              0x00001000UL
-#define FILE__EXECUTE                             0x00002000UL
-#define FILE__SWAPON                              0x00004000UL
-#define FILE__QUOTAON                             0x00008000UL
-#define FILE__MOUNTON                             0x00010000UL
-#define FILE__EXECUTE_NO_TRANS                    0x00020000UL
-#define FILE__ENTRYPOINT                          0x00040000UL
-#define FILE__EXECMOD                             0x00080000UL
-#define FILE__OPEN                                0x00100000UL
-#define LNK_FILE__IOCTL                           0x00000001UL
-#define LNK_FILE__READ                            0x00000002UL
-#define LNK_FILE__WRITE                           0x00000004UL
-#define LNK_FILE__CREATE                          0x00000008UL
-#define LNK_FILE__GETATTR                         0x00000010UL
-#define LNK_FILE__SETATTR                         0x00000020UL
-#define LNK_FILE__LOCK                            0x00000040UL
-#define LNK_FILE__RELABELFROM                     0x00000080UL
-#define LNK_FILE__RELABELTO                       0x00000100UL
-#define LNK_FILE__APPEND                          0x00000200UL
-#define LNK_FILE__UNLINK                          0x00000400UL
-#define LNK_FILE__LINK                            0x00000800UL
-#define LNK_FILE__RENAME                          0x00001000UL
-#define LNK_FILE__EXECUTE                         0x00002000UL
-#define LNK_FILE__SWAPON                          0x00004000UL
-#define LNK_FILE__QUOTAON                         0x00008000UL
-#define LNK_FILE__MOUNTON                         0x00010000UL
-#define CHR_FILE__IOCTL                           0x00000001UL
-#define CHR_FILE__READ                            0x00000002UL
-#define CHR_FILE__WRITE                           0x00000004UL
-#define CHR_FILE__CREATE                          0x00000008UL
-#define CHR_FILE__GETATTR                         0x00000010UL
-#define CHR_FILE__SETATTR                         0x00000020UL
-#define CHR_FILE__LOCK                            0x00000040UL
-#define CHR_FILE__RELABELFROM                     0x00000080UL
-#define CHR_FILE__RELABELTO                       0x00000100UL
-#define CHR_FILE__APPEND                          0x00000200UL
-#define CHR_FILE__UNLINK                          0x00000400UL
-#define CHR_FILE__LINK                            0x00000800UL
-#define CHR_FILE__RENAME                          0x00001000UL
-#define CHR_FILE__EXECUTE                         0x00002000UL
-#define CHR_FILE__SWAPON                          0x00004000UL
-#define CHR_FILE__QUOTAON                         0x00008000UL
-#define CHR_FILE__MOUNTON                         0x00010000UL
-#define CHR_FILE__EXECUTE_NO_TRANS                0x00020000UL
-#define CHR_FILE__ENTRYPOINT                      0x00040000UL
-#define CHR_FILE__EXECMOD                         0x00080000UL
-#define CHR_FILE__OPEN                            0x00100000UL
-#define BLK_FILE__IOCTL                           0x00000001UL
-#define BLK_FILE__READ                            0x00000002UL
-#define BLK_FILE__WRITE                           0x00000004UL
-#define BLK_FILE__CREATE                          0x00000008UL
-#define BLK_FILE__GETATTR                         0x00000010UL
-#define BLK_FILE__SETATTR                         0x00000020UL
-#define BLK_FILE__LOCK                            0x00000040UL
-#define BLK_FILE__RELABELFROM                     0x00000080UL
-#define BLK_FILE__RELABELTO                       0x00000100UL
-#define BLK_FILE__APPEND                          0x00000200UL
-#define BLK_FILE__UNLINK                          0x00000400UL
-#define BLK_FILE__LINK                            0x00000800UL
-#define BLK_FILE__RENAME                          0x00001000UL
-#define BLK_FILE__EXECUTE                         0x00002000UL
-#define BLK_FILE__SWAPON                          0x00004000UL
-#define BLK_FILE__QUOTAON                         0x00008000UL
-#define BLK_FILE__MOUNTON                         0x00010000UL
-#define BLK_FILE__OPEN                            0x00020000UL
-#define SOCK_FILE__IOCTL                          0x00000001UL
-#define SOCK_FILE__READ                           0x00000002UL
-#define SOCK_FILE__WRITE                          0x00000004UL
-#define SOCK_FILE__CREATE                         0x00000008UL
-#define SOCK_FILE__GETATTR                        0x00000010UL
-#define SOCK_FILE__SETATTR                        0x00000020UL
-#define SOCK_FILE__LOCK                           0x00000040UL
-#define SOCK_FILE__RELABELFROM                    0x00000080UL
-#define SOCK_FILE__RELABELTO                      0x00000100UL
-#define SOCK_FILE__APPEND                         0x00000200UL
-#define SOCK_FILE__UNLINK                         0x00000400UL
-#define SOCK_FILE__LINK                           0x00000800UL
-#define SOCK_FILE__RENAME                         0x00001000UL
-#define SOCK_FILE__EXECUTE                        0x00002000UL
-#define SOCK_FILE__SWAPON                         0x00004000UL
-#define SOCK_FILE__QUOTAON                        0x00008000UL
-#define SOCK_FILE__MOUNTON                        0x00010000UL
-#define SOCK_FILE__OPEN                           0x00020000UL
-#define FIFO_FILE__IOCTL                          0x00000001UL
-#define FIFO_FILE__READ                           0x00000002UL
-#define FIFO_FILE__WRITE                          0x00000004UL
-#define FIFO_FILE__CREATE                         0x00000008UL
-#define FIFO_FILE__GETATTR                        0x00000010UL
-#define FIFO_FILE__SETATTR                        0x00000020UL
-#define FIFO_FILE__LOCK                           0x00000040UL
-#define FIFO_FILE__RELABELFROM                    0x00000080UL
-#define FIFO_FILE__RELABELTO                      0x00000100UL
-#define FIFO_FILE__APPEND                         0x00000200UL
-#define FIFO_FILE__UNLINK                         0x00000400UL
-#define FIFO_FILE__LINK                           0x00000800UL
-#define FIFO_FILE__RENAME                         0x00001000UL
-#define FIFO_FILE__EXECUTE                        0x00002000UL
-#define FIFO_FILE__SWAPON                         0x00004000UL
-#define FIFO_FILE__QUOTAON                        0x00008000UL
-#define FIFO_FILE__MOUNTON                        0x00010000UL
-#define FIFO_FILE__OPEN                           0x00020000UL
-#define FD__USE                                   0x00000001UL
-#define SOCKET__IOCTL                             0x00000001UL
-#define SOCKET__READ                              0x00000002UL
-#define SOCKET__WRITE                             0x00000004UL
-#define SOCKET__CREATE                            0x00000008UL
-#define SOCKET__GETATTR                           0x00000010UL
-#define SOCKET__SETATTR                           0x00000020UL
-#define SOCKET__LOCK                              0x00000040UL
-#define SOCKET__RELABELFROM                       0x00000080UL
-#define SOCKET__RELABELTO                         0x00000100UL
-#define SOCKET__APPEND                            0x00000200UL
-#define SOCKET__BIND                              0x00000400UL
-#define SOCKET__CONNECT                           0x00000800UL
-#define SOCKET__LISTEN                            0x00001000UL
-#define SOCKET__ACCEPT                            0x00002000UL
-#define SOCKET__GETOPT                            0x00004000UL
-#define SOCKET__SETOPT                            0x00008000UL
-#define SOCKET__SHUTDOWN                          0x00010000UL
-#define SOCKET__RECVFROM                          0x00020000UL
-#define SOCKET__SENDTO                            0x00040000UL
-#define SOCKET__RECV_MSG                          0x00080000UL
-#define SOCKET__SEND_MSG                          0x00100000UL
-#define SOCKET__NAME_BIND                         0x00200000UL
-#define TCP_SOCKET__IOCTL                         0x00000001UL
-#define TCP_SOCKET__READ                          0x00000002UL
-#define TCP_SOCKET__WRITE                         0x00000004UL
-#define TCP_SOCKET__CREATE                        0x00000008UL
-#define TCP_SOCKET__GETATTR                       0x00000010UL
-#define TCP_SOCKET__SETATTR                       0x00000020UL
-#define TCP_SOCKET__LOCK                          0x00000040UL
-#define TCP_SOCKET__RELABELFROM                   0x00000080UL
-#define TCP_SOCKET__RELABELTO                     0x00000100UL
-#define TCP_SOCKET__APPEND                        0x00000200UL
-#define TCP_SOCKET__BIND                          0x00000400UL
-#define TCP_SOCKET__CONNECT                       0x00000800UL
-#define TCP_SOCKET__LISTEN                        0x00001000UL
-#define TCP_SOCKET__ACCEPT                        0x00002000UL
-#define TCP_SOCKET__GETOPT                        0x00004000UL
-#define TCP_SOCKET__SETOPT                        0x00008000UL
-#define TCP_SOCKET__SHUTDOWN                      0x00010000UL
-#define TCP_SOCKET__RECVFROM                      0x00020000UL
-#define TCP_SOCKET__SENDTO                        0x00040000UL
-#define TCP_SOCKET__RECV_MSG                      0x00080000UL
-#define TCP_SOCKET__SEND_MSG                      0x00100000UL
-#define TCP_SOCKET__NAME_BIND                     0x00200000UL
-#define TCP_SOCKET__CONNECTTO                     0x00400000UL
-#define TCP_SOCKET__NEWCONN                       0x00800000UL
-#define TCP_SOCKET__ACCEPTFROM                    0x01000000UL
-#define TCP_SOCKET__NODE_BIND                     0x02000000UL
-#define TCP_SOCKET__NAME_CONNECT                  0x04000000UL
-#define UDP_SOCKET__IOCTL                         0x00000001UL
-#define UDP_SOCKET__READ                          0x00000002UL
-#define UDP_SOCKET__WRITE                         0x00000004UL
-#define UDP_SOCKET__CREATE                        0x00000008UL
-#define UDP_SOCKET__GETATTR                       0x00000010UL
-#define UDP_SOCKET__SETATTR                       0x00000020UL
-#define UDP_SOCKET__LOCK                          0x00000040UL
-#define UDP_SOCKET__RELABELFROM                   0x00000080UL
-#define UDP_SOCKET__RELABELTO                     0x00000100UL
-#define UDP_SOCKET__APPEND                        0x00000200UL
-#define UDP_SOCKET__BIND                          0x00000400UL
-#define UDP_SOCKET__CONNECT                       0x00000800UL
-#define UDP_SOCKET__LISTEN                        0x00001000UL
-#define UDP_SOCKET__ACCEPT                        0x00002000UL
-#define UDP_SOCKET__GETOPT                        0x00004000UL
-#define UDP_SOCKET__SETOPT                        0x00008000UL
-#define UDP_SOCKET__SHUTDOWN                      0x00010000UL
-#define UDP_SOCKET__RECVFROM                      0x00020000UL
-#define UDP_SOCKET__SENDTO                        0x00040000UL
-#define UDP_SOCKET__RECV_MSG                      0x00080000UL
-#define UDP_SOCKET__SEND_MSG                      0x00100000UL
-#define UDP_SOCKET__NAME_BIND                     0x00200000UL
-#define UDP_SOCKET__NODE_BIND                     0x00400000UL
-#define RAWIP_SOCKET__IOCTL                       0x00000001UL
-#define RAWIP_SOCKET__READ                        0x00000002UL
-#define RAWIP_SOCKET__WRITE                       0x00000004UL
-#define RAWIP_SOCKET__CREATE                      0x00000008UL
-#define RAWIP_SOCKET__GETATTR                     0x00000010UL
-#define RAWIP_SOCKET__SETATTR                     0x00000020UL
-#define RAWIP_SOCKET__LOCK                        0x00000040UL
-#define RAWIP_SOCKET__RELABELFROM                 0x00000080UL
-#define RAWIP_SOCKET__RELABELTO                   0x00000100UL
-#define RAWIP_SOCKET__APPEND                      0x00000200UL
-#define RAWIP_SOCKET__BIND                        0x00000400UL
-#define RAWIP_SOCKET__CONNECT                     0x00000800UL
-#define RAWIP_SOCKET__LISTEN                      0x00001000UL
-#define RAWIP_SOCKET__ACCEPT                      0x00002000UL
-#define RAWIP_SOCKET__GETOPT                      0x00004000UL
-#define RAWIP_SOCKET__SETOPT                      0x00008000UL
-#define RAWIP_SOCKET__SHUTDOWN                    0x00010000UL
-#define RAWIP_SOCKET__RECVFROM                    0x00020000UL
-#define RAWIP_SOCKET__SENDTO                      0x00040000UL
-#define RAWIP_SOCKET__RECV_MSG                    0x00080000UL
-#define RAWIP_SOCKET__SEND_MSG                    0x00100000UL
-#define RAWIP_SOCKET__NAME_BIND                   0x00200000UL
-#define RAWIP_SOCKET__NODE_BIND                   0x00400000UL
-#define NODE__TCP_RECV                            0x00000001UL
-#define NODE__TCP_SEND                            0x00000002UL
-#define NODE__UDP_RECV                            0x00000004UL
-#define NODE__UDP_SEND                            0x00000008UL
-#define NODE__RAWIP_RECV                          0x00000010UL
-#define NODE__RAWIP_SEND                          0x00000020UL
-#define NODE__ENFORCE_DEST                        0x00000040UL
-#define NODE__DCCP_RECV                           0x00000080UL
-#define NODE__DCCP_SEND                           0x00000100UL
-#define NODE__RECVFROM                            0x00000200UL
-#define NODE__SENDTO                              0x00000400UL
-#define NETIF__TCP_RECV                           0x00000001UL
-#define NETIF__TCP_SEND                           0x00000002UL
-#define NETIF__UDP_RECV                           0x00000004UL
-#define NETIF__UDP_SEND                           0x00000008UL
-#define NETIF__RAWIP_RECV                         0x00000010UL
-#define NETIF__RAWIP_SEND                         0x00000020UL
-#define NETIF__DCCP_RECV                          0x00000040UL
-#define NETIF__DCCP_SEND                          0x00000080UL
-#define NETIF__INGRESS                            0x00000100UL
-#define NETIF__EGRESS                             0x00000200UL
-#define NETLINK_SOCKET__IOCTL                     0x00000001UL
-#define NETLINK_SOCKET__READ                      0x00000002UL
-#define NETLINK_SOCKET__WRITE                     0x00000004UL
-#define NETLINK_SOCKET__CREATE                    0x00000008UL
-#define NETLINK_SOCKET__GETATTR                   0x00000010UL
-#define NETLINK_SOCKET__SETATTR                   0x00000020UL
-#define NETLINK_SOCKET__LOCK                      0x00000040UL
-#define NETLINK_SOCKET__RELABELFROM               0x00000080UL
-#define NETLINK_SOCKET__RELABELTO                 0x00000100UL
-#define NETLINK_SOCKET__APPEND                    0x00000200UL
-#define NETLINK_SOCKET__BIND                      0x00000400UL
-#define NETLINK_SOCKET__CONNECT                   0x00000800UL
-#define NETLINK_SOCKET__LISTEN                    0x00001000UL
-#define NETLINK_SOCKET__ACCEPT                    0x00002000UL
-#define NETLINK_SOCKET__GETOPT                    0x00004000UL
-#define NETLINK_SOCKET__SETOPT                    0x00008000UL
-#define NETLINK_SOCKET__SHUTDOWN                  0x00010000UL
-#define NETLINK_SOCKET__RECVFROM                  0x00020000UL
-#define NETLINK_SOCKET__SENDTO                    0x00040000UL
-#define NETLINK_SOCKET__RECV_MSG                  0x00080000UL
-#define NETLINK_SOCKET__SEND_MSG                  0x00100000UL
-#define NETLINK_SOCKET__NAME_BIND                 0x00200000UL
-#define PACKET_SOCKET__IOCTL                      0x00000001UL
-#define PACKET_SOCKET__READ                       0x00000002UL
-#define PACKET_SOCKET__WRITE                      0x00000004UL
-#define PACKET_SOCKET__CREATE                     0x00000008UL
-#define PACKET_SOCKET__GETATTR                    0x00000010UL
-#define PACKET_SOCKET__SETATTR                    0x00000020UL
-#define PACKET_SOCKET__LOCK                       0x00000040UL
-#define PACKET_SOCKET__RELABELFROM                0x00000080UL
-#define PACKET_SOCKET__RELABELTO                  0x00000100UL
-#define PACKET_SOCKET__APPEND                     0x00000200UL
-#define PACKET_SOCKET__BIND                       0x00000400UL
-#define PACKET_SOCKET__CONNECT                    0x00000800UL
-#define PACKET_SOCKET__LISTEN                     0x00001000UL
-#define PACKET_SOCKET__ACCEPT                     0x00002000UL
-#define PACKET_SOCKET__GETOPT                     0x00004000UL
-#define PACKET_SOCKET__SETOPT                     0x00008000UL
-#define PACKET_SOCKET__SHUTDOWN                   0x00010000UL
-#define PACKET_SOCKET__RECVFROM                   0x00020000UL
-#define PACKET_SOCKET__SENDTO                     0x00040000UL
-#define PACKET_SOCKET__RECV_MSG                   0x00080000UL
-#define PACKET_SOCKET__SEND_MSG                   0x00100000UL
-#define PACKET_SOCKET__NAME_BIND                  0x00200000UL
-#define KEY_SOCKET__IOCTL                         0x00000001UL
-#define KEY_SOCKET__READ                          0x00000002UL
-#define KEY_SOCKET__WRITE                         0x00000004UL
-#define KEY_SOCKET__CREATE                        0x00000008UL
-#define KEY_SOCKET__GETATTR                       0x00000010UL
-#define KEY_SOCKET__SETATTR                       0x00000020UL
-#define KEY_SOCKET__LOCK                          0x00000040UL
-#define KEY_SOCKET__RELABELFROM                   0x00000080UL
-#define KEY_SOCKET__RELABELTO                     0x00000100UL
-#define KEY_SOCKET__APPEND                        0x00000200UL
-#define KEY_SOCKET__BIND                          0x00000400UL
-#define KEY_SOCKET__CONNECT                       0x00000800UL
-#define KEY_SOCKET__LISTEN                        0x00001000UL
-#define KEY_SOCKET__ACCEPT                        0x00002000UL
-#define KEY_SOCKET__GETOPT                        0x00004000UL
-#define KEY_SOCKET__SETOPT                        0x00008000UL
-#define KEY_SOCKET__SHUTDOWN                      0x00010000UL
-#define KEY_SOCKET__RECVFROM                      0x00020000UL
-#define KEY_SOCKET__SENDTO                        0x00040000UL
-#define KEY_SOCKET__RECV_MSG                      0x00080000UL
-#define KEY_SOCKET__SEND_MSG                      0x00100000UL
-#define KEY_SOCKET__NAME_BIND                     0x00200000UL
-#define UNIX_STREAM_SOCKET__IOCTL                 0x00000001UL
-#define UNIX_STREAM_SOCKET__READ                  0x00000002UL
-#define UNIX_STREAM_SOCKET__WRITE                 0x00000004UL
-#define UNIX_STREAM_SOCKET__CREATE                0x00000008UL
-#define UNIX_STREAM_SOCKET__GETATTR               0x00000010UL
-#define UNIX_STREAM_SOCKET__SETATTR               0x00000020UL
-#define UNIX_STREAM_SOCKET__LOCK                  0x00000040UL
-#define UNIX_STREAM_SOCKET__RELABELFROM           0x00000080UL
-#define UNIX_STREAM_SOCKET__RELABELTO             0x00000100UL
-#define UNIX_STREAM_SOCKET__APPEND                0x00000200UL
-#define UNIX_STREAM_SOCKET__BIND                  0x00000400UL
-#define UNIX_STREAM_SOCKET__CONNECT               0x00000800UL
-#define UNIX_STREAM_SOCKET__LISTEN                0x00001000UL
-#define UNIX_STREAM_SOCKET__ACCEPT                0x00002000UL
-#define UNIX_STREAM_SOCKET__GETOPT                0x00004000UL
-#define UNIX_STREAM_SOCKET__SETOPT                0x00008000UL
-#define UNIX_STREAM_SOCKET__SHUTDOWN              0x00010000UL
-#define UNIX_STREAM_SOCKET__RECVFROM              0x00020000UL
-#define UNIX_STREAM_SOCKET__SENDTO                0x00040000UL
-#define UNIX_STREAM_SOCKET__RECV_MSG              0x00080000UL
-#define UNIX_STREAM_SOCKET__SEND_MSG              0x00100000UL
-#define UNIX_STREAM_SOCKET__NAME_BIND             0x00200000UL
-#define UNIX_STREAM_SOCKET__CONNECTTO             0x00400000UL
-#define UNIX_STREAM_SOCKET__NEWCONN               0x00800000UL
-#define UNIX_STREAM_SOCKET__ACCEPTFROM            0x01000000UL
-#define UNIX_DGRAM_SOCKET__IOCTL                  0x00000001UL
-#define UNIX_DGRAM_SOCKET__READ                   0x00000002UL
-#define UNIX_DGRAM_SOCKET__WRITE                  0x00000004UL
-#define UNIX_DGRAM_SOCKET__CREATE                 0x00000008UL
-#define UNIX_DGRAM_SOCKET__GETATTR                0x00000010UL
-#define UNIX_DGRAM_SOCKET__SETATTR                0x00000020UL
-#define UNIX_DGRAM_SOCKET__LOCK                   0x00000040UL
-#define UNIX_DGRAM_SOCKET__RELABELFROM            0x00000080UL
-#define UNIX_DGRAM_SOCKET__RELABELTO              0x00000100UL
-#define UNIX_DGRAM_SOCKET__APPEND                 0x00000200UL
-#define UNIX_DGRAM_SOCKET__BIND                   0x00000400UL
-#define UNIX_DGRAM_SOCKET__CONNECT                0x00000800UL
-#define UNIX_DGRAM_SOCKET__LISTEN                 0x00001000UL
-#define UNIX_DGRAM_SOCKET__ACCEPT                 0x00002000UL
-#define UNIX_DGRAM_SOCKET__GETOPT                 0x00004000UL
-#define UNIX_DGRAM_SOCKET__SETOPT                 0x00008000UL
-#define UNIX_DGRAM_SOCKET__SHUTDOWN               0x00010000UL
-#define UNIX_DGRAM_SOCKET__RECVFROM               0x00020000UL
-#define UNIX_DGRAM_SOCKET__SENDTO                 0x00040000UL
-#define UNIX_DGRAM_SOCKET__RECV_MSG               0x00080000UL
-#define UNIX_DGRAM_SOCKET__SEND_MSG               0x00100000UL
-#define UNIX_DGRAM_SOCKET__NAME_BIND              0x00200000UL
-#define TUN_SOCKET__IOCTL                         0x00000001UL
-#define TUN_SOCKET__READ                          0x00000002UL
-#define TUN_SOCKET__WRITE                         0x00000004UL
-#define TUN_SOCKET__CREATE                        0x00000008UL
-#define TUN_SOCKET__GETATTR                       0x00000010UL
-#define TUN_SOCKET__SETATTR                       0x00000020UL
-#define TUN_SOCKET__LOCK                          0x00000040UL
-#define TUN_SOCKET__RELABELFROM                   0x00000080UL
-#define TUN_SOCKET__RELABELTO                     0x00000100UL
-#define TUN_SOCKET__APPEND                        0x00000200UL
-#define TUN_SOCKET__BIND                          0x00000400UL
-#define TUN_SOCKET__CONNECT                       0x00000800UL
-#define TUN_SOCKET__LISTEN                        0x00001000UL
-#define TUN_SOCKET__ACCEPT                        0x00002000UL
-#define TUN_SOCKET__GETOPT                        0x00004000UL
-#define TUN_SOCKET__SETOPT                        0x00008000UL
-#define TUN_SOCKET__SHUTDOWN                      0x00010000UL
-#define TUN_SOCKET__RECVFROM                      0x00020000UL
-#define TUN_SOCKET__SENDTO                        0x00040000UL
-#define TUN_SOCKET__RECV_MSG                      0x00080000UL
-#define TUN_SOCKET__SEND_MSG                      0x00100000UL
-#define TUN_SOCKET__NAME_BIND                     0x00200000UL
-#define PROCESS__FORK                             0x00000001UL
-#define PROCESS__TRANSITION                       0x00000002UL
-#define PROCESS__SIGCHLD                          0x00000004UL
-#define PROCESS__SIGKILL                          0x00000008UL
-#define PROCESS__SIGSTOP                          0x00000010UL
-#define PROCESS__SIGNULL                          0x00000020UL
-#define PROCESS__SIGNAL                           0x00000040UL
-#define PROCESS__PTRACE                           0x00000080UL
-#define PROCESS__GETSCHED                         0x00000100UL
-#define PROCESS__SETSCHED                         0x00000200UL
-#define PROCESS__GETSESSION                       0x00000400UL
-#define PROCESS__GETPGID                          0x00000800UL
-#define PROCESS__SETPGID                          0x00001000UL
-#define PROCESS__GETCAP                           0x00002000UL
-#define PROCESS__SETCAP                           0x00004000UL
-#define PROCESS__SHARE                            0x00008000UL
-#define PROCESS__GETATTR                          0x00010000UL
-#define PROCESS__SETEXEC                          0x00020000UL
-#define PROCESS__SETFSCREATE                      0x00040000UL
-#define PROCESS__NOATSECURE                       0x00080000UL
-#define PROCESS__SIGINH                           0x00100000UL
-#define PROCESS__SETRLIMIT                        0x00200000UL
-#define PROCESS__RLIMITINH                        0x00400000UL
-#define PROCESS__DYNTRANSITION                    0x00800000UL
-#define PROCESS__SETCURRENT                       0x01000000UL
-#define PROCESS__EXECMEM                          0x02000000UL
-#define PROCESS__EXECSTACK                        0x04000000UL
-#define PROCESS__EXECHEAP                         0x08000000UL
-#define PROCESS__SETKEYCREATE                     0x10000000UL
-#define PROCESS__SETSOCKCREATE                    0x20000000UL
-#define IPC__CREATE                               0x00000001UL
-#define IPC__DESTROY                              0x00000002UL
-#define IPC__GETATTR                              0x00000004UL
-#define IPC__SETATTR                              0x00000008UL
-#define IPC__READ                                 0x00000010UL
-#define IPC__WRITE                                0x00000020UL
-#define IPC__ASSOCIATE                            0x00000040UL
-#define IPC__UNIX_READ                            0x00000080UL
-#define IPC__UNIX_WRITE                           0x00000100UL
-#define SEM__CREATE                               0x00000001UL
-#define SEM__DESTROY                              0x00000002UL
-#define SEM__GETATTR                              0x00000004UL
-#define SEM__SETATTR                              0x00000008UL
-#define SEM__READ                                 0x00000010UL
-#define SEM__WRITE                                0x00000020UL
-#define SEM__ASSOCIATE                            0x00000040UL
-#define SEM__UNIX_READ                            0x00000080UL
-#define SEM__UNIX_WRITE                           0x00000100UL
-#define MSGQ__CREATE                              0x00000001UL
-#define MSGQ__DESTROY                             0x00000002UL
-#define MSGQ__GETATTR                             0x00000004UL
-#define MSGQ__SETATTR                             0x00000008UL
-#define MSGQ__READ                                0x00000010UL
-#define MSGQ__WRITE                               0x00000020UL
-#define MSGQ__ASSOCIATE                           0x00000040UL
-#define MSGQ__UNIX_READ                           0x00000080UL
-#define MSGQ__UNIX_WRITE                          0x00000100UL
-#define MSGQ__ENQUEUE                             0x00000200UL
-#define MSG__SEND                                 0x00000001UL
-#define MSG__RECEIVE                              0x00000002UL
-#define SHM__CREATE                               0x00000001UL
-#define SHM__DESTROY                              0x00000002UL
-#define SHM__GETATTR                              0x00000004UL
-#define SHM__SETATTR                              0x00000008UL
-#define SHM__READ                                 0x00000010UL
-#define SHM__WRITE                                0x00000020UL
-#define SHM__ASSOCIATE                            0x00000040UL
-#define SHM__UNIX_READ                            0x00000080UL
-#define SHM__UNIX_WRITE                           0x00000100UL
-#define SHM__LOCK                                 0x00000200UL
-#define SECURITY__COMPUTE_AV                      0x00000001UL
-#define SECURITY__COMPUTE_CREATE                  0x00000002UL
-#define SECURITY__COMPUTE_MEMBER                  0x00000004UL
-#define SECURITY__CHECK_CONTEXT                   0x00000008UL
-#define SECURITY__LOAD_POLICY                     0x00000010UL
-#define SECURITY__COMPUTE_RELABEL                 0x00000020UL
-#define SECURITY__COMPUTE_USER                    0x00000040UL
-#define SECURITY__SETENFORCE                      0x00000080UL
-#define SECURITY__SETBOOL                         0x00000100UL
-#define SECURITY__SETSECPARAM                     0x00000200UL
-#define SECURITY__SETCHECKREQPROT                 0x00000400UL
-#define SYSTEM__IPC_INFO                          0x00000001UL
-#define SYSTEM__SYSLOG_READ                       0x00000002UL
-#define SYSTEM__SYSLOG_MOD                        0x00000004UL
-#define SYSTEM__SYSLOG_CONSOLE                    0x00000008UL
-#define SYSTEM__MODULE_REQUEST                    0x00000010UL
-#define CAPABILITY__CHOWN                         0x00000001UL
-#define CAPABILITY__DAC_OVERRIDE                  0x00000002UL
-#define CAPABILITY__DAC_READ_SEARCH               0x00000004UL
-#define CAPABILITY__FOWNER                        0x00000008UL
-#define CAPABILITY__FSETID                        0x00000010UL
-#define CAPABILITY__KILL                          0x00000020UL
-#define CAPABILITY__SETGID                        0x00000040UL
-#define CAPABILITY__SETUID                        0x00000080UL
-#define CAPABILITY__SETPCAP                       0x00000100UL
-#define CAPABILITY__LINUX_IMMUTABLE               0x00000200UL
-#define CAPABILITY__NET_BIND_SERVICE              0x00000400UL
-#define CAPABILITY__NET_BROADCAST                 0x00000800UL
-#define CAPABILITY__NET_ADMIN                     0x00001000UL
-#define CAPABILITY__NET_RAW                       0x00002000UL
-#define CAPABILITY__IPC_LOCK                      0x00004000UL
-#define CAPABILITY__IPC_OWNER                     0x00008000UL
-#define CAPABILITY__SYS_MODULE                    0x00010000UL
-#define CAPABILITY__SYS_RAWIO                     0x00020000UL
-#define CAPABILITY__SYS_CHROOT                    0x00040000UL
-#define CAPABILITY__SYS_PTRACE                    0x00080000UL
-#define CAPABILITY__SYS_PACCT                     0x00100000UL
-#define CAPABILITY__SYS_ADMIN                     0x00200000UL
-#define CAPABILITY__SYS_BOOT                      0x00400000UL
-#define CAPABILITY__SYS_NICE                      0x00800000UL
-#define CAPABILITY__SYS_RESOURCE                  0x01000000UL
-#define CAPABILITY__SYS_TIME                      0x02000000UL
-#define CAPABILITY__SYS_TTY_CONFIG                0x04000000UL
-#define CAPABILITY__MKNOD                         0x08000000UL
-#define CAPABILITY__LEASE                         0x10000000UL
-#define CAPABILITY__AUDIT_WRITE                   0x20000000UL
-#define CAPABILITY__AUDIT_CONTROL                 0x40000000UL
-#define CAPABILITY__SETFCAP                       0x80000000UL
-#define CAPABILITY2__MAC_OVERRIDE                 0x00000001UL
-#define CAPABILITY2__MAC_ADMIN                    0x00000002UL
-#define NETLINK_ROUTE_SOCKET__IOCTL               0x00000001UL
-#define NETLINK_ROUTE_SOCKET__READ                0x00000002UL
-#define NETLINK_ROUTE_SOCKET__WRITE               0x00000004UL
-#define NETLINK_ROUTE_SOCKET__CREATE              0x00000008UL
-#define NETLINK_ROUTE_SOCKET__GETATTR             0x00000010UL
-#define NETLINK_ROUTE_SOCKET__SETATTR             0x00000020UL
-#define NETLINK_ROUTE_SOCKET__LOCK                0x00000040UL
-#define NETLINK_ROUTE_SOCKET__RELABELFROM         0x00000080UL
-#define NETLINK_ROUTE_SOCKET__RELABELTO           0x00000100UL
-#define NETLINK_ROUTE_SOCKET__APPEND              0x00000200UL
-#define NETLINK_ROUTE_SOCKET__BIND                0x00000400UL
-#define NETLINK_ROUTE_SOCKET__CONNECT             0x00000800UL
-#define NETLINK_ROUTE_SOCKET__LISTEN              0x00001000UL
-#define NETLINK_ROUTE_SOCKET__ACCEPT              0x00002000UL
-#define NETLINK_ROUTE_SOCKET__GETOPT              0x00004000UL
-#define NETLINK_ROUTE_SOCKET__SETOPT              0x00008000UL
-#define NETLINK_ROUTE_SOCKET__SHUTDOWN            0x00010000UL
-#define NETLINK_ROUTE_SOCKET__RECVFROM            0x00020000UL
-#define NETLINK_ROUTE_SOCKET__SENDTO              0x00040000UL
-#define NETLINK_ROUTE_SOCKET__RECV_MSG            0x00080000UL
-#define NETLINK_ROUTE_SOCKET__SEND_MSG            0x00100000UL
-#define NETLINK_ROUTE_SOCKET__NAME_BIND           0x00200000UL
-#define NETLINK_ROUTE_SOCKET__NLMSG_READ          0x00400000UL
-#define NETLINK_ROUTE_SOCKET__NLMSG_WRITE         0x00800000UL
-#define NETLINK_FIREWALL_SOCKET__IOCTL            0x00000001UL
-#define NETLINK_FIREWALL_SOCKET__READ             0x00000002UL
-#define NETLINK_FIREWALL_SOCKET__WRITE            0x00000004UL
-#define NETLINK_FIREWALL_SOCKET__CREATE           0x00000008UL
-#define NETLINK_FIREWALL_SOCKET__GETATTR          0x00000010UL
-#define NETLINK_FIREWALL_SOCKET__SETATTR          0x00000020UL
-#define NETLINK_FIREWALL_SOCKET__LOCK             0x00000040UL
-#define NETLINK_FIREWALL_SOCKET__RELABELFROM      0x00000080UL
-#define NETLINK_FIREWALL_SOCKET__RELABELTO        0x00000100UL
-#define NETLINK_FIREWALL_SOCKET__APPEND           0x00000200UL
-#define NETLINK_FIREWALL_SOCKET__BIND             0x00000400UL
-#define NETLINK_FIREWALL_SOCKET__CONNECT          0x00000800UL
-#define NETLINK_FIREWALL_SOCKET__LISTEN           0x00001000UL
-#define NETLINK_FIREWALL_SOCKET__ACCEPT           0x00002000UL
-#define NETLINK_FIREWALL_SOCKET__GETOPT           0x00004000UL
-#define NETLINK_FIREWALL_SOCKET__SETOPT           0x00008000UL
-#define NETLINK_FIREWALL_SOCKET__SHUTDOWN         0x00010000UL
-#define NETLINK_FIREWALL_SOCKET__RECVFROM         0x00020000UL
-#define NETLINK_FIREWALL_SOCKET__SENDTO           0x00040000UL
-#define NETLINK_FIREWALL_SOCKET__RECV_MSG         0x00080000UL
-#define NETLINK_FIREWALL_SOCKET__SEND_MSG         0x00100000UL
-#define NETLINK_FIREWALL_SOCKET__NAME_BIND        0x00200000UL
-#define NETLINK_FIREWALL_SOCKET__NLMSG_READ       0x00400000UL
-#define NETLINK_FIREWALL_SOCKET__NLMSG_WRITE      0x00800000UL
-#define NETLINK_TCPDIAG_SOCKET__IOCTL             0x00000001UL
-#define NETLINK_TCPDIAG_SOCKET__READ              0x00000002UL
-#define NETLINK_TCPDIAG_SOCKET__WRITE             0x00000004UL
-#define NETLINK_TCPDIAG_SOCKET__CREATE            0x00000008UL
-#define NETLINK_TCPDIAG_SOCKET__GETATTR           0x00000010UL
-#define NETLINK_TCPDIAG_SOCKET__SETATTR           0x00000020UL
-#define NETLINK_TCPDIAG_SOCKET__LOCK              0x00000040UL
-#define NETLINK_TCPDIAG_SOCKET__RELABELFROM       0x00000080UL
-#define NETLINK_TCPDIAG_SOCKET__RELABELTO         0x00000100UL
-#define NETLINK_TCPDIAG_SOCKET__APPEND            0x00000200UL
-#define NETLINK_TCPDIAG_SOCKET__BIND              0x00000400UL
-#define NETLINK_TCPDIAG_SOCKET__CONNECT           0x00000800UL
-#define NETLINK_TCPDIAG_SOCKET__LISTEN            0x00001000UL
-#define NETLINK_TCPDIAG_SOCKET__ACCEPT            0x00002000UL
-#define NETLINK_TCPDIAG_SOCKET__GETOPT            0x00004000UL
-#define NETLINK_TCPDIAG_SOCKET__SETOPT            0x00008000UL
-#define NETLINK_TCPDIAG_SOCKET__SHUTDOWN          0x00010000UL
-#define NETLINK_TCPDIAG_SOCKET__RECVFROM          0x00020000UL
-#define NETLINK_TCPDIAG_SOCKET__SENDTO            0x00040000UL
-#define NETLINK_TCPDIAG_SOCKET__RECV_MSG          0x00080000UL
-#define NETLINK_TCPDIAG_SOCKET__SEND_MSG          0x00100000UL
-#define NETLINK_TCPDIAG_SOCKET__NAME_BIND         0x00200000UL
-#define NETLINK_TCPDIAG_SOCKET__NLMSG_READ        0x00400000UL
-#define NETLINK_TCPDIAG_SOCKET__NLMSG_WRITE       0x00800000UL
-#define NETLINK_NFLOG_SOCKET__IOCTL               0x00000001UL
-#define NETLINK_NFLOG_SOCKET__READ                0x00000002UL
-#define NETLINK_NFLOG_SOCKET__WRITE               0x00000004UL
-#define NETLINK_NFLOG_SOCKET__CREATE              0x00000008UL
-#define NETLINK_NFLOG_SOCKET__GETATTR             0x00000010UL
-#define NETLINK_NFLOG_SOCKET__SETATTR             0x00000020UL
-#define NETLINK_NFLOG_SOCKET__LOCK                0x00000040UL
-#define NETLINK_NFLOG_SOCKET__RELABELFROM         0x00000080UL
-#define NETLINK_NFLOG_SOCKET__RELABELTO           0x00000100UL
-#define NETLINK_NFLOG_SOCKET__APPEND              0x00000200UL
-#define NETLINK_NFLOG_SOCKET__BIND                0x00000400UL
-#define NETLINK_NFLOG_SOCKET__CONNECT             0x00000800UL
-#define NETLINK_NFLOG_SOCKET__LISTEN              0x00001000UL
-#define NETLINK_NFLOG_SOCKET__ACCEPT              0x00002000UL
-#define NETLINK_NFLOG_SOCKET__GETOPT              0x00004000UL
-#define NETLINK_NFLOG_SOCKET__SETOPT              0x00008000UL
-#define NETLINK_NFLOG_SOCKET__SHUTDOWN            0x00010000UL
-#define NETLINK_NFLOG_SOCKET__RECVFROM            0x00020000UL
-#define NETLINK_NFLOG_SOCKET__SENDTO              0x00040000UL
-#define NETLINK_NFLOG_SOCKET__RECV_MSG            0x00080000UL
-#define NETLINK_NFLOG_SOCKET__SEND_MSG            0x00100000UL
-#define NETLINK_NFLOG_SOCKET__NAME_BIND           0x00200000UL
-#define NETLINK_XFRM_SOCKET__IOCTL                0x00000001UL
-#define NETLINK_XFRM_SOCKET__READ                 0x00000002UL
-#define NETLINK_XFRM_SOCKET__WRITE                0x00000004UL
-#define NETLINK_XFRM_SOCKET__CREATE               0x00000008UL
-#define NETLINK_XFRM_SOCKET__GETATTR              0x00000010UL
-#define NETLINK_XFRM_SOCKET__SETATTR              0x00000020UL
-#define NETLINK_XFRM_SOCKET__LOCK                 0x00000040UL
-#define NETLINK_XFRM_SOCKET__RELABELFROM          0x00000080UL
-#define NETLINK_XFRM_SOCKET__RELABELTO            0x00000100UL
-#define NETLINK_XFRM_SOCKET__APPEND               0x00000200UL
-#define NETLINK_XFRM_SOCKET__BIND                 0x00000400UL
-#define NETLINK_XFRM_SOCKET__CONNECT              0x00000800UL
-#define NETLINK_XFRM_SOCKET__LISTEN               0x00001000UL
-#define NETLINK_XFRM_SOCKET__ACCEPT               0x00002000UL
-#define NETLINK_XFRM_SOCKET__GETOPT               0x00004000UL
-#define NETLINK_XFRM_SOCKET__SETOPT               0x00008000UL
-#define NETLINK_XFRM_SOCKET__SHUTDOWN             0x00010000UL
-#define NETLINK_XFRM_SOCKET__RECVFROM             0x00020000UL
-#define NETLINK_XFRM_SOCKET__SENDTO               0x00040000UL
-#define NETLINK_XFRM_SOCKET__RECV_MSG             0x00080000UL
-#define NETLINK_XFRM_SOCKET__SEND_MSG             0x00100000UL
-#define NETLINK_XFRM_SOCKET__NAME_BIND            0x00200000UL
-#define NETLINK_XFRM_SOCKET__NLMSG_READ           0x00400000UL
-#define NETLINK_XFRM_SOCKET__NLMSG_WRITE          0x00800000UL
-#define NETLINK_SELINUX_SOCKET__IOCTL             0x00000001UL
-#define NETLINK_SELINUX_SOCKET__READ              0x00000002UL
-#define NETLINK_SELINUX_SOCKET__WRITE             0x00000004UL
-#define NETLINK_SELINUX_SOCKET__CREATE            0x00000008UL
-#define NETLINK_SELINUX_SOCKET__GETATTR           0x00000010UL
-#define NETLINK_SELINUX_SOCKET__SETATTR           0x00000020UL
-#define NETLINK_SELINUX_SOCKET__LOCK              0x00000040UL
-#define NETLINK_SELINUX_SOCKET__RELABELFROM       0x00000080UL
-#define NETLINK_SELINUX_SOCKET__RELABELTO         0x00000100UL
-#define NETLINK_SELINUX_SOCKET__APPEND            0x00000200UL
-#define NETLINK_SELINUX_SOCKET__BIND              0x00000400UL
-#define NETLINK_SELINUX_SOCKET__CONNECT           0x00000800UL
-#define NETLINK_SELINUX_SOCKET__LISTEN            0x00001000UL
-#define NETLINK_SELINUX_SOCKET__ACCEPT            0x00002000UL
-#define NETLINK_SELINUX_SOCKET__GETOPT            0x00004000UL
-#define NETLINK_SELINUX_SOCKET__SETOPT            0x00008000UL
-#define NETLINK_SELINUX_SOCKET__SHUTDOWN          0x00010000UL
-#define NETLINK_SELINUX_SOCKET__RECVFROM          0x00020000UL
-#define NETLINK_SELINUX_SOCKET__SENDTO            0x00040000UL
-#define NETLINK_SELINUX_SOCKET__RECV_MSG          0x00080000UL
-#define NETLINK_SELINUX_SOCKET__SEND_MSG          0x00100000UL
-#define NETLINK_SELINUX_SOCKET__NAME_BIND         0x00200000UL
-#define NETLINK_AUDIT_SOCKET__IOCTL               0x00000001UL
-#define NETLINK_AUDIT_SOCKET__READ                0x00000002UL
-#define NETLINK_AUDIT_SOCKET__WRITE               0x00000004UL
-#define NETLINK_AUDIT_SOCKET__CREATE              0x00000008UL
-#define NETLINK_AUDIT_SOCKET__GETATTR             0x00000010UL
-#define NETLINK_AUDIT_SOCKET__SETATTR             0x00000020UL
-#define NETLINK_AUDIT_SOCKET__LOCK                0x00000040UL
-#define NETLINK_AUDIT_SOCKET__RELABELFROM         0x00000080UL
-#define NETLINK_AUDIT_SOCKET__RELABELTO           0x00000100UL
-#define NETLINK_AUDIT_SOCKET__APPEND              0x00000200UL
-#define NETLINK_AUDIT_SOCKET__BIND                0x00000400UL
-#define NETLINK_AUDIT_SOCKET__CONNECT             0x00000800UL
-#define NETLINK_AUDIT_SOCKET__LISTEN              0x00001000UL
-#define NETLINK_AUDIT_SOCKET__ACCEPT              0x00002000UL
-#define NETLINK_AUDIT_SOCKET__GETOPT              0x00004000UL
-#define NETLINK_AUDIT_SOCKET__SETOPT              0x00008000UL
-#define NETLINK_AUDIT_SOCKET__SHUTDOWN            0x00010000UL
-#define NETLINK_AUDIT_SOCKET__RECVFROM            0x00020000UL
-#define NETLINK_AUDIT_SOCKET__SENDTO              0x00040000UL
-#define NETLINK_AUDIT_SOCKET__RECV_MSG            0x00080000UL
-#define NETLINK_AUDIT_SOCKET__SEND_MSG            0x00100000UL
-#define NETLINK_AUDIT_SOCKET__NAME_BIND           0x00200000UL
-#define NETLINK_AUDIT_SOCKET__NLMSG_READ          0x00400000UL
-#define NETLINK_AUDIT_SOCKET__NLMSG_WRITE         0x00800000UL
-#define NETLINK_AUDIT_SOCKET__NLMSG_RELAY         0x01000000UL
-#define NETLINK_AUDIT_SOCKET__NLMSG_READPRIV      0x02000000UL
-#define NETLINK_AUDIT_SOCKET__NLMSG_TTY_AUDIT     0x04000000UL
-#define NETLINK_IP6FW_SOCKET__IOCTL               0x00000001UL
-#define NETLINK_IP6FW_SOCKET__READ                0x00000002UL
-#define NETLINK_IP6FW_SOCKET__WRITE               0x00000004UL
-#define NETLINK_IP6FW_SOCKET__CREATE              0x00000008UL
-#define NETLINK_IP6FW_SOCKET__GETATTR             0x00000010UL
-#define NETLINK_IP6FW_SOCKET__SETATTR             0x00000020UL
-#define NETLINK_IP6FW_SOCKET__LOCK                0x00000040UL
-#define NETLINK_IP6FW_SOCKET__RELABELFROM         0x00000080UL
-#define NETLINK_IP6FW_SOCKET__RELABELTO           0x00000100UL
-#define NETLINK_IP6FW_SOCKET__APPEND              0x00000200UL
-#define NETLINK_IP6FW_SOCKET__BIND                0x00000400UL
-#define NETLINK_IP6FW_SOCKET__CONNECT             0x00000800UL
-#define NETLINK_IP6FW_SOCKET__LISTEN              0x00001000UL
-#define NETLINK_IP6FW_SOCKET__ACCEPT              0x00002000UL
-#define NETLINK_IP6FW_SOCKET__GETOPT              0x00004000UL
-#define NETLINK_IP6FW_SOCKET__SETOPT              0x00008000UL
-#define NETLINK_IP6FW_SOCKET__SHUTDOWN            0x00010000UL
-#define NETLINK_IP6FW_SOCKET__RECVFROM            0x00020000UL
-#define NETLINK_IP6FW_SOCKET__SENDTO              0x00040000UL
-#define NETLINK_IP6FW_SOCKET__RECV_MSG            0x00080000UL
-#define NETLINK_IP6FW_SOCKET__SEND_MSG            0x00100000UL
-#define NETLINK_IP6FW_SOCKET__NAME_BIND           0x00200000UL
-#define NETLINK_IP6FW_SOCKET__NLMSG_READ          0x00400000UL
-#define NETLINK_IP6FW_SOCKET__NLMSG_WRITE         0x00800000UL
-#define NETLINK_DNRT_SOCKET__IOCTL                0x00000001UL
-#define NETLINK_DNRT_SOCKET__READ                 0x00000002UL
-#define NETLINK_DNRT_SOCKET__WRITE                0x00000004UL
-#define NETLINK_DNRT_SOCKET__CREATE               0x00000008UL
-#define NETLINK_DNRT_SOCKET__GETATTR              0x00000010UL
-#define NETLINK_DNRT_SOCKET__SETATTR              0x00000020UL
-#define NETLINK_DNRT_SOCKET__LOCK                 0x00000040UL
-#define NETLINK_DNRT_SOCKET__RELABELFROM          0x00000080UL
-#define NETLINK_DNRT_SOCKET__RELABELTO            0x00000100UL
-#define NETLINK_DNRT_SOCKET__APPEND               0x00000200UL
-#define NETLINK_DNRT_SOCKET__BIND                 0x00000400UL
-#define NETLINK_DNRT_SOCKET__CONNECT              0x00000800UL
-#define NETLINK_DNRT_SOCKET__LISTEN               0x00001000UL
-#define NETLINK_DNRT_SOCKET__ACCEPT               0x00002000UL
-#define NETLINK_DNRT_SOCKET__GETOPT               0x00004000UL
-#define NETLINK_DNRT_SOCKET__SETOPT               0x00008000UL
-#define NETLINK_DNRT_SOCKET__SHUTDOWN             0x00010000UL
-#define NETLINK_DNRT_SOCKET__RECVFROM             0x00020000UL
-#define NETLINK_DNRT_SOCKET__SENDTO               0x00040000UL
-#define NETLINK_DNRT_SOCKET__RECV_MSG             0x00080000UL
-#define NETLINK_DNRT_SOCKET__SEND_MSG             0x00100000UL
-#define NETLINK_DNRT_SOCKET__NAME_BIND            0x00200000UL
-#define ASSOCIATION__SENDTO                       0x00000001UL
-#define ASSOCIATION__RECVFROM                     0x00000002UL
-#define ASSOCIATION__SETCONTEXT                   0x00000004UL
-#define ASSOCIATION__POLMATCH                     0x00000008UL
-#define NETLINK_KOBJECT_UEVENT_SOCKET__IOCTL      0x00000001UL
-#define NETLINK_KOBJECT_UEVENT_SOCKET__READ       0x00000002UL
-#define NETLINK_KOBJECT_UEVENT_SOCKET__WRITE      0x00000004UL
-#define NETLINK_KOBJECT_UEVENT_SOCKET__CREATE     0x00000008UL
-#define NETLINK_KOBJECT_UEVENT_SOCKET__GETATTR    0x00000010UL
-#define NETLINK_KOBJECT_UEVENT_SOCKET__SETATTR    0x00000020UL
-#define NETLINK_KOBJECT_UEVENT_SOCKET__LOCK       0x00000040UL
-#define NETLINK_KOBJECT_UEVENT_SOCKET__RELABELFROM 0x00000080UL
-#define NETLINK_KOBJECT_UEVENT_SOCKET__RELABELTO  0x00000100UL
-#define NETLINK_KOBJECT_UEVENT_SOCKET__APPEND     0x00000200UL
-#define NETLINK_KOBJECT_UEVENT_SOCKET__BIND       0x00000400UL
-#define NETLINK_KOBJECT_UEVENT_SOCKET__CONNECT    0x00000800UL
-#define NETLINK_KOBJECT_UEVENT_SOCKET__LISTEN     0x00001000UL
-#define NETLINK_KOBJECT_UEVENT_SOCKET__ACCEPT     0x00002000UL
-#define NETLINK_KOBJECT_UEVENT_SOCKET__GETOPT     0x00004000UL
-#define NETLINK_KOBJECT_UEVENT_SOCKET__SETOPT     0x00008000UL
-#define NETLINK_KOBJECT_UEVENT_SOCKET__SHUTDOWN   0x00010000UL
-#define NETLINK_KOBJECT_UEVENT_SOCKET__RECVFROM   0x00020000UL
-#define NETLINK_KOBJECT_UEVENT_SOCKET__SENDTO     0x00040000UL
-#define NETLINK_KOBJECT_UEVENT_SOCKET__RECV_MSG   0x00080000UL
-#define NETLINK_KOBJECT_UEVENT_SOCKET__SEND_MSG   0x00100000UL
-#define NETLINK_KOBJECT_UEVENT_SOCKET__NAME_BIND  0x00200000UL
-#define APPLETALK_SOCKET__IOCTL                   0x00000001UL
-#define APPLETALK_SOCKET__READ                    0x00000002UL
-#define APPLETALK_SOCKET__WRITE                   0x00000004UL
-#define APPLETALK_SOCKET__CREATE                  0x00000008UL
-#define APPLETALK_SOCKET__GETATTR                 0x00000010UL
-#define APPLETALK_SOCKET__SETATTR                 0x00000020UL
-#define APPLETALK_SOCKET__LOCK                    0x00000040UL
-#define APPLETALK_SOCKET__RELABELFROM             0x00000080UL
-#define APPLETALK_SOCKET__RELABELTO               0x00000100UL
-#define APPLETALK_SOCKET__APPEND                  0x00000200UL
-#define APPLETALK_SOCKET__BIND                    0x00000400UL
-#define APPLETALK_SOCKET__CONNECT                 0x00000800UL
-#define APPLETALK_SOCKET__LISTEN                  0x00001000UL
-#define APPLETALK_SOCKET__ACCEPT                  0x00002000UL
-#define APPLETALK_SOCKET__GETOPT                  0x00004000UL
-#define APPLETALK_SOCKET__SETOPT                  0x00008000UL
-#define APPLETALK_SOCKET__SHUTDOWN                0x00010000UL
-#define APPLETALK_SOCKET__RECVFROM                0x00020000UL
-#define APPLETALK_SOCKET__SENDTO                  0x00040000UL
-#define APPLETALK_SOCKET__RECV_MSG                0x00080000UL
-#define APPLETALK_SOCKET__SEND_MSG                0x00100000UL
-#define APPLETALK_SOCKET__NAME_BIND               0x00200000UL
-#define PACKET__SEND                              0x00000001UL
-#define PACKET__RECV                              0x00000002UL
-#define PACKET__RELABELTO                         0x00000004UL
-#define PACKET__FLOW_IN                           0x00000008UL
-#define PACKET__FLOW_OUT                          0x00000010UL
-#define PACKET__FORWARD_IN                        0x00000020UL
-#define PACKET__FORWARD_OUT                       0x00000040UL
-#define KEY__VIEW                                 0x00000001UL
-#define KEY__READ                                 0x00000002UL
-#define KEY__WRITE                                0x00000004UL
-#define KEY__SEARCH                               0x00000008UL
-#define KEY__LINK                                 0x00000010UL
-#define KEY__SETATTR                              0x00000020UL
-#define KEY__CREATE                               0x00000040UL
-#define DCCP_SOCKET__IOCTL                        0x00000001UL
-#define DCCP_SOCKET__READ                         0x00000002UL
-#define DCCP_SOCKET__WRITE                        0x00000004UL
-#define DCCP_SOCKET__CREATE                       0x00000008UL
-#define DCCP_SOCKET__GETATTR                      0x00000010UL
-#define DCCP_SOCKET__SETATTR                      0x00000020UL
-#define DCCP_SOCKET__LOCK                         0x00000040UL
-#define DCCP_SOCKET__RELABELFROM                  0x00000080UL
-#define DCCP_SOCKET__RELABELTO                    0x00000100UL
-#define DCCP_SOCKET__APPEND                       0x00000200UL
-#define DCCP_SOCKET__BIND                         0x00000400UL
-#define DCCP_SOCKET__CONNECT                      0x00000800UL
-#define DCCP_SOCKET__LISTEN                       0x00001000UL
-#define DCCP_SOCKET__ACCEPT                       0x00002000UL
-#define DCCP_SOCKET__GETOPT                       0x00004000UL
-#define DCCP_SOCKET__SETOPT                       0x00008000UL
-#define DCCP_SOCKET__SHUTDOWN                     0x00010000UL
-#define DCCP_SOCKET__RECVFROM                     0x00020000UL
-#define DCCP_SOCKET__SENDTO                       0x00040000UL
-#define DCCP_SOCKET__RECV_MSG                     0x00080000UL
-#define DCCP_SOCKET__SEND_MSG                     0x00100000UL
-#define DCCP_SOCKET__NAME_BIND                    0x00200000UL
-#define DCCP_SOCKET__NODE_BIND                    0x00400000UL
-#define DCCP_SOCKET__NAME_CONNECT                 0x00800000UL
-#define MEMPROTECT__MMAP_ZERO                     0x00000001UL
-#define PEER__RECV                                0x00000001UL
-#define KERNEL_SERVICE__USE_AS_OVERRIDE           0x00000001UL
-#define KERNEL_SERVICE__CREATE_FILES_AS           0x00000002UL
index bb1ec801bdfe1dda2984b27da8ecef52c2715755..4677aa519b0471b2f4dd7bad0cf79c737f93bd8d 100644 (file)
 
 int avc_ss_reset(u32 seqno);
 
-struct av_perm_to_string {
-       u16 tclass;
-       u32 value;
+/* Class/perm mapping support */
+struct security_class_mapping {
        const char *name;
+       const char *perms[sizeof(u32) * 8 + 1];
 };
 
-struct av_inherit {
-       const char **common_pts;
-       u32 common_base;
-       u16 tclass;
-};
-
-struct selinux_class_perm {
-       const struct av_perm_to_string *av_perm_to_string;
-       u32 av_pts_len;
-       u32 cts_len;
-       const char **class_to_string;
-       const struct av_inherit *av_inherit;
-       u32 av_inherit_len;
-};
+extern struct security_class_mapping secclass_map[];
 
 #endif /* _SELINUX_AVC_SS_H_ */
 
diff --git a/security/selinux/include/class_to_string.h b/security/selinux/include/class_to_string.h
deleted file mode 100644 (file)
index 7ab9299..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-/* This file is automatically generated.  Do not edit. */
-/*
- * Security object class definitions
- */
-    S_(NULL)
-    S_("security")
-    S_("process")
-    S_("system")
-    S_("capability")
-    S_("filesystem")
-    S_("file")
-    S_("dir")
-    S_("fd")
-    S_("lnk_file")
-    S_("chr_file")
-    S_("blk_file")
-    S_("sock_file")
-    S_("fifo_file")
-    S_("socket")
-    S_("tcp_socket")
-    S_("udp_socket")
-    S_("rawip_socket")
-    S_("node")
-    S_("netif")
-    S_("netlink_socket")
-    S_("packet_socket")
-    S_("key_socket")
-    S_("unix_stream_socket")
-    S_("unix_dgram_socket")
-    S_("sem")
-    S_("msg")
-    S_("msgq")
-    S_("shm")
-    S_("ipc")
-    S_(NULL)
-    S_(NULL)
-    S_(NULL)
-    S_(NULL)
-    S_(NULL)
-    S_(NULL)
-    S_(NULL)
-    S_(NULL)
-    S_(NULL)
-    S_(NULL)
-    S_(NULL)
-    S_(NULL)
-    S_(NULL)
-    S_("netlink_route_socket")
-    S_("netlink_firewall_socket")
-    S_("netlink_tcpdiag_socket")
-    S_("netlink_nflog_socket")
-    S_("netlink_xfrm_socket")
-    S_("netlink_selinux_socket")
-    S_("netlink_audit_socket")
-    S_("netlink_ip6fw_socket")
-    S_("netlink_dnrt_socket")
-    S_(NULL)
-    S_(NULL)
-    S_("association")
-    S_("netlink_kobject_uevent_socket")
-    S_("appletalk_socket")
-    S_("packet")
-    S_("key")
-    S_(NULL)
-    S_("dccp_socket")
-    S_("memprotect")
-    S_(NULL)
-    S_(NULL)
-    S_(NULL)
-    S_(NULL)
-    S_(NULL)
-    S_(NULL)
-    S_("peer")
-    S_("capability2")
-    S_(NULL)
-    S_(NULL)
-    S_(NULL)
-    S_(NULL)
-    S_("kernel_service")
-    S_("tun_socket")
diff --git a/security/selinux/include/classmap.h b/security/selinux/include/classmap.h
new file mode 100644 (file)
index 0000000..8b32e95
--- /dev/null
@@ -0,0 +1,150 @@
+#define COMMON_FILE_SOCK_PERMS "ioctl", "read", "write", "create", \
+    "getattr", "setattr", "lock", "relabelfrom", "relabelto", "append"
+
+#define COMMON_FILE_PERMS COMMON_FILE_SOCK_PERMS, "unlink", "link", \
+    "rename", "execute", "swapon", "quotaon", "mounton"
+
+#define COMMON_SOCK_PERMS COMMON_FILE_SOCK_PERMS, "bind", "connect", \
+    "listen", "accept", "getopt", "setopt", "shutdown", "recvfrom",  \
+    "sendto", "recv_msg", "send_msg", "name_bind"
+
+#define COMMON_IPC_PERMS "create", "destroy", "getattr", "setattr", "read", \
+           "write", "associate", "unix_read", "unix_write"
+
+struct security_class_mapping secclass_map[] = {
+       { "security",
+         { "compute_av", "compute_create", "compute_member",
+           "check_context", "load_policy", "compute_relabel",
+           "compute_user", "setenforce", "setbool", "setsecparam",
+           "setcheckreqprot", NULL } },
+       { "process",
+         { "fork", "transition", "sigchld", "sigkill",
+           "sigstop", "signull", "signal", "ptrace", "getsched", "setsched",
+           "getsession", "getpgid", "setpgid", "getcap", "setcap", "share",
+           "getattr", "setexec", "setfscreate", "noatsecure", "siginh",
+           "setrlimit", "rlimitinh", "dyntransition", "setcurrent",
+           "execmem", "execstack", "execheap", "setkeycreate",
+           "setsockcreate", NULL } },
+       { "system",
+         { "ipc_info", "syslog_read", "syslog_mod",
+           "syslog_console", "module_request", NULL } },
+       { "capability",
+         { "chown", "dac_override", "dac_read_search",
+           "fowner", "fsetid", "kill", "setgid", "setuid", "setpcap",
+           "linux_immutable", "net_bind_service", "net_broadcast",
+           "net_admin", "net_raw", "ipc_lock", "ipc_owner", "sys_module",
+           "sys_rawio", "sys_chroot", "sys_ptrace", "sys_pacct", "sys_admin",
+           "sys_boot", "sys_nice", "sys_resource", "sys_time",
+           "sys_tty_config", "mknod", "lease", "audit_write",
+           "audit_control", "setfcap", NULL } },
+       { "filesystem",
+         { "mount", "remount", "unmount", "getattr",
+           "relabelfrom", "relabelto", "transition", "associate", "quotamod",
+           "quotaget", NULL } },
+       { "file",
+         { COMMON_FILE_PERMS,
+           "execute_no_trans", "entrypoint", "execmod", "open", NULL } },
+       { "dir",
+         { COMMON_FILE_PERMS, "add_name", "remove_name",
+           "reparent", "search", "rmdir", "open", NULL } },
+       { "fd", { "use", NULL } },
+       { "lnk_file",
+         { COMMON_FILE_PERMS, NULL } },
+       { "chr_file",
+         { COMMON_FILE_PERMS,
+           "execute_no_trans", "entrypoint", "execmod", "open", NULL } },
+       { "blk_file",
+         { COMMON_FILE_PERMS, "open", NULL } },
+       { "sock_file",
+         { COMMON_FILE_PERMS, "open", NULL } },
+       { "fifo_file",
+         { COMMON_FILE_PERMS, "open", NULL } },
+       { "socket",
+         { COMMON_SOCK_PERMS, NULL } },
+       { "tcp_socket",
+         { COMMON_SOCK_PERMS,
+           "connectto", "newconn", "acceptfrom", "node_bind", "name_connect",
+           NULL } },
+       { "udp_socket",
+         { COMMON_SOCK_PERMS,
+           "node_bind", NULL } },
+       { "rawip_socket",
+         { COMMON_SOCK_PERMS,
+           "node_bind", NULL } },
+       { "node",
+         { "tcp_recv", "tcp_send", "udp_recv", "udp_send",
+           "rawip_recv", "rawip_send", "enforce_dest",
+           "dccp_recv", "dccp_send", "recvfrom", "sendto", NULL } },
+       { "netif",
+         {  "tcp_recv", "tcp_send", "udp_recv", "udp_send",
+            "rawip_recv", "rawip_send", "dccp_recv", "dccp_send",
+            "ingress", "egress", NULL } },
+       { "netlink_socket",
+         { COMMON_SOCK_PERMS, NULL } },
+       { "packet_socket",
+         { COMMON_SOCK_PERMS, NULL } },
+       { "key_socket",
+         { COMMON_SOCK_PERMS, NULL } },
+       { "unix_stream_socket",
+         { COMMON_SOCK_PERMS, "connectto", "newconn", "acceptfrom", NULL
+         } },
+       { "unix_dgram_socket",
+         { COMMON_SOCK_PERMS, NULL
+         } },
+       { "sem",
+         { COMMON_IPC_PERMS, NULL } },
+       { "msg", { "send", "receive", NULL } },
+       { "msgq",
+         { COMMON_IPC_PERMS, "enqueue", NULL } },
+       { "shm",
+         { COMMON_IPC_PERMS, "lock", NULL } },
+       { "ipc",
+         { COMMON_IPC_PERMS, NULL } },
+       { "netlink_route_socket",
+         { COMMON_SOCK_PERMS,
+           "nlmsg_read", "nlmsg_write", NULL } },
+       { "netlink_firewall_socket",
+         { COMMON_SOCK_PERMS,
+           "nlmsg_read", "nlmsg_write", NULL } },
+       { "netlink_tcpdiag_socket",
+         { COMMON_SOCK_PERMS,
+           "nlmsg_read", "nlmsg_write", NULL } },
+       { "netlink_nflog_socket",
+         { COMMON_SOCK_PERMS, NULL } },
+       { "netlink_xfrm_socket",
+         { COMMON_SOCK_PERMS,
+           "nlmsg_read", "nlmsg_write", NULL } },
+       { "netlink_selinux_socket",
+         { COMMON_SOCK_PERMS, NULL } },
+       { "netlink_audit_socket",
+         { COMMON_SOCK_PERMS,
+           "nlmsg_read", "nlmsg_write", "nlmsg_relay", "nlmsg_readpriv",
+           "nlmsg_tty_audit", NULL } },
+       { "netlink_ip6fw_socket",
+         { COMMON_SOCK_PERMS,
+           "nlmsg_read", "nlmsg_write", NULL } },
+       { "netlink_dnrt_socket",
+         { COMMON_SOCK_PERMS, NULL } },
+       { "association",
+         { "sendto", "recvfrom", "setcontext", "polmatch", NULL } },
+       { "netlink_kobject_uevent_socket",
+         { COMMON_SOCK_PERMS, NULL } },
+       { "appletalk_socket",
+         { COMMON_SOCK_PERMS, NULL } },
+       { "packet",
+         { "send", "recv", "relabelto", "flow_in", "flow_out",
+           "forward_in", "forward_out", NULL } },
+       { "key",
+         { "view", "read", "write", "search", "link", "setattr", "create",
+           NULL } },
+       { "dccp_socket",
+         { COMMON_SOCK_PERMS,
+           "node_bind", "name_connect", NULL } },
+       { "memprotect", { "mmap_zero", NULL } },
+       { "peer", { "recv", NULL } },
+       { "capability2", { "mac_override", "mac_admin", NULL } },
+       { "kernel_service", { "use_as_override", "create_files_as", NULL } },
+       { "tun_socket",
+         { COMMON_SOCK_PERMS, NULL } },
+       { NULL }
+  };
diff --git a/security/selinux/include/common_perm_to_string.h b/security/selinux/include/common_perm_to_string.h
deleted file mode 100644 (file)
index ce5b6e2..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-/* This file is automatically generated.  Do not edit. */
-TB_(common_file_perm_to_string)
-    S_("ioctl")
-    S_("read")
-    S_("write")
-    S_("create")
-    S_("getattr")
-    S_("setattr")
-    S_("lock")
-    S_("relabelfrom")
-    S_("relabelto")
-    S_("append")
-    S_("unlink")
-    S_("link")
-    S_("rename")
-    S_("execute")
-    S_("swapon")
-    S_("quotaon")
-    S_("mounton")
-TE_(common_file_perm_to_string)
-
-TB_(common_socket_perm_to_string)
-    S_("ioctl")
-    S_("read")
-    S_("write")
-    S_("create")
-    S_("getattr")
-    S_("setattr")
-    S_("lock")
-    S_("relabelfrom")
-    S_("relabelto")
-    S_("append")
-    S_("bind")
-    S_("connect")
-    S_("listen")
-    S_("accept")
-    S_("getopt")
-    S_("setopt")
-    S_("shutdown")
-    S_("recvfrom")
-    S_("sendto")
-    S_("recv_msg")
-    S_("send_msg")
-    S_("name_bind")
-TE_(common_socket_perm_to_string)
-
-TB_(common_ipc_perm_to_string)
-    S_("create")
-    S_("destroy")
-    S_("getattr")
-    S_("setattr")
-    S_("read")
-    S_("write")
-    S_("associate")
-    S_("unix_read")
-    S_("unix_write")
-TE_(common_ipc_perm_to_string)
-
diff --git a/security/selinux/include/flask.h b/security/selinux/include/flask.h
deleted file mode 100644 (file)
index f248500..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-/* This file is automatically generated.  Do not edit. */
-#ifndef _SELINUX_FLASK_H_
-#define _SELINUX_FLASK_H_
-
-/*
- * Security object class definitions
- */
-#define SECCLASS_SECURITY                                1
-#define SECCLASS_PROCESS                                 2
-#define SECCLASS_SYSTEM                                  3
-#define SECCLASS_CAPABILITY                              4
-#define SECCLASS_FILESYSTEM                              5
-#define SECCLASS_FILE                                    6
-#define SECCLASS_DIR                                     7
-#define SECCLASS_FD                                      8
-#define SECCLASS_LNK_FILE                                9
-#define SECCLASS_CHR_FILE                                10
-#define SECCLASS_BLK_FILE                                11
-#define SECCLASS_SOCK_FILE                               12
-#define SECCLASS_FIFO_FILE                               13
-#define SECCLASS_SOCKET                                  14
-#define SECCLASS_TCP_SOCKET                              15
-#define SECCLASS_UDP_SOCKET                              16
-#define SECCLASS_RAWIP_SOCKET                            17
-#define SECCLASS_NODE                                    18
-#define SECCLASS_NETIF                                   19
-#define SECCLASS_NETLINK_SOCKET                          20
-#define SECCLASS_PACKET_SOCKET                           21
-#define SECCLASS_KEY_SOCKET                              22
-#define SECCLASS_UNIX_STREAM_SOCKET                      23
-#define SECCLASS_UNIX_DGRAM_SOCKET                       24
-#define SECCLASS_SEM                                     25
-#define SECCLASS_MSG                                     26
-#define SECCLASS_MSGQ                                    27
-#define SECCLASS_SHM                                     28
-#define SECCLASS_IPC                                     29
-#define SECCLASS_NETLINK_ROUTE_SOCKET                    43
-#define SECCLASS_NETLINK_FIREWALL_SOCKET                 44
-#define SECCLASS_NETLINK_TCPDIAG_SOCKET                  45
-#define SECCLASS_NETLINK_NFLOG_SOCKET                    46
-#define SECCLASS_NETLINK_XFRM_SOCKET                     47
-#define SECCLASS_NETLINK_SELINUX_SOCKET                  48
-#define SECCLASS_NETLINK_AUDIT_SOCKET                    49
-#define SECCLASS_NETLINK_IP6FW_SOCKET                    50
-#define SECCLASS_NETLINK_DNRT_SOCKET                     51
-#define SECCLASS_ASSOCIATION                             54
-#define SECCLASS_NETLINK_KOBJECT_UEVENT_SOCKET           55
-#define SECCLASS_APPLETALK_SOCKET                        56
-#define SECCLASS_PACKET                                  57
-#define SECCLASS_KEY                                     58
-#define SECCLASS_DCCP_SOCKET                             60
-#define SECCLASS_MEMPROTECT                              61
-#define SECCLASS_PEER                                    68
-#define SECCLASS_CAPABILITY2                             69
-#define SECCLASS_KERNEL_SERVICE                          74
-#define SECCLASS_TUN_SOCKET                              75
-
-/*
- * Security identifier indices for initial entities
- */
-#define SECINITSID_KERNEL                               1
-#define SECINITSID_SECURITY                             2
-#define SECINITSID_UNLABELED                            3
-#define SECINITSID_FS                                   4
-#define SECINITSID_FILE                                 5
-#define SECINITSID_FILE_LABELS                          6
-#define SECINITSID_INIT                                 7
-#define SECINITSID_ANY_SOCKET                           8
-#define SECINITSID_PORT                                 9
-#define SECINITSID_NETIF                                10
-#define SECINITSID_NETMSG                               11
-#define SECINITSID_NODE                                 12
-#define SECINITSID_IGMP_PACKET                          13
-#define SECINITSID_ICMP_SOCKET                          14
-#define SECINITSID_TCP_SOCKET                           15
-#define SECINITSID_SYSCTL_MODPROBE                      16
-#define SECINITSID_SYSCTL                               17
-#define SECINITSID_SYSCTL_FS                            18
-#define SECINITSID_SYSCTL_KERNEL                        19
-#define SECINITSID_SYSCTL_NET                           20
-#define SECINITSID_SYSCTL_NET_UNIX                      21
-#define SECINITSID_SYSCTL_VM                            22
-#define SECINITSID_SYSCTL_DEV                           23
-#define SECINITSID_KMOD                                 24
-#define SECINITSID_POLICY                               25
-#define SECINITSID_SCMP_PACKET                          26
-#define SECINITSID_DEVNULL                              27
-
-#define SECINITSID_NUM                                  27
-
-#endif
index ca835795a8b322e7e4398d065d2eb0976741e2ad..2553266ad793ff76c6cf30d4a4383f285e66a2e4 100644 (file)
@@ -97,11 +97,18 @@ struct av_decision {
 #define AVD_FLAGS_PERMISSIVE   0x0001
 
 int security_compute_av(u32 ssid, u32 tsid,
-       u16 tclass, u32 requested,
-       struct av_decision *avd);
+                       u16 tclass, u32 requested,
+                       struct av_decision *avd);
+
+int security_compute_av_user(u32 ssid, u32 tsid,
+                            u16 tclass, u32 requested,
+                            struct av_decision *avd);
 
 int security_transition_sid(u32 ssid, u32 tsid,
-       u16 tclass, u32 *out_sid);
+                           u16 tclass, u32 *out_sid);
+
+int security_transition_sid_user(u32 ssid, u32 tsid,
+                                u16 tclass, u32 *out_sid);
 
 int security_member_sid(u32 ssid, u32 tsid,
        u16 tclass, u32 *out_sid);
index b4fc506e7a87c8aa69a71ccc1a9c1b6c55c00ce8..fab36fdf2769f0e0bce984bb0f40f84c63fff144 100644 (file)
@@ -522,7 +522,7 @@ static ssize_t sel_write_access(struct file *file, char *buf, size_t size)
        if (length < 0)
                goto out2;
 
-       length = security_compute_av(ssid, tsid, tclass, req, &avd);
+       length = security_compute_av_user(ssid, tsid, tclass, req, &avd);
        if (length < 0)
                goto out2;
 
@@ -571,7 +571,7 @@ static ssize_t sel_write_create(struct file *file, char *buf, size_t size)
        if (length < 0)
                goto out2;
 
-       length = security_transition_sid(ssid, tsid, tclass, &newsid);
+       length = security_transition_sid_user(ssid, tsid, tclass, &newsid);
        if (length < 0)
                goto out2;
 
index bad78779b9b0f3ee3944012889b55f7c3e500d28..15d4e62917de759028f3c442dc51605db6cf9faa 100644 (file)
@@ -2,7 +2,7 @@
 # Makefile for building the SELinux security server as part of the kernel tree.
 #
 
-EXTRA_CFLAGS += -Isecurity/selinux/include
+EXTRA_CFLAGS += -Isecurity/selinux -Isecurity/selinux/include
 obj-y := ss.o
 
 ss-y := ebitmap.o hashtab.o symtab.o sidtab.o avtab.o policydb.o services.o conditional.o mls.o
index b5407f16c2a4e71b06550beb671ddb9de14591b3..3f2b2706b5bbc9226b9e211c9fd46191c5856e23 100644 (file)
@@ -532,7 +532,7 @@ int mls_compute_sid(struct context *scontext,
                }
                /* Fallthrough */
        case AVTAB_CHANGE:
-               if (tclass == SECCLASS_PROCESS)
+               if (tclass == policydb.process_class)
                        /* Use the process MLS attributes. */
                        return mls_context_cpy(newcontext, scontext);
                else
index 72e4a54973aae503c9c9378aa392750f7f4adb20..f03667213ea8d4c1d0cb94ed270c4da8e8752dea 100644 (file)
@@ -713,7 +713,6 @@ void policydb_destroy(struct policydb *p)
                        ebitmap_destroy(&p->type_attr_map[i]);
        }
        kfree(p->type_attr_map);
-       kfree(p->undefined_perms);
        ebitmap_destroy(&p->policycaps);
        ebitmap_destroy(&p->permissive_map);
 
@@ -1640,6 +1639,40 @@ static int policydb_bounds_sanity_check(struct policydb *p)
 
 extern int ss_initialized;
 
+u16 string_to_security_class(struct policydb *p, const char *name)
+{
+       struct class_datum *cladatum;
+
+       cladatum = hashtab_search(p->p_classes.table, name);
+       if (!cladatum)
+               return 0;
+
+       return cladatum->value;
+}
+
+u32 string_to_av_perm(struct policydb *p, u16 tclass, const char *name)
+{
+       struct class_datum *cladatum;
+       struct perm_datum *perdatum = NULL;
+       struct common_datum *comdatum;
+
+       if (!tclass || tclass > p->p_classes.nprim)
+               return 0;
+
+       cladatum = p->class_val_to_struct[tclass-1];
+       comdatum = cladatum->comdatum;
+       if (comdatum)
+               perdatum = hashtab_search(comdatum->permissions.table,
+                                         name);
+       if (!perdatum)
+               perdatum = hashtab_search(cladatum->permissions.table,
+                                         name);
+       if (!perdatum)
+               return 0;
+
+       return 1U << (perdatum->value-1);
+}
+
 /*
  * Read the configuration data from a policy database binary
  * representation file into a policy database structure.
@@ -1861,6 +1894,16 @@ int policydb_read(struct policydb *p, void *fp)
        if (rc)
                goto bad;
 
+       p->process_class = string_to_security_class(p, "process");
+       if (!p->process_class)
+               goto bad;
+       p->process_trans_perms = string_to_av_perm(p, p->process_class,
+                                                  "transition");
+       p->process_trans_perms |= string_to_av_perm(p, p->process_class,
+                                                   "dyntransition");
+       if (!p->process_trans_perms)
+               goto bad;
+
        for (i = 0; i < info->ocon_num; i++) {
                rc = next_entry(buf, fp, sizeof(u32));
                if (rc < 0)
@@ -2101,7 +2144,7 @@ int policydb_read(struct policydb *p, void *fp)
                                        goto bad;
                                rt->target_class = le32_to_cpu(buf[0]);
                        } else
-                               rt->target_class = SECCLASS_PROCESS;
+                               rt->target_class = p->process_class;
                        if (!policydb_type_isvalid(p, rt->source_type) ||
                            !policydb_type_isvalid(p, rt->target_type) ||
                            !policydb_class_isvalid(p, rt->target_class)) {
index 55152d498b5342aba65d04c0a6be1b79f784a9f5..cdcc5700946f7f850dfb251f8c8ccb0596ac3c74 100644 (file)
@@ -254,7 +254,9 @@ struct policydb {
 
        unsigned int reject_unknown : 1;
        unsigned int allow_unknown : 1;
-       u32 *undefined_perms;
+
+       u16 process_class;
+       u32 process_trans_perms;
 };
 
 extern void policydb_destroy(struct policydb *p);
@@ -295,5 +297,8 @@ static inline int next_entry(void *buf, struct policy_file *fp, size_t bytes)
        return 0;
 }
 
+extern u16 string_to_security_class(struct policydb *p, const char *name);
+extern u32 string_to_av_perm(struct policydb *p, u16 tclass, const char *name);
+
 #endif /* _SS_POLICYDB_H_ */
 
index ff17820d35ec73bedfab174d3adfb7c87b762420..d6bb20cbad623703116160ad791c4831b504d067 100644 (file)
 #include "audit.h"
 
 extern void selnl_notify_policyload(u32 seqno);
-unsigned int policydb_loaded_version;
 
 int selinux_policycap_netpeer;
 int selinux_policycap_openperm;
 
-/*
- * This is declared in avc.c
- */
-extern const struct selinux_class_perm selinux_class_perm;
-
 static DEFINE_RWLOCK(policy_rwlock);
 
 static struct sidtab sidtab;
@@ -98,6 +92,165 @@ static int context_struct_compute_av(struct context *scontext,
                                     u16 tclass,
                                     u32 requested,
                                     struct av_decision *avd);
+
+struct selinux_mapping {
+       u16 value; /* policy value */
+       unsigned num_perms;
+       u32 perms[sizeof(u32) * 8];
+};
+
+static struct selinux_mapping *current_mapping;
+static u16 current_mapping_size;
+
+static int selinux_set_mapping(struct policydb *pol,
+                              struct security_class_mapping *map,
+                              struct selinux_mapping **out_map_p,
+                              u16 *out_map_size)
+{
+       struct selinux_mapping *out_map = NULL;
+       size_t size = sizeof(struct selinux_mapping);
+       u16 i, j;
+       unsigned k;
+       bool print_unknown_handle = false;
+
+       /* Find number of classes in the input mapping */
+       if (!map)
+               return -EINVAL;
+       i = 0;
+       while (map[i].name)
+               i++;
+
+       /* Allocate space for the class records, plus one for class zero */
+       out_map = kcalloc(++i, size, GFP_ATOMIC);
+       if (!out_map)
+               return -ENOMEM;
+
+       /* Store the raw class and permission values */
+       j = 0;
+       while (map[j].name) {
+               struct security_class_mapping *p_in = map + (j++);
+               struct selinux_mapping *p_out = out_map + j;
+
+               /* An empty class string skips ahead */
+               if (!strcmp(p_in->name, "")) {
+                       p_out->num_perms = 0;
+                       continue;
+               }
+
+               p_out->value = string_to_security_class(pol, p_in->name);
+               if (!p_out->value) {
+                       printk(KERN_INFO
+                              "SELinux:  Class %s not defined in policy.\n",
+                              p_in->name);
+                       if (pol->reject_unknown)
+                               goto err;
+                       p_out->num_perms = 0;
+                       print_unknown_handle = true;
+                       continue;
+               }
+
+               k = 0;
+               while (p_in->perms && p_in->perms[k]) {
+                       /* An empty permission string skips ahead */
+                       if (!*p_in->perms[k]) {
+                               k++;
+                               continue;
+                       }
+                       p_out->perms[k] = string_to_av_perm(pol, p_out->value,
+                                                           p_in->perms[k]);
+                       if (!p_out->perms[k]) {
+                               printk(KERN_INFO
+                                      "SELinux:  Permission %s in class %s not defined in policy.\n",
+                                      p_in->perms[k], p_in->name);
+                               if (pol->reject_unknown)
+                                       goto err;
+                               print_unknown_handle = true;
+                       }
+
+                       k++;
+               }
+               p_out->num_perms = k;
+       }
+
+       if (print_unknown_handle)
+               printk(KERN_INFO "SELinux: the above unknown classes and permissions will be %s\n",
+                      pol->allow_unknown ? "allowed" : "denied");
+
+       *out_map_p = out_map;
+       *out_map_size = i;
+       return 0;
+err:
+       kfree(out_map);
+       return -EINVAL;
+}
+
+/*
+ * Get real, policy values from mapped values
+ */
+
+static u16 unmap_class(u16 tclass)
+{
+       if (tclass < current_mapping_size)
+               return current_mapping[tclass].value;
+
+       return tclass;
+}
+
+static u32 unmap_perm(u16 tclass, u32 tperm)
+{
+       if (tclass < current_mapping_size) {
+               unsigned i;
+               u32 kperm = 0;
+
+               for (i = 0; i < current_mapping[tclass].num_perms; i++)
+                       if (tperm & (1<<i)) {
+                               kperm |= current_mapping[tclass].perms[i];
+                               tperm &= ~(1<<i);
+                       }
+               return kperm;
+       }
+
+       return tperm;
+}
+
+static void map_decision(u16 tclass, struct av_decision *avd,
+                        int allow_unknown)
+{
+       if (tclass < current_mapping_size) {
+               unsigned i, n = current_mapping[tclass].num_perms;
+               u32 result;
+
+               for (i = 0, result = 0; i < n; i++) {
+                       if (avd->allowed & current_mapping[tclass].perms[i])
+                               result |= 1<<i;
+                       if (allow_unknown && !current_mapping[tclass].perms[i])
+                               result |= 1<<i;
+               }
+               avd->allowed = result;
+
+               for (i = 0, result = 0; i < n; i++)
+                       if (avd->auditallow & current_mapping[tclass].perms[i])
+                               result |= 1<<i;
+               avd->auditallow = result;
+
+               for (i = 0, result = 0; i < n; i++) {
+                       if (avd->auditdeny & current_mapping[tclass].perms[i])
+                               result |= 1<<i;
+                       if (!allow_unknown && !current_mapping[tclass].perms[i])
+                               result |= 1<<i;
+               }
+               /*
+                * In case the kernel has a bug and requests a permission
+                * between num_perms and the maximum permission number, we
+                * should audit that denial
+                */
+               for (; i < (sizeof(u32)*8); i++)
+                       result |= 1<<i;
+               avd->auditdeny = result;
+       }
+}
+
+
 /*
  * Return the boolean value of a constraint expression
  * when it is applied to the specified source and target
@@ -467,20 +620,8 @@ static int context_struct_compute_av(struct context *scontext,
        struct class_datum *tclass_datum;
        struct ebitmap *sattr, *tattr;
        struct ebitmap_node *snode, *tnode;
-       const struct selinux_class_perm *kdefs = &selinux_class_perm;
        unsigned int i, j;
 
-       /*
-        * Remap extended Netlink classes for old policy versions.
-        * Do this here rather than socket_type_to_security_class()
-        * in case a newer policy version is loaded, allowing sockets
-        * to remain in the correct class.
-        */
-       if (policydb_loaded_version < POLICYDB_VERSION_NLCLASS)
-               if (tclass >= SECCLASS_NETLINK_ROUTE_SOCKET &&
-                   tclass <= SECCLASS_NETLINK_DNRT_SOCKET)
-                       tclass = SECCLASS_NETLINK_SOCKET;
-
        /*
         * Initialize the access vectors to the default values.
         */
@@ -490,33 +631,11 @@ static int context_struct_compute_av(struct context *scontext,
        avd->seqno = latest_granting;
        avd->flags = 0;
 
-       /*
-        * Check for all the invalid cases.
-        * - tclass 0
-        * - tclass > policy and > kernel
-        * - tclass > policy but is a userspace class
-        * - tclass > policy but we do not allow unknowns
-        */
-       if (unlikely(!tclass))
-               goto inval_class;
-       if (unlikely(tclass > policydb.p_classes.nprim))
-               if (tclass > kdefs->cts_len ||
-                   !kdefs->class_to_string[tclass] ||
-                   !policydb.allow_unknown)
-                       goto inval_class;
-
-       /*
-        * Kernel class and we allow unknown so pad the allow decision
-        * the pad will be all 1 for unknown classes.
-        */
-       if (tclass <= kdefs->cts_len && policydb.allow_unknown)
-               avd->allowed = policydb.undefined_perms[tclass - 1];
-
-       /*
-        * Not in policy. Since decision is completed (all 1 or all 0) return.
-        */
-       if (unlikely(tclass > policydb.p_classes.nprim))
-               return 0;
+       if (unlikely(!tclass || tclass > policydb.p_classes.nprim)) {
+               if (printk_ratelimit())
+                       printk(KERN_WARNING "SELinux:  Invalid class %hu\n", tclass);
+               return -EINVAL;
+       }
 
        tclass_datum = policydb.class_val_to_struct[tclass - 1];
 
@@ -568,8 +687,8 @@ static int context_struct_compute_av(struct context *scontext,
         * role is changing, then check the (current_role, new_role)
         * pair.
         */
-       if (tclass == SECCLASS_PROCESS &&
-           (avd->allowed & (PROCESS__TRANSITION | PROCESS__DYNTRANSITION)) &&
+       if (tclass == policydb.process_class &&
+           (avd->allowed & policydb.process_trans_perms) &&
            scontext->role != tcontext->role) {
                for (ra = policydb.role_allow; ra; ra = ra->next) {
                        if (scontext->role == ra->role &&
@@ -577,8 +696,7 @@ static int context_struct_compute_av(struct context *scontext,
                                break;
                }
                if (!ra)
-                       avd->allowed &= ~(PROCESS__TRANSITION |
-                                         PROCESS__DYNTRANSITION);
+                       avd->allowed &= ~policydb.process_trans_perms;
        }
 
        /*
@@ -590,21 +708,6 @@ static int context_struct_compute_av(struct context *scontext,
                                 tclass, requested, avd);
 
        return 0;
-
-inval_class:
-       if (!tclass || tclass > kdefs->cts_len ||
-           !kdefs->class_to_string[tclass]) {
-               if (printk_ratelimit())
-                       printk(KERN_ERR "SELinux: %s:  unrecognized class %d\n",
-                              __func__, tclass);
-               return -EINVAL;
-       }
-
-       /*
-        * Known to the kernel, but not to the policy.
-        * Handle as a denial (allowed is 0).
-        */
-       return 0;
 }
 
 static int security_validtrans_handle_fail(struct context *ocontext,
@@ -636,13 +739,14 @@ out:
 }
 
 int security_validate_transition(u32 oldsid, u32 newsid, u32 tasksid,
-                                u16 tclass)
+                                u16 orig_tclass)
 {
        struct context *ocontext;
        struct context *ncontext;
        struct context *tcontext;
        struct class_datum *tclass_datum;
        struct constraint_node *constraint;
+       u16 tclass;
        int rc = 0;
 
        if (!ss_initialized)
@@ -650,16 +754,7 @@ int security_validate_transition(u32 oldsid, u32 newsid, u32 tasksid,
 
        read_lock(&policy_rwlock);
 
-       /*
-        * Remap extended Netlink classes for old policy versions.
-        * Do this here rather than socket_type_to_security_class()
-        * in case a newer policy version is loaded, allowing sockets
-        * to remain in the correct class.
-        */
-       if (policydb_loaded_version < POLICYDB_VERSION_NLCLASS)
-               if (tclass >= SECCLASS_NETLINK_ROUTE_SOCKET &&
-                   tclass <= SECCLASS_NETLINK_DNRT_SOCKET)
-                       tclass = SECCLASS_NETLINK_SOCKET;
+       tclass = unmap_class(orig_tclass);
 
        if (!tclass || tclass > policydb.p_classes.nprim) {
                printk(KERN_ERR "SELinux: %s:  unrecognized class %d\n",
@@ -792,6 +887,38 @@ out:
 }
 
 
+static int security_compute_av_core(u32 ssid,
+                                   u32 tsid,
+                                   u16 tclass,
+                                   u32 requested,
+                                   struct av_decision *avd)
+{
+       struct context *scontext = NULL, *tcontext = NULL;
+       int rc = 0;
+
+       scontext = sidtab_search(&sidtab, ssid);
+       if (!scontext) {
+               printk(KERN_ERR "SELinux: %s:  unrecognized SID %d\n",
+                      __func__, ssid);
+               return -EINVAL;
+       }
+       tcontext = sidtab_search(&sidtab, tsid);
+       if (!tcontext) {
+               printk(KERN_ERR "SELinux: %s:  unrecognized SID %d\n",
+                      __func__, tsid);
+               return -EINVAL;
+       }
+
+       rc = context_struct_compute_av(scontext, tcontext, tclass,
+                                      requested, avd);
+
+       /* permissive domain? */
+       if (ebitmap_get_bit(&policydb.permissive_map, scontext->type))
+               avd->flags |= AVD_FLAGS_PERMISSIVE;
+
+       return rc;
+}
+
 /**
  * security_compute_av - Compute access vector decisions.
  * @ssid: source security identifier
@@ -807,12 +934,49 @@ out:
  */
 int security_compute_av(u32 ssid,
                        u32 tsid,
-                       u16 tclass,
-                       u32 requested,
+                       u16 orig_tclass,
+                       u32 orig_requested,
                        struct av_decision *avd)
 {
-       struct context *scontext = NULL, *tcontext = NULL;
-       int rc = 0;
+       u16 tclass;
+       u32 requested;
+       int rc;
+
+       read_lock(&policy_rwlock);
+
+       if (!ss_initialized)
+               goto allow;
+
+       requested = unmap_perm(orig_tclass, orig_requested);
+       tclass = unmap_class(orig_tclass);
+       if (unlikely(orig_tclass && !tclass)) {
+               if (policydb.allow_unknown)
+                       goto allow;
+               rc = -EINVAL;
+               goto out;
+       }
+       rc = security_compute_av_core(ssid, tsid, tclass, requested, avd);
+       map_decision(orig_tclass, avd, policydb.allow_unknown);
+out:
+       read_unlock(&policy_rwlock);
+       return rc;
+allow:
+       avd->allowed = 0xffffffff;
+       avd->auditallow = 0;
+       avd->auditdeny = 0xffffffff;
+       avd->seqno = latest_granting;
+       avd->flags = 0;
+       rc = 0;
+       goto out;
+}
+
+int security_compute_av_user(u32 ssid,
+                            u32 tsid,
+                            u16 tclass,
+                            u32 requested,
+                            struct av_decision *avd)
+{
+       int rc;
 
        if (!ss_initialized) {
                avd->allowed = 0xffffffff;
@@ -823,29 +987,7 @@ int security_compute_av(u32 ssid,
        }
 
        read_lock(&policy_rwlock);
-
-       scontext = sidtab_search(&sidtab, ssid);
-       if (!scontext) {
-               printk(KERN_ERR "SELinux: %s:  unrecognized SID %d\n",
-                      __func__, ssid);
-               rc = -EINVAL;
-               goto out;
-       }
-       tcontext = sidtab_search(&sidtab, tsid);
-       if (!tcontext) {
-               printk(KERN_ERR "SELinux: %s:  unrecognized SID %d\n",
-                      __func__, tsid);
-               rc = -EINVAL;
-               goto out;
-       }
-
-       rc = context_struct_compute_av(scontext, tcontext, tclass,
-                                      requested, avd);
-
-       /* permissive domain? */
-       if (ebitmap_get_bit(&policydb.permissive_map, scontext->type))
-           avd->flags |= AVD_FLAGS_PERMISSIVE;
-out:
+       rc = security_compute_av_core(ssid, tsid, tclass, requested, avd);
        read_unlock(&policy_rwlock);
        return rc;
 }
@@ -1204,20 +1346,22 @@ out:
 
 static int security_compute_sid(u32 ssid,
                                u32 tsid,
-                               u16 tclass,
+                               u16 orig_tclass,
                                u32 specified,
-                               u32 *out_sid)
+                               u32 *out_sid,
+                               bool kern)
 {
        struct context *scontext = NULL, *tcontext = NULL, newcontext;
        struct role_trans *roletr = NULL;
        struct avtab_key avkey;
        struct avtab_datum *avdatum;
        struct avtab_node *node;
+       u16 tclass;
        int rc = 0;
 
        if (!ss_initialized) {
-               switch (tclass) {
-               case SECCLASS_PROCESS:
+               switch (orig_tclass) {
+               case SECCLASS_PROCESS: /* kernel value */
                        *out_sid = ssid;
                        break;
                default:
@@ -1231,6 +1375,11 @@ static int security_compute_sid(u32 ssid,
 
        read_lock(&policy_rwlock);
 
+       if (kern)
+               tclass = unmap_class(orig_tclass);
+       else
+               tclass = orig_tclass;
+
        scontext = sidtab_search(&sidtab, ssid);
        if (!scontext) {
                printk(KERN_ERR "SELinux: %s:  unrecognized SID %d\n",
@@ -1260,13 +1409,11 @@ static int security_compute_sid(u32 ssid,
        }
 
        /* Set the role and type to default values. */
-       switch (tclass) {
-       case SECCLASS_PROCESS:
+       if (tclass == policydb.process_class) {
                /* Use the current role and type of process. */
                newcontext.role = scontext->role;
                newcontext.type = scontext->type;
-               break;
-       default:
+       } else {
                /* Use the well-defined object role. */
                newcontext.role = OBJECT_R_VAL;
                /* Use the type of the related object. */
@@ -1297,8 +1444,7 @@ static int security_compute_sid(u32 ssid,
        }
 
        /* Check for class-specific changes. */
-       switch (tclass) {
-       case SECCLASS_PROCESS:
+       if  (tclass == policydb.process_class) {
                if (specified & AVTAB_TRANSITION) {
                        /* Look for a role transition rule. */
                        for (roletr = policydb.role_tr; roletr;
@@ -1311,9 +1457,6 @@ static int security_compute_sid(u32 ssid,
                                }
                        }
                }
-               break;
-       default:
-               break;
        }
 
        /* Set the MLS attributes.
@@ -1358,7 +1501,17 @@ int security_transition_sid(u32 ssid,
                            u16 tclass,
                            u32 *out_sid)
 {
-       return security_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION, out_sid);
+       return security_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION,
+                                   out_sid, true);
+}
+
+int security_transition_sid_user(u32 ssid,
+                                u32 tsid,
+                                u16 tclass,
+                                u32 *out_sid)
+{
+       return security_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION,
+                                   out_sid, false);
 }
 
 /**
@@ -1379,7 +1532,8 @@ int security_member_sid(u32 ssid,
                        u16 tclass,
                        u32 *out_sid)
 {
-       return security_compute_sid(ssid, tsid, tclass, AVTAB_MEMBER, out_sid);
+       return security_compute_sid(ssid, tsid, tclass, AVTAB_MEMBER, out_sid,
+                                   false);
 }
 
 /**
@@ -1400,144 +1554,8 @@ int security_change_sid(u32 ssid,
                        u16 tclass,
                        u32 *out_sid)
 {
-       return security_compute_sid(ssid, tsid, tclass, AVTAB_CHANGE, out_sid);
-}
-
-/*
- * Verify that each kernel class that is defined in the
- * policy is correct
- */
-static int validate_classes(struct policydb *p)
-{
-       int i, j;
-       struct class_datum *cladatum;
-       struct perm_datum *perdatum;
-       u32 nprim, tmp, common_pts_len, perm_val, pol_val;
-       u16 class_val;
-       const struct selinux_class_perm *kdefs = &selinux_class_perm;
-       const char *def_class, *def_perm, *pol_class;
-       struct symtab *perms;
-       bool print_unknown_handle = 0;
-
-       if (p->allow_unknown) {
-               u32 num_classes = kdefs->cts_len;
-               p->undefined_perms = kcalloc(num_classes, sizeof(u32), GFP_KERNEL);
-               if (!p->undefined_perms)
-                       return -ENOMEM;
-       }
-
-       for (i = 1; i < kdefs->cts_len; i++) {
-               def_class = kdefs->class_to_string[i];
-               if (!def_class)
-                       continue;
-               if (i > p->p_classes.nprim) {
-                       printk(KERN_INFO
-                              "SELinux:  class %s not defined in policy\n",
-                              def_class);
-                       if (p->reject_unknown)
-                               return -EINVAL;
-                       if (p->allow_unknown)
-                               p->undefined_perms[i-1] = ~0U;
-                       print_unknown_handle = 1;
-                       continue;
-               }
-               pol_class = p->p_class_val_to_name[i-1];
-               if (strcmp(pol_class, def_class)) {
-                       printk(KERN_ERR
-                              "SELinux:  class %d is incorrect, found %s but should be %s\n",
-                              i, pol_class, def_class);
-                       return -EINVAL;
-               }
-       }
-       for (i = 0; i < kdefs->av_pts_len; i++) {
-               class_val = kdefs->av_perm_to_string[i].tclass;
-               perm_val = kdefs->av_perm_to_string[i].value;
-               def_perm = kdefs->av_perm_to_string[i].name;
-               if (class_val > p->p_classes.nprim)
-                       continue;
-               pol_class = p->p_class_val_to_name[class_val-1];
-               cladatum = hashtab_search(p->p_classes.table, pol_class);
-               BUG_ON(!cladatum);
-               perms = &cladatum->permissions;
-               nprim = 1 << (perms->nprim - 1);
-               if (perm_val > nprim) {
-                       printk(KERN_INFO
-                              "SELinux:  permission %s in class %s not defined in policy\n",
-                              def_perm, pol_class);
-                       if (p->reject_unknown)
-                               return -EINVAL;
-                       if (p->allow_unknown)
-                               p->undefined_perms[class_val-1] |= perm_val;
-                       print_unknown_handle = 1;
-                       continue;
-               }
-               perdatum = hashtab_search(perms->table, def_perm);
-               if (perdatum == NULL) {
-                       printk(KERN_ERR
-                              "SELinux:  permission %s in class %s not found in policy, bad policy\n",
-                              def_perm, pol_class);
-                       return -EINVAL;
-               }
-               pol_val = 1 << (perdatum->value - 1);
-               if (pol_val != perm_val) {
-                       printk(KERN_ERR
-                              "SELinux:  permission %s in class %s has incorrect value\n",
-                              def_perm, pol_class);
-                       return -EINVAL;
-               }
-       }
-       for (i = 0; i < kdefs->av_inherit_len; i++) {
-               class_val = kdefs->av_inherit[i].tclass;
-               if (class_val > p->p_classes.nprim)
-                       continue;
-               pol_class = p->p_class_val_to_name[class_val-1];
-               cladatum = hashtab_search(p->p_classes.table, pol_class);
-               BUG_ON(!cladatum);
-               if (!cladatum->comdatum) {
-                       printk(KERN_ERR
-                              "SELinux:  class %s should have an inherits clause but does not\n",
-                              pol_class);
-                       return -EINVAL;
-               }
-               tmp = kdefs->av_inherit[i].common_base;
-               common_pts_len = 0;
-               while (!(tmp & 0x01)) {
-                       common_pts_len++;
-                       tmp >>= 1;
-               }
-               perms = &cladatum->comdatum->permissions;
-               for (j = 0; j < common_pts_len; j++) {
-                       def_perm = kdefs->av_inherit[i].common_pts[j];
-                       if (j >= perms->nprim) {
-                               printk(KERN_INFO
-                                      "SELinux:  permission %s in class %s not defined in policy\n",
-                                      def_perm, pol_class);
-                               if (p->reject_unknown)
-                                       return -EINVAL;
-                               if (p->allow_unknown)
-                                       p->undefined_perms[class_val-1] |= (1 << j);
-                               print_unknown_handle = 1;
-                               continue;
-                       }
-                       perdatum = hashtab_search(perms->table, def_perm);
-                       if (perdatum == NULL) {
-                               printk(KERN_ERR
-                                      "SELinux:  permission %s in class %s not found in policy, bad policy\n",
-                                      def_perm, pol_class);
-                               return -EINVAL;
-                       }
-                       if (perdatum->value != j + 1) {
-                               printk(KERN_ERR
-                                      "SELinux:  permission %s in class %s has incorrect value\n",
-                                      def_perm, pol_class);
-                               return -EINVAL;
-                       }
-               }
-       }
-       if (print_unknown_handle)
-               printk(KERN_INFO "SELinux: the above unknown classes and permissions will be %s\n",
-                       (security_get_allow_unknown() ? "allowed" : "denied"));
-       return 0;
+       return security_compute_sid(ssid, tsid, tclass, AVTAB_CHANGE, out_sid,
+                                   false);
 }
 
 /* Clone the SID into the new SID table. */
@@ -1710,8 +1728,10 @@ int security_load_policy(void *data, size_t len)
 {
        struct policydb oldpolicydb, newpolicydb;
        struct sidtab oldsidtab, newsidtab;
+       struct selinux_mapping *oldmap, *map = NULL;
        struct convert_context_args args;
        u32 seqno;
+       u16 map_size;
        int rc = 0;
        struct policy_file file = { data, len }, *fp = &file;
 
@@ -1721,22 +1741,19 @@ int security_load_policy(void *data, size_t len)
                        avtab_cache_destroy();
                        return -EINVAL;
                }
-               if (policydb_load_isids(&policydb, &sidtab)) {
+               if (selinux_set_mapping(&policydb, secclass_map,
+                                       &current_mapping,
+                                       &current_mapping_size)) {
                        policydb_destroy(&policydb);
                        avtab_cache_destroy();
                        return -EINVAL;
                }
-               /* Verify that the kernel defined classes are correct. */
-               if (validate_classes(&policydb)) {
-                       printk(KERN_ERR
-                              "SELinux:  the definition of a class is incorrect\n");
-                       sidtab_destroy(&sidtab);
+               if (policydb_load_isids(&policydb, &sidtab)) {
                        policydb_destroy(&policydb);
                        avtab_cache_destroy();
                        return -EINVAL;
                }
                security_load_policycaps();
-               policydb_loaded_version = policydb.policyvers;
                ss_initialized = 1;
                seqno = ++latest_granting;
                selinux_complete_init();
@@ -1759,13 +1776,9 @@ int security_load_policy(void *data, size_t len)
                return -ENOMEM;
        }
 
-       /* Verify that the kernel defined classes are correct. */
-       if (validate_classes(&newpolicydb)) {
-               printk(KERN_ERR
-                      "SELinux:  the definition of a class is incorrect\n");
-               rc = -EINVAL;
+       if (selinux_set_mapping(&newpolicydb, secclass_map,
+                               &map, &map_size))
                goto err;
-       }
 
        rc = security_preserve_bools(&newpolicydb);
        if (rc) {
@@ -1799,13 +1812,16 @@ int security_load_policy(void *data, size_t len)
        memcpy(&policydb, &newpolicydb, sizeof policydb);
        sidtab_set(&sidtab, &newsidtab);
        security_load_policycaps();
+       oldmap = current_mapping;
+       current_mapping = map;
+       current_mapping_size = map_size;
        seqno = ++latest_granting;
-       policydb_loaded_version = policydb.policyvers;
        write_unlock_irq(&policy_rwlock);
 
        /* Free the old policydb and SID table. */
        policydb_destroy(&oldpolicydb);
        sidtab_destroy(&oldsidtab);
+       kfree(oldmap);
 
        avc_ss_reset(seqno);
        selnl_notify_policyload(seqno);
@@ -1815,6 +1831,7 @@ int security_load_policy(void *data, size_t len)
        return 0;
 
 err:
+       kfree(map);
        sidtab_destroy(&newsidtab);
        policydb_destroy(&newpolicydb);
        return rc;
@@ -2091,7 +2108,7 @@ out_unlock:
        }
        for (i = 0, j = 0; i < mynel; i++) {
                rc = avc_has_perm_noaudit(fromsid, mysids[i],
-                                         SECCLASS_PROCESS,
+                                         SECCLASS_PROCESS, /* kernel value */
                                          PROCESS__TRANSITION, AVC_STRICT,
                                          NULL);
                if (!rc)
@@ -2119,10 +2136,11 @@ out:
  */
 int security_genfs_sid(const char *fstype,
                       char *path,
-                      u16 sclass,
+                      u16 orig_sclass,
                       u32 *sid)
 {
        int len;
+       u16 sclass;
        struct genfs *genfs;
        struct ocontext *c;
        int rc = 0, cmp = 0;
@@ -2132,6 +2150,8 @@ int security_genfs_sid(const char *fstype,
 
        read_lock(&policy_rwlock);
 
+       sclass = unmap_class(orig_sclass);
+
        for (genfs = policydb.genfs; genfs; genfs = genfs->next) {
                cmp = strcmp(fstype, genfs->fstype);
                if (cmp <= 0)
index 3c8bd8ee0b95e70e17e801913eb7481030ebcfae..e0d0354008b75a041887b2ae59a50fbd1e572a2b 100644 (file)
@@ -187,6 +187,8 @@ bool tomoyo_is_correct_path(const char *filename, const s8 start_type,
                            const s8 pattern_type, const s8 end_type,
                            const char *function)
 {
+       const char *const start = filename;
+       bool in_repetition = false;
        bool contains_pattern = false;
        unsigned char c;
        unsigned char d;
@@ -212,9 +214,13 @@ bool tomoyo_is_correct_path(const char *filename, const s8 start_type,
                if (c == '/')
                        goto out;
        }
-       while ((c = *filename++) != '\0') {
+       while (1) {
+               c = *filename++;
+               if (!c)
+                       break;
                if (c == '\\') {
-                       switch ((c = *filename++)) {
+                       c = *filename++;
+                       switch (c) {
                        case '\\':  /* "\\" */
                                continue;
                        case '$':   /* "\$" */
@@ -231,6 +237,22 @@ bool tomoyo_is_correct_path(const char *filename, const s8 start_type,
                                        break; /* Must not contain pattern */
                                contains_pattern = true;
                                continue;
+                       case '{':   /* "/\{" */
+                               if (filename - 3 < start ||
+                                   *(filename - 3) != '/')
+                                       break;
+                               if (pattern_type == -1)
+                                       break; /* Must not contain pattern */
+                               contains_pattern = true;
+                               in_repetition = true;
+                               continue;
+                       case '}':   /* "\}/" */
+                               if (*filename != '/')
+                                       break;
+                               if (!in_repetition)
+                                       break;
+                               in_repetition = false;
+                               continue;
                        case '0':   /* "\ooo" */
                        case '1':
                        case '2':
@@ -246,6 +268,8 @@ bool tomoyo_is_correct_path(const char *filename, const s8 start_type,
                                        continue; /* pattern is not \000 */
                        }
                        goto out;
+               } else if (in_repetition && c == '/') {
+                       goto out;
                } else if (tomoyo_is_invalid(c)) {
                        goto out;
                }
@@ -254,6 +278,8 @@ bool tomoyo_is_correct_path(const char *filename, const s8 start_type,
                if (!contains_pattern)
                        goto out;
        }
+       if (in_repetition)
+               goto out;
        return true;
  out:
        printk(KERN_DEBUG "%s: Invalid pathname '%s'\n", function,
@@ -359,33 +385,6 @@ struct tomoyo_domain_info *tomoyo_find_domain(const char *domainname)
        return NULL;
 }
 
-/**
- * tomoyo_path_depth - Evaluate the number of '/' in a string.
- *
- * @pathname: The string to evaluate.
- *
- * Returns path depth of the string.
- *
- * I score 2 for each of the '/' in the @pathname
- * and score 1 if the @pathname ends with '/'.
- */
-static int tomoyo_path_depth(const char *pathname)
-{
-       int i = 0;
-
-       if (pathname) {
-               const char *ep = pathname + strlen(pathname);
-               if (pathname < ep--) {
-                       if (*ep != '/')
-                               i++;
-                       while (pathname <= ep)
-                               if (*ep-- == '/')
-                                       i += 2;
-               }
-       }
-       return i;
-}
-
 /**
  * tomoyo_const_part_length - Evaluate the initial length without a pattern in a token.
  *
@@ -444,11 +443,10 @@ void tomoyo_fill_path_info(struct tomoyo_path_info *ptr)
        ptr->is_dir = len && (name[len - 1] == '/');
        ptr->is_patterned = (ptr->const_len < len);
        ptr->hash = full_name_hash(name, len);
-       ptr->depth = tomoyo_path_depth(name);
 }
 
 /**
- * tomoyo_file_matches_to_pattern2 - Pattern matching without '/' character
+ * tomoyo_file_matches_pattern2 - Pattern matching without '/' character
  * and "\-" pattern.
  *
  * @filename:     The start of string to check.
@@ -458,10 +456,10 @@ void tomoyo_fill_path_info(struct tomoyo_path_info *ptr)
  *
  * Returns true if @filename matches @pattern, false otherwise.
  */
-static bool tomoyo_file_matches_to_pattern2(const char *filename,
-                                           const char *filename_end,
-                                           const char *pattern,
-                                           const char *pattern_end)
+static bool tomoyo_file_matches_pattern2(const char *filename,
+                                        const char *filename_end,
+                                        const char *pattern,
+                                        const char *pattern_end)
 {
        while (filename < filename_end && pattern < pattern_end) {
                char c;
@@ -519,7 +517,7 @@ static bool tomoyo_file_matches_to_pattern2(const char *filename,
                case '*':
                case '@':
                        for (i = 0; i <= filename_end - filename; i++) {
-                               if (tomoyo_file_matches_to_pattern2(
+                               if (tomoyo_file_matches_pattern2(
                                                    filename + i, filename_end,
                                                    pattern + 1, pattern_end))
                                        return true;
@@ -550,7 +548,7 @@ static bool tomoyo_file_matches_to_pattern2(const char *filename,
                                        j++;
                        }
                        for (i = 1; i <= j; i++) {
-                               if (tomoyo_file_matches_to_pattern2(
+                               if (tomoyo_file_matches_pattern2(
                                                    filename + i, filename_end,
                                                    pattern + 1, pattern_end))
                                        return true;
@@ -567,7 +565,7 @@ static bool tomoyo_file_matches_to_pattern2(const char *filename,
 }
 
 /**
- * tomoyo_file_matches_to_pattern - Pattern matching without without '/' character.
+ * tomoyo_file_matches_pattern - Pattern matching without without '/' character.
  *
  * @filename:     The start of string to check.
  * @filename_end: The end of string to check.
@@ -576,7 +574,7 @@ static bool tomoyo_file_matches_to_pattern2(const char *filename,
  *
  * Returns true if @filename matches @pattern, false otherwise.
  */
-static bool tomoyo_file_matches_to_pattern(const char *filename,
+static bool tomoyo_file_matches_pattern(const char *filename,
                                           const char *filename_end,
                                           const char *pattern,
                                           const char *pattern_end)
@@ -589,10 +587,10 @@ static bool tomoyo_file_matches_to_pattern(const char *filename,
                /* Split at "\-" pattern. */
                if (*pattern++ != '\\' || *pattern++ != '-')
                        continue;
-               result = tomoyo_file_matches_to_pattern2(filename,
-                                                        filename_end,
-                                                        pattern_start,
-                                                        pattern - 2);
+               result = tomoyo_file_matches_pattern2(filename,
+                                                     filename_end,
+                                                     pattern_start,
+                                                     pattern - 2);
                if (first)
                        result = !result;
                if (result)
@@ -600,13 +598,79 @@ static bool tomoyo_file_matches_to_pattern(const char *filename,
                first = false;
                pattern_start = pattern;
        }
-       result = tomoyo_file_matches_to_pattern2(filename, filename_end,
-                                                pattern_start, pattern_end);
+       result = tomoyo_file_matches_pattern2(filename, filename_end,
+                                             pattern_start, pattern_end);
        return first ? result : !result;
 }
 
+/**
+ * tomoyo_path_matches_pattern2 - Do pathname pattern matching.
+ *
+ * @f: The start of string to check.
+ * @p: The start of pattern to compare.
+ *
+ * Returns true if @f matches @p, false otherwise.
+ */
+static bool tomoyo_path_matches_pattern2(const char *f, const char *p)
+{
+       const char *f_delimiter;
+       const char *p_delimiter;
+
+       while (*f && *p) {
+               f_delimiter = strchr(f, '/');
+               if (!f_delimiter)
+                       f_delimiter = f + strlen(f);
+               p_delimiter = strchr(p, '/');
+               if (!p_delimiter)
+                       p_delimiter = p + strlen(p);
+               if (*p == '\\' && *(p + 1) == '{')
+                       goto recursive;
+               if (!tomoyo_file_matches_pattern(f, f_delimiter, p,
+                                                p_delimiter))
+                       return false;
+               f = f_delimiter;
+               if (*f)
+                       f++;
+               p = p_delimiter;
+               if (*p)
+                       p++;
+       }
+       /* Ignore trailing "\*" and "\@" in @pattern. */
+       while (*p == '\\' &&
+              (*(p + 1) == '*' || *(p + 1) == '@'))
+               p += 2;
+       return !*f && !*p;
+ recursive:
+       /*
+        * The "\{" pattern is permitted only after '/' character.
+        * This guarantees that below "*(p - 1)" is safe.
+        * Also, the "\}" pattern is permitted only before '/' character
+        * so that "\{" + "\}" pair will not break the "\-" operator.
+        */
+       if (*(p - 1) != '/' || p_delimiter <= p + 3 || *p_delimiter != '/' ||
+           *(p_delimiter - 1) != '}' || *(p_delimiter - 2) != '\\')
+               return false; /* Bad pattern. */
+       do {
+               /* Compare current component with pattern. */
+               if (!tomoyo_file_matches_pattern(f, f_delimiter, p + 2,
+                                                p_delimiter - 2))
+                       break;
+               /* Proceed to next component. */
+               f = f_delimiter;
+               if (!*f)
+                       break;
+               f++;
+               /* Continue comparison. */
+               if (tomoyo_path_matches_pattern2(f, p_delimiter + 1))
+                       return true;
+               f_delimiter = strchr(f, '/');
+       } while (f_delimiter);
+       return false; /* Not matched. */
+}
+
 /**
  * tomoyo_path_matches_pattern - Check whether the given filename matches the given pattern.
+ *
  * @filename: The filename to check.
  * @pattern:  The pattern to compare.
  *
@@ -615,24 +679,24 @@ static bool tomoyo_file_matches_to_pattern(const char *filename,
  * The following patterns are available.
  *   \\     \ itself.
  *   \ooo   Octal representation of a byte.
- *   \*     More than or equals to 0 character other than '/'.
- *   \@     More than or equals to 0 character other than '/' or '.'.
+ *   \*     Zero or more repetitions of characters other than '/'.
+ *   \@     Zero or more repetitions of characters other than '/' or '.'.
  *   \?     1 byte character other than '/'.
- *   \$     More than or equals to 1 decimal digit.
+ *   \$     One or more repetitions of decimal digits.
  *   \+     1 decimal digit.
- *   \X     More than or equals to 1 hexadecimal digit.
+ *   \X     One or more repetitions of hexadecimal digits.
  *   \x     1 hexadecimal digit.
- *   \A     More than or equals to 1 alphabet character.
+ *   \A     One or more repetitions of alphabet characters.
  *   \a     1 alphabet character.
+ *
  *   \-     Subtraction operator.
+ *
+ *   /\{dir\}/   '/' + 'One or more repetitions of dir/' (e.g. /dir/ /dir/dir/
+ *               /dir/dir/dir/ ).
  */
 bool tomoyo_path_matches_pattern(const struct tomoyo_path_info *filename,
                                 const struct tomoyo_path_info *pattern)
 {
-       /*
-         if (!filename || !pattern)
-         return false;
-       */
        const char *f = filename->name;
        const char *p = pattern->name;
        const int len = pattern->const_len;
@@ -640,37 +704,15 @@ bool tomoyo_path_matches_pattern(const struct tomoyo_path_info *filename,
        /* If @pattern doesn't contain pattern, I can use strcmp(). */
        if (!pattern->is_patterned)
                return !tomoyo_pathcmp(filename, pattern);
-       /* Dont compare if the number of '/' differs. */
-       if (filename->depth != pattern->depth)
+       /* Don't compare directory and non-directory. */
+       if (filename->is_dir != pattern->is_dir)
                return false;
        /* Compare the initial length without patterns. */
        if (strncmp(f, p, len))
                return false;
        f += len;
        p += len;
-       /* Main loop. Compare each directory component. */
-       while (*f && *p) {
-               const char *f_delimiter = strchr(f, '/');
-               const char *p_delimiter = strchr(p, '/');
-               if (!f_delimiter)
-                       f_delimiter = f + strlen(f);
-               if (!p_delimiter)
-                       p_delimiter = p + strlen(p);
-               if (!tomoyo_file_matches_to_pattern(f, f_delimiter,
-                                                   p, p_delimiter))
-                       return false;
-               f = f_delimiter;
-               if (*f)
-                       f++;
-               p = p_delimiter;
-               if (*p)
-                       p++;
-       }
-       /* Ignore trailing "\*" and "\@" in @pattern. */
-       while (*p == '\\' &&
-              (*(p + 1) == '*' || *(p + 1) == '@'))
-               p += 2;
-       return !*f && !*p;
+       return tomoyo_path_matches_pattern2(f, p);
 }
 
 /**
index 31df541911f76f3d5cc39c92508eb37a25fb8545..92169d29b2db4c1e71ea5f89d142da5b02ca0ec3 100644 (file)
@@ -56,9 +56,6 @@ struct tomoyo_page_buffer {
  * (5) "is_patterned" is a bool which is true if "name" contains wildcard
  *     characters, false otherwise. This allows TOMOYO to use "hash" and
  *     strcmp() for string comparison if "is_patterned" is false.
- * (6) "depth" is calculated using the number of "/" characters in "name".
- *     This allows TOMOYO to avoid comparing two pathnames which never match
- *     (e.g. whether "/var/www/html/index.html" matches "/tmp/sh-thd-\$").
  */
 struct tomoyo_path_info {
        const char *name;
@@ -66,7 +63,6 @@ struct tomoyo_path_info {
        u16 const_len;     /* = tomoyo_const_part_length(name)     */
        bool is_dir;       /* = tomoyo_strendswith(name, "/")      */
        bool is_patterned; /* = tomoyo_path_contains_pattern(name) */
-       u16 depth;         /* = tomoyo_path_depth(name)            */
 };
 
 /*
index 5f2e3326337118c9252dc80ec10e53b3365c0a9c..917f564cdab16bbc6daa73215ee8a39cdd559bb6 100644 (file)
@@ -13,6 +13,8 @@
 #include <linux/mount.h>
 #include <linux/mnt_namespace.h>
 #include <linux/fs_struct.h>
+#include <linux/hash.h>
+
 #include "common.h"
 #include "realpath.h"
 
@@ -263,7 +265,8 @@ static unsigned int tomoyo_quota_for_savename;
  * table. Frequency of appending strings is very low. So we don't need
  * large (e.g. 64k) hash size. 256 will be sufficient.
  */
-#define TOMOYO_MAX_HASH 256
+#define TOMOYO_HASH_BITS  8
+#define TOMOYO_MAX_HASH (1u<<TOMOYO_HASH_BITS)
 
 /*
  * tomoyo_name_entry is a structure which is used for linking
@@ -315,6 +318,7 @@ const struct tomoyo_path_info *tomoyo_save_name(const char *name)
        struct tomoyo_free_memory_block_list *fmb;
        int len;
        char *cp;
+       struct list_head *head;
 
        if (!name)
                return NULL;
@@ -325,9 +329,10 @@ const struct tomoyo_path_info *tomoyo_save_name(const char *name)
                return NULL;
        }
        hash = full_name_hash((const unsigned char *) name, len - 1);
+       head = &tomoyo_name_list[hash_long(hash, TOMOYO_HASH_BITS)];
+
        mutex_lock(&lock);
-       list_for_each_entry(ptr, &tomoyo_name_list[hash % TOMOYO_MAX_HASH],
-                            list) {
+       list_for_each_entry(ptr, head, list) {
                if (hash == ptr->entry.hash && !strcmp(name, ptr->entry.name))
                        goto out;
        }
@@ -365,7 +370,7 @@ const struct tomoyo_path_info *tomoyo_save_name(const char *name)
        tomoyo_fill_path_info(&ptr->entry);
        fmb->ptr += len;
        fmb->len -= len;
-       list_add_tail(&ptr->list, &tomoyo_name_list[hash % TOMOYO_MAX_HASH]);
+       list_add_tail(&ptr->list, head);
        if (fmb->len == 0) {
                list_del(&fmb->list);
                kfree(fmb);
index 1f0f8213e2d5dde34a11e220d3fff44c3b70120b..6c160a038b239a7c9e2baa0d3f941c68c7d68398 100644 (file)
@@ -504,6 +504,10 @@ static int aaci_pcm_hw_params(struct snd_pcm_substream *substream,
        int err;
 
        aaci_pcm_hw_free(substream);
+       if (aacirun->pcm_open) {
+               snd_ac97_pcm_close(aacirun->pcm);
+               aacirun->pcm_open = 0;
+       }
 
        err = devdma_hw_alloc(NULL, substream,
                              params_buffer_bytes(params));
@@ -517,7 +521,7 @@ static int aaci_pcm_hw_params(struct snd_pcm_substream *substream,
        else
                err = snd_ac97_pcm_open(aacirun->pcm, params_rate(params),
                                        params_channels(params),
-                                       aacirun->pcm->r[1].slots);
+                                       aacirun->pcm->r[0].slots);
 
        if (err)
                goto out;
index 5460faae98c9a305015fbf8ee57fb20c883dcb84..041ef5c52bc269389fd3249dbcff0e0bc5ffdd43 100644 (file)
@@ -12,7 +12,7 @@
 #define MAX_SIZE (256*1024)
 unsigned char buf[MAX_SIZE];
 
-int loadhex(FILE *inf, unsigned char *buf)
+static int loadhex(FILE *inf, unsigned char *buf)
 {
        int l=0, c, i;
 
index 9fb60276f5c9d6782d5d00cf030dff7266b91bdf..6afdab09bab77ae9e81737b12f1f81d3d476b9ce 100644 (file)
@@ -397,6 +397,7 @@ static int patch_nvhdmi_2ch(struct hda_codec *codec)
 static struct hda_codec_preset snd_hda_preset_nvhdmi[] = {
        { .id = 0x10de0002, .name = "MCP78 HDMI", .patch = patch_nvhdmi_8ch },
        { .id = 0x10de0003, .name = "MCP78 HDMI", .patch = patch_nvhdmi_8ch },
+       { .id = 0x10de0005, .name = "MCP78 HDMI", .patch = patch_nvhdmi_8ch },
        { .id = 0x10de0006, .name = "MCP78 HDMI", .patch = patch_nvhdmi_8ch },
        { .id = 0x10de0007, .name = "MCP7A HDMI", .patch = patch_nvhdmi_8ch },
        { .id = 0x10de0067, .name = "MCP67 HDMI", .patch = patch_nvhdmi_2ch },
@@ -406,6 +407,7 @@ static struct hda_codec_preset snd_hda_preset_nvhdmi[] = {
 
 MODULE_ALIAS("snd-hda-codec-id:10de0002");
 MODULE_ALIAS("snd-hda-codec-id:10de0003");
+MODULE_ALIAS("snd-hda-codec-id:10de0005");
 MODULE_ALIAS("snd-hda-codec-id:10de0006");
 MODULE_ALIAS("snd-hda-codec-id:10de0007");
 MODULE_ALIAS("snd-hda-codec-id:10de0067");
index daf6975b0c2eed70f768422324a5ac0e12e448b3..70583719282bed6d0e62b44cc1c15127fc0b916e 100644 (file)
@@ -8911,10 +8911,11 @@ static struct snd_pci_quirk alc882_ssid_cfg_tbl[] = {
        SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3),
        SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_IMAC24),
        SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5),
-       /* FIXME: HP jack sense seems not working for MBP 5,1, so apparently
-        * no perfect solution yet
+       /* FIXME: HP jack sense seems not working for MBP 5,1 or 5,2,
+        * so apparently no perfect solution yet
         */
        SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5),
+       SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC885_MB5),
        {} /* terminator */
 };
 
@@ -11461,6 +11462,7 @@ static struct snd_pci_quirk alc262_cfg_tbl[] = {
        SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */
        SND_PCI_QUIRK(0x104d, 0x9025, "Sony VAIO Z21MN", ALC262_TOSHIBA_S06),
        SND_PCI_QUIRK(0x104d, 0x9035, "Sony VAIO VGN-FW170J", ALC262_AUTO),
+       SND_PCI_QUIRK(0x104d, 0x9047, "Sony VAIO Type G", ALC262_AUTO),
        SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO",
                           ALC262_SONY_ASSAMD),
        SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
index 8eb6508cd991214e4c06de4891d959059913d998..86de305fc9f225ef382f6a7bdfbd438a2f97840f 100644 (file)
@@ -1590,6 +1590,8 @@ static struct snd_pci_quirk stac92hd73xx_cfg_tbl[] = {
                                "Dell Studio 17", STAC_DELL_M6_DMIC),
        SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02be,
                                "Dell Studio 1555", STAC_DELL_M6_DMIC),
+       SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02bd,
+                               "Dell Studio 1557", STAC_DELL_M6_DMIC),
        {} /* terminator */
 };
 
index 9da2dae64c5b6e565ffb85d7b184a62d3c07af99..d063149e70475326dc1713d9ed08a8b1098ed4b3 100644 (file)
@@ -382,8 +382,8 @@ struct snd_ice1712 {
 #ifdef CONFIG_PM
        int (*pm_suspend)(struct snd_ice1712 *);
        int (*pm_resume)(struct snd_ice1712 *);
-       int pm_suspend_enabled:1;
-       int pm_saved_is_spdif_master:1;
+       unsigned int pm_suspend_enabled:1;
+       unsigned int pm_saved_is_spdif_master:1;
        unsigned int pm_saved_spdif_ctrl;
        unsigned char pm_saved_spdif_cfg;
        unsigned int pm_saved_route;
index c75515f5be6f0cd7ac4910cf52e930799984535c..6a9fee3ee78faee3e31bcd7de5d4873d5a6d461f 100644 (file)
@@ -1100,7 +1100,7 @@ static void ak4396_init(struct snd_ice1712 *ice)
 }
 
 #ifdef CONFIG_PM
-static int __devinit prodigy_hd2_resume(struct snd_ice1712 *ice)
+static int prodigy_hd2_resume(struct snd_ice1712 *ice)
 {
        /* initialize ak4396 codec and restore previous mixer volumes */
        struct prodigy_hifi_spec *spec = ice->spec;
index 64b859925c0b16bd5ac458f25419fbcd8b4c3308..7717e01fc07127f51e99c3a669a18be75ab6a0eb 100644 (file)
@@ -131,7 +131,7 @@ static int snd_pdacf_probe(struct pcmcia_device *link)
                return err;
        }
 
-       snd_card_set_dev(card, &handle_to_dev(link));
+       snd_card_set_dev(card, &link->dev);
 
        pdacf->index = i;
        card_list[i] = card;
@@ -142,12 +142,10 @@ static int snd_pdacf_probe(struct pcmcia_device *link)
        link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
        link->io.NumPorts1 = 16;
 
-       link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT | IRQ_FORCED_PULSE;
+       link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_FORCED_PULSE;
        // link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
 
-       link->irq.IRQInfo1 = 0 /* | IRQ_LEVEL_ID */;
        link->irq.Handler = pdacf_interrupt;
-       link->irq.Instance = pdacf;
        link->conf.Attributes = CONF_ENABLE_IRQ;
        link->conf.IntType = INT_MEMORY_AND_IO;
        link->conf.ConfigIndex = 1;
index 1492744ad67feb156ea03bf41182a21c25c98ca6..7be3b335704597d0a7808e8cc4eae1356ded7f73 100644 (file)
@@ -161,11 +161,9 @@ static int snd_vxpocket_new(struct snd_card *card, int ibl,
        link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
        link->io.NumPorts1 = 16;
 
-       link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
+       link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
 
-       link->irq.IRQInfo1 = IRQ_LEVEL_ID;
        link->irq.Handler = &snd_vx_irq_handler;
-       link->irq.Instance = chip;
 
        link->conf.Attributes = CONF_ENABLE_IRQ;
        link->conf.IntType = INT_MEMORY_AND_IO;
@@ -244,7 +242,7 @@ static int vxpocket_config(struct pcmcia_device *link)
        if (ret)
                goto failed;
 
-       chip->dev = &handle_to_dev(link);
+       chip->dev = &link->dev;
        snd_card_set_dev(chip->card, chip->dev);
 
        if (snd_vxpocket_assign_resources(chip, link->io.BasePort1, link->irq.AssignedIRQ) < 0)
index 0b8dcb5cd729281bfd80264acdb5a58b9025636e..90a0264f75389f49e4c9ed544787ba0375f00c7f 100644 (file)
@@ -265,8 +265,8 @@ static const int bosr_usb_divisor_table[] = {
 #define UPPER_GROUP ((1<<8) | (1<<9) | (1<<10) | (1<<11)        | (1<<15))
 static const unsigned short sr_valid_mask[] = {
        LOWER_GROUP|UPPER_GROUP,        /* Normal, bosr - 0*/
-       LOWER_GROUP|UPPER_GROUP,        /* Normal, bosr - 1*/
        LOWER_GROUP,                    /* Usb, bosr - 0*/
+       LOWER_GROUP|UPPER_GROUP,        /* Normal, bosr - 1*/
        UPPER_GROUP,                    /* Usb, bosr - 1*/
 };
 /*
@@ -625,11 +625,10 @@ static int tlv320aic23_resume(struct platform_device *pdev)
 {
        struct snd_soc_device *socdev = platform_get_drvdata(pdev);
        struct snd_soc_codec *codec = socdev->card->codec;
-       int i;
        u16 reg;
 
        /* Sync reg_cache with the hardware */
-       for (reg = 0; reg < ARRAY_SIZE(tlv320aic23_reg); i++) {
+       for (reg = 0; reg < TLV320AIC23_RESET; reg++) {
                u16 val = tlv320aic23_read_reg_cache(codec, reg);
                tlv320aic23_write(codec, reg, val);
        }
index 9114c263077bb18972164c41f29fcaaf02448005..13aa380de162daa7deab8abbdf8fb3231ddca418 100644 (file)
@@ -144,4 +144,4 @@ module_exit(omap3evm_soc_exit);
 
 MODULE_AUTHOR("Anuj Aggarwal <anuj.aggarwal@ti.com>");
 MODULE_DESCRIPTION("ALSA SoC OMAP3 EVM");
-MODULE_LICENSE("GPLv2");
+MODULE_LICENSE("GPL v2");
index ad219aaf7cb80678ae80c1263f41df565803cfe0..0cd06f5dd356f24214d91d714ecfbd991478ff81 100644 (file)
@@ -134,7 +134,7 @@ static int omap3pandora_hp_event(struct snd_soc_dapm_widget *w,
  *  |P| <--- TWL4030 <--------- Line In and MICs
  */
 static const struct snd_soc_dapm_widget omap3pandora_out_dapm_widgets[] = {
-       SND_SOC_DAPM_DAC("PCM DAC", "Playback", SND_SOC_NOPM, 0, 0),
+       SND_SOC_DAPM_DAC("PCM DAC", "HiFi Playback", SND_SOC_NOPM, 0, 0),
        SND_SOC_DAPM_PGA_E("Headphone Amplifier", SND_SOC_NOPM,
                           0, 0, NULL, 0, omap3pandora_hp_event,
                           SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
@@ -181,6 +181,7 @@ static int omap3pandora_out_init(struct snd_soc_codec *codec)
        snd_soc_dapm_nc_pin(codec, "CARKITR");
        snd_soc_dapm_nc_pin(codec, "HFL");
        snd_soc_dapm_nc_pin(codec, "HFR");
+       snd_soc_dapm_nc_pin(codec, "VIBRA");
 
        ret = snd_soc_dapm_new_controls(codec, omap3pandora_out_dapm_widgets,
                                ARRAY_SIZE(omap3pandora_out_dapm_widgets));
index d89f6dc00908284d0e97e5778dfe9444b99683ff..66d4c165f99b468fe2fe051b6bd5782684705852 100644 (file)
@@ -973,9 +973,19 @@ static int dapm_power_widgets(struct snd_soc_codec *codec, int event)
                        if (!w->power_check)
                                continue;
 
-                       power = w->power_check(w);
-                       if (power)
-                               sys_power = 1;
+                       /* If we're suspending then pull down all the 
+                        * power. */
+                       switch (event) {
+                       case SND_SOC_DAPM_STREAM_SUSPEND:
+                               power = 0;
+                               break;
+
+                       default:
+                               power = w->power_check(w);
+                               if (power)
+                                       sys_power = 1;
+                               break;
+                       }
 
                        if (w->power == power)
                                continue;
@@ -999,8 +1009,12 @@ static int dapm_power_widgets(struct snd_soc_codec *codec, int event)
                case SND_SOC_DAPM_STREAM_RESUME:
                        sys_power = 1;
                        break;
+               case SND_SOC_DAPM_STREAM_SUSPEND:
+                       sys_power = 0;
+                       break;
                case SND_SOC_DAPM_STREAM_NOP:
                        sys_power = codec->bias_level != SND_SOC_BIAS_STANDBY;
+                       break;
                default:
                        break;
                }
index 9efcfd08d747b1c430ae17f9429fda3b57974a0b..c998220b99c62e30c4d32276478ed7e15c2ca7c5 100644 (file)
@@ -1071,6 +1071,15 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, unsig
        channels = (ftr[0] - 7) / csize - 1;
 
        master_bits = snd_usb_combine_bytes(ftr + 6, csize);
+       /* master configuration quirks */
+       switch (state->chip->usb_id) {
+       case USB_ID(0x08bb, 0x2702):
+               snd_printk(KERN_INFO
+                          "usbmixer: master volume quirk for PCM2702 chip\n");
+               /* disable non-functional volume control */
+               master_bits &= ~(1 << (USB_FEATURE_VOLUME - 1));
+               break;
+       }
        if (channels > 0)
                first_ch_bits = snd_usb_combine_bytes(ftr + 6 + csize, csize);
        else