]> git.karo-electronics.de Git - mv-sheeva.git/commitdiff
Merge branch 'media_fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab...
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 3 Feb 2011 01:52:19 +0000 (17:52 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 3 Feb 2011 01:52:19 +0000 (17:52 -0800)
* 'media_fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6:
  [media] fix saa7111 non-detection
  [media] rc/streamzap: fix reporting response times
  [media] mceusb: really fix remaining keybounce issues
  [media] rc: use time unit conversion macros correctly
  [media] rc/ir-lirc-codec: add back debug spew
  [media] ir-kbd-i2c: improve remote behavior with z8 behind usb
  [media] lirc_zilog: z8 on usb doesn't like back-to-back i2c_master_send
  [media] hdpvr: fix up i2c device registration
  [media] rc/mce: add mappings for missing keys
  [media] gspca - zc3xx: Discard the partial frames
  [media] gspca - zc3xx: Fix bad images with the sensor hv7131r
  [media] gspca - zc3xx: Bad delay when given by a table

542 files changed:
.mailmap
Documentation/ABI/testing/sysfs-platform-at91 [new file with mode: 0644]
Documentation/DocBook/device-drivers.tmpl
Documentation/feature-removal-schedule.txt
Documentation/filesystems/ntfs.txt
Documentation/kernel-parameters.txt
Documentation/networking/bonding.txt
MAINTAINERS
Makefile
arch/arm/include/asm/hardware/sp810.h
arch/arm/include/asm/io.h
arch/arm/include/asm/memory.h
arch/arm/kernel/head.S
arch/arm/kernel/smp_twd.c
arch/arm/mach-ep93xx/gpio.c
arch/arm/mach-footbridge/include/mach/debug-macro.S
arch/arm/mach-omap1/Kconfig
arch/arm/mach-omap1/Makefile
arch/arm/mach-omap1/include/mach/entry-macro.S
arch/arm/mach-omap1/irq.c
arch/arm/mach-omap1/time.c
arch/arm/mach-omap1/timer32k.c
arch/arm/mach-omap2/board-cm-t3517.c
arch/arm/mach-omap2/board-devkit8000.c
arch/arm/mach-omap2/clock44xx_data.c
arch/arm/mach-omap2/clockdomain.c
arch/arm/mach-omap2/clockdomains44xx_data.c
arch/arm/mach-omap2/dma.c
arch/arm/mach-omap2/include/mach/entry-macro.S
arch/arm/mach-omap2/io.c
arch/arm/mach-omap2/mux.c
arch/arm/mach-omap2/pm24xx.c
arch/arm/mach-omap2/pm34xx.c
arch/arm/mach-omap2/powerdomain2xxx_3xxx.c
arch/arm/mach-omap2/serial.c
arch/arm/mach-omap2/timer-gp.c
arch/arm/mach-realview/Kconfig
arch/arm/mach-realview/platsmp.c
arch/arm/mach-shmobile/Kconfig
arch/arm/mach-shmobile/board-ag5evm.c
arch/arm/mach-shmobile/board-g3evm.c
arch/arm/mach-shmobile/board-mackerel.c
arch/arm/mach-shmobile/clock-sh7372.c
arch/arm/mach-shmobile/clock-sh73a0.c
arch/arm/mach-shmobile/intc-sh7372.c
arch/arm/mach-shmobile/intc-sh73a0.c
arch/arm/mach-tegra/gpio.c
arch/arm/mach-tegra/include/mach/clk.h
arch/arm/mach-tegra/include/mach/clkdev.h
arch/arm/mach-tegra/include/mach/kbc.h [new file with mode: 0644]
arch/arm/mach-tegra/irq.c
arch/arm/mach-versatile/Kconfig
arch/arm/mach-vexpress/platsmp.c
arch/arm/mach-vexpress/v2m.c
arch/arm/mm/init.c
arch/arm/plat-omap/Kconfig
arch/arm/plat-omap/counter_32k.c
arch/arm/plat-omap/dma.c
arch/arm/plat-omap/include/plat/common.h
arch/avr32/include/asm/pgalloc.h
arch/m68k/amiga/config.c
arch/m68k/atari/ataints.c
arch/m68k/atari/config.c
arch/m68k/atari/debug.c
arch/m68k/include/asm/atarihw.h
arch/m68k/include/asm/string.h
arch/microblaze/kernel/head.S
arch/microblaze/kernel/hw_exception_handler.S
arch/microblaze/lib/fastcopy.S
arch/parisc/kernel/pdc_cons.c
arch/powerpc/kernel/perf_event_fsl_emb.c
arch/s390/Kconfig
arch/s390/include/asm/cacheflush.h
arch/s390/include/asm/tlb.h
arch/s390/lib/uaccess_std.c
arch/s390/mm/pgtable.c
arch/sh/Kconfig
arch/sh/Makefile
arch/sh/boards/mach-ecovec24/setup.c
arch/sh/boot/Makefile
arch/sh/boot/compressed/Makefile
arch/sh/boot/compressed/misc.c
arch/sh/include/asm/pgtable.h
arch/sh/kernel/cpu/sh4/setup-sh7750.c
arch/sh/kernel/topology.c
arch/x86/include/asm/cacheflush.h
arch/x86/include/asm/cpu.h
arch/x86/include/asm/jump_label.h
arch/x86/include/asm/paravirt.h
arch/x86/include/asm/percpu.h
arch/x86/include/asm/system_64.h [deleted file]
arch/x86/kernel/cpu/intel_cacheinfo.c
arch/x86/kernel/cpu/mcheck/therm_throt.c
arch/x86/kernel/dumpstack_64.c
arch/x86/kernel/process.c
arch/x86/kernel/smpboot.c
arch/x86/xen/p2m.c
arch/x86/xen/setup.c
drivers/ata/ahci.c
drivers/ata/libata-core.c
drivers/ata/libata-scsi.c
drivers/ata/pata_hpt366.c
drivers/ata/pata_hpt37x.c
drivers/ata/pata_hpt3x2n.c
drivers/ata/pata_mpc52xx.c
drivers/atm/idt77105.c
drivers/base/power/runtime.c
drivers/bluetooth/ath3k.c
drivers/char/agp/intel-gtt.c
drivers/char/bfin_jtag_comm.c
drivers/char/tpm/tpm.c
drivers/char/tpm/tpm_tis.c
drivers/clocksource/acpi_pm.c
drivers/clocksource/tcb_clksrc.c
drivers/gpio/langwell_gpio.c
drivers/gpu/drm/Kconfig
drivers/gpu/drm/i915/i915_dma.c
drivers/gpu/drm/i915/i915_drv.c
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/i915_gem.c
drivers/gpu/drm/i915/i915_gem_execbuffer.c
drivers/gpu/drm/i915/i915_gem_gtt.c
drivers/gpu/drm/i915/i915_irq.c
drivers/gpu/drm/i915/i915_reg.h
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_opregion.c
drivers/gpu/drm/i915/intel_ringbuffer.c
drivers/gpu/drm/i915/intel_ringbuffer.h
drivers/gpu/drm/nouveau/nouveau_bios.c
drivers/gpu/drm/nouveau/nouveau_drv.c
drivers/gpu/drm/nouveau/nouveau_drv.h
drivers/gpu/drm/nouveau/nouveau_temp.c
drivers/gpu/drm/nouveau/nv50_graph.c
drivers/gpu/drm/nouveau/nv50_vm.c
drivers/gpu/drm/nouveau/nvc0_graph.c
drivers/gpu/drm/nouveau/nvc0_grctx.c
drivers/gpu/drm/radeon/atombios_crtc.c
drivers/gpu/drm/radeon/atombios_dp.c
drivers/gpu/drm/radeon/evergreen.c
drivers/gpu/drm/radeon/evergreen_blit_kms.c
drivers/gpu/drm/radeon/r100.c
drivers/gpu/drm/radeon/r300.c
drivers/gpu/drm/radeon/r420.c
drivers/gpu/drm/radeon/r520.c
drivers/gpu/drm/radeon/r600.c
drivers/gpu/drm/radeon/r600_reg.h
drivers/gpu/drm/radeon/radeon_atombios.c
drivers/gpu/drm/radeon/radeon_device.c
drivers/gpu/drm/radeon/radeon_drv.c
drivers/gpu/drm/radeon/radeon_encoders.c
drivers/gpu/drm/radeon/radeon_irq_kms.c
drivers/gpu/drm/radeon/radeon_kms.c
drivers/gpu/drm/radeon/radeon_reg.h
drivers/gpu/drm/radeon/rs400.c
drivers/gpu/drm/radeon/rv515.c
drivers/gpu/stub/Kconfig
drivers/gpu/vga/vgaarb.c
drivers/hwmon/applesmc.c
drivers/hwmon/asus_atk0110.c
drivers/hwmon/lis3lv02d.c
drivers/idle/intel_idle.c
drivers/input/keyboard/Kconfig
drivers/input/keyboard/Makefile
drivers/input/keyboard/gpio_keys.c
drivers/input/keyboard/tegra-kbc.c [new file with mode: 0644]
drivers/input/keyboard/tnetv107x-keypad.c
drivers/input/mouse/synaptics.c
drivers/input/serio/ct82c710.c
drivers/input/serio/serport.c
drivers/input/sparse-keymap.c
drivers/input/tablet/wacom_wac.c
drivers/input/touchscreen/bu21013_ts.c
drivers/input/touchscreen/tnetv107x-ts.c
drivers/leds/leds-pwm.c
drivers/media/rc/rc-main.c
drivers/mmc/host/bfin_sdh.c
drivers/mmc/host/jz4740_mmc.c
drivers/mmc/host/mmci.c
drivers/mmc/host/mmci.h
drivers/mmc/host/msm_sdcc.c
drivers/mmc/host/sdhci-s3c.c
drivers/mmc/host/ushc.c
drivers/mtd/ubi/build.c
drivers/net/arm/ks8695net.c
drivers/net/bnx2.c
drivers/net/bnx2.h
drivers/net/bonding/bond_3ad.c
drivers/net/bonding/bond_alb.c
drivers/net/bonding/bond_main.c
drivers/net/can/Kconfig
drivers/net/can/Makefile
drivers/net/can/at91_can.c
drivers/net/can/softing/Kconfig [new file with mode: 0644]
drivers/net/can/softing/Makefile [new file with mode: 0644]
drivers/net/can/softing/softing.h [new file with mode: 0644]
drivers/net/can/softing/softing_cs.c [new file with mode: 0644]
drivers/net/can/softing/softing_fw.c [new file with mode: 0644]
drivers/net/can/softing/softing_main.c [new file with mode: 0644]
drivers/net/can/softing/softing_platform.h [new file with mode: 0644]
drivers/net/cnic.c
drivers/net/cxgb4/cxgb4_main.c
drivers/net/pch_gbe/pch_gbe_main.c
drivers/net/tg3.c
drivers/net/tg3.h
drivers/net/usb/kaweth.c
drivers/net/wireless/ath/ath9k/hw.c
drivers/net/wireless/ath/ath9k/hw.h
drivers/net/wireless/ath/ath9k/main.c
drivers/net/wireless/ath/ath9k/xmit.c
drivers/net/wireless/iwlwifi/iwl-4965.c
drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c
drivers/net/wireless/rt2x00/rt73usb.c
drivers/net/wireless/rtlwifi/pci.c
drivers/parport/share.c
drivers/platform/x86/intel_scu_ipc.c
drivers/platform/x86/intel_scu_ipcutil.c
drivers/pps/clients/pps-ktimer.c
drivers/pps/clients/pps_parport.c
drivers/pps/generators/pps_gen_parport.c
drivers/rapidio/rio-scan.c
drivers/rtc/Kconfig
drivers/rtc/interface.c
drivers/s390/block/dasd_alias.c
drivers/s390/cio/qdio_main.c
drivers/sh/intc/chip.c
drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.c
drivers/staging/brcm80211/sys/wl_mac80211.c
drivers/staging/brcm80211/sys/wlc_mac80211.c
drivers/staging/comedi/drivers/ni_labpc.c
drivers/staging/hv/blkvsc_drv.c
drivers/staging/hv/netvsc.c
drivers/staging/hv/netvsc_drv.c
drivers/staging/iio/adc/ad7476_core.c
drivers/staging/iio/adc/ad7887_core.c
drivers/staging/iio/adc/ad799x_core.c
drivers/staging/iio/dac/ad5446.c
drivers/staging/msm/msm_fb.c
drivers/staging/olpc_dcon/olpc_dcon.c
drivers/staging/rt2860/rt_main_dev.c
drivers/staging/rt2860/usb_main_dev.c
drivers/staging/rtl8712/hal_init.c
drivers/staging/rtl8712/usb_intf.c
drivers/staging/sm7xx/smtcfb.c
drivers/staging/speakup/kobjects.c
drivers/staging/ste_rmi4/synaptics_i2c_rmi4.c
drivers/staging/tidspbridge/core/io_sm.c
drivers/staging/tidspbridge/core/tiomap3430.c
drivers/staging/tidspbridge/include/dspbridge/io_sm.h
drivers/staging/usbip/stub.h
drivers/staging/usbip/stub_dev.c
drivers/staging/usbip/stub_rx.c
drivers/staging/usbip/vhci.h
drivers/staging/usbip/vhci_hcd.c
drivers/staging/usbip/vhci_rx.c
drivers/staging/vme/bridges/Module.symvers [deleted file]
drivers/staging/xgifb/vb_setmode.c
drivers/tty/n_hdlc.c
drivers/tty/serial/8250.c
drivers/tty/serial/Kconfig
drivers/tty/serial/sb1250-duart.c
drivers/tty/sysrq.c
drivers/tty/tty_io.c
drivers/tty/vt/selection.c
drivers/tty/vt/vc_screen.c
drivers/tty/vt/vt.c
drivers/tty/vt/vt_ioctl.c
drivers/usb/class/cdc-wdm.c
drivers/usb/core/endpoint.c
drivers/usb/core/hcd-pci.c
drivers/usb/core/hub.c
drivers/usb/gadget/Kconfig
drivers/usb/gadget/ci13xxx_udc.c
drivers/usb/gadget/ci13xxx_udc.h
drivers/usb/gadget/composite.c
drivers/usb/gadget/pch_udc.c
drivers/usb/gadget/printer.c
drivers/usb/host/ehci-fsl.c
drivers/usb/host/ehci-fsl.h
drivers/usb/host/ehci-hcd.c
drivers/usb/host/ehci-mxc.c
drivers/usb/host/ehci-pci.c
drivers/usb/host/fsl-mph-dr-of.c
drivers/usb/host/xhci-ring.c
drivers/usb/host/xhci.c
drivers/usb/host/xhci.h
drivers/usb/misc/usbled.c
drivers/usb/misc/uss720.c
drivers/usb/otg/nop-usb-xceiv.c
drivers/usb/otg/ulpi.c
drivers/usb/serial/ch341.c
drivers/usb/serial/cp210x.c
drivers/usb/serial/digi_acceleport.c
drivers/usb/serial/ftdi_sio.c
drivers/usb/serial/ftdi_sio_ids.h
drivers/usb/serial/generic.c
drivers/usb/serial/io_tables.h
drivers/usb/serial/iuu_phoenix.c
drivers/usb/serial/keyspan.h
drivers/usb/serial/keyspan_pda.c
drivers/usb/serial/moto_modem.c
drivers/usb/serial/option.c
drivers/usb/serial/oti6858.c
drivers/usb/serial/pl2303.c
drivers/usb/serial/pl2303.h
drivers/usb/serial/qcaux.c
drivers/usb/serial/siemens_mpi.c
drivers/usb/serial/spcp8x5.c
drivers/usb/serial/usb-serial.c
drivers/usb/serial/usb_debug.c
drivers/usb/storage/unusual_cypress.h
drivers/usb/storage/unusual_devs.h
drivers/video/arkfb.c
drivers/video/aty/aty128fb.c
drivers/video/aty/atyfb_base.c
drivers/video/aty/radeon_pm.c
drivers/video/bf537-lq035.c
drivers/video/chipsfb.c
drivers/video/console/fbcon.c
drivers/video/console/vgacon.c
drivers/video/da8xx-fb.c
drivers/video/fbmem.c
drivers/video/fbsysfs.c
drivers/video/geode/gxfb_core.c
drivers/video/geode/lxfb_core.c
drivers/video/i810/i810_main.c
drivers/video/jz4740_fb.c
drivers/video/mx3fb.c
drivers/video/nuc900fb.c
drivers/video/nvidia/nvidia.c
drivers/video/ps3fb.c
drivers/video/pxa168fb.c
drivers/video/pxa3xx-gcu.c
drivers/video/s3fb.c
drivers/video/savage/savagefb_driver.c
drivers/video/sh_mobile_hdmi.c
drivers/video/sh_mobile_lcdcfb.c
drivers/video/sm501fb.c
drivers/video/tmiofb.c
drivers/video/via/viafbdev.c
drivers/video/vt8623fb.c
drivers/video/xen-fbfront.c
fs/ceph/caps.c
fs/ceph/inode.c
fs/ceph/mds_client.c
fs/ceph/super.c
fs/ceph/xattr.c
fs/cifs/Kconfig
fs/cifs/Makefile
fs/cifs/README
fs/cifs/cifs_dfs_ref.c
fs/cifs/cifsencrypt.c
fs/cifs/cifsencrypt.h [deleted file]
fs/cifs/cifsfs.c
fs/cifs/cifsfs.h
fs/cifs/cifsglob.h
fs/cifs/cifsproto.h
fs/cifs/cifssmb.c
fs/cifs/connect.c
fs/cifs/file.c
fs/cifs/link.c
fs/cifs/md4.c [deleted file]
fs/cifs/md5.c [deleted file]
fs/cifs/md5.h [deleted file]
fs/cifs/misc.c
fs/cifs/readdir.c
fs/cifs/smbdes.c
fs/cifs/smbencrypt.c
fs/cifs/transport.c
fs/dcache.c
fs/eventpoll.c
fs/exec.c
fs/fcntl.c
fs/ioctl.c
fs/lockd/host.c
fs/nfs/callback.c
fs/nfs/callback.h
fs/nfs/callback_proc.c
fs/nfs/callback_xdr.c
fs/nfs/client.c
fs/nfs/delegation.c
fs/nfs/direct.c
fs/nfs/inode.c
fs/nfs/internal.h
fs/nfs/nfs3acl.c
fs/nfs/nfs3xdr.c
fs/nfs/nfs4filelayoutdev.c
fs/nfs/nfs4proc.c
fs/nfs/nfs4state.c
fs/nfs/nfs4xdr.c
fs/nfs/pnfs.c
fs/nfs/write.c
fs/nfs_common/nfsacl.c
fs/nilfs2/super.c
fs/ntfs/mft.c
fs/posix_acl.c
fs/proc/consoles.c
fs/squashfs/block.c
fs/squashfs/xz_wrapper.c
fs/squashfs/zlib_wrapper.c
fs/xfs/linux-2.6/xfs_ioctl.c
fs/xfs/quota/xfs_qm.c
fs/xfs/xfs_alloc.h
fs/xfs/xfs_bmap.c
fs/xfs/xfs_buf_item.c
fs/xfs/xfs_extfree_item.c
fs/xfs/xfs_iomap.c
fs/xfs/xfs_log.h
fs/xfs/xfs_log_cil.c
fs/xfs/xfs_trans.c
include/asm-generic/vmlinux.lds.h
include/drm/radeon_drm.h
include/linux/console.h
include/linux/fs.h
include/linux/gfp.h
include/linux/input/bu21013.h
include/linux/kernel.h
include/linux/kmemcheck.h
include/linux/mmc/sh_mmcif.h
include/linux/module.h
include/linux/moduleparam.h
include/linux/nfsacl.h
include/linux/posix_acl.h
include/linux/res_counter.h
include/linux/rtc.h
include/linux/sunrpc/bc_xprt.h
include/linux/sunrpc/svc_xprt.h
include/linux/sysrq.h
include/linux/usb/hcd.h
include/linux/usb/serial.h
include/linux/virtio_config.h
include/net/bluetooth/hci_core.h
include/net/sch_generic.h
kernel/params.c
kernel/perf_event.c
kernel/printk.c
kernel/sched_fair.c
kernel/sys.c
kernel/sysctl.c
kernel/time/tick-sched.c
lib/radix-tree.c
lib/rbtree.c
lib/textsearch.c
mm/Kconfig
mm/huge_memory.c
mm/kmemleak-test.c
mm/kmemleak.c
mm/memcontrol.c
mm/memory-failure.c
mm/migrate.c
mm/mlock.c
mm/page_alloc.c
mm/pgtable-generic.c
mm/vmscan.c
net/bluetooth/hci_conn.c
net/bluetooth/hci_core.c
net/bluetooth/hci_event.c
net/bluetooth/l2cap.c
net/bluetooth/rfcomm/core.c
net/core/dev.c
net/core/ethtool.c
net/core/skbuff.c
net/dcb/dcbnl.c
net/dsa/dsa.c
net/ipv4/arp.c
net/ipv4/inetpeer.c
net/ipv4/tcp_input.c
net/ipv4/tcp_ipv4.c
net/ipv6/addrconf.c
net/ipv6/route.c
net/ipv6/xfrm6_policy.c
net/mac80211/tx.c
net/sched/sch_cbq.c
net/sched/sch_drr.c
net/sched/sch_dsmark.c
net/sched/sch_fifo.c
net/sched/sch_hfsc.c
net/sched/sch_htb.c
net/sched/sch_multiq.c
net/sched/sch_netem.c
net/sched/sch_prio.c
net/sched/sch_red.c
net/sched/sch_sfq.c
net/sched/sch_tbf.c
net/sched/sch_teql.c
net/sunrpc/svcsock.c
security/keys/Makefile
security/keys/encrypted.c [moved from security/keys/encrypted_defined.c with 99% similarity]
security/keys/encrypted.h [moved from security/keys/encrypted_defined.h with 100% similarity]
security/keys/internal.h
security/keys/key.c
security/keys/keyring.c
security/keys/request_key.c
security/keys/trusted.c [moved from security/keys/trusted_defined.c with 99% similarity]
security/keys/trusted.h [moved from security/keys/trusted_defined.h with 100% similarity]
security/selinux/ss/conditional.c
security/selinux/ss/policydb.c
sound/arm/aaci.c
sound/atmel/ac97c.c
sound/pci/azt3328.c
sound/pci/hda/hda_eld.c
sound/pci/hda/patch_realtek.c
sound/pci/oxygen/xonar_cs43xx.c
sound/soc/atmel/snd-soc-afeb9260.c
sound/soc/blackfin/bf5xx-ssm2602.c
sound/soc/codecs/wm8994.c
sound/soc/codecs/wm8995.c
sound/soc/codecs/wm_hubs.c
sound/soc/davinci/davinci-evm.c
sound/soc/pxa/corgi.c
sound/soc/pxa/poodle.c
sound/soc/pxa/spitz.c
sound/soc/samsung/neo1973_gta02_wm8753.c
sound/soc/samsung/neo1973_wm8753.c
sound/soc/samsung/s3c24xx_simtec_hermes.c
sound/soc/samsung/s3c24xx_simtec_tlv320aic23.c
sound/soc/samsung/s3c24xx_uda134x.c
tools/perf/Makefile
tools/perf/builtin-annotate.c
tools/perf/builtin-kmem.c
tools/perf/builtin-lock.c
tools/perf/builtin-record.c
tools/perf/builtin-report.c
tools/perf/builtin-sched.c
tools/perf/builtin-script.c
tools/perf/builtin-stat.c
tools/perf/builtin-test.c
tools/perf/builtin-top.c
tools/perf/util/event.c
tools/perf/util/header.c
tools/perf/util/hist.c
tools/perf/util/include/linux/bitops.h
tools/perf/util/map.c
tools/perf/util/parse-events.c
tools/perf/util/parse-events.h
tools/perf/util/probe-event.c
tools/perf/util/session.c
tools/perf/util/svghelper.c
tools/perf/util/symbol.c
tools/perf/util/types.h
tools/perf/util/ui/browsers/hists.c
tools/perf/util/ui/browsers/map.c
tools/perf/util/values.c

index 581fd39193a26d2932c696d21f0b78c28f4bdc92..1eba28acab64c83c3e6fd1c39cebfbc6ad6d29ac 100644 (file)
--- a/.mailmap
+++ b/.mailmap
@@ -23,6 +23,7 @@ Andy Adamson <andros@citi.umich.edu>
 Arnaud Patard <arnaud.patard@rtp-net.org>
 Arnd Bergmann <arnd@arndb.de>
 Axel Dyks <xl@xlsigned.net>
+Axel Lin <axel.lin@gmail.com>
 Ben Gardner <bgardner@wabtec.com>
 Ben M Cahill <ben.m.cahill@intel.com>
 Björn Steinbrink <B.Steinbrink@gmx.de>
diff --git a/Documentation/ABI/testing/sysfs-platform-at91 b/Documentation/ABI/testing/sysfs-platform-at91
new file mode 100644 (file)
index 0000000..4cc6a86
--- /dev/null
@@ -0,0 +1,25 @@
+What:          /sys/devices/platform/at91_can/net/<iface>/mb0_id
+Date:          January 2011
+KernelVersion: 2.6.38
+Contact:       Marc Kleine-Budde <kernel@pengutronix.de>
+Description:
+               Value representing the can_id of mailbox 0.
+
+               Default: 0x7ff (standard frame)
+
+               Due to a chip bug (errata 50.2.6.3 & 50.3.5.3 in
+               "AT91SAM9263 Preliminary 6249H-ATARM-27-Jul-09") the
+               contents of mailbox 0 may be send under certain
+               conditions (even if disabled or in rx mode).
+
+               The workaround in the errata suggests not to use the
+               mailbox and load it with an unused identifier.
+
+               In order to use an extended can_id add the
+               CAN_EFF_FLAG (0x80000000U) to the can_id. Example:
+
+               - standard id 0x7ff:
+               echo 0x7ff      > /sys/class/net/can0/mb0_id
+
+               - extended id 0x1fffffff:
+               echo 0x9fffffff > /sys/class/net/can0/mb0_id
index 35447e0817367083e2a13d1ec3a1cc389e815d50..36f63d4a0a065368e187822b86a8c4af2feddbe3 100644 (file)
@@ -217,8 +217,8 @@ X!Isound/sound_firmware.c
   <chapter id="uart16x50">
      <title>16x50 UART Driver</title>
 !Iinclude/linux/serial_core.h
-!Edrivers/serial/serial_core.c
-!Edrivers/serial/8250.c
+!Edrivers/tty/serial/serial_core.c
+!Edrivers/tty/serial/8250.c
   </chapter>
 
   <chapter id="fbdev">
index b959659c5df46414413530bd213f1e50aa528ee3..b3f35e5f9c95470c96dce361251c3c2275bc2207 100644 (file)
@@ -603,3 +603,19 @@ Why:       The adm9240, w83792d and w83793 hardware monitoring drivers have
 Who:   Jean Delvare <khali@linux-fr.org>
 
 ----------------------------
+
+What:  noswapaccount kernel command line parameter
+When:  2.6.40
+Why:   The original implementation of memsw feature enabled by
+       CONFIG_CGROUP_MEM_RES_CTLR_SWAP could be disabled by the noswapaccount
+       kernel parameter (introduced in 2.6.29-rc1). Later on, this decision
+       turned out to be not ideal because we cannot have the feature compiled
+       in and disabled by default and let only interested to enable it
+       (e.g. general distribution kernels might need it). Therefore we have
+       added swapaccount[=0|1] parameter (introduced in 2.6.37) which provides
+       the both possibilities. If we remove noswapaccount we will have
+       less command line parameters with the same functionality and we
+       can also cleanup the parameter handling a bit ().
+Who:   Michal Hocko <mhocko@suse.cz>
+
+----------------------------
index 6ef8cf3bc9a33f1083a173143ebcd6fe68947465..933bc66ccff1881470c68f14b350407dae1d1318 100644 (file)
@@ -460,6 +460,8 @@ Note, a technical ChangeLog aimed at kernel hackers is in fs/ntfs/ChangeLog.
 2.1.30:
        - Fix writev() (it kept writing the first segment over and over again
          instead of moving onto subsequent segments).
+       - Fix crash in ntfs_mft_record_alloc() when mapping the new extent mft
+         record failed.
 2.1.29:
        - Fix a deadlock when mounting read-write.
 2.1.28:
index b72e071a3e5bd1ca958c423df347d7b1ab515573..89835a4766a684468695b430ac8e7e7f1b76dabc 100644 (file)
@@ -43,11 +43,11 @@ parameter is applicable:
        AVR32   AVR32 architecture is enabled.
        AX25    Appropriate AX.25 support is enabled.
        BLACKFIN Blackfin architecture is enabled.
+       DRM     Direct Rendering Management support is enabled.
+       DYNAMIC_DEBUG Build in debug messages and enable them at runtime
        EDD     BIOS Enhanced Disk Drive Services (EDD) is enabled
        EFI     EFI Partitioning (GPT) is enabled
        EIDE    EIDE/ATAPI support is enabled.
-       DRM     Direct Rendering Management support is enabled.
-       DYNAMIC_DEBUG Build in debug messages and enable them at runtime
        FB      The frame buffer device is enabled.
        GCOV    GCOV profiling is enabled.
        HW      Appropriate hardware is enabled.
index 5dc638791d975116bf1a1e590fdfc44a6ae5c33c..25d2f4141d27aaa53d297688de68326c85571dcb 100644 (file)
@@ -49,7 +49,8 @@ Table of Contents
 3.3    Configuring Bonding Manually with Ifenslave
 3.3.1          Configuring Multiple Bonds Manually
 3.4    Configuring Bonding Manually via Sysfs
-3.5    Overriding Configuration for Special Cases
+3.5    Configuration with Interfaces Support
+3.6    Overriding Configuration for Special Cases
 
 4. Querying Bonding Configuration
 4.1    Bonding Configuration
@@ -161,8 +162,8 @@ onwards) do not have /usr/include/linux symbolically linked to the
 default kernel source include directory.
 
 SECOND IMPORTANT NOTE:
-       If you plan to configure bonding using sysfs, you do not need
-to use ifenslave.
+       If you plan to configure bonding using sysfs or using the
+/etc/network/interfaces file, you do not need to use ifenslave.
 
 2. Bonding Driver Options
 =========================
@@ -779,22 +780,26 @@ resend_igmp
 
        You can configure bonding using either your distro's network
 initialization scripts, or manually using either ifenslave or the
-sysfs interface.  Distros generally use one of two packages for the
-network initialization scripts: initscripts or sysconfig.  Recent
-versions of these packages have support for bonding, while older
+sysfs interface.  Distros generally use one of three packages for the
+network initialization scripts: initscripts, sysconfig or interfaces.
+Recent versions of these packages have support for bonding, while older
 versions do not.
 
        We will first describe the options for configuring bonding for
-distros using versions of initscripts and sysconfig with full or
-partial support for bonding, then provide information on enabling
+distros using versions of initscripts, sysconfig and interfaces with full
+or partial support for bonding, then provide information on enabling
 bonding without support from the network initialization scripts (i.e.,
 older versions of initscripts or sysconfig).
 
-       If you're unsure whether your distro uses sysconfig or
-initscripts, or don't know if it's new enough, have no fear.
+       If you're unsure whether your distro uses sysconfig,
+initscripts or interfaces, or don't know if it's new enough, have no fear.
 Determining this is fairly straightforward.
 
-       First, issue the command:
+       First, look for a file called interfaces in /etc/network directory.
+If this file is present in your system, then your system use interfaces. See
+Configuration with Interfaces Support.
+
+       Else, issue the command:
 
 $ rpm -qf /sbin/ifup
 
@@ -1327,8 +1332,62 @@ echo 2000 > /sys/class/net/bond1/bonding/arp_interval
 echo +eth2 > /sys/class/net/bond1/bonding/slaves
 echo +eth3 > /sys/class/net/bond1/bonding/slaves
 
-3.5 Overriding Configuration for Special Cases
+3.5 Configuration with Interfaces Support
+-----------------------------------------
+
+        This section applies to distros which use /etc/network/interfaces file
+to describe network interface configuration, most notably Debian and it's
+derivatives.
+
+       The ifup and ifdown commands on Debian don't support bonding out of
+the box. The ifenslave-2.6 package should be installed to provide bonding
+support.  Once installed, this package will provide bond-* options to be used
+into /etc/network/interfaces.
+
+       Note that ifenslave-2.6 package will load the bonding module and use
+the ifenslave command when appropriate.
+
+Example Configurations
+----------------------
+
+In /etc/network/interfaces, the following stanza will configure bond0, in
+active-backup mode, with eth0 and eth1 as slaves.
+
+auto bond0
+iface bond0 inet dhcp
+       bond-slaves eth0 eth1
+       bond-mode active-backup
+       bond-miimon 100
+       bond-primary eth0 eth1
+
+If the above configuration doesn't work, you might have a system using
+upstart for system startup. This is most notably true for recent
+Ubuntu versions. The following stanza in /etc/network/interfaces will
+produce the same result on those systems.
+
+auto bond0
+iface bond0 inet dhcp
+       bond-slaves none
+       bond-mode active-backup
+       bond-miimon 100
+
+auto eth0
+iface eth0 inet manual
+       bond-master bond0
+       bond-primary eth0 eth1
+
+auto eth1
+iface eth1 inet manual
+       bond-master bond0
+       bond-primary eth0 eth1
+
+For a full list of bond-* supported options in /etc/network/interfaces and some
+more advanced examples tailored to you particular distros, see the files in
+/usr/share/doc/ifenslave-2.6.
+
+3.6 Overriding Configuration for Special Cases
 ----------------------------------------------
+
 When using the bonding driver, the physical port which transmits a frame is
 typically selected by the bonding driver, and is not relevant to the user or
 system administrator.  The output port is simply selected using the policies of
index 55592f8b672cafa19b9564c51a54d48d00ec68d4..9511bff301c9d3fed53292987147e6b4924fd478 100644 (file)
@@ -978,6 +978,8 @@ S:  Maintained
 F:     arch/arm/plat-samsung/
 F:     arch/arm/plat-s3c24xx/
 F:     arch/arm/plat-s5p/
+F:     drivers/*/*s3c2410*
+F:     drivers/*/*/*s3c2410*
 
 ARM/S3C2410 ARM ARCHITECTURE
 M:     Ben Dooks <ben-linux@fluff.org>
@@ -3139,6 +3141,12 @@ S:       Maintained
 F:     net/ieee802154/
 F:     drivers/ieee802154/
 
+IKANOS/ADI EAGLE ADSL USB DRIVER
+M:     Matthieu Castet <castet.matthieu@free.fr>
+M:     Stanislaw Gruszka <stf_xl@wp.pl>
+S:     Maintained
+F:     drivers/usb/atm/ueagle-atm.c
+
 INTEGRITY MEASUREMENT ARCHITECTURE (IMA)
 M:     Mimi Zohar <zohar@us.ibm.com>
 S:     Supported
@@ -3327,7 +3335,6 @@ F:        drivers/net/wimax/i2400m/
 F:     include/linux/wimax/i2400m.h
 
 INTEL WIRELESS WIFI LINK (iwlwifi)
-M:     Reinette Chatre <reinette.chatre@intel.com>
 M:     Wey-Yi Guy <wey-yi.w.guy@intel.com>
 M:     Intel Linux Wireless <ilw@linux.intel.com>
 L:     linux-wireless@vger.kernel.org
@@ -3674,6 +3681,28 @@ F:       include/linux/key-type.h
 F:     include/keys/
 F:     security/keys/
 
+KEYS-TRUSTED
+M:     David Safford <safford@watson.ibm.com>
+M:     Mimi Zohar <zohar@us.ibm.com>
+L:     linux-security-module@vger.kernel.org
+L:     keyrings@linux-nfs.org
+S:     Supported
+F:     Documentation/keys-trusted-encrypted.txt
+F:     include/keys/trusted-type.h
+F:     security/keys/trusted.c
+F:     security/keys/trusted.h
+
+KEYS-ENCRYPTED
+M:     Mimi Zohar <zohar@us.ibm.com>
+M:     David Safford <safford@watson.ibm.com>
+L:     linux-security-module@vger.kernel.org
+L:     keyrings@linux-nfs.org
+S:     Supported
+F:     Documentation/keys-trusted-encrypted.txt
+F:     include/keys/encrypted-type.h
+F:     security/keys/encrypted.c
+F:     security/keys/encrypted.h
+
 KGDB / KDB /debug_core
 M:     Jason Wessel <jason.wessel@windriver.com>
 W:     http://kgdb.wiki.kernel.org/
@@ -5587,18 +5616,20 @@ F:      include/linux/sfi*.h
 
 SIMTEC EB110ATX (Chalice CATS)
 P:     Ben Dooks
-M:     Vincent Sanders <support@simtec.co.uk>
+P:     Vincent Sanders <vince@simtec.co.uk>
+M:     Simtec Linux Team <linux@simtec.co.uk>
 W:     http://www.simtec.co.uk/products/EB110ATX/
 S:     Supported
 
 SIMTEC EB2410ITX (BAST)
 P:     Ben Dooks
-M:     Vincent Sanders <support@simtec.co.uk>
+P:     Vincent Sanders <vince@simtec.co.uk>
+M:     Simtec Linux Team <linux@simtec.co.uk>
 W:     http://www.simtec.co.uk/products/EB2410ITX/
 S:     Supported
-F:     arch/arm/mach-s3c2410/
-F:     drivers/*/*s3c2410*
-F:     drivers/*/*/*s3c2410*
+F:     arch/arm/mach-s3c2410/mach-bast.c
+F:     arch/arm/mach-s3c2410/bast-ide.c
+F:     arch/arm/mach-s3c2410/bast-irq.c
 
 TI DAVINCI MACHINE SUPPORT
 M:     Kevin Hilman <khilman@deeprootsystems.com>
@@ -6573,6 +6604,16 @@ S:       Maintained
 F:     drivers/char/virtio_console.c
 F:     include/linux/virtio_console.h
 
+VIRTIO CORE, NET AND BLOCK DRIVERS
+M:     Rusty Russell <rusty@rustcorp.com.au>
+M:     "Michael S. Tsirkin" <mst@redhat.com>
+L:     virtualization@lists.linux-foundation.org
+S:     Maintained
+F:     drivers/virtio/
+F:     drivers/net/virtio_net.c
+F:     drivers/block/virtio_blk.c
+F:     include/linux/virtio_*.h
+
 VIRTIO HOST (VHOST)
 M:     "Michael S. Tsirkin" <mst@redhat.com>
 L:     kvm@vger.kernel.org
index 1f474953427fdabd12561feeafcd42ae41f16f86..66e7e977ddc00f486fabde85faac0d0cafcef169 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 6
 SUBLEVEL = 38
-EXTRAVERSION = -rc2
+EXTRAVERSION = -rc3
 NAME = Flesh-Eating Bats with Fangs
 
 # *DOCUMENTATION*
index a101f10bb5b11be8cf75a8b89c647ca70ec65871..721847dc68abd0ea3d5590af9e9fe09d48277363 100644 (file)
 #define SCPCELLID2             0xFF8
 #define SCPCELLID3             0xFFC
 
+#define SCCTRL_TIMEREN0SEL_REFCLK      (0 << 15)
+#define SCCTRL_TIMEREN0SEL_TIMCLK      (1 << 15)
+
+#define SCCTRL_TIMEREN1SEL_REFCLK      (0 << 17)
+#define SCCTRL_TIMEREN1SEL_TIMCLK      (1 << 17)
+
 static inline void sysctl_soft_reset(void __iomem *base)
 {
        /* writing any value to SCSYSSTAT reg will reset system */
index 20e0f7c9e03ed91678324170d8039ceadeea37a3..d66605dea55a217fc10df9fda8a94f3e5b1eb9ea 100644 (file)
@@ -95,6 +95,15 @@ static inline void __iomem *__typesafe_io(unsigned long addr)
        return (void __iomem *)addr;
 }
 
+/* IO barriers */
+#ifdef CONFIG_ARM_DMA_MEM_BUFFERABLE
+#define __iormb()              rmb()
+#define __iowmb()              wmb()
+#else
+#define __iormb()              do { } while (0)
+#define __iowmb()              do { } while (0)
+#endif
+
 /*
  * Now, pick up the machine-defined IO definitions
  */
@@ -125,17 +134,17 @@ static inline void __iomem *__typesafe_io(unsigned long addr)
  * The {in,out}[bwl] macros are for emulating x86-style PCI/ISA IO space.
  */
 #ifdef __io
-#define outb(v,p)              __raw_writeb(v,__io(p))
-#define outw(v,p)              __raw_writew((__force __u16) \
-                                       cpu_to_le16(v),__io(p))
-#define outl(v,p)              __raw_writel((__force __u32) \
-                                       cpu_to_le32(v),__io(p))
+#define outb(v,p)      ({ __iowmb(); __raw_writeb(v,__io(p)); })
+#define outw(v,p)      ({ __iowmb(); __raw_writew((__force __u16) \
+                                       cpu_to_le16(v),__io(p)); })
+#define outl(v,p)      ({ __iowmb(); __raw_writel((__force __u32) \
+                                       cpu_to_le32(v),__io(p)); })
 
-#define inb(p) ({ __u8 __v = __raw_readb(__io(p)); __v; })
+#define inb(p) ({ __u8 __v = __raw_readb(__io(p)); __iormb(); __v; })
 #define inw(p) ({ __u16 __v = le16_to_cpu((__force __le16) \
-                       __raw_readw(__io(p))); __v; })
+                       __raw_readw(__io(p))); __iormb(); __v; })
 #define inl(p) ({ __u32 __v = le32_to_cpu((__force __le32) \
-                       __raw_readl(__io(p))); __v; })
+                       __raw_readl(__io(p))); __iormb(); __v; })
 
 #define outsb(p,d,l)           __raw_writesb(__io(p),d,l)
 #define outsw(p,d,l)           __raw_writesw(__io(p),d,l)
@@ -192,14 +201,6 @@ extern void _memset_io(volatile void __iomem *, int, size_t);
 #define writel_relaxed(v,c)    ((void)__raw_writel((__force u32) \
                                        cpu_to_le32(v),__mem_pci(c)))
 
-#ifdef CONFIG_ARM_DMA_MEM_BUFFERABLE
-#define __iormb()              rmb()
-#define __iowmb()              wmb()
-#else
-#define __iormb()              do { } while (0)
-#define __iowmb()              do { } while (0)
-#endif
-
 #define readb(c)               ({ u8  __v = readb_relaxed(c); __iormb(); __v; })
 #define readw(c)               ({ u16 __v = readw_relaxed(c); __iormb(); __v; })
 #define readl(c)               ({ u32 __v = readl_relaxed(c); __iormb(); __v; })
index 23c2e8e5c0faaa09d81910456d4de63a96a513da..d0ee74b7cf86bc2627cc9e7ebf3bdbd7c63400cb 100644 (file)
  * translation for translating DMA addresses.  Use the driver
  * DMA support - see dma-mapping.h.
  */
-static inline unsigned long virt_to_phys(void *x)
+static inline unsigned long virt_to_phys(const volatile void *x)
 {
        return __virt_to_phys((unsigned long)(x));
 }
index f17d9a09e8fbf115c26a1f169553d2f6034c4d45..c0225da3fb21d6cfa5c762650ec095f90936c1da 100644 (file)
@@ -392,24 +392,22 @@ ENDPROC(__turn_mmu_on)
 
 #ifdef CONFIG_SMP_ON_UP
 __fixup_smp:
-       mov     r4, #0x00070000
-       orr     r3, r4, #0xff000000     @ mask 0xff070000
-       orr     r4, r4, #0x41000000     @ val 0x41070000
-       and     r0, r9, r3
-       teq     r0, r4                  @ ARM CPU and ARMv6/v7?
+       and     r3, r9, #0x000f0000     @ architecture version
+       teq     r3, #0x000f0000         @ CPU ID supported?
        bne     __fixup_smp_on_up       @ no, assume UP
 
-       orr     r3, r3, #0x0000ff00
-       orr     r3, r3, #0x000000f0     @ mask 0xff07fff0
+       bic     r3, r9, #0x00ff0000
+       bic     r3, r3, #0x0000000f     @ mask 0xff00fff0
+       mov     r4, #0x41000000
        orr     r4, r4, #0x0000b000
-       orr     r4, r4, #0x00000020     @ val 0x4107b020
-       and     r0, r9, r3
-       teq     r0, r4                  @ ARM 11MPCore?
+       orr     r4, r4, #0x00000020     @ val 0x4100b020
+       teq     r3, r4                  @ ARM 11MPCore?
        moveq   pc, lr                  @ yes, assume SMP
 
        mrc     p15, 0, r0, c0, c0, 5   @ read MPIDR
-       tst     r0, #1 << 31
-       movne   pc, lr                  @ bit 31 => SMP
+       and     r0, r0, #0xc0000000     @ multiprocessing extensions and
+       teq     r0, #0x80000000         @ not part of a uniprocessor system?
+       moveq   pc, lr                  @ yes, assume SMP
 
 __fixup_smp_on_up:
        adr     r0, 1f
index fd9156698ab93798244f4560f9a4983e69d12e94..60636f499cb3eafd5318413dd4c83a97949abe91 100644 (file)
@@ -36,6 +36,7 @@ static void twd_set_mode(enum clock_event_mode mode,
                /* timer load already set up */
                ctrl = TWD_TIMER_CONTROL_ENABLE | TWD_TIMER_CONTROL_IT_ENABLE
                        | TWD_TIMER_CONTROL_PERIODIC;
+               __raw_writel(twd_timer_rate / HZ, twd_base + TWD_TIMER_LOAD);
                break;
        case CLOCK_EVT_MODE_ONESHOT:
                /* period set, and timer enabled in 'next_event' hook */
@@ -81,7 +82,7 @@ int twd_timer_ack(void)
 
 static void __cpuinit twd_calibrate_rate(void)
 {
-       unsigned long load, count;
+       unsigned long count;
        u64 waitjiffies;
 
        /*
@@ -116,10 +117,6 @@ static void __cpuinit twd_calibrate_rate(void)
                printk("%lu.%02luMHz.\n", twd_timer_rate / 1000000,
                        (twd_timer_rate / 1000000) % 100);
        }
-
-       load = twd_timer_rate / HZ;
-
-       __raw_writel(load, twd_base + TWD_TIMER_LOAD);
 }
 
 /*
index f3dc76fdcea8591a8855782132376aba3262442a..bec34b83495870057d686573df9bbfd69865be76 100644 (file)
@@ -427,6 +427,13 @@ void __init ep93xx_gpio_init(void)
 {
        int i;
 
+       /* Set Ports C, D, E, G, and H for GPIO use */
+       ep93xx_devcfg_set_bits(EP93XX_SYSCON_DEVCFG_KEYS |
+                                EP93XX_SYSCON_DEVCFG_GONK |
+                                EP93XX_SYSCON_DEVCFG_EONIDE |
+                                EP93XX_SYSCON_DEVCFG_GONIDE |
+                                EP93XX_SYSCON_DEVCFG_HONIDE);
+
        for (i = 0; i < ARRAY_SIZE(ep93xx_gpio_banks); i++)
                gpiochip_add(&ep93xx_gpio_banks[i].chip);
 }
index 3c9e0c40c679196ba02766ad7949ae1d504c1bf7..30b971d65815f342069719afca2052769ac99ba9 100644 (file)
@@ -17,8 +17,8 @@
        /* For NetWinder debugging */
                .macro  addruart, rp, rv
                mov     \rp, #0x000003f8
-               orr     \rv, \rp, #0x7c000000   @ physical
-               orr     \rp, \rp, #0xff000000   @ virtual
+               orr     \rv, \rp, #0xff000000   @ virtual
+               orr     \rp, \rp, #0x7c000000   @ physical
                .endm
 
 #define UART_SHIFT     0
index 8d2f2daba0c001f2cfdffa637cc0478d9f1c563b..e0a028161ddee89a4119014ed83420bd0a21ad4e 100644 (file)
@@ -9,6 +9,7 @@ config ARCH_OMAP730
        depends on ARCH_OMAP1
        bool "OMAP730 Based System"
        select CPU_ARM926T
+       select OMAP_MPU_TIMER
        select ARCH_OMAP_OTG
 
 config ARCH_OMAP850
@@ -22,6 +23,7 @@ config ARCH_OMAP15XX
        default y
        bool "OMAP15xx Based System"
        select CPU_ARM925T
+       select OMAP_MPU_TIMER
 
 config ARCH_OMAP16XX
        depends on ARCH_OMAP1
index 6ee19504845f3b476980e9e79307fc3735331d03..ba6009f2767789040664995803d6f691cad2574a 100644 (file)
@@ -3,12 +3,11 @@
 #
 
 # Common support
-obj-y := io.o id.o sram.o irq.o mux.o flash.o serial.o devices.o dma.o
+obj-y := io.o id.o sram.o time.o irq.o mux.o flash.o serial.o devices.o dma.o
 obj-y += clock.o clock_data.o opp_data.o
 
 obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o
 
-obj-$(CONFIG_OMAP_MPU_TIMER)   += time.o
 obj-$(CONFIG_OMAP_32K_TIMER)   += timer32k.o
 
 # Power Management
index c9be6d4d83e27cfd034cd8ea8df34948d3364a8c..bfb4fb1d7382018e24b4dfb561bbf7cb6d92967d 100644 (file)
 #include <mach/irqs.h>
 #include <asm/hardware/gic.h>
 
-/*
- * We use __glue to avoid errors with multiple definitions of
- * .globl omap_irq_flags as it's included from entry-armv.S but not
- * from entry-common.S.
- */
-#ifdef __glue
-               .pushsection .data
-               .globl  omap_irq_flags
-omap_irq_flags:
-               .word   0
-               .popsection
-#endif
-
                .macro  disable_fiq
                .endm
 
index 47701584df35c34966511b12e1c659294c49f685..731dd33bff511ad412e5e314bc6be36771d2eded 100644 (file)
@@ -57,6 +57,7 @@ struct omap_irq_bank {
        unsigned long wake_enable;
 };
 
+u32 omap_irq_flags;
 static unsigned int irq_bank_count;
 static struct omap_irq_bank *irq_banks;
 
@@ -176,7 +177,6 @@ static struct irq_chip omap_irq_chip = {
 
 void __init omap_init_irq(void)
 {
-       extern unsigned int omap_irq_flags;
        int i, j;
 
 #if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
index ed7a61ff916a1e57f392dbedc21ff0c12101aa7b..f83fc335c613db6e3ac14e7fcf2cf15cd6af5a45 100644 (file)
 #include <linux/clocksource.h>
 #include <linux/clockchips.h>
 #include <linux/io.h>
+#include <linux/sched.h>
 
 #include <asm/system.h>
 #include <mach/hardware.h>
 #include <asm/leds.h>
 #include <asm/irq.h>
+#include <asm/sched_clock.h>
+
 #include <asm/mach/irq.h>
 #include <asm/mach/time.h>
 
 #include <plat/common.h>
 
+#ifdef CONFIG_OMAP_MPU_TIMER
+
 #define OMAP_MPU_TIMER_BASE            OMAP_MPU_TIMER1_BASE
 #define OMAP_MPU_TIMER_OFFSET          0x100
 
@@ -67,7 +72,7 @@ typedef struct {
 ((volatile omap_mpu_timer_regs_t*)OMAP1_IO_ADDRESS(OMAP_MPU_TIMER_BASE +       \
                                 (n)*OMAP_MPU_TIMER_OFFSET))
 
-static inline unsigned long omap_mpu_timer_read(int nr)
+static inline unsigned long notrace omap_mpu_timer_read(int nr)
 {
        volatile omap_mpu_timer_regs_t* timer = omap_mpu_timer_base(nr);
        return timer->read_tim;
@@ -212,6 +217,32 @@ static struct clocksource clocksource_mpu = {
        .flags          = CLOCK_SOURCE_IS_CONTINUOUS,
 };
 
+static DEFINE_CLOCK_DATA(cd);
+
+static inline unsigned long long notrace _omap_mpu_sched_clock(void)
+{
+       u32 cyc = mpu_read(&clocksource_mpu);
+       return cyc_to_sched_clock(&cd, cyc, (u32)~0);
+}
+
+#ifndef CONFIG_OMAP_32K_TIMER
+unsigned long long notrace sched_clock(void)
+{
+       return _omap_mpu_sched_clock();
+}
+#else
+static unsigned long long notrace omap_mpu_sched_clock(void)
+{
+       return _omap_mpu_sched_clock();
+}
+#endif
+
+static void notrace mpu_update_sched_clock(void)
+{
+       u32 cyc = mpu_read(&clocksource_mpu);
+       update_sched_clock(&cd, cyc, (u32)~0);
+}
+
 static void __init omap_init_clocksource(unsigned long rate)
 {
        static char err[] __initdata = KERN_ERR
@@ -219,17 +250,13 @@ static void __init omap_init_clocksource(unsigned long rate)
 
        setup_irq(INT_TIMER2, &omap_mpu_timer2_irq);
        omap_mpu_timer_start(1, ~0, 1);
+       init_sched_clock(&cd, mpu_update_sched_clock, 32, rate);
 
        if (clocksource_register_hz(&clocksource_mpu, rate))
                printk(err, clocksource_mpu.name);
 }
 
-/*
- * ---------------------------------------------------------------------------
- * Timer initialization
- * ---------------------------------------------------------------------------
- */
-static void __init omap_timer_init(void)
+static void __init omap_mpu_timer_init(void)
 {
        struct clk      *ck_ref = clk_get(NULL, "ck_ref");
        unsigned long   rate;
@@ -246,6 +273,66 @@ static void __init omap_timer_init(void)
        omap_init_clocksource(rate);
 }
 
+#else
+static inline void omap_mpu_timer_init(void)
+{
+       pr_err("Bogus timer, should not happen\n");
+}
+#endif /* CONFIG_OMAP_MPU_TIMER */
+
+#if defined(CONFIG_OMAP_MPU_TIMER) && defined(CONFIG_OMAP_32K_TIMER)
+static unsigned long long (*preferred_sched_clock)(void);
+
+unsigned long long notrace sched_clock(void)
+{
+       if (!preferred_sched_clock)
+               return 0;
+
+       return preferred_sched_clock();
+}
+
+static inline void preferred_sched_clock_init(bool use_32k_sched_clock)
+{
+       if (use_32k_sched_clock)
+               preferred_sched_clock = omap_32k_sched_clock;
+       else
+               preferred_sched_clock = omap_mpu_sched_clock;
+}
+#else
+static inline void preferred_sched_clock_init(bool use_32k_sched_clcok)
+{
+}
+#endif
+
+static inline int omap_32k_timer_usable(void)
+{
+       int res = false;
+
+       if (cpu_is_omap730() || cpu_is_omap15xx())
+               return res;
+
+#ifdef CONFIG_OMAP_32K_TIMER
+       res = omap_32k_timer_init();
+#endif
+
+       return res;
+}
+
+/*
+ * ---------------------------------------------------------------------------
+ * Timer initialization
+ * ---------------------------------------------------------------------------
+ */
+static void __init omap_timer_init(void)
+{
+       if (omap_32k_timer_usable()) {
+               preferred_sched_clock_init(1);
+       } else {
+               omap_mpu_timer_init();
+               preferred_sched_clock_init(0);
+       }
+}
+
 struct sys_timer omap_timer = {
        .init           = omap_timer_init,
 };
index 20cfbcc6c60ca08eb1c38f465adf09436a67dd81..13d7b8f145bd3979f5ffeb08cf1e28652a512fce 100644 (file)
 #include <asm/irq.h>
 #include <asm/mach/irq.h>
 #include <asm/mach/time.h>
+#include <plat/common.h>
 #include <plat/dmtimer.h>
 
-struct sys_timer omap_timer;
-
 /*
  * ---------------------------------------------------------------------------
  * 32KHz OS timer
@@ -181,14 +180,14 @@ static __init void omap_init_32k_timer(void)
  * Timer initialization
  * ---------------------------------------------------------------------------
  */
-static void __init omap_timer_init(void)
+bool __init omap_32k_timer_init(void)
 {
+       omap_init_clocksource_32k();
+
 #ifdef CONFIG_OMAP_DM_TIMER
        omap_dm_timer_init();
 #endif
        omap_init_32k_timer();
-}
 
-struct sys_timer omap_timer = {
-       .init           = omap_timer_init,
-};
+       return true;
+}
index 5b0c77732dfc4435303b32b22b9fd5a24a541f17..8f9a64d650ee7896f70983ad0b9f72f717cf23ab 100644 (file)
@@ -124,8 +124,9 @@ static inline void cm_t3517_init_hecc(void) {}
 #if defined(CONFIG_RTC_DRV_V3020) || defined(CONFIG_RTC_DRV_V3020_MODULE)
 #define RTC_IO_GPIO            (153)
 #define RTC_WR_GPIO            (154)
-#define RTC_RD_GPIO            (160)
+#define RTC_RD_GPIO            (53)
 #define RTC_CS_GPIO            (163)
+#define RTC_CS_EN_GPIO         (160)
 
 struct v3020_platform_data cm_t3517_v3020_pdata = {
        .use_gpio       = 1,
@@ -145,6 +146,16 @@ static struct platform_device cm_t3517_rtc_device = {
 
 static void __init cm_t3517_init_rtc(void)
 {
+       int err;
+
+       err = gpio_request(RTC_CS_EN_GPIO, "rtc cs en");
+       if (err) {
+               pr_err("CM-T3517: rtc cs en gpio request failed: %d\n", err);
+               return;
+       }
+
+       gpio_direction_output(RTC_CS_EN_GPIO, 1);
+
        platform_device_register(&cm_t3517_rtc_device);
 }
 #else
@@ -214,12 +225,12 @@ static struct mtd_partition cm_t3517_nand_partitions[] = {
        },
        {
                .name           = "linux",
-               .offset         = MTDPART_OFS_APPEND,   /* Offset = 0x280000 */
+               .offset         = MTDPART_OFS_APPEND,   /* Offset = 0x2A0000 */
                .size           = 32 * NAND_BLOCK_SIZE,
        },
        {
                .name           = "rootfs",
-               .offset         = MTDPART_OFS_APPEND,   /* Offset = 0x680000 */
+               .offset         = MTDPART_OFS_APPEND,   /* Offset = 0x6A0000 */
                .size           = MTDPART_SIZ_FULL,
        },
 };
@@ -256,11 +267,19 @@ static void __init cm_t3517_init_irq(void)
 static struct omap_board_mux board_mux[] __initdata = {
        /* GPIO186 - Green LED */
        OMAP3_MUX(SYS_CLKOUT2, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT),
-       /* RTC GPIOs: IO, WR#, RD#, CS# */
+
+       /* RTC GPIOs: */
+       /* IO - GPIO153 */
        OMAP3_MUX(MCBSP4_DR, OMAP_MUX_MODE4 | OMAP_PIN_INPUT),
+       /* WR# - GPIO154 */
        OMAP3_MUX(MCBSP4_DX, OMAP_MUX_MODE4 | OMAP_PIN_INPUT),
-       OMAP3_MUX(MCBSP_CLKS, OMAP_MUX_MODE4 | OMAP_PIN_INPUT),
+       /* RD# - GPIO53 */
+       OMAP3_MUX(GPMC_NCS2, OMAP_MUX_MODE4 | OMAP_PIN_INPUT),
+       /* CS# - GPIO163 */
        OMAP3_MUX(UART3_CTS_RCTX, OMAP_MUX_MODE4 | OMAP_PIN_INPUT),
+       /* CS EN - GPIO160 */
+       OMAP3_MUX(MCBSP_CLKS, OMAP_MUX_MODE4 | OMAP_PIN_INPUT),
+
        /* HSUSB1 RESET */
        OMAP3_MUX(UART2_TX, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT),
        /* HSUSB2 RESET */
index 00bb1fc5e0175fb433dcb564ffce78ce46f2e0ff..e906e05bb41bdaded0ce50978bb9b7996a44ca1a 100644 (file)
@@ -275,8 +275,7 @@ static struct twl4030_gpio_platform_data devkit8000_gpio_data = {
        .irq_base       = TWL4030_GPIO_IRQ_BASE,
        .irq_end        = TWL4030_GPIO_IRQ_END,
        .use_leds       = true,
-       .pullups        = BIT(1),
-       .pulldowns      = BIT(2) | BIT(6) | BIT(7) | BIT(8) | BIT(13)
+       .pulldowns      = BIT(1) | BIT(2) | BIT(6) | BIT(8) | BIT(13)
                                | BIT(15) | BIT(16) | BIT(17),
        .setup          = devkit8000_twl_gpio_setup,
 };
index e8cb32fd7f135519610c2bb35c869f921832b62a..de9ec8ddd2ae21673964c8c3cf6224c180ae3c78 100644 (file)
@@ -34,7 +34,6 @@
 #include "cm2_44xx.h"
 #include "cm-regbits-44xx.h"
 #include "prm44xx.h"
-#include "prm44xx.h"
 #include "prm-regbits-44xx.h"
 #include "control.h"
 #include "scrm44xx.h"
index e20b98636ab444b1d6e21b4e00ab9ab5eb980a67..58e42f76603f5638675077b36c329e30a9475212 100644 (file)
@@ -423,6 +423,12 @@ int clkdm_add_wkdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)
 {
        struct clkdm_dep *cd;
 
+       if (!cpu_is_omap24xx() && !cpu_is_omap34xx()) {
+               pr_err("clockdomain: %s/%s: %s: not yet implemented\n",
+                      clkdm1->name, clkdm2->name, __func__);
+               return -EINVAL;
+       }
+
        if (!clkdm1 || !clkdm2)
                return -EINVAL;
 
@@ -458,6 +464,12 @@ int clkdm_del_wkdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)
 {
        struct clkdm_dep *cd;
 
+       if (!cpu_is_omap24xx() && !cpu_is_omap34xx()) {
+               pr_err("clockdomain: %s/%s: %s: not yet implemented\n",
+                      clkdm1->name, clkdm2->name, __func__);
+               return -EINVAL;
+       }
+
        if (!clkdm1 || !clkdm2)
                return -EINVAL;
 
@@ -500,6 +512,12 @@ int clkdm_read_wkdep(struct clockdomain *clkdm1, struct clockdomain *clkdm2)
        if (!clkdm1 || !clkdm2)
                return -EINVAL;
 
+       if (!cpu_is_omap24xx() && !cpu_is_omap34xx()) {
+               pr_err("clockdomain: %s/%s: %s: not yet implemented\n",
+                      clkdm1->name, clkdm2->name, __func__);
+               return -EINVAL;
+       }
+
        cd = _clkdm_deps_lookup(clkdm2, clkdm1->wkdep_srcs);
        if (IS_ERR(cd)) {
                pr_debug("clockdomain: hardware cannot set/clear wake up of "
@@ -527,6 +545,12 @@ int clkdm_clear_all_wkdeps(struct clockdomain *clkdm)
        struct clkdm_dep *cd;
        u32 mask = 0;
 
+       if (!cpu_is_omap24xx() && !cpu_is_omap34xx()) {
+               pr_err("clockdomain: %s: %s: not yet implemented\n",
+                      clkdm->name, __func__);
+               return -EINVAL;
+       }
+
        if (!clkdm)
                return -EINVAL;
 
@@ -830,8 +854,7 @@ void omap2_clkdm_allow_idle(struct clockdomain *clkdm)
         * dependency code and data for OMAP4.
         */
        if (cpu_is_omap44xx()) {
-               WARN_ONCE(1, "clockdomain: OMAP4 wakeup/sleep dependency "
-                         "support is not yet implemented\n");
+               pr_err("clockdomain: %s: OMAP4 wakeup/sleep dependency support: not yet implemented\n", clkdm->name);
        } else {
                if (atomic_read(&clkdm->usecount) > 0)
                        _clkdm_add_autodeps(clkdm);
@@ -872,8 +895,7 @@ void omap2_clkdm_deny_idle(struct clockdomain *clkdm)
         * dependency code and data for OMAP4.
         */
        if (cpu_is_omap44xx()) {
-               WARN_ONCE(1, "clockdomain: OMAP4 wakeup/sleep dependency "
-                         "support is not yet implemented\n");
+               pr_err("clockdomain: %s: OMAP4 wakeup/sleep dependency support: not yet implemented\n", clkdm->name);
        } else {
                if (atomic_read(&clkdm->usecount) > 0)
                        _clkdm_del_autodeps(clkdm);
index 51920fc7fc5256b54e7c655ef7a491961db72913..10622c914abcbf338675316fc600928bd8251c50 100644 (file)
@@ -30,8 +30,6 @@
 #include "cm1_44xx.h"
 #include "cm2_44xx.h"
 
-#include "cm1_44xx.h"
-#include "cm2_44xx.h"
 #include "cm-regbits-44xx.h"
 #include "prm44xx.h"
 #include "prcm44xx.h"
index d2f15f5cfd36d1b5cbb7f227e5669c1241cdde7c..34922b2d2e3fac135de325cb39af662ab1c7296e 100644 (file)
@@ -264,7 +264,7 @@ static int __init omap2_system_dma_init_dev(struct omap_hwmod *oh, void *unused)
        if (IS_ERR(od)) {
                pr_err("%s: Cant build omap_device for %s:%s.\n",
                        __func__, name, oh->name);
-               return IS_ERR(od);
+               return PTR_ERR(od);
        }
 
        mem = platform_get_resource(&od->pdev, IORESOURCE_MEM, 0);
index befa321c4c1399b42084067ff601ec14703d937f..81985a665cb3ee420357bb53ea19b7268e9ab3ca 100644 (file)
  */
 
 #ifdef MULTI_OMAP2
-
-/*
- * We use __glue to avoid errors with multiple definitions of
- * .globl omap_irq_base as it's included from entry-armv.S but not
- * from entry-common.S.
- */
-#ifdef __glue
-               .pushsection .data
-               .globl  omap_irq_base
-omap_irq_base:
-               .word   0
-               .popsection
-#endif
-
                /*
                 * Configure the interrupt base on the first interrupt.
                 * See also omap_irq_base_init for setting omap_irq_base.
index e66687b0b9de02450a952ed78c7bedaa086c755c..c2032041d26fb5276cdeef1ae302ff39115ecff5 100644 (file)
@@ -314,14 +314,13 @@ static int _set_hwmod_postsetup_state(struct omap_hwmod *oh, void *data)
        return omap_hwmod_set_postsetup_state(oh, *(u8 *)data);
 }
 
+void __iomem *omap_irq_base;
+
 /*
  * Initialize asm_irq_base for entry-macro.S
  */
 static inline void omap_irq_base_init(void)
 {
-       extern void __iomem *omap_irq_base;
-
-#ifdef MULTI_OMAP2
        if (cpu_is_omap24xx())
                omap_irq_base = OMAP2_L4_IO_ADDRESS(OMAP24XX_IC_BASE);
        else if (cpu_is_omap34xx())
@@ -330,7 +329,6 @@ static inline void omap_irq_base_init(void)
                omap_irq_base = OMAP2_L4_IO_ADDRESS(OMAP44XX_GIC_CPU_BASE);
        else
                pr_err("Could not initialize omap_irq_base\n");
-#endif
 }
 
 void __init omap2_init_common_infrastructure(void)
index df8d2f2872c6edce5e8d72a2ac668c7f10ebe336..fae49d12bc76c26224f9e016997ee7bc8b45b1d1 100644 (file)
@@ -160,7 +160,7 @@ static int __init _omap_mux_get_by_name(struct omap_mux_partition *partition,
        struct omap_mux *mux = NULL;
        struct omap_mux_entry *e;
        const char *mode_name;
-       int found = 0, found_mode, mode0_len = 0;
+       int found = 0, found_mode = 0, mode0_len = 0;
        struct list_head *muxmodes = &partition->muxmodes;
 
        mode_name = strchr(muxname, '.');
index 9e5dc8ed51e9a0530a87361bfcd571c91a36c6f8..97feb3ab6a69e9842961a2da169be26f07c5f55a 100644 (file)
@@ -134,7 +134,7 @@ static void omap2_enter_full_retention(void)
 
        /* Block console output in case it is on one of the OMAP UARTs */
        if (!is_suspending())
-               if (try_acquire_console_sem())
+               if (!console_trylock())
                        goto no_sleep;
 
        omap_uart_prepare_idle(0);
@@ -151,7 +151,7 @@ static void omap2_enter_full_retention(void)
        omap_uart_resume_idle(0);
 
        if (!is_suspending())
-               release_console_sem();
+               console_unlock();
 
 no_sleep:
        if (omap2_pm_debug) {
index 8cbbeade4b8a87df8eafe3de9ce7292131947969..a4aa1920a75ca5fa499b97028f334dd72290acee 100644 (file)
@@ -398,7 +398,7 @@ void omap_sram_idle(void)
        if (!is_suspending())
                if (per_next_state < PWRDM_POWER_ON ||
                    core_next_state < PWRDM_POWER_ON)
-                       if (try_acquire_console_sem())
+                       if (!console_trylock())
                                goto console_still_active;
 
        /* PER */
@@ -481,7 +481,7 @@ void omap_sram_idle(void)
        }
 
        if (!is_suspending())
-               release_console_sem();
+               console_unlock();
 
 console_still_active:
        /* Disable IO-PAD and IO-CHAIN wakeup */
index d5233890370cb18ecd021fdcd9313877c5dc0c7d..cf600e22bf8e723668dc9a20c893e163d6f5c76a 100644 (file)
@@ -19,7 +19,6 @@
 #include <plat/prcm.h>
 
 #include "powerdomain.h"
-#include "prm-regbits-34xx.h"
 #include "prm.h"
 #include "prm-regbits-24xx.h"
 #include "prm-regbits-34xx.h"
index 302da7403a102a7317709b0529e58201dce5458d..32e91a9c8b6b7815ea1fd71789175d53b4bd3dcd 100644 (file)
@@ -812,7 +812,7 @@ void __init omap_serial_init_port(struct omap_board_data *bdata)
 
        oh->dev_attr = uart;
 
-       acquire_console_sem(); /* in case the earlycon is on the UART */
+       console_lock(); /* in case the earlycon is on the UART */
 
        /*
         * Because of early UART probing, UART did not get idled
@@ -838,7 +838,7 @@ void __init omap_serial_init_port(struct omap_board_data *bdata)
        omap_uart_block_sleep(uart);
        uart->timeout = DEFAULT_TIMEOUT;
 
-       release_console_sem();
+       console_unlock();
 
        if ((cpu_is_omap34xx() && uart->padconf) ||
            (uart->wk_en && uart->wk_mask)) {
index 4e48e786bec728f625c1359ce9c0f785cdf99b53..7b7c2683ae7bb15cad4a2d32b4eab681884a0864 100644 (file)
@@ -42,6 +42,8 @@
 
 #include "timer-gp.h"
 
+#include <plat/common.h>
+
 /* MAX_GPTIMER_ID: number of GPTIMERs on the chip */
 #define MAX_GPTIMER_ID         12
 
@@ -176,10 +178,14 @@ static void __init omap2_gp_clockevent_init(void)
 /* 
  * When 32k-timer is enabled, don't use GPTimer for clocksource
  * instead, just leave default clocksource which uses the 32k
- * sync counter.  See clocksource setup in see plat-omap/common.c. 
+ * sync counter.  See clocksource setup in plat-omap/counter_32k.c
  */
 
-static inline void __init omap2_gp_clocksource_init(void) {}
+static void __init omap2_gp_clocksource_init(void)
+{
+       omap_init_clocksource_32k();
+}
+
 #else
 /*
  * clocksource
index b4575ae9648ee7220ffb40d31359e8f12b7cecbb..7ca138a943a9d3a66cc739e55fcaa1945c5ab684 100644 (file)
@@ -2,52 +2,56 @@ menu "RealView platform type"
        depends on ARCH_REALVIEW
 
 config MACH_REALVIEW_EB
-       bool "Support RealView/EB platform"
+       bool "Support RealView(R) Emulation Baseboard"
        select ARM_GIC
        help
-         Include support for the ARM(R) RealView Emulation Baseboard platform.
+         Include support for the ARM(R) RealView(R) Emulation Baseboard
+         platform.
 
 config REALVIEW_EB_A9MP
-       bool "Support Multicore Cortex-A9"
+       bool "Support Multicore Cortex-A9 Tile"
        depends on MACH_REALVIEW_EB
        select CPU_V7
        help
-         Enable support for the Cortex-A9MPCore tile on the Realview platform.
+         Enable support for the Cortex-A9MPCore tile fitted to the
+         Realview(R) Emulation Baseboard platform.
 
 config REALVIEW_EB_ARM11MP
-       bool "Support ARM11MPCore tile"
+       bool "Support ARM11MPCore Tile"
        depends on MACH_REALVIEW_EB
        select CPU_V6
        select ARCH_HAS_BARRIERS if SMP
        help
-         Enable support for the ARM11MPCore tile on the Realview platform.
+         Enable support for the ARM11MPCore tile fitted to the Realview(R)
+         Emulation Baseboard platform.
 
 config REALVIEW_EB_ARM11MP_REVB
-       bool "Support ARM11MPCore RevB tile"
+       bool "Support ARM11MPCore RevB Tile"
        depends on REALVIEW_EB_ARM11MP
        help
-         Enable support for the ARM11MPCore RevB tile on the Realview
-         platform. Since there are device address differences, a
-         kernel built with this option enabled is not compatible with
-         other revisions of the ARM11MPCore tile.
+         Enable support for the ARM11MPCore Revision B tile on the
+         Realview(R) Emulation Baseboard platform. Since there are device
+         address differences, a kernel built with this option enabled is
+         not compatible with other revisions of the ARM11MPCore tile.
 
 config MACH_REALVIEW_PB11MP
-       bool "Support RealView/PB11MPCore platform"
+       bool "Support RealView(R) Platform Baseboard for ARM11MPCore"
        select CPU_V6
        select ARM_GIC
        select HAVE_PATA_PLATFORM
        select ARCH_HAS_BARRIERS if SMP
        help
-         Include support for the ARM(R) RealView MPCore Platform Baseboard.
-         PB11MPCore is a platform with an on-board ARM11MPCore and has
+         Include support for the ARM(R) RealView(R) Platform Baseboard for
+         the ARM11MPCore.  This platform has an on-board ARM11MPCore and has
          support for PCI-E and Compact Flash.
 
 config MACH_REALVIEW_PB1176
-       bool "Support RealView/PB1176 platform"
+       bool "Support RealView(R) Platform Baseboard for ARM1176JZF-S"
        select CPU_V6
        select ARM_GIC
        help
-         Include support for the ARM(R) RealView ARM1176 Platform Baseboard.
+         Include support for the ARM(R) RealView(R) Platform Baseboard for
+         ARM1176JZF-S.
 
 config REALVIEW_PB1176_SECURE_FLASH
        bool "Allow access to the secure flash memory block"
@@ -59,23 +63,24 @@ config REALVIEW_PB1176_SECURE_FLASH
          block (64MB @ 0x3c000000) is required.
 
 config MACH_REALVIEW_PBA8
-       bool "Support RealView/PB-A8 platform"
+       bool "Support RealView(R) Platform Baseboard for Cortex(tm)-A8 platform"
        select CPU_V7
        select ARM_GIC
        select HAVE_PATA_PLATFORM
        help
-         Include support for the ARM(R) RealView Cortex-A8 Platform Baseboard.
-         PB-A8 is a platform with an on-board Cortex-A8 and has support for
-         PCI-E and Compact Flash.
+         Include support for the ARM(R) RealView Platform Baseboard for
+         Cortex(tm)-A8.  This platform has an on-board Cortex-A8 and has
+         support for PCI-E and Compact Flash.
 
 config MACH_REALVIEW_PBX
-       bool "Support RealView/PBX platform"
+       bool "Support RealView(R) Platform Baseboard Explore"
        select ARM_GIC
        select HAVE_PATA_PLATFORM
        select ARCH_SPARSEMEM_ENABLE if CPU_V7 && !REALVIEW_HIGH_PHYS_OFFSET
        select ZONE_DMA if SPARSEMEM
        help
-         Include support for the ARM(R) RealView PBX platform.
+         Include support for the ARM(R) RealView(R) Platform Baseboard
+         Explore.
 
 config REALVIEW_HIGH_PHYS_OFFSET
        bool "High physical base address for the RealView platform"
index a22bf67f2f78ca8aada648cc2ba2a6737de9f53f..6959d13d908a1e1242abe96e8b064b859f67ca11 100644 (file)
@@ -41,7 +41,7 @@ volatile int __cpuinitdata pen_release = -1;
  * observers, irrespective of whether they're taking part in coherency
  * or not.  This is necessary for the hotplug code to work reliably.
  */
-static void write_pen_release(int val)
+static void __cpuinit write_pen_release(int val)
 {
        pen_release = val;
        smp_wmb();
index 4d1b4c5c938931065166555dffa9f5b7779f7cfe..0c8f6cf3e948270f55c55b3f3f61cca77e3f8a80 100644 (file)
@@ -60,6 +60,8 @@ endchoice
 
 config MACH_AG5EVM
        bool "AG5EVM board"
+       select ARCH_REQUIRE_GPIOLIB
+       select SH_LCD_MIPI_DSI
        depends on ARCH_SH73A0
 
 config MACH_MACKEREL
index c18a740a415957b2bcd8e4ea30d192822b501c5f..2123b96b563822abe183140aba3de1f385993d05 100644 (file)
 #include <linux/input/sh_keysc.h>
 #include <linux/mmc/host.h>
 #include <linux/mmc/sh_mmcif.h>
-
+#include <linux/sh_clk.h>
+#include <video/sh_mobile_lcdc.h>
+#include <video/sh_mipi_dsi.h>
 #include <sound/sh_fsi.h>
-
 #include <mach/hardware.h>
 #include <mach/sh73a0.h>
 #include <mach/common.h>
@@ -183,11 +184,165 @@ static struct platform_device mmc_device = {
        .resource       = sh_mmcif_resources,
 };
 
+/* IrDA */
+static struct resource irda_resources[] = {
+       [0] = {
+               .start  = 0xE6D00000,
+               .end    = 0xE6D01FD4 - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = gic_spi(95),
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device irda_device = {
+       .name           = "sh_irda",
+       .id             = 0,
+       .resource       = irda_resources,
+       .num_resources  = ARRAY_SIZE(irda_resources),
+};
+
+static unsigned char lcd_backlight_seq[3][2] = {
+       { 0x04, 0x07 },
+       { 0x23, 0x80 },
+       { 0x03, 0x01 },
+};
+
+static void lcd_backlight_on(void)
+{
+       struct i2c_adapter *a;
+       struct i2c_msg msg;
+       int k;
+
+       a = i2c_get_adapter(1);
+       for (k = 0; a && k < 3; k++) {
+               msg.addr = 0x6d;
+               msg.buf = &lcd_backlight_seq[k][0];
+               msg.len = 2;
+               msg.flags = 0;
+               if (i2c_transfer(a, &msg, 1) != 1)
+                       break;
+       }
+}
+
+static void lcd_backlight_reset(void)
+{
+       gpio_set_value(GPIO_PORT235, 0);
+       mdelay(24);
+       gpio_set_value(GPIO_PORT235, 1);
+}
+
+static void lcd_on(void *board_data, struct fb_info *info)
+{
+       lcd_backlight_on();
+}
+
+static void lcd_off(void *board_data)
+{
+       lcd_backlight_reset();
+}
+
+/* LCDC0 */
+static const struct fb_videomode lcdc0_modes[] = {
+       {
+               .name           = "R63302(QHD)",
+               .xres           = 544,
+               .yres           = 961,
+               .left_margin    = 72,
+               .right_margin   = 600,
+               .hsync_len      = 16,
+               .upper_margin   = 8,
+               .lower_margin   = 8,
+               .vsync_len      = 2,
+               .sync           = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_HOR_HIGH_ACT,
+       },
+};
+
+static struct sh_mobile_lcdc_info lcdc0_info = {
+       .clock_source = LCDC_CLK_PERIPHERAL,
+       .ch[0] = {
+               .chan = LCDC_CHAN_MAINLCD,
+               .interface_type = RGB24,
+               .clock_divider = 1,
+               .flags = LCDC_FLAGS_DWPOL,
+               .lcd_size_cfg.width = 44,
+               .lcd_size_cfg.height = 79,
+               .bpp = 16,
+               .lcd_cfg = lcdc0_modes,
+               .num_cfg = ARRAY_SIZE(lcdc0_modes),
+               .board_cfg = {
+                       .display_on = lcd_on,
+                       .display_off = lcd_off,
+               },
+       }
+};
+
+static struct resource lcdc0_resources[] = {
+       [0] = {
+               .name   = "LCDC0",
+               .start  = 0xfe940000, /* P4-only space */
+               .end    = 0xfe943fff,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = intcs_evt2irq(0x580),
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device lcdc0_device = {
+       .name           = "sh_mobile_lcdc_fb",
+       .num_resources  = ARRAY_SIZE(lcdc0_resources),
+       .resource       = lcdc0_resources,
+       .id             = 0,
+       .dev    = {
+               .platform_data  = &lcdc0_info,
+               .coherent_dma_mask = ~0,
+       },
+};
+
+/* MIPI-DSI */
+static struct resource mipidsi0_resources[] = {
+       [0] = {
+               .start  = 0xfeab0000,
+               .end    = 0xfeab3fff,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = 0xfeab4000,
+               .end    = 0xfeab7fff,
+               .flags  = IORESOURCE_MEM,
+       },
+};
+
+static struct sh_mipi_dsi_info mipidsi0_info = {
+       .data_format    = MIPI_RGB888,
+       .lcd_chan       = &lcdc0_info.ch[0],
+       .vsynw_offset   = 20,
+       .clksrc         = 1,
+       .flags          = SH_MIPI_DSI_HSABM,
+};
+
+static struct platform_device mipidsi0_device = {
+       .name           = "sh-mipi-dsi",
+       .num_resources  = ARRAY_SIZE(mipidsi0_resources),
+       .resource       = mipidsi0_resources,
+       .id             = 0,
+       .dev    = {
+               .platform_data  = &mipidsi0_info,
+       },
+};
+
 static struct platform_device *ag5evm_devices[] __initdata = {
        &eth_device,
        &keysc_device,
        &fsi_device,
        &mmc_device,
+       &irda_device,
+       &lcdc0_device,
+       &mipidsi0_device,
 };
 
 static struct map_desc ag5evm_io_desc[] __initdata = {
@@ -224,6 +379,8 @@ void __init ag5evm_init_irq(void)
        __raw_writew(__raw_readw(PINTCR0A) | (2<<10), PINTCR0A);
 }
 
+#define DSI0PHYCR      0xe615006c
+
 static void __init ag5evm_init(void)
 {
        sh73a0_pinmux_init();
@@ -287,6 +444,25 @@ static void __init ag5evm_init(void)
        gpio_request(GPIO_FN_FSIAISLD, NULL);
        gpio_request(GPIO_FN_FSIAOSLD, NULL);
 
+       /* IrDA */
+       gpio_request(GPIO_FN_PORT241_IRDA_OUT, NULL);
+       gpio_request(GPIO_FN_PORT242_IRDA_IN,  NULL);
+       gpio_request(GPIO_FN_PORT243_IRDA_FIRSEL, NULL);
+
+       /* LCD panel */
+       gpio_request(GPIO_PORT217, NULL); /* RESET */
+       gpio_direction_output(GPIO_PORT217, 0);
+       mdelay(1);
+       gpio_set_value(GPIO_PORT217, 1);
+
+       /* LCD backlight controller */
+       gpio_request(GPIO_PORT235, NULL); /* RESET */
+       gpio_direction_output(GPIO_PORT235, 0);
+       lcd_backlight_reset();
+
+       /* MIPI-DSI clock setup */
+       __raw_writel(0x2a809010, DSI0PHYCR);
+
 #ifdef CONFIG_CACHE_L2X0
        /* Shared attribute override enable, 64K*8way */
        l2x0_init(__io(0xf0100000), 0x00460000, 0xc2000fff);
index 686b304a7708793b42084840bd900234cac82f1c..ef4613b993a2c030829aaec7975aab8498f3d742 100644 (file)
@@ -347,7 +347,6 @@ static void __init g3evm_init(void)
        gpio_request(GPIO_FN_IRDA_OUT, NULL);
        gpio_request(GPIO_FN_IRDA_IN, NULL);
        gpio_request(GPIO_FN_IRDA_FIRSEL, NULL);
-       set_irq_type(evt2irq(0x480), IRQ_TYPE_LEVEL_LOW);
 
        sh7367_add_standard_devices();
 
index 7b15d21f0f68b473fc7e8d87a859effdece7670d..fb4213a4e15a66ac06ff09070ec330d9463f0787 100644 (file)
  *     SW1     |       SW33
  *             | bit1 | bit2 | bit3 | bit4
  * -------------+------+------+------+-------
- * MMC0          OFF   |  OFF |  ON  |  ON  |  X
- * MMC1          ON    |  OFF |  ON  |  X   | ON
- * SDHI1  OFF  |  ON  |   X  |  OFF | ON
+ * MMC0   OFF  |  OFF |   X  |  ON  |  X       (Use MMCIF)
+ * SDHI1  OFF  |  ON  |   X  |  OFF |  X       (Use MFD_SH_MOBILE_SDHI)
  *
  */
 
index 9aa8d68d1a9c027e5b3660235a17b5ad55cf24eb..e9731b5a73edacc54f2d0a9340ca455e84a063e5 100644 (file)
@@ -234,7 +234,9 @@ static int pllc2_set_rate(struct clk *clk, unsigned long rate)
 
        value = __raw_readl(PLLC2CR) & ~(0x3f << 24);
 
-       __raw_writel((value & ~0x80000000) | ((idx + 19) << 24), PLLC2CR);
+       __raw_writel(value | ((idx + 19) << 24), PLLC2CR);
+
+       clk->rate = clk->freq_table[idx].frequency;
 
        return 0;
 }
index 720a71433be60743fe01214a4fa335322c92e71f..ddd4a1b775f030a0b7635fe666aa31d5867aae63 100644 (file)
@@ -118,8 +118,16 @@ static unsigned long pll_recalc(struct clk *clk)
 {
        unsigned long mult = 1;
 
-       if (__raw_readl(PLLECR) & (1 << clk->enable_bit))
+       if (__raw_readl(PLLECR) & (1 << clk->enable_bit)) {
                mult = (((__raw_readl(clk->enable_reg) >> 24) & 0x3f) + 1);
+               /* handle CFG bit for PLL1 and PLL2 */
+               switch (clk->enable_bit) {
+               case 1:
+               case 2:
+                       if (__raw_readl(clk->enable_reg) & (1 << 20))
+                               mult *= 2;
+               }
+       }
 
        return clk->parent->rate * mult;
 }
@@ -212,7 +220,7 @@ enum { DIV4_I, DIV4_ZG, DIV4_M3, DIV4_B, DIV4_M1, DIV4_M2,
 static struct clk div4_clks[DIV4_NR] = {
        [DIV4_I] = DIV4(FRQCRA, 20, 0xfff, CLK_ENABLE_ON_INIT),
        [DIV4_ZG] = DIV4(FRQCRA, 16, 0xbff, CLK_ENABLE_ON_INIT),
-       [DIV4_M3] = DIV4(FRQCRA, 8, 0xfff, CLK_ENABLE_ON_INIT),
+       [DIV4_M3] = DIV4(FRQCRA, 12, 0xfff, CLK_ENABLE_ON_INIT),
        [DIV4_B] = DIV4(FRQCRA, 8, 0xfff, CLK_ENABLE_ON_INIT),
        [DIV4_M1] = DIV4(FRQCRA, 4, 0xfff, 0),
        [DIV4_M2] = DIV4(FRQCRA, 0, 0xfff, 0),
@@ -255,10 +263,10 @@ static struct clk div6_clks[DIV6_NR] = {
 };
 
 enum { MSTP001,
-       MSTP125, MSTP116,
+       MSTP125, MSTP118, MSTP116, MSTP100,
        MSTP219,
        MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200,
-       MSTP331, MSTP329, MSTP323, MSTP312,
+       MSTP331, MSTP329, MSTP325, MSTP323, MSTP312,
        MSTP411, MSTP410, MSTP403,
        MSTP_NR };
 
@@ -268,7 +276,9 @@ enum { MSTP001,
 static struct clk mstp_clks[MSTP_NR] = {
        [MSTP001] = MSTP(&div4_clks[DIV4_HP], SMSTPCR0, 1, 0), /* IIC2 */
        [MSTP125] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR1, 25, 0), /* TMU0 */
+       [MSTP118] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 18, 0), /* DSITX0 */
        [MSTP116] = MSTP(&div4_clks[DIV4_HP], SMSTPCR1, 16, 0), /* IIC0 */
+       [MSTP100] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 0, 0), /* LCDC0 */
        [MSTP219] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 19, 0), /* SCIFA7 */
        [MSTP207] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 7, 0), /* SCIFA5 */
        [MSTP206] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 6, 0), /* SCIFB */
@@ -279,6 +289,7 @@ static struct clk mstp_clks[MSTP_NR] = {
        [MSTP200] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 0, 0), /* SCIFA4 */
        [MSTP331] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 31, 0), /* SCIFA6 */
        [MSTP329] = MSTP(&r_clk, SMSTPCR3, 29, 0), /* CMT10 */
+       [MSTP325] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 25, 0), /* IrDA */
        [MSTP323] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 23, 0), /* IIC1 */
        [MSTP312] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 12, 0), /* MMCIF0 */
        [MSTP411] = MSTP(&div4_clks[DIV4_HP], SMSTPCR4, 11, 0), /* IIC3 */
@@ -288,16 +299,25 @@ static struct clk mstp_clks[MSTP_NR] = {
 
 #define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk }
 #define CLKDEV_DEV_ID(_id, _clk) { .dev_id = _id, .clk = _clk }
+#define CLKDEV_ICK_ID(_cid, _did, _clk) { .con_id = _cid, .dev_id = _did, .clk = _clk }
 
 static struct clk_lookup lookups[] = {
        /* main clocks */
        CLKDEV_CON_ID("r_clk", &r_clk),
 
+       /* DIV6 clocks */
+       CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSIT]),
+       CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSIT]),
+       CLKDEV_ICK_ID("dsi0p_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSI0P]),
+       CLKDEV_ICK_ID("dsi1p_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSI1P]),
+
        /* MSTP32 clocks */
        CLKDEV_DEV_ID("i2c-sh_mobile.2", &mstp_clks[MSTP001]), /* I2C2 */
+       CLKDEV_DEV_ID("sh_mobile_lcdc_fb.0", &mstp_clks[MSTP100]), /* LCDC0 */
        CLKDEV_DEV_ID("sh_tmu.0", &mstp_clks[MSTP125]), /* TMU00 */
        CLKDEV_DEV_ID("sh_tmu.1", &mstp_clks[MSTP125]), /* TMU01 */
        CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP116]), /* I2C0 */
+       CLKDEV_DEV_ID("sh-mipi-dsi.0", &mstp_clks[MSTP118]), /* DSITX */
        CLKDEV_DEV_ID("sh-sci.7", &mstp_clks[MSTP219]), /* SCIFA7 */
        CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP207]), /* SCIFA5 */
        CLKDEV_DEV_ID("sh-sci.8", &mstp_clks[MSTP206]), /* SCIFB */
@@ -308,6 +328,7 @@ static struct clk_lookup lookups[] = {
        CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP200]), /* SCIFA4 */
        CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP331]), /* SCIFA6 */
        CLKDEV_DEV_ID("sh_cmt.10", &mstp_clks[MSTP329]), /* CMT10 */
+       CLKDEV_DEV_ID("sh_irda.0", &mstp_clks[MSTP325]), /* IrDA */
        CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), /* I2C1 */
        CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP312]), /* MMCIF0 */
        CLKDEV_DEV_ID("i2c-sh_mobile.3", &mstp_clks[MSTP411]), /* I2C3 */
index f78a1ead71a5e3a8ce8d8b8a4229aaaca52ddc36..ca5f9d17b39abd6cb1f92ce2d33c09bf5f9e86b8 100644 (file)
@@ -365,6 +365,7 @@ static struct intc_desc intca_desc __initdata = {
 
 enum {
        UNUSED_INTCS = 0,
+       ENABLED_INTCS,
 
        INTCS,
 
@@ -413,7 +414,7 @@ enum {
        CMT4,
        DSITX1_DSITX1_0,
        DSITX1_DSITX1_1,
-       /* MFIS2 */
+       MFIS2_INTCS, /* Priority always enabled using ENABLED_INTCS */
        CPORTS2R,
        /* CEC */
        JPU6E,
@@ -477,7 +478,7 @@ static struct intc_vect intcs_vectors[] = {
        INTCS_VECT(CMT4, 0x1980),
        INTCS_VECT(DSITX1_DSITX1_0, 0x19a0),
        INTCS_VECT(DSITX1_DSITX1_1, 0x19c0),
-       /* MFIS2 */
+       INTCS_VECT(MFIS2_INTCS, 0x1a00),
        INTCS_VECT(CPORTS2R, 0x1a20),
        /* CEC */
        INTCS_VECT(JPU6E, 0x1a80),
@@ -543,7 +544,7 @@ static struct intc_mask_reg intcs_mask_registers[] = {
          { 0, TMU1_TUNI2, TMU1_TUNI1, TMU1_TUNI0,
            CMT4, DSITX1_DSITX1_0, DSITX1_DSITX1_1, 0 } },
        { 0xffd5019c, 0xffd501dc, 8, /* IMR7SA3 / IMCR7SA3 */
-         { 0, CPORTS2R, 0, 0,
+         { MFIS2_INTCS, CPORTS2R, 0, 0,
            JPU6E, 0, 0, 0 } },
        { 0xffd20104, 0, 16, /* INTAMASK */
          { 0, 0, 0, 0, 0, 0, 0, 0,
@@ -571,7 +572,8 @@ static struct intc_prio_reg intcs_prio_registers[] = {
        { 0xffd50030, 0, 16, 4, /* IPRMS3 */ { TMU1, 0, 0, 0 } },
        { 0xffd50034, 0, 16, 4, /* IPRNS3 */ { CMT4, DSITX1_DSITX1_0,
                                               DSITX1_DSITX1_1, 0 } },
-       { 0xffd50038, 0, 16, 4, /* IPROS3 */ { 0, CPORTS2R, 0, 0 } },
+       { 0xffd50038, 0, 16, 4, /* IPROS3 */ { ENABLED_INTCS, CPORTS2R,
+                                              0, 0 } },
        { 0xffd5003c, 0, 16, 4, /* IPRPS3 */ { JPU6E, 0, 0, 0 } },
 };
 
@@ -590,6 +592,7 @@ static struct resource intcs_resources[] __initdata = {
 
 static struct intc_desc intcs_desc __initdata = {
        .name = "sh7372-intcs",
+       .force_enable = ENABLED_INTCS,
        .resource = intcs_resources,
        .num_resources = ARRAY_SIZE(intcs_resources),
        .hw = INTC_HW_DESC(intcs_vectors, intcs_groups, intcs_mask_registers,
index 322d8d57cbcf754b09d15762bf7b0a947394c5d9..5d0e1503ece66fb9385f3ffc80abb88e60d2ed27 100644 (file)
@@ -252,10 +252,11 @@ static irqreturn_t sh73a0_intcs_demux(int irq, void *dev_id)
 
 void __init sh73a0_init_irq(void)
 {
-       void __iomem *gic_base = __io(0xf0001000);
+       void __iomem *gic_dist_base = __io(0xf0001000);
+       void __iomem *gic_cpu_base = __io(0xf0000100);
        void __iomem *intevtsa = ioremap_nocache(0xffd20100, PAGE_SIZE);
 
-       gic_init(0, 29, gic_base, gic_base);
+       gic_init(0, 29, gic_dist_base, gic_cpu_base);
 
        register_intc_controller(&intcs_desc);
 
index bd066206e110301dccfe6e13c1a24c3749b662fb..ad80488015136135443e3b1d59664b96a67b4fc6 100644 (file)
@@ -207,9 +207,9 @@ static int tegra_gpio_irq_set_type(struct irq_data *d, unsigned int type)
        spin_unlock_irqrestore(&bank->lvl_lock[port], flags);
 
        if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH))
-               __set_irq_handler_unlocked(irq, handle_level_irq);
+               __set_irq_handler_unlocked(d->irq, handle_level_irq);
        else if (type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING))
-               __set_irq_handler_unlocked(irq, handle_edge_irq);
+               __set_irq_handler_unlocked(d->irq, handle_edge_irq);
 
        return 0;
 }
index d7723955dac7486519618d3e2c3715267eee667d..a217f68ba57c6c790d24f4f7eb3e50ddd925ec7a 100644 (file)
@@ -20,6 +20,8 @@
 #ifndef __MACH_CLK_H
 #define __MACH_CLK_H
 
+struct clk;
+
 void tegra_periph_reset_deassert(struct clk *c);
 void tegra_periph_reset_assert(struct clk *c);
 
index 412f5c63e65adabc23eab9bf520acaccccd7f399..66cd3f4fc8967a02a6f0462937cf4d5b640e23dc 100644 (file)
@@ -20,6 +20,8 @@
 #ifndef __MACH_CLKDEV_H
 #define __MACH_CLKDEV_H
 
+struct clk;
+
 static inline int __clk_get(struct clk *clk)
 {
        return 1;
diff --git a/arch/arm/mach-tegra/include/mach/kbc.h b/arch/arm/mach-tegra/include/mach/kbc.h
new file mode 100644 (file)
index 0000000..66ad276
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Platform definitions for tegra-kbc keyboard input driver
+ *
+ * Copyright (c) 2010-2011, NVIDIA Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#ifndef ASMARM_ARCH_TEGRA_KBC_H
+#define ASMARM_ARCH_TEGRA_KBC_H
+
+#include <linux/types.h>
+#include <linux/input/matrix_keypad.h>
+
+#ifdef CONFIG_ARCH_TEGRA_2x_SOC
+#define KBC_MAX_GPIO   24
+#define KBC_MAX_KPENT  8
+#else
+#define KBC_MAX_GPIO   20
+#define KBC_MAX_KPENT  7
+#endif
+
+#define KBC_MAX_ROW    16
+#define KBC_MAX_COL    8
+#define KBC_MAX_KEY    (KBC_MAX_ROW * KBC_MAX_COL)
+
+struct tegra_kbc_pin_cfg {
+       bool is_row;
+       unsigned char num;
+};
+
+struct tegra_kbc_wake_key {
+       u8 row:4;
+       u8 col:4;
+};
+
+struct tegra_kbc_platform_data {
+       unsigned int debounce_cnt;
+       unsigned int repeat_cnt;
+
+       unsigned int wake_cnt; /* 0:wake on any key >1:wake on wake_cfg */
+       const struct tegra_kbc_wake_key *wake_cfg;
+
+       struct tegra_kbc_pin_cfg pin_cfg[KBC_MAX_GPIO];
+       const struct matrix_keymap_data *keymap_data;
+
+       bool wakeup;
+};
+#endif
index de7dfad6f769d67d0c81bb10152b3def9beca491..17c74d21077c3663c2b466c928762be3b1ace248 100644 (file)
 #define ICTLR_COP_IER_CLR      0x38
 #define ICTLR_COP_IEP_CLASS    0x3c
 
-static void (*gic_mask_irq)(struct irq_data *d);
-static void (*gic_unmask_irq)(struct irq_data *d);
+static void (*tegra_gic_mask_irq)(struct irq_data *d);
+static void (*tegra_gic_unmask_irq)(struct irq_data *d);
 
-#define irq_to_ictlr(irq) (((irq)-32) >> 5)
+#define irq_to_ictlr(irq) (((irq) - 32) >> 5)
 static void __iomem *tegra_ictlr_base = IO_ADDRESS(TEGRA_PRIMARY_ICTLR_BASE);
-#define ictlr_to_virt(ictlr) (tegra_ictlr_base + (ictlr)*0x100)
+#define ictlr_to_virt(ictlr) (tegra_ictlr_base + (ictlr) * 0x100)
 
 static void tegra_mask(struct irq_data *d)
 {
        void __iomem *addr = ictlr_to_virt(irq_to_ictlr(d->irq));
-       gic_mask_irq(d);
-       writel(1<<(d->irq&31), addr+ICTLR_CPU_IER_CLR);
+       tegra_gic_mask_irq(d);
+       writel(1 << (d->irq & 31), addr+ICTLR_CPU_IER_CLR);
 }
 
 static void tegra_unmask(struct irq_data *d)
 {
        void __iomem *addr = ictlr_to_virt(irq_to_ictlr(d->irq));
-       gic_unmask_irq(d);
+       tegra_gic_unmask_irq(d);
        writel(1<<(d->irq&31), addr+ICTLR_CPU_IER_SET);
 }
 
@@ -98,8 +98,8 @@ void __init tegra_init_irq(void)
                 IO_ADDRESS(TEGRA_ARM_PERIF_BASE + 0x100));
 
        gic = get_irq_chip(29);
-       gic_unmask_irq = gic->irq_unmask;
-       gic_mask_irq = gic->irq_mask;
+       tegra_gic_unmask_irq = gic->irq_unmask;
+       tegra_gic_mask_irq = gic->irq_mask;
        tegra_irq.irq_ack = gic->irq_ack;
 #ifdef CONFIG_SMP
        tegra_irq.irq_set_affinity = gic->irq_set_affinity;
index 3f7b5e9d83c51633556dca30b9fada357c49e0ba..9cdec5aa04a04bf57eb66a5bcc2c5966c3f99629 100644 (file)
@@ -2,17 +2,19 @@ menu "Versatile platform type"
        depends on ARCH_VERSATILE
 
 config ARCH_VERSATILE_PB
-       bool "Support Versatile/PB platform"
+       bool "Support Versatile Platform Baseboard for ARM926EJ-S"
        select CPU_ARM926T
        select MIGHT_HAVE_PCI
        default y
        help
-         Include support for the ARM(R) Versatile/PB platform.
+         Include support for the ARM(R) Versatile Platform Baseboard
+         for the ARM926EJ-S.
 
 config MACH_VERSATILE_AB
-       bool "Support Versatile/AB platform"
+       bool "Support Versatile Application Baseboard for ARM926EJ-S"
        select CPU_ARM926T
        help
-         Include support for the ARM(R) Versatile/AP platform.
+         Include support for the ARM(R) Versatile Application Baseboard
+         for the ARM926EJ-S.
 
 endmenu
index b1687b6abe63024daa40582b49446aa4eb3965cc..634bf1d3a311d13360c32c269fedbe81e146d3fd 100644 (file)
@@ -39,7 +39,7 @@ volatile int __cpuinitdata pen_release = -1;
  * observers, irrespective of whether they're taking part in coherency
  * or not.  This is necessary for the hotplug code to work reliably.
  */
-static void write_pen_release(int val)
+static void __cpuinit write_pen_release(int val)
 {
        pen_release = val;
        smp_wmb();
index a9ed3428a2fae616a75405c69692e38c2f3a7de4..1edae65a0e72c4cec6edea8810b8f841a4c1b46a 100644 (file)
@@ -19,6 +19,7 @@
 #include <asm/mach/time.h>
 #include <asm/hardware/arm_timer.h>
 #include <asm/hardware/timer-sp.h>
+#include <asm/hardware/sp810.h>
 
 #include <mach/motherboard.h>
 
@@ -50,8 +51,16 @@ void __init v2m_map_io(struct map_desc *tile, size_t num)
 
 static void __init v2m_timer_init(void)
 {
+       u32 scctrl;
+
        versatile_sched_clock_init(MMIO_P2V(V2M_SYS_24MHZ), 24000000);
 
+       /* Select 1MHz TIMCLK as the reference clock for SP804 timers */
+       scctrl = readl(MMIO_P2V(V2M_SYSCTL + SCCTRL));
+       scctrl |= SCCTRL_TIMEREN0SEL_TIMCLK;
+       scctrl |= SCCTRL_TIMEREN1SEL_TIMCLK;
+       writel(scctrl, MMIO_P2V(V2M_SYSCTL + SCCTRL));
+
        writel(0, MMIO_P2V(V2M_TIMER0) + TIMER_CTRL);
        writel(0, MMIO_P2V(V2M_TIMER1) + TIMER_CTRL);
 
index 5164069ced42f0d0176369247fa40701292ea511..cddd684364dab2f6503d20132d8f5047615a2a52 100644 (file)
@@ -297,6 +297,12 @@ void __init arm_memblock_init(struct meminfo *mi, struct machine_desc *mdesc)
        memblock_reserve(__pa(_stext), _end - _stext);
 #endif
 #ifdef CONFIG_BLK_DEV_INITRD
+       if (phys_initrd_size &&
+           memblock_is_region_reserved(phys_initrd_start, phys_initrd_size)) {
+               pr_err("INITRD: 0x%08lx+0x%08lx overlaps in-use memory region - disabling initrd\n",
+                      phys_initrd_start, phys_initrd_size);
+               phys_initrd_start = phys_initrd_size = 0;
+       }
        if (phys_initrd_size) {
                memblock_reserve(phys_initrd_start, phys_initrd_size);
 
index 18fe3cb195dce938ee47b3f37ac2ecd8c2f64298..b6333ae3f92aa22f8820720d5cf147089ce62efc 100644 (file)
@@ -144,12 +144,9 @@ config OMAP_IOMMU_DEBUG
 config OMAP_IOMMU_IVA2
        bool
 
-choice
-       prompt "System timer"
-       default OMAP_32K_TIMER if !ARCH_OMAP15XX
-
 config OMAP_MPU_TIMER
        bool "Use mpu timer"
+       depends on ARCH_OMAP1
        help
          Select this option if you want to use the OMAP mpu timer. This
          timer provides more intra-tick resolution than the 32KHz timer,
@@ -158,6 +155,7 @@ config OMAP_MPU_TIMER
 config OMAP_32K_TIMER
        bool "Use 32KHz timer"
        depends on ARCH_OMAP16XX || ARCH_OMAP2PLUS
+       default y if (ARCH_OMAP16XX || ARCH_OMAP2PLUS)
        help
          Select this option if you want to enable the OMAP 32KHz timer.
          This timer saves power compared to the OMAP_MPU_TIMER, and has
@@ -165,8 +163,6 @@ config OMAP_32K_TIMER
          intra-tick resolution than OMAP_MPU_TIMER. The 32KHz timer is
          currently only available for OMAP16XX, 24XX, 34XX and OMAP4.
 
-endchoice
-
 config OMAP3_L2_AUX_SECURE_SAVE_RESTORE
        bool "OMAP3 HS/EMU save and restore for L2 AUX control register"
        depends on ARCH_OMAP3 && PM
index ea4644021fb9c0867c2e4ca4bd4bcb118e863f80..862dda95d61d2085c2bbc5e77b866f166b1e4ca3 100644 (file)
@@ -36,8 +36,6 @@
 
 #define OMAP16XX_TIMER_32K_SYNCHRONIZED                0xfffbc410
 
-#if !(defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP15XX))
-
 #include <linux/clocksource.h>
 
 /*
@@ -122,12 +120,24 @@ static DEFINE_CLOCK_DATA(cd);
 #define SC_MULT                4000000000u
 #define SC_SHIFT       17
 
-unsigned long long notrace sched_clock(void)
+static inline unsigned long long notrace _omap_32k_sched_clock(void)
 {
        u32 cyc = clocksource_32k.read(&clocksource_32k);
        return cyc_to_fixed_sched_clock(&cd, cyc, (u32)~0, SC_MULT, SC_SHIFT);
 }
 
+#ifndef CONFIG_OMAP_MPU_TIMER
+unsigned long long notrace sched_clock(void)
+{
+       return _omap_32k_sched_clock();
+}
+#else
+unsigned long long notrace omap_32k_sched_clock(void)
+{
+       return _omap_32k_sched_clock();
+}
+#endif
+
 static void notrace omap_update_sched_clock(void)
 {
        u32 cyc = clocksource_32k.read(&clocksource_32k);
@@ -160,7 +170,7 @@ void read_persistent_clock(struct timespec *ts)
        *ts = *tsp;
 }
 
-static int __init omap_init_clocksource_32k(void)
+int __init omap_init_clocksource_32k(void)
 {
        static char err[] __initdata = KERN_ERR
                        "%s: can't register clocksource!\n";
@@ -195,7 +205,3 @@ static int __init omap_init_clocksource_32k(void)
        }
        return 0;
 }
-arch_initcall(omap_init_clocksource_32k);
-
-#endif /* !(defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP15XX)) */
-
index c4b2b478b1a544e6ef768c3f3e6a3543ca37119c..85363084cc1a366f28417c9df6a7b914d7274e69 100644 (file)
@@ -53,7 +53,7 @@ enum { DMA_CHAIN_STARTED, DMA_CHAIN_NOTSTARTED };
 #endif
 
 #define OMAP_DMA_ACTIVE                        0x01
-#define OMAP2_DMA_CSR_CLEAR_MASK       0xffe
+#define OMAP2_DMA_CSR_CLEAR_MASK       0xffffffff
 
 #define OMAP_FUNC_MUX_ARM_BASE         (0xfffe1000 + 0xec)
 
@@ -1873,7 +1873,7 @@ static int omap2_dma_handle_ch(int ch)
                printk(KERN_INFO "DMA misaligned error with device %d\n",
                       dma_chan[ch].dev_id);
 
-       p->dma_write(OMAP2_DMA_CSR_CLEAR_MASK, CSR, ch);
+       p->dma_write(status, CSR, ch);
        p->dma_write(1 << ch, IRQSTATUS_L0, ch);
        /* read back the register to flush the write */
        p->dma_read(IRQSTATUS_L0, ch);
@@ -1893,10 +1893,9 @@ static int omap2_dma_handle_ch(int ch)
                        OMAP_DMA_CHAIN_INCQHEAD(chain_id);
 
                status = p->dma_read(CSR, ch);
+               p->dma_write(status, CSR, ch);
        }
 
-       p->dma_write(status, CSR, ch);
-
        if (likely(dma_chan[ch].callback != NULL))
                dma_chan[ch].callback(ch, status, dma_chan[ch].data);
 
index 6b8088ec74af9ae775988a5abe33fa085bc92ce2..29b2afb4288f2bde34d42659e461791027e6e4fc 100644 (file)
@@ -35,6 +35,9 @@ struct sys_timer;
 
 extern void omap_map_common_io(void);
 extern struct sys_timer omap_timer;
+extern bool omap_32k_timer_init(void);
+extern int __init omap_init_clocksource_32k(void);
+extern unsigned long long notrace omap_32k_sched_clock(void);
 
 extern void omap_reserve(void);
 
index 92ecd8446ef80b6fe06c62bce45fe93a40f344bb..bc7e8ae479ee4f7f9be717cbcd38d0731773a6f9 100644 (file)
@@ -8,6 +8,7 @@
 #ifndef __ASM_AVR32_PGALLOC_H
 #define __ASM_AVR32_PGALLOC_H
 
+#include <linux/mm.h>
 #include <linux/quicklist.h>
 #include <asm/page.h>
 #include <asm/pgtable.h>
index b1577f741fa8c46789c4324662dcb87f6a6369ce..82a4bb51d5d85b4f6271b7f4a830f1150bea5b59 100644 (file)
@@ -610,17 +610,17 @@ static void amiga_mem_console_write(struct console *co, const char *s,
 
 static int __init amiga_savekmsg_setup(char *arg)
 {
-       static struct resource debug_res = { .name = "Debug" };
-
        if (!MACH_IS_AMIGA || strcmp(arg, "mem"))
-               goto done;
+               return 0;
 
-       if (!AMIGAHW_PRESENT(CHIP_RAM)) {
-               printk("Warning: no chipram present for debugging\n");
-               goto done;
+       if (amiga_chip_size < SAVEKMSG_MAXMEM) {
+               pr_err("Not enough chipram for debugging\n");
+               return -ENOMEM;
        }
 
-       savekmsg = amiga_chip_alloc_res(SAVEKMSG_MAXMEM, &debug_res);
+       /* Just steal the block, the chipram allocator isn't functional yet */
+       amiga_chip_size -= SAVEKMSG_MAXMEM;
+       savekmsg = (void *)ZTWO_VADDR(CHIP_PHYSADDR + amiga_chip_size);
        savekmsg->magic1 = SAVEKMSG_MAGIC1;
        savekmsg->magic2 = SAVEKMSG_MAGIC2;
        savekmsg->magicptr = ZTWO_PADDR(savekmsg);
@@ -628,8 +628,6 @@ static int __init amiga_savekmsg_setup(char *arg)
 
        amiga_console_driver.write = amiga_mem_console_write;
        register_console(&amiga_console_driver);
-
-done:
        return 0;
 }
 
index 39478dd08e67dd8a5d34a76fecc21bc511e1f4b2..26a804e67bced56a5d447ae66d23ce40c3e3fd97 100644 (file)
@@ -388,9 +388,9 @@ void __init atari_init_IRQ(void)
        }
 
        if (ATARIHW_PRESENT(SCC) && !atari_SCC_reset_done) {
-               scc.cha_a_ctrl = 9;
+               atari_scc.cha_a_ctrl = 9;
                MFPDELAY();
-               scc.cha_a_ctrl = (char) 0xc0; /* hardware reset */
+               atari_scc.cha_a_ctrl = (char) 0xc0; /* hardware reset */
        }
 
        if (ATARIHW_PRESENT(SCU)) {
index ae2d96e5d618eba94ed0428468ca2e9f025e983f..4203d101363cf23074e7ce0e22a6f19579bf92ba 100644 (file)
@@ -315,7 +315,7 @@ void __init config_atari(void)
                ATARIHW_SET(SCC_DMA);
                printk("SCC_DMA ");
        }
-       if (scc_test(&scc.cha_a_ctrl)) {
+       if (scc_test(&atari_scc.cha_a_ctrl)) {
                ATARIHW_SET(SCC);
                printk("SCC ");
        }
index 28efdc33c1aeab89afde05ff5249ba5bdf2f20ac..5a484247e493ebb8b6f9be142cdcdfe0db978c92 100644 (file)
@@ -53,9 +53,9 @@ static inline void ata_scc_out(char c)
 {
        do {
                MFPDELAY();
-       } while (!(scc.cha_b_ctrl & 0x04)); /* wait for tx buf empty */
+       } while (!(atari_scc.cha_b_ctrl & 0x04)); /* wait for tx buf empty */
        MFPDELAY();
-       scc.cha_b_data = c;
+       atari_scc.cha_b_data = c;
 }
 
 static void atari_scc_console_write(struct console *co, const char *str,
@@ -140,9 +140,9 @@ int atari_scc_console_wait_key(struct console *co)
 {
        do {
                MFPDELAY();
-       } while (!(scc.cha_b_ctrl & 0x01)); /* wait for rx buf filled */
+       } while (!(atari_scc.cha_b_ctrl & 0x01)); /* wait for rx buf filled */
        MFPDELAY();
-       return scc.cha_b_data;
+       return atari_scc.cha_b_data;
 }
 
 int atari_midi_console_wait_key(struct console *co)
@@ -185,9 +185,9 @@ static void __init atari_init_mfp_port(int cflag)
 
 #define SCC_WRITE(reg, val)                            \
        do {                                            \
-               scc.cha_b_ctrl = (reg);                 \
+               atari_scc.cha_b_ctrl = (reg);           \
                MFPDELAY();                             \
-               scc.cha_b_ctrl = (val);                 \
+               atari_scc.cha_b_ctrl = (val);           \
                MFPDELAY();                             \
        } while (0)
 
@@ -240,7 +240,7 @@ static void __init atari_init_scc_port(int cflag)
        reg3 = (cflag & CSIZE) == CS8 ? 0xc0 : 0x40;
        reg5 = (cflag & CSIZE) == CS8 ? 0x60 : 0x20 | 0x82 /* assert DTR/RTS */;
 
-       (void)scc.cha_b_ctrl;           /* reset reg pointer */
+       (void)atari_scc.cha_b_ctrl;     /* reset reg pointer */
        SCC_WRITE(9, 0xc0);             /* reset */
        LONG_DELAY();                   /* extra delay after WR9 access */
        SCC_WRITE(4, (cflag & PARENB) ? ((cflag & PARODD) ? 0x01 : 0x03)
index a714e1aa072a0e4bf4981894ed2c00b71ce7ca6c..f51f709bbf3036f8ee7438eafe64226c1c02b043 100644 (file)
@@ -449,7 +449,7 @@ struct SCC
   u_char char_dummy3;
   u_char cha_b_data;
  };
-# define scc ((*(volatile struct SCC*)SCC_BAS))
+# define atari_scc ((*(volatile struct SCC*)SCC_BAS))
 
 /* The ESCC (Z85230) in an Atari ST. The channels are reversed! */
 # define st_escc ((*(volatile struct SCC*)0xfffffa31))
index 2936dda938d78d057c2f8c9c7b370b4cf79cb4c6..65b131282837c93c9c1accc198815b2d67532ade 100644 (file)
@@ -81,18 +81,6 @@ static inline char *strncpy(char *dest, const char *src, size_t n)
        strcpy(__d + strlen(__d), (s));         \
 })
 
-#define __HAVE_ARCH_STRCHR
-static inline char *strchr(const char *s, int c)
-{
-       char sc, ch = c;
-
-       for (; (sc = *s++) != ch; ) {
-               if (!sc)
-                       return NULL;
-       }
-       return (char *)s - 1;
-}
-
 #ifndef CONFIG_COLDFIRE
 #define __HAVE_ARCH_STRCMP
 static inline int strcmp(const char *cs, const char *ct)
index 42434008209eaffdeb3db74518db24d2d088512b..0db20b5abb54e44489362d2bcc53e2600ccb8ad5 100644 (file)
@@ -77,8 +77,18 @@ real_start:
    We ensure r7 points to a valid FDT, just in case the bootloader
    is broken or non-existent */
        beqi    r7, no_fdt_arg                  /* NULL pointer?  don't copy */
-       lw      r11, r0, r7                     /* Does r7 point to a */
-       rsubi   r11, r11, OF_DT_HEADER          /* valid FDT? */
+/* Does r7 point to a valid FDT? Load HEADER magic number */
+       /* Run time Big/Little endian platform */
+       /* Save 1 as word and load byte - 0 - BIG, 1 - LITTLE */
+       addik   r11, r0, 0x1 /* BIG/LITTLE checking value */
+       /* __bss_start will be zeroed later - it is just temp location */
+       swi     r11, r0, TOPHYS(__bss_start)
+       lbui    r11, r0, TOPHYS(__bss_start)
+       beqid   r11, big_endian /* DO NOT break delay stop dependency */
+       lw      r11, r0, r7 /* Big endian load in delay slot */
+       lwr     r11, r0, r7 /* Little endian load */
+big_endian:
+       rsubi   r11, r11, OF_DT_HEADER  /* Check FDT header */
        beqi    r11, _prepare_copy_fdt
        or      r7, r0, r0              /* clear R7 when not valid DTB */
        bnei    r11, no_fdt_arg                 /* No - get out of here */
index 25f6e07d8de883c701a8113da277b56f3a9f86de..782680de312178cf014d818ec0f4f58550000692 100644 (file)
        #if CONFIG_XILINX_MICROBLAZE0_USE_BARREL > 0
        #define BSRLI(rD, rA, imm)      \
                bsrli rD, rA, imm
-       #elif CONFIG_XILINX_MICROBLAZE0_USE_DIV > 0
-       #define BSRLI(rD, rA, imm)      \
-               ori rD, r0, (1 << imm); \
-               idivu rD, rD, rA
        #else
        #define BSRLI(rD, rA, imm) BSRLI ## imm (rD, rA)
        /* Only the used shift constants defined here - add more if needed */
index fdc48bb065d89fe3b2443ef054d1a6ece3744b54..62021d7e249e0665cd6a1483c12de5b8b0bf5739 100644 (file)
  *     between mem locations with size of xfer spec'd in bytes
  */
 
+#ifdef __MICROBLAZEEL__
+#error Microblaze LE not support ASM optimized lib func. Disable OPT_LIB_ASM.
+#endif
+
 #include <linux/linkage.h>
        .text
        .globl  memcpy
index 11bdd68e576239bffe235dc8b4b3d3a38709beed..fc770be465ff648cb6e5d33dc883e1782531613a 100644 (file)
@@ -169,11 +169,11 @@ static int __init pdc_console_tty_driver_init(void)
 
        struct console *tmp;
 
-       acquire_console_sem();
+       console_lock();
        for_each_console(tmp)
                if (tmp == &pdc_cons)
                        break;
-       release_console_sem();
+       console_unlock();
 
        if (!tmp) {
                printk(KERN_INFO "PDC console driver not registered anymore, not creating %s\n", pdc_cons.name);
index 4dcf5f831e9d01f8694443ac7d56146b6f7a9777..b0dc8f7069cd5fb7bb41ec8b2a3bd9a046f3f57e 100644 (file)
@@ -596,6 +596,7 @@ static void record_and_restart(struct perf_event *event, unsigned long val,
                        if (left <= 0)
                                left = period;
                        record = 1;
+                       event->hw.last_period = event->hw.sample_period;
                }
                if (left < 0x80000000LL)
                        val = 0x80000000LL - left;
index ff19efdf6feff6995bdfa57067e65b616c386ae8..636bcb81d06866b400ddb9754b0bff3c4ef2213d 100644 (file)
@@ -406,7 +406,7 @@ config QDIO
          If unsure, say Y.
 
 config CHSC_SCH
-       def_tristate y
+       def_tristate m
        prompt "Support for CHSC subchannels"
        help
          This driver allows usage of CHSC subchannels. A CHSC subchannel
index 405cc97c624900e41825368df09323b3c9add045..7e1f776206248033025a1bd50779acd5be1225c6 100644 (file)
@@ -1,29 +1,8 @@
 #ifndef _S390_CACHEFLUSH_H
 #define _S390_CACHEFLUSH_H
 
-/* Keep includes the same across arches.  */
-#include <linux/mm.h>
-
 /* Caches aren't brain-dead on the s390. */
-#define flush_cache_all()                      do { } while (0)
-#define flush_cache_mm(mm)                     do { } while (0)
-#define flush_cache_dup_mm(mm)                 do { } while (0)
-#define flush_cache_range(vma, start, end)     do { } while (0)
-#define flush_cache_page(vma, vmaddr, pfn)     do { } while (0)
-#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 0
-#define flush_dcache_page(page)                        do { } while (0)
-#define flush_dcache_mmap_lock(mapping)                do { } while (0)
-#define flush_dcache_mmap_unlock(mapping)      do { } while (0)
-#define flush_icache_range(start, end)         do { } while (0)
-#define flush_icache_page(vma,pg)              do { } while (0)
-#define flush_icache_user_range(vma,pg,adr,len)        do { } while (0)
-#define flush_cache_vmap(start, end)           do { } while (0)
-#define flush_cache_vunmap(start, end)         do { } while (0)
-
-#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
-       memcpy(dst, src, len)
-#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
-       memcpy(dst, src, len)
+#include <asm-generic/cacheflush.h>
 
 #ifdef CONFIG_DEBUG_PAGEALLOC
 void kernel_map_pages(struct page *page, int numpages, int enable);
index f1f644f2240a5cd377042a7dfe63bf546fde6da5..9074a54c4d10f843320ae85819895024dbf5d67f 100644 (file)
@@ -22,6 +22,7 @@
  */
 
 #include <linux/mm.h>
+#include <linux/pagemap.h>
 #include <linux/swap.h>
 #include <asm/processor.h>
 #include <asm/pgalloc.h>
index 07deaeee14c833e20557d5a57f4799c9de261944..a6c4f7ed24a493d1e0ea5fde43b19dc5b0fe37f2 100644 (file)
@@ -125,9 +125,9 @@ static size_t copy_in_user_std(size_t size, void __user *to,
        unsigned long tmp1;
 
        asm volatile(
+               "   sacf  256\n"
                "  "AHI"  %0,-1\n"
                "   jo    5f\n"
-               "   sacf  256\n"
                "   bras  %3,3f\n"
                "0:"AHI"  %0,257\n"
                "1: mvc   0(1,%1),0(%2)\n"
@@ -142,9 +142,8 @@ static size_t copy_in_user_std(size_t size, void __user *to,
                "3:"AHI"  %0,-256\n"
                "   jnm   2b\n"
                "4: ex    %0,1b-0b(%3)\n"
-               "   sacf  0\n"
                "5: "SLR"  %0,%0\n"
-               "6:\n"
+               "6: sacf  0\n"
                EX_TABLE(1b,6b) EX_TABLE(2b,0b) EX_TABLE(4b,0b)
                : "+a" (size), "+a" (to), "+a" (from), "=a" (tmp1)
                : : "cc", "memory");
@@ -156,9 +155,9 @@ static size_t clear_user_std(size_t size, void __user *to)
        unsigned long tmp1, tmp2;
 
        asm volatile(
+               "   sacf  256\n"
                "  "AHI"  %0,-1\n"
                "   jo    5f\n"
-               "   sacf  256\n"
                "   bras  %3,3f\n"
                "   xc    0(1,%1),0(%1)\n"
                "0:"AHI"  %0,257\n"
@@ -178,9 +177,8 @@ static size_t clear_user_std(size_t size, void __user *to)
                "3:"AHI"  %0,-256\n"
                "   jnm   2b\n"
                "4: ex    %0,0(%3)\n"
-               "   sacf  0\n"
                "5: "SLR"  %0,%0\n"
-               "6:\n"
+               "6: sacf  0\n"
                EX_TABLE(1b,6b) EX_TABLE(2b,0b) EX_TABLE(4b,0b)
                : "+a" (size), "+a" (to), "=a" (tmp1), "=a" (tmp2)
                : : "cc", "memory");
index 0c719c61972e5d95d52e4151b298659b57239845..e1850c28cd68453b2bde08189269e21702b3aa42 100644 (file)
@@ -336,7 +336,8 @@ void page_table_free(struct mm_struct *mm, unsigned long *table)
        page->flags ^= bits;
        if (page->flags & FRAG_MASK) {
                /* Page now has some free pgtable fragments. */
-               list_move(&page->lru, &mm->context.pgtable_list);
+               if (!list_empty(&page->lru))
+                       list_move(&page->lru, &mm->context.pgtable_list);
                page = NULL;
        } else
                /* All fragments of the 4K page have been freed. */
index ae555569823b7686252ea1da69ecd465bc2d1808..8a9011dced149cd754fe6c0b1f0053a56a13dff0 100644 (file)
@@ -15,6 +15,7 @@ config SUPERH
        select HAVE_KERNEL_GZIP
        select HAVE_KERNEL_BZIP2
        select HAVE_KERNEL_LZMA
+       select HAVE_KERNEL_XZ
        select HAVE_KERNEL_LZO
        select HAVE_SYSCALL_TRACEPOINTS
        select HAVE_REGS_AND_STACK_ACCESS_API
index 9c8c6e1a2a154d4dff50db8d0d532201c5f991be..e3d8170ad00b98a8739d572fea653c22582a6953 100644 (file)
@@ -200,7 +200,7 @@ endif
 libs-$(CONFIG_SUPERH32)                := arch/sh/lib/ $(libs-y)
 libs-$(CONFIG_SUPERH64)                := arch/sh/lib64/ $(libs-y)
 
-BOOT_TARGETS = uImage uImage.bz2 uImage.gz uImage.lzma uImage.lzo \
+BOOT_TARGETS = uImage uImage.bz2 uImage.gz uImage.lzma uImage.xz uImage.lzo \
               uImage.srec uImage.bin zImage vmlinux.bin vmlinux.srec \
               romImage
 PHONY += $(BOOT_TARGETS)
@@ -230,5 +230,6 @@ define archhelp
        @echo '* uImage.gz                 - Kernel-only image for U-Boot (gzip)'
        @echo '  uImage.bz2                - Kernel-only image for U-Boot (bzip2)'
        @echo '  uImage.lzma               - Kernel-only image for U-Boot (lzma)'
+       @echo '  uImage.xz                 - Kernel-only image for U-Boot (xz)'
        @echo '  uImage.lzo                - Kernel-only image for U-Boot (lzo)'
 endef
index 33b662999fc66b68b8fbe5f1893aa5ce675e5d0c..701667acfd89e919f15202ef2161f445e15e0c93 100644 (file)
@@ -1294,6 +1294,7 @@ static int __init arch_setup(void)
        i2c_register_board_info(1, i2c1_devices,
                                ARRAY_SIZE(i2c1_devices));
 
+#if defined(CONFIG_VIDEO_SH_VOU) || defined(CONFIG_VIDEO_SH_VOU_MODULE)
        /* VOU */
        gpio_request(GPIO_FN_DV_D15, NULL);
        gpio_request(GPIO_FN_DV_D14, NULL);
@@ -1325,6 +1326,7 @@ static int __init arch_setup(void)
 
        /* Remove reset */
        gpio_set_value(GPIO_PTG4, 1);
+#endif
 
        return platform_add_devices(ecovec_devices,
                                    ARRAY_SIZE(ecovec_devices));
index 1ce63624c9b9c8140a1eb9d348442b7fa2d560e8..ba515d8002457546db2e5138bbb229dbd39cb8e2 100644 (file)
@@ -24,12 +24,13 @@ suffix-y := bin
 suffix-$(CONFIG_KERNEL_GZIP)   := gz
 suffix-$(CONFIG_KERNEL_BZIP2)  := bz2
 suffix-$(CONFIG_KERNEL_LZMA)   := lzma
+suffix-$(CONFIG_KERNEL_XZ)     := xz
 suffix-$(CONFIG_KERNEL_LZO)    := lzo
 
 targets := zImage vmlinux.srec romImage uImage uImage.srec uImage.gz \
-          uImage.bz2 uImage.lzma uImage.lzo uImage.bin
+          uImage.bz2 uImage.lzma uImage.xz uImage.lzo uImage.bin
 extra-y += vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma \
-          vmlinux.bin.lzo
+          vmlinux.bin.xz vmlinux.bin.lzo
 subdir- := compressed romimage
 
 $(obj)/zImage: $(obj)/compressed/vmlinux FORCE
@@ -76,6 +77,9 @@ $(obj)/vmlinux.bin.bz2: $(obj)/vmlinux.bin FORCE
 $(obj)/vmlinux.bin.lzma: $(obj)/vmlinux.bin FORCE
        $(call if_changed,lzma)
 
+$(obj)/vmlinux.bin.xz: $(obj)/vmlinux.bin FORCE
+       $(call if_changed,xzkern)
+
 $(obj)/vmlinux.bin.lzo: $(obj)/vmlinux.bin FORCE
        $(call if_changed,lzo)
 
@@ -88,6 +92,9 @@ $(obj)/uImage.gz: $(obj)/vmlinux.bin.gz
 $(obj)/uImage.lzma: $(obj)/vmlinux.bin.lzma
        $(call if_changed,uimage,lzma)
 
+$(obj)/uImage.xz: $(obj)/vmlinux.bin.xz
+       $(call if_changed,uimage,xz)
+
 $(obj)/uImage.lzo: $(obj)/vmlinux.bin.lzo
        $(call if_changed,uimage,lzo)
 
index cfa5a087a886f5e9fa7ee5e90dd467e5003cc041..e0b0293bae63e5240e0df723b3725fbba52a7af2 100644 (file)
@@ -6,7 +6,7 @@
 
 targets                := vmlinux vmlinux.bin vmlinux.bin.gz \
                   vmlinux.bin.bz2 vmlinux.bin.lzma \
-                  vmlinux.bin.lzo \
+                  vmlinux.bin.xz vmlinux.bin.lzo \
                   head_$(BITS).o misc.o piggy.o
 
 OBJECTS = $(obj)/head_$(BITS).o $(obj)/misc.o $(obj)/cache.o
@@ -50,6 +50,8 @@ $(obj)/vmlinux.bin.bz2: $(vmlinux.bin.all-y) FORCE
        $(call if_changed,bzip2)
 $(obj)/vmlinux.bin.lzma: $(vmlinux.bin.all-y) FORCE
        $(call if_changed,lzma)
+$(obj)/vmlinux.bin.xz: $(vmlinux.bin.all-y) FORCE
+       $(call if_changed,xzkern)
 $(obj)/vmlinux.bin.lzo: $(vmlinux.bin.all-y) FORCE
        $(call if_changed,lzo)
 
index 27140a6b365d60b610c25ddc21d38e709cd4cc23..95470a472d2cf793ddad131f55805385a514e65f 100644 (file)
@@ -61,6 +61,10 @@ static unsigned long free_mem_end_ptr;
 #include "../../../../lib/decompress_unlzma.c"
 #endif
 
+#ifdef CONFIG_KERNEL_XZ
+#include "../../../../lib/decompress_unxz.c"
+#endif
+
 #ifdef CONFIG_KERNEL_LZO
 #include "../../../../lib/decompress_unlzo.c"
 #endif
index 083ea068e819e80a389d5610bc9e19243d4ed950..db85916b9e95aa8def960feff9b7b9ca1a5549f4 100644 (file)
@@ -134,6 +134,7 @@ typedef pte_t *pte_addr_t;
 extern void pgtable_cache_init(void);
 
 struct vm_area_struct;
+struct mm_struct;
 
 extern void __update_cache(struct vm_area_struct *vma,
                           unsigned long address, pte_t pte);
index c2b0aaaedcaedd4e70249230b816db082ce734fe..672944f5b19c63031f128232345360869ff6a558 100644 (file)
@@ -230,10 +230,10 @@ static struct platform_device *sh7750_devices[] __initdata = {
 static int __init sh7750_devices_setup(void)
 {
        if (mach_is_rts7751r2d()) {
-               platform_register_device(&scif_device);
+               platform_device_register(&scif_device);
        } else {
-               platform_register_device(&sci_device);
-               platform_register_device(&scif_device);
+               platform_device_register(&sci_device);
+               platform_device_register(&scif_device);
        }
 
        return platform_add_devices(sh7750_devices,
index 948fdb65693384826b77dbc6024a93bcb88246bd..38e862852dd0ce3fbcd10e9291c09fd35e6699d4 100644 (file)
@@ -17,6 +17,7 @@
 static DEFINE_PER_CPU(struct cpu, cpu_devices);
 
 cpumask_t cpu_core_map[NR_CPUS];
+EXPORT_SYMBOL(cpu_core_map);
 
 static cpumask_t cpu_coregroup_map(unsigned int cpu)
 {
index 63e35ec9075ca4ff6b813d946463655d905a5c60..62f084478f7e08448050cac33152f8f62bed8b72 100644 (file)
@@ -1,48 +1,8 @@
 #ifndef _ASM_X86_CACHEFLUSH_H
 #define _ASM_X86_CACHEFLUSH_H
 
-/* Keep includes the same across arches.  */
-#include <linux/mm.h>
-
 /* Caches aren't brain-dead on the intel. */
-static inline void flush_cache_all(void) { }
-static inline void flush_cache_mm(struct mm_struct *mm) { }
-static inline void flush_cache_dup_mm(struct mm_struct *mm) { }
-static inline void flush_cache_range(struct vm_area_struct *vma,
-                                    unsigned long start, unsigned long end) { }
-static inline void flush_cache_page(struct vm_area_struct *vma,
-                                   unsigned long vmaddr, unsigned long pfn) { }
-#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 0
-static inline void flush_dcache_page(struct page *page) { }
-static inline void flush_dcache_mmap_lock(struct address_space *mapping) { }
-static inline void flush_dcache_mmap_unlock(struct address_space *mapping) { }
-static inline void flush_icache_range(unsigned long start,
-                                     unsigned long end) { }
-static inline void flush_icache_page(struct vm_area_struct *vma,
-                                    struct page *page) { }
-static inline void flush_icache_user_range(struct vm_area_struct *vma,
-                                          struct page *page,
-                                          unsigned long addr,
-                                          unsigned long len) { }
-static inline void flush_cache_vmap(unsigned long start, unsigned long end) { }
-static inline void flush_cache_vunmap(unsigned long start,
-                                     unsigned long end) { }
-
-static inline void copy_to_user_page(struct vm_area_struct *vma,
-                                    struct page *page, unsigned long vaddr,
-                                    void *dst, const void *src,
-                                    unsigned long len)
-{
-       memcpy(dst, src, len);
-}
-
-static inline void copy_from_user_page(struct vm_area_struct *vma,
-                                      struct page *page, unsigned long vaddr,
-                                      void *dst, const void *src,
-                                      unsigned long len)
-{
-       memcpy(dst, src, len);
-}
+#include <asm-generic/cacheflush.h>
 
 #ifdef CONFIG_X86_PAT
 /*
index 4fab24de26b18404069994b908c79d3e4e481c50..6e6e7558e702cbdeb56a5fb7c5e048cb82f15e9b 100644 (file)
@@ -32,5 +32,6 @@ extern void arch_unregister_cpu(int);
 
 DECLARE_PER_CPU(int, cpu_state);
 
+int __cpuinit mwait_usable(const struct cpuinfo_x86 *);
 
 #endif /* _ASM_X86_CPU_H */
index f52d42e805853ea09532a86aca6290410bb2d83b..574dbc22893a9301914def19c5004b9ec1b851fe 100644 (file)
@@ -14,7 +14,7 @@
        do {                                                    \
                asm goto("1:"                                   \
                        JUMP_LABEL_INITIAL_NOP                  \
-                       ".pushsection __jump_table,  \"a\" \n\t"\
+                       ".pushsection __jump_table,  \"aw\" \n\t"\
                        _ASM_PTR "1b, %l[" #label "], %c0 \n\t" \
                        ".popsection \n\t"                      \
                        : :  "i" (key) :  : label);             \
index 2071a8b2b32f2fb35a40637f4cf4aa14db7dc35b..ebbc4d8ab1709e9427394f793af878cdd5cf9e66 100644 (file)
@@ -558,13 +558,12 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
 static inline void set_pmd_at(struct mm_struct *mm, unsigned long addr,
                              pmd_t *pmdp, pmd_t pmd)
 {
-#if PAGETABLE_LEVELS >= 3
        if (sizeof(pmdval_t) > sizeof(long))
                /* 5 arg words */
                pv_mmu_ops.set_pmd_at(mm, addr, pmdp, pmd);
        else
-               PVOP_VCALL4(pv_mmu_ops.set_pmd_at, mm, addr, pmdp, pmd.pmd);
-#endif
+               PVOP_VCALL4(pv_mmu_ops.set_pmd_at, mm, addr, pmdp,
+                           native_pmd_val(pmd));
 }
 #endif
 
index 3788f4649db45427e80fd5a170942a984fe61514..7e172955ee57cf9b410d77cddda53c6c5daf6f12 100644 (file)
@@ -273,34 +273,34 @@ do {                                                                      \
        typeof(var) pxo_new__ = (nval);                                 \
        switch (sizeof(var)) {                                          \
        case 1:                                                         \
-               asm("\n1:mov "__percpu_arg(1)",%%al"                    \
-                   "\n\tcmpxchgb %2, "__percpu_arg(1)                  \
+               asm("\n\tmov "__percpu_arg(1)",%%al"                    \
+                   "\n1:\tcmpxchgb %2, "__percpu_arg(1)                \
                    "\n\tjnz 1b"                                        \
-                           : "=a" (pxo_ret__), "+m" (var)              \
+                           : "=&a" (pxo_ret__), "+m" (var)             \
                            : "q" (pxo_new__)                           \
                            : "memory");                                \
                break;                                                  \
        case 2:                                                         \
-               asm("\n1:mov "__percpu_arg(1)",%%ax"                    \
-                   "\n\tcmpxchgw %2, "__percpu_arg(1)                  \
+               asm("\n\tmov "__percpu_arg(1)",%%ax"                    \
+                   "\n1:\tcmpxchgw %2, "__percpu_arg(1)                \
                    "\n\tjnz 1b"                                        \
-                           : "=a" (pxo_ret__), "+m" (var)              \
+                           : "=&a" (pxo_ret__), "+m" (var)             \
                            : "r" (pxo_new__)                           \
                            : "memory");                                \
                break;                                                  \
        case 4:                                                         \
-               asm("\n1:mov "__percpu_arg(1)",%%eax"                   \
-                   "\n\tcmpxchgl %2, "__percpu_arg(1)                  \
+               asm("\n\tmov "__percpu_arg(1)",%%eax"                   \
+                   "\n1:\tcmpxchgl %2, "__percpu_arg(1)                \
                    "\n\tjnz 1b"                                        \
-                           : "=a" (pxo_ret__), "+m" (var)              \
+                           : "=&a" (pxo_ret__), "+m" (var)             \
                            : "r" (pxo_new__)                           \
                            : "memory");                                \
                break;                                                  \
        case 8:                                                         \
-               asm("\n1:mov "__percpu_arg(1)",%%rax"                   \
-                   "\n\tcmpxchgq %2, "__percpu_arg(1)                  \
+               asm("\n\tmov "__percpu_arg(1)",%%rax"                   \
+                   "\n1:\tcmpxchgq %2, "__percpu_arg(1)                \
                    "\n\tjnz 1b"                                        \
-                           : "=a" (pxo_ret__), "+m" (var)              \
+                           : "=&a" (pxo_ret__), "+m" (var)             \
                            : "r" (pxo_new__)                           \
                            : "memory");                                \
                break;                                                  \
diff --git a/arch/x86/include/asm/system_64.h b/arch/x86/include/asm/system_64.h
deleted file mode 100644 (file)
index 1159e09..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-#ifndef _ASM_X86_SYSTEM_64_H
-#define _ASM_X86_SYSTEM_64_H
-
-#include <asm/segment.h>
-#include <asm/cmpxchg.h>
-
-
-static inline unsigned long read_cr8(void)
-{
-       unsigned long cr8;
-       asm volatile("movq %%cr8,%0" : "=r" (cr8));
-       return cr8;
-}
-
-static inline void write_cr8(unsigned long val)
-{
-       asm volatile("movq %0,%%cr8" :: "r" (val) : "memory");
-}
-
-#include <linux/irqflags.h>
-
-#endif /* _ASM_X86_SYSTEM_64_H */
index 7283e98deaae14ca8f712acf3759f11cf7e9fc2b..ec2c19a7b8efe4cc366ac709072460f0023ef296 100644 (file)
@@ -45,6 +45,7 @@ static const struct _cache_table __cpuinitconst cache_table[] =
        { 0x0a, LVL_1_DATA, 8 },        /* 2 way set assoc, 32 byte line size */
        { 0x0c, LVL_1_DATA, 16 },       /* 4-way set assoc, 32 byte line size */
        { 0x0d, LVL_1_DATA, 16 },       /* 4-way set assoc, 64 byte line size */
+       { 0x0e, LVL_1_DATA, 24 },       /* 6-way set assoc, 64 byte line size */
        { 0x21, LVL_2,      256 },      /* 8-way set assoc, 64 byte line size */
        { 0x22, LVL_3,      512 },      /* 4-way set assoc, sectored cache, 64 byte line size */
        { 0x23, LVL_3,      MB(1) },    /* 8-way set assoc, sectored cache, 64 byte line size */
@@ -66,6 +67,7 @@ static const struct _cache_table __cpuinitconst cache_table[] =
        { 0x45, LVL_2,      MB(2) },    /* 4-way set assoc, 32 byte line size */
        { 0x46, LVL_3,      MB(4) },    /* 4-way set assoc, 64 byte line size */
        { 0x47, LVL_3,      MB(8) },    /* 8-way set assoc, 64 byte line size */
+       { 0x48, LVL_2,      MB(3) },    /* 12-way set assoc, 64 byte line size */
        { 0x49, LVL_3,      MB(4) },    /* 16-way set assoc, 64 byte line size */
        { 0x4a, LVL_3,      MB(6) },    /* 12-way set assoc, 64 byte line size */
        { 0x4b, LVL_3,      MB(8) },    /* 16-way set assoc, 64 byte line size */
@@ -87,6 +89,7 @@ static const struct _cache_table __cpuinitconst cache_table[] =
        { 0x7c, LVL_2,      MB(1) },    /* 8-way set assoc, sectored cache, 64 byte line size */
        { 0x7d, LVL_2,      MB(2) },    /* 8-way set assoc, 64 byte line size */
        { 0x7f, LVL_2,      512 },      /* 2-way set assoc, 64 byte line size */
+       { 0x80, LVL_2,      512 },      /* 8-way set assoc, 64 byte line size */
        { 0x82, LVL_2,      256 },      /* 8-way set assoc, 32 byte line size */
        { 0x83, LVL_2,      512 },      /* 8-way set assoc, 32 byte line size */
        { 0x84, LVL_2,      MB(1) },    /* 8-way set assoc, 32 byte line size */
index e12246ff5aa6d2683ae8537a92da76e479a26bf7..6f8c5e9da97f0f3e4c0ac89557a3b2f1c3a5f01e 100644 (file)
@@ -59,6 +59,7 @@ struct thermal_state {
 
 /* Callback to handle core threshold interrupts */
 int (*platform_thermal_notify)(__u64 msr_val);
+EXPORT_SYMBOL(platform_thermal_notify);
 
 static DEFINE_PER_CPU(struct thermal_state, thermal_state);
 
index 64101335de19aad09ec03d75dea8260b28051747..a6b6fcf7f0aee9665e00fc2ed8d8d9290fc0423a 100644 (file)
@@ -149,13 +149,13 @@ void dump_trace(struct task_struct *task,
        unsigned used = 0;
        struct thread_info *tinfo;
        int graph = 0;
+       unsigned long dummy;
        unsigned long bp;
 
        if (!task)
                task = current;
 
        if (!stack) {
-               unsigned long dummy;
                stack = &dummy;
                if (task && task != current)
                        stack = (unsigned long *)task->thread.sp;
index d8286ed54ffaba86a0882baae443cd9d267b5a30..e764fc05d700365246d4e77f52a406bbfe1c7d22 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/utsname.h>
 #include <trace/events/power.h>
 #include <linux/hw_breakpoint.h>
+#include <asm/cpu.h>
 #include <asm/system.h>
 #include <asm/apic.h>
 #include <asm/syscalls.h>
@@ -505,7 +506,7 @@ static void poll_idle(void)
 #define MWAIT_ECX_EXTENDED_INFO                0x01
 #define MWAIT_EDX_C1                   0xf0
 
-static int __cpuinit mwait_usable(const struct cpuinfo_x86 *c)
+int __cpuinit mwait_usable(const struct cpuinfo_x86 *c)
 {
        u32 eax, ebx, ecx, edx;
 
index 763df77343dd99db4300a74304013ea685310f55..0cbe8c0b35edd290e98c989cfc48c5b4b0af350a 100644 (file)
@@ -1402,8 +1402,9 @@ static inline void mwait_play_dead(void)
        unsigned int highest_subcstate = 0;
        int i;
        void *mwait_ptr;
+       struct cpuinfo_x86 *c = __this_cpu_ptr(&cpu_info);
 
-       if (!cpu_has(__this_cpu_ptr(&cpu_info), X86_FEATURE_MWAIT))
+       if (!(cpu_has(c, X86_FEATURE_MWAIT) && mwait_usable(c)))
                return;
        if (!cpu_has(__this_cpu_ptr(&cpu_info), X86_FEATURE_CLFLSH))
                return;
index ddc81a06edb94dc2ce306eb93cb136f59b6edfef..fd12d7ce7ff93265ed620ac9ef96db2c676a6c94 100644 (file)
@@ -241,21 +241,15 @@ void __init xen_build_dynamic_phys_to_machine(void)
                 * As long as the mfn_list has enough entries to completely
                 * fill a p2m page, pointing into the array is ok. But if
                 * not the entries beyond the last pfn will be undefined.
-                * And guessing that the 'what-ever-there-is' does not take it
-                * too kindly when changing it to invalid markers, a new page
-                * is allocated, initialized and filled with the valid part.
                 */
                if (unlikely(pfn + P2M_PER_PAGE > max_pfn)) {
                        unsigned long p2midx;
-                       unsigned long *p2m = extend_brk(PAGE_SIZE, PAGE_SIZE);
-                       p2m_init(p2m);
-
-                       for (p2midx = 0; pfn + p2midx < max_pfn; p2midx++) {
-                               p2m[p2midx] = mfn_list[pfn + p2midx];
-                       }
-                       p2m_top[topidx][mididx] = p2m;
-               } else
-                       p2m_top[topidx][mididx] = &mfn_list[pfn];
+
+                       p2midx = max_pfn % P2M_PER_PAGE;
+                       for ( ; p2midx < P2M_PER_PAGE; p2midx++)
+                               mfn_list[pfn + p2midx] = INVALID_P2M_ENTRY;
+               }
+               p2m_top[topidx][mididx] = &mfn_list[pfn];
        }
 
        m2p_override_init();
index b5a7f928234b064b34a0b9d2c8d2f9d869e7c635..a8a66a50d446342128776bfae67b27a5b97dd6f4 100644 (file)
@@ -179,8 +179,13 @@ char * __init xen_memory_setup(void)
        e820.nr_map = 0;
        xen_extra_mem_start = mem_end;
        for (i = 0; i < memmap.nr_entries; i++) {
-               unsigned long long end = map[i].addr + map[i].size;
+               unsigned long long end;
 
+               /* Guard against non-page aligned E820 entries. */
+               if (map[i].type == E820_RAM)
+                       map[i].size -= (map[i].size + map[i].addr) % PAGE_SIZE;
+
+               end = map[i].addr + map[i].size;
                if (map[i].type == E820_RAM && end > mem_end) {
                        /* RAM off the end - may be partially included */
                        u64 delta = min(map[i].size, end - mem_end);
@@ -350,6 +355,7 @@ void __init xen_arch_setup(void)
        boot_cpu_data.hlt_works_ok = 1;
 #endif
        pm_idle = default_idle;
+       boot_option_idle_override = IDLE_HALT;
 
        fiddle_vdso();
 }
index 328826381a2dc38def47aba259e78da11b24b5b0..b8d96ce37fc99798af81a27a2604f890cf6c4518 100644 (file)
@@ -260,6 +260,7 @@ static const struct pci_device_id ahci_pci_tbl[] = {
        { PCI_VDEVICE(INTEL, 0x1d02), board_ahci }, /* PBG AHCI */
        { PCI_VDEVICE(INTEL, 0x1d04), board_ahci }, /* PBG RAID */
        { PCI_VDEVICE(INTEL, 0x1d06), board_ahci }, /* PBG RAID */
+       { PCI_VDEVICE(INTEL, 0x2323), board_ahci }, /* DH89xxCC AHCI */
 
        /* JMicron 360/1/3/5/6, match class to avoid IDE function */
        { PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
@@ -379,6 +380,8 @@ static const struct pci_device_id ahci_pci_tbl[] = {
        { PCI_VDEVICE(MARVELL, 0x6145), board_ahci_mv },        /* 6145 */
        { PCI_VDEVICE(MARVELL, 0x6121), board_ahci_mv },        /* 6121 */
        { PCI_DEVICE(0x1b4b, 0x9123),
+         .class = PCI_CLASS_STORAGE_SATA_AHCI,
+         .class_mask = 0xffffff,
          .driver_data = board_ahci_yes_fbs },                  /* 88se9128 */
 
        /* Promise */
index a31fe96f7de670927dd0a10f7c1abc74a89a03e6..d4e52e2148593e9fddde5884586683fc5ab14242 100644 (file)
@@ -4138,6 +4138,7 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
         * device and controller are SATA.
         */
        { "PIONEER DVD-RW  DVRTD08",    "1.00", ATA_HORKAGE_NOSETXFER },
+       { "PIONEER DVD-RW  DVR-212D",   "1.28", ATA_HORKAGE_NOSETXFER },
 
        /* End Marker */
        { }
index 5defc74973d751a6283b10ac40bc29f257abbedd..600f6353ecf8743f608260b268a5a58c6442789e 100644 (file)
@@ -1099,9 +1099,9 @@ static int ata_scsi_dev_config(struct scsi_device *sdev,
                struct request_queue *q = sdev->request_queue;
                void *buf;
 
-               /* set the min alignment and padding */
-               blk_queue_update_dma_alignment(sdev->request_queue,
-                                              ATA_DMA_PAD_SZ - 1);
+               sdev->sector_size = ATA_SECT_SIZE;
+
+               /* set DMA padding */
                blk_queue_update_dma_pad(sdev->request_queue,
                                         ATA_DMA_PAD_SZ - 1);
 
@@ -1115,13 +1115,25 @@ static int ata_scsi_dev_config(struct scsi_device *sdev,
 
                blk_queue_dma_drain(q, atapi_drain_needed, buf, ATAPI_MAX_DRAIN);
        } else {
-               /* ATA devices must be sector aligned */
                sdev->sector_size = ata_id_logical_sector_size(dev->id);
-               blk_queue_update_dma_alignment(sdev->request_queue,
-                                              sdev->sector_size - 1);
                sdev->manage_start_stop = 1;
        }
 
+       /*
+        * ata_pio_sectors() expects buffer for each sector to not cross
+        * page boundary.  Enforce it by requiring buffers to be sector
+        * aligned, which works iff sector_size is not larger than
+        * PAGE_SIZE.  ATAPI devices also need the alignment as
+        * IDENTIFY_PACKET is executed as ATA_PROT_PIO.
+        */
+       if (sdev->sector_size > PAGE_SIZE)
+               ata_dev_printk(dev, KERN_WARNING,
+                       "sector_size=%u > PAGE_SIZE, PIO may malfunction\n",
+                       sdev->sector_size);
+
+       blk_queue_update_dma_alignment(sdev->request_queue,
+                                      sdev->sector_size - 1);
+
        if (dev->flags & ATA_DFLAG_AN)
                set_bit(SDEV_EVT_MEDIA_CHANGE, sdev->supported_events);
 
index d7e57db36bc835d83c11bcfb7aea1757cf46844e..538ec38ba995d92b8516699de5e68dcf7fbe736c 100644 (file)
@@ -25,7 +25,7 @@
 #include <linux/libata.h>
 
 #define DRV_NAME       "pata_hpt366"
-#define DRV_VERSION    "0.6.9"
+#define DRV_VERSION    "0.6.10"
 
 struct hpt_clock {
        u8      xfer_mode;
@@ -160,8 +160,8 @@ static int hpt_dma_blacklisted(const struct ata_device *dev, char *modestr,
 
        while (list[i] != NULL) {
                if (!strcmp(list[i], model_num)) {
-                       printk(KERN_WARNING DRV_NAME ": %s is not supported for %s.\n",
-                               modestr, list[i]);
+                       pr_warning(DRV_NAME ": %s is not supported for %s.\n",
+                                  modestr, list[i]);
                        return 1;
                }
                i++;
index efdd18bc8663588d5db55942bea138fa353b6df6..4c5b5183225e04f244ca3638afe2d964d722f03a 100644 (file)
@@ -24,7 +24,7 @@
 #include <linux/libata.h>
 
 #define DRV_NAME       "pata_hpt37x"
-#define DRV_VERSION    "0.6.18"
+#define DRV_VERSION    "0.6.22"
 
 struct hpt_clock {
        u8      xfer_speed;
@@ -229,8 +229,8 @@ static int hpt_dma_blacklisted(const struct ata_device *dev, char *modestr,
 
        while (list[i] != NULL) {
                if (!strcmp(list[i], model_num)) {
-                       printk(KERN_WARNING DRV_NAME ": %s is not supported for %s.\n",
-                               modestr, list[i]);
+                       pr_warning(DRV_NAME ": %s is not supported for %s.\n",
+                                  modestr, list[i]);
                        return 1;
                }
                i++;
@@ -642,7 +642,6 @@ static struct ata_port_operations hpt372_port_ops = {
 static struct ata_port_operations hpt374_fn1_port_ops = {
        .inherits       = &hpt372_port_ops,
        .cable_detect   = hpt374_fn1_cable_detect,
-       .prereset       = hpt37x_pre_reset,
 };
 
 /**
@@ -803,7 +802,7 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
                .udma_mask = ATA_UDMA6,
                .port_ops = &hpt302_port_ops
        };
-       /* HPT374 - UDMA100, function 1 uses different prereset method */
+       /* HPT374 - UDMA100, function 1 uses different cable_detect method */
        static const struct ata_port_info info_hpt374_fn0 = {
                .flags = ATA_FLAG_SLAVE_POSS,
                .pio_mask = ATA_PIO4,
@@ -838,7 +837,8 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
        if (rc)
                return rc;
 
-       if (dev->device == PCI_DEVICE_ID_TTI_HPT366) {
+       switch (dev->device) {
+       case PCI_DEVICE_ID_TTI_HPT366:
                /* May be a later chip in disguise. Check */
                /* Older chips are in the HPT366 driver. Ignore them */
                if (rev < 3)
@@ -863,54 +863,50 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
                        chip_table = &hpt372;
                        break;
                default:
-                       printk(KERN_ERR "pata_hpt37x: Unknown HPT366 subtype, "
+                       pr_err(DRV_NAME ": Unknown HPT366 subtype, "
                               "please report (%d).\n", rev);
                        return -ENODEV;
                }
-       } else {
-               switch (dev->device) {
-               case PCI_DEVICE_ID_TTI_HPT372:
-                       /* 372N if rev >= 2 */
-                       if (rev >= 2)
-                               return -ENODEV;
-                       ppi[0] = &info_hpt372;
-                       chip_table = &hpt372a;
-                       break;
-               case PCI_DEVICE_ID_TTI_HPT302:
-                       /* 302N if rev > 1 */
-                       if (rev > 1)
-                               return -ENODEV;
-                       ppi[0] = &info_hpt302;
-                       /* Check this */
-                       chip_table = &hpt302;
-                       break;
-               case PCI_DEVICE_ID_TTI_HPT371:
-                       if (rev > 1)
-                               return -ENODEV;
-                       ppi[0] = &info_hpt302;
-                       chip_table = &hpt371;
-                       /*
-                        * Single channel device, master is not present
-                        * but the BIOS (or us for non x86) must mark it
-                        * absent
-                        */
-                       pci_read_config_byte(dev, 0x50, &mcr1);
-                       mcr1 &= ~0x04;
-                       pci_write_config_byte(dev, 0x50, mcr1);
-                       break;
-               case PCI_DEVICE_ID_TTI_HPT374:
-                       chip_table = &hpt374;
-                       if (!(PCI_FUNC(dev->devfn) & 1))
-                               *ppi = &info_hpt374_fn0;
-                       else
-                               *ppi = &info_hpt374_fn1;
-                       break;
-               default:
-                       printk(KERN_ERR
-                              "pata_hpt37x: PCI table is bogus, please report (%d).\n",
-                              dev->device);
-                               return -ENODEV;
-               }
+               break;
+       case PCI_DEVICE_ID_TTI_HPT372:
+               /* 372N if rev >= 2 */
+               if (rev >= 2)
+                       return -ENODEV;
+               ppi[0] = &info_hpt372;
+               chip_table = &hpt372a;
+               break;
+       case PCI_DEVICE_ID_TTI_HPT302:
+               /* 302N if rev > 1 */
+               if (rev > 1)
+                       return -ENODEV;
+               ppi[0] = &info_hpt302;
+               /* Check this */
+               chip_table = &hpt302;
+               break;
+       case PCI_DEVICE_ID_TTI_HPT371:
+               if (rev > 1)
+                       return -ENODEV;
+               ppi[0] = &info_hpt302;
+               chip_table = &hpt371;
+               /*
+                * Single channel device, master is not present but the BIOS
+                * (or us for non x86) must mark it absent
+                */
+               pci_read_config_byte(dev, 0x50, &mcr1);
+               mcr1 &= ~0x04;
+               pci_write_config_byte(dev, 0x50, mcr1);
+               break;
+       case PCI_DEVICE_ID_TTI_HPT374:
+               chip_table = &hpt374;
+               if (!(PCI_FUNC(dev->devfn) & 1))
+                       *ppi = &info_hpt374_fn0;
+               else
+                       *ppi = &info_hpt374_fn1;
+               break;
+       default:
+               pr_err(DRV_NAME ": PCI table is bogus, please report (%d).\n",
+                      dev->device);
+               return -ENODEV;
        }
        /* Ok so this is a chip we support */
 
@@ -957,8 +953,7 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
                u8 sr;
                u32 total = 0;
 
-               printk(KERN_WARNING
-                      "pata_hpt37x: BIOS has not set timing clocks.\n");
+               pr_warning(DRV_NAME ": BIOS has not set timing clocks.\n");
 
                /* This is the process the HPT371 BIOS is reported to use */
                for (i = 0; i < 128; i++) {
@@ -1014,7 +1009,7 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
                                               (f_high << 16) | f_low | 0x100);
                }
                if (adjust == 8) {
-                       printk(KERN_ERR "pata_hpt37x: DPLL did not stabilize!\n");
+                       pr_err(DRV_NAME ": DPLL did not stabilize!\n");
                        return -ENODEV;
                }
                if (dpll == 3)
@@ -1022,8 +1017,8 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
                else
                        private_data = (void *)hpt37x_timings_50;
 
-               printk(KERN_INFO "pata_hpt37x: bus clock %dMHz, using %dMHz DPLL.\n",
-                      MHz[clock_slot], MHz[dpll]);
+               pr_info(DRV_NAME ": bus clock %dMHz, using %dMHz DPLL.\n",
+                       MHz[clock_slot], MHz[dpll]);
        } else {
                private_data = (void *)chip_table->clocks[clock_slot];
                /*
@@ -1036,8 +1031,9 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
                        ppi[0] = &info_hpt370_33;
                if (clock_slot < 2 && ppi[0] == &info_hpt370a)
                        ppi[0] = &info_hpt370a_33;
-               printk(KERN_INFO "pata_hpt37x: %s using %dMHz bus clock.\n",
-                      chip_table->name, MHz[clock_slot]);
+
+               pr_info(DRV_NAME ": %s using %dMHz bus clock.\n",
+                       chip_table->name, MHz[clock_slot]);
        }
 
        /* Now kick off ATA set up */
index d2239bbdb798faba32b70f2a122ee1222052d8e8..eca68caf5f46cedece0b5127ac615f33de325808 100644 (file)
@@ -25,7 +25,7 @@
 #include <linux/libata.h>
 
 #define DRV_NAME       "pata_hpt3x2n"
-#define DRV_VERSION    "0.3.13"
+#define DRV_VERSION    "0.3.14"
 
 enum {
        HPT_PCI_FAST    =       (1 << 31),
@@ -418,7 +418,7 @@ static int hpt3x2n_pci_clock(struct pci_dev *pdev)
                u16 sr;
                u32 total = 0;
 
-               printk(KERN_WARNING "pata_hpt3x2n: BIOS clock data not set.\n");
+               pr_warning(DRV_NAME ": BIOS clock data not set.\n");
 
                /* This is the process the HPT371 BIOS is reported to use */
                for (i = 0; i < 128; i++) {
@@ -528,8 +528,7 @@ hpt372n:
                ppi[0] = &info_hpt372n;
                break;
        default:
-               printk(KERN_ERR
-                      "pata_hpt3x2n: PCI table is bogus please report (%d).\n",
+               pr_err(DRV_NAME ": PCI table is bogus, please report (%d).\n",
                       dev->device);
                return -ENODEV;
        }
@@ -579,12 +578,11 @@ hpt372n:
                pci_write_config_dword(dev, 0x5C, (f_high << 16) | f_low);
        }
        if (adjust == 8) {
-               printk(KERN_ERR "pata_hpt3x2n: DPLL did not stabilize!\n");
+               pr_err(DRV_NAME ": DPLL did not stabilize!\n");
                return -ENODEV;
        }
 
-       printk(KERN_INFO "pata_hpt37x: bus clock %dMHz, using 66MHz DPLL.\n",
-              pci_mhz);
+       pr_info(DRV_NAME ": bus clock %dMHz, using 66MHz DPLL.\n", pci_mhz);
 
        /*
         * Set our private data up. We only need a few flags
index 8cc536e49a0ae4a851b6bf42009eef01848a0023..d7d8026cde9948a562cf61f126fabd7960cafe5a 100644 (file)
@@ -610,7 +610,7 @@ static struct scsi_host_template mpc52xx_ata_sht = {
 };
 
 static struct ata_port_operations mpc52xx_ata_port_ops = {
-       .inherits               = &ata_sff_port_ops,
+       .inherits               = &ata_bmdma_port_ops,
        .sff_dev_select         = mpc52xx_ata_dev_select,
        .set_piomode            = mpc52xx_ata_set_piomode,
        .set_dmamode            = mpc52xx_ata_set_dmamode,
index bca9cb89a118b02525fbf68ad7071e755f544c5c..487a54739854780c71ebce5de87d405f4b656e5d 100644 (file)
@@ -151,7 +151,7 @@ static int fetch_stats(struct atm_dev *dev,struct idt77105_stats __user *arg,int
        spin_unlock_irqrestore(&idt77105_priv_lock, flags);
        if (arg == NULL)
                return 0;
-       return copy_to_user(arg, &PRIV(dev)->stats,
+       return copy_to_user(arg, &stats,
                    sizeof(struct idt77105_stats)) ? -EFAULT : 0;
 }
 
index 656493a5e073262dc88efc646d254abd5c3646c7..42615b419dfb5bc4f30e0f6dfb2ad607015d95b7 100644 (file)
@@ -407,12 +407,15 @@ static int rpm_suspend(struct device *dev, int rpmflags)
                goto out;
        }
 
+       /* Maybe the parent is now able to suspend. */
        if (parent && !parent->power.ignore_children && !dev->power.irq_safe) {
-               spin_unlock_irq(&dev->power.lock);
+               spin_unlock(&dev->power.lock);
 
-               pm_request_idle(parent);
+               spin_lock(&parent->power.lock);
+               rpm_idle(parent, RPM_ASYNC);
+               spin_unlock(&parent->power.lock);
 
-               spin_lock_irq(&dev->power.lock);
+               spin_lock(&dev->power.lock);
        }
 
  out:
index 949ed09c6361130c30c3ebda1bc4db02b00fa4c2..a126e614601fdea6f07043026dab6b3c8e07a24e 100644 (file)
@@ -47,46 +47,40 @@ MODULE_DEVICE_TABLE(usb, ath3k_table);
 #define USB_REQ_DFU_DNLOAD     1
 #define BULK_SIZE              4096
 
-struct ath3k_data {
-       struct usb_device *udev;
-       u8 *fw_data;
-       u32 fw_size;
-       u32 fw_sent;
-};
-
-static int ath3k_load_firmware(struct ath3k_data *data,
-                               unsigned char *firmware,
-                               int count)
+static int ath3k_load_firmware(struct usb_device *udev,
+                               const struct firmware *firmware)
 {
        u8 *send_buf;
        int err, pipe, len, size, sent = 0;
+       int count = firmware->size;
 
-       BT_DBG("ath3k %p udev %p", data, data->udev);
+       BT_DBG("udev %p", udev);
 
-       pipe = usb_sndctrlpipe(data->udev, 0);
+       pipe = usb_sndctrlpipe(udev, 0);
 
-       if ((usb_control_msg(data->udev, pipe,
+       send_buf = kmalloc(BULK_SIZE, GFP_ATOMIC);
+       if (!send_buf) {
+               BT_ERR("Can't allocate memory chunk for firmware");
+               return -ENOMEM;
+       }
+
+       memcpy(send_buf, firmware->data, 20);
+       if ((err = usb_control_msg(udev, pipe,
                                USB_REQ_DFU_DNLOAD,
                                USB_TYPE_VENDOR, 0, 0,
-                               firmware, 20, USB_CTRL_SET_TIMEOUT)) < 0) {
+                               send_buf, 20, USB_CTRL_SET_TIMEOUT)) < 0) {
                BT_ERR("Can't change to loading configuration err");
-               return -EBUSY;
+               goto error;
        }
        sent += 20;
        count -= 20;
 
-       send_buf = kmalloc(BULK_SIZE, GFP_ATOMIC);
-       if (!send_buf) {
-               BT_ERR("Can't allocate memory chunk for firmware");
-               return -ENOMEM;
-       }
-
        while (count) {
                size = min_t(uint, count, BULK_SIZE);
-               pipe = usb_sndbulkpipe(data->udev, 0x02);
-               memcpy(send_buf, firmware + sent, size);
+               pipe = usb_sndbulkpipe(udev, 0x02);
+               memcpy(send_buf, firmware->data + sent, size);
 
-               err = usb_bulk_msg(data->udev, pipe, send_buf, size,
+               err = usb_bulk_msg(udev, pipe, send_buf, size,
                                        &len, 3000);
 
                if (err || (len != size)) {
@@ -112,57 +106,28 @@ static int ath3k_probe(struct usb_interface *intf,
 {
        const struct firmware *firmware;
        struct usb_device *udev = interface_to_usbdev(intf);
-       struct ath3k_data *data;
-       int size;
 
        BT_DBG("intf %p id %p", intf, id);
 
        if (intf->cur_altsetting->desc.bInterfaceNumber != 0)
                return -ENODEV;
 
-       data = kzalloc(sizeof(*data), GFP_KERNEL);
-       if (!data)
-               return -ENOMEM;
-
-       data->udev = udev;
-
        if (request_firmware(&firmware, "ath3k-1.fw", &udev->dev) < 0) {
-               kfree(data);
                return -EIO;
        }
 
-       size = max_t(uint, firmware->size, 4096);
-       data->fw_data = kmalloc(size, GFP_KERNEL);
-       if (!data->fw_data) {
+       if (ath3k_load_firmware(udev, firmware)) {
                release_firmware(firmware);
-               kfree(data);
-               return -ENOMEM;
-       }
-
-       memcpy(data->fw_data, firmware->data, firmware->size);
-       data->fw_size = firmware->size;
-       data->fw_sent = 0;
-       release_firmware(firmware);
-
-       usb_set_intfdata(intf, data);
-       if (ath3k_load_firmware(data, data->fw_data, data->fw_size)) {
-               usb_set_intfdata(intf, NULL);
-               kfree(data->fw_data);
-               kfree(data);
                return -EIO;
        }
+       release_firmware(firmware);
 
        return 0;
 }
 
 static void ath3k_disconnect(struct usb_interface *intf)
 {
-       struct ath3k_data *data = usb_get_intfdata(intf);
-
        BT_DBG("ath3k_disconnect intf %p", intf);
-
-       kfree(data->fw_data);
-       kfree(data);
 }
 
 static struct usb_driver ath3k_driver = {
index 826ab0939a128308b294207eda495207884f5361..fab3d3265adbec77ba71096587d924e9858d59f7 100644 (file)
@@ -68,6 +68,7 @@ static struct _intel_private {
        phys_addr_t gma_bus_addr;
        u32 PGETBL_save;
        u32 __iomem *gtt;               /* I915G */
+       bool clear_fake_agp; /* on first access via agp, fill with scratch */
        int num_dcache_entries;
        union {
                void __iomem *i9xx_flush_page;
@@ -869,21 +870,12 @@ static int intel_fake_agp_free_gatt_table(struct agp_bridge_data *bridge)
 
 static int intel_fake_agp_configure(void)
 {
-       int i;
-
        if (!intel_enable_gtt())
            return -EIO;
 
+       intel_private.clear_fake_agp = true;
        agp_bridge->gart_bus_addr = intel_private.gma_bus_addr;
 
-       for (i = 0; i < intel_private.base.gtt_total_entries; i++) {
-               intel_private.driver->write_entry(intel_private.scratch_page_dma,
-                                                 i, 0);
-       }
-       readl(intel_private.gtt+i-1);   /* PCI Posting. */
-
-       global_cache_flush();
-
        return 0;
 }
 
@@ -945,6 +937,13 @@ static int intel_fake_agp_insert_entries(struct agp_memory *mem,
 {
        int ret = -EINVAL;
 
+       if (intel_private.clear_fake_agp) {
+               int start = intel_private.base.stolen_size / PAGE_SIZE;
+               int end = intel_private.base.gtt_mappable_entries;
+               intel_gtt_clear_range(start, end - start);
+               intel_private.clear_fake_agp = false;
+       }
+
        if (INTEL_GTT_GEN == 1 && type == AGP_DCACHE_MEMORY)
                return i810_insert_dcache_entries(mem, pg_start, type);
 
index e397df3ad98e2f451a51e9bcb91cd3c47deaa610..16402445f2b237303589ede6d768753bb08c6166 100644 (file)
@@ -183,16 +183,16 @@ bfin_jc_circ_write(const unsigned char *buf, int count)
 }
 
 #ifndef CONFIG_BFIN_JTAG_COMM_CONSOLE
-# define acquire_console_sem()
-# define release_console_sem()
+# define console_lock()
+# define console_unlock()
 #endif
 static int
 bfin_jc_write(struct tty_struct *tty, const unsigned char *buf, int count)
 {
        int i;
-       acquire_console_sem();
+       console_lock();
        i = bfin_jc_circ_write(buf, count);
-       release_console_sem();
+       console_unlock();
        wake_up_process(bfin_jc_kthread);
        return i;
 }
index 1f46f1cd9225c3c0d2a894bc80d3d1e74fe012e7..36e0fa161c2bf0b46206a6e0af00698935ad158b 100644 (file)
@@ -364,12 +364,14 @@ unsigned long tpm_calc_ordinal_duration(struct tpm_chip *chip,
                    tpm_protected_ordinal_duration[ordinal &
                                                   TPM_PROTECTED_ORDINAL_MASK];
 
-       if (duration_idx != TPM_UNDEFINED)
+       if (duration_idx != TPM_UNDEFINED) {
                duration = chip->vendor.duration[duration_idx];
-       if (duration <= 0)
+               /* if duration is 0, it's because chip->vendor.duration wasn't */
+               /* filled yet, so we set the lowest timeout just to give enough */
+               /* time for tpm_get_timeouts() to succeed */
+               return (duration <= 0 ? HZ : duration);
+       } else
                return 2 * 60 * HZ;
-       else
-               return duration;
 }
 EXPORT_SYMBOL_GPL(tpm_calc_ordinal_duration);
 
index c17a305ecb2806256c2f7c4f1e9e0e4c3f878734..dd21df55689d96a39d5fea3f66d2161dfec44467 100644 (file)
@@ -493,9 +493,6 @@ 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 (is_itpm(to_pnp_dev(dev)))
-               itpm = 1;
-
        if (itpm)
                dev_info(dev, "Intel iTPM workaround enabled\n");
 
@@ -637,6 +634,9 @@ static int __devinit tpm_tis_pnp_init(struct pnp_dev *pnp_dev,
        else
                interrupts = 0;
 
+       if (is_itpm(pnp_dev))
+               itpm = 1;
+
        return tpm_tis_init(&pnp_dev->dev, start, len, irq);
 }
 
index cfb0f5278415a2d371f2a6902ec0670183f6bc10..effe7974aa9a742b78e893d5ef508fca63481376 100644 (file)
@@ -202,17 +202,21 @@ static int __init init_acpi_pm_clocksource(void)
                        printk(KERN_INFO "PM-Timer had inconsistent results:"
                               " 0x%#llx, 0x%#llx - aborting.\n",
                               value1, value2);
+                       pmtmr_ioport = 0;
                        return -EINVAL;
                }
                if (i == ACPI_PM_READ_CHECKS) {
                        printk(KERN_INFO "PM-Timer failed consistency check "
                               " (0x%#llx) - aborting.\n", value1);
+                       pmtmr_ioport = 0;
                        return -ENODEV;
                }
        }
 
-       if (verify_pmtmr_rate() != 0)
+       if (verify_pmtmr_rate() != 0){
+               pmtmr_ioport = 0;
                return -ENODEV;
+       }
 
        return clocksource_register_hz(&clocksource_acpi_pm,
                                                PMTMR_TICKS_PER_SEC);
index 01b886e6882215f526dab803ebb66531919df544..79c47e88d5d1ed17059aa99c9370168af7530d12 100644 (file)
@@ -196,9 +196,9 @@ static void __init setup_clkevents(struct atmel_tc *tc, int clk32k_divisor_idx)
        clkevt.clkevt.min_delta_ns = clockevent_delta2ns(1, &clkevt.clkevt) + 1;
        clkevt.clkevt.cpumask = cpumask_of(0);
 
-       setup_irq(irq, &tc_irqaction);
-
        clockevents_register_device(&clkevt.clkevt);
+
+       setup_irq(irq, &tc_irqaction);
 }
 
 #else /* !CONFIG_GENERIC_CLOCKEVENTS */
index d81cc748e77f424c1201fd823bea18a5464ac83c..54d70a47afc1a7f4e6f5f566899090b46bfb804a 100644 (file)
@@ -187,7 +187,7 @@ MODULE_DEVICE_TABLE(pci, lnw_gpio_ids);
 
 static void lnw_irq_handler(unsigned irq, struct irq_desc *desc)
 {
-       struct lnw_gpio *lnw = (struct lnw_gpio *)get_irq_data(irq);
+       struct lnw_gpio *lnw = get_irq_data(irq);
        u32 base, gpio;
        void __iomem *gedr;
        u32 gedr_v;
@@ -206,7 +206,12 @@ static void lnw_irq_handler(unsigned irq, struct irq_desc *desc)
                /* clear the edge detect status bit */
                writel(gedr_v, gedr);
        }
-       desc->chip->eoi(irq);
+
+       if (desc->chip->irq_eoi)
+               desc->chip->irq_eoi(irq_get_irq_data(irq));
+       else
+               dev_warn(lnw->chip.dev, "missing EOI handler for irq %d\n", irq);
+
 }
 
 static int __devinit lnw_gpio_probe(struct pci_dev *pdev,
index bea966f8ac84c96b3e02c908c146637c7ef7e7d1..0902d44600394fd1d6888bd6e5065bda884d2e03 100644 (file)
@@ -100,7 +100,10 @@ config DRM_I830
 config DRM_I915
        tristate "i915 driver"
        depends on AGP_INTEL
+       # we need shmfs for the swappable backing store, and in particular
+       # the shmem_readpage() which depends upon tmpfs
        select SHMEM
+       select TMPFS
        select DRM_KMS_HELPER
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
index 844f3c972b04dd8a55ccde3ab6a84766940b9e31..17bd766f20811ae5622a4276adf78de9a77c5208 100644 (file)
@@ -152,7 +152,7 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init)
 {
        drm_i915_private_t *dev_priv = dev->dev_private;
        struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv;
-       struct intel_ring_buffer *ring = LP_RING(dev_priv);
+       int ret;
 
        master_priv->sarea = drm_getsarea(dev);
        if (master_priv->sarea) {
@@ -163,33 +163,22 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init)
        }
 
        if (init->ring_size != 0) {
-               if (ring->obj != NULL) {
+               if (LP_RING(dev_priv)->obj != NULL) {
                        i915_dma_cleanup(dev);
                        DRM_ERROR("Client tried to initialize ringbuffer in "
                                  "GEM mode\n");
                        return -EINVAL;
                }
 
-               ring->size = init->ring_size;
-
-               ring->map.offset = init->ring_start;
-               ring->map.size = init->ring_size;
-               ring->map.type = 0;
-               ring->map.flags = 0;
-               ring->map.mtrr = 0;
-
-               drm_core_ioremap_wc(&ring->map, dev);
-
-               if (ring->map.handle == NULL) {
+               ret = intel_render_ring_init_dri(dev,
+                                                init->ring_start,
+                                                init->ring_size);
+               if (ret) {
                        i915_dma_cleanup(dev);
-                       DRM_ERROR("can not ioremap virtual address for"
-                                 " ring buffer\n");
-                       return -ENOMEM;
+                       return ret;
                }
        }
 
-       ring->virtual_start = ring->map.handle;
-
        dev_priv->cpp = init->cpp;
        dev_priv->back_offset = init->back_offset;
        dev_priv->front_offset = init->front_offset;
@@ -1226,9 +1215,15 @@ static int i915_load_modeset_init(struct drm_device *dev)
        if (ret)
                DRM_INFO("failed to find VBIOS tables\n");
 
-       /* if we have > 1 VGA cards, then disable the radeon VGA resources */
+       /* If we have > 1 VGA cards, then we need to arbitrate access
+        * to the common VGA resources.
+        *
+        * If we are a secondary display controller (!PCI_DISPLAY_CLASS_VGA),
+        * then we do not take part in VGA arbitration and the
+        * vga_client_register() fails with -ENODEV.
+        */
        ret = vga_client_register(dev->pdev, dev, NULL, i915_vga_set_decode);
-       if (ret)
+       if (ret && ret != -ENODEV)
                goto cleanup_ringbuffer;
 
        intel_register_dsm_handler();
index 72fea2bcfc4f77241a7b1087e558637841279afb..66796bb82d3e540b1db6d356308916a534be22b5 100644 (file)
@@ -60,7 +60,7 @@ extern int intel_agp_enabled;
 
 #define INTEL_VGA_DEVICE(id, info) {           \
        .class = PCI_CLASS_DISPLAY_VGA << 8,    \
-       .class_mask = 0xffff00,                 \
+       .class_mask = 0xff0000,                 \
        .vendor = 0x8086,                       \
        .device = id,                           \
        .subvendor = PCI_ANY_ID,                \
@@ -752,6 +752,9 @@ static int __init i915_init(void)
                driver.driver_features &= ~DRIVER_MODESET;
 #endif
 
+       if (!(driver.driver_features & DRIVER_MODESET))
+               driver.get_vblank_timestamp = NULL;
+
        return drm_init(&driver);
 }
 
index 5969f46ac2d6023740204c74e62d25265cfc736f..a0149c619cdd117026f2c4f32309ee462b623455 100644 (file)
@@ -543,8 +543,11 @@ typedef struct drm_i915_private {
                /** List of all objects in gtt_space. Used to restore gtt
                 * mappings on resume */
                struct list_head gtt_list;
-               /** End of mappable part of GTT */
+
+               /** Usable portion of the GTT for GEM */
+               unsigned long gtt_start;
                unsigned long gtt_mappable_end;
+               unsigned long gtt_end;
 
                struct io_mapping *gtt_mapping;
                int gtt_mtrr;
index 3dfc848ff7556e325ee4fdddd1642a44d44d1252..cf4f74c7c6fb6fb7fa8dcedc4839ce2910039846 100644 (file)
@@ -140,12 +140,16 @@ void i915_gem_do_init(struct drm_device *dev,
 {
        drm_i915_private_t *dev_priv = dev->dev_private;
 
-       drm_mm_init(&dev_priv->mm.gtt_space, start,
-                   end - start);
+       drm_mm_init(&dev_priv->mm.gtt_space, start, end - start);
 
+       dev_priv->mm.gtt_start = start;
+       dev_priv->mm.gtt_mappable_end = mappable_end;
+       dev_priv->mm.gtt_end = end;
        dev_priv->mm.gtt_total = end - start;
        dev_priv->mm.mappable_gtt_total = min(end, mappable_end) - start;
-       dev_priv->mm.gtt_mappable_end = mappable_end;
+
+       /* Take over this portion of the GTT */
+       intel_gtt_clear_range(start / PAGE_SIZE, (end-start) / PAGE_SIZE);
 }
 
 int
@@ -1857,7 +1861,7 @@ i915_gem_retire_requests_ring(struct drm_device *dev,
 
        seqno = ring->get_seqno(ring);
 
-       for (i = 0; i < I915_NUM_RINGS; i++)
+       for (i = 0; i < ARRAY_SIZE(ring->sync_seqno); i++)
                if (seqno >= ring->sync_seqno[i])
                        ring->sync_seqno[i] = 0;
 
index dcfdf4151b6dedddec0f45ba21f2c81156e1fe27..d2f445e825f200b10aad8aef884ddb2ec2671fc9 100644 (file)
@@ -1175,7 +1175,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
                goto err;
 
        seqno = i915_gem_next_request_seqno(dev, ring);
-       for (i = 0; i < I915_NUM_RINGS-1; i++) {
+       for (i = 0; i < ARRAY_SIZE(ring->sync_seqno); i++) {
                if (seqno < ring->sync_seqno[i]) {
                        /* The GPU can not handle its semaphore value wrapping,
                         * so every billion or so execbuffers, we need to stall
index 70433ae50ac80fe4fe44f90be74c4cb5840c3715..b0abdc64aa9f63aba4b018626da562421deb2a84 100644 (file)
@@ -34,6 +34,10 @@ void i915_gem_restore_gtt_mappings(struct drm_device *dev)
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct drm_i915_gem_object *obj;
 
+       /* First fill our portion of the GTT with scratch pages */
+       intel_gtt_clear_range(dev_priv->mm.gtt_start / PAGE_SIZE,
+                             (dev_priv->mm.gtt_end - dev_priv->mm.gtt_start) / PAGE_SIZE);
+
        list_for_each_entry(obj, &dev_priv->mm.gtt_list, gtt_list) {
                i915_gem_clflush_object(obj);
 
index b8e509ae065e41c0e5580b48454609dfc3314b55..062f353497e6ee6add30b8fd3469da200fcba7f6 100644 (file)
@@ -274,24 +274,35 @@ int i915_get_crtc_scanoutpos(struct drm_device *dev, int pipe,
        return ret;
 }
 
-int i915_get_vblank_timestamp(struct drm_device *dev, int crtc,
+int i915_get_vblank_timestamp(struct drm_device *dev, int pipe,
                              int *max_error,
                              struct timeval *vblank_time,
                              unsigned flags)
 {
-       struct drm_crtc *drmcrtc;
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       struct drm_crtc *crtc;
 
-       if (crtc < 0 || crtc >= dev->num_crtcs) {
-               DRM_ERROR("Invalid crtc %d\n", crtc);
+       if (pipe < 0 || pipe >= dev_priv->num_pipe) {
+               DRM_ERROR("Invalid crtc %d\n", pipe);
                return -EINVAL;
        }
 
        /* Get drm_crtc to timestamp: */
-       drmcrtc = intel_get_crtc_for_pipe(dev, crtc);
+       crtc = intel_get_crtc_for_pipe(dev, pipe);
+       if (crtc == NULL) {
+               DRM_ERROR("Invalid crtc %d\n", pipe);
+               return -EINVAL;
+       }
+
+       if (!crtc->enabled) {
+               DRM_DEBUG_KMS("crtc %d is disabled\n", pipe);
+               return -EBUSY;
+       }
 
        /* Helper routine in DRM core does all the work: */
-       return drm_calc_vbltimestamp_from_scanoutpos(dev, crtc, max_error,
-                                                    vblank_time, flags, drmcrtc);
+       return drm_calc_vbltimestamp_from_scanoutpos(dev, pipe, max_error,
+                                                    vblank_time, flags,
+                                                    crtc);
 }
 
 /*
@@ -348,8 +359,12 @@ static void notify_ring(struct drm_device *dev,
                        struct intel_ring_buffer *ring)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
-       u32 seqno = ring->get_seqno(ring);
+       u32 seqno;
 
+       if (ring->obj == NULL)
+               return;
+
+       seqno = ring->get_seqno(ring);
        trace_i915_gem_request_complete(dev, seqno);
 
        ring->irq_seqno = seqno;
@@ -831,6 +846,8 @@ static void i915_capture_error_state(struct drm_device *dev)
                i++;
        error->pinned_bo_count = i - error->active_bo_count;
 
+       error->active_bo = NULL;
+       error->pinned_bo = NULL;
        if (i) {
                error->active_bo = kmalloc(sizeof(*error->active_bo)*i,
                                           GFP_ATOMIC);
@@ -1278,12 +1295,12 @@ static int i915_wait_irq(struct drm_device * dev, int irq_nr)
        if (master_priv->sarea_priv)
                master_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT;
 
-       ret = -ENODEV;
        if (ring->irq_get(ring)) {
                DRM_WAIT_ON(ret, ring->irq_queue, 3 * DRM_HZ,
                            READ_BREADCRUMB(dev_priv) >= irq_nr);
                ring->irq_put(ring);
-       }
+       } else if (wait_for(READ_BREADCRUMB(dev_priv) >= irq_nr, 3000))
+               ret = -EBUSY;
 
        if (ret == -EBUSY) {
                DRM_ERROR("EBUSY -- rec: %d emitted: %d\n",
index 40a407f41f61954fb5bd89cff03256b5283c3c35..5cfc68940f17dcaaa76b528a1eaf863402a5046c 100644 (file)
 #define   GEN6_BLITTER_SYNC_STATUS                     (1 << 24)
 #define   GEN6_BLITTER_USER_INTERRUPT                  (1 << 22)
 
+#define GEN6_BLITTER_ECOSKPD   0x221d0
+#define   GEN6_BLITTER_LOCK_SHIFT                      16
+#define   GEN6_BLITTER_FBC_NOTIFY                      (1<<3)
+
 #define GEN6_BSD_SLEEP_PSMI_CONTROL    0x12050
 #define   GEN6_BSD_SLEEP_PSMI_CONTROL_RC_ILDL_MESSAGE_MODIFY_MASK      (1 << 16)
 #define   GEN6_BSD_SLEEP_PSMI_CONTROL_RC_ILDL_MESSAGE_DISABLE          (1 << 0)
 #define DISPLAY_PORT_PLL_BIOS_2         0x46014
 
 #define PCH_DSPCLK_GATE_D      0x42020
+# define DPFCUNIT_CLOCK_GATE_DISABLE           (1 << 9)
+# define DPFCRUNIT_CLOCK_GATE_DISABLE          (1 << 8)
 # define DPFDUNIT_CLOCK_GATE_DISABLE           (1 << 7)
 # define DPARBUNIT_CLOCK_GATE_DISABLE          (1 << 5)
 
index 98967f3b7724e1554713fa665e62b67f6abbddcd..d7f237deaaf01700c6b217b3aefb2227c43a686f 100644 (file)
@@ -1213,6 +1213,26 @@ static bool g4x_fbc_enabled(struct drm_device *dev)
        return I915_READ(DPFC_CONTROL) & DPFC_CTL_EN;
 }
 
+static void sandybridge_blit_fbc_update(struct drm_device *dev)
+{
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       u32 blt_ecoskpd;
+
+       /* Make sure blitter notifies FBC of writes */
+       __gen6_force_wake_get(dev_priv);
+       blt_ecoskpd = I915_READ(GEN6_BLITTER_ECOSKPD);
+       blt_ecoskpd |= GEN6_BLITTER_FBC_NOTIFY <<
+               GEN6_BLITTER_LOCK_SHIFT;
+       I915_WRITE(GEN6_BLITTER_ECOSKPD, blt_ecoskpd);
+       blt_ecoskpd |= GEN6_BLITTER_FBC_NOTIFY;
+       I915_WRITE(GEN6_BLITTER_ECOSKPD, blt_ecoskpd);
+       blt_ecoskpd &= ~(GEN6_BLITTER_FBC_NOTIFY <<
+                        GEN6_BLITTER_LOCK_SHIFT);
+       I915_WRITE(GEN6_BLITTER_ECOSKPD, blt_ecoskpd);
+       POSTING_READ(GEN6_BLITTER_ECOSKPD);
+       __gen6_force_wake_put(dev_priv);
+}
+
 static void ironlake_enable_fbc(struct drm_crtc *crtc, unsigned long interval)
 {
        struct drm_device *dev = crtc->dev;
@@ -1266,6 +1286,7 @@ static void ironlake_enable_fbc(struct drm_crtc *crtc, unsigned long interval)
                I915_WRITE(SNB_DPFC_CTL_SA,
                           SNB_CPU_FENCE_ENABLE | dev_priv->cfb_fence);
                I915_WRITE(DPFC_CPU_FENCE_OFFSET, crtc->y);
+               sandybridge_blit_fbc_update(dev);
        }
 
        DRM_DEBUG_KMS("enabled fbc on plane %d\n", intel_crtc->plane);
@@ -6286,7 +6307,9 @@ void intel_enable_clock_gating(struct drm_device *dev)
 
                if (IS_GEN5(dev)) {
                        /* Required for FBC */
-                       dspclk_gate |= DPFDUNIT_CLOCK_GATE_DISABLE;
+                       dspclk_gate |= DPFCUNIT_CLOCK_GATE_DISABLE |
+                               DPFCRUNIT_CLOCK_GATE_DISABLE |
+                               DPFDUNIT_CLOCK_GATE_DISABLE;
                        /* Required for CxSR */
                        dspclk_gate |= DPARBUNIT_CLOCK_GATE_DISABLE;
 
index f295a7aaadf9e54edb9cbe905739890e3c2edbe4..64fd64443ca69a3e064551e3ebd25e2c08c6a624 100644 (file)
@@ -26,6 +26,7 @@
  */
 
 #include <linux/acpi.h>
+#include <linux/acpi_io.h>
 #include <acpi/video.h>
 
 #include "drmP.h"
@@ -476,7 +477,7 @@ int intel_opregion_setup(struct drm_device *dev)
                return -ENOTSUPP;
        }
 
-       base = ioremap(asls, OPREGION_SIZE);
+       base = acpi_os_ioremap(asls, OPREGION_SIZE);
        if (!base)
                return -ENOMEM;
 
index f6b9baa6a63dec8c0100f8ded5b6b80540d1a5a3..6218fa97aa1e27385749a449a055ccdd9df7a1c8 100644 (file)
 #include "i915_trace.h"
 #include "intel_drv.h"
 
+static inline int ring_space(struct intel_ring_buffer *ring)
+{
+       int space = (ring->head & HEAD_ADDR) - (ring->tail + 8);
+       if (space < 0)
+               space += ring->size;
+       return space;
+}
+
 static u32 i915_gem_get_seqno(struct drm_device *dev)
 {
        drm_i915_private_t *dev_priv = dev->dev_private;
@@ -204,11 +212,9 @@ static int init_ring_common(struct intel_ring_buffer *ring)
        if (!drm_core_check_feature(ring->dev, DRIVER_MODESET))
                i915_kernel_lost_context(ring->dev);
        else {
-               ring->head = I915_READ_HEAD(ring) & HEAD_ADDR;
+               ring->head = I915_READ_HEAD(ring);
                ring->tail = I915_READ_TAIL(ring) & TAIL_ADDR;
-               ring->space = ring->head - (ring->tail + 8);
-               if (ring->space < 0)
-                       ring->space += ring->size;
+               ring->space = ring_space(ring);
        }
 
        return 0;
@@ -921,32 +927,34 @@ static int intel_wrap_ring_buffer(struct intel_ring_buffer *ring)
        }
 
        ring->tail = 0;
-       ring->space = ring->head - 8;
+       ring->space = ring_space(ring);
 
        return 0;
 }
 
 int intel_wait_ring_buffer(struct intel_ring_buffer *ring, int n)
 {
-       int reread = 0;
        struct drm_device *dev = ring->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
        unsigned long end;
        u32 head;
 
+       /* If the reported head position has wrapped or hasn't advanced,
+        * fallback to the slow and accurate path.
+        */
+       head = intel_read_status_page(ring, 4);
+       if (head > ring->head) {
+               ring->head = head;
+               ring->space = ring_space(ring);
+               if (ring->space >= n)
+                       return 0;
+       }
+
        trace_i915_ring_wait_begin (dev);
        end = jiffies + 3 * HZ;
        do {
-               /* If the reported head position has wrapped or hasn't advanced,
-                * fallback to the slow and accurate path.
-                */
-               head = intel_read_status_page(ring, 4);
-               if (reread)
-                       head = I915_READ_HEAD(ring);
-               ring->head = head & HEAD_ADDR;
-               ring->space = ring->head - (ring->tail + 8);
-               if (ring->space < 0)
-                       ring->space += ring->size;
+               ring->head = I915_READ_HEAD(ring);
+               ring->space = ring_space(ring);
                if (ring->space >= n) {
                        trace_i915_ring_wait_end(dev);
                        return 0;
@@ -961,7 +969,6 @@ int intel_wait_ring_buffer(struct intel_ring_buffer *ring, int n)
                msleep(1);
                if (atomic_read(&dev_priv->mm.wedged))
                        return -EAGAIN;
-               reread = 1;
        } while (!time_after(jiffies, end));
        trace_i915_ring_wait_end (dev);
        return -EBUSY;
@@ -1292,6 +1299,48 @@ int intel_init_render_ring_buffer(struct drm_device *dev)
        return intel_init_ring_buffer(dev, ring);
 }
 
+int intel_render_ring_init_dri(struct drm_device *dev, u64 start, u32 size)
+{
+       drm_i915_private_t *dev_priv = dev->dev_private;
+       struct intel_ring_buffer *ring = &dev_priv->ring[RCS];
+
+       *ring = render_ring;
+       if (INTEL_INFO(dev)->gen >= 6) {
+               ring->add_request = gen6_add_request;
+               ring->irq_get = gen6_render_ring_get_irq;
+               ring->irq_put = gen6_render_ring_put_irq;
+       } else if (IS_GEN5(dev)) {
+               ring->add_request = pc_render_add_request;
+               ring->get_seqno = pc_render_get_seqno;
+       }
+
+       ring->dev = dev;
+       INIT_LIST_HEAD(&ring->active_list);
+       INIT_LIST_HEAD(&ring->request_list);
+       INIT_LIST_HEAD(&ring->gpu_write_list);
+
+       ring->size = size;
+       ring->effective_size = ring->size;
+       if (IS_I830(ring->dev))
+               ring->effective_size -= 128;
+
+       ring->map.offset = start;
+       ring->map.size = size;
+       ring->map.type = 0;
+       ring->map.flags = 0;
+       ring->map.mtrr = 0;
+
+       drm_core_ioremap_wc(&ring->map, dev);
+       if (ring->map.handle == NULL) {
+               DRM_ERROR("can not ioremap virtual address for"
+                         " ring buffer\n");
+               return -ENOMEM;
+       }
+
+       ring->virtual_start = (void __force __iomem *)ring->map.handle;
+       return 0;
+}
+
 int intel_init_bsd_ring_buffer(struct drm_device *dev)
 {
        drm_i915_private_t *dev_priv = dev->dev_private;
index 5b0abfa881fc7964eab452b5ea254e568ea49fe8..6d6fde85a636248e373d9ef288450597f1ba6f91 100644 (file)
@@ -166,4 +166,7 @@ int intel_init_blt_ring_buffer(struct drm_device *dev);
 u32 intel_ring_get_active_head(struct intel_ring_buffer *ring);
 void intel_ring_setup_status_page(struct intel_ring_buffer *ring);
 
+/* DRI warts */
+int intel_render_ring_init_dri(struct drm_device *dev, u64 start, u32 size);
+
 #endif /* _INTEL_RINGBUFFER_H_ */
index 2aef5cd3acf578197c1530454c37a345e1efee3f..49e5e99917e22bbf8c8b02cae4d8dce23205b475 100644 (file)
@@ -6310,6 +6310,9 @@ void merge_like_dcb_entries(struct drm_device *dev, struct dcb_table *dcb)
 static bool
 apply_dcb_encoder_quirks(struct drm_device *dev, int idx, u32 *conn, u32 *conf)
 {
+       struct drm_nouveau_private *dev_priv = dev->dev_private;
+       struct dcb_table *dcb = &dev_priv->vbios.dcb;
+
        /* Dell Precision M6300
         *   DCB entry 2: 02025312 00000010
         *   DCB entry 3: 02026312 00000020
@@ -6327,6 +6330,18 @@ apply_dcb_encoder_quirks(struct drm_device *dev, int idx, u32 *conn, u32 *conf)
                        return false;
        }
 
+       /* GeForce3 Ti 200
+        *
+        * DCB reports an LVDS output that should be TMDS:
+        *   DCB entry 1: f2005014 ffffffff
+        */
+       if (nv_match_device(dev, 0x0201, 0x1462, 0x8851)) {
+               if (*conn == 0xf2005014 && *conf == 0xffffffff) {
+                       fabricate_dcb_output(dcb, OUTPUT_TMDS, 1, 1, 1);
+                       return false;
+               }
+       }
+
        return true;
 }
 
index 13bb672a16f49cf09e18161b231b7c53477bada2..f658a04eecf951e8dc3b132d4ec4b679e282ccc7 100644 (file)
@@ -234,9 +234,9 @@ nouveau_pci_suspend(struct pci_dev *pdev, pm_message_t pm_state)
                pci_set_power_state(pdev, PCI_D3hot);
        }
 
-       acquire_console_sem();
+       console_lock();
        nouveau_fbcon_set_suspend(dev, 1);
-       release_console_sem();
+       console_unlock();
        nouveau_fbcon_restore_accel(dev);
        return 0;
 
@@ -359,9 +359,9 @@ nouveau_pci_resume(struct pci_dev *pdev)
                nv_crtc->lut.depth = 0;
        }
 
-       acquire_console_sem();
+       console_lock();
        nouveau_fbcon_set_suspend(dev, 0);
-       release_console_sem();
+       console_unlock();
 
        nouveau_fbcon_zfill_all(dev);
 
index 01bffc4412d2edcfbe957066f0768c708570cb30..9821fcacc3d2f561ed10da893509ac3ace7d5b21 100644 (file)
@@ -848,9 +848,6 @@ extern void nv10_mem_put_tile_region(struct drm_device *dev,
                                     struct nouveau_fence *fence);
 extern const struct ttm_mem_type_manager_func nouveau_vram_manager;
 
-/* nvc0_vram.c */
-extern const struct ttm_mem_type_manager_func nvc0_vram_manager;
-
 /* nouveau_notifier.c */
 extern int  nouveau_notifier_init_channel(struct nouveau_channel *);
 extern void nouveau_notifier_takedown_channel(struct nouveau_channel *);
index 7ecc4adc1e4575aca6ef2791752c25300ff7668b..8d9968e1cba8fc47f0b655d16d8aa46c9b8c0554 100644 (file)
@@ -265,8 +265,8 @@ nouveau_temp_probe_i2c(struct drm_device *dev)
        struct i2c_board_info info[] = {
                { I2C_BOARD_INFO("w83l785ts", 0x2d) },
                { I2C_BOARD_INFO("w83781d", 0x2d) },
-               { I2C_BOARD_INFO("f75375", 0x2e) },
                { I2C_BOARD_INFO("adt7473", 0x2e) },
+               { I2C_BOARD_INFO("f75375", 0x2e) },
                { I2C_BOARD_INFO("lm99", 0x4c) },
                { }
        };
index 2d7ea75a09d49deb0f21f9228828dd58c7663c47..37e21d2be95be028185748d77e34a6adaf8fa4a4 100644 (file)
@@ -256,6 +256,7 @@ nv50_graph_destroy_context(struct nouveau_channel *chan)
        struct drm_device *dev = chan->dev;
        struct drm_nouveau_private *dev_priv = dev->dev_private;
        struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
+       struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo;
        int i, hdr = (dev_priv->chipset == 0x50) ? 0x200 : 0x20;
        unsigned long flags;
 
@@ -265,6 +266,7 @@ nv50_graph_destroy_context(struct nouveau_channel *chan)
                return;
 
        spin_lock_irqsave(&dev_priv->context_switch_lock, flags);
+       pfifo->reassign(dev, false);
        pgraph->fifo_access(dev, false);
 
        if (pgraph->channel(dev) == chan)
@@ -275,6 +277,7 @@ nv50_graph_destroy_context(struct nouveau_channel *chan)
        dev_priv->engine.instmem.flush(dev);
 
        pgraph->fifo_access(dev, true);
+       pfifo->reassign(dev, true);
        spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);
 
        nouveau_gpuobj_ref(NULL, &chan->ramin_grctx);
index 38e523e1099519379f62c8bc017887198b5fdd5c..459ff08241e571400eb63e9e84c2cdae9a150bb7 100644 (file)
@@ -45,11 +45,6 @@ nv50_vm_map_pgt(struct nouveau_gpuobj *pgd, u32 pde,
        }
 
        if (phys & 1) {
-               if (dev_priv->vram_sys_base) {
-                       phys += dev_priv->vram_sys_base;
-                       phys |= 0x30;
-               }
-
                if (coverage <= 32 * 1024 * 1024)
                        phys |= 0x60;
                else if (coverage <= 64 * 1024 * 1024)
index e6ea7d83187f9e71c4d96c9e610d142671fb9140..eb18a7e89f5b51b567964fa5a72f1f10f9324412 100644 (file)
@@ -31,6 +31,7 @@
 #include "nvc0_graph.h"
 
 static void nvc0_graph_isr(struct drm_device *);
+static void nvc0_runk140_isr(struct drm_device *);
 static int  nvc0_graph_unload_context_to(struct drm_device *dev, u64 chan);
 
 void
@@ -281,6 +282,7 @@ nvc0_graph_destroy(struct drm_device *dev)
                return;
 
        nouveau_irq_unregister(dev, 12);
+       nouveau_irq_unregister(dev, 25);
 
        nouveau_gpuobj_ref(NULL, &priv->unk4188b8);
        nouveau_gpuobj_ref(NULL, &priv->unk4188b4);
@@ -390,6 +392,7 @@ nvc0_graph_create(struct drm_device *dev)
        }
 
        nouveau_irq_register(dev, 12, nvc0_graph_isr);
+       nouveau_irq_register(dev, 25, nvc0_runk140_isr);
        NVOBJ_CLASS(dev, 0x902d, GR); /* 2D */
        NVOBJ_CLASS(dev, 0x9039, GR); /* M2MF */
        NVOBJ_CLASS(dev, 0x9097, GR); /* 3D */
@@ -512,8 +515,8 @@ nvc0_graph_init_gpc_1(struct drm_device *dev)
                        nv_wr32(dev, TP_UNIT(gpc, tp, 0x224), 0xc0000000);
                        nv_wr32(dev, TP_UNIT(gpc, tp, 0x48c), 0xc0000000);
                        nv_wr32(dev, TP_UNIT(gpc, tp, 0x084), 0xc0000000);
-                       nv_wr32(dev, TP_UNIT(gpc, tp, 0xe44), 0x001ffffe);
-                       nv_wr32(dev, TP_UNIT(gpc, tp, 0xe4c), 0x0000000f);
+                       nv_wr32(dev, TP_UNIT(gpc, tp, 0x644), 0x001ffffe);
+                       nv_wr32(dev, TP_UNIT(gpc, tp, 0x64c), 0x0000000f);
                }
                nv_wr32(dev, GPC_UNIT(gpc, 0x2c90), 0xffffffff);
                nv_wr32(dev, GPC_UNIT(gpc, 0x2c94), 0xffffffff);
@@ -777,3 +780,19 @@ nvc0_graph_isr(struct drm_device *dev)
 
        nv_wr32(dev, 0x400500, 0x00010001);
 }
+
+static void
+nvc0_runk140_isr(struct drm_device *dev)
+{
+       u32 units = nv_rd32(dev, 0x00017c) & 0x1f;
+
+       while (units) {
+               u32 unit = ffs(units) - 1;
+               u32 reg = 0x140000 + unit * 0x2000;
+               u32 st0 = nv_mask(dev, reg + 0x1020, 0, 0);
+               u32 st1 = nv_mask(dev, reg + 0x1420, 0, 0);
+
+               NV_INFO(dev, "PRUNK140: %d 0x%08x 0x%08x\n", unit, st0, st1);
+               units &= ~(1 << unit);
+       }
+}
index b9e68b2d30aa5c1819426e63212f72ba8ce7c926..f880ff776db8562842142ebbc5482632e9ff2ecd 100644 (file)
@@ -1830,7 +1830,7 @@ nvc0_grctx_generate(struct nouveau_channel *chan)
 
        for (tp = 0, id = 0; tp < 4; tp++) {
                for (gpc = 0; gpc < priv->gpc_nr; gpc++) {
-                       if (tp <= priv->tp_nr[gpc]) {
+                       if (tp < priv->tp_nr[gpc]) {
                                nv_wr32(dev, TP_UNIT(gpc, tp, 0x698), id);
                                nv_wr32(dev, TP_UNIT(gpc, tp, 0x4e8), id);
                                nv_wr32(dev, GPC_UNIT(gpc, 0x0c10 + tp * 4), id);
index b0ab185b86f6ad9ee4bddd9eeff65d5601ca70c4..842954fe74c51e411defe35c88647e1a03103773 100644 (file)
@@ -606,14 +606,9 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
                                args.v1.usPixelClock = cpu_to_le16(mode->clock / 10);
                                args.v1.ucTransmitterID = radeon_encoder->encoder_id;
                                args.v1.ucEncodeMode = encoder_mode;
-                               if (encoder_mode == ATOM_ENCODER_MODE_DP) {
-                                       if (ss_enabled)
-                                               args.v1.ucConfig |=
-                                                       ADJUST_DISPLAY_CONFIG_SS_ENABLE;
-                               } else if (encoder_mode == ATOM_ENCODER_MODE_LVDS) {
+                               if (ss_enabled)
                                        args.v1.ucConfig |=
                                                ADJUST_DISPLAY_CONFIG_SS_ENABLE;
-                               }
 
                                atom_execute_table(rdev->mode_info.atom_context,
                                                   index, (uint32_t *)&args);
@@ -624,12 +619,12 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
                                args.v3.sInput.ucTransmitterID = radeon_encoder->encoder_id;
                                args.v3.sInput.ucEncodeMode = encoder_mode;
                                args.v3.sInput.ucDispPllConfig = 0;
+                               if (ss_enabled)
+                                       args.v3.sInput.ucDispPllConfig |=
+                                               DISPPLL_CONFIG_SS_ENABLE;
                                if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {
                                        struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
                                        if (encoder_mode == ATOM_ENCODER_MODE_DP) {
-                                               if (ss_enabled)
-                                                       args.v3.sInput.ucDispPllConfig |=
-                                                               DISPPLL_CONFIG_SS_ENABLE;
                                                args.v3.sInput.ucDispPllConfig |=
                                                        DISPPLL_CONFIG_COHERENT_MODE;
                                                /* 16200 or 27000 */
@@ -649,18 +644,11 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
                                        }
                                } else if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
                                        if (encoder_mode == ATOM_ENCODER_MODE_DP) {
-                                               if (ss_enabled)
-                                                       args.v3.sInput.ucDispPllConfig |=
-                                                               DISPPLL_CONFIG_SS_ENABLE;
                                                args.v3.sInput.ucDispPllConfig |=
                                                        DISPPLL_CONFIG_COHERENT_MODE;
                                                /* 16200 or 27000 */
                                                args.v3.sInput.usPixelClock = cpu_to_le16(dp_clock / 10);
-                                       } else if (encoder_mode == ATOM_ENCODER_MODE_LVDS) {
-                                               if (ss_enabled)
-                                                       args.v3.sInput.ucDispPllConfig |=
-                                                               DISPPLL_CONFIG_SS_ENABLE;
-                                       } else {
+                                       } else if (encoder_mode != ATOM_ENCODER_MODE_LVDS) {
                                                if (mode->clock > 165000)
                                                        args.v3.sInput.ucDispPllConfig |=
                                                                DISPPLL_CONFIG_DUAL_LINK;
@@ -1006,6 +994,7 @@ static int evergreen_crtc_do_set_base(struct drm_crtc *crtc,
        struct radeon_bo *rbo;
        uint64_t fb_location;
        uint32_t fb_format, fb_pitch_pixels, tiling_flags;
+       u32 fb_swap = EVERGREEN_GRPH_ENDIAN_SWAP(EVERGREEN_GRPH_ENDIAN_NONE);
        int r;
 
        /* no fb bound */
@@ -1057,11 +1046,17 @@ static int evergreen_crtc_do_set_base(struct drm_crtc *crtc,
        case 16:
                fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_16BPP) |
                             EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_ARGB565));
+#ifdef __BIG_ENDIAN
+               fb_swap = EVERGREEN_GRPH_ENDIAN_SWAP(EVERGREEN_GRPH_ENDIAN_8IN16);
+#endif
                break;
        case 24:
        case 32:
                fb_format = (EVERGREEN_GRPH_DEPTH(EVERGREEN_GRPH_DEPTH_32BPP) |
                             EVERGREEN_GRPH_FORMAT(EVERGREEN_GRPH_FORMAT_ARGB8888));
+#ifdef __BIG_ENDIAN
+               fb_swap = EVERGREEN_GRPH_ENDIAN_SWAP(EVERGREEN_GRPH_ENDIAN_8IN32);
+#endif
                break;
        default:
                DRM_ERROR("Unsupported screen depth %d\n",
@@ -1106,6 +1101,7 @@ static int evergreen_crtc_do_set_base(struct drm_crtc *crtc,
        WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset,
               (u32) fb_location & EVERGREEN_GRPH_SURFACE_ADDRESS_MASK);
        WREG32(EVERGREEN_GRPH_CONTROL + radeon_crtc->crtc_offset, fb_format);
+       WREG32(EVERGREEN_GRPH_SWAP_CONTROL + radeon_crtc->crtc_offset, fb_swap);
 
        WREG32(EVERGREEN_GRPH_SURFACE_OFFSET_X + radeon_crtc->crtc_offset, 0);
        WREG32(EVERGREEN_GRPH_SURFACE_OFFSET_Y + radeon_crtc->crtc_offset, 0);
@@ -1162,6 +1158,7 @@ static int avivo_crtc_do_set_base(struct drm_crtc *crtc,
        struct drm_framebuffer *target_fb;
        uint64_t fb_location;
        uint32_t fb_format, fb_pitch_pixels, tiling_flags;
+       u32 fb_swap = R600_D1GRPH_SWAP_ENDIAN_NONE;
        int r;
 
        /* no fb bound */
@@ -1215,12 +1212,18 @@ static int avivo_crtc_do_set_base(struct drm_crtc *crtc,
                fb_format =
                    AVIVO_D1GRPH_CONTROL_DEPTH_16BPP |
                    AVIVO_D1GRPH_CONTROL_16BPP_RGB565;
+#ifdef __BIG_ENDIAN
+               fb_swap = R600_D1GRPH_SWAP_ENDIAN_16BIT;
+#endif
                break;
        case 24:
        case 32:
                fb_format =
                    AVIVO_D1GRPH_CONTROL_DEPTH_32BPP |
                    AVIVO_D1GRPH_CONTROL_32BPP_ARGB8888;
+#ifdef __BIG_ENDIAN
+               fb_swap = R600_D1GRPH_SWAP_ENDIAN_32BIT;
+#endif
                break;
        default:
                DRM_ERROR("Unsupported screen depth %d\n",
@@ -1260,6 +1263,8 @@ static int avivo_crtc_do_set_base(struct drm_crtc *crtc,
        WREG32(AVIVO_D1GRPH_SECONDARY_SURFACE_ADDRESS +
               radeon_crtc->crtc_offset, (u32) fb_location);
        WREG32(AVIVO_D1GRPH_CONTROL + radeon_crtc->crtc_offset, fb_format);
+       if (rdev->family >= CHIP_R600)
+               WREG32(R600_D1GRPH_SWAP_CONTROL + radeon_crtc->crtc_offset, fb_swap);
 
        WREG32(AVIVO_D1GRPH_SURFACE_OFFSET_X + radeon_crtc->crtc_offset, 0);
        WREG32(AVIVO_D1GRPH_SURFACE_OFFSET_Y + radeon_crtc->crtc_offset, 0);
index 4e7778d44b8d36fa4491c97de47aa5f4d400919f..695de9a38506dea0aa19c8b2ec315486c7b26bb1 100644 (file)
@@ -187,9 +187,9 @@ static int dp_link_clock_for_mode_clock(u8 dpcd[DP_DPCD_SIZE], int mode_clock)
 int dp_mode_valid(u8 dpcd[DP_DPCD_SIZE], int mode_clock)
 {
        int lanes = dp_lanes_for_mode_clock(dpcd, mode_clock);
-       int bw = dp_lanes_for_mode_clock(dpcd, mode_clock);
+       int dp_clock = dp_link_clock_for_mode_clock(dpcd, mode_clock);
 
-       if ((lanes == 0) || (bw == 0))
+       if ((lanes == 0) || (dp_clock == 0))
                return MODE_CLOCK_HIGH;
 
        return MODE_OK;
index a8973acb39870e2af0c253f92daec14cd80bf146..677af91b555cefc3dec7536b6c08dd1e831927ab 100644 (file)
@@ -2201,6 +2201,9 @@ static int evergreen_gpu_soft_reset(struct radeon_device *rdev)
        struct evergreen_mc_save save;
        u32 grbm_reset = 0;
 
+       if (!(RREG32(GRBM_STATUS) & GUI_ACTIVE))
+               return 0;
+
        dev_info(rdev->dev, "GPU softreset \n");
        dev_info(rdev->dev, "  GRBM_STATUS=0x%08X\n",
                RREG32(GRBM_STATUS));
index b758dc7f2f2c62ce510850797f1b37ecb85efdd9..d4d4db49a8b8dc88a48b0a09c18bec85f1d9eb8c 100644 (file)
@@ -232,7 +232,7 @@ draw_auto(struct radeon_device *rdev)
 
 }
 
-/* emits 30 */
+/* emits 34 */
 static void
 set_default_state(struct radeon_device *rdev)
 {
@@ -245,6 +245,8 @@ set_default_state(struct radeon_device *rdev)
        int num_hs_threads, num_ls_threads;
        int num_ps_stack_entries, num_vs_stack_entries, num_gs_stack_entries, num_es_stack_entries;
        int num_hs_stack_entries, num_ls_stack_entries;
+       u64 gpu_addr;
+       int dwords;
 
        switch (rdev->family) {
        case CHIP_CEDAR:
@@ -497,6 +499,14 @@ set_default_state(struct radeon_device *rdev)
        radeon_ring_write(rdev, 0x00000000);
        radeon_ring_write(rdev, 0x00000000);
 
+       /* emit an IB pointing at default state */
+       dwords = ALIGN(rdev->r600_blit.state_len, 0x10);
+       gpu_addr = rdev->r600_blit.shader_gpu_addr + rdev->r600_blit.state_offset;
+       radeon_ring_write(rdev, PACKET3(PACKET3_INDIRECT_BUFFER, 2));
+       radeon_ring_write(rdev, gpu_addr & 0xFFFFFFFC);
+       radeon_ring_write(rdev, upper_32_bits(gpu_addr) & 0xFF);
+       radeon_ring_write(rdev, dwords);
+
 }
 
 static inline uint32_t i2f(uint32_t input)
@@ -527,8 +537,10 @@ static inline uint32_t i2f(uint32_t input)
 int evergreen_blit_init(struct radeon_device *rdev)
 {
        u32 obj_size;
-       int r;
+       int r, dwords;
        void *ptr;
+       u32 packet2s[16];
+       int num_packet2s = 0;
 
        /* pin copy shader into vram if already initialized */
        if (rdev->r600_blit.shader_obj)
@@ -536,8 +548,17 @@ int evergreen_blit_init(struct radeon_device *rdev)
 
        mutex_init(&rdev->r600_blit.mutex);
        rdev->r600_blit.state_offset = 0;
-       rdev->r600_blit.state_len = 0;
-       obj_size = 0;
+
+       rdev->r600_blit.state_len = evergreen_default_size;
+
+       dwords = rdev->r600_blit.state_len;
+       while (dwords & 0xf) {
+               packet2s[num_packet2s++] = PACKET2(0);
+               dwords++;
+       }
+
+       obj_size = dwords * 4;
+       obj_size = ALIGN(obj_size, 256);
 
        rdev->r600_blit.vs_offset = obj_size;
        obj_size += evergreen_vs_size * 4;
@@ -567,6 +588,12 @@ int evergreen_blit_init(struct radeon_device *rdev)
                return r;
        }
 
+       memcpy_toio(ptr + rdev->r600_blit.state_offset,
+                   evergreen_default_state, rdev->r600_blit.state_len * 4);
+
+       if (num_packet2s)
+               memcpy_toio(ptr + rdev->r600_blit.state_offset + (rdev->r600_blit.state_len * 4),
+                           packet2s, num_packet2s * 4);
        memcpy(ptr + rdev->r600_blit.vs_offset, evergreen_vs, evergreen_vs_size * 4);
        memcpy(ptr + rdev->r600_blit.ps_offset, evergreen_ps, evergreen_ps_size * 4);
        radeon_bo_kunmap(rdev->r600_blit.shader_obj);
@@ -652,7 +679,7 @@ int evergreen_blit_prepare_copy(struct radeon_device *rdev, int size_bytes)
        /* calculate number of loops correctly */
        ring_size = num_loops * dwords_per_loop;
        /* set default  + shaders */
-       ring_size += 46; /* shaders + def state */
+       ring_size += 50; /* shaders + def state */
        ring_size += 10; /* fence emit for VB IB */
        ring_size += 5; /* done copy */
        ring_size += 10; /* fence emit for done copy */
@@ -660,7 +687,7 @@ int evergreen_blit_prepare_copy(struct radeon_device *rdev, int size_bytes)
        if (r)
                return r;
 
-       set_default_state(rdev); /* 30 */
+       set_default_state(rdev); /* 34 */
        set_shaders(rdev); /* 16 */
        return 0;
 }
index 46da5142b1314da56b716c8feba1eae082e9e7dd..5f15820efe124579534c0654dba191ee6001e689 100644 (file)
@@ -1031,8 +1031,8 @@ int r100_cp_init(struct radeon_device *rdev, unsigned ring_size)
        WREG32(RADEON_CP_CSQ_MODE,
               REG_SET(RADEON_INDIRECT2_START, indirect2_start) |
               REG_SET(RADEON_INDIRECT1_START, indirect1_start));
-       WREG32(0x718, 0);
-       WREG32(0x744, 0x00004D4D);
+       WREG32(RADEON_CP_RB_WPTR_DELAY, 0);
+       WREG32(RADEON_CP_CSQ_MODE, 0x00004D4D);
        WREG32(RADEON_CP_CSQ_CNTL, RADEON_CSQ_PRIBM_INDBM);
        radeon_ring_start(rdev);
        r = radeon_ring_test(rdev);
@@ -2347,10 +2347,10 @@ void r100_vga_set_state(struct radeon_device *rdev, bool state)
 
        temp = RREG32(RADEON_CONFIG_CNTL);
        if (state == false) {
-               temp &= ~(1<<8);
-               temp |= (1<<9);
+               temp &= ~RADEON_CFG_VGA_RAM_EN;
+               temp |= RADEON_CFG_VGA_IO_DIS;
        } else {
-               temp &= ~(1<<9);
+               temp &= ~RADEON_CFG_VGA_IO_DIS;
        }
        WREG32(RADEON_CONFIG_CNTL, temp);
 }
@@ -3522,7 +3522,7 @@ int r100_ring_test(struct radeon_device *rdev)
        if (i < rdev->usec_timeout) {
                DRM_INFO("ring test succeeded in %d usecs\n", i);
        } else {
-               DRM_ERROR("radeon: ring test failed (sracth(0x%04X)=0x%08X)\n",
+               DRM_ERROR("radeon: ring test failed (scratch(0x%04X)=0x%08X)\n",
                          scratch, tmp);
                r = -EINVAL;
        }
index cf862ca580bf898bfb43452ad76edd9b2e78b1c9..55fe5ba7def36e058a11bf71e54fae83b8615ad9 100644 (file)
@@ -69,6 +69,9 @@ void rv370_pcie_gart_tlb_flush(struct radeon_device *rdev)
        mb();
 }
 
+#define R300_PTE_WRITEABLE (1 << 2)
+#define R300_PTE_READABLE  (1 << 3)
+
 int rv370_pcie_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr)
 {
        void __iomem *ptr = (void *)rdev->gart.table.vram.ptr;
@@ -78,7 +81,7 @@ int rv370_pcie_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr)
        }
        addr = (lower_32_bits(addr) >> 8) |
               ((upper_32_bits(addr) & 0xff) << 24) |
-              0xc;
+              R300_PTE_WRITEABLE | R300_PTE_READABLE;
        /* on x86 we want this to be CPU endian, on powerpc
         * on powerpc without HW swappers, it'll get swapped on way
         * into VRAM - so no need for cpu_to_le32 on VRAM tables */
@@ -135,7 +138,7 @@ int rv370_pcie_gart_enable(struct radeon_device *rdev)
        WREG32_PCIE(RADEON_PCIE_TX_DISCARD_RD_ADDR_LO, rdev->mc.vram_start);
        WREG32_PCIE(RADEON_PCIE_TX_DISCARD_RD_ADDR_HI, 0);
        /* Clear error */
-       WREG32_PCIE(0x18, 0);
+       WREG32_PCIE(RADEON_PCIE_TX_GART_ERROR, 0);
        tmp = RREG32_PCIE(RADEON_PCIE_TX_GART_CNTL);
        tmp |= RADEON_PCIE_TX_GART_EN;
        tmp |= RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_DISCARD;
index c387346f93a9d5a924bc6aab769e92aebba8fe91..0b59ed7c7d2cc9c4fa37554911c1a40a69119009 100644 (file)
@@ -96,7 +96,7 @@ void r420_pipes_init(struct radeon_device *rdev)
                       "programming pipes. Bad things might happen.\n");
        }
        /* get max number of pipes */
-       gb_pipe_select = RREG32(0x402C);
+       gb_pipe_select = RREG32(R400_GB_PIPE_SELECT);
        num_pipes = ((gb_pipe_select >> 12) & 3) + 1;
 
        /* SE chips have 1 pipe */
index 3c8677f9e38550f05e9940fd12a728d8178a58c8..2ce80d976568c41b2cba34926ae2264c535bdbef 100644 (file)
@@ -79,8 +79,8 @@ static void r520_gpu_init(struct radeon_device *rdev)
                WREG32(0x4128, 0xFF);
        }
        r420_pipes_init(rdev);
-       gb_pipe_select = RREG32(0x402C);
-       tmp = RREG32(0x170C);
+       gb_pipe_select = RREG32(R400_GB_PIPE_SELECT);
+       tmp = RREG32(R300_DST_PIPE_CONFIG);
        pipe_select_current = (tmp >> 2) & 3;
        tmp = (1 << pipe_select_current) |
              (((gb_pipe_select >> 8) & 0xF) << 4);
index aca2236268fae105ce75c6546a06ba4dfb09fb2d..1e10e3e2ba2a388362bf5ea7cd6ab15b618f3dfa 100644 (file)
@@ -1287,6 +1287,9 @@ int r600_gpu_soft_reset(struct radeon_device *rdev)
                        S_008014_CB2_BUSY(1) | S_008014_CB3_BUSY(1);
        u32 tmp;
 
+       if (!(RREG32(GRBM_STATUS) & GUI_ACTIVE))
+               return 0;
+
        dev_info(rdev->dev, "GPU softreset \n");
        dev_info(rdev->dev, "  R_008010_GRBM_STATUS=0x%08X\n",
                RREG32(R_008010_GRBM_STATUS));
index 33cda016b083be82ca99f6a382da813d28e777a2..f869897c745699ab4494738e390a689081fe4e59 100644 (file)
 #define R600_MEDIUM_VID_LOWER_GPIO_CNTL                            0x720
 #define R600_LOW_VID_LOWER_GPIO_CNTL                               0x724
 
-
+#define R600_D1GRPH_SWAP_CONTROL                               0x610C
+#       define R600_D1GRPH_SWAP_ENDIAN_NONE                    (0 << 0)
+#       define R600_D1GRPH_SWAP_ENDIAN_16BIT                   (1 << 0)
+#       define R600_D1GRPH_SWAP_ENDIAN_32BIT                   (2 << 0)
+#       define R600_D1GRPH_SWAP_ENDIAN_64BIT                   (3 << 0)
 
 #define R600_HDP_NONSURFACE_BASE                                0x2c04
 
index 1573202a6418f655f03906edef82737c21982250..52777902bbcc365c2a2dce237ae79cfe8e120af8 100644 (file)
@@ -387,15 +387,11 @@ static bool radeon_atom_apply_quirks(struct drm_device *dev,
                        *line_mux = 0x90;
        }
 
-       /* mac rv630 */
-       if ((dev->pdev->device == 0x9588) &&
-           (dev->pdev->subsystem_vendor == 0x106b) &&
-           (dev->pdev->subsystem_device == 0x00a6)) {
-               if ((supported_device == ATOM_DEVICE_TV1_SUPPORT) &&
-                   (*connector_type == DRM_MODE_CONNECTOR_DVII)) {
-                       *connector_type = DRM_MODE_CONNECTOR_9PinDIN;
-                       *line_mux = CONNECTOR_7PIN_DIN_ENUM_ID1;
-               }
+       /* mac rv630, rv730, others */
+       if ((supported_device == ATOM_DEVICE_TV1_SUPPORT) &&
+           (*connector_type == DRM_MODE_CONNECTOR_DVII)) {
+               *connector_type = DRM_MODE_CONNECTOR_9PinDIN;
+               *line_mux = CONNECTOR_7PIN_DIN_ENUM_ID1;
        }
 
        /* ASUS HD 3600 XT board lists the DVI port as HDMI */
index 26091d602b848b966dd0342217362abf0218ddcb..0d478932b1a9499ea50ef75d56e1a104a434b546 100644 (file)
@@ -891,9 +891,9 @@ int radeon_suspend_kms(struct drm_device *dev, pm_message_t state)
                pci_disable_device(dev->pdev);
                pci_set_power_state(dev->pdev, PCI_D3hot);
        }
-       acquire_console_sem();
+       console_lock();
        radeon_fbdev_set_suspend(rdev, 1);
-       release_console_sem();
+       console_unlock();
        return 0;
 }
 
@@ -905,11 +905,11 @@ int radeon_resume_kms(struct drm_device *dev)
        if (dev->switch_power_state == DRM_SWITCH_POWER_OFF)
                return 0;
 
-       acquire_console_sem();
+       console_lock();
        pci_set_power_state(dev->pdev, PCI_D0);
        pci_restore_state(dev->pdev);
        if (pci_enable_device(dev->pdev)) {
-               release_console_sem();
+               console_unlock();
                return -1;
        }
        pci_set_master(dev->pdev);
@@ -920,7 +920,7 @@ int radeon_resume_kms(struct drm_device *dev)
        radeon_restore_bios_scratch_regs(rdev);
 
        radeon_fbdev_set_suspend(rdev, 0);
-       release_console_sem();
+       console_unlock();
 
        /* reset hpd state */
        radeon_hpd_init(rdev);
index d5680a0c87af4a557d18e12f30626a98ed6fae59..275b26a708d6505a9f44ae2c8a0b5f45cbf2f971 100644 (file)
@@ -48,7 +48,7 @@
  * - 2.5.0 - add get accel 2 to work around ddx breakage for evergreen
  * - 2.6.0 - add tiling config query (r6xx+), add initial HiZ support (r300->r500)
  *   2.7.0 - fixups for r600 2D tiling support. (no external ABI change), add eg dyn gpr regs
- *   2.8.0 - pageflip support, r500 US_FORMAT regs. r500 ARGB2101010 colorbuf, r300->r500 CMASK
+ *   2.8.0 - pageflip support, r500 US_FORMAT regs. r500 ARGB2101010 colorbuf, r300->r500 CMASK, clock crystal query
  */
 #define KMS_DRIVER_MAJOR       2
 #define KMS_DRIVER_MINOR       8
index 8fd184286c0b8343618bf9d6e0c08e63888a9ce5..5e90984d5ad2817aea7f4dde6bebae7a8d8c50b7 100644 (file)
@@ -641,7 +641,7 @@ atombios_get_encoder_mode(struct drm_encoder *encoder)
        switch (connector->connector_type) {
        case DRM_MODE_CONNECTOR_DVII:
        case DRM_MODE_CONNECTOR_HDMIB: /* HDMI-B is basically DL-DVI; analog works fine */
-               if (drm_detect_monitor_audio(radeon_connector->edid)) {
+               if (drm_detect_monitor_audio(radeon_connector->edid) && radeon_audio) {
                        /* fix me */
                        if (ASIC_IS_DCE4(rdev))
                                return ATOM_ENCODER_MODE_DVI;
@@ -655,7 +655,7 @@ atombios_get_encoder_mode(struct drm_encoder *encoder)
        case DRM_MODE_CONNECTOR_DVID:
        case DRM_MODE_CONNECTOR_HDMIA:
        default:
-               if (drm_detect_monitor_audio(radeon_connector->edid)) {
+               if (drm_detect_monitor_audio(radeon_connector->edid) && radeon_audio) {
                        /* fix me */
                        if (ASIC_IS_DCE4(rdev))
                                return ATOM_ENCODER_MODE_DVI;
@@ -673,7 +673,7 @@ atombios_get_encoder_mode(struct drm_encoder *encoder)
                if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) ||
                    (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP))
                        return ATOM_ENCODER_MODE_DP;
-               else if (drm_detect_monitor_audio(radeon_connector->edid)) {
+               else if (drm_detect_monitor_audio(radeon_connector->edid) && radeon_audio) {
                        /* fix me */
                        if (ASIC_IS_DCE4(rdev))
                                return ATOM_ENCODER_MODE_DVI;
index a289646e8aa46b83a848b4ca9327139593068110..9ec830c77af0be7afdba4c9b32f13f1b277bdbe8 100644 (file)
@@ -110,11 +110,14 @@ void radeon_driver_irq_uninstall_kms(struct drm_device *dev)
 
 int radeon_irq_kms_init(struct radeon_device *rdev)
 {
+       int i;
        int r = 0;
 
        INIT_WORK(&rdev->hotplug_work, radeon_hotplug_work_func);
 
        spin_lock_init(&rdev->irq.sw_lock);
+       for (i = 0; i < rdev->num_crtc; i++)
+               spin_lock_init(&rdev->irq.pflip_lock[i]);
        r = drm_vblank_init(rdev->ddev, rdev->num_crtc);
        if (r) {
                return r;
index 28a53e4a925f0c15a23b0d85dbc8145c1e4036a5..8387d32caaa76be06f95aa79bbb30fda15916f5f 100644 (file)
@@ -201,6 +201,10 @@ int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
                }
                radeon_set_filp_rights(dev, &rdev->cmask_filp, filp, &value);
                break;
+       case RADEON_INFO_CLOCK_CRYSTAL_FREQ:
+               /* return clock value in KHz */
+               value = rdev->clock.spll.reference_freq * 10;
+               break;
        default:
                DRM_DEBUG_KMS("Invalid request %d\n", info->request);
                return -EINVAL;
@@ -243,6 +247,8 @@ void radeon_driver_preclose_kms(struct drm_device *dev,
        struct radeon_device *rdev = dev->dev_private;
        if (rdev->hyperz_filp == file_priv)
                rdev->hyperz_filp = NULL;
+       if (rdev->cmask_filp == file_priv)
+               rdev->cmask_filp = NULL;
 }
 
 /*
index 3cd4dace57c76ed7938e1217984c49c29bce8afd..ec93a75369e671c9b9d0b98407ad5c5e901a4eb2 100644 (file)
 #define RADEON_CONFIG_APER_SIZE             0x0108
 #define RADEON_CONFIG_BONDS                 0x00e8
 #define RADEON_CONFIG_CNTL                  0x00e0
+#       define RADEON_CFG_VGA_RAM_EN        (1 << 8)
+#       define RADEON_CFG_VGA_IO_DIS        (1 << 9)
 #       define RADEON_CFG_ATI_REV_A11       (0   << 16)
 #       define RADEON_CFG_ATI_REV_A12       (1   << 16)
 #       define RADEON_CFG_ATI_REV_A13       (2   << 16)
index 5512e4e5e636ebb91ea73e99d63a4e60bb95bbe6..c76283d9eb3dbd4b0ab40ee5729c2576365f6df1 100644 (file)
@@ -203,6 +203,9 @@ void rs400_gart_fini(struct radeon_device *rdev)
        radeon_gart_table_ram_free(rdev);
 }
 
+#define RS400_PTE_WRITEABLE (1 << 2)
+#define RS400_PTE_READABLE  (1 << 3)
+
 int rs400_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr)
 {
        uint32_t entry;
@@ -213,7 +216,7 @@ int rs400_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr)
 
        entry = (lower_32_bits(addr) & PAGE_MASK) |
                ((upper_32_bits(addr) & 0xff) << 4) |
-               0xc;
+               RS400_PTE_WRITEABLE | RS400_PTE_READABLE;
        entry = cpu_to_le32(entry);
        rdev->gart.table.ram.ptr[i] = entry;
        return 0;
@@ -226,8 +229,8 @@ int rs400_mc_wait_for_idle(struct radeon_device *rdev)
 
        for (i = 0; i < rdev->usec_timeout; i++) {
                /* read MC_STATUS */
-               tmp = RREG32(0x0150);
-               if (tmp & (1 << 2)) {
+               tmp = RREG32(RADEON_MC_STATUS);
+               if (tmp & RADEON_MC_IDLE) {
                        return 0;
                }
                DRM_UDELAY(1);
@@ -241,7 +244,7 @@ void rs400_gpu_init(struct radeon_device *rdev)
        r420_pipes_init(rdev);
        if (rs400_mc_wait_for_idle(rdev)) {
                printk(KERN_WARNING "rs400: Failed to wait MC idle while "
-                      "programming pipes. Bad things might happen. %08x\n", RREG32(0x150));
+                      "programming pipes. Bad things might happen. %08x\n", RREG32(RADEON_MC_STATUS));
        }
 }
 
@@ -300,9 +303,9 @@ static int rs400_debugfs_gart_info(struct seq_file *m, void *data)
                seq_printf(m, "MCCFG_AGP_BASE_2 0x%08x\n", tmp);
                tmp = RREG32_MC(RS690_MCCFG_AGP_LOCATION);
                seq_printf(m, "MCCFG_AGP_LOCATION 0x%08x\n", tmp);
-               tmp = RREG32_MC(0x100);
+               tmp = RREG32_MC(RS690_MCCFG_FB_LOCATION);
                seq_printf(m, "MCCFG_FB_LOCATION 0x%08x\n", tmp);
-               tmp = RREG32(0x134);
+               tmp = RREG32(RS690_HDP_FB_LOCATION);
                seq_printf(m, "HDP_FB_LOCATION 0x%08x\n", tmp);
        } else {
                tmp = RREG32(RADEON_AGP_BASE);
index 5d569f41f4aeadbe04ee1d1c21cb165d4bf8c338..64b57af937143bd84ac8d31b0383ad91614c51e0 100644 (file)
@@ -69,13 +69,13 @@ void rv515_ring_start(struct radeon_device *rdev)
                          ISYNC_CPSCRATCH_IDLEGUI);
        radeon_ring_write(rdev, PACKET0(WAIT_UNTIL, 0));
        radeon_ring_write(rdev, WAIT_2D_IDLECLEAN | WAIT_3D_IDLECLEAN);
-       radeon_ring_write(rdev, PACKET0(0x170C, 0));
-       radeon_ring_write(rdev, 1 << 31);
+       radeon_ring_write(rdev, PACKET0(R300_DST_PIPE_CONFIG, 0));
+       radeon_ring_write(rdev, R300_PIPE_AUTO_CONFIG);
        radeon_ring_write(rdev, PACKET0(GB_SELECT, 0));
        radeon_ring_write(rdev, 0);
        radeon_ring_write(rdev, PACKET0(GB_ENABLE, 0));
        radeon_ring_write(rdev, 0);
-       radeon_ring_write(rdev, PACKET0(0x42C8, 0));
+       radeon_ring_write(rdev, PACKET0(R500_SU_REG_DEST, 0));
        radeon_ring_write(rdev, (1 << rdev->num_gb_pipes) - 1);
        radeon_ring_write(rdev, PACKET0(VAP_INDEX_OFFSET, 0));
        radeon_ring_write(rdev, 0);
@@ -153,8 +153,8 @@ void rv515_gpu_init(struct radeon_device *rdev)
        }
        rv515_vga_render_disable(rdev);
        r420_pipes_init(rdev);
-       gb_pipe_select = RREG32(0x402C);
-       tmp = RREG32(0x170C);
+       gb_pipe_select = RREG32(R400_GB_PIPE_SELECT);
+       tmp = RREG32(R300_DST_PIPE_CONFIG);
        pipe_select_current = (tmp >> 2) & 3;
        tmp = (1 << pipe_select_current) |
              (((gb_pipe_select >> 8) & 0xF) << 4);
index 09aea5f1556da96d756c4ce04d104f226873c97f..70e60a4bb678e0c1ed669badc4ceb3e69be5c9e5 100644 (file)
@@ -1,11 +1,13 @@
 config STUB_POULSBO
        tristate "Intel GMA500 Stub Driver"
        depends on PCI
+       depends on NET # for THERMAL
        # Poulsbo stub depends on ACPI_VIDEO when ACPI is enabled
        # but for select to work, need to select ACPI_VIDEO's dependencies, ick
        select BACKLIGHT_CLASS_DEVICE if ACPI
        select INPUT if ACPI
        select ACPI_VIDEO if ACPI
+       select THERMAL if ACPI
        help
          Choose this option if you have a system that has Intel GMA500
          (Poulsbo) integrated graphics. If M is selected, the module will
index c380c65da41798faf91b9e730f585be97a7b49d6..ace2b1623b214671d6e49e115d4b3c2f3755230e 100644 (file)
@@ -636,7 +636,7 @@ int vga_client_register(struct pci_dev *pdev, void *cookie,
                        void (*irq_set_state)(void *cookie, bool state),
                        unsigned int (*set_vga_decode)(void *cookie, bool decode))
 {
-       int ret = -1;
+       int ret = -ENODEV;
        struct vga_device *vgadev;
        unsigned long flags;
 
index ce0372f0615ebd37474a1ab9e93ecc3a3d40e79f..4c0743660e9c7684c12184b9824c94ffe655f4eb 100644 (file)
@@ -1072,6 +1072,7 @@ static int applesmc_create_nodes(struct applesmc_node_group *groups, int num)
                        node->sda.dev_attr.show = grp->show;
                        node->sda.dev_attr.store = grp->store;
                        attr = &node->sda.dev_attr.attr;
+                       sysfs_attr_init(attr);
                        attr->name = node->name;
                        attr->mode = S_IRUGO | (grp->store ? S_IWUSR : 0);
                        ret = sysfs_create_file(&pdev->dev.kobj, attr);
index 2d68cf3c223b7cb401a76481d9064aa040ea2eef..b5e892017e0c57497f7726d59812a56144f35ea8 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/list.h>
 #include <linux/module.h>
 #include <linux/slab.h>
+#include <linux/dmi.h>
 
 #include <acpi/acpi.h>
 #include <acpi/acpixf.h>
 
 #define ATK_HID "ATK0110"
 
+static bool new_if;
+module_param(new_if, bool, 0);
+MODULE_PARM_DESC(new_if, "Override detection heuristic and force the use of the new ATK0110 interface");
+
+static const struct dmi_system_id __initconst atk_force_new_if[] = {
+       {
+               /* Old interface has broken MCH temp monitoring */
+               .ident = "Asus Sabertooth X58",
+               .matches = {
+                       DMI_MATCH(DMI_BOARD_NAME, "SABERTOOTH X58")
+               }
+       },
+       { }
+};
+
 /* Minimum time between readings, enforced in order to avoid
  * hogging the CPU.
  */
@@ -1302,7 +1318,9 @@ static int atk_probe_if(struct atk_data *data)
         * analysis of multiple DSDTs indicates that when both interfaces
         * are present the new one (GGRP/GITM) is not functional.
         */
-       if (data->rtmp_handle && data->rvlt_handle && data->rfan_handle)
+       if (new_if)
+               dev_info(dev, "Overriding interface detection\n");
+       if (data->rtmp_handle && data->rvlt_handle && data->rfan_handle && !new_if)
                data->old_interface = true;
        else if (data->enumerate_handle && data->read_handle &&
                        data->write_handle)
@@ -1420,6 +1438,9 @@ static int __init atk0110_init(void)
                return -EBUSY;
        }
 
+       if (dmi_check_system(atk_force_new_if))
+               new_if = true;
+
        ret = acpi_bus_register_driver(&atk_driver);
        if (ret)
                pr_info("acpi_bus_register_driver failed: %d\n", ret);
index 1b674b7d4584ee74b1f8399f87ea9d5e62c22dfc..d805e8e579671d4218a9e1517a487aca1daed761 100644 (file)
@@ -957,7 +957,7 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
 
        /* bail if we did not get an IRQ from the bus layer */
        if (!dev->irq) {
-               pr_err("No IRQ. Disabling /dev/freefall\n");
+               pr_debug("No IRQ. Disabling /dev/freefall\n");
                goto out;
        }
 
index 7acb32e7f8173de556aaa2fa93db2fecae20603a..1fa091e05690fe345817c9858b7c020e7c005eec 100644 (file)
@@ -263,7 +263,7 @@ static void __setup_broadcast_timer(void *arg)
        clockevents_notify(reason, &cpu);
 }
 
-static int __cpuinit setup_broadcast_cpuhp_notify(struct notifier_block *n,
+static int setup_broadcast_cpuhp_notify(struct notifier_block *n,
                unsigned long action, void *hcpu)
 {
        int hotcpu = (unsigned long)hcpu;
@@ -273,15 +273,11 @@ static int __cpuinit setup_broadcast_cpuhp_notify(struct notifier_block *n,
                smp_call_function_single(hotcpu, __setup_broadcast_timer,
                        (void *)true, 1);
                break;
-       case CPU_DOWN_PREPARE:
-               smp_call_function_single(hotcpu, __setup_broadcast_timer,
-                       (void *)false, 1);
-               break;
        }
        return NOTIFY_OK;
 }
 
-static struct notifier_block __cpuinitdata setup_broadcast_notifier = {
+static struct notifier_block setup_broadcast_notifier = {
        .notifier_call = setup_broadcast_cpuhp_notify,
 };
 
index 417507348babea8fd204418dc6096b19836b95d2..c7a92028f450953b264ac6d8d950eeef9135c4a6 100644 (file)
@@ -343,6 +343,16 @@ config KEYBOARD_NOMADIK
          To compile this driver as a module, choose M here: the
          module will be called nmk-ske-keypad.
 
+config KEYBOARD_TEGRA
+       tristate "NVIDIA Tegra internal matrix keyboard controller support"
+       depends on ARCH_TEGRA
+       help
+         Say Y here if you want to use a matrix keyboard connected directly
+         to the internal keyboard controller on Tegra SoCs.
+
+         To compile this driver as a module, choose M here: the
+         module will be called tegra-kbc.
+
 config KEYBOARD_OPENCORES
        tristate "OpenCores Keyboard Controller"
        help
index 4e5571b72cda460ddda5363f1738dbeef2c103b7..468c627a28447efb78b9fb32b9a35351719d4f06 100644 (file)
@@ -42,6 +42,7 @@ obj-$(CONFIG_KEYBOARD_STMPE)          += stmpe-keypad.o
 obj-$(CONFIG_KEYBOARD_STOWAWAY)                += stowaway.o
 obj-$(CONFIG_KEYBOARD_SUNKBD)          += sunkbd.o
 obj-$(CONFIG_KEYBOARD_TC3589X)         += tc3589x-keypad.o
+obj-$(CONFIG_KEYBOARD_TEGRA)           += tegra-kbc.o
 obj-$(CONFIG_KEYBOARD_TNETV107X)       += tnetv107x-keypad.o
 obj-$(CONFIG_KEYBOARD_TWL4030)         += twl4030_keypad.o
 obj-$(CONFIG_KEYBOARD_XTKBD)           += xtkbd.o
index 6069abe31e42b0b4a8f17cf0f08ac91ff4de3fe4..eb3006361ee4440179b46377e272f97e6c7010b3 100644 (file)
@@ -322,7 +322,7 @@ static void gpio_keys_report_event(struct gpio_button_data *bdata)
        struct gpio_keys_button *button = bdata->button;
        struct input_dev *input = bdata->input;
        unsigned int type = button->type ?: EV_KEY;
-       int state = (gpio_get_value(button->gpio) ? 1 : 0) ^ button->active_low;
+       int state = (gpio_get_value_cansleep(button->gpio) ? 1 : 0) ^ button->active_low;
 
        input_event(input, type, button->code, !!state);
        input_sync(input);
@@ -410,8 +410,8 @@ static int __devinit gpio_keys_setup_key(struct platform_device *pdev,
        if (!button->can_disable)
                irqflags |= IRQF_SHARED;
 
-       error = request_irq(irq, gpio_keys_isr, irqflags, desc, bdata);
-       if (error) {
+       error = request_any_context_irq(irq, gpio_keys_isr, irqflags, desc, bdata);
+       if (error < 0) {
                dev_err(dev, "Unable to claim irq %d; error %d\n",
                        irq, error);
                goto fail3;
diff --git a/drivers/input/keyboard/tegra-kbc.c b/drivers/input/keyboard/tegra-kbc.c
new file mode 100644 (file)
index 0000000..ac471b7
--- /dev/null
@@ -0,0 +1,727 @@
+/*
+ * Keyboard class input driver for the NVIDIA Tegra SoC internal matrix
+ * keyboard controller
+ *
+ * Copyright (c) 2009-2011, NVIDIA Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/input.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/interrupt.h>
+#include <linux/clk.h>
+#include <linux/slab.h>
+#include <mach/clk.h>
+#include <mach/kbc.h>
+
+#define KBC_MAX_DEBOUNCE_CNT   0x3ffu
+
+/* KBC row scan time and delay for beginning the row scan. */
+#define KBC_ROW_SCAN_TIME      16
+#define KBC_ROW_SCAN_DLY       5
+
+/* KBC uses a 32KHz clock so a cycle = 1/32Khz */
+#define KBC_CYCLE_USEC 32
+
+/* KBC Registers */
+
+/* KBC Control Register */
+#define KBC_CONTROL_0  0x0
+#define KBC_FIFO_TH_CNT_SHIFT(cnt)     (cnt << 14)
+#define KBC_DEBOUNCE_CNT_SHIFT(cnt)    (cnt << 4)
+#define KBC_CONTROL_FIFO_CNT_INT_EN    (1 << 3)
+#define KBC_CONTROL_KBC_EN             (1 << 0)
+
+/* KBC Interrupt Register */
+#define KBC_INT_0      0x4
+#define KBC_INT_FIFO_CNT_INT_STATUS    (1 << 2)
+
+#define KBC_ROW_CFG0_0 0x8
+#define KBC_COL_CFG0_0 0x18
+#define KBC_INIT_DLY_0 0x28
+#define KBC_RPT_DLY_0  0x2c
+#define KBC_KP_ENT0_0  0x30
+#define KBC_KP_ENT1_0  0x34
+#define KBC_ROW0_MASK_0        0x38
+
+#define KBC_ROW_SHIFT  3
+
+struct tegra_kbc {
+       void __iomem *mmio;
+       struct input_dev *idev;
+       unsigned int irq;
+       unsigned int wake_enable_rows;
+       unsigned int wake_enable_cols;
+       spinlock_t lock;
+       unsigned int repoll_dly;
+       unsigned long cp_dly_jiffies;
+       const struct tegra_kbc_platform_data *pdata;
+       unsigned short keycode[KBC_MAX_KEY];
+       unsigned short current_keys[KBC_MAX_KPENT];
+       unsigned int num_pressed_keys;
+       struct timer_list timer;
+       struct clk *clk;
+};
+
+static const u32 tegra_kbc_default_keymap[] = {
+       KEY(0, 2, KEY_W),
+       KEY(0, 3, KEY_S),
+       KEY(0, 4, KEY_A),
+       KEY(0, 5, KEY_Z),
+       KEY(0, 7, KEY_FN),
+
+       KEY(1, 7, KEY_LEFTMETA),
+
+       KEY(2, 6, KEY_RIGHTALT),
+       KEY(2, 7, KEY_LEFTALT),
+
+       KEY(3, 0, KEY_5),
+       KEY(3, 1, KEY_4),
+       KEY(3, 2, KEY_R),
+       KEY(3, 3, KEY_E),
+       KEY(3, 4, KEY_F),
+       KEY(3, 5, KEY_D),
+       KEY(3, 6, KEY_X),
+
+       KEY(4, 0, KEY_7),
+       KEY(4, 1, KEY_6),
+       KEY(4, 2, KEY_T),
+       KEY(4, 3, KEY_H),
+       KEY(4, 4, KEY_G),
+       KEY(4, 5, KEY_V),
+       KEY(4, 6, KEY_C),
+       KEY(4, 7, KEY_SPACE),
+
+       KEY(5, 0, KEY_9),
+       KEY(5, 1, KEY_8),
+       KEY(5, 2, KEY_U),
+       KEY(5, 3, KEY_Y),
+       KEY(5, 4, KEY_J),
+       KEY(5, 5, KEY_N),
+       KEY(5, 6, KEY_B),
+       KEY(5, 7, KEY_BACKSLASH),
+
+       KEY(6, 0, KEY_MINUS),
+       KEY(6, 1, KEY_0),
+       KEY(6, 2, KEY_O),
+       KEY(6, 3, KEY_I),
+       KEY(6, 4, KEY_L),
+       KEY(6, 5, KEY_K),
+       KEY(6, 6, KEY_COMMA),
+       KEY(6, 7, KEY_M),
+
+       KEY(7, 1, KEY_EQUAL),
+       KEY(7, 2, KEY_RIGHTBRACE),
+       KEY(7, 3, KEY_ENTER),
+       KEY(7, 7, KEY_MENU),
+
+       KEY(8, 4, KEY_RIGHTSHIFT),
+       KEY(8, 5, KEY_LEFTSHIFT),
+
+       KEY(9, 5, KEY_RIGHTCTRL),
+       KEY(9, 7, KEY_LEFTCTRL),
+
+       KEY(11, 0, KEY_LEFTBRACE),
+       KEY(11, 1, KEY_P),
+       KEY(11, 2, KEY_APOSTROPHE),
+       KEY(11, 3, KEY_SEMICOLON),
+       KEY(11, 4, KEY_SLASH),
+       KEY(11, 5, KEY_DOT),
+
+       KEY(12, 0, KEY_F10),
+       KEY(12, 1, KEY_F9),
+       KEY(12, 2, KEY_BACKSPACE),
+       KEY(12, 3, KEY_3),
+       KEY(12, 4, KEY_2),
+       KEY(12, 5, KEY_UP),
+       KEY(12, 6, KEY_PRINT),
+       KEY(12, 7, KEY_PAUSE),
+
+       KEY(13, 0, KEY_INSERT),
+       KEY(13, 1, KEY_DELETE),
+       KEY(13, 3, KEY_PAGEUP),
+       KEY(13, 4, KEY_PAGEDOWN),
+       KEY(13, 5, KEY_RIGHT),
+       KEY(13, 6, KEY_DOWN),
+       KEY(13, 7, KEY_LEFT),
+
+       KEY(14, 0, KEY_F11),
+       KEY(14, 1, KEY_F12),
+       KEY(14, 2, KEY_F8),
+       KEY(14, 3, KEY_Q),
+       KEY(14, 4, KEY_F4),
+       KEY(14, 5, KEY_F3),
+       KEY(14, 6, KEY_1),
+       KEY(14, 7, KEY_F7),
+
+       KEY(15, 0, KEY_ESC),
+       KEY(15, 1, KEY_GRAVE),
+       KEY(15, 2, KEY_F5),
+       KEY(15, 3, KEY_TAB),
+       KEY(15, 4, KEY_F1),
+       KEY(15, 5, KEY_F2),
+       KEY(15, 6, KEY_CAPSLOCK),
+       KEY(15, 7, KEY_F6),
+};
+
+static const struct matrix_keymap_data tegra_kbc_default_keymap_data = {
+       .keymap         = tegra_kbc_default_keymap,
+       .keymap_size    = ARRAY_SIZE(tegra_kbc_default_keymap),
+};
+
+static void tegra_kbc_report_released_keys(struct input_dev *input,
+                                          unsigned short old_keycodes[],
+                                          unsigned int old_num_keys,
+                                          unsigned short new_keycodes[],
+                                          unsigned int new_num_keys)
+{
+       unsigned int i, j;
+
+       for (i = 0; i < old_num_keys; i++) {
+               for (j = 0; j < new_num_keys; j++)
+                       if (old_keycodes[i] == new_keycodes[j])
+                               break;
+
+               if (j == new_num_keys)
+                       input_report_key(input, old_keycodes[i], 0);
+       }
+}
+
+static void tegra_kbc_report_pressed_keys(struct input_dev *input,
+                                         unsigned char scancodes[],
+                                         unsigned short keycodes[],
+                                         unsigned int num_pressed_keys)
+{
+       unsigned int i;
+
+       for (i = 0; i < num_pressed_keys; i++) {
+               input_event(input, EV_MSC, MSC_SCAN, scancodes[i]);
+               input_report_key(input, keycodes[i], 1);
+       }
+}
+
+static void tegra_kbc_report_keys(struct tegra_kbc *kbc)
+{
+       unsigned char scancodes[KBC_MAX_KPENT];
+       unsigned short keycodes[KBC_MAX_KPENT];
+       u32 val = 0;
+       unsigned int i;
+       unsigned int num_down = 0;
+       unsigned long flags;
+
+       spin_lock_irqsave(&kbc->lock, flags);
+       for (i = 0; i < KBC_MAX_KPENT; i++) {
+               if ((i % 4) == 0)
+                       val = readl(kbc->mmio + KBC_KP_ENT0_0 + i);
+
+               if (val & 0x80) {
+                       unsigned int col = val & 0x07;
+                       unsigned int row = (val >> 3) & 0x0f;
+                       unsigned char scancode =
+                               MATRIX_SCAN_CODE(row, col, KBC_ROW_SHIFT);
+
+                       scancodes[num_down] = scancode;
+                       keycodes[num_down++] = kbc->keycode[scancode];
+               }
+
+               val >>= 8;
+       }
+       spin_unlock_irqrestore(&kbc->lock, flags);
+
+       tegra_kbc_report_released_keys(kbc->idev,
+                                      kbc->current_keys, kbc->num_pressed_keys,
+                                      keycodes, num_down);
+       tegra_kbc_report_pressed_keys(kbc->idev, scancodes, keycodes, num_down);
+       input_sync(kbc->idev);
+
+       memcpy(kbc->current_keys, keycodes, sizeof(kbc->current_keys));
+       kbc->num_pressed_keys = num_down;
+}
+
+static void tegra_kbc_keypress_timer(unsigned long data)
+{
+       struct tegra_kbc *kbc = (struct tegra_kbc *)data;
+       unsigned long flags;
+       u32 val;
+       unsigned int i;
+
+       val = (readl(kbc->mmio + KBC_INT_0) >> 4) & 0xf;
+       if (val) {
+               unsigned long dly;
+
+               tegra_kbc_report_keys(kbc);
+
+               /*
+                * If more than one keys are pressed we need not wait
+                * for the repoll delay.
+                */
+               dly = (val == 1) ? kbc->repoll_dly : 1;
+               mod_timer(&kbc->timer, jiffies + msecs_to_jiffies(dly));
+       } else {
+               /* Release any pressed keys and exit the polling loop */
+               for (i = 0; i < kbc->num_pressed_keys; i++)
+                       input_report_key(kbc->idev, kbc->current_keys[i], 0);
+               input_sync(kbc->idev);
+
+               kbc->num_pressed_keys = 0;
+
+               /* All keys are released so enable the keypress interrupt */
+               spin_lock_irqsave(&kbc->lock, flags);
+               val = readl(kbc->mmio + KBC_CONTROL_0);
+               val |= KBC_CONTROL_FIFO_CNT_INT_EN;
+               writel(val, kbc->mmio + KBC_CONTROL_0);
+               spin_unlock_irqrestore(&kbc->lock, flags);
+       }
+}
+
+static irqreturn_t tegra_kbc_isr(int irq, void *args)
+{
+       struct tegra_kbc *kbc = args;
+       u32 val, ctl;
+
+       /*
+        * Until all keys are released, defer further processing to
+        * the polling loop in tegra_kbc_keypress_timer
+        */
+       ctl = readl(kbc->mmio + KBC_CONTROL_0);
+       ctl &= ~KBC_CONTROL_FIFO_CNT_INT_EN;
+       writel(ctl, kbc->mmio + KBC_CONTROL_0);
+
+       /*
+        * Quickly bail out & reenable interrupts if the fifo threshold
+        * count interrupt wasn't the interrupt source
+        */
+       val = readl(kbc->mmio + KBC_INT_0);
+       writel(val, kbc->mmio + KBC_INT_0);
+
+       if (val & KBC_INT_FIFO_CNT_INT_STATUS) {
+               /*
+                * Schedule timer to run when hardware is in continuous
+                * polling mode.
+                */
+               mod_timer(&kbc->timer, jiffies + kbc->cp_dly_jiffies);
+       } else {
+               ctl |= KBC_CONTROL_FIFO_CNT_INT_EN;
+               writel(ctl, kbc->mmio + KBC_CONTROL_0);
+       }
+
+       return IRQ_HANDLED;
+}
+
+static void tegra_kbc_setup_wakekeys(struct tegra_kbc *kbc, bool filter)
+{
+       const struct tegra_kbc_platform_data *pdata = kbc->pdata;
+       int i;
+       unsigned int rst_val;
+
+       BUG_ON(pdata->wake_cnt > KBC_MAX_KEY);
+       rst_val = (filter && pdata->wake_cnt) ? ~0 : 0;
+
+       for (i = 0; i < KBC_MAX_ROW; i++)
+               writel(rst_val, kbc->mmio + KBC_ROW0_MASK_0 + i * 4);
+
+       if (filter) {
+               for (i = 0; i < pdata->wake_cnt; i++) {
+                       u32 val, addr;
+                       addr = pdata->wake_cfg[i].row * 4 + KBC_ROW0_MASK_0;
+                       val = readl(kbc->mmio + addr);
+                       val &= ~(1 << pdata->wake_cfg[i].col);
+                       writel(val, kbc->mmio + addr);
+               }
+       }
+}
+
+static void tegra_kbc_config_pins(struct tegra_kbc *kbc)
+{
+       const struct tegra_kbc_platform_data *pdata = kbc->pdata;
+       int i;
+
+       for (i = 0; i < KBC_MAX_GPIO; i++) {
+               u32 r_shft = 5 * (i % 6);
+               u32 c_shft = 4 * (i % 8);
+               u32 r_mask = 0x1f << r_shft;
+               u32 c_mask = 0x0f << c_shft;
+               u32 r_offs = (i / 6) * 4 + KBC_ROW_CFG0_0;
+               u32 c_offs = (i / 8) * 4 + KBC_COL_CFG0_0;
+               u32 row_cfg = readl(kbc->mmio + r_offs);
+               u32 col_cfg = readl(kbc->mmio + c_offs);
+
+               row_cfg &= ~r_mask;
+               col_cfg &= ~c_mask;
+
+               if (pdata->pin_cfg[i].is_row)
+                       row_cfg |= ((pdata->pin_cfg[i].num << 1) | 1) << r_shft;
+               else
+                       col_cfg |= ((pdata->pin_cfg[i].num << 1) | 1) << c_shft;
+
+               writel(row_cfg, kbc->mmio + r_offs);
+               writel(col_cfg, kbc->mmio + c_offs);
+       }
+}
+
+static int tegra_kbc_start(struct tegra_kbc *kbc)
+{
+       const struct tegra_kbc_platform_data *pdata = kbc->pdata;
+       unsigned long flags;
+       unsigned int debounce_cnt;
+       u32 val = 0;
+
+       clk_enable(kbc->clk);
+
+       /* Reset the KBC controller to clear all previous status.*/
+       tegra_periph_reset_assert(kbc->clk);
+       udelay(100);
+       tegra_periph_reset_deassert(kbc->clk);
+       udelay(100);
+
+       tegra_kbc_config_pins(kbc);
+       tegra_kbc_setup_wakekeys(kbc, false);
+
+       writel(pdata->repeat_cnt, kbc->mmio + KBC_RPT_DLY_0);
+
+       /* Keyboard debounce count is maximum of 12 bits. */
+       debounce_cnt = min(pdata->debounce_cnt, KBC_MAX_DEBOUNCE_CNT);
+       val = KBC_DEBOUNCE_CNT_SHIFT(debounce_cnt);
+       val |= KBC_FIFO_TH_CNT_SHIFT(1); /* set fifo interrupt threshold to 1 */
+       val |= KBC_CONTROL_FIFO_CNT_INT_EN;  /* interrupt on FIFO threshold */
+       val |= KBC_CONTROL_KBC_EN;     /* enable */
+       writel(val, kbc->mmio + KBC_CONTROL_0);
+
+       /*
+        * Compute the delay(ns) from interrupt mode to continuous polling
+        * mode so the timer routine is scheduled appropriately.
+        */
+       val = readl(kbc->mmio + KBC_INIT_DLY_0);
+       kbc->cp_dly_jiffies = usecs_to_jiffies((val & 0xfffff) * 32);
+
+       kbc->num_pressed_keys = 0;
+
+       /*
+        * Atomically clear out any remaining entries in the key FIFO
+        * and enable keyboard interrupts.
+        */
+       spin_lock_irqsave(&kbc->lock, flags);
+       while (1) {
+               val = readl(kbc->mmio + KBC_INT_0);
+               val >>= 4;
+               if (!val)
+                       break;
+
+               val = readl(kbc->mmio + KBC_KP_ENT0_0);
+               val = readl(kbc->mmio + KBC_KP_ENT1_0);
+       }
+       writel(0x7, kbc->mmio + KBC_INT_0);
+       spin_unlock_irqrestore(&kbc->lock, flags);
+
+       enable_irq(kbc->irq);
+
+       return 0;
+}
+
+static void tegra_kbc_stop(struct tegra_kbc *kbc)
+{
+       unsigned long flags;
+       u32 val;
+
+       spin_lock_irqsave(&kbc->lock, flags);
+       val = readl(kbc->mmio + KBC_CONTROL_0);
+       val &= ~1;
+       writel(val, kbc->mmio + KBC_CONTROL_0);
+       spin_unlock_irqrestore(&kbc->lock, flags);
+
+       disable_irq(kbc->irq);
+       del_timer_sync(&kbc->timer);
+
+       clk_disable(kbc->clk);
+}
+
+static int tegra_kbc_open(struct input_dev *dev)
+{
+       struct tegra_kbc *kbc = input_get_drvdata(dev);
+
+       return tegra_kbc_start(kbc);
+}
+
+static void tegra_kbc_close(struct input_dev *dev)
+{
+       struct tegra_kbc *kbc = input_get_drvdata(dev);
+
+       return tegra_kbc_stop(kbc);
+}
+
+static bool __devinit
+tegra_kbc_check_pin_cfg(const struct tegra_kbc_platform_data *pdata,
+                       struct device *dev, unsigned int *num_rows)
+{
+       int i;
+
+       *num_rows = 0;
+
+       for (i = 0; i < KBC_MAX_GPIO; i++) {
+               const struct tegra_kbc_pin_cfg *pin_cfg = &pdata->pin_cfg[i];
+
+               if (pin_cfg->is_row) {
+                       if (pin_cfg->num >= KBC_MAX_ROW) {
+                               dev_err(dev,
+                                       "pin_cfg[%d]: invalid row number %d\n",
+                                       i, pin_cfg->num);
+                               return false;
+                       }
+                       (*num_rows)++;
+               } else {
+                       if (pin_cfg->num >= KBC_MAX_COL) {
+                               dev_err(dev,
+                                       "pin_cfg[%d]: invalid column number %d\n",
+                                       i, pin_cfg->num);
+                               return false;
+                       }
+               }
+       }
+
+       return true;
+}
+
+static int __devinit tegra_kbc_probe(struct platform_device *pdev)
+{
+       const struct tegra_kbc_platform_data *pdata = pdev->dev.platform_data;
+       const struct matrix_keymap_data *keymap_data;
+       struct tegra_kbc *kbc;
+       struct input_dev *input_dev;
+       struct resource *res;
+       int irq;
+       int err;
+       int i;
+       int num_rows = 0;
+       unsigned int debounce_cnt;
+       unsigned int scan_time_rows;
+
+       if (!pdata)
+               return -EINVAL;
+
+       if (!tegra_kbc_check_pin_cfg(pdata, &pdev->dev, &num_rows))
+               return -EINVAL;
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!res) {
+               dev_err(&pdev->dev, "failed to get I/O memory\n");
+               return -ENXIO;
+       }
+
+       irq = platform_get_irq(pdev, 0);
+       if (irq < 0) {
+               dev_err(&pdev->dev, "failed to get keyboard IRQ\n");
+               return -ENXIO;
+       }
+
+       kbc = kzalloc(sizeof(*kbc), GFP_KERNEL);
+       input_dev = input_allocate_device();
+       if (!kbc || !input_dev) {
+               err = -ENOMEM;
+               goto err_free_mem;
+       }
+
+       kbc->pdata = pdata;
+       kbc->idev = input_dev;
+       kbc->irq = irq;
+       spin_lock_init(&kbc->lock);
+       setup_timer(&kbc->timer, tegra_kbc_keypress_timer, (unsigned long)kbc);
+
+       res = request_mem_region(res->start, resource_size(res), pdev->name);
+       if (!res) {
+               dev_err(&pdev->dev, "failed to request I/O memory\n");
+               err = -EBUSY;
+               goto err_free_mem;
+       }
+
+       kbc->mmio = ioremap(res->start, resource_size(res));
+       if (!kbc->mmio) {
+               dev_err(&pdev->dev, "failed to remap I/O memory\n");
+               err = -ENXIO;
+               goto err_free_mem_region;
+       }
+
+       kbc->clk = clk_get(&pdev->dev, NULL);
+       if (IS_ERR(kbc->clk)) {
+               dev_err(&pdev->dev, "failed to get keyboard clock\n");
+               err = PTR_ERR(kbc->clk);
+               goto err_iounmap;
+       }
+
+       kbc->wake_enable_rows = 0;
+       kbc->wake_enable_cols = 0;
+       for (i = 0; i < pdata->wake_cnt; i++) {
+               kbc->wake_enable_rows |= (1 << pdata->wake_cfg[i].row);
+               kbc->wake_enable_cols |= (1 << pdata->wake_cfg[i].col);
+       }
+
+       /*
+        * The time delay between two consecutive reads of the FIFO is
+        * the sum of the repeat time and the time taken for scanning
+        * the rows. There is an additional delay before the row scanning
+        * starts. The repoll delay is computed in milliseconds.
+        */
+       debounce_cnt = min(pdata->debounce_cnt, KBC_MAX_DEBOUNCE_CNT);
+       scan_time_rows = (KBC_ROW_SCAN_TIME + debounce_cnt) * num_rows;
+       kbc->repoll_dly = KBC_ROW_SCAN_DLY + scan_time_rows + pdata->repeat_cnt;
+       kbc->repoll_dly = ((kbc->repoll_dly * KBC_CYCLE_USEC) + 999) / 1000;
+
+       input_dev->name = pdev->name;
+       input_dev->id.bustype = BUS_HOST;
+       input_dev->dev.parent = &pdev->dev;
+       input_dev->open = tegra_kbc_open;
+       input_dev->close = tegra_kbc_close;
+
+       input_set_drvdata(input_dev, kbc);
+
+       input_dev->evbit[0] = BIT_MASK(EV_KEY);
+       input_set_capability(input_dev, EV_MSC, MSC_SCAN);
+
+       input_dev->keycode = kbc->keycode;
+       input_dev->keycodesize = sizeof(kbc->keycode[0]);
+       input_dev->keycodemax = ARRAY_SIZE(kbc->keycode);
+
+       keymap_data = pdata->keymap_data ?: &tegra_kbc_default_keymap_data;
+       matrix_keypad_build_keymap(keymap_data, KBC_ROW_SHIFT,
+                                  input_dev->keycode, input_dev->keybit);
+
+       err = request_irq(kbc->irq, tegra_kbc_isr, IRQF_TRIGGER_HIGH,
+                         pdev->name, kbc);
+       if (err) {
+               dev_err(&pdev->dev, "failed to request keyboard IRQ\n");
+               goto err_put_clk;
+       }
+
+       disable_irq(kbc->irq);
+
+       err = input_register_device(kbc->idev);
+       if (err) {
+               dev_err(&pdev->dev, "failed to register input device\n");
+               goto err_free_irq;
+       }
+
+       platform_set_drvdata(pdev, kbc);
+       device_init_wakeup(&pdev->dev, pdata->wakeup);
+
+       return 0;
+
+err_free_irq:
+       free_irq(kbc->irq, pdev);
+err_put_clk:
+       clk_put(kbc->clk);
+err_iounmap:
+       iounmap(kbc->mmio);
+err_free_mem_region:
+       release_mem_region(res->start, resource_size(res));
+err_free_mem:
+       input_free_device(kbc->idev);
+       kfree(kbc);
+
+       return err;
+}
+
+static int __devexit tegra_kbc_remove(struct platform_device *pdev)
+{
+       struct tegra_kbc *kbc = platform_get_drvdata(pdev);
+       struct resource *res;
+
+       free_irq(kbc->irq, pdev);
+       clk_put(kbc->clk);
+
+       input_unregister_device(kbc->idev);
+       iounmap(kbc->mmio);
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       release_mem_region(res->start, resource_size(res));
+
+       kfree(kbc);
+
+       platform_set_drvdata(pdev, NULL);
+
+       return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int tegra_kbc_suspend(struct device *dev)
+{
+       struct platform_device *pdev = to_platform_device(dev);
+       struct tegra_kbc *kbc = platform_get_drvdata(pdev);
+
+       if (device_may_wakeup(&pdev->dev)) {
+               tegra_kbc_setup_wakekeys(kbc, true);
+               enable_irq_wake(kbc->irq);
+               /* Forcefully clear the interrupt status */
+               writel(0x7, kbc->mmio + KBC_INT_0);
+               msleep(30);
+       } else {
+               mutex_lock(&kbc->idev->mutex);
+               if (kbc->idev->users)
+                       tegra_kbc_stop(kbc);
+               mutex_unlock(&kbc->idev->mutex);
+       }
+
+       return 0;
+}
+
+static int tegra_kbc_resume(struct device *dev)
+{
+       struct platform_device *pdev = to_platform_device(dev);
+       struct tegra_kbc *kbc = platform_get_drvdata(pdev);
+       int err = 0;
+
+       if (device_may_wakeup(&pdev->dev)) {
+               disable_irq_wake(kbc->irq);
+               tegra_kbc_setup_wakekeys(kbc, false);
+       } else {
+               mutex_lock(&kbc->idev->mutex);
+               if (kbc->idev->users)
+                       err = tegra_kbc_start(kbc);
+               mutex_unlock(&kbc->idev->mutex);
+       }
+
+       return err;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(tegra_kbc_pm_ops, tegra_kbc_suspend, tegra_kbc_resume);
+
+static struct platform_driver tegra_kbc_driver = {
+       .probe          = tegra_kbc_probe,
+       .remove         = __devexit_p(tegra_kbc_remove),
+       .driver = {
+               .name   = "tegra-kbc",
+               .owner  = THIS_MODULE,
+               .pm     = &tegra_kbc_pm_ops,
+       },
+};
+
+static void __exit tegra_kbc_exit(void)
+{
+       platform_driver_unregister(&tegra_kbc_driver);
+}
+module_exit(tegra_kbc_exit);
+
+static int __init tegra_kbc_init(void)
+{
+       return platform_driver_register(&tegra_kbc_driver);
+}
+module_init(tegra_kbc_init);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Rakesh Iyer <riyer@nvidia.com>");
+MODULE_DESCRIPTION("Tegra matrix keyboard controller driver");
+MODULE_ALIAS("platform:tegra-kbc");
index b4a81ebfab92bb32f4949264ab6f9b81623569b0..c8f097a15d89a4865ba0c324cc63b76cec2646f9 100644 (file)
@@ -14,6 +14,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/err.h>
 #include <linux/errno.h>
 #include <linux/input.h>
 #include <linux/platform_device.h>
@@ -219,9 +220,9 @@ static int __devinit keypad_probe(struct platform_device *pdev)
        }
 
        kp->clk = clk_get(dev, NULL);
-       if (!kp->clk) {
+       if (IS_ERR(kp->clk)) {
                dev_err(dev, "cannot claim device clock\n");
-               error = -EINVAL;
+               error = PTR_ERR(kp->clk);
                goto error_clk;
        }
 
index da392c22fc6c045007194516c8a2ad2b004c03ee..aa186cf6c514526fec46d40d4d5a47bbe38af0e9 100644 (file)
@@ -755,23 +755,26 @@ static int synaptics_reconnect(struct psmouse *psmouse)
 {
        struct synaptics_data *priv = psmouse->private;
        struct synaptics_data old_priv = *priv;
+       int retry = 0;
+       int error;
 
-       psmouse_reset(psmouse);
+       do {
+               psmouse_reset(psmouse);
+               error = synaptics_detect(psmouse, 0);
+       } while (error && ++retry < 3);
 
-       if (synaptics_detect(psmouse, 0))
+       if (error)
                return -1;
 
+       if (retry > 1)
+               printk(KERN_DEBUG "Synaptics reconnected after %d tries\n",
+                       retry);
+
        if (synaptics_query_hardware(psmouse)) {
                printk(KERN_ERR "Unable to query Synaptics hardware.\n");
                return -1;
        }
 
-       if (old_priv.identity != priv->identity ||
-           old_priv.model_id != priv->model_id ||
-           old_priv.capabilities != priv->capabilities ||
-           old_priv.ext_cap != priv->ext_cap)
-               return -1;
-
        if (synaptics_set_absolute_mode(psmouse)) {
                printk(KERN_ERR "Unable to initialize Synaptics hardware.\n");
                return -1;
@@ -782,6 +785,19 @@ static int synaptics_reconnect(struct psmouse *psmouse)
                return -1;
        }
 
+       if (old_priv.identity != priv->identity ||
+           old_priv.model_id != priv->model_id ||
+           old_priv.capabilities != priv->capabilities ||
+           old_priv.ext_cap != priv->ext_cap) {
+               printk(KERN_ERR "Synaptics hardware appears to be different: "
+                       "id(%ld-%ld), model(%ld-%ld), caps(%lx-%lx), ext(%lx-%lx).\n",
+                       old_priv.identity, priv->identity,
+                       old_priv.model_id, priv->model_id,
+                       old_priv.capabilities, priv->capabilities,
+                       old_priv.ext_cap, priv->ext_cap);
+               return -1;
+       }
+
        return 0;
 }
 
index 448c7724beb90eda75edc0ef2d83c04e1fd9357a..852816567241cf5f0f08cc72c55bbb38b854ab8b 100644 (file)
@@ -111,9 +111,11 @@ static void ct82c710_close(struct serio *serio)
 static int ct82c710_open(struct serio *serio)
 {
        unsigned char status;
+       int err;
 
-       if (request_irq(CT82C710_IRQ, ct82c710_interrupt, 0, "ct82c710", NULL))
-               return -1;
+       err = request_irq(CT82C710_IRQ, ct82c710_interrupt, 0, "ct82c710", NULL);
+       if (err)
+               return err;
 
        status = inb_p(CT82C710_STATUS);
 
@@ -131,7 +133,7 @@ static int ct82c710_open(struct serio *serio)
                status &= ~(CT82C710_ENABLE | CT82C710_INTS_ON);
                outb_p(status, CT82C710_STATUS);
                free_irq(CT82C710_IRQ, NULL);
-               return -1;
+               return -EBUSY;
        }
 
        return 0;
index 6e362de3f412fe32a5755bdd49aed8bd891fecb5..8755f5f3ad37c2218de60b96782c0863615a705e 100644 (file)
@@ -116,14 +116,15 @@ static void serport_ldisc_close(struct tty_struct *tty)
 
 /*
  * serport_ldisc_receive() is called by the low level tty driver when characters
- * are ready for us. We forward the characters, one by one to the 'interrupt'
- * routine.
+ * are ready for us. We forward the characters and flags, one by one to the
+ * 'interrupt' routine.
  */
 
 static void serport_ldisc_receive(struct tty_struct *tty, const unsigned char *cp, char *fp, int count)
 {
        struct serport *serport = (struct serport*) tty->disc_data;
        unsigned long flags;
+       unsigned int ch_flags;
        int i;
 
        spin_lock_irqsave(&serport->lock, flags);
@@ -131,8 +132,23 @@ static void serport_ldisc_receive(struct tty_struct *tty, const unsigned char *c
        if (!test_bit(SERPORT_ACTIVE, &serport->flags))
                goto out;
 
-       for (i = 0; i < count; i++)
-               serio_interrupt(serport->serio, cp[i], 0);
+       for (i = 0; i < count; i++) {
+               switch (fp[i]) {
+               case TTY_FRAME:
+                       ch_flags = SERIO_FRAME;
+                       break;
+
+               case TTY_PARITY:
+                       ch_flags = SERIO_PARITY;
+                       break;
+
+               default:
+                       ch_flags = 0;
+                       break;
+               }
+
+               serio_interrupt(serport->serio, cp[i], ch_flags);
+       }
 
 out:
        spin_unlock_irqrestore(&serport->lock, flags);
index a29a7812bd46cea26613b813a3091eed476077aa..7729e547ba65d853581e115a4ce6428883549ecd 100644 (file)
@@ -201,6 +201,7 @@ int sparse_keymap_setup(struct input_dev *dev,
                        break;
 
                case KE_SW:
+               case KE_VSW:
                        __set_bit(EV_SW, dev->evbit);
                        __set_bit(entry->sw.code, dev->swbit);
                        break;
index 518782999fea2b2bf07e9aec0ebf6c9e25722d1c..367fa82a607e81ef8bf03d7b69c8bc231736fc65 100644 (file)
@@ -1101,6 +1101,13 @@ void wacom_setup_device_quirks(struct wacom_features *features)
        }
 }
 
+static unsigned int wacom_calculate_touch_res(unsigned int logical_max,
+                                             unsigned int physical_max)
+{
+       /* Touch physical dimensions are in 100th of mm */
+       return (logical_max * 100) / physical_max;
+}
+
 void wacom_setup_input_capabilities(struct input_dev *input_dev,
                                    struct wacom_wac *wacom_wac)
 {
@@ -1228,8 +1235,12 @@ void wacom_setup_input_capabilities(struct input_dev *input_dev,
        case TABLETPC:
                if (features->device_type == BTN_TOOL_DOUBLETAP ||
                    features->device_type == BTN_TOOL_TRIPLETAP) {
-                       input_set_abs_params(input_dev, ABS_RX, 0, features->x_phy, 0, 0);
-                       input_set_abs_params(input_dev, ABS_RY, 0, features->y_phy, 0, 0);
+                       input_abs_set_res(input_dev, ABS_X,
+                               wacom_calculate_touch_res(features->x_max,
+                                                       features->x_phy));
+                       input_abs_set_res(input_dev, ABS_Y,
+                               wacom_calculate_touch_res(features->y_max,
+                                                       features->y_phy));
                        __set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit);
                }
 
@@ -1272,6 +1283,12 @@ void wacom_setup_input_capabilities(struct input_dev *input_dev,
                        input_set_abs_params(input_dev, ABS_MT_PRESSURE,
                                             0, features->pressure_max,
                                             features->pressure_fuzz, 0);
+                       input_abs_set_res(input_dev, ABS_X,
+                               wacom_calculate_touch_res(features->x_max,
+                                                       features->x_phy));
+                       input_abs_set_res(input_dev, ABS_Y,
+                               wacom_calculate_touch_res(features->y_max,
+                                                       features->y_phy));
                } else if (features->device_type == BTN_TOOL_PEN) {
                        __set_bit(BTN_TOOL_RUBBER, input_dev->keybit);
                        __set_bit(BTN_TOOL_PEN, input_dev->keybit);
@@ -1426,6 +1443,10 @@ static struct wacom_features wacom_features_0xD3 =
        { "Wacom Bamboo 2FG 6x8", WACOM_PKGLEN_BBFUN,     21648, 13530, 1023, 63, BAMBOO_PT };
 static const struct wacom_features wacom_features_0xD4 =
        { "Wacom Bamboo Pen",     WACOM_PKGLEN_BBFUN,     14720,  9200,  255, 63, BAMBOO_PT };
+static struct wacom_features wacom_features_0xD6 =
+       { "Wacom BambooPT 2FG 4x5", WACOM_PKGLEN_BBFUN,   14720,  9200, 1023, 63, BAMBOO_PT };
+static struct wacom_features wacom_features_0xD7 =
+       { "Wacom BambooPT 2FG Small", WACOM_PKGLEN_BBFUN, 14720,  9200, 1023, 63, BAMBOO_PT };
 static struct wacom_features wacom_features_0xD8 =
        { "Wacom Bamboo Comic 2FG", WACOM_PKGLEN_BBFUN,   21648, 13530, 1023, 63, BAMBOO_PT };
 static struct wacom_features wacom_features_0xDA =
@@ -1507,6 +1528,8 @@ const struct usb_device_id wacom_ids[] = {
        { USB_DEVICE_WACOM(0xD2) },
        { USB_DEVICE_WACOM(0xD3) },
        { USB_DEVICE_WACOM(0xD4) },
+       { USB_DEVICE_WACOM(0xD6) },
+       { USB_DEVICE_WACOM(0xD7) },
        { USB_DEVICE_WACOM(0xD8) },
        { USB_DEVICE_WACOM(0xDA) },
        { USB_DEVICE_WACOM(0xDB) },
index f7fa9ef4cd6579d5ee9c9ec47e5cf57e2034498d..1507ce108d5b1f418f131265110f174cde22a0f6 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/input.h>
 #include <linux/input/bu21013.h>
 #include <linux/slab.h>
+#include <linux/regulator/consumer.h>
 
 #define PEN_DOWN_INTR  0
 #define MAX_FINGERS    2
  * @chip: pointer to the touch panel controller
  * @in_dev: pointer to the input device structure
  * @intr_pin: interrupt pin value
+ * @regulator: pointer to the Regulator used for touch screen
  *
  * Touch panel device data structure
  */
@@ -149,6 +151,7 @@ struct bu21013_ts_data {
        const struct bu21013_platform_device *chip;
        struct input_dev *in_dev;
        unsigned int intr_pin;
+       struct regulator *regulator;
 };
 
 /**
@@ -456,6 +459,20 @@ static int __devinit bu21013_probe(struct i2c_client *client,
        bu21013_data->in_dev = in_dev;
        bu21013_data->chip = pdata;
        bu21013_data->client = client;
+
+       bu21013_data->regulator = regulator_get(&client->dev, "V-TOUCH");
+       if (IS_ERR(bu21013_data->regulator)) {
+               dev_err(&client->dev, "regulator_get failed\n");
+               error = PTR_ERR(bu21013_data->regulator);
+               goto err_free_mem;
+       }
+
+       error = regulator_enable(bu21013_data->regulator);
+       if (error < 0) {
+               dev_err(&client->dev, "regulator enable failed\n");
+               goto err_put_regulator;
+       }
+
        bu21013_data->touch_stopped = false;
        init_waitqueue_head(&bu21013_data->wait);
 
@@ -464,7 +481,7 @@ static int __devinit bu21013_probe(struct i2c_client *client,
                error = pdata->cs_en(pdata->cs_pin);
                if (error < 0) {
                        dev_err(&client->dev, "chip init failed\n");
-                       goto err_free_mem;
+                       goto err_disable_regulator;
                }
        }
 
@@ -485,9 +502,9 @@ static int __devinit bu21013_probe(struct i2c_client *client,
        __set_bit(EV_ABS, in_dev->evbit);
 
        input_set_abs_params(in_dev, ABS_MT_POSITION_X, 0,
-                                               pdata->x_max_res, 0, 0);
+                                               pdata->touch_x_max, 0, 0);
        input_set_abs_params(in_dev, ABS_MT_POSITION_Y, 0,
-                                               pdata->y_max_res, 0, 0);
+                                               pdata->touch_y_max, 0, 0);
        input_set_drvdata(in_dev, bu21013_data);
 
        error = request_threaded_irq(pdata->irq, NULL, bu21013_gpio_irq,
@@ -513,6 +530,10 @@ err_free_irq:
        bu21013_free_irq(bu21013_data);
 err_cs_disable:
        pdata->cs_dis(pdata->cs_pin);
+err_disable_regulator:
+       regulator_disable(bu21013_data->regulator);
+err_put_regulator:
+       regulator_put(bu21013_data->regulator);
 err_free_mem:
        input_free_device(in_dev);
        kfree(bu21013_data);
@@ -535,6 +556,10 @@ static int __devexit bu21013_remove(struct i2c_client *client)
        bu21013_data->chip->cs_dis(bu21013_data->chip->cs_pin);
 
        input_unregister_device(bu21013_data->in_dev);
+
+       regulator_disable(bu21013_data->regulator);
+       regulator_put(bu21013_data->regulator);
+
        kfree(bu21013_data);
 
        device_init_wakeup(&client->dev, false);
@@ -561,6 +586,8 @@ static int bu21013_suspend(struct device *dev)
        else
                disable_irq(bu21013_data->chip->irq);
 
+       regulator_disable(bu21013_data->regulator);
+
        return 0;
 }
 
@@ -577,6 +604,12 @@ static int bu21013_resume(struct device *dev)
        struct i2c_client *client = bu21013_data->client;
        int retval;
 
+       retval = regulator_enable(bu21013_data->regulator);
+       if (retval < 0) {
+               dev_err(&client->dev, "bu21013 regulator enable failed\n");
+               return retval;
+       }
+
        retval = bu21013_init_chip(bu21013_data);
        if (retval < 0) {
                dev_err(&client->dev, "bu21013 controller config failed\n");
index cf1dba2e267c1510be41c901f02a058f94673bbb..22a3411e93c56bf7f8577334ab19d7a4e2003111 100644 (file)
@@ -14,6 +14,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/err.h>
 #include <linux/errno.h>
 #include <linux/input.h>
 #include <linux/platform_device.h>
@@ -289,9 +290,9 @@ static int __devinit tsc_probe(struct platform_device *pdev)
        }
 
        ts->clk = clk_get(dev, NULL);
-       if (!ts->clk) {
+       if (IS_ERR(ts->clk)) {
                dev_err(dev, "cannot claim device clock\n");
-               error = -EINVAL;
+               error = PTR_ERR(ts->clk);
                goto error_clk;
        }
 
index da3fa8dcdf5b924f71a7f117c05009f0fc671514..666daf77872e56239bbf59a002c180593996ae7a 100644 (file)
@@ -69,6 +69,7 @@ static int led_pwm_probe(struct platform_device *pdev)
                led_dat->pwm = pwm_request(cur_led->pwm_id,
                                cur_led->name);
                if (IS_ERR(led_dat->pwm)) {
+                       ret = PTR_ERR(led_dat->pwm);
                        dev_err(&pdev->dev, "unable to request PWM %d\n",
                                        cur_led->pwm_id);
                        goto err;
index 72be8a02118cc7cbb9440a7baab9fa8128930dc1..512a2f4ada0e113ccc213ff5a5c50d0d93eaaf90 100644 (file)
@@ -458,21 +458,27 @@ static int ir_getkeycode(struct input_dev *idev,
                index = ir_lookup_by_scancode(rc_map, scancode);
        }
 
-       if (index >= rc_map->len) {
-               if (!(ke->flags & INPUT_KEYMAP_BY_INDEX))
-                       IR_dprintk(1, "unknown key for scancode 0x%04x\n",
-                                  scancode);
+       if (index < rc_map->len) {
+               entry = &rc_map->scan[index];
+
+               ke->index = index;
+               ke->keycode = entry->keycode;
+               ke->len = sizeof(entry->scancode);
+               memcpy(ke->scancode, &entry->scancode, sizeof(entry->scancode));
+
+       } else if (!(ke->flags & INPUT_KEYMAP_BY_INDEX)) {
+               /*
+                * We do not really know the valid range of scancodes
+                * so let's respond with KEY_RESERVED to anything we
+                * do not have mapping for [yet].
+                */
+               ke->index = index;
+               ke->keycode = KEY_RESERVED;
+       } else {
                retval = -EINVAL;
                goto out;
        }
 
-       entry = &rc_map->scan[index];
-
-       ke->index = index;
-       ke->keycode = entry->keycode;
-       ke->len = sizeof(entry->scancode);
-       memcpy(ke->scancode, &entry->scancode, sizeof(entry->scancode));
-
        retval = 0;
 
 out:
index bac7d62866b731cc60e924a34521015b7c2cc288..0371bf502249baf416d78b85c88ca1ba218f28b0 100644 (file)
@@ -462,7 +462,7 @@ static int __devinit sdh_probe(struct platform_device *pdev)
                goto out;
        }
 
-       mmc = mmc_alloc_host(sizeof(*mmc), &pdev->dev);
+       mmc = mmc_alloc_host(sizeof(struct sdh_host), &pdev->dev);
        if (!mmc) {
                ret = -ENOMEM;
                goto out;
index b3a0ab0e4c2b6ce37ed2ff68321c154e45d5c1f0..74218ad677e4955d2dcb0941f68ed45c3fa4e85b 100644 (file)
@@ -14,6 +14,7 @@
  */
 
 #include <linux/mmc/host.h>
+#include <linux/err.h>
 #include <linux/io.h>
 #include <linux/irq.h>
 #include <linux/interrupt.h>
@@ -827,8 +828,8 @@ static int __devinit jz4740_mmc_probe(struct platform_device* pdev)
        }
 
        host->clk = clk_get(&pdev->dev, "mmc");
-       if (!host->clk) {
-               ret = -ENOENT;
+       if (IS_ERR(host->clk)) {
+               ret = PTR_ERR(host->clk);
                dev_err(&pdev->dev, "Failed to get mmc clock\n");
                goto err_free_host;
        }
index 56302282566777daddc5c63bb2eff3582b0ba062..2d6de3e03e2dcca2e01f9322ef5c306d5bb473af 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/ioport.h>
 #include <linux/device.h>
 #include <linux/interrupt.h>
+#include <linux/kernel.h>
 #include <linux/delay.h>
 #include <linux/err.h>
 #include <linux/highmem.h>
@@ -46,10 +47,6 @@ static unsigned int fmax = 515633;
  *           is asserted (likewise for RX)
  * @fifohalfsize: number of bytes that can be written when MCI_TXFIFOHALFEMPTY
  *               is asserted (likewise for RX)
- * @broken_blockend: the MCI_DATABLOCKEND is broken on the hardware
- *             and will not work at all.
- * @broken_blockend_dma: the MCI_DATABLOCKEND is broken on the hardware when
- *             using DMA.
  * @sdio: variant supports SDIO
  * @st_clkdiv: true if using a ST-specific clock divider algorithm
  */
@@ -59,8 +56,6 @@ struct variant_data {
        unsigned int            datalength_bits;
        unsigned int            fifosize;
        unsigned int            fifohalfsize;
-       bool                    broken_blockend;
-       bool                    broken_blockend_dma;
        bool                    sdio;
        bool                    st_clkdiv;
 };
@@ -76,7 +71,6 @@ static struct variant_data variant_u300 = {
        .fifohalfsize           = 8 * 4,
        .clkreg_enable          = 1 << 13, /* HWFCEN */
        .datalength_bits        = 16,
-       .broken_blockend_dma    = true,
        .sdio                   = true,
 };
 
@@ -86,7 +80,6 @@ static struct variant_data variant_ux500 = {
        .clkreg                 = MCI_CLK_ENABLE,
        .clkreg_enable          = 1 << 14, /* HWFCEN */
        .datalength_bits        = 24,
-       .broken_blockend        = true,
        .sdio                   = true,
        .st_clkdiv              = true,
 };
@@ -210,8 +203,6 @@ static void mmci_start_data(struct mmci_host *host, struct mmc_data *data)
        host->data = data;
        host->size = data->blksz * data->blocks;
        host->data_xfered = 0;
-       host->blockend = false;
-       host->dataend = false;
 
        mmci_init_sg(host, data);
 
@@ -288,21 +279,26 @@ static void
 mmci_data_irq(struct mmci_host *host, struct mmc_data *data,
              unsigned int status)
 {
-       struct variant_data *variant = host->variant;
-
        /* First check for errors */
        if (status & (MCI_DATACRCFAIL|MCI_DATATIMEOUT|MCI_TXUNDERRUN|MCI_RXOVERRUN)) {
+               u32 remain, success;
+
+               /* Calculate how far we are into the transfer */
+               remain = readl(host->base + MMCIDATACNT);
+               success = data->blksz * data->blocks - remain;
+
                dev_dbg(mmc_dev(host->mmc), "MCI ERROR IRQ (status %08x)\n", status);
-               if (status & MCI_DATACRCFAIL)
+               if (status & MCI_DATACRCFAIL) {
+                       /* Last block was not successful */
+                       host->data_xfered = round_down(success - 1, data->blksz);
                        data->error = -EILSEQ;
-               else if (status & MCI_DATATIMEOUT)
+               } else if (status & MCI_DATATIMEOUT) {
+                       host->data_xfered = round_down(success, data->blksz);
                        data->error = -ETIMEDOUT;
-               else if (status & (MCI_TXUNDERRUN|MCI_RXOVERRUN))
+               } else if (status & (MCI_TXUNDERRUN|MCI_RXOVERRUN)) {
+                       host->data_xfered = round_down(success, data->blksz);
                        data->error = -EIO;
-
-               /* Force-complete the transaction */
-               host->blockend = true;
-               host->dataend = true;
+               }
 
                /*
                 * We hit an error condition.  Ensure that any data
@@ -321,61 +317,14 @@ mmci_data_irq(struct mmci_host *host, struct mmc_data *data,
                }
        }
 
-       /*
-        * On ARM variants in PIO mode, MCI_DATABLOCKEND
-        * is always sent first, and we increase the
-        * transfered number of bytes for that IRQ. Then
-        * MCI_DATAEND follows and we conclude the transaction.
-        *
-        * On the Ux500 single-IRQ variant MCI_DATABLOCKEND
-        * doesn't seem to immediately clear from the status,
-        * so we can't use it keep count when only one irq is
-        * used because the irq will hit for other reasons, and
-        * then the flag is still up. So we use the MCI_DATAEND
-        * IRQ at the end of the entire transfer because
-        * MCI_DATABLOCKEND is broken.
-        *
-        * In the U300, the IRQs can arrive out-of-order,
-        * e.g. MCI_DATABLOCKEND sometimes arrives after MCI_DATAEND,
-        * so for this case we use the flags "blockend" and
-        * "dataend" to make sure both IRQs have arrived before
-        * concluding the transaction. (This does not apply
-        * to the Ux500 which doesn't fire MCI_DATABLOCKEND
-        * at all.) In DMA mode it suffers from the same problem
-        * as the Ux500.
-        */
-       if (status & MCI_DATABLOCKEND) {
-               /*
-                * Just being a little over-cautious, we do not
-                * use this progressive update if the hardware blockend
-                * flag is unreliable: since it can stay high between
-                * IRQs it will corrupt the transfer counter.
-                */
-               if (!variant->broken_blockend)
-                       host->data_xfered += data->blksz;
-               host->blockend = true;
-       }
-
-       if (status & MCI_DATAEND)
-               host->dataend = true;
+       if (status & MCI_DATABLOCKEND)
+               dev_err(mmc_dev(host->mmc), "stray MCI_DATABLOCKEND interrupt\n");
 
-       /*
-        * On variants with broken blockend we shall only wait for dataend,
-        * on others we must sync with the blockend signal since they can
-        * appear out-of-order.
-        */
-       if (host->dataend && (host->blockend || variant->broken_blockend)) {
+       if (status & MCI_DATAEND || data->error) {
                mmci_stop_data(host);
 
-               /* Reset these flags */
-               host->blockend = false;
-               host->dataend = false;
-
-               /*
-                * Variants with broken blockend flags need to handle the
-                * end of the entire transfer here.
-                */
-               if (variant->broken_blockend && !data->error)
+               if (!data->error)
+                       /* The error clause is handled above, success! */
                        host->data_xfered += data->blksz * data->blocks;
 
                if (!data->stop) {
@@ -394,15 +343,15 @@ mmci_cmd_irq(struct mmci_host *host, struct mmc_command *cmd,
 
        host->cmd = NULL;
 
-       cmd->resp[0] = readl(base + MMCIRESPONSE0);
-       cmd->resp[1] = readl(base + MMCIRESPONSE1);
-       cmd->resp[2] = readl(base + MMCIRESPONSE2);
-       cmd->resp[3] = readl(base + MMCIRESPONSE3);
-
        if (status & MCI_CMDTIMEOUT) {
                cmd->error = -ETIMEDOUT;
        } else if (status & MCI_CMDCRCFAIL && cmd->flags & MMC_RSP_CRC) {
                cmd->error = -EILSEQ;
+       } else {
+               cmd->resp[0] = readl(base + MMCIRESPONSE0);
+               cmd->resp[1] = readl(base + MMCIRESPONSE1);
+               cmd->resp[2] = readl(base + MMCIRESPONSE2);
+               cmd->resp[3] = readl(base + MMCIRESPONSE3);
        }
 
        if (!cmd->data || cmd->error) {
@@ -770,7 +719,6 @@ static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id)
        struct variant_data *variant = id->data;
        struct mmci_host *host;
        struct mmc_host *mmc;
-       unsigned int mask;
        int ret;
 
        /* must have platform data */
@@ -951,12 +899,7 @@ static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id)
                        goto irq0_free;
        }
 
-       mask = MCI_IRQENABLE;
-       /* Don't use the datablockend flag if it's broken */
-       if (variant->broken_blockend)
-               mask &= ~MCI_DATABLOCKEND;
-
-       writel(mask, host->base + MMCIMASK0);
+       writel(MCI_IRQENABLE, host->base + MMCIMASK0);
 
        amba_set_drvdata(dev, mmc);
 
index df06f01aac8953a482bb25fdf3261f2496b6504c..c1df7b82d36cc63f5f420ac71ff68cdc120ccee5 100644 (file)
 #define MCI_IRQENABLE  \
        (MCI_CMDCRCFAILMASK|MCI_DATACRCFAILMASK|MCI_CMDTIMEOUTMASK|     \
        MCI_DATATIMEOUTMASK|MCI_TXUNDERRUNMASK|MCI_RXOVERRUNMASK|       \
-       MCI_CMDRESPENDMASK|MCI_CMDSENTMASK|MCI_DATABLOCKENDMASK)
+       MCI_CMDRESPENDMASK|MCI_CMDSENTMASK)
 
 /* These interrupts are directed to IRQ1 when two IRQ lines are available */
 #define MCI_IRQ1MASK \
@@ -177,9 +177,6 @@ struct mmci_host {
        struct timer_list       timer;
        unsigned int            oldstat;
 
-       bool                    blockend;
-       bool                    dataend;
-
        /* pio stuff */
        struct sg_mapping_iter  sg_miter;
        unsigned int            size;
index 5decfd0bd61dc1d1369e8c5cd81fca8d681f1322..153ab977a013638a7d1a187d3bdb73a33c8d2345 100644 (file)
@@ -383,14 +383,30 @@ static int msmsdcc_config_dma(struct msmsdcc_host *host, struct mmc_data *data)
        host->curr.user_pages = 0;
 
        box = &nc->cmd[0];
-       for (i = 0; i < host->dma.num_ents; i++) {
-               box->cmd = CMD_MODE_BOX;
 
-       /* Initialize sg dma address */
-       sg->dma_address = page_to_dma(mmc_dev(host->mmc), sg_page(sg))
-                               + sg->offset;
+       /* location of command block must be 64 bit aligned */
+       BUG_ON(host->dma.cmd_busaddr & 0x07);
 
-       if (i == (host->dma.num_ents - 1))
+       nc->cmdptr = (host->dma.cmd_busaddr >> 3) | CMD_PTR_LP;
+       host->dma.hdr.cmdptr = DMOV_CMD_PTR_LIST |
+                              DMOV_CMD_ADDR(host->dma.cmdptr_busaddr);
+       host->dma.hdr.complete_func = msmsdcc_dma_complete_func;
+
+       n = dma_map_sg(mmc_dev(host->mmc), host->dma.sg,
+                       host->dma.num_ents, host->dma.dir);
+       if (n == 0) {
+               printk(KERN_ERR "%s: Unable to map in all sg elements\n",
+                       mmc_hostname(host->mmc));
+               host->dma.sg = NULL;
+               host->dma.num_ents = 0;
+               return -ENOMEM;
+       }
+
+       for_each_sg(host->dma.sg, sg, n, i) {
+
+               box->cmd = CMD_MODE_BOX;
+
+               if (i == n - 1)
                        box->cmd |= CMD_LC;
                rows = (sg_dma_len(sg) % MCI_FIFOSIZE) ?
                        (sg_dma_len(sg) / MCI_FIFOSIZE) + 1 :
@@ -418,27 +434,6 @@ static int msmsdcc_config_dma(struct msmsdcc_host *host, struct mmc_data *data)
                        box->cmd |= CMD_DST_CRCI(crci);
                }
                box++;
-               sg++;
-       }
-
-       /* location of command block must be 64 bit aligned */
-       BUG_ON(host->dma.cmd_busaddr & 0x07);
-
-       nc->cmdptr = (host->dma.cmd_busaddr >> 3) | CMD_PTR_LP;
-       host->dma.hdr.cmdptr = DMOV_CMD_PTR_LIST |
-                              DMOV_CMD_ADDR(host->dma.cmdptr_busaddr);
-       host->dma.hdr.complete_func = msmsdcc_dma_complete_func;
-
-       n = dma_map_sg(mmc_dev(host->mmc), host->dma.sg,
-                       host->dma.num_ents, host->dma.dir);
-/* dsb inside dma_map_sg will write nc out to mem as well */
-
-       if (n != host->dma.num_ents) {
-               printk(KERN_ERR "%s: Unable to map in all sg elements\n",
-                       mmc_hostname(host->mmc));
-               host->dma.sg = NULL;
-               host->dma.num_ents = 0;
-               return -ENOMEM;
        }
 
        return 0;
@@ -1331,9 +1326,6 @@ msmsdcc_probe(struct platform_device *pdev)
        if (host->timer.function)
                pr_info("%s: Polling status mode enabled\n", mmc_hostname(mmc));
 
-#if BUSCLK_PWRSAVE
-       msmsdcc_disable_clocks(host, 1);
-#endif
        return 0;
  cmd_irq_free:
        free_irq(cmd_irqres->start, host);
index 17203586305cf57f931449de97a7db7c5d099262..5309ab95aada9a39914300833b1be38f4ec07ad9 100644 (file)
@@ -277,10 +277,43 @@ static void sdhci_cmu_set_clock(struct sdhci_host *host, unsigned int clock)
        host->clock = clock;
 }
 
+/**
+ * sdhci_s3c_platform_8bit_width - support 8bit buswidth
+ * @host: The SDHCI host being queried
+ * @width: MMC_BUS_WIDTH_ macro for the bus width being requested
+ *
+ * We have 8-bit width support but is not a v3 controller.
+ * So we add platform_8bit_width() and support 8bit width.
+ */
+static int sdhci_s3c_platform_8bit_width(struct sdhci_host *host, int width)
+{
+       u8 ctrl;
+
+       ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
+
+       switch (width) {
+       case MMC_BUS_WIDTH_8:
+               ctrl |= SDHCI_CTRL_8BITBUS;
+               ctrl &= ~SDHCI_CTRL_4BITBUS;
+               break;
+       case MMC_BUS_WIDTH_4:
+               ctrl |= SDHCI_CTRL_4BITBUS;
+               ctrl &= ~SDHCI_CTRL_8BITBUS;
+               break;
+       default:
+               break;
+       }
+
+       sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
+
+       return 0;
+}
+
 static struct sdhci_ops sdhci_s3c_ops = {
        .get_max_clock          = sdhci_s3c_get_max_clk,
        .set_clock              = sdhci_s3c_set_clock,
        .get_min_clock          = sdhci_s3c_get_min_clock,
+       .platform_8bit_width    = sdhci_s3c_platform_8bit_width,
 };
 
 static void sdhci_s3c_notify_change(struct platform_device *dev, int state)
@@ -473,6 +506,9 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
        if (pdata->cd_type == S3C_SDHCI_CD_PERMANENT)
                host->mmc->caps = MMC_CAP_NONREMOVABLE;
 
+       if (pdata->host_caps)
+               host->mmc->caps |= pdata->host_caps;
+
        host->quirks |= (SDHCI_QUIRK_32BIT_DMA_ADDR |
                         SDHCI_QUIRK_32BIT_DMA_SIZE);
 
index f8f65df9b01746052a5fe457f3e9419a98e63ee2..f08f944ac53c64f5cc57877eaefcb9ec02c96c99 100644 (file)
@@ -19,7 +19,6 @@
 #include <linux/module.h>
 #include <linux/usb.h>
 #include <linux/kernel.h>
-#include <linux/usb.h>
 #include <linux/slab.h>
 #include <linux/dma-mapping.h>
 #include <linux/mmc/host.h>
index f49e49dc5928cf1acfa5b25d019162f99a3eb1db..5ebe280225d60a69f28bc81c5c4593a47e017365 100644 (file)
@@ -672,33 +672,7 @@ static int io_init(struct ubi_device *ubi)
                ubi->nor_flash = 1;
        }
 
-       /*
-        * Set UBI min. I/O size (@ubi->min_io_size). We use @mtd->writebufsize
-        * for these purposes, not @mtd->writesize. At the moment this does not
-        * matter for NAND, because currently @mtd->writebufsize is equivalent to
-        * @mtd->writesize for all NANDs. However, some CFI NOR flashes may
-        * have @mtd->writebufsize which is multiple of @mtd->writesize.
-        *
-        * The reason we use @mtd->writebufsize for @ubi->min_io_size is that
-        * UBI and UBIFS recovery algorithms rely on the fact that if there was
-        * an unclean power cut, then we can find offset of the last corrupted
-        * node, align the offset to @ubi->min_io_size, read the rest of the
-        * eraseblock starting from this offset, and check whether there are
-        * only 0xFF bytes. If yes, then we are probably dealing with a
-        * corruption caused by a power cut, if not, then this is probably some
-        * severe corruption.
-        *
-        * Thus, we have to use the maximum write unit size of the flash, which
-        * is @mtd->writebufsize, because @mtd->writesize is the minimum write
-        * size, not the maximum.
-        */
-       if (ubi->mtd->type == MTD_NANDFLASH)
-               ubi_assert(ubi->mtd->writebufsize == ubi->mtd->writesize);
-       else if (ubi->mtd->type == MTD_NORFLASH)
-               ubi_assert(ubi->mtd->writebufsize % ubi->mtd->writesize == 0);
-
-       ubi->min_io_size = ubi->mtd->writebufsize;
-
+       ubi->min_io_size = ubi->mtd->writesize;
        ubi->hdrs_min_io_size = ubi->mtd->writesize >> ubi->mtd->subpage_sft;
 
        /*
index 62d6f88cbab57deb4fb7141745f700ad68efceb4..aa07657744c3a8a5d1fff8437dbc04e0689dd115 100644 (file)
@@ -1644,7 +1644,7 @@ ks8695_cleanup(void)
 module_init(ks8695_init);
 module_exit(ks8695_cleanup);
 
-MODULE_AUTHOR("Simtec Electronics")
+MODULE_AUTHOR("Simtec Electronics");
 MODULE_DESCRIPTION("Micrel KS8695 (Centaur) Ethernet driver");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("platform:" MODULENAME);
index df99edf3464ad59e4872ea82f008c13c9ae3e942..0ba59d5aeb7f54253171f56dc711b2a3e47f0f89 100644 (file)
@@ -7553,6 +7553,10 @@ bnx2_set_flags(struct net_device *dev, u32 data)
            !(data & ETH_FLAG_RXVLAN))
                return -EINVAL;
 
+       /* TSO with VLAN tag won't work with current firmware */
+       if (!(data & ETH_FLAG_TXVLAN))
+               return -EINVAL;
+
        rc = ethtool_op_set_flags(dev, data, ETH_FLAG_RXHASH | ETH_FLAG_RXVLAN |
                                  ETH_FLAG_TXVLAN);
        if (rc)
@@ -7962,11 +7966,8 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
 
                /* AER (Advanced Error Reporting) hooks */
                err = pci_enable_pcie_error_reporting(pdev);
-               if (err) {
-                       dev_err(&pdev->dev, "pci_enable_pcie_error_reporting "
-                                           "failed 0x%x\n", err);
-                       /* non-fatal, continue */
-               }
+               if (!err)
+                       bp->flags |= BNX2_FLAG_AER_ENABLED;
 
        } else {
                bp->pcix_cap = pci_find_capability(pdev, PCI_CAP_ID_PCIX);
@@ -8229,8 +8230,10 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
        return 0;
 
 err_out_unmap:
-       if (bp->flags & BNX2_FLAG_PCIE)
+       if (bp->flags & BNX2_FLAG_AER_ENABLED) {
                pci_disable_pcie_error_reporting(pdev);
+               bp->flags &= ~BNX2_FLAG_AER_ENABLED;
+       }
 
        if (bp->regview) {
                iounmap(bp->regview);
@@ -8418,8 +8421,10 @@ bnx2_remove_one(struct pci_dev *pdev)
 
        kfree(bp->temp_stats_blk);
 
-       if (bp->flags & BNX2_FLAG_PCIE)
+       if (bp->flags & BNX2_FLAG_AER_ENABLED) {
                pci_disable_pcie_error_reporting(pdev);
+               bp->flags &= ~BNX2_FLAG_AER_ENABLED;
+       }
 
        free_netdev(dev);
 
@@ -8535,7 +8540,7 @@ static pci_ers_result_t bnx2_io_slot_reset(struct pci_dev *pdev)
        }
        rtnl_unlock();
 
-       if (!(bp->flags & BNX2_FLAG_PCIE))
+       if (!(bp->flags & BNX2_FLAG_AER_ENABLED))
                return result;
 
        err = pci_cleanup_aer_uncorrect_error_status(pdev);
index 5488a2e82fe93a445dd9e38f695d7035703c39a3..f459fb2f9add61ac8c16063104578f3e21e48e66 100644 (file)
@@ -6741,6 +6741,7 @@ struct bnx2 {
 #define BNX2_FLAG_JUMBO_BROKEN         0x00000800
 #define BNX2_FLAG_CAN_KEEP_VLAN                0x00001000
 #define BNX2_FLAG_BROKEN_STATS         0x00002000
+#define BNX2_FLAG_AER_ENABLED          0x00004000
 
        struct bnx2_napi        bnx2_napi[BNX2_MAX_MSIX_VEC];
 
index 171782e2bb39354de45e011022235f3797e576c9..1024ae158227306aeacd30fa69159b3bfac97987 100644 (file)
@@ -2470,6 +2470,10 @@ int bond_3ad_lacpdu_recv(struct sk_buff *skb, struct net_device *dev, struct pac
        if (!(dev->flags & IFF_MASTER))
                goto out;
 
+       skb = skb_share_check(skb, GFP_ATOMIC);
+       if (!skb)
+               goto out;
+
        if (!pskb_may_pull(skb, sizeof(struct lacpdu)))
                goto out;
 
index f4e638c651298aba65bae970216d4c0e7a7dfd00..5c6fba802f2b759561ee6c9c0c44bd3ea761b2c6 100644 (file)
@@ -326,6 +326,10 @@ static int rlb_arp_recv(struct sk_buff *skb, struct net_device *bond_dev, struct
                goto out;
        }
 
+       skb = skb_share_check(skb, GFP_ATOMIC);
+       if (!skb)
+               goto out;
+
        if (!pskb_may_pull(skb, arp_hdr_len(bond_dev)))
                goto out;
 
index b1025b85acf1210f70da338f5df4292d316e5384..163e0b06eaa5d1aba0dda6aef0765016020e2b1a 100644 (file)
@@ -2733,6 +2733,10 @@ static int bond_arp_rcv(struct sk_buff *skb, struct net_device *dev, struct pack
        if (!slave || !slave_do_arp_validate(bond, slave))
                goto out_unlock;
 
+       skb = skb_share_check(skb, GFP_ATOMIC);
+       if (!skb)
+               goto out_unlock;
+
        if (!pskb_may_pull(skb, arp_hdr_len(dev)))
                goto out_unlock;
 
index d5a9db60ade9cf783273f57a7abac5679aea0003..986195eaa57cff44bb982149504c558944f09ade 100644 (file)
@@ -117,6 +117,8 @@ source "drivers/net/can/sja1000/Kconfig"
 
 source "drivers/net/can/usb/Kconfig"
 
+source "drivers/net/can/softing/Kconfig"
+
 config CAN_DEBUG_DEVICES
        bool "CAN devices debugging messages"
        depends on CAN
index 07ca159ba3f91ab643a167cda786d46a488c2e05..53c82a71778e8b20c80308aa1ceca1840272ab92 100644 (file)
@@ -9,6 +9,7 @@ obj-$(CONFIG_CAN_DEV)           += can-dev.o
 can-dev-y                      := dev.o
 
 obj-y                          += usb/
+obj-y                          += softing/
 
 obj-$(CONFIG_CAN_SJA1000)      += sja1000/
 obj-$(CONFIG_CAN_MSCAN)                += mscan/
index 7ef83d06f7eddce14ef7a4cff8cc866a0a6bc572..2532b96315389bb4878b23060ba0a229f92692fb 100644 (file)
@@ -2,7 +2,7 @@
  * at91_can.c - CAN network driver for AT91 SoC CAN controller
  *
  * (C) 2007 by Hans J. Koch <hjk@hansjkoch.de>
- * (C) 2008, 2009, 2010 by Marc Kleine-Budde <kernel@pengutronix.de>
+ * (C) 2008, 2009, 2010, 2011 by Marc Kleine-Budde <kernel@pengutronix.de>
  *
  * This software may be distributed under the terms of the GNU General
  * Public License ("GPL") version 2 as distributed in the 'COPYING'
@@ -30,6 +30,7 @@
 #include <linux/module.h>
 #include <linux/netdevice.h>
 #include <linux/platform_device.h>
+#include <linux/rtnetlink.h>
 #include <linux/skbuff.h>
 #include <linux/spinlock.h>
 #include <linux/string.h>
 
 #include <mach/board.h>
 
-#define AT91_NAPI_WEIGHT       12
+#define AT91_NAPI_WEIGHT       11
 
 /*
  * RX/TX Mailbox split
  * don't dare to touch
  */
-#define AT91_MB_RX_NUM         12
+#define AT91_MB_RX_NUM         11
 #define AT91_MB_TX_SHIFT       2
 
-#define AT91_MB_RX_FIRST       0
+#define AT91_MB_RX_FIRST       1
 #define AT91_MB_RX_LAST                (AT91_MB_RX_FIRST + AT91_MB_RX_NUM - 1)
 
 #define AT91_MB_RX_MASK(i)     ((1 << (i)) - 1)
 #define AT91_MB_RX_SPLIT       8
 #define AT91_MB_RX_LOW_LAST    (AT91_MB_RX_SPLIT - 1)
-#define AT91_MB_RX_LOW_MASK    (AT91_MB_RX_MASK(AT91_MB_RX_SPLIT))
+#define AT91_MB_RX_LOW_MASK    (AT91_MB_RX_MASK(AT91_MB_RX_SPLIT) & \
+                                ~AT91_MB_RX_MASK(AT91_MB_RX_FIRST))
 
 #define AT91_MB_TX_NUM         (1 << AT91_MB_TX_SHIFT)
 #define AT91_MB_TX_FIRST       (AT91_MB_RX_LAST + 1)
@@ -168,6 +170,8 @@ struct at91_priv {
 
        struct clk              *clk;
        struct at91_can_data    *pdata;
+
+       canid_t                 mb0_id;
 };
 
 static struct can_bittiming_const at91_bittiming_const = {
@@ -220,6 +224,18 @@ static inline void set_mb_mode(const struct at91_priv *priv, unsigned int mb,
        set_mb_mode_prio(priv, mb, mode, 0);
 }
 
+static inline u32 at91_can_id_to_reg_mid(canid_t can_id)
+{
+       u32 reg_mid;
+
+       if (can_id & CAN_EFF_FLAG)
+               reg_mid = (can_id & CAN_EFF_MASK) | AT91_MID_MIDE;
+       else
+               reg_mid = (can_id & CAN_SFF_MASK) << 18;
+
+       return reg_mid;
+}
+
 /*
  * Swtich transceiver on or off
  */
@@ -233,12 +249,22 @@ static void at91_setup_mailboxes(struct net_device *dev)
 {
        struct at91_priv *priv = netdev_priv(dev);
        unsigned int i;
+       u32 reg_mid;
 
        /*
-        * The first 12 mailboxes are used as a reception FIFO. The
-        * last mailbox is configured with overwrite option. The
-        * overwrite flag indicates a FIFO overflow.
+        * Due to a chip bug (errata 50.2.6.3 & 50.3.5.3) the first
+        * mailbox is disabled. The next 11 mailboxes are used as a
+        * reception FIFO. The last mailbox is configured with
+        * overwrite option. The overwrite flag indicates a FIFO
+        * overflow.
         */
+       reg_mid = at91_can_id_to_reg_mid(priv->mb0_id);
+       for (i = 0; i < AT91_MB_RX_FIRST; i++) {
+               set_mb_mode(priv, i, AT91_MB_MODE_DISABLED);
+               at91_write(priv, AT91_MID(i), reg_mid);
+               at91_write(priv, AT91_MCR(i), 0x0);     /* clear dlc */
+       }
+
        for (i = AT91_MB_RX_FIRST; i < AT91_MB_RX_LAST; i++)
                set_mb_mode(priv, i, AT91_MB_MODE_RX);
        set_mb_mode(priv, AT91_MB_RX_LAST, AT91_MB_MODE_RX_OVRWR);
@@ -254,7 +280,8 @@ static void at91_setup_mailboxes(struct net_device *dev)
                set_mb_mode_prio(priv, i, AT91_MB_MODE_TX, 0);
 
        /* Reset tx and rx helper pointers */
-       priv->tx_next = priv->tx_echo = priv->rx_next = 0;
+       priv->tx_next = priv->tx_echo = 0;
+       priv->rx_next = AT91_MB_RX_FIRST;
 }
 
 static int at91_set_bittiming(struct net_device *dev)
@@ -372,12 +399,7 @@ static netdev_tx_t at91_start_xmit(struct sk_buff *skb, struct net_device *dev)
                netdev_err(dev, "BUG! TX buffer full when queue awake!\n");
                return NETDEV_TX_BUSY;
        }
-
-       if (cf->can_id & CAN_EFF_FLAG)
-               reg_mid = (cf->can_id & CAN_EFF_MASK) | AT91_MID_MIDE;
-       else
-               reg_mid = (cf->can_id & CAN_SFF_MASK) << 18;
-
+       reg_mid = at91_can_id_to_reg_mid(cf->can_id);
        reg_mcr = ((cf->can_id & CAN_RTR_FLAG) ? AT91_MCR_MRTR : 0) |
                (cf->can_dlc << 16) | AT91_MCR_MTCR;
 
@@ -539,27 +561,31 @@ static void at91_read_msg(struct net_device *dev, unsigned int mb)
  *
  * Theory of Operation:
  *
- * 12 of the 16 mailboxes on the chip are reserved for RX. we split
- * them into 2 groups. The lower group holds 8 and upper 4 mailboxes.
+ * 11 of the 16 mailboxes on the chip are reserved for RX. we split
+ * them into 2 groups. The lower group holds 7 and upper 4 mailboxes.
  *
  * Like it or not, but the chip always saves a received CAN message
  * into the first free mailbox it finds (starting with the
  * lowest). This makes it very difficult to read the messages in the
  * right order from the chip. This is how we work around that problem:
  *
- * The first message goes into mb nr. 0 and issues an interrupt. All
+ * The first message goes into mb nr. 1 and issues an interrupt. All
  * rx ints are disabled in the interrupt handler and a napi poll is
  * scheduled. We read the mailbox, but do _not_ reenable the mb (to
  * receive another message).
  *
  *    lower mbxs      upper
- *   ______^______    __^__
- *  /             \  /     \
+ *     ____^______    __^__
+ *    /           \  /     \
  * +-+-+-+-+-+-+-+-++-+-+-+-+
- * |x|x|x|x|x|x|x|x|| | | | |
+ * | |x|x|x|x|x|x|x|| | | | |
  * +-+-+-+-+-+-+-+-++-+-+-+-+
  *  0 0 0 0 0 0  0 0 0 0 1 1  \ mail
  *  0 1 2 3 4 5  6 7 8 9 0 1  / box
+ *  ^
+ *  |
+ *   \
+ *     unused, due to chip bug
  *
  * The variable priv->rx_next points to the next mailbox to read a
  * message from. As long we're in the lower mailboxes we just read the
@@ -590,10 +616,10 @@ static int at91_poll_rx(struct net_device *dev, int quota)
                        "order of incoming frames cannot be guaranteed\n");
 
  again:
-       for (mb = find_next_bit(addr, AT91_MB_RX_NUM, priv->rx_next);
-            mb < AT91_MB_RX_NUM && quota > 0;
+       for (mb = find_next_bit(addr, AT91_MB_RX_LAST + 1, priv->rx_next);
+            mb < AT91_MB_RX_LAST + 1 && quota > 0;
             reg_sr = at91_read(priv, AT91_SR),
-            mb = find_next_bit(addr, AT91_MB_RX_NUM, ++priv->rx_next)) {
+            mb = find_next_bit(addr, AT91_MB_RX_LAST + 1, ++priv->rx_next)) {
                at91_read_msg(dev, mb);
 
                /* reactivate mailboxes */
@@ -610,8 +636,8 @@ static int at91_poll_rx(struct net_device *dev, int quota)
 
        /* upper group completed, look again in lower */
        if (priv->rx_next > AT91_MB_RX_LOW_LAST &&
-           quota > 0 && mb >= AT91_MB_RX_NUM) {
-               priv->rx_next = 0;
+           quota > 0 && mb > AT91_MB_RX_LAST) {
+               priv->rx_next = AT91_MB_RX_FIRST;
                goto again;
        }
 
@@ -1037,6 +1063,64 @@ static const struct net_device_ops at91_netdev_ops = {
        .ndo_start_xmit = at91_start_xmit,
 };
 
+static ssize_t at91_sysfs_show_mb0_id(struct device *dev,
+               struct device_attribute *attr, char *buf)
+{
+       struct at91_priv *priv = netdev_priv(to_net_dev(dev));
+
+       if (priv->mb0_id & CAN_EFF_FLAG)
+               return snprintf(buf, PAGE_SIZE, "0x%08x\n", priv->mb0_id);
+       else
+               return snprintf(buf, PAGE_SIZE, "0x%03x\n", priv->mb0_id);
+}
+
+static ssize_t at91_sysfs_set_mb0_id(struct device *dev,
+               struct device_attribute *attr, const char *buf, size_t count)
+{
+       struct net_device *ndev = to_net_dev(dev);
+       struct at91_priv *priv = netdev_priv(ndev);
+       unsigned long can_id;
+       ssize_t ret;
+       int err;
+
+       rtnl_lock();
+
+       if (ndev->flags & IFF_UP) {
+               ret = -EBUSY;
+               goto out;
+       }
+
+       err = strict_strtoul(buf, 0, &can_id);
+       if (err) {
+               ret = err;
+               goto out;
+       }
+
+       if (can_id & CAN_EFF_FLAG)
+               can_id &= CAN_EFF_MASK | CAN_EFF_FLAG;
+       else
+               can_id &= CAN_SFF_MASK;
+
+       priv->mb0_id = can_id;
+       ret = count;
+
+ out:
+       rtnl_unlock();
+       return ret;
+}
+
+static DEVICE_ATTR(mb0_id, S_IWUGO | S_IRUGO,
+       at91_sysfs_show_mb0_id, at91_sysfs_set_mb0_id);
+
+static struct attribute *at91_sysfs_attrs[] = {
+       &dev_attr_mb0_id.attr,
+       NULL,
+};
+
+static struct attribute_group at91_sysfs_attr_group = {
+       .attrs = at91_sysfs_attrs,
+};
+
 static int __devinit at91_can_probe(struct platform_device *pdev)
 {
        struct net_device *dev;
@@ -1082,6 +1166,7 @@ static int __devinit at91_can_probe(struct platform_device *pdev)
        dev->netdev_ops = &at91_netdev_ops;
        dev->irq = irq;
        dev->flags |= IFF_ECHO;
+       dev->sysfs_groups[0] = &at91_sysfs_attr_group;
 
        priv = netdev_priv(dev);
        priv->can.clock.freq = clk_get_rate(clk);
@@ -1093,6 +1178,7 @@ static int __devinit at91_can_probe(struct platform_device *pdev)
        priv->dev = dev;
        priv->clk = clk;
        priv->pdata = pdev->dev.platform_data;
+       priv->mb0_id = 0x7ff;
 
        netif_napi_add(dev, &priv->napi, at91_poll, AT91_NAPI_WEIGHT);
 
diff --git a/drivers/net/can/softing/Kconfig b/drivers/net/can/softing/Kconfig
new file mode 100644 (file)
index 0000000..92bd6bd
--- /dev/null
@@ -0,0 +1,30 @@
+config CAN_SOFTING
+       tristate "Softing Gmbh CAN generic support"
+       depends on CAN_DEV
+       ---help---
+         Support for CAN cards from Softing Gmbh & some cards
+         from Vector Gmbh.
+         Softing Gmbh CAN cards come with 1 or 2 physical busses.
+         Those cards typically use Dual Port RAM to communicate
+         with the host CPU. The interface is then identical for PCI
+         and PCMCIA cards. This driver operates on a platform device,
+         which has been created by softing_cs or softing_pci driver.
+         Warning:
+         The API of the card does not allow fine control per bus, but
+         controls the 2 busses on the card together.
+         As such, some actions (start/stop/busoff recovery) on 1 bus
+         must bring down the other bus too temporarily.
+
+config CAN_SOFTING_CS
+       tristate "Softing Gmbh CAN pcmcia cards"
+       depends on PCMCIA
+       select CAN_SOFTING
+       ---help---
+         Support for PCMCIA cards from Softing Gmbh & some cards
+         from Vector Gmbh.
+         You need firmware for these, which you can get at
+         http://developer.berlios.de/projects/socketcan/
+         This version of the driver is written against
+         firmware version 4.6 (softing-fw-4.6-binaries.tar.gz)
+         In order to use the card as CAN device, you need the Softing generic
+         support too.
diff --git a/drivers/net/can/softing/Makefile b/drivers/net/can/softing/Makefile
new file mode 100644 (file)
index 0000000..c5e5016
--- /dev/null
@@ -0,0 +1,6 @@
+
+softing-y := softing_main.o softing_fw.o
+obj-$(CONFIG_CAN_SOFTING) += softing.o
+obj-$(CONFIG_CAN_SOFTING_CS) += softing_cs.o
+
+ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG
diff --git a/drivers/net/can/softing/softing.h b/drivers/net/can/softing/softing.h
new file mode 100644 (file)
index 0000000..7ec9f4d
--- /dev/null
@@ -0,0 +1,167 @@
+/*
+ * softing common interfaces
+ *
+ * by Kurt Van Dijck, 2008-2010
+ */
+
+#include <linux/atomic.h>
+#include <linux/netdevice.h>
+#include <linux/ktime.h>
+#include <linux/mutex.h>
+#include <linux/spinlock.h>
+#include <linux/can.h>
+#include <linux/can/dev.h>
+
+#include "softing_platform.h"
+
+struct softing;
+
+struct softing_priv {
+       struct can_priv can; /* must be the first member! */
+       struct net_device *netdev;
+       struct softing *card;
+       struct {
+               int pending;
+               /* variables wich hold the circular buffer */
+               int echo_put;
+               int echo_get;
+       } tx;
+       struct can_bittiming_const btr_const;
+       int index;
+       uint8_t output;
+       uint16_t chip;
+};
+#define netdev2softing(netdev) ((struct softing_priv *)netdev_priv(netdev))
+
+struct softing {
+       const struct softing_platform_data *pdat;
+       struct platform_device *pdev;
+       struct net_device *net[2];
+       spinlock_t spin; /* protect this structure & DPRAM access */
+       ktime_t ts_ref;
+       ktime_t ts_overflow; /* timestamp overflow value, in ktime */
+
+       struct {
+               /* indication of firmware status */
+               int up;
+               /* protection of the 'up' variable */
+               struct mutex lock;
+       } fw;
+       struct {
+               int nr;
+               int requested;
+               int svc_count;
+               unsigned int dpram_position;
+       } irq;
+       struct {
+               int pending;
+               int last_bus;
+               /*
+                * keep the bus that last tx'd a message,
+                * in order to let every netdev queue resume
+                */
+       } tx;
+       __iomem uint8_t *dpram;
+       unsigned long dpram_phys;
+       unsigned long dpram_size;
+       struct {
+               uint16_t fw_version, hw_version, license, serial;
+               uint16_t chip[2];
+               unsigned int freq; /* remote cpu's operating frequency */
+       } id;
+};
+
+extern int softing_default_output(struct net_device *netdev);
+
+extern ktime_t softing_raw2ktime(struct softing *card, u32 raw);
+
+extern int softing_chip_poweron(struct softing *card);
+
+extern int softing_bootloader_command(struct softing *card, int16_t cmd,
+               const char *msg);
+
+/* Load firmware after reset */
+extern int softing_load_fw(const char *file, struct softing *card,
+                       __iomem uint8_t *virt, unsigned int size, int offset);
+
+/* Load final application firmware after bootloader */
+extern int softing_load_app_fw(const char *file, struct softing *card);
+
+/*
+ * enable or disable irq
+ * only called with fw.lock locked
+ */
+extern int softing_enable_irq(struct softing *card, int enable);
+
+/* start/stop 1 bus on card */
+extern int softing_startstop(struct net_device *netdev, int up);
+
+/* netif_rx() */
+extern int softing_netdev_rx(struct net_device *netdev,
+               const struct can_frame *msg, ktime_t ktime);
+
+/* SOFTING DPRAM mappings */
+#define DPRAM_RX               0x0000
+       #define DPRAM_RX_SIZE   32
+       #define DPRAM_RX_CNT    16
+#define DPRAM_RX_RD            0x0201  /* uint8_t */
+#define DPRAM_RX_WR            0x0205  /* uint8_t */
+#define DPRAM_RX_LOST          0x0207  /* uint8_t */
+
+#define DPRAM_FCT_PARAM                0x0300  /* int16_t [20] */
+#define DPRAM_FCT_RESULT       0x0328  /* int16_t */
+#define DPRAM_FCT_HOST         0x032b  /* uint16_t */
+
+#define DPRAM_INFO_BUSSTATE    0x0331  /* uint16_t */
+#define DPRAM_INFO_BUSSTATE2   0x0335  /* uint16_t */
+#define DPRAM_INFO_ERRSTATE    0x0339  /* uint16_t */
+#define DPRAM_INFO_ERRSTATE2   0x033d  /* uint16_t */
+#define DPRAM_RESET            0x0341  /* uint16_t */
+#define DPRAM_CLR_RECV_FIFO    0x0345  /* uint16_t */
+#define DPRAM_RESET_TIME       0x034d  /* uint16_t */
+#define DPRAM_TIME             0x0350  /* uint64_t */
+#define DPRAM_WR_START         0x0358  /* uint8_t */
+#define DPRAM_WR_END           0x0359  /* uint8_t */
+#define DPRAM_RESET_RX_FIFO    0x0361  /* uint16_t */
+#define DPRAM_RESET_TX_FIFO    0x0364  /* uint8_t */
+#define DPRAM_READ_FIFO_LEVEL  0x0365  /* uint8_t */
+#define DPRAM_RX_FIFO_LEVEL    0x0366  /* uint16_t */
+#define DPRAM_TX_FIFO_LEVEL    0x0366  /* uint16_t */
+
+#define DPRAM_TX               0x0400  /* uint16_t */
+       #define DPRAM_TX_SIZE   16
+       #define DPRAM_TX_CNT    32
+#define DPRAM_TX_RD            0x0601  /* uint8_t */
+#define DPRAM_TX_WR            0x0605  /* uint8_t */
+
+#define DPRAM_COMMAND          0x07e0  /* uint16_t */
+#define DPRAM_RECEIPT          0x07f0  /* uint16_t */
+#define DPRAM_IRQ_TOHOST       0x07fe  /* uint8_t */
+#define DPRAM_IRQ_TOCARD       0x07ff  /* uint8_t */
+
+#define DPRAM_V2_RESET         0x0e00  /* uint8_t */
+#define DPRAM_V2_IRQ_TOHOST    0x0e02  /* uint8_t */
+
+#define TXMAX  (DPRAM_TX_CNT - 1)
+
+/* DPRAM return codes */
+#define RES_NONE       0
+#define RES_OK         1
+#define RES_NOK                2
+#define RES_UNKNOWN    3
+/* DPRAM flags */
+#define CMD_TX         0x01
+#define CMD_ACK                0x02
+#define CMD_XTD                0x04
+#define CMD_RTR                0x08
+#define CMD_ERR                0x10
+#define CMD_BUS2       0x80
+
+/* returned fifo entry bus state masks */
+#define SF_MASK_BUSOFF         0x80
+#define SF_MASK_EPASSIVE       0x60
+
+/* bus states */
+#define STATE_BUSOFF   2
+#define STATE_EPASSIVE 1
+#define STATE_EACTIVE  0
diff --git a/drivers/net/can/softing/softing_cs.c b/drivers/net/can/softing/softing_cs.c
new file mode 100644 (file)
index 0000000..300fe75
--- /dev/null
@@ -0,0 +1,359 @@
+/*
+ * Copyright (C) 2008-2010
+ *
+ * - Kurt Van Dijck, EIA Electronics
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the version 2 of the GNU General Public License
+ * as published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+
+#include <pcmcia/cistpl.h>
+#include <pcmcia/ds.h>
+
+#include "softing_platform.h"
+
+static int softingcs_index;
+static spinlock_t softingcs_index_lock;
+
+static int softingcs_reset(struct platform_device *pdev, int v);
+static int softingcs_enable_irq(struct platform_device *pdev, int v);
+
+/*
+ * platform_data descriptions
+ */
+#define MHZ (1000*1000)
+static const struct softing_platform_data softingcs_platform_data[] = {
+{
+       .name = "CANcard",
+       .manf = 0x0168, .prod = 0x001,
+       .generation = 1,
+       .nbus = 2,
+       .freq = 16 * MHZ, .max_brp = 32, .max_sjw = 4,
+       .dpram_size = 0x0800,
+       .boot = {0x0000, 0x000000, fw_dir "bcard.bin",},
+       .load = {0x0120, 0x00f600, fw_dir "ldcard.bin",},
+       .app = {0x0010, 0x0d0000, fw_dir "cancard.bin",},
+       .reset = softingcs_reset,
+       .enable_irq = softingcs_enable_irq,
+}, {
+       .name = "CANcard-NEC",
+       .manf = 0x0168, .prod = 0x002,
+       .generation = 1,
+       .nbus = 2,
+       .freq = 16 * MHZ, .max_brp = 32, .max_sjw = 4,
+       .dpram_size = 0x0800,
+       .boot = {0x0000, 0x000000, fw_dir "bcard.bin",},
+       .load = {0x0120, 0x00f600, fw_dir "ldcard.bin",},
+       .app = {0x0010, 0x0d0000, fw_dir "cancard.bin",},
+       .reset = softingcs_reset,
+       .enable_irq = softingcs_enable_irq,
+}, {
+       .name = "CANcard-SJA",
+       .manf = 0x0168, .prod = 0x004,
+       .generation = 1,
+       .nbus = 2,
+       .freq = 20 * MHZ, .max_brp = 32, .max_sjw = 4,
+       .dpram_size = 0x0800,
+       .boot = {0x0000, 0x000000, fw_dir "bcard.bin",},
+       .load = {0x0120, 0x00f600, fw_dir "ldcard.bin",},
+       .app = {0x0010, 0x0d0000, fw_dir "cansja.bin",},
+       .reset = softingcs_reset,
+       .enable_irq = softingcs_enable_irq,
+}, {
+       .name = "CANcard-2",
+       .manf = 0x0168, .prod = 0x005,
+       .generation = 2,
+       .nbus = 2,
+       .freq = 24 * MHZ, .max_brp = 64, .max_sjw = 4,
+       .dpram_size = 0x1000,
+       .boot = {0x0000, 0x000000, fw_dir "bcard2.bin",},
+       .load = {0x0120, 0x00f600, fw_dir "ldcard2.bin",},
+       .app = {0x0010, 0x0d0000, fw_dir "cancrd2.bin",},
+       .reset = softingcs_reset,
+       .enable_irq = NULL,
+}, {
+       .name = "Vector-CANcard",
+       .manf = 0x0168, .prod = 0x081,
+       .generation = 1,
+       .nbus = 2,
+       .freq = 16 * MHZ, .max_brp = 64, .max_sjw = 4,
+       .dpram_size = 0x0800,
+       .boot = {0x0000, 0x000000, fw_dir "bcard.bin",},
+       .load = {0x0120, 0x00f600, fw_dir "ldcard.bin",},
+       .app = {0x0010, 0x0d0000, fw_dir "cancard.bin",},
+       .reset = softingcs_reset,
+       .enable_irq = softingcs_enable_irq,
+}, {
+       .name = "Vector-CANcard-SJA",
+       .manf = 0x0168, .prod = 0x084,
+       .generation = 1,
+       .nbus = 2,
+       .freq = 20 * MHZ, .max_brp = 32, .max_sjw = 4,
+       .dpram_size = 0x0800,
+       .boot = {0x0000, 0x000000, fw_dir "bcard.bin",},
+       .load = {0x0120, 0x00f600, fw_dir "ldcard.bin",},
+       .app = {0x0010, 0x0d0000, fw_dir "cansja.bin",},
+       .reset = softingcs_reset,
+       .enable_irq = softingcs_enable_irq,
+}, {
+       .name = "Vector-CANcard-2",
+       .manf = 0x0168, .prod = 0x085,
+       .generation = 2,
+       .nbus = 2,
+       .freq = 24 * MHZ, .max_brp = 64, .max_sjw = 4,
+       .dpram_size = 0x1000,
+       .boot = {0x0000, 0x000000, fw_dir "bcard2.bin",},
+       .load = {0x0120, 0x00f600, fw_dir "ldcard2.bin",},
+       .app = {0x0010, 0x0d0000, fw_dir "cancrd2.bin",},
+       .reset = softingcs_reset,
+       .enable_irq = NULL,
+}, {
+       .name = "EDICcard-NEC",
+       .manf = 0x0168, .prod = 0x102,
+       .generation = 1,
+       .nbus = 2,
+       .freq = 16 * MHZ, .max_brp = 64, .max_sjw = 4,
+       .dpram_size = 0x0800,
+       .boot = {0x0000, 0x000000, fw_dir "bcard.bin",},
+       .load = {0x0120, 0x00f600, fw_dir "ldcard.bin",},
+       .app = {0x0010, 0x0d0000, fw_dir "cancard.bin",},
+       .reset = softingcs_reset,
+       .enable_irq = softingcs_enable_irq,
+}, {
+       .name = "EDICcard-2",
+       .manf = 0x0168, .prod = 0x105,
+       .generation = 2,
+       .nbus = 2,
+       .freq = 24 * MHZ, .max_brp = 64, .max_sjw = 4,
+       .dpram_size = 0x1000,
+       .boot = {0x0000, 0x000000, fw_dir "bcard2.bin",},
+       .load = {0x0120, 0x00f600, fw_dir "ldcard2.bin",},
+       .app = {0x0010, 0x0d0000, fw_dir "cancrd2.bin",},
+       .reset = softingcs_reset,
+       .enable_irq = NULL,
+}, {
+       0, 0,
+},
+};
+
+MODULE_FIRMWARE(fw_dir "bcard.bin");
+MODULE_FIRMWARE(fw_dir "ldcard.bin");
+MODULE_FIRMWARE(fw_dir "cancard.bin");
+MODULE_FIRMWARE(fw_dir "cansja.bin");
+
+MODULE_FIRMWARE(fw_dir "bcard2.bin");
+MODULE_FIRMWARE(fw_dir "ldcard2.bin");
+MODULE_FIRMWARE(fw_dir "cancrd2.bin");
+
+static __devinit const struct softing_platform_data
+*softingcs_find_platform_data(unsigned int manf, unsigned int prod)
+{
+       const struct softing_platform_data *lp;
+
+       for (lp = softingcs_platform_data; lp->manf; ++lp) {
+               if ((lp->manf == manf) && (lp->prod == prod))
+                       return lp;
+       }
+       return NULL;
+}
+
+/*
+ * platformdata callbacks
+ */
+static int softingcs_reset(struct platform_device *pdev, int v)
+{
+       struct pcmcia_device *pcmcia = to_pcmcia_dev(pdev->dev.parent);
+
+       dev_dbg(&pdev->dev, "pcmcia config [2] %02x\n", v ? 0 : 0x20);
+       return pcmcia_write_config_byte(pcmcia, 2, v ? 0 : 0x20);
+}
+
+static int softingcs_enable_irq(struct platform_device *pdev, int v)
+{
+       struct pcmcia_device *pcmcia = to_pcmcia_dev(pdev->dev.parent);
+
+       dev_dbg(&pdev->dev, "pcmcia config [0] %02x\n", v ? 0x60 : 0);
+       return pcmcia_write_config_byte(pcmcia, 0, v ? 0x60 : 0);
+}
+
+/*
+ * pcmcia check
+ */
+static __devinit int softingcs_probe_config(struct pcmcia_device *pcmcia,
+               void *priv_data)
+{
+       struct softing_platform_data *pdat = priv_data;
+       struct resource *pres;
+       int memspeed = 0;
+
+       WARN_ON(!pdat);
+       pres = pcmcia->resource[PCMCIA_IOMEM_0];
+       if (resource_size(pres) < 0x1000)
+               return -ERANGE;
+
+       pres->flags |= WIN_MEMORY_TYPE_CM | WIN_ENABLE;
+       if (pdat->generation < 2) {
+               pres->flags |= WIN_USE_WAIT | WIN_DATA_WIDTH_8;
+               memspeed = 3;
+       } else {
+               pres->flags |= WIN_DATA_WIDTH_16;
+       }
+       return pcmcia_request_window(pcmcia, pres, memspeed);
+}
+
+static __devexit void softingcs_remove(struct pcmcia_device *pcmcia)
+{
+       struct platform_device *pdev = pcmcia->priv;
+
+       /* free bits */
+       platform_device_unregister(pdev);
+       /* release pcmcia stuff */
+       pcmcia_disable_device(pcmcia);
+}
+
+/*
+ * platform_device wrapper
+ * pdev->resource has 2 entries: io & irq
+ */
+static void softingcs_pdev_release(struct device *dev)
+{
+       struct platform_device *pdev = to_platform_device(dev);
+       kfree(pdev);
+}
+
+static __devinit int softingcs_probe(struct pcmcia_device *pcmcia)
+{
+       int ret;
+       struct platform_device *pdev;
+       const struct softing_platform_data *pdat;
+       struct resource *pres;
+       struct dev {
+               struct platform_device pdev;
+               struct resource res[2];
+       } *dev;
+
+       /* find matching platform_data */
+       pdat = softingcs_find_platform_data(pcmcia->manf_id, pcmcia->card_id);
+       if (!pdat)
+               return -ENOTTY;
+
+       /* setup pcmcia device */
+       pcmcia->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IOMEM |
+               CONF_AUTO_SET_VPP | CONF_AUTO_CHECK_VCC;
+       ret = pcmcia_loop_config(pcmcia, softingcs_probe_config, (void *)pdat);
+       if (ret)
+               goto pcmcia_failed;
+
+       ret = pcmcia_enable_device(pcmcia);
+       if (ret < 0)
+               goto pcmcia_failed;
+
+       pres = pcmcia->resource[PCMCIA_IOMEM_0];
+       if (!pres) {
+               ret = -EBADF;
+               goto pcmcia_bad;
+       }
+
+       /* create softing platform device */
+       dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+       if (!dev) {
+               ret = -ENOMEM;
+               goto mem_failed;
+       }
+       dev->pdev.resource = dev->res;
+       dev->pdev.num_resources = ARRAY_SIZE(dev->res);
+       dev->pdev.dev.release = softingcs_pdev_release;
+
+       pdev = &dev->pdev;
+       pdev->dev.platform_data = (void *)pdat;
+       pdev->dev.parent = &pcmcia->dev;
+       pcmcia->priv = pdev;
+
+       /* platform device resources */
+       pdev->resource[0].flags = IORESOURCE_MEM;
+       pdev->resource[0].start = pres->start;
+       pdev->resource[0].end = pres->end;
+
+       pdev->resource[1].flags = IORESOURCE_IRQ;
+       pdev->resource[1].start = pcmcia->irq;
+       pdev->resource[1].end = pdev->resource[1].start;
+
+       /* platform device setup */
+       spin_lock(&softingcs_index_lock);
+       pdev->id = softingcs_index++;
+       spin_unlock(&softingcs_index_lock);
+       pdev->name = "softing";
+       dev_set_name(&pdev->dev, "softingcs.%i", pdev->id);
+       ret = platform_device_register(pdev);
+       if (ret < 0)
+               goto platform_failed;
+
+       dev_info(&pcmcia->dev, "created %s\n", dev_name(&pdev->dev));
+       return 0;
+
+platform_failed:
+       kfree(dev);
+mem_failed:
+pcmcia_bad:
+pcmcia_failed:
+       pcmcia_disable_device(pcmcia);
+       pcmcia->priv = NULL;
+       return ret ?: -ENODEV;
+}
+
+static /*const*/ struct pcmcia_device_id softingcs_ids[] = {
+       /* softing */
+       PCMCIA_DEVICE_MANF_CARD(0x0168, 0x0001),
+       PCMCIA_DEVICE_MANF_CARD(0x0168, 0x0002),
+       PCMCIA_DEVICE_MANF_CARD(0x0168, 0x0004),
+       PCMCIA_DEVICE_MANF_CARD(0x0168, 0x0005),
+       /* vector, manufacturer? */
+       PCMCIA_DEVICE_MANF_CARD(0x0168, 0x0081),
+       PCMCIA_DEVICE_MANF_CARD(0x0168, 0x0084),
+       PCMCIA_DEVICE_MANF_CARD(0x0168, 0x0085),
+       /* EDIC */
+       PCMCIA_DEVICE_MANF_CARD(0x0168, 0x0102),
+       PCMCIA_DEVICE_MANF_CARD(0x0168, 0x0105),
+       PCMCIA_DEVICE_NULL,
+};
+
+MODULE_DEVICE_TABLE(pcmcia, softingcs_ids);
+
+static struct pcmcia_driver softingcs_driver = {
+       .owner          = THIS_MODULE,
+       .name           = "softingcs",
+       .id_table       = softingcs_ids,
+       .probe          = softingcs_probe,
+       .remove         = __devexit_p(softingcs_remove),
+};
+
+static int __init softingcs_start(void)
+{
+       spin_lock_init(&softingcs_index_lock);
+       return pcmcia_register_driver(&softingcs_driver);
+}
+
+static void __exit softingcs_stop(void)
+{
+       pcmcia_unregister_driver(&softingcs_driver);
+}
+
+module_init(softingcs_start);
+module_exit(softingcs_stop);
+
+MODULE_DESCRIPTION("softing CANcard driver"
+               ", links PCMCIA card to softing driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/net/can/softing/softing_fw.c b/drivers/net/can/softing/softing_fw.c
new file mode 100644 (file)
index 0000000..b520784
--- /dev/null
@@ -0,0 +1,691 @@
+/*
+ * Copyright (C) 2008-2010
+ *
+ * - Kurt Van Dijck, EIA Electronics
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the version 2 of the GNU General Public License
+ * as published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/firmware.h>
+#include <linux/sched.h>
+#include <asm/div64.h>
+
+#include "softing.h"
+
+/*
+ * low level DPRAM command.
+ * Make sure that card->dpram[DPRAM_FCT_HOST] is preset
+ */
+static int _softing_fct_cmd(struct softing *card, int16_t cmd, uint16_t vector,
+               const char *msg)
+{
+       int ret;
+       unsigned long stamp;
+
+       iowrite16(cmd, &card->dpram[DPRAM_FCT_PARAM]);
+       iowrite8(vector >> 8, &card->dpram[DPRAM_FCT_HOST + 1]);
+       iowrite8(vector, &card->dpram[DPRAM_FCT_HOST]);
+       /* be sure to flush this to the card */
+       wmb();
+       stamp = jiffies + 1 * HZ;
+       /* wait for card */
+       do {
+               /* DPRAM_FCT_HOST is _not_ aligned */
+               ret = ioread8(&card->dpram[DPRAM_FCT_HOST]) +
+                       (ioread8(&card->dpram[DPRAM_FCT_HOST + 1]) << 8);
+               /* don't have any cached variables */
+               rmb();
+               if (ret == RES_OK)
+                       /* read return-value now */
+                       return ioread16(&card->dpram[DPRAM_FCT_RESULT]);
+
+               if ((ret != vector) || time_after(jiffies, stamp))
+                       break;
+               /* process context => relax */
+               usleep_range(500, 10000);
+       } while (1);
+
+       ret = (ret == RES_NONE) ? -ETIMEDOUT : -ECANCELED;
+       dev_alert(&card->pdev->dev, "firmware %s failed (%i)\n", msg, ret);
+       return ret;
+}
+
+static int softing_fct_cmd(struct softing *card, int16_t cmd, const char *msg)
+{
+       int ret;
+
+       ret = _softing_fct_cmd(card, cmd, 0, msg);
+       if (ret > 0) {
+               dev_alert(&card->pdev->dev, "%s returned %u\n", msg, ret);
+               ret = -EIO;
+       }
+       return ret;
+}
+
+int softing_bootloader_command(struct softing *card, int16_t cmd,
+               const char *msg)
+{
+       int ret;
+       unsigned long stamp;
+
+       iowrite16(RES_NONE, &card->dpram[DPRAM_RECEIPT]);
+       iowrite16(cmd, &card->dpram[DPRAM_COMMAND]);
+       /* be sure to flush this to the card */
+       wmb();
+       stamp = jiffies + 3 * HZ;
+       /* wait for card */
+       do {
+               ret = ioread16(&card->dpram[DPRAM_RECEIPT]);
+               /* don't have any cached variables */
+               rmb();
+               if (ret == RES_OK)
+                       return 0;
+               if (time_after(jiffies, stamp))
+                       break;
+               /* process context => relax */
+               usleep_range(500, 10000);
+       } while (!signal_pending(current));
+
+       ret = (ret == RES_NONE) ? -ETIMEDOUT : -ECANCELED;
+       dev_alert(&card->pdev->dev, "bootloader %s failed (%i)\n", msg, ret);
+       return ret;
+}
+
+static int fw_parse(const uint8_t **pmem, uint16_t *ptype, uint32_t *paddr,
+               uint16_t *plen, const uint8_t **pdat)
+{
+       uint16_t checksum[2];
+       const uint8_t *mem;
+       const uint8_t *end;
+
+       /*
+        * firmware records are a binary, unaligned stream composed of:
+        * uint16_t type;
+        * uint32_t addr;
+        * uint16_t len;
+        * uint8_t dat[len];
+        * uint16_t checksum;
+        * all values in little endian.
+        * We could define a struct for this, with __attribute__((packed)),
+        * but would that solve the alignment in _all_ cases (cfr. the
+        * struct itself may be an odd address)?
+        *
+        * I chose to use leXX_to_cpup() since this solves both
+        * endianness & alignment.
+        */
+       mem = *pmem;
+       *ptype = le16_to_cpup((void *)&mem[0]);
+       *paddr = le32_to_cpup((void *)&mem[2]);
+       *plen = le16_to_cpup((void *)&mem[6]);
+       *pdat = &mem[8];
+       /* verify checksum */
+       end = &mem[8 + *plen];
+       checksum[0] = le16_to_cpup((void *)end);
+       for (checksum[1] = 0; mem < end; ++mem)
+               checksum[1] += *mem;
+       if (checksum[0] != checksum[1])
+               return -EINVAL;
+       /* increment */
+       *pmem += 10 + *plen;
+       return 0;
+}
+
+int softing_load_fw(const char *file, struct softing *card,
+               __iomem uint8_t *dpram, unsigned int size, int offset)
+{
+       const struct firmware *fw;
+       int ret;
+       const uint8_t *mem, *end, *dat;
+       uint16_t type, len;
+       uint32_t addr;
+       uint8_t *buf = NULL;
+       int buflen = 0;
+       int8_t type_end = 0;
+
+       ret = request_firmware(&fw, file, &card->pdev->dev);
+       if (ret < 0)
+               return ret;
+       dev_dbg(&card->pdev->dev, "%s, firmware(%s) got %u bytes"
+               ", offset %c0x%04x\n",
+               card->pdat->name, file, (unsigned int)fw->size,
+               (offset >= 0) ? '+' : '-', (unsigned int)abs(offset));
+       /* parse the firmware */
+       mem = fw->data;
+       end = &mem[fw->size];
+       /* look for header record */
+       ret = fw_parse(&mem, &type, &addr, &len, &dat);
+       if (ret < 0)
+               goto failed;
+       if (type != 0xffff)
+               goto failed;
+       if (strncmp("Structured Binary Format, Softing GmbH" , dat, len)) {
+               ret = -EINVAL;
+               goto failed;
+       }
+       /* ok, we had a header */
+       while (mem < end) {
+               ret = fw_parse(&mem, &type, &addr, &len, &dat);
+               if (ret < 0)
+                       goto failed;
+               if (type == 3) {
+                       /* start address, not used here */
+                       continue;
+               } else if (type == 1) {
+                       /* eof */
+                       type_end = 1;
+                       break;
+               } else if (type != 0) {
+                       ret = -EINVAL;
+                       goto failed;
+               }
+
+               if ((addr + len + offset) > size)
+                       goto failed;
+               memcpy_toio(&dpram[addr + offset], dat, len);
+               /* be sure to flush caches from IO space */
+               mb();
+               if (len > buflen) {
+                       /* align buflen */
+                       buflen = (len + (1024-1)) & ~(1024-1);
+                       buf = krealloc(buf, buflen, GFP_KERNEL);
+                       if (!buf) {
+                               ret = -ENOMEM;
+                               goto failed;
+                       }
+               }
+               /* verify record data */
+               memcpy_fromio(buf, &dpram[addr + offset], len);
+               if (memcmp(buf, dat, len)) {
+                       /* is not ok */
+                       dev_alert(&card->pdev->dev, "DPRAM readback failed\n");
+                       ret = -EIO;
+                       goto failed;
+               }
+       }
+       if (!type_end)
+               /* no end record seen */
+               goto failed;
+       ret = 0;
+failed:
+       kfree(buf);
+       release_firmware(fw);
+       if (ret < 0)
+               dev_info(&card->pdev->dev, "firmware %s failed\n", file);
+       return ret;
+}
+
+int softing_load_app_fw(const char *file, struct softing *card)
+{
+       const struct firmware *fw;
+       const uint8_t *mem, *end, *dat;
+       int ret, j;
+       uint16_t type, len;
+       uint32_t addr, start_addr = 0;
+       unsigned int sum, rx_sum;
+       int8_t type_end = 0, type_entrypoint = 0;
+
+       ret = request_firmware(&fw, file, &card->pdev->dev);
+       if (ret) {
+               dev_alert(&card->pdev->dev, "request_firmware(%s) got %i\n",
+                       file, ret);
+               return ret;
+       }
+       dev_dbg(&card->pdev->dev, "firmware(%s) got %lu bytes\n",
+               file, (unsigned long)fw->size);
+       /* parse the firmware */
+       mem = fw->data;
+       end = &mem[fw->size];
+       /* look for header record */
+       ret = fw_parse(&mem, &type, &addr, &len, &dat);
+       if (ret)
+               goto failed;
+       ret = -EINVAL;
+       if (type != 0xffff) {
+               dev_alert(&card->pdev->dev, "firmware starts with type 0x%x\n",
+                       type);
+               goto failed;
+       }
+       if (strncmp("Structured Binary Format, Softing GmbH", dat, len)) {
+               dev_alert(&card->pdev->dev, "firmware string '%.*s' fault\n",
+                               len, dat);
+               goto failed;
+       }
+       /* ok, we had a header */
+       while (mem < end) {
+               ret = fw_parse(&mem, &type, &addr, &len, &dat);
+               if (ret)
+                       goto failed;
+
+               if (type == 3) {
+                       /* start address */
+                       start_addr = addr;
+                       type_entrypoint = 1;
+                       continue;
+               } else if (type == 1) {
+                       /* eof */
+                       type_end = 1;
+                       break;
+               } else if (type != 0) {
+                       dev_alert(&card->pdev->dev,
+                                       "unknown record type 0x%04x\n", type);
+                       ret = -EINVAL;
+                       goto failed;
+               }
+
+               /* regualar data */
+               for (sum = 0, j = 0; j < len; ++j)
+                       sum += dat[j];
+               /* work in 16bit (target) */
+               sum &= 0xffff;
+
+               memcpy_toio(&card->dpram[card->pdat->app.offs], dat, len);
+               iowrite32(card->pdat->app.offs + card->pdat->app.addr,
+                               &card->dpram[DPRAM_COMMAND + 2]);
+               iowrite32(addr, &card->dpram[DPRAM_COMMAND + 6]);
+               iowrite16(len, &card->dpram[DPRAM_COMMAND + 10]);
+               iowrite8(1, &card->dpram[DPRAM_COMMAND + 12]);
+               ret = softing_bootloader_command(card, 1, "loading app.");
+               if (ret < 0)
+                       goto failed;
+               /* verify checksum */
+               rx_sum = ioread16(&card->dpram[DPRAM_RECEIPT + 2]);
+               if (rx_sum != sum) {
+                       dev_alert(&card->pdev->dev, "SRAM seems to be damaged"
+                               ", wanted 0x%04x, got 0x%04x\n", sum, rx_sum);
+                       ret = -EIO;
+                       goto failed;
+               }
+       }
+       if (!type_end || !type_entrypoint)
+               goto failed;
+       /* start application in card */
+       iowrite32(start_addr, &card->dpram[DPRAM_COMMAND + 2]);
+       iowrite8(1, &card->dpram[DPRAM_COMMAND + 6]);
+       ret = softing_bootloader_command(card, 3, "start app.");
+       if (ret < 0)
+               goto failed;
+       ret = 0;
+failed:
+       release_firmware(fw);
+       if (ret < 0)
+               dev_info(&card->pdev->dev, "firmware %s failed\n", file);
+       return ret;
+}
+
+static int softing_reset_chip(struct softing *card)
+{
+       int ret;
+
+       do {
+               /* reset chip */
+               iowrite8(0, &card->dpram[DPRAM_RESET_RX_FIFO]);
+               iowrite8(0, &card->dpram[DPRAM_RESET_RX_FIFO+1]);
+               iowrite8(1, &card->dpram[DPRAM_RESET]);
+               iowrite8(0, &card->dpram[DPRAM_RESET+1]);
+
+               ret = softing_fct_cmd(card, 0, "reset_can");
+               if (!ret)
+                       break;
+               if (signal_pending(current))
+                       /* don't wait any longer */
+                       break;
+       } while (1);
+       card->tx.pending = 0;
+       return ret;
+}
+
+int softing_chip_poweron(struct softing *card)
+{
+       int ret;
+       /* sync */
+       ret = _softing_fct_cmd(card, 99, 0x55, "sync-a");
+       if (ret < 0)
+               goto failed;
+
+       ret = _softing_fct_cmd(card, 99, 0xaa, "sync-b");
+       if (ret < 0)
+               goto failed;
+
+       ret = softing_reset_chip(card);
+       if (ret < 0)
+               goto failed;
+       /* get_serial */
+       ret = softing_fct_cmd(card, 43, "get_serial_number");
+       if (ret < 0)
+               goto failed;
+       card->id.serial = ioread32(&card->dpram[DPRAM_FCT_PARAM]);
+       /* get_version */
+       ret = softing_fct_cmd(card, 12, "get_version");
+       if (ret < 0)
+               goto failed;
+       card->id.fw_version = ioread16(&card->dpram[DPRAM_FCT_PARAM + 2]);
+       card->id.hw_version = ioread16(&card->dpram[DPRAM_FCT_PARAM + 4]);
+       card->id.license = ioread16(&card->dpram[DPRAM_FCT_PARAM + 6]);
+       card->id.chip[0] = ioread16(&card->dpram[DPRAM_FCT_PARAM + 8]);
+       card->id.chip[1] = ioread16(&card->dpram[DPRAM_FCT_PARAM + 10]);
+       return 0;
+failed:
+       return ret;
+}
+
+static void softing_initialize_timestamp(struct softing *card)
+{
+       uint64_t ovf;
+
+       card->ts_ref = ktime_get();
+
+       /* 16MHz is the reference */
+       ovf = 0x100000000ULL * 16;
+       do_div(ovf, card->pdat->freq ?: 16);
+
+       card->ts_overflow = ktime_add_us(ktime_set(0, 0), ovf);
+}
+
+ktime_t softing_raw2ktime(struct softing *card, u32 raw)
+{
+       uint64_t rawl;
+       ktime_t now, real_offset;
+       ktime_t target;
+       ktime_t tmp;
+
+       now = ktime_get();
+       real_offset = ktime_sub(ktime_get_real(), now);
+
+       /* find nsec from card */
+       rawl = raw * 16;
+       do_div(rawl, card->pdat->freq ?: 16);
+       target = ktime_add_us(card->ts_ref, rawl);
+       /* test for overflows */
+       tmp = ktime_add(target, card->ts_overflow);
+       while (unlikely(ktime_to_ns(tmp) > ktime_to_ns(now))) {
+               card->ts_ref = ktime_add(card->ts_ref, card->ts_overflow);
+               target = tmp;
+               tmp = ktime_add(target, card->ts_overflow);
+       }
+       return ktime_add(target, real_offset);
+}
+
+static inline int softing_error_reporting(struct net_device *netdev)
+{
+       struct softing_priv *priv = netdev_priv(netdev);
+
+       return (priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING)
+               ? 1 : 0;
+}
+
+int softing_startstop(struct net_device *dev, int up)
+{
+       int ret;
+       struct softing *card;
+       struct softing_priv *priv;
+       struct net_device *netdev;
+       int bus_bitmask_start;
+       int j, error_reporting;
+       struct can_frame msg;
+       const struct can_bittiming *bt;
+
+       priv = netdev_priv(dev);
+       card = priv->card;
+
+       if (!card->fw.up)
+               return -EIO;
+
+       ret = mutex_lock_interruptible(&card->fw.lock);
+       if (ret)
+               return ret;
+
+       bus_bitmask_start = 0;
+       if (dev && up)
+               /* prepare to start this bus as well */
+               bus_bitmask_start |= (1 << priv->index);
+       /* bring netdevs down */
+       for (j = 0; j < ARRAY_SIZE(card->net); ++j) {
+               netdev = card->net[j];
+               if (!netdev)
+                       continue;
+               priv = netdev_priv(netdev);
+
+               if (dev != netdev)
+                       netif_stop_queue(netdev);
+
+               if (netif_running(netdev)) {
+                       if (dev != netdev)
+                               bus_bitmask_start |= (1 << j);
+                       priv->tx.pending = 0;
+                       priv->tx.echo_put = 0;
+                       priv->tx.echo_get = 0;
+                       /*
+                        * this bus' may just have called open_candev()
+                        * which is rather stupid to call close_candev()
+                        * already
+                        * but we may come here from busoff recovery too
+                        * in which case the echo_skb _needs_ flushing too.
+                        * just be sure to call open_candev() again
+                        */
+                       close_candev(netdev);
+               }
+               priv->can.state = CAN_STATE_STOPPED;
+       }
+       card->tx.pending = 0;
+
+       softing_enable_irq(card, 0);
+       ret = softing_reset_chip(card);
+       if (ret)
+               goto failed;
+       if (!bus_bitmask_start)
+               /* no busses to be brought up */
+               goto card_done;
+
+       if ((bus_bitmask_start & 1) && (bus_bitmask_start & 2)
+                       && (softing_error_reporting(card->net[0])
+                               != softing_error_reporting(card->net[1]))) {
+               dev_alert(&card->pdev->dev,
+                               "err_reporting flag differs for busses\n");
+               goto invalid;
+       }
+       error_reporting = 0;
+       if (bus_bitmask_start & 1) {
+               netdev = card->net[0];
+               priv = netdev_priv(netdev);
+               error_reporting += softing_error_reporting(netdev);
+               /* init chip 1 */
+               bt = &priv->can.bittiming;
+               iowrite16(bt->brp, &card->dpram[DPRAM_FCT_PARAM + 2]);
+               iowrite16(bt->sjw, &card->dpram[DPRAM_FCT_PARAM + 4]);
+               iowrite16(bt->phase_seg1 + bt->prop_seg,
+                               &card->dpram[DPRAM_FCT_PARAM + 6]);
+               iowrite16(bt->phase_seg2, &card->dpram[DPRAM_FCT_PARAM + 8]);
+               iowrite16((priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES) ? 1 : 0,
+                               &card->dpram[DPRAM_FCT_PARAM + 10]);
+               ret = softing_fct_cmd(card, 1, "initialize_chip[0]");
+               if (ret < 0)
+                       goto failed;
+               /* set mode */
+               iowrite16(0, &card->dpram[DPRAM_FCT_PARAM + 2]);
+               iowrite16(0, &card->dpram[DPRAM_FCT_PARAM + 4]);
+               ret = softing_fct_cmd(card, 3, "set_mode[0]");
+               if (ret < 0)
+                       goto failed;
+               /* set filter */
+               /* 11bit id & mask */
+               iowrite16(0x0000, &card->dpram[DPRAM_FCT_PARAM + 2]);
+               iowrite16(0x07ff, &card->dpram[DPRAM_FCT_PARAM + 4]);
+               /* 29bit id.lo & mask.lo & id.hi & mask.hi */
+               iowrite16(0x0000, &card->dpram[DPRAM_FCT_PARAM + 6]);
+               iowrite16(0xffff, &card->dpram[DPRAM_FCT_PARAM + 8]);
+               iowrite16(0x0000, &card->dpram[DPRAM_FCT_PARAM + 10]);
+               iowrite16(0x1fff, &card->dpram[DPRAM_FCT_PARAM + 12]);
+               ret = softing_fct_cmd(card, 7, "set_filter[0]");
+               if (ret < 0)
+                       goto failed;
+               /* set output control */
+               iowrite16(priv->output, &card->dpram[DPRAM_FCT_PARAM + 2]);
+               ret = softing_fct_cmd(card, 5, "set_output[0]");
+               if (ret < 0)
+                       goto failed;
+       }
+       if (bus_bitmask_start & 2) {
+               netdev = card->net[1];
+               priv = netdev_priv(netdev);
+               error_reporting += softing_error_reporting(netdev);
+               /* init chip2 */
+               bt = &priv->can.bittiming;
+               iowrite16(bt->brp, &card->dpram[DPRAM_FCT_PARAM + 2]);
+               iowrite16(bt->sjw, &card->dpram[DPRAM_FCT_PARAM + 4]);
+               iowrite16(bt->phase_seg1 + bt->prop_seg,
+                               &card->dpram[DPRAM_FCT_PARAM + 6]);
+               iowrite16(bt->phase_seg2, &card->dpram[DPRAM_FCT_PARAM + 8]);
+               iowrite16((priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES) ? 1 : 0,
+                               &card->dpram[DPRAM_FCT_PARAM + 10]);
+               ret = softing_fct_cmd(card, 2, "initialize_chip[1]");
+               if (ret < 0)
+                       goto failed;
+               /* set mode2 */
+               iowrite16(0, &card->dpram[DPRAM_FCT_PARAM + 2]);
+               iowrite16(0, &card->dpram[DPRAM_FCT_PARAM + 4]);
+               ret = softing_fct_cmd(card, 4, "set_mode[1]");
+               if (ret < 0)
+                       goto failed;
+               /* set filter2 */
+               /* 11bit id & mask */
+               iowrite16(0x0000, &card->dpram[DPRAM_FCT_PARAM + 2]);
+               iowrite16(0x07ff, &card->dpram[DPRAM_FCT_PARAM + 4]);
+               /* 29bit id.lo & mask.lo & id.hi & mask.hi */
+               iowrite16(0x0000, &card->dpram[DPRAM_FCT_PARAM + 6]);
+               iowrite16(0xffff, &card->dpram[DPRAM_FCT_PARAM + 8]);
+               iowrite16(0x0000, &card->dpram[DPRAM_FCT_PARAM + 10]);
+               iowrite16(0x1fff, &card->dpram[DPRAM_FCT_PARAM + 12]);
+               ret = softing_fct_cmd(card, 8, "set_filter[1]");
+               if (ret < 0)
+                       goto failed;
+               /* set output control2 */
+               iowrite16(priv->output, &card->dpram[DPRAM_FCT_PARAM + 2]);
+               ret = softing_fct_cmd(card, 6, "set_output[1]");
+               if (ret < 0)
+                       goto failed;
+       }
+       /* enable_error_frame */
+       /*
+        * Error reporting is switched off at the moment since
+        * the receiving of them is not yet 100% verified
+        * This should be enabled sooner or later
+        *
+       if (error_reporting) {
+               ret = softing_fct_cmd(card, 51, "enable_error_frame");
+               if (ret < 0)
+                       goto failed;
+       }
+       */
+       /* initialize interface */
+       iowrite16(1, &card->dpram[DPRAM_FCT_PARAM + 2]);
+       iowrite16(1, &card->dpram[DPRAM_FCT_PARAM + 4]);
+       iowrite16(1, &card->dpram[DPRAM_FCT_PARAM + 6]);
+       iowrite16(1, &card->dpram[DPRAM_FCT_PARAM + 8]);
+       iowrite16(1, &card->dpram[DPRAM_FCT_PARAM + 10]);
+       iowrite16(1, &card->dpram[DPRAM_FCT_PARAM + 12]);
+       iowrite16(1, &card->dpram[DPRAM_FCT_PARAM + 14]);
+       iowrite16(1, &card->dpram[DPRAM_FCT_PARAM + 16]);
+       iowrite16(1, &card->dpram[DPRAM_FCT_PARAM + 18]);
+       iowrite16(1, &card->dpram[DPRAM_FCT_PARAM + 20]);
+       ret = softing_fct_cmd(card, 17, "initialize_interface");
+       if (ret < 0)
+               goto failed;
+       /* enable_fifo */
+       ret = softing_fct_cmd(card, 36, "enable_fifo");
+       if (ret < 0)
+               goto failed;
+       /* enable fifo tx ack */
+       ret = softing_fct_cmd(card, 13, "fifo_tx_ack[0]");
+       if (ret < 0)
+               goto failed;
+       /* enable fifo tx ack2 */
+       ret = softing_fct_cmd(card, 14, "fifo_tx_ack[1]");
+       if (ret < 0)
+               goto failed;
+       /* start_chip */
+       ret = softing_fct_cmd(card, 11, "start_chip");
+       if (ret < 0)
+               goto failed;
+       iowrite8(0, &card->dpram[DPRAM_INFO_BUSSTATE]);
+       iowrite8(0, &card->dpram[DPRAM_INFO_BUSSTATE2]);
+       if (card->pdat->generation < 2) {
+               iowrite8(0, &card->dpram[DPRAM_V2_IRQ_TOHOST]);
+               /* flush the DPRAM caches */
+               wmb();
+       }
+
+       softing_initialize_timestamp(card);
+
+       /*
+        * do socketcan notifications/status changes
+        * from here, no errors should occur, or the failed: part
+        * must be reviewed
+        */
+       memset(&msg, 0, sizeof(msg));
+       msg.can_id = CAN_ERR_FLAG | CAN_ERR_RESTARTED;
+       msg.can_dlc = CAN_ERR_DLC;
+       for (j = 0; j < ARRAY_SIZE(card->net); ++j) {
+               if (!(bus_bitmask_start & (1 << j)))
+                       continue;
+               netdev = card->net[j];
+               if (!netdev)
+                       continue;
+               priv = netdev_priv(netdev);
+               priv->can.state = CAN_STATE_ERROR_ACTIVE;
+               open_candev(netdev);
+               if (dev != netdev) {
+                       /* notify other busses on the restart */
+                       softing_netdev_rx(netdev, &msg, ktime_set(0, 0));
+                       ++priv->can.can_stats.restarts;
+               }
+               netif_wake_queue(netdev);
+       }
+
+       /* enable interrupts */
+       ret = softing_enable_irq(card, 1);
+       if (ret)
+               goto failed;
+card_done:
+       mutex_unlock(&card->fw.lock);
+       return 0;
+invalid:
+       ret = -EINVAL;
+failed:
+       softing_enable_irq(card, 0);
+       softing_reset_chip(card);
+       mutex_unlock(&card->fw.lock);
+       /* bring all other interfaces down */
+       for (j = 0; j < ARRAY_SIZE(card->net); ++j) {
+               netdev = card->net[j];
+               if (!netdev)
+                       continue;
+               dev_close(netdev);
+       }
+       return ret;
+}
+
+int softing_default_output(struct net_device *netdev)
+{
+       struct softing_priv *priv = netdev_priv(netdev);
+       struct softing *card = priv->card;
+
+       switch (priv->chip) {
+       case 1000:
+               return (card->pdat->generation < 2) ? 0xfb : 0xfa;
+       case 5:
+               return 0x60;
+       default:
+               return 0x40;
+       }
+}
diff --git a/drivers/net/can/softing/softing_main.c b/drivers/net/can/softing/softing_main.c
new file mode 100644 (file)
index 0000000..5157e15
--- /dev/null
@@ -0,0 +1,893 @@
+/*
+ * Copyright (C) 2008-2010
+ *
+ * - Kurt Van Dijck, EIA Electronics
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the version 2 of the GNU General Public License
+ * as published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+
+#include "softing.h"
+
+#define TX_ECHO_SKB_MAX (((TXMAX+1)/2)-1)
+
+/*
+ * test is a specific CAN netdev
+ * is online (ie. up 'n running, not sleeping, not busoff
+ */
+static inline int canif_is_active(struct net_device *netdev)
+{
+       struct can_priv *can = netdev_priv(netdev);
+
+       if (!netif_running(netdev))
+               return 0;
+       return (can->state <= CAN_STATE_ERROR_PASSIVE);
+}
+
+/* reset DPRAM */
+static inline void softing_set_reset_dpram(struct softing *card)
+{
+       if (card->pdat->generation >= 2) {
+               spin_lock_bh(&card->spin);
+               iowrite8(ioread8(&card->dpram[DPRAM_V2_RESET]) & ~1,
+                               &card->dpram[DPRAM_V2_RESET]);
+               spin_unlock_bh(&card->spin);
+       }
+}
+
+static inline void softing_clr_reset_dpram(struct softing *card)
+{
+       if (card->pdat->generation >= 2) {
+               spin_lock_bh(&card->spin);
+               iowrite8(ioread8(&card->dpram[DPRAM_V2_RESET]) | 1,
+                               &card->dpram[DPRAM_V2_RESET]);
+               spin_unlock_bh(&card->spin);
+       }
+}
+
+/* trigger the tx queue-ing */
+static netdev_tx_t softing_netdev_start_xmit(struct sk_buff *skb,
+               struct net_device *dev)
+{
+       struct softing_priv *priv = netdev_priv(dev);
+       struct softing *card = priv->card;
+       int ret;
+       uint8_t *ptr;
+       uint8_t fifo_wr, fifo_rd;
+       struct can_frame *cf = (struct can_frame *)skb->data;
+       uint8_t buf[DPRAM_TX_SIZE];
+
+       if (can_dropped_invalid_skb(dev, skb))
+               return NETDEV_TX_OK;
+
+       spin_lock(&card->spin);
+
+       ret = NETDEV_TX_BUSY;
+       if (!card->fw.up ||
+                       (card->tx.pending >= TXMAX) ||
+                       (priv->tx.pending >= TX_ECHO_SKB_MAX))
+               goto xmit_done;
+       fifo_wr = ioread8(&card->dpram[DPRAM_TX_WR]);
+       fifo_rd = ioread8(&card->dpram[DPRAM_TX_RD]);
+       if (fifo_wr == fifo_rd)
+               /* fifo full */
+               goto xmit_done;
+       memset(buf, 0, sizeof(buf));
+       ptr = buf;
+       *ptr = CMD_TX;
+       if (cf->can_id & CAN_RTR_FLAG)
+               *ptr |= CMD_RTR;
+       if (cf->can_id & CAN_EFF_FLAG)
+               *ptr |= CMD_XTD;
+       if (priv->index)
+               *ptr |= CMD_BUS2;
+       ++ptr;
+       *ptr++ = cf->can_dlc;
+       *ptr++ = (cf->can_id >> 0);
+       *ptr++ = (cf->can_id >> 8);
+       if (cf->can_id & CAN_EFF_FLAG) {
+               *ptr++ = (cf->can_id >> 16);
+               *ptr++ = (cf->can_id >> 24);
+       } else {
+               /* increment 1, not 2 as you might think */
+               ptr += 1;
+       }
+       if (!(cf->can_id & CAN_RTR_FLAG))
+               memcpy(ptr, &cf->data[0], cf->can_dlc);
+       memcpy_toio(&card->dpram[DPRAM_TX + DPRAM_TX_SIZE * fifo_wr],
+                       buf, DPRAM_TX_SIZE);
+       if (++fifo_wr >= DPRAM_TX_CNT)
+               fifo_wr = 0;
+       iowrite8(fifo_wr, &card->dpram[DPRAM_TX_WR]);
+       card->tx.last_bus = priv->index;
+       ++card->tx.pending;
+       ++priv->tx.pending;
+       can_put_echo_skb(skb, dev, priv->tx.echo_put);
+       ++priv->tx.echo_put;
+       if (priv->tx.echo_put >= TX_ECHO_SKB_MAX)
+               priv->tx.echo_put = 0;
+       /* can_put_echo_skb() saves the skb, safe to return TX_OK */
+       ret = NETDEV_TX_OK;
+xmit_done:
+       spin_unlock(&card->spin);
+       if (card->tx.pending >= TXMAX) {
+               int j;
+               for (j = 0; j < ARRAY_SIZE(card->net); ++j) {
+                       if (card->net[j])
+                               netif_stop_queue(card->net[j]);
+               }
+       }
+       if (ret != NETDEV_TX_OK)
+               netif_stop_queue(dev);
+
+       return ret;
+}
+
+/*
+ * shortcut for skb delivery
+ */
+int softing_netdev_rx(struct net_device *netdev, const struct can_frame *msg,
+               ktime_t ktime)
+{
+       struct sk_buff *skb;
+       struct can_frame *cf;
+
+       skb = alloc_can_skb(netdev, &cf);
+       if (!skb)
+               return -ENOMEM;
+       memcpy(cf, msg, sizeof(*msg));
+       skb->tstamp = ktime;
+       return netif_rx(skb);
+}
+
+/*
+ * softing_handle_1
+ * pop 1 entry from the DPRAM queue, and process
+ */
+static int softing_handle_1(struct softing *card)
+{
+       struct net_device *netdev;
+       struct softing_priv *priv;
+       ktime_t ktime;
+       struct can_frame msg;
+       int cnt = 0, lost_msg;
+       uint8_t fifo_rd, fifo_wr, cmd;
+       uint8_t *ptr;
+       uint32_t tmp_u32;
+       uint8_t buf[DPRAM_RX_SIZE];
+
+       memset(&msg, 0, sizeof(msg));
+       /* test for lost msgs */
+       lost_msg = ioread8(&card->dpram[DPRAM_RX_LOST]);
+       if (lost_msg) {
+               int j;
+               /* reset condition */
+               iowrite8(0, &card->dpram[DPRAM_RX_LOST]);
+               /* prepare msg */
+               msg.can_id = CAN_ERR_FLAG | CAN_ERR_CRTL;
+               msg.can_dlc = CAN_ERR_DLC;
+               msg.data[1] = CAN_ERR_CRTL_RX_OVERFLOW;
+               /*
+                * service to all busses, we don't know which it was applicable
+                * but only service busses that are online
+                */
+               for (j = 0; j < ARRAY_SIZE(card->net); ++j) {
+                       netdev = card->net[j];
+                       if (!netdev)
+                               continue;
+                       if (!canif_is_active(netdev))
+                               /* a dead bus has no overflows */
+                               continue;
+                       ++netdev->stats.rx_over_errors;
+                       softing_netdev_rx(netdev, &msg, ktime_set(0, 0));
+               }
+               /* prepare for other use */
+               memset(&msg, 0, sizeof(msg));
+               ++cnt;
+       }
+
+       fifo_rd = ioread8(&card->dpram[DPRAM_RX_RD]);
+       fifo_wr = ioread8(&card->dpram[DPRAM_RX_WR]);
+
+       if (++fifo_rd >= DPRAM_RX_CNT)
+               fifo_rd = 0;
+       if (fifo_wr == fifo_rd)
+               return cnt;
+
+       memcpy_fromio(buf, &card->dpram[DPRAM_RX + DPRAM_RX_SIZE*fifo_rd],
+                       DPRAM_RX_SIZE);
+       mb();
+       /* trigger dual port RAM */
+       iowrite8(fifo_rd, &card->dpram[DPRAM_RX_RD]);
+
+       ptr = buf;
+       cmd = *ptr++;
+       if (cmd == 0xff)
+               /* not quite usefull, probably the card has got out */
+               return 0;
+       netdev = card->net[0];
+       if (cmd & CMD_BUS2)
+               netdev = card->net[1];
+       priv = netdev_priv(netdev);
+
+       if (cmd & CMD_ERR) {
+               uint8_t can_state, state;
+
+               state = *ptr++;
+
+               msg.can_id = CAN_ERR_FLAG;
+               msg.can_dlc = CAN_ERR_DLC;
+
+               if (state & SF_MASK_BUSOFF) {
+                       can_state = CAN_STATE_BUS_OFF;
+                       msg.can_id |= CAN_ERR_BUSOFF;
+                       state = STATE_BUSOFF;
+               } else if (state & SF_MASK_EPASSIVE) {
+                       can_state = CAN_STATE_ERROR_PASSIVE;
+                       msg.can_id |= CAN_ERR_CRTL;
+                       msg.data[1] = CAN_ERR_CRTL_TX_PASSIVE;
+                       state = STATE_EPASSIVE;
+               } else {
+                       can_state = CAN_STATE_ERROR_ACTIVE;
+                       msg.can_id |= CAN_ERR_CRTL;
+                       state = STATE_EACTIVE;
+               }
+               /* update DPRAM */
+               iowrite8(state, &card->dpram[priv->index ?
+                               DPRAM_INFO_BUSSTATE2 : DPRAM_INFO_BUSSTATE]);
+               /* timestamp */
+               tmp_u32 = le32_to_cpup((void *)ptr);
+               ptr += 4;
+               ktime = softing_raw2ktime(card, tmp_u32);
+
+               ++netdev->stats.rx_errors;
+               /* update internal status */
+               if (can_state != priv->can.state) {
+                       priv->can.state = can_state;
+                       if (can_state == CAN_STATE_ERROR_PASSIVE)
+                               ++priv->can.can_stats.error_passive;
+                       else if (can_state == CAN_STATE_BUS_OFF) {
+                               /* this calls can_close_cleanup() */
+                               can_bus_off(netdev);
+                               netif_stop_queue(netdev);
+                       }
+                       /* trigger socketcan */
+                       softing_netdev_rx(netdev, &msg, ktime);
+               }
+
+       } else {
+               if (cmd & CMD_RTR)
+                       msg.can_id |= CAN_RTR_FLAG;
+               msg.can_dlc = get_can_dlc(*ptr++);
+               if (cmd & CMD_XTD) {
+                       msg.can_id |= CAN_EFF_FLAG;
+                       msg.can_id |= le32_to_cpup((void *)ptr);
+                       ptr += 4;
+               } else {
+                       msg.can_id |= le16_to_cpup((void *)ptr);
+                       ptr += 2;
+               }
+               /* timestamp */
+               tmp_u32 = le32_to_cpup((void *)ptr);
+               ptr += 4;
+               ktime = softing_raw2ktime(card, tmp_u32);
+               if (!(msg.can_id & CAN_RTR_FLAG))
+                       memcpy(&msg.data[0], ptr, 8);
+               ptr += 8;
+               /* update socket */
+               if (cmd & CMD_ACK) {
+                       /* acknowledge, was tx msg */
+                       struct sk_buff *skb;
+                       skb = priv->can.echo_skb[priv->tx.echo_get];
+                       if (skb)
+                               skb->tstamp = ktime;
+                       can_get_echo_skb(netdev, priv->tx.echo_get);
+                       ++priv->tx.echo_get;
+                       if (priv->tx.echo_get >= TX_ECHO_SKB_MAX)
+                               priv->tx.echo_get = 0;
+                       if (priv->tx.pending)
+                               --priv->tx.pending;
+                       if (card->tx.pending)
+                               --card->tx.pending;
+                       ++netdev->stats.tx_packets;
+                       if (!(msg.can_id & CAN_RTR_FLAG))
+                               netdev->stats.tx_bytes += msg.can_dlc;
+               } else {
+                       int ret;
+
+                       ret = softing_netdev_rx(netdev, &msg, ktime);
+                       if (ret == NET_RX_SUCCESS) {
+                               ++netdev->stats.rx_packets;
+                               if (!(msg.can_id & CAN_RTR_FLAG))
+                                       netdev->stats.rx_bytes += msg.can_dlc;
+                       } else {
+                               ++netdev->stats.rx_dropped;
+                       }
+               }
+       }
+       ++cnt;
+       return cnt;
+}
+
+/*
+ * real interrupt handler
+ */
+static irqreturn_t softing_irq_thread(int irq, void *dev_id)
+{
+       struct softing *card = (struct softing *)dev_id;
+       struct net_device *netdev;
+       struct softing_priv *priv;
+       int j, offset, work_done;
+
+       work_done = 0;
+       spin_lock_bh(&card->spin);
+       while (softing_handle_1(card) > 0) {
+               ++card->irq.svc_count;
+               ++work_done;
+       }
+       spin_unlock_bh(&card->spin);
+       /* resume tx queue's */
+       offset = card->tx.last_bus;
+       for (j = 0; j < ARRAY_SIZE(card->net); ++j) {
+               if (card->tx.pending >= TXMAX)
+                       break;
+               netdev = card->net[(j + offset + 1) % card->pdat->nbus];
+               if (!netdev)
+                       continue;
+               priv = netdev_priv(netdev);
+               if (!canif_is_active(netdev))
+                       /* it makes no sense to wake dead busses */
+                       continue;
+               if (priv->tx.pending >= TX_ECHO_SKB_MAX)
+                       continue;
+               ++work_done;
+               netif_wake_queue(netdev);
+       }
+       return work_done ? IRQ_HANDLED : IRQ_NONE;
+}
+
+/*
+ * interrupt routines:
+ * schedule the 'real interrupt handler'
+ */
+static irqreturn_t softing_irq_v2(int irq, void *dev_id)
+{
+       struct softing *card = (struct softing *)dev_id;
+       uint8_t ir;
+
+       ir = ioread8(&card->dpram[DPRAM_V2_IRQ_TOHOST]);
+       iowrite8(0, &card->dpram[DPRAM_V2_IRQ_TOHOST]);
+       return (1 == ir) ? IRQ_WAKE_THREAD : IRQ_NONE;
+}
+
+static irqreturn_t softing_irq_v1(int irq, void *dev_id)
+{
+       struct softing *card = (struct softing *)dev_id;
+       uint8_t ir;
+
+       ir = ioread8(&card->dpram[DPRAM_IRQ_TOHOST]);
+       iowrite8(0, &card->dpram[DPRAM_IRQ_TOHOST]);
+       return ir ? IRQ_WAKE_THREAD : IRQ_NONE;
+}
+
+/*
+ * netdev/candev inter-operability
+ */
+static int softing_netdev_open(struct net_device *ndev)
+{
+       int ret;
+
+       /* check or determine and set bittime */
+       ret = open_candev(ndev);
+       if (!ret)
+               ret = softing_startstop(ndev, 1);
+       return ret;
+}
+
+static int softing_netdev_stop(struct net_device *ndev)
+{
+       int ret;
+
+       netif_stop_queue(ndev);
+
+       /* softing cycle does close_candev() */
+       ret = softing_startstop(ndev, 0);
+       return ret;
+}
+
+static int softing_candev_set_mode(struct net_device *ndev, enum can_mode mode)
+{
+       int ret;
+
+       switch (mode) {
+       case CAN_MODE_START:
+               /* softing_startstop does close_candev() */
+               ret = softing_startstop(ndev, 1);
+               return ret;
+       case CAN_MODE_STOP:
+       case CAN_MODE_SLEEP:
+               return -EOPNOTSUPP;
+       }
+       return 0;
+}
+
+/*
+ * Softing device management helpers
+ */
+int softing_enable_irq(struct softing *card, int enable)
+{
+       int ret;
+
+       if (!card->irq.nr) {
+               return 0;
+       } else if (card->irq.requested && !enable) {
+               free_irq(card->irq.nr, card);
+               card->irq.requested = 0;
+       } else if (!card->irq.requested && enable) {
+               ret = request_threaded_irq(card->irq.nr,
+                               (card->pdat->generation >= 2) ?
+                                       softing_irq_v2 : softing_irq_v1,
+                               softing_irq_thread, IRQF_SHARED,
+                               dev_name(&card->pdev->dev), card);
+               if (ret) {
+                       dev_alert(&card->pdev->dev,
+                                       "request_threaded_irq(%u) failed\n",
+                                       card->irq.nr);
+                       return ret;
+               }
+               card->irq.requested = 1;
+       }
+       return 0;
+}
+
+static void softing_card_shutdown(struct softing *card)
+{
+       int fw_up = 0;
+
+       if (mutex_lock_interruptible(&card->fw.lock))
+               /* return -ERESTARTSYS */;
+       fw_up = card->fw.up;
+       card->fw.up = 0;
+
+       if (card->irq.requested && card->irq.nr) {
+               free_irq(card->irq.nr, card);
+               card->irq.requested = 0;
+       }
+       if (fw_up) {
+               if (card->pdat->enable_irq)
+                       card->pdat->enable_irq(card->pdev, 0);
+               softing_set_reset_dpram(card);
+               if (card->pdat->reset)
+                       card->pdat->reset(card->pdev, 1);
+       }
+       mutex_unlock(&card->fw.lock);
+}
+
+static __devinit int softing_card_boot(struct softing *card)
+{
+       int ret, j;
+       static const uint8_t stream[] = {
+               0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, };
+       unsigned char back[sizeof(stream)];
+
+       if (mutex_lock_interruptible(&card->fw.lock))
+               return -ERESTARTSYS;
+       if (card->fw.up) {
+               mutex_unlock(&card->fw.lock);
+               return 0;
+       }
+       /* reset board */
+       if (card->pdat->enable_irq)
+               card->pdat->enable_irq(card->pdev, 1);
+       /* boot card */
+       softing_set_reset_dpram(card);
+       if (card->pdat->reset)
+               card->pdat->reset(card->pdev, 1);
+       for (j = 0; (j + sizeof(stream)) < card->dpram_size;
+                       j += sizeof(stream)) {
+
+               memcpy_toio(&card->dpram[j], stream, sizeof(stream));
+               /* flush IO cache */
+               mb();
+               memcpy_fromio(back, &card->dpram[j], sizeof(stream));
+
+               if (!memcmp(back, stream, sizeof(stream)))
+                       continue;
+               /* memory is not equal */
+               dev_alert(&card->pdev->dev, "dpram failed at 0x%04x\n", j);
+               ret = -EIO;
+               goto failed;
+       }
+       wmb();
+       /* load boot firmware */
+       ret = softing_load_fw(card->pdat->boot.fw, card, card->dpram,
+                               card->dpram_size,
+                               card->pdat->boot.offs - card->pdat->boot.addr);
+       if (ret < 0)
+               goto failed;
+       /* load loader firmware */
+       ret = softing_load_fw(card->pdat->load.fw, card, card->dpram,
+                               card->dpram_size,
+                               card->pdat->load.offs - card->pdat->load.addr);
+       if (ret < 0)
+               goto failed;
+
+       if (card->pdat->reset)
+               card->pdat->reset(card->pdev, 0);
+       softing_clr_reset_dpram(card);
+       ret = softing_bootloader_command(card, 0, "card boot");
+       if (ret < 0)
+               goto failed;
+       ret = softing_load_app_fw(card->pdat->app.fw, card);
+       if (ret < 0)
+               goto failed;
+
+       ret = softing_chip_poweron(card);
+       if (ret < 0)
+               goto failed;
+
+       card->fw.up = 1;
+       mutex_unlock(&card->fw.lock);
+       return 0;
+failed:
+       card->fw.up = 0;
+       if (card->pdat->enable_irq)
+               card->pdat->enable_irq(card->pdev, 0);
+       softing_set_reset_dpram(card);
+       if (card->pdat->reset)
+               card->pdat->reset(card->pdev, 1);
+       mutex_unlock(&card->fw.lock);
+       return ret;
+}
+
+/*
+ * netdev sysfs
+ */
+static ssize_t show_channel(struct device *dev, struct device_attribute *attr,
+               char *buf)
+{
+       struct net_device *ndev = to_net_dev(dev);
+       struct softing_priv *priv = netdev2softing(ndev);
+
+       return sprintf(buf, "%i\n", priv->index);
+}
+
+static ssize_t show_chip(struct device *dev, struct device_attribute *attr,
+               char *buf)
+{
+       struct net_device *ndev = to_net_dev(dev);
+       struct softing_priv *priv = netdev2softing(ndev);
+
+       return sprintf(buf, "%i\n", priv->chip);
+}
+
+static ssize_t show_output(struct device *dev, struct device_attribute *attr,
+               char *buf)
+{
+       struct net_device *ndev = to_net_dev(dev);
+       struct softing_priv *priv = netdev2softing(ndev);
+
+       return sprintf(buf, "0x%02x\n", priv->output);
+}
+
+static ssize_t store_output(struct device *dev, struct device_attribute *attr,
+               const char *buf, size_t count)
+{
+       struct net_device *ndev = to_net_dev(dev);
+       struct softing_priv *priv = netdev2softing(ndev);
+       struct softing *card = priv->card;
+       unsigned long val;
+       int ret;
+
+       ret = strict_strtoul(buf, 0, &val);
+       if (ret < 0)
+               return ret;
+       val &= 0xFF;
+
+       ret = mutex_lock_interruptible(&card->fw.lock);
+       if (ret)
+               return -ERESTARTSYS;
+       if (netif_running(ndev)) {
+               mutex_unlock(&card->fw.lock);
+               return -EBUSY;
+       }
+       priv->output = val;
+       mutex_unlock(&card->fw.lock);
+       return count;
+}
+
+static const DEVICE_ATTR(channel, S_IRUGO, show_channel, NULL);
+static const DEVICE_ATTR(chip, S_IRUGO, show_chip, NULL);
+static const DEVICE_ATTR(output, S_IRUGO | S_IWUSR, show_output, store_output);
+
+static const struct attribute *const netdev_sysfs_attrs[] = {
+       &dev_attr_channel.attr,
+       &dev_attr_chip.attr,
+       &dev_attr_output.attr,
+       NULL,
+};
+static const struct attribute_group netdev_sysfs_group = {
+       .name = NULL,
+       .attrs = (struct attribute **)netdev_sysfs_attrs,
+};
+
+static const struct net_device_ops softing_netdev_ops = {
+       .ndo_open = softing_netdev_open,
+       .ndo_stop = softing_netdev_stop,
+       .ndo_start_xmit = softing_netdev_start_xmit,
+};
+
+static const struct can_bittiming_const softing_btr_const = {
+       .tseg1_min = 1,
+       .tseg1_max = 16,
+       .tseg2_min = 1,
+       .tseg2_max = 8,
+       .sjw_max = 4, /* overruled */
+       .brp_min = 1,
+       .brp_max = 32, /* overruled */
+       .brp_inc = 1,
+};
+
+
+static __devinit struct net_device *softing_netdev_create(struct softing *card,
+               uint16_t chip_id)
+{
+       struct net_device *netdev;
+       struct softing_priv *priv;
+
+       netdev = alloc_candev(sizeof(*priv), TX_ECHO_SKB_MAX);
+       if (!netdev) {
+               dev_alert(&card->pdev->dev, "alloc_candev failed\n");
+               return NULL;
+       }
+       priv = netdev_priv(netdev);
+       priv->netdev = netdev;
+       priv->card = card;
+       memcpy(&priv->btr_const, &softing_btr_const, sizeof(priv->btr_const));
+       priv->btr_const.brp_max = card->pdat->max_brp;
+       priv->btr_const.sjw_max = card->pdat->max_sjw;
+       priv->can.bittiming_const = &priv->btr_const;
+       priv->can.clock.freq = 8000000;
+       priv->chip = chip_id;
+       priv->output = softing_default_output(netdev);
+       SET_NETDEV_DEV(netdev, &card->pdev->dev);
+
+       netdev->flags |= IFF_ECHO;
+       netdev->netdev_ops = &softing_netdev_ops;
+       priv->can.do_set_mode = softing_candev_set_mode;
+       priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES;
+
+       return netdev;
+}
+
+static __devinit int softing_netdev_register(struct net_device *netdev)
+{
+       int ret;
+
+       netdev->sysfs_groups[0] = &netdev_sysfs_group;
+       ret = register_candev(netdev);
+       if (ret) {
+               dev_alert(&netdev->dev, "register failed\n");
+               return ret;
+       }
+       return 0;
+}
+
+static void softing_netdev_cleanup(struct net_device *netdev)
+{
+       unregister_candev(netdev);
+       free_candev(netdev);
+}
+
+/*
+ * sysfs for Platform device
+ */
+#define DEV_ATTR_RO(name, member) \
+static ssize_t show_##name(struct device *dev, \
+               struct device_attribute *attr, char *buf) \
+{ \
+       struct softing *card = platform_get_drvdata(to_platform_device(dev)); \
+       return sprintf(buf, "%u\n", card->member); \
+} \
+static DEVICE_ATTR(name, 0444, show_##name, NULL)
+
+#define DEV_ATTR_RO_STR(name, member) \
+static ssize_t show_##name(struct device *dev, \
+               struct device_attribute *attr, char *buf) \
+{ \
+       struct softing *card = platform_get_drvdata(to_platform_device(dev)); \
+       return sprintf(buf, "%s\n", card->member); \
+} \
+static DEVICE_ATTR(name, 0444, show_##name, NULL)
+
+DEV_ATTR_RO(serial, id.serial);
+DEV_ATTR_RO_STR(firmware, pdat->app.fw);
+DEV_ATTR_RO(firmware_version, id.fw_version);
+DEV_ATTR_RO_STR(hardware, pdat->name);
+DEV_ATTR_RO(hardware_version, id.hw_version);
+DEV_ATTR_RO(license, id.license);
+DEV_ATTR_RO(frequency, id.freq);
+DEV_ATTR_RO(txpending, tx.pending);
+
+static struct attribute *softing_pdev_attrs[] = {
+       &dev_attr_serial.attr,
+       &dev_attr_firmware.attr,
+       &dev_attr_firmware_version.attr,
+       &dev_attr_hardware.attr,
+       &dev_attr_hardware_version.attr,
+       &dev_attr_license.attr,
+       &dev_attr_frequency.attr,
+       &dev_attr_txpending.attr,
+       NULL,
+};
+
+static const struct attribute_group softing_pdev_group = {
+       .name = NULL,
+       .attrs = softing_pdev_attrs,
+};
+
+/*
+ * platform driver
+ */
+static __devexit int softing_pdev_remove(struct platform_device *pdev)
+{
+       struct softing *card = platform_get_drvdata(pdev);
+       int j;
+
+       /* first, disable card*/
+       softing_card_shutdown(card);
+
+       for (j = 0; j < ARRAY_SIZE(card->net); ++j) {
+               if (!card->net[j])
+                       continue;
+               softing_netdev_cleanup(card->net[j]);
+               card->net[j] = NULL;
+       }
+       sysfs_remove_group(&pdev->dev.kobj, &softing_pdev_group);
+
+       iounmap(card->dpram);
+       kfree(card);
+       return 0;
+}
+
+static __devinit int softing_pdev_probe(struct platform_device *pdev)
+{
+       const struct softing_platform_data *pdat = pdev->dev.platform_data;
+       struct softing *card;
+       struct net_device *netdev;
+       struct softing_priv *priv;
+       struct resource *pres;
+       int ret;
+       int j;
+
+       if (!pdat) {
+               dev_warn(&pdev->dev, "no platform data\n");
+               return -EINVAL;
+       }
+       if (pdat->nbus > ARRAY_SIZE(card->net)) {
+               dev_warn(&pdev->dev, "%u nets??\n", pdat->nbus);
+               return -EINVAL;
+       }
+
+       card = kzalloc(sizeof(*card), GFP_KERNEL);
+       if (!card)
+               return -ENOMEM;
+       card->pdat = pdat;
+       card->pdev = pdev;
+       platform_set_drvdata(pdev, card);
+       mutex_init(&card->fw.lock);
+       spin_lock_init(&card->spin);
+
+       ret = -EINVAL;
+       pres = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!pres)
+               goto platform_resource_failed;;
+       card->dpram_phys = pres->start;
+       card->dpram_size = pres->end - pres->start + 1;
+       card->dpram = ioremap_nocache(card->dpram_phys, card->dpram_size);
+       if (!card->dpram) {
+               dev_alert(&card->pdev->dev, "dpram ioremap failed\n");
+               goto ioremap_failed;
+       }
+
+       pres = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+       if (pres)
+               card->irq.nr = pres->start;
+
+       /* reset card */
+       ret = softing_card_boot(card);
+       if (ret < 0) {
+               dev_alert(&pdev->dev, "failed to boot\n");
+               goto boot_failed;
+       }
+
+       /* only now, the chip's are known */
+       card->id.freq = card->pdat->freq;
+
+       ret = sysfs_create_group(&pdev->dev.kobj, &softing_pdev_group);
+       if (ret < 0) {
+               dev_alert(&card->pdev->dev, "sysfs failed\n");
+               goto sysfs_failed;
+       }
+
+       ret = -ENOMEM;
+       for (j = 0; j < ARRAY_SIZE(card->net); ++j) {
+               card->net[j] = netdev =
+                       softing_netdev_create(card, card->id.chip[j]);
+               if (!netdev) {
+                       dev_alert(&pdev->dev, "failed to make can[%i]", j);
+                       goto netdev_failed;
+               }
+               priv = netdev_priv(card->net[j]);
+               priv->index = j;
+               ret = softing_netdev_register(netdev);
+               if (ret) {
+                       free_candev(netdev);
+                       card->net[j] = NULL;
+                       dev_alert(&card->pdev->dev,
+                                       "failed to register can[%i]\n", j);
+                       goto netdev_failed;
+               }
+       }
+       dev_info(&card->pdev->dev, "%s ready.\n", card->pdat->name);
+       return 0;
+
+netdev_failed:
+       for (j = 0; j < ARRAY_SIZE(card->net); ++j) {
+               if (!card->net[j])
+                       continue;
+               softing_netdev_cleanup(card->net[j]);
+       }
+       sysfs_remove_group(&pdev->dev.kobj, &softing_pdev_group);
+sysfs_failed:
+       softing_card_shutdown(card);
+boot_failed:
+       iounmap(card->dpram);
+ioremap_failed:
+platform_resource_failed:
+       kfree(card);
+       return ret;
+}
+
+static struct platform_driver softing_driver = {
+       .driver = {
+               .name = "softing",
+               .owner = THIS_MODULE,
+       },
+       .probe = softing_pdev_probe,
+       .remove = __devexit_p(softing_pdev_remove),
+};
+
+MODULE_ALIAS("platform:softing");
+
+static int __init softing_start(void)
+{
+       return platform_driver_register(&softing_driver);
+}
+
+static void __exit softing_stop(void)
+{
+       platform_driver_unregister(&softing_driver);
+}
+
+module_init(softing_start);
+module_exit(softing_stop);
+
+MODULE_DESCRIPTION("Softing DPRAM CAN driver");
+MODULE_AUTHOR("Kurt Van Dijck <kurt.van.dijck@eia.be>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/net/can/softing/softing_platform.h b/drivers/net/can/softing/softing_platform.h
new file mode 100644 (file)
index 0000000..ebbf698
--- /dev/null
@@ -0,0 +1,40 @@
+
+#include <linux/platform_device.h>
+
+#ifndef _SOFTING_DEVICE_H_
+#define _SOFTING_DEVICE_H_
+
+/* softing firmware directory prefix */
+#define fw_dir "softing-4.6/"
+
+struct softing_platform_data {
+       unsigned int manf;
+       unsigned int prod;
+       /*
+        * generation
+        * 1st with NEC or SJA1000
+        * 8bit, exclusive interrupt, ...
+        * 2nd only SJA1000
+        * 16bit, shared interrupt
+        */
+       int generation;
+       int nbus; /* # busses on device */
+       unsigned int freq; /* operating frequency in Hz */
+       unsigned int max_brp;
+       unsigned int max_sjw;
+       unsigned long dpram_size;
+       const char *name;
+       struct {
+               unsigned long offs;
+               unsigned long addr;
+               const char *fw;
+       } boot, load, app;
+       /*
+        * reset() function
+        * bring pdev in or out of reset, depending on value
+        */
+       int (*reset)(struct platform_device *pdev, int value);
+       int (*enable_irq)(struct platform_device *pdev, int value);
+};
+
+#endif
index 263a2944566f6948f759f029a875d6f4eb01e3ce..7ff170cbc7dcfa7ec73b8ffe055289aaba8093b9 100644 (file)
@@ -699,13 +699,13 @@ static void cnic_free_dma(struct cnic_dev *dev, struct cnic_dma *dma)
 static void cnic_setup_page_tbl(struct cnic_dev *dev, struct cnic_dma *dma)
 {
        int i;
-       u32 *page_table = dma->pgtbl;
+       __le32 *page_table = (__le32 *) dma->pgtbl;
 
        for (i = 0; i < dma->num_pages; i++) {
                /* Each entry needs to be in big endian format. */
-               *page_table = (u32) ((u64) dma->pg_map_arr[i] >> 32);
+               *page_table = cpu_to_le32((u64) dma->pg_map_arr[i] >> 32);
                page_table++;
-               *page_table = (u32) dma->pg_map_arr[i];
+               *page_table = cpu_to_le32(dma->pg_map_arr[i] & 0xffffffff);
                page_table++;
        }
 }
@@ -713,13 +713,13 @@ static void cnic_setup_page_tbl(struct cnic_dev *dev, struct cnic_dma *dma)
 static void cnic_setup_page_tbl_le(struct cnic_dev *dev, struct cnic_dma *dma)
 {
        int i;
-       u32 *page_table = dma->pgtbl;
+       __le32 *page_table = (__le32 *) dma->pgtbl;
 
        for (i = 0; i < dma->num_pages; i++) {
                /* Each entry needs to be in little endian format. */
-               *page_table = dma->pg_map_arr[i] & 0xffffffff;
+               *page_table = cpu_to_le32(dma->pg_map_arr[i] & 0xffffffff);
                page_table++;
-               *page_table = (u32) ((u64) dma->pg_map_arr[i] >> 32);
+               *page_table = cpu_to_le32((u64) dma->pg_map_arr[i] >> 32);
                page_table++;
        }
 }
index 059c1eec8c3ff79b23d7ea8e9a17c111c8c57429..ec35d458102c797ea7f19cf6fcacb9bff88aa408 100644 (file)
@@ -2710,6 +2710,8 @@ static int cxgb_open(struct net_device *dev)
        struct port_info *pi = netdev_priv(dev);
        struct adapter *adapter = pi->adapter;
 
+       netif_carrier_off(dev);
+
        if (!(adapter->flags & FULL_INIT_DONE)) {
                err = cxgb_up(adapter);
                if (err < 0)
@@ -3661,7 +3663,6 @@ static int __devinit init_one(struct pci_dev *pdev,
                pi->xact_addr_filt = -1;
                pi->rx_offload = RX_CSO;
                pi->port_id = i;
-               netif_carrier_off(netdev);
                netdev->irq = pdev->irq;
 
                netdev->features |= NETIF_F_SG | TSO_FLAGS;
index d7355306a738fbbe78b7848423ea203a6fd5c444..1bf12339441bb5887a4cfaf2c81abea647a41923 100644 (file)
@@ -2247,7 +2247,7 @@ static void pch_gbe_remove(struct pci_dev *pdev)
        struct net_device *netdev = pci_get_drvdata(pdev);
        struct pch_gbe_adapter *adapter = netdev_priv(netdev);
 
-       flush_scheduled_work();
+       cancel_work_sync(&adapter->reset_task);
        unregister_netdev(netdev);
 
        pch_gbe_hal_phy_hw_reset(&adapter->hw);
index 7841a8f69998d5351bad0745350edcfa65972208..93b32d3666111c55179f66e9760bb838c1fc103d 100644 (file)
 #define BAR_0  0
 #define BAR_2  2
 
-#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
-#define TG3_VLAN_TAG_USED 1
-#else
-#define TG3_VLAN_TAG_USED 0
-#endif
-
 #include "tg3.h"
 
 #define DRV_MODULE_NAME                "tg3"
                                 TG3_TX_RING_SIZE)
 #define NEXT_TX(N)             (((N) + 1) & (TG3_TX_RING_SIZE - 1))
 
-#define TG3_RX_DMA_ALIGN               16
-#define TG3_RX_HEADROOM                        ALIGN(VLAN_HLEN, TG3_RX_DMA_ALIGN)
-
 #define TG3_DMA_BYTE_ENAB              64
 
 #define TG3_RX_STD_DMA_SZ              1536
@@ -4722,8 +4713,6 @@ static int tg3_rx(struct tg3_napi *tnapi, int budget)
                struct sk_buff *skb;
                dma_addr_t dma_addr;
                u32 opaque_key, desc_idx, *post_ptr;
-               bool hw_vlan __maybe_unused = false;
-               u16 vtag __maybe_unused = 0;
 
                desc_idx = desc->opaque & RXD_OPAQUE_INDEX_MASK;
                opaque_key = desc->opaque & RXD_OPAQUE_RING_MASK;
@@ -4782,12 +4771,12 @@ static int tg3_rx(struct tg3_napi *tnapi, int budget)
                        tg3_recycle_rx(tnapi, tpr, opaque_key,
                                       desc_idx, *post_ptr);
 
-                       copy_skb = netdev_alloc_skb(tp->dev, len + VLAN_HLEN +
+                       copy_skb = netdev_alloc_skb(tp->dev, len +
                                                    TG3_RAW_IP_ALIGN);
                        if (copy_skb == NULL)
                                goto drop_it_no_recycle;
 
-                       skb_reserve(copy_skb, TG3_RAW_IP_ALIGN + VLAN_HLEN);
+                       skb_reserve(copy_skb, TG3_RAW_IP_ALIGN);
                        skb_put(copy_skb, len);
                        pci_dma_sync_single_for_cpu(tp->pdev, dma_addr, len, PCI_DMA_FROMDEVICE);
                        skb_copy_from_linear_data(skb, copy_skb->data, len);
@@ -4814,30 +4803,11 @@ static int tg3_rx(struct tg3_napi *tnapi, int budget)
                }
 
                if (desc->type_flags & RXD_FLAG_VLAN &&
-                   !(tp->rx_mode & RX_MODE_KEEP_VLAN_TAG)) {
-                       vtag = desc->err_vlan & RXD_VLAN_MASK;
-#if TG3_VLAN_TAG_USED
-                       if (tp->vlgrp)
-                               hw_vlan = true;
-                       else
-#endif
-                       {
-                               struct vlan_ethhdr *ve = (struct vlan_ethhdr *)
-                                                   __skb_push(skb, VLAN_HLEN);
-
-                               memmove(ve, skb->data + VLAN_HLEN,
-                                       ETH_ALEN * 2);
-                               ve->h_vlan_proto = htons(ETH_P_8021Q);
-                               ve->h_vlan_TCI = htons(vtag);
-                       }
-               }
+                   !(tp->rx_mode & RX_MODE_KEEP_VLAN_TAG))
+                       __vlan_hwaccel_put_tag(skb,
+                                              desc->err_vlan & RXD_VLAN_MASK);
 
-#if TG3_VLAN_TAG_USED
-               if (hw_vlan)
-                       vlan_gro_receive(&tnapi->napi, tp->vlgrp, vtag, skb);
-               else
-#endif
-                       napi_gro_receive(&tnapi->napi, skb);
+               napi_gro_receive(&tnapi->napi, skb);
 
                received++;
                budget--;
@@ -5740,11 +5710,9 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb,
                base_flags |= TXD_FLAG_TCPUDP_CSUM;
        }
 
-#if TG3_VLAN_TAG_USED
        if (vlan_tx_tag_present(skb))
                base_flags |= (TXD_FLAG_VLAN |
                               (vlan_tx_tag_get(skb) << 16));
-#endif
 
        len = skb_headlen(skb);
 
@@ -5986,11 +5954,10 @@ static netdev_tx_t tg3_start_xmit_dma_bug(struct sk_buff *skb,
                        }
                }
        }
-#if TG3_VLAN_TAG_USED
+
        if (vlan_tx_tag_present(skb))
                base_flags |= (TXD_FLAG_VLAN |
                               (vlan_tx_tag_get(skb) << 16));
-#endif
 
        if ((tp->tg3_flags3 & TG3_FLG3_USE_JUMBO_BDFLAG) &&
            !mss && skb->len > VLAN_ETH_FRAME_LEN)
@@ -9532,17 +9499,10 @@ static void __tg3_set_rx_mode(struct net_device *dev)
        rx_mode = tp->rx_mode & ~(RX_MODE_PROMISC |
                                  RX_MODE_KEEP_VLAN_TAG);
 
+#if !defined(CONFIG_VLAN_8021Q) && !defined(CONFIG_VLAN_8021Q_MODULE)
        /* When ASF is in use, we always keep the RX_MODE_KEEP_VLAN_TAG
         * flag clear.
         */
-#if TG3_VLAN_TAG_USED
-       if (!tp->vlgrp &&
-           !(tp->tg3_flags & TG3_FLAG_ENABLE_ASF))
-               rx_mode |= RX_MODE_KEEP_VLAN_TAG;
-#else
-       /* By definition, VLAN is disabled always in this
-        * case.
-        */
        if (!(tp->tg3_flags & TG3_FLAG_ENABLE_ASF))
                rx_mode |= RX_MODE_KEEP_VLAN_TAG;
 #endif
@@ -11230,31 +11190,6 @@ static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
        return -EOPNOTSUPP;
 }
 
-#if TG3_VLAN_TAG_USED
-static void tg3_vlan_rx_register(struct net_device *dev, struct vlan_group *grp)
-{
-       struct tg3 *tp = netdev_priv(dev);
-
-       if (!netif_running(dev)) {
-               tp->vlgrp = grp;
-               return;
-       }
-
-       tg3_netif_stop(tp);
-
-       tg3_full_lock(tp, 0);
-
-       tp->vlgrp = grp;
-
-       /* Update RX_MODE_KEEP_VLAN_TAG bit in RX_MODE register. */
-       __tg3_set_rx_mode(dev);
-
-       tg3_netif_start(tp);
-
-       tg3_full_unlock(tp);
-}
-#endif
-
 static int tg3_get_coalesce(struct net_device *dev, struct ethtool_coalesce *ec)
 {
        struct tg3 *tp = netdev_priv(dev);
@@ -13066,9 +13001,7 @@ static struct pci_dev * __devinit tg3_find_peer(struct tg3 *);
 
 static void inline vlan_features_add(struct net_device *dev, unsigned long flags)
 {
-#if TG3_VLAN_TAG_USED
        dev->vlan_features |= flags;
-#endif
 }
 
 static inline u32 tg3_rx_ret_ring_size(struct tg3 *tp)
@@ -13861,11 +13794,11 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
        else
                tp->tg3_flags &= ~TG3_FLAG_POLL_SERDES;
 
-       tp->rx_offset = NET_IP_ALIGN + TG3_RX_HEADROOM;
+       tp->rx_offset = NET_IP_ALIGN;
        tp->rx_copy_thresh = TG3_RX_COPY_THRESHOLD;
        if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701 &&
            (tp->tg3_flags & TG3_FLAG_PCIX_MODE) != 0) {
-               tp->rx_offset -= NET_IP_ALIGN;
+               tp->rx_offset = 0;
 #ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
                tp->rx_copy_thresh = ~(u16)0;
 #endif
@@ -14629,9 +14562,6 @@ static const struct net_device_ops tg3_netdev_ops = {
        .ndo_do_ioctl           = tg3_ioctl,
        .ndo_tx_timeout         = tg3_tx_timeout,
        .ndo_change_mtu         = tg3_change_mtu,
-#if TG3_VLAN_TAG_USED
-       .ndo_vlan_rx_register   = tg3_vlan_rx_register,
-#endif
 #ifdef CONFIG_NET_POLL_CONTROLLER
        .ndo_poll_controller    = tg3_poll_controller,
 #endif
@@ -14648,9 +14578,6 @@ static const struct net_device_ops tg3_netdev_ops_dma_bug = {
        .ndo_do_ioctl           = tg3_ioctl,
        .ndo_tx_timeout         = tg3_tx_timeout,
        .ndo_change_mtu         = tg3_change_mtu,
-#if TG3_VLAN_TAG_USED
-       .ndo_vlan_rx_register   = tg3_vlan_rx_register,
-#endif
 #ifdef CONFIG_NET_POLL_CONTROLLER
        .ndo_poll_controller    = tg3_poll_controller,
 #endif
@@ -14700,9 +14627,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
 
        SET_NETDEV_DEV(dev, &pdev->dev);
 
-#if TG3_VLAN_TAG_USED
        dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
-#endif
 
        tp = netdev_priv(dev);
        tp->pdev = pdev;
index d62c8d937c820cf3a124a2250a351156b49a84c6..f528243e1a4fd73fc289d65ed63f24124aa79c5f 100644 (file)
@@ -2808,9 +2808,6 @@ struct tg3 {
        u32                             rx_std_max_post;
        u32                             rx_offset;
        u32                             rx_pkt_map_sz;
-#if TG3_VLAN_TAG_USED
-       struct vlan_group               *vlgrp;
-#endif
 
 
        /* begin "everything else" cacheline(s) section */
index 5e98643a4a214b2734d738cc7a24b55ef0225298..7dc84971f26f8720f8aea9384e33a669d1b825b7 100644 (file)
@@ -406,6 +406,7 @@ static int kaweth_download_firmware(struct kaweth_device *kaweth,
 
        if (fw->size > KAWETH_FIRMWARE_BUF_SIZE) {
                err("Firmware too big: %zu", fw->size);
+               release_firmware(fw);
                return -ENOSPC;
        }
        data_len = fw->size;
index 1afb8bb85756ee55e5a2a82d5f1f825279c803ea..9f01e50d5cda718e391f9582f71064f82c5f8733 100644 (file)
@@ -369,6 +369,9 @@ static void ath9k_hw_init_config(struct ath_hw *ah)
        else
                ah->config.ht_enable = 0;
 
+       /* PAPRD needs some more work to be enabled */
+       ah->config.paprd_disable = 1;
+
        ah->config.rx_intr_mitigation = true;
        ah->config.pcieSerDesWrite = true;
 
@@ -1933,7 +1936,8 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
                pCap->rx_status_len = sizeof(struct ar9003_rxs);
                pCap->tx_desc_len = sizeof(struct ar9003_txc);
                pCap->txs_len = sizeof(struct ar9003_txs);
-               if (ah->eep_ops->get_eeprom(ah, EEP_PAPRD))
+               if (!ah->config.paprd_disable &&
+                   ah->eep_ops->get_eeprom(ah, EEP_PAPRD))
                        pCap->hw_caps |= ATH9K_HW_CAP_PAPRD;
        } else {
                pCap->tx_desc_len = sizeof(struct ath_desc);
index 5a3dfec45e96004d02c84a33cbb39ff9aa201d45..ea9fde6706461cb12560b53018ef101a87be5481 100644 (file)
@@ -225,6 +225,7 @@ struct ath9k_ops_config {
        u32 pcie_waen;
        u8 analog_shiftreg;
        u8 ht_enable;
+       u8 paprd_disable;
        u32 ofdm_trig_low;
        u32 ofdm_trig_high;
        u32 cck_trig_high;
index f90a6ca94a7682705d0180bd74119873d6fc2416..c79c97be6cd4417afd8a2cf2ff0776c11856f17b 100644 (file)
@@ -592,14 +592,12 @@ void ath9k_tasklet(unsigned long data)
        u32 status = sc->intrstatus;
        u32 rxmask;
 
-       ath9k_ps_wakeup(sc);
-
        if (status & ATH9K_INT_FATAL) {
                ath_reset(sc, true);
-               ath9k_ps_restore(sc);
                return;
        }
 
+       ath9k_ps_wakeup(sc);
        spin_lock(&sc->sc_pcu_lock);
 
        if (!ath9k_hw_check_alive(ah))
@@ -969,6 +967,7 @@ int ath_reset(struct ath_softc *sc, bool retry_tx)
        /* Stop ANI */
        del_timer_sync(&common->ani.timer);
 
+       ath9k_ps_wakeup(sc);
        spin_lock_bh(&sc->sc_pcu_lock);
 
        ieee80211_stop_queues(hw);
@@ -1015,6 +1014,7 @@ int ath_reset(struct ath_softc *sc, bool retry_tx)
 
        /* Start ANI */
        ath_start_ani(common);
+       ath9k_ps_restore(sc);
 
        return r;
 }
@@ -1701,7 +1701,9 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
 skip_chan_change:
        if (changed & IEEE80211_CONF_CHANGE_POWER) {
                sc->config.txpowlimit = 2 * conf->power_level;
+               ath9k_ps_wakeup(sc);
                ath_update_txpow(sc);
+               ath9k_ps_restore(sc);
        }
 
        spin_lock_bh(&sc->wiphy_lock);
index 332d1feb5c18ece5b4024beefc21fb83826902f4..33a37edbaf79f5ce249dc5c8ca35812e85ecf60f 100644 (file)
@@ -2113,9 +2113,7 @@ static void ath_tx_complete_poll_work(struct work_struct *work)
        if (needreset) {
                ath_dbg(ath9k_hw_common(sc->sc_ah), ATH_DBG_RESET,
                        "tx hung, resetting the chip\n");
-               ath9k_ps_wakeup(sc);
                ath_reset(sc, true);
-               ath9k_ps_restore(sc);
        }
 
        ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work,
index 3f1e5f1bf84720932e25ffa88f63b4f80d972d9a..91a9f5253469948d573725ec54cc7b5e6f1e3208 100644 (file)
@@ -2624,6 +2624,7 @@ struct iwl_cfg iwl4965_agn_cfg = {
        .fw_name_pre = IWL4965_FW_PRE,
        .ucode_api_max = IWL4965_UCODE_API_MAX,
        .ucode_api_min = IWL4965_UCODE_API_MIN,
+       .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
        .valid_tx_ant = ANT_AB,
        .valid_rx_ant = ANT_ABC,
        .eeprom_ver = EEPROM_4965_EEPROM_VERSION,
index 14ceb4df72f63e3fa4f467a074c15ecda5849454..27b5a3eec9dc28dc12f17d8a47bf9ba25250085a 100644 (file)
@@ -152,11 +152,14 @@ int iwl_eeprom_check_sku(struct iwl_priv *priv)
 
        eeprom_sku = iwl_eeprom_query16(priv, EEPROM_SKU_CAP);
 
-       priv->cfg->sku = ((eeprom_sku & EEPROM_SKU_CAP_BAND_SELECTION) >>
+       if (!priv->cfg->sku) {
+               /* not using sku overwrite */
+               priv->cfg->sku =
+                       ((eeprom_sku & EEPROM_SKU_CAP_BAND_SELECTION) >>
                        EEPROM_SKU_CAP_BAND_POS);
-       if (eeprom_sku & EEPROM_SKU_CAP_11N_ENABLE)
-               priv->cfg->sku |= IWL_SKU_N;
-
+               if (eeprom_sku & EEPROM_SKU_CAP_11N_ENABLE)
+                       priv->cfg->sku |= IWL_SKU_N;
+       }
        if (!priv->cfg->sku) {
                IWL_ERR(priv, "Invalid device sku\n");
                return -EINVAL;
index 0b4e8590cbb77e067902f9d176043db0a713c4c9..029be3c6c030971f6aec1d9326e43185a8b6479a 100644 (file)
@@ -2446,6 +2446,7 @@ static struct usb_device_id rt73usb_device_table[] = {
        { USB_DEVICE(0x04bb, 0x093d), USB_DEVICE_DATA(&rt73usb_ops) },
        { USB_DEVICE(0x148f, 0x2573), USB_DEVICE_DATA(&rt73usb_ops) },
        { USB_DEVICE(0x148f, 0x2671), USB_DEVICE_DATA(&rt73usb_ops) },
+       { USB_DEVICE(0x0812, 0x3101), USB_DEVICE_DATA(&rt73usb_ops) },
        /* Qcom */
        { USB_DEVICE(0x18e8, 0x6196), USB_DEVICE_DATA(&rt73usb_ops) },
        { USB_DEVICE(0x18e8, 0x6229), USB_DEVICE_DATA(&rt73usb_ops) },
index 0fa36aa6701a80fb1b06f03891bd3830d7f5e4ca..1758d4463247395c7e9d3d15a8e3be5010160744 100644 (file)
@@ -619,6 +619,13 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw)
                                        struct sk_buff *uskb = NULL;
                                        u8 *pdata;
                                        uskb = dev_alloc_skb(skb->len + 128);
+                                       if (!uskb) {
+                                               RT_TRACE(rtlpriv,
+                                                       (COMP_INTR | COMP_RECV),
+                                                       DBG_EMERG,
+                                                       ("can't alloc rx skb\n"));
+                                               goto done;
+                                       }
                                        memcpy(IEEE80211_SKB_RXCB(uskb),
                                                        &rx_status,
                                                        sizeof(rx_status));
@@ -641,7 +648,7 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw)
                        new_skb = dev_alloc_skb(rtlpci->rxbuffersize);
                        if (unlikely(!new_skb)) {
                                RT_TRACE(rtlpriv, (COMP_INTR | COMP_RECV),
-                                        DBG_DMESG,
+                                        DBG_EMERG,
                                         ("can't alloc skb for rx\n"));
                                goto done;
                        }
@@ -1066,9 +1073,9 @@ static int _rtl_pci_init_rx_ring(struct ieee80211_hw *hw)
                        struct sk_buff *skb =
                            dev_alloc_skb(rtlpci->rxbuffersize);
                        u32 bufferaddress;
-                       entry = &rtlpci->rx_ring[rx_queue_idx].desc[i];
                        if (!skb)
                                return 0;
+                       entry = &rtlpci->rx_ring[rx_queue_idx].desc[i];
 
                        /*skb->dev = dev; */
 
index a2d9d1e59260eab17097e0a12f16908eed26c552..a848e02e6be3d4537b5dd94c7017ec799cf7becb 100644 (file)
@@ -678,7 +678,7 @@ void parport_unregister_device(struct pardevice *dev)
 
        /* Make sure we haven't left any pointers around in the wait
         * list. */
-       spin_lock (&port->waitlist_lock);
+       spin_lock_irq(&port->waitlist_lock);
        if (dev->waitprev || dev->waitnext || port->waithead == dev) {
                if (dev->waitprev)
                        dev->waitprev->waitnext = dev->waitnext;
@@ -689,7 +689,7 @@ void parport_unregister_device(struct pardevice *dev)
                else
                        port->waittail = dev->waitprev;
        }
-       spin_unlock (&port->waitlist_lock);
+       spin_unlock_irq(&port->waitlist_lock);
 
        kfree(dev->state);
        kfree(dev);
index 1752ef006d26e44f2154293ba9c6f052cf2480e0..a91d510a798b2a9e5f2e35c67c369979b273900f 100644 (file)
@@ -26,7 +26,6 @@
 #include <linux/sfi.h>
 #include <asm/mrst.h>
 #include <asm/intel_scu_ipc.h>
-#include <asm/mrst.h>
 
 /* IPC defines the following message types */
 #define IPCMSG_WATCHDOG_TIMER 0xF8 /* Set Kernel Watchdog Threshold */
@@ -161,7 +160,7 @@ static int pwr_reg_rdwr(u16 *addr, u8 *data, u32 count, u32 op, u32 id)
 {
        int i, nc, bytes, d;
        u32 offset = 0;
-       u32 err = 0;
+       int err;
        u8 cbuf[IPC_WWBUF_SIZE] = { };
        u32 *wbuf = (u32 *)&cbuf;
 
@@ -404,7 +403,7 @@ EXPORT_SYMBOL(intel_scu_ipc_update_register);
  */
 int intel_scu_ipc_simple_command(int cmd, int sub)
 {
-       u32 err = 0;
+       int err;
 
        mutex_lock(&ipclock);
        if (ipcdev.pdev == NULL) {
@@ -434,8 +433,7 @@ EXPORT_SYMBOL(intel_scu_ipc_simple_command);
 int intel_scu_ipc_command(int cmd, int sub, u32 *in, int inlen,
                                                        u32 *out, int outlen)
 {
-       u32 err = 0;
-       int i = 0;
+       int i, err;
 
        mutex_lock(&ipclock);
        if (ipcdev.pdev == NULL) {
index ba3231d0819ee12163807147332297082341ee1c..b93a03259c16909b2e7a811a0aea1a4278239aa8 100644 (file)
@@ -128,6 +128,6 @@ static void __exit ipc_module_exit(void)
 module_init(ipc_module_init);
 module_exit(ipc_module_exit);
 
-MODULE_LICENSE("GPL V2");
+MODULE_LICENSE("GPL v2");
 MODULE_DESCRIPTION("Utility driver for intel scu ipc");
 MODULE_AUTHOR("Sreedhara <sreedhara.ds@intel.com>");
index 2728469d388494031c401a8dcbb64028370a1612..82583b0ff82dac05efd9c1d495654ccd244419cc 100644 (file)
@@ -46,8 +46,6 @@ static void pps_ktimer_event(unsigned long ptr)
        /* First of all we get the time stamp... */
        pps_get_ts(&ts);
 
-       dev_info(pps->dev, "PPS event at %lu\n", jiffies);
-
        pps_event(pps, &ts, PPS_CAPTUREASSERT, NULL);
 
        mod_timer(&ktimer, jiffies + HZ);
index 32221efd9ca979d9518d2e130d2e4ebe3cba777c..c571d6dd8f61f626bdaeb6405de5a3f8aa7a30a6 100644 (file)
@@ -163,7 +163,7 @@ static void parport_attach(struct parport *port)
        }
 
        device->pardev = parport_register_device(port, KBUILD_MODNAME,
-                       NULL, NULL, parport_irq, 0, device);
+                       NULL, NULL, parport_irq, PARPORT_FLAG_EXCL, device);
        if (!device->pardev) {
                pr_err("couldn't register with %s\n", port->name);
                goto err_free;
index 5c32f8dacf56d5fa265a8edbcd0e50d829bcb0a7..b93af3ebb5baa1ece794b9054ca0fbf84563f20e 100644 (file)
@@ -198,7 +198,7 @@ static void parport_attach(struct parport *port)
        }
 
        device.pardev = parport_register_device(port, KBUILD_MODNAME,
-                       NULL, NULL, NULL, 0, &device);
+                       NULL, NULL, NULL, PARPORT_FLAG_EXCL, &device);
        if (!device.pardev) {
                pr_err("couldn't register with %s\n", port->name);
                return;
index 467e82bd0929789867031a0ae31e1114d38e8274..a50391b6ba2a95b8afcc6d397a90c068c5f9bc36 100644 (file)
@@ -943,6 +943,8 @@ static int rio_enum_complete(struct rio_mport *port)
  * @port: Master port to send transactions
  * @destid: Current destination ID in network
  * @hopcount: Number of hops into the network
+ * @prev: previous rio_dev
+ * @prev_port: previous port number
  *
  * Recursively discovers a RIO network.  Transactions are sent via the
  * master port passed in @port.
index 4941cade319f5cef06d508d0b1f1354d951c1034..cdd97192dc693cc84d075e24af1450ba5aebd2e5 100644 (file)
@@ -97,18 +97,6 @@ config RTC_INTF_DEV
 
          If unsure, say Y.
 
-config RTC_INTF_DEV_UIE_EMUL
-       bool "RTC UIE emulation on dev interface"
-       depends on RTC_INTF_DEV
-       help
-         Provides an emulation for RTC_UIE if the underlying rtc chip
-         driver does not expose RTC_UIE ioctls. Those requests generate
-         once-per-second update interrupts, used for synchronization.
-
-         The emulation code will read the time from the hardware
-         clock several times per second, please enable this option
-         only if you know that you really need it.
-
 config RTC_DRV_TEST
        tristate "Test driver/device"
        help
index 90384b9f6b2c52bade8b2dd067ff31ffd73e7930..925006d331099699e27b26012050b81cd3acbcce 100644 (file)
@@ -16,6 +16,9 @@
 #include <linux/log2.h>
 #include <linux/workqueue.h>
 
+static int rtc_timer_enqueue(struct rtc_device *rtc, struct rtc_timer *timer);
+static void rtc_timer_remove(struct rtc_device *rtc, struct rtc_timer *timer);
+
 static int __rtc_read_time(struct rtc_device *rtc, struct rtc_time *tm)
 {
        int err;
@@ -120,12 +123,18 @@ int rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
        err = mutex_lock_interruptible(&rtc->ops_lock);
        if (err)
                return err;
-       alarm->enabled = rtc->aie_timer.enabled;
-       if (alarm->enabled)
+       if (rtc->ops == NULL)
+               err = -ENODEV;
+       else if (!rtc->ops->read_alarm)
+               err = -EINVAL;
+       else {
+               memset(alarm, 0, sizeof(struct rtc_wkalrm));
+               alarm->enabled = rtc->aie_timer.enabled;
                alarm->time = rtc_ktime_to_tm(rtc->aie_timer.node.expires);
+       }
        mutex_unlock(&rtc->ops_lock);
 
-       return 0;
+       return err;
 }
 EXPORT_SYMBOL_GPL(rtc_read_alarm);
 
@@ -175,16 +184,14 @@ int rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
                return err;
        if (rtc->aie_timer.enabled) {
                rtc_timer_remove(rtc, &rtc->aie_timer);
-               rtc->aie_timer.enabled = 0;
        }
        rtc->aie_timer.node.expires = rtc_tm_to_ktime(alarm->time);
        rtc->aie_timer.period = ktime_set(0, 0);
        if (alarm->enabled) {
-               rtc->aie_timer.enabled = 1;
-               rtc_timer_enqueue(rtc, &rtc->aie_timer);
+               err = rtc_timer_enqueue(rtc, &rtc->aie_timer);
        }
        mutex_unlock(&rtc->ops_lock);
-       return 0;
+       return err;
 }
 EXPORT_SYMBOL_GPL(rtc_set_alarm);
 
@@ -195,15 +202,15 @@ int rtc_alarm_irq_enable(struct rtc_device *rtc, unsigned int enabled)
                return err;
 
        if (rtc->aie_timer.enabled != enabled) {
-               if (enabled) {
-                       rtc->aie_timer.enabled = 1;
-                       rtc_timer_enqueue(rtc, &rtc->aie_timer);
-               } else {
+               if (enabled)
+                       err = rtc_timer_enqueue(rtc, &rtc->aie_timer);
+               else
                        rtc_timer_remove(rtc, &rtc->aie_timer);
-                       rtc->aie_timer.enabled = 0;
-               }
        }
 
+       if (err)
+               return err;
+
        if (!rtc->ops)
                err = -ENODEV;
        else if (!rtc->ops->alarm_irq_enable)
@@ -235,12 +242,9 @@ int rtc_update_irq_enable(struct rtc_device *rtc, unsigned int enabled)
                now = rtc_tm_to_ktime(tm);
                rtc->uie_rtctimer.node.expires = ktime_add(now, onesec);
                rtc->uie_rtctimer.period = ktime_set(1, 0);
-               rtc->uie_rtctimer.enabled = 1;
-               rtc_timer_enqueue(rtc, &rtc->uie_rtctimer);
-       } else {
+               err = rtc_timer_enqueue(rtc, &rtc->uie_rtctimer);
+       } else
                rtc_timer_remove(rtc, &rtc->uie_rtctimer);
-               rtc->uie_rtctimer.enabled = 0;
-       }
 
 out:
        mutex_unlock(&rtc->ops_lock);
@@ -488,10 +492,13 @@ EXPORT_SYMBOL_GPL(rtc_irq_set_freq);
  * Enqueues a timer onto the rtc devices timerqueue and sets
  * the next alarm event appropriately.
  *
+ * Sets the enabled bit on the added timer.
+ *
  * Must hold ops_lock for proper serialization of timerqueue
  */
-void rtc_timer_enqueue(struct rtc_device *rtc, struct rtc_timer *timer)
+static int rtc_timer_enqueue(struct rtc_device *rtc, struct rtc_timer *timer)
 {
+       timer->enabled = 1;
        timerqueue_add(&rtc->timerqueue, &timer->node);
        if (&timer->node == timerqueue_getnext(&rtc->timerqueue)) {
                struct rtc_wkalrm alarm;
@@ -501,7 +508,13 @@ void rtc_timer_enqueue(struct rtc_device *rtc, struct rtc_timer *timer)
                err = __rtc_set_alarm(rtc, &alarm);
                if (err == -ETIME)
                        schedule_work(&rtc->irqwork);
+               else if (err) {
+                       timerqueue_del(&rtc->timerqueue, &timer->node);
+                       timer->enabled = 0;
+                       return err;
+               }
        }
+       return 0;
 }
 
 /**
@@ -512,13 +525,15 @@ void rtc_timer_enqueue(struct rtc_device *rtc, struct rtc_timer *timer)
  * Removes a timer onto the rtc devices timerqueue and sets
  * the next alarm event appropriately.
  *
+ * Clears the enabled bit on the removed timer.
+ *
  * Must hold ops_lock for proper serialization of timerqueue
  */
-void rtc_timer_remove(struct rtc_device *rtc, struct rtc_timer *timer)
+static void rtc_timer_remove(struct rtc_device *rtc, struct rtc_timer *timer)
 {
        struct timerqueue_node *next = timerqueue_getnext(&rtc->timerqueue);
        timerqueue_del(&rtc->timerqueue, &timer->node);
-
+       timer->enabled = 0;
        if (next == &timer->node) {
                struct rtc_wkalrm alarm;
                int err;
@@ -626,8 +641,7 @@ int rtc_timer_start(struct rtc_device *rtc, struct rtc_timer* timer,
        timer->node.expires = expires;
        timer->period = period;
 
-       timer->enabled = 1;
-       rtc_timer_enqueue(rtc, timer);
+       ret = rtc_timer_enqueue(rtc, timer);
 
        mutex_unlock(&rtc->ops_lock);
        return ret;
@@ -645,7 +659,6 @@ int rtc_timer_cancel(struct rtc_device *rtc, struct rtc_timer* timer)
        mutex_lock(&rtc->ops_lock);
        if (timer->enabled)
                rtc_timer_remove(rtc, timer);
-       timer->enabled = 0;
        mutex_unlock(&rtc->ops_lock);
        return ret;
 }
index 4155805dcdff6230e2510cd753fd03b960ba5044..2b771f18d1adc836f36c6c509060af409f9f1bed 100644 (file)
@@ -319,6 +319,9 @@ void dasd_alias_disconnect_device_from_lcu(struct dasd_device *device)
 
        private = (struct dasd_eckd_private *) device->private;
        lcu = private->lcu;
+       /* nothing to do if already disconnected */
+       if (!lcu)
+               return;
        device->discipline->get_uid(device, &uid);
        spin_lock_irqsave(&lcu->lock, flags);
        list_del_init(&device->alias_list);
@@ -680,6 +683,9 @@ int dasd_alias_remove_device(struct dasd_device *device)
 
        private = (struct dasd_eckd_private *) device->private;
        lcu = private->lcu;
+       /* nothing to do if already removed */
+       if (!lcu)
+               return 0;
        spin_lock_irqsave(&lcu->lock, flags);
        _remove_device_from_lcu(lcu, device);
        spin_unlock_irqrestore(&lcu->lock, flags);
index e9fff2b9bce23e3d905968488d72138165e268fc..5640c89cd9de3bae5f6f283f08eda97d7b3c3960 100644 (file)
@@ -476,7 +476,7 @@ static inline void inbound_primed(struct qdio_q *q, int count)
 static int get_inbound_buffer_frontier(struct qdio_q *q)
 {
        int count, stop;
-       unsigned char state;
+       unsigned char state = 0;
 
        /*
         * Don't check 128 buffers, as otherwise qdio_inbound_q_moved
@@ -643,7 +643,7 @@ void qdio_inbound_processing(unsigned long data)
 static int get_outbound_buffer_frontier(struct qdio_q *q)
 {
        int count, stop;
-       unsigned char state;
+       unsigned char state = 0;
 
        if (need_siga_sync(q))
                if (((queue_type(q) != QDIO_IQDIO_QFMT) &&
index de885a0f917a4ca747da4a46e44145068896ef8b..f33e2dd979348f4b78560d15b2f8e9f9d33ef09e 100644 (file)
@@ -173,7 +173,8 @@ int intc_set_priority(unsigned int irq, unsigned int prio)
        return 0;
 }
 
-#define VALID(x) (x | 0x80)
+#define SENSE_VALID_FLAG 0x80
+#define VALID(x) (x | SENSE_VALID_FLAG)
 
 static unsigned char intc_irq_sense_table[IRQ_TYPE_SENSE_MASK + 1] = {
        [IRQ_TYPE_EDGE_FALLING] = VALID(0),
@@ -201,7 +202,8 @@ static int intc_set_type(struct irq_data *data, unsigned int type)
        ihp = intc_find_irq(d->sense, d->nr_sense, irq);
        if (ihp) {
                addr = INTC_REG(d, _INTC_ADDR_E(ihp->handle), 0);
-               intc_reg_fns[_INTC_FN(ihp->handle)](addr, ihp->handle, value);
+               intc_reg_fns[_INTC_FN(ihp->handle)](addr, ihp->handle,
+                                                   value & ~SENSE_VALID_FLAG);
        }
 
        return 0;
index 0e298dba9fc80cc3d54c304e8e77cd674a21dbf4..29b8ab44ea4720e840365fc0fdb0071d670c196b 100644 (file)
@@ -360,8 +360,8 @@ int PSSendOps(void *arg)
                status = 1;
                goto complete;
        }
-        len = (firmware->size > MAX_BDADDR_FORMAT_LENGTH)? MAX_BDADDR_FORMAT_LENGTH: firmware->size;
-       memcpy(config_bdaddr, firmware->data,len);
+       len = min(firmware->size, MAX_BDADDR_FORMAT_LENGTH - 1);
+       memcpy(config_bdaddr, firmware->data, len);
        config_bdaddr[len] = '\0';
        write_bdaddr(hdev,config_bdaddr,BDADDR_TYPE_STRING);
                A_RELEASE_FIRMWARE(firmware);
index bdd629d72a756105e1308ebff61ecfb7c9e3934b..f1235884cc5d24f15d3619b8678e0a2751754563 100644 (file)
@@ -209,11 +209,8 @@ static void wl_ops_stop(struct ieee80211_hw *hw)
        struct wl_info *wl = hw->priv;
        ASSERT(wl);
        WL_LOCK(wl);
-       wl_down(wl);
        ieee80211_stop_queues(hw);
        WL_UNLOCK(wl);
-
-       return;
 }
 
 static int
@@ -246,7 +243,14 @@ wl_ops_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
 static void
 wl_ops_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
 {
-       return;
+       struct wl_info *wl;
+
+       wl = HW_TO_WL(hw);
+
+       /* put driver in down state */
+       WL_LOCK(wl);
+       wl_down(wl);
+       WL_UNLOCK(wl);
 }
 
 static int
@@ -779,7 +783,7 @@ static struct wl_info *wl_attach(u16 vendor, u16 device, unsigned long regs,
        wl_found++;
        return wl;
 
- fail:
+fail:
        wl_free(wl);
 fail1:
        return NULL;
@@ -1090,7 +1094,6 @@ wl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        return 0;
 }
 
-#ifdef LINUXSTA_PS
 static int wl_suspend(struct pci_dev *pdev, pm_message_t state)
 {
        struct wl_info *wl;
@@ -1105,11 +1108,12 @@ static int wl_suspend(struct pci_dev *pdev, pm_message_t state)
                return -ENODEV;
        }
 
+       /* only need to flag hw is down for proper resume */
        WL_LOCK(wl);
-       wl_down(wl);
        wl->pub->hw_up = false;
        WL_UNLOCK(wl);
-       pci_save_state(pdev, wl->pci_psstate);
+
+       pci_save_state(pdev);
        pci_disable_device(pdev);
        return pci_set_power_state(pdev, PCI_D3hot);
 }
@@ -1133,7 +1137,7 @@ static int wl_resume(struct pci_dev *pdev)
        if (err)
                return err;
 
-       pci_restore_state(pdev, wl->pci_psstate);
+       pci_restore_state(pdev);
 
        err = pci_enable_device(pdev);
        if (err)
@@ -1145,13 +1149,12 @@ static int wl_resume(struct pci_dev *pdev)
        if ((val & 0x0000ff00) != 0)
                pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
 
-       WL_LOCK(wl);
-       err = wl_up(wl);
-       WL_UNLOCK(wl);
-
+       /*
+       *  done. driver will be put in up state
+       *  in wl_ops_add_interface() call.
+       */
        return err;
 }
-#endif                         /* LINUXSTA_PS */
 
 static void wl_remove(struct pci_dev *pdev)
 {
@@ -1184,14 +1187,12 @@ static void wl_remove(struct pci_dev *pdev)
 }
 
 static struct pci_driver wl_pci_driver = {
- .name  = "brcm80211",
- .probe = wl_pci_probe,
-#ifdef LINUXSTA_PS
- .suspend = wl_suspend,
- .resume  = wl_resume,
-#endif                         /* LINUXSTA_PS */
- .remove   = __devexit_p(wl_remove),
- .id_table = wl_id_table,
+       .name = "brcm80211",
+       .probe = wl_pci_probe,
+       .suspend = wl_suspend,
+       .resume = wl_resume,
+       .remove = __devexit_p(wl_remove),
+       .id_table = wl_id_table,
 };
 
 /**
index 1d5d01ac0a9b384e7b9c6d08f9b821f695d38f36..a1303863686c465e076b54a028b6ce56e2cd3fce 100644 (file)
@@ -5126,7 +5126,6 @@ wlc_sendpkt_mac80211(struct wlc_info *wlc, struct sk_buff *sdu,
        fifo = prio2fifo[prio];
 
        ASSERT((uint) skb_headroom(sdu) >= TXOFF);
-       ASSERT(!(sdu->cloned));
        ASSERT(!(sdu->next));
        ASSERT(!(sdu->prev));
        ASSERT(fifo < NFIFO);
index 4d1868d04bac93a6ecb49c2a51f456b3d62b12bf..0728c3c0cb0e258738e0f0c767eaec65e3adac95 100644 (file)
@@ -575,7 +575,8 @@ int labpc_common_attach(struct comedi_device *dev, unsigned long iobase,
        /* grab our IRQ */
        if (irq) {
                isr_flags = 0;
-               if (thisboard->bustype == pci_bustype)
+               if (thisboard->bustype == pci_bustype
+                   || thisboard->bustype == pcmcia_bustype)
                        isr_flags |= IRQF_SHARED;
                if (request_irq(irq, labpc_interrupt, isr_flags,
                                driver_labpc.driver_name, dev)) {
index b3d05fcfe6d2a1ee2cde4a8f4b678322c9e05527..4fb809485d9e6409c5537e3576db9c9e009ca59c 100644 (file)
@@ -368,6 +368,7 @@ static int blkvsc_probe(struct device *device)
                blkdev->gd->first_minor = 0;
        blkdev->gd->fops = &block_ops;
        blkdev->gd->private_data = blkdev;
+       blkdev->gd->driverfs_dev = &(blkdev->device_ctx->device);
        sprintf(blkdev->gd->disk_name, "hd%c", 'a' + devnum);
 
        blkvsc_do_inquiry(blkdev);
index df9cd131e9535e2f0dad72222d9873c9eaf5a491..0edbe7483a4c4606cce94c2f001806ebf23ed234 100644 (file)
@@ -1279,7 +1279,7 @@ static void netvsc_channel_cb(void *context)
        /* ASSERT(device); */
 
        packet = kzalloc(NETVSC_PACKET_SIZE * sizeof(unsigned char),
-                        GFP_KERNEL);
+                        GFP_ATOMIC);
        if (!packet)
                return;
        buffer = packet;
index 0147b407512ce40c799fb7579da90248a3473c15..54706a16dc0a59b943ebca95a5b641983a9de5bc 100644 (file)
@@ -358,7 +358,6 @@ static int netvsc_probe(struct device *device)
 
        /* Set initial state */
        netif_carrier_off(net);
-       netif_stop_queue(net);
 
        net_device_ctx = netdev_priv(net);
        net_device_ctx->device_ctx = device_ctx;
index deb68c8a6e180c6dea01a11313ef932a9b54170c..b8b54da67c632b6bdafa6c3aba0af2fb3f2cf03b 100644 (file)
@@ -68,7 +68,7 @@ static ssize_t ad7476_show_scale(struct device *dev,
        /* Corresponds to Vref / 2^(bits) */
        unsigned int scale_uv = (st->int_vref_mv * 1000) >> st->chip_info->bits;
 
-       return sprintf(buf, "%d.%d\n", scale_uv / 1000, scale_uv % 1000);
+       return sprintf(buf, "%d.%03d\n", scale_uv / 1000, scale_uv % 1000);
 }
 static IIO_DEVICE_ATTR(in_scale, S_IRUGO, ad7476_show_scale, NULL, 0);
 
index 685908995d49198e7b11a46ed0eba2ce500ca913..5d85efab658cfbac69fb8b3d055f89e7ec88740a 100644 (file)
@@ -68,7 +68,7 @@ static ssize_t ad7887_show_scale(struct device *dev,
        /* Corresponds to Vref / 2^(bits) */
        unsigned int scale_uv = (st->int_vref_mv * 1000) >> st->chip_info->bits;
 
-       return sprintf(buf, "%d.%d\n", scale_uv / 1000, scale_uv % 1000);
+       return sprintf(buf, "%d.%03d\n", scale_uv / 1000, scale_uv % 1000);
 }
 static IIO_DEVICE_ATTR(in_scale, S_IRUGO, ad7887_show_scale, NULL, 0);
 
index 6309d521a864932aa09cfeb9b298b600cb3254ef..89ccf375a188c79fa586dc9036d7763e2d6d655c 100644 (file)
@@ -432,7 +432,7 @@ static ssize_t ad799x_show_scale(struct device *dev,
        /* Corresponds to Vref / 2^(bits) */
        unsigned int scale_uv = (st->int_vref_mv * 1000) >> st->chip_info->bits;
 
-       return sprintf(buf, "%d.%d\n", scale_uv / 1000, scale_uv % 1000);
+       return sprintf(buf, "%d.%03d\n", scale_uv / 1000, scale_uv % 1000);
 }
 
 static IIO_DEVICE_ATTR(in_scale, S_IRUGO, ad799x_show_scale, NULL, 0);
index e3387cd311457f067cc6ca90590a388a38c2e2b6..0f87ecac82fc044e84d7673152e71f3f9d3d821a 100644 (file)
@@ -87,7 +87,7 @@ static ssize_t ad5446_show_scale(struct device *dev,
        /* Corresponds to Vref / 2^(bits) */
        unsigned int scale_uv = (st->vref_mv * 1000) >> st->chip_info->bits;
 
-       return sprintf(buf, "%d.%d\n", scale_uv / 1000, scale_uv % 1000);
+       return sprintf(buf, "%d.%03d\n", scale_uv / 1000, scale_uv % 1000);
 }
 static IIO_DEVICE_ATTR(out_scale, S_IRUGO, ad5446_show_scale, NULL, 0);
 
index 23fa049b51f22d941ebd8415f375c93ad3462898..a2f29d464051a53b86bb43158bd4c7716b01d63c 100644 (file)
@@ -347,7 +347,7 @@ static int msm_fb_suspend(struct platform_device *pdev, pm_message_t state)
        if ((!mfd) || (mfd->key != MFD_KEY))
                return 0;
 
-       acquire_console_sem();
+       console_lock();
        fb_set_suspend(mfd->fbi, 1);
 
        ret = msm_fb_suspend_sub(mfd);
@@ -358,7 +358,7 @@ static int msm_fb_suspend(struct platform_device *pdev, pm_message_t state)
                pdev->dev.power.power_state = state;
        }
 
-       release_console_sem();
+       console_unlock();
        return ret;
 }
 #else
@@ -431,11 +431,11 @@ static int msm_fb_resume(struct platform_device *pdev)
        if ((!mfd) || (mfd->key != MFD_KEY))
                return 0;
 
-       acquire_console_sem();
+       console_lock();
        ret = msm_fb_resume_sub(mfd);
        pdev->dev.power.power_state = PMSG_ON;
        fb_set_suspend(mfd->fbi, 1);
-       release_console_sem();
+       console_unlock();
 
        return ret;
 }
index 9f26dc9408bb757525599dbec98d47ca9a78ebc8..56a283d1a74dc7b01597052d0b6a2f83ae7de02e 100644 (file)
@@ -373,17 +373,17 @@ static void dcon_source_switch(struct work_struct *work)
                 *
                 * For now, we just hope..
                 */
-               acquire_console_sem();
+               console_lock();
                ignore_fb_events = 1;
                if (fb_blank(fbinfo, FB_BLANK_UNBLANK)) {
                        ignore_fb_events = 0;
-                       release_console_sem();
+                       console_unlock();
                        printk(KERN_ERR "olpc-dcon:  Failed to enter CPU mode\n");
                        dcon_pending = DCON_SOURCE_DCON;
                        return;
                }
                ignore_fb_events = 0;
-               release_console_sem();
+               console_unlock();
 
                /* And turn off the DCON */
                pdata->set_dconload(1);
@@ -435,12 +435,12 @@ static void dcon_source_switch(struct work_struct *work)
                        }
                }
 
-               acquire_console_sem();
+               console_lock();
                ignore_fb_events = 1;
                if (fb_blank(fbinfo, FB_BLANK_POWERDOWN))
                        printk(KERN_ERR "olpc-dcon:  couldn't blank fb!\n");
                ignore_fb_events = 0;
-               release_console_sem();
+               console_unlock();
 
                printk(KERN_INFO "olpc-dcon: The DCON has control\n");
                break;
index 701561d6b6fdc03a4ecad832ef39940653a023a4..236dd36d349a16b6a1c099f93e5ca4b867547590 100644 (file)
@@ -484,8 +484,6 @@ struct net_device *RtmpPhyNetDevInit(struct rt_rtmp_adapter *pAd,
        net_dev->ml_priv = (void *)pAd;
        pAd->net_dev = net_dev;
 
-       netif_stop_queue(net_dev);
-
        return net_dev;
 
 }
index ee68d51caa4e8e4dbd7a90337570d6815224dc9a..322bf49ee90670ff1b5fb175998f782db94905d9 100644 (file)
@@ -106,6 +106,7 @@ struct usb_device_id rtusb_usb_id[] = {
        {USB_DEVICE(0x0411, 0x016f)},   /* MelCo.,Inc. WLI-UC-G301N */
        {USB_DEVICE(0x1737, 0x0070)},   /* Linksys WUSB100 */
        {USB_DEVICE(0x1737, 0x0071)},   /* Linksys WUSB600N */
+       {USB_DEVICE(0x1737, 0x0078)},   /* Linksys WUSB100v2 */
        {USB_DEVICE(0x0411, 0x00e8)},   /* Buffalo WLI-UC-G300N */
        {USB_DEVICE(0x050d, 0x815c)},   /* Belkin F5D8053 */
        {USB_DEVICE(0x100D, 0x9031)},   /* Motorola 2770 */
index 32088a641eba12f60f1e20acf27bc80c8e28fb5e..84be383abec3eea25feba26c4645838a2ebfd4b4 100644 (file)
@@ -128,12 +128,13 @@ static u8 rtl8712_dl_fw(struct _adapter *padapter)
        u8 *ptmpchar = NULL, *ppayload, *ptr;
        struct tx_desc *ptx_desc;
        u32 txdscp_sz = sizeof(struct tx_desc);
+       u8 ret = _FAIL;
 
        ulfilelength = rtl871x_open_fw(padapter, &phfwfile_hdl, &pmappedfw);
        if (pmappedfw && (ulfilelength > 0)) {
                update_fwhdr(&fwhdr, pmappedfw);
                if (chk_fwhdr(&fwhdr, ulfilelength) == _FAIL)
-                       goto exit_fail;
+                       goto firmware_rel;
                fill_fwpriv(padapter, &fwhdr.fwpriv);
                /* firmware check ok */
                maxlen = (fwhdr.img_IMEM_size > fwhdr.img_SRAM_size) ?
@@ -141,7 +142,7 @@ static u8 rtl8712_dl_fw(struct _adapter *padapter)
                maxlen += txdscp_sz;
                ptmpchar = _malloc(maxlen + FWBUFF_ALIGN_SZ);
                if (ptmpchar == NULL)
-                       return _FAIL;
+                       goto firmware_rel;
 
                ptx_desc = (struct tx_desc *)(ptmpchar + FWBUFF_ALIGN_SZ -
                            ((addr_t)(ptmpchar) & (FWBUFF_ALIGN_SZ - 1)));
@@ -273,11 +274,13 @@ static u8 rtl8712_dl_fw(struct _adapter *padapter)
                        goto exit_fail;
        } else
                goto exit_fail;
-       return _SUCCESS;
+       ret = _SUCCESS;
 
 exit_fail:
        kfree(ptmpchar);
-       return _FAIL;
+firmware_rel:
+       release_firmware((struct firmware *)phfwfile_hdl);
+       return ret;
 }
 
 uint rtl8712_hal_init(struct _adapter *padapter)
index a692ee88b9e9a3c3d97a4e97d7197ca9b2f71995..21ce2af447b527c61ddab279ee6533a6c74ee69b 100644 (file)
@@ -47,54 +47,123 @@ static int r871xu_drv_init(struct usb_interface *pusb_intf,
 static void r871xu_dev_remove(struct usb_interface *pusb_intf);
 
 static struct usb_device_id rtl871x_usb_id_tbl[] = {
-       /*92SU
-        * Realtek */
-       {USB_DEVICE(0x0bda, 0x8171)},
-       {USB_DEVICE(0x0bda, 0x8172)},
+
+/* RTL8188SU */
+       /* Realtek */
+       {USB_DEVICE(0x0BDA, 0x8171)},
        {USB_DEVICE(0x0bda, 0x8173)},
-       {USB_DEVICE(0x0bda, 0x8174)},
        {USB_DEVICE(0x0bda, 0x8712)},
        {USB_DEVICE(0x0bda, 0x8713)},
        {USB_DEVICE(0x0bda, 0xC512)},
-       /* Abocom  */
+       /* Abocom */
        {USB_DEVICE(0x07B8, 0x8188)},
+       /* ASUS */
+       {USB_DEVICE(0x0B05, 0x1786)},
+       {USB_DEVICE(0x0B05, 0x1791)}, /* 11n mode disable */
+       /* Belkin */
+       {USB_DEVICE(0x050D, 0x945A)},
        /* Corega */
-       {USB_DEVICE(0x07aa, 0x0047)},
-       /* Dlink */
-       {USB_DEVICE(0x07d1, 0x3303)},
-       {USB_DEVICE(0x07d1, 0x3302)},
-       {USB_DEVICE(0x07d1, 0x3300)},
-       /* Dlink for Skyworth */
-       {USB_DEVICE(0x14b2, 0x3300)},
-       {USB_DEVICE(0x14b2, 0x3301)},
-       {USB_DEVICE(0x14b2, 0x3302)},
+       {USB_DEVICE(0x07AA, 0x0047)},
+       /* D-Link */
+       {USB_DEVICE(0x2001, 0x3306)},
+       {USB_DEVICE(0x07D1, 0x3306)}, /* 11n mode disable */
+       /* Edimax */
+       {USB_DEVICE(0x7392, 0x7611)},
        /* EnGenius */
        {USB_DEVICE(0x1740, 0x9603)},
-       {USB_DEVICE(0x1740, 0x9605)},
+       /* Hawking */
+       {USB_DEVICE(0x0E66, 0x0016)},
+       /* Hercules */
+       {USB_DEVICE(0x06F8, 0xE034)},
+       {USB_DEVICE(0x06F8, 0xE032)},
+       /* Logitec */
+       {USB_DEVICE(0x0789, 0x0167)},
+       /* PCI */
+       {USB_DEVICE(0x2019, 0xAB28)},
+       {USB_DEVICE(0x2019, 0xED16)},
+       /* Sitecom */
+       {USB_DEVICE(0x0DF6, 0x0057)},
+       {USB_DEVICE(0x0DF6, 0x0045)},
+       {USB_DEVICE(0x0DF6, 0x0059)}, /* 11n mode disable */
+       {USB_DEVICE(0x0DF6, 0x004B)},
+       {USB_DEVICE(0x0DF6, 0x0063)},
+       /* Sweex */
+       {USB_DEVICE(0x177F, 0x0154)},
+       /* Thinkware */
+       {USB_DEVICE(0x0BDA, 0x5077)},
+       /* Toshiba */
+       {USB_DEVICE(0x1690, 0x0752)},
+       /* - */
+       {USB_DEVICE(0x20F4, 0x646B)},
+       {USB_DEVICE(0x083A, 0xC512)},
+
+/* RTL8191SU */
+       /* Realtek */
+       {USB_DEVICE(0x0BDA, 0x8172)},
+       /* Amigo */
+       {USB_DEVICE(0x0EB0, 0x9061)},
+       /* ASUS/EKB */
+       {USB_DEVICE(0x0BDA, 0x8172)},
+       {USB_DEVICE(0x13D3, 0x3323)},
+       {USB_DEVICE(0x13D3, 0x3311)}, /* 11n mode disable */
+       {USB_DEVICE(0x13D3, 0x3342)},
+       /* ASUS/EKBLenovo */
+       {USB_DEVICE(0x13D3, 0x3333)},
+       {USB_DEVICE(0x13D3, 0x3334)},
+       {USB_DEVICE(0x13D3, 0x3335)}, /* 11n mode disable */
+       {USB_DEVICE(0x13D3, 0x3336)}, /* 11n mode disable */
+       /* ASUS/Media BOX */
+       {USB_DEVICE(0x13D3, 0x3309)},
        /* Belkin */
-       {USB_DEVICE(0x050d, 0x815F)},
-       {USB_DEVICE(0x050d, 0x945A)},
-       {USB_DEVICE(0x050d, 0x845A)},
-       /* Guillemot */
-       {USB_DEVICE(0x06f8, 0xe031)},
+       {USB_DEVICE(0x050D, 0x815F)},
+       /* D-Link */
+       {USB_DEVICE(0x07D1, 0x3302)},
+       {USB_DEVICE(0x07D1, 0x3300)},
+       {USB_DEVICE(0x07D1, 0x3303)},
        /* Edimax */
-       {USB_DEVICE(0x7392, 0x7611)},
        {USB_DEVICE(0x7392, 0x7612)},
-       {USB_DEVICE(0x7392, 0x7622)},
-       /* Sitecom */
-       {USB_DEVICE(0x0DF6, 0x0045)},
+       /* EnGenius */
+       {USB_DEVICE(0x1740, 0x9605)},
+       /* Guillemot */
+       {USB_DEVICE(0x06F8, 0xE031)},
        /* Hawking */
        {USB_DEVICE(0x0E66, 0x0015)},
-       {USB_DEVICE(0x0E66, 0x0016)},
-       {USB_DEVICE(0x0b05, 0x1786)},
-       {USB_DEVICE(0x0b05, 0x1791)},    /* 11n mode disable */
-
+       /* Mediao */
        {USB_DEVICE(0x13D3, 0x3306)},
-       {USB_DEVICE(0x13D3, 0x3309)},
+       /* PCI */
+       {USB_DEVICE(0x2019, 0xED18)},
+       {USB_DEVICE(0x2019, 0x4901)},
+       /* Sitecom */
+       {USB_DEVICE(0x0DF6, 0x0058)},
+       {USB_DEVICE(0x0DF6, 0x0049)},
+       {USB_DEVICE(0x0DF6, 0x004C)},
+       {USB_DEVICE(0x0DF6, 0x0064)},
+       /* Skyworth */
+       {USB_DEVICE(0x14b2, 0x3300)},
+       {USB_DEVICE(0x14b2, 0x3301)},
+       {USB_DEVICE(0x14B2, 0x3302)},
+       /* - */
+       {USB_DEVICE(0x04F2, 0xAFF2)},
+       {USB_DEVICE(0x04F2, 0xAFF5)},
+       {USB_DEVICE(0x04F2, 0xAFF6)},
+       {USB_DEVICE(0x13D3, 0x3339)},
+       {USB_DEVICE(0x13D3, 0x3340)}, /* 11n mode disable */
+       {USB_DEVICE(0x13D3, 0x3341)}, /* 11n mode disable */
        {USB_DEVICE(0x13D3, 0x3310)},
-       {USB_DEVICE(0x13D3, 0x3311)},    /* 11n mode disable */
        {USB_DEVICE(0x13D3, 0x3325)},
-       {USB_DEVICE(0x083A, 0xC512)},
+
+/* RTL8192SU */
+       /* Realtek */
+       {USB_DEVICE(0x0BDA, 0x8174)},
+       {USB_DEVICE(0x0BDA, 0x8174)},
+       /* Belkin */
+       {USB_DEVICE(0x050D, 0x845A)},
+       /* Corega */
+       {USB_DEVICE(0x07AA, 0x0051)},
+       /* Edimax */
+       {USB_DEVICE(0x7392, 0x7622)},
+       /* NEC */
+       {USB_DEVICE(0x0409, 0x02B6)},
        {}
 };
 
@@ -103,8 +172,20 @@ MODULE_DEVICE_TABLE(usb, rtl871x_usb_id_tbl);
 static struct specific_device_id specific_device_id_tbl[] = {
        {.idVendor = 0x0b05, .idProduct = 0x1791,
                 .flags = SPEC_DEV_ID_DISABLE_HT},
+       {.idVendor = 0x0df6, .idProduct = 0x0059,
+                .flags = SPEC_DEV_ID_DISABLE_HT},
+       {.idVendor = 0x13d3, .idProduct = 0x3306,
+                .flags = SPEC_DEV_ID_DISABLE_HT},
        {.idVendor = 0x13D3, .idProduct = 0x3311,
                 .flags = SPEC_DEV_ID_DISABLE_HT},
+       {.idVendor = 0x13d3, .idProduct = 0x3335,
+                .flags = SPEC_DEV_ID_DISABLE_HT},
+       {.idVendor = 0x13d3, .idProduct = 0x3336,
+                .flags = SPEC_DEV_ID_DISABLE_HT},
+       {.idVendor = 0x13d3, .idProduct = 0x3340,
+                .flags = SPEC_DEV_ID_DISABLE_HT},
+       {.idVendor = 0x13d3, .idProduct = 0x3341,
+                .flags = SPEC_DEV_ID_DISABLE_HT},
        {}
 };
 
index 0bc113c44d393423665b80f888c78660d67e8e6b..d007e4a12c14b8bd93370c4bb38a1aef5ca42cd5 100644 (file)
@@ -1044,9 +1044,9 @@ static int __maybe_unused smtcfb_suspend(struct pci_dev *pdev, pm_message_t msg)
 
        /* when doing suspend, call fb apis and pci apis */
        if (msg.event == PM_EVENT_SUSPEND) {
-               acquire_console_sem();
+               console_lock();
                fb_set_suspend(&sfb->fb, 1);
-               release_console_sem();
+               console_unlock();
                retv = pci_save_state(pdev);
                pci_disable_device(pdev);
                retv = pci_choose_state(pdev, msg);
@@ -1105,9 +1105,9 @@ static int __maybe_unused smtcfb_resume(struct pci_dev *pdev)
 
        smtcfb_setmode(sfb);
 
-       acquire_console_sem();
+       console_lock();
        fb_set_suspend(&sfb->fb, 0);
-       release_console_sem();
+       console_unlock();
 
        return 0;
 }
index 408bb9b3303e89d7c0f95e1d8c25cb99af05cc94..07a7f5432597f4d88719850e15406435b9a9b412 100644 (file)
@@ -332,7 +332,7 @@ static ssize_t silent_store(struct kobject *kobj, struct kobj_attribute *attr,
        unsigned long flags;
 
        len = strlen(buf);
-       if (len > 0 || len < 3) {
+       if (len > 0 && len < 3) {
                ch = buf[0];
                if (ch == '\n')
                        ch = '0';
index e8f047e86a3292dcaf286a706ff32121665d9f6e..80183a7e6624ab1e42301ae8e6232d851e024bae 100644 (file)
@@ -986,12 +986,6 @@ static int __devinit synaptics_rmi4_probe
        input_set_abs_params(rmi4_data->input_dev, ABS_MT_TOUCH_MAJOR, 0,
                                                MAX_TOUCH_MAJOR, 0, 0);
 
-       retval = input_register_device(rmi4_data->input_dev);
-       if (retval) {
-               dev_err(&client->dev, "%s:input register failed\n", __func__);
-               goto err_input_register;
-       }
-
        /* Clear interrupts */
        synaptics_rmi4_i2c_block_read(rmi4_data,
                        rmi4_data->fn01_data_base_addr + 1, intr_status,
@@ -1003,15 +997,20 @@ static int __devinit synaptics_rmi4_probe
        if (retval) {
                dev_err(&client->dev, "%s:Unable to get attn irq %d\n",
                                __func__, platformdata->irq_number);
-               goto err_request_irq;
+               goto err_unset_clientdata;
+       }
+
+       retval = input_register_device(rmi4_data->input_dev);
+       if (retval) {
+               dev_err(&client->dev, "%s:input register failed\n", __func__);
+               goto err_free_irq;
        }
 
        return retval;
 
-err_request_irq:
+err_free_irq:
        free_irq(platformdata->irq_number, rmi4_data);
-       input_unregister_device(rmi4_data->input_dev);
-err_input_register:
+err_unset_clientdata:
        i2c_set_clientdata(client, NULL);
 err_query_dev:
        if (platformdata->regulator_en) {
index 571864555ddd894c73f2649ca43996b5bf7d77a4..27e0aa81a584b61f16626e788cce3981b0a9f75a 100644 (file)
@@ -949,7 +949,7 @@ func_end:
  *      Calls the Bridge's CHNL_ISR to determine if this interrupt is ours, then
  *      schedules a DPC to dispatch I/O.
  */
-void io_mbox_msg(u32 msg)
+int io_mbox_msg(struct notifier_block *self, unsigned long len, void *msg)
 {
        struct io_mgr *pio_mgr;
        struct dev_object *dev_obj;
@@ -959,9 +959,9 @@ void io_mbox_msg(u32 msg)
        dev_get_io_mgr(dev_obj, &pio_mgr);
 
        if (!pio_mgr)
-               return;
+               return NOTIFY_BAD;
 
-       pio_mgr->intr_val = (u16)msg;
+       pio_mgr->intr_val = (u16)((u32)msg);
        if (pio_mgr->intr_val & MBX_PM_CLASS)
                io_dispatch_pm(pio_mgr);
 
@@ -973,7 +973,7 @@ void io_mbox_msg(u32 msg)
                spin_unlock_irqrestore(&pio_mgr->dpc_lock, flags);
                tasklet_schedule(&pio_mgr->dpc_tasklet);
        }
-       return;
+       return NOTIFY_OK;
 }
 
 /*
index a3b0a183d5704e5052281a313455725e0ef1ced8..a3f69f6f505f8839d0b96c6b9b0055071450ac05 100644 (file)
@@ -223,6 +223,10 @@ static struct bridge_drv_interface drv_interface_fxns = {
        bridge_msg_set_queue_id,
 };
 
+static struct notifier_block dsp_mbox_notifier = {
+       .notifier_call = io_mbox_msg,
+};
+
 static inline void flush_all(struct bridge_dev_context *dev_context)
 {
        if (dev_context->dw_brd_state == BRD_DSP_HIBERNATION ||
@@ -553,7 +557,7 @@ static int bridge_brd_start(struct bridge_dev_context *dev_ctxt,
                 * Enable Mailbox events and also drain any pending
                 * stale messages.
                 */
-               dev_context->mbox = omap_mbox_get("dsp");
+               dev_context->mbox = omap_mbox_get("dsp", &dsp_mbox_notifier);
                if (IS_ERR(dev_context->mbox)) {
                        dev_context->mbox = NULL;
                        pr_err("%s: Failed to get dsp mailbox handle\n",
@@ -563,8 +567,6 @@ static int bridge_brd_start(struct bridge_dev_context *dev_ctxt,
 
        }
        if (!status) {
-               dev_context->mbox->rxq->callback = (int (*)(void *))io_mbox_msg;
-
 /*PM_IVA2GRPSEL_PER = 0xC0;*/
                temp = readl(resources->dw_per_pm_base + 0xA8);
                temp = (temp & 0xFFFFFF30) | 0xC0;
@@ -685,7 +687,7 @@ static int bridge_brd_stop(struct bridge_dev_context *dev_ctxt)
        /* Disable the mailbox interrupts */
        if (dev_context->mbox) {
                omap_mbox_disable_irq(dev_context->mbox, IRQ_RX);
-               omap_mbox_put(dev_context->mbox);
+               omap_mbox_put(dev_context->mbox, &dsp_mbox_notifier);
                dev_context->mbox = NULL;
        }
        /* Reset IVA2 clocks*/
@@ -786,10 +788,7 @@ static int bridge_dev_create(struct bridge_dev_context
 
        pt_attrs = kzalloc(sizeof(struct pg_table_attrs), GFP_KERNEL);
        if (pt_attrs != NULL) {
-               /* Assuming that we use only DSP's memory map
-                * until 0x4000:0000 , we would need only 1024
-                * L1 enties i.e L1 size = 4K */
-               pt_attrs->l1_size = 0x1000;
+               pt_attrs->l1_size = SZ_16K; /* 4096 entries of 32 bits */
                align_size = pt_attrs->l1_size;
                /* Align sizes are expected to be power of 2 */
                /* we like to get aligned on L1 table size */
index 18aec55d8647fdcf3cb33111c7ff1a8f3aca2e78..8242c70e09dd27c0d95a9ce959ba64c91efa1c22 100644 (file)
@@ -72,22 +72,17 @@ extern void io_dpc(unsigned long ref_data);
 /*
  *  ======== io_mbox_msg ========
  *  Purpose:
- *      Main interrupt handler for the shared memory Bridge channel manager.
- *      Calls the Bridge's chnlsm_isr to determine if this interrupt is ours,
- *      then schedules a DPC to dispatch I/O.
+ *     Main message handler for the shared memory Bridge channel manager.
+ *     Determine if this message is ours, then schedules a DPC to
+ *     dispatch I/O.
  *  Parameters:
- *      ref_data:   Pointer to the channel manager object for this board.
- *                  Set in an initial call to ISR_Install().
+ *     self:   Pointer to its own notifier_block struct.
+ *     len:    Length of message.
+ *     msg:    Message code received.
  *  Returns:
- *      TRUE if interrupt handled; FALSE otherwise.
- *  Requires:
- *      Must be in locked memory if executing in kernel mode.
- *      Must only call functions which are in locked memory if Kernel mode.
- *      Must only call asynchronous services.
- *      Interrupts are disabled and EOI for this interrupt has been sent.
- *  Ensures:
+ *     NOTIFY_OK if handled; NOTIFY_BAD otherwise.
  */
-void io_mbox_msg(u32 msg);
+int io_mbox_msg(struct notifier_block *self, unsigned long len, void *msg);
 
 /*
  *  ======== io_request_chnl ========
index 30dbfb6d16f20febb872a60ab882490d9c87abfb..d73267961ef48774cbd8583fbdb1ec0daf7a25e3 100644 (file)
@@ -32,6 +32,7 @@
 
 struct stub_device {
        struct usb_interface *interface;
+       struct usb_device *udev;
        struct list_head list;
 
        struct usbip_device ud;
index b186b5fed2b96b7973388cd337dfce6f5cafc66d..a7ce51cc89099bfc26a8c777d604e1dc623d164e 100644 (file)
@@ -258,10 +258,11 @@ static void stub_shutdown_connection(struct usbip_device *ud)
 static void stub_device_reset(struct usbip_device *ud)
 {
        struct stub_device *sdev = container_of(ud, struct stub_device, ud);
-       struct usb_device *udev = interface_to_usbdev(sdev->interface);
+       struct usb_device *udev = sdev->udev;
        int ret;
 
        usbip_udbg("device reset");
+
        ret = usb_lock_device_for_reset(udev, sdev->interface);
        if (ret < 0) {
                dev_err(&udev->dev, "lock for reset\n");
@@ -309,7 +310,8 @@ static void stub_device_unusable(struct usbip_device *ud)
  *
  * Allocates and initializes a new stub_device struct.
  */
-static struct stub_device *stub_device_alloc(struct usb_interface *interface)
+static struct stub_device *stub_device_alloc(struct usb_device *udev,
+                                            struct usb_interface *interface)
 {
        struct stub_device *sdev;
        int busnum = interface_to_busnum(interface);
@@ -324,7 +326,8 @@ static struct stub_device *stub_device_alloc(struct usb_interface *interface)
                return NULL;
        }
 
-       sdev->interface = interface;
+       sdev->interface = usb_get_intf(interface);
+       sdev->udev = usb_get_dev(udev);
 
        /*
         * devid is defined with devnum when this driver is first allocated.
@@ -450,11 +453,12 @@ static int stub_probe(struct usb_interface *interface,
                        return err;
                }
 
+               usb_get_intf(interface);
                return 0;
        }
 
        /* ok. this is my device. */
-       sdev = stub_device_alloc(interface);
+       sdev = stub_device_alloc(udev, interface);
        if (!sdev)
                return -ENOMEM;
 
@@ -476,6 +480,8 @@ static int stub_probe(struct usb_interface *interface,
                dev_err(&interface->dev, "create sysfs files for %s\n",
                        udev_busid);
                usb_set_intfdata(interface, NULL);
+               usb_put_intf(interface);
+
                busid_priv->interf_count = 0;
 
                busid_priv->sdev = NULL;
@@ -545,6 +551,7 @@ static void stub_disconnect(struct usb_interface *interface)
        if (busid_priv->interf_count > 1) {
                busid_priv->interf_count--;
                shutdown_busid(busid_priv);
+               usb_put_intf(interface);
                return;
        }
 
@@ -554,6 +561,9 @@ static void stub_disconnect(struct usb_interface *interface)
        /* 1. shutdown the current connection */
        shutdown_busid(busid_priv);
 
+       usb_put_dev(sdev->udev);
+       usb_put_intf(interface);
+
        /* 3. free sdev */
        busid_priv->sdev = NULL;
        stub_device_free(sdev);
index 3de6fd2539dcb65efa74d25040f25cf9c22beb6e..ae6ac82754a4dd1296071037dac674f713de618f 100644 (file)
@@ -364,7 +364,7 @@ static struct stub_priv *stub_priv_alloc(struct stub_device *sdev,
 
 static int get_pipe(struct stub_device *sdev, int epnum, int dir)
 {
-       struct usb_device *udev = interface_to_usbdev(sdev->interface);
+       struct usb_device *udev = sdev->udev;
        struct usb_host_endpoint *ep;
        struct usb_endpoint_descriptor *epd = NULL;
 
@@ -484,7 +484,7 @@ static void stub_recv_cmd_submit(struct stub_device *sdev,
        int ret;
        struct stub_priv *priv;
        struct usbip_device *ud = &sdev->ud;
-       struct usb_device *udev = interface_to_usbdev(sdev->interface);
+       struct usb_device *udev = sdev->udev;
        int pipe = get_pipe(sdev, pdu->base.ep, pdu->base.direction);
 
 
index 41a1fe5138f4e020c13683e59e362ecdc38b5be9..afc3b1a7188199bf29496fbb6e9933d6f3d37952 100644 (file)
@@ -100,9 +100,6 @@ struct vhci_hcd {
         * But, the index of this array begins from 0.
         */
        struct vhci_device vdev[VHCI_NPORTS];
-
-       /* vhci_device which has not been assiged its address yet */
-       int pending_port;
 };
 
 
@@ -119,6 +116,9 @@ void rh_port_disconnect(int rhport);
 void vhci_rx_loop(struct usbip_task *ut);
 void vhci_tx_loop(struct usbip_task *ut);
 
+struct urb *pickup_urb_and_free_priv(struct vhci_device *vdev,
+                                           __u32 seqnum);
+
 #define hardware               (&the_controller->pdev.dev)
 
 static inline struct vhci_device *port_to_vdev(__u32 port)
index 08bd26a245d50f6a74c9b2a47797e739b6fbbfaa..a35fe61268de3e974f8ece7f2edb0bd1e28b0468 100644 (file)
@@ -138,8 +138,6 @@ void rh_port_connect(int rhport, enum usb_device_speed speed)
         * the_controller->vdev[rhport].ud.status = VDEV_CONNECT;
         * spin_unlock(&the_controller->vdev[rhport].ud.lock); */
 
-       the_controller->pending_port = rhport;
-
        spin_unlock_irqrestore(&the_controller->lock, flags);
 
        usb_hcd_poll_rh_status(vhci_to_hcd(the_controller));
@@ -559,6 +557,7 @@ static int vhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb,
        struct device *dev = &urb->dev->dev;
        int ret = 0;
        unsigned long flags;
+       struct vhci_device *vdev;
 
        usbip_dbg_vhci_hc("enter, usb_hcd %p urb %p mem_flags %d\n",
                    hcd, urb, mem_flags);
@@ -574,6 +573,18 @@ static int vhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb,
                return urb->status;
        }
 
+       vdev = port_to_vdev(urb->dev->portnum-1);
+
+       /* refuse enqueue for dead connection */
+       spin_lock(&vdev->ud.lock);
+       if (vdev->ud.status == VDEV_ST_NULL || vdev->ud.status == VDEV_ST_ERROR) {
+               usbip_uerr("enqueue for inactive port %d\n", vdev->rhport);
+               spin_unlock(&vdev->ud.lock);
+               spin_unlock_irqrestore(&the_controller->lock, flags);
+               return -ENODEV;
+       }
+       spin_unlock(&vdev->ud.lock);
+
        ret = usb_hcd_link_urb_to_ep(hcd, urb);
        if (ret)
                goto no_need_unlink;
@@ -592,8 +603,6 @@ static int vhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb,
                __u8 type = usb_pipetype(urb->pipe);
                struct usb_ctrlrequest *ctrlreq =
                                (struct usb_ctrlrequest *) urb->setup_packet;
-               struct vhci_device *vdev =
-                               port_to_vdev(the_controller->pending_port);
 
                if (type != PIPE_CONTROL || !ctrlreq) {
                        dev_err(dev, "invalid request to devnum 0\n");
@@ -607,7 +616,9 @@ static int vhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb,
                        dev_info(dev, "SetAddress Request (%d) to port %d\n",
                                 ctrlreq->wValue, vdev->rhport);
 
-                       vdev->udev = urb->dev;
+                       if (vdev->udev)
+                               usb_put_dev(vdev->udev);
+                       vdev->udev = usb_get_dev(urb->dev);
 
                        spin_lock(&vdev->ud.lock);
                        vdev->ud.status = VDEV_ST_USED;
@@ -627,8 +638,9 @@ static int vhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb,
                                                "Get_Descriptor to device 0 "
                                                "(get max pipe size)\n");
 
-                       /* FIXME: reference count? (usb_get_dev()) */
-                       vdev->udev = urb->dev;
+                       if (vdev->udev)
+                               usb_put_dev(vdev->udev);
+                       vdev->udev = usb_get_dev(urb->dev);
                        goto out;
 
                default:
@@ -805,7 +817,6 @@ static int vhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
        return 0;
 }
 
-
 static void vhci_device_unlink_cleanup(struct vhci_device *vdev)
 {
        struct vhci_unlink *unlink, *tmp;
@@ -813,11 +824,34 @@ static void vhci_device_unlink_cleanup(struct vhci_device *vdev)
        spin_lock(&vdev->priv_lock);
 
        list_for_each_entry_safe(unlink, tmp, &vdev->unlink_tx, list) {
+               usbip_uinfo("unlink cleanup tx %lu\n", unlink->unlink_seqnum);
                list_del(&unlink->list);
                kfree(unlink);
        }
 
        list_for_each_entry_safe(unlink, tmp, &vdev->unlink_rx, list) {
+               struct urb *urb;
+
+               /* give back URB of unanswered unlink request */
+               usbip_uinfo("unlink cleanup rx %lu\n", unlink->unlink_seqnum);
+
+               urb = pickup_urb_and_free_priv(vdev, unlink->unlink_seqnum);
+               if (!urb) {
+                       usbip_uinfo("the urb (seqnum %lu) was already given back\n",
+                                                       unlink->unlink_seqnum);
+                       list_del(&unlink->list);
+                       kfree(unlink);
+                       continue;
+               }
+
+               urb->status = -ENODEV;
+
+               spin_lock(&the_controller->lock);
+               usb_hcd_unlink_urb_from_ep(vhci_to_hcd(the_controller), urb);
+               spin_unlock(&the_controller->lock);
+
+               usb_hcd_giveback_urb(vhci_to_hcd(the_controller), urb, urb->status);
+
                list_del(&unlink->list);
                kfree(unlink);
        }
@@ -887,6 +921,10 @@ static void vhci_device_reset(struct usbip_device *ud)
        vdev->speed  = 0;
        vdev->devid  = 0;
 
+       if (vdev->udev)
+               usb_put_dev(vdev->udev);
+       vdev->udev = NULL;
+
        ud->tcp_socket = NULL;
 
        ud->status = VDEV_ST_NULL;
index 8147d7202b2dc092e8986891baaf463e6e3f1bf3..bf69914709410cf054825933a638b7dd7060180a 100644 (file)
 #include "vhci.h"
 
 
-/* get URB from transmitted urb queue */
-static struct urb *pickup_urb_and_free_priv(struct vhci_device *vdev,
+/* get URB from transmitted urb queue. caller must hold vdev->priv_lock */
+struct urb *pickup_urb_and_free_priv(struct vhci_device *vdev,
                                            __u32 seqnum)
 {
        struct vhci_priv *priv, *tmp;
        struct urb *urb = NULL;
        int status;
 
-       spin_lock(&vdev->priv_lock);
-
        list_for_each_entry_safe(priv, tmp, &vdev->priv_rx, list) {
                if (priv->seqnum == seqnum) {
                        urb = priv->urb;
@@ -63,8 +61,6 @@ static struct urb *pickup_urb_and_free_priv(struct vhci_device *vdev,
                }
        }
 
-       spin_unlock(&vdev->priv_lock);
-
        return urb;
 }
 
@@ -74,9 +70,11 @@ static void vhci_recv_ret_submit(struct vhci_device *vdev,
        struct usbip_device *ud = &vdev->ud;
        struct urb *urb;
 
+       spin_lock(&vdev->priv_lock);
 
        urb = pickup_urb_and_free_priv(vdev, pdu->base.seqnum);
 
+       spin_unlock(&vdev->priv_lock);
 
        if (!urb) {
                usbip_uerr("cannot find a urb of seqnum %u\n",
@@ -161,7 +159,12 @@ static void vhci_recv_ret_unlink(struct vhci_device *vdev,
                return;
        }
 
+       spin_lock(&vdev->priv_lock);
+
        urb = pickup_urb_and_free_priv(vdev, unlink->unlink_seqnum);
+
+       spin_unlock(&vdev->priv_lock);
+
        if (!urb) {
                /*
                 * I get the result of a unlink request. But, it seems that I
@@ -190,6 +193,19 @@ static void vhci_recv_ret_unlink(struct vhci_device *vdev,
        return;
 }
 
+static int vhci_priv_tx_empty(struct vhci_device *vdev)
+{
+       int empty = 0;
+
+       spin_lock(&vdev->priv_lock);
+
+       empty = list_empty(&vdev->priv_rx);
+
+       spin_unlock(&vdev->priv_lock);
+
+       return empty;
+}
+
 /* recv a pdu */
 static void vhci_rx_pdu(struct usbip_device *ud)
 {
@@ -202,11 +218,29 @@ static void vhci_rx_pdu(struct usbip_device *ud)
 
        memset(&pdu, 0, sizeof(pdu));
 
-
        /* 1. receive a pdu header */
        ret = usbip_xmit(0, ud->tcp_socket, (char *) &pdu, sizeof(pdu), 0);
+       if (ret < 0) {
+               if (ret == -ECONNRESET)
+                       usbip_uinfo("connection reset by peer\n");
+               else if (ret == -EAGAIN) {
+                       /* ignore if connection was idle */
+                       if (vhci_priv_tx_empty(vdev))
+                               return;
+                       usbip_uinfo("connection timed out with pending urbs\n");
+               } else if (ret != -ERESTARTSYS)
+                       usbip_uinfo("xmit failed %d\n", ret);
+
+               usbip_event_add(ud, VDEV_EVENT_ERROR_TCP);
+               return;
+       }
+       if (ret == 0) {
+               usbip_uinfo("connection closed");
+               usbip_event_add(ud, VDEV_EVENT_DOWN);
+               return;
+       }
        if (ret != sizeof(pdu)) {
-               usbip_uerr("receiving pdu failed! size is %d, should be %d\n",
+               usbip_uerr("received pdu size is %d, should be %d\n",
                                        ret, (unsigned int)sizeof(pdu));
                usbip_event_add(ud, VDEV_EVENT_ERROR_TCP);
                return;
diff --git a/drivers/staging/vme/bridges/Module.symvers b/drivers/staging/vme/bridges/Module.symvers
deleted file mode 100644 (file)
index e69de29..0000000
index 7016fdd2509f5ce83e6bc29acd6b01ffcb9316c3..e19b932492e1e5443b916c210a0c261e6af61c2f 100644 (file)
@@ -3954,8 +3954,8 @@ void XGI_GetCRT2ResInfo(unsigned short ModeNo, unsigned short ModeIdIndex,
 unsigned char XGI_IsLCDDualLink(struct vb_device_info *pVBInfo)
 {
 
-       if ((((pVBInfo->VBInfo & SetCRT2ToLCD) | SetCRT2ToLCDA))
-                       && (pVBInfo->LCDInfo & SetLCDDualLink)) /* shampoo0129 */
+       if ((pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) &&
+                       (pVBInfo->LCDInfo & SetLCDDualLink)) /* shampoo0129 */
                return 1;
 
        return 0;
@@ -8773,7 +8773,7 @@ unsigned short XGI_GetVCLK2Ptr(unsigned short ModeNo,
 
        if (pVBInfo->IF_DEF_LVDS == 0) {
                CRT2Index = CRT2Index >> 6; /*  for LCD */
-               if (((pVBInfo->VBInfo & SetCRT2ToLCD) | SetCRT2ToLCDA)) { /*301b*/
+               if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { /*301b*/
                        if (pVBInfo->LCDResInfo != Panel1024x768)
                                VCLKIndex = LCDXlat2VCLK[CRT2Index];
                        else
index 47d32281032c75322b1181c65ab710f00b7967c6..52fc0c9a6364e05edc80e8bdf4e4d28250f9a754 100644 (file)
@@ -581,8 +581,9 @@ static ssize_t n_hdlc_tty_read(struct tty_struct *tty, struct file *file,
                           __u8 __user *buf, size_t nr)
 {
        struct n_hdlc *n_hdlc = tty2n_hdlc(tty);
-       int ret;
+       int ret = 0;
        struct n_hdlc_buf *rbuf;
+       DECLARE_WAITQUEUE(wait, current);
 
        if (debuglevel >= DEBUG_LEVEL_INFO)     
                printk("%s(%d)n_hdlc_tty_read() called\n",__FILE__,__LINE__);
@@ -598,57 +599,55 @@ static ssize_t n_hdlc_tty_read(struct tty_struct *tty, struct file *file,
                return -EFAULT;
        }
 
-       tty_lock();
+       add_wait_queue(&tty->read_wait, &wait);
 
        for (;;) {
                if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) {
-                       tty_unlock();
-                       return -EIO;
+                       ret = -EIO;
+                       break;
                }
+               if (tty_hung_up_p(file))
+                       break;
 
-               n_hdlc = tty2n_hdlc (tty);
-               if (!n_hdlc || n_hdlc->magic != HDLC_MAGIC ||
-                        tty != n_hdlc->tty) {
-                       tty_unlock();
-                       return 0;
-               }
+               set_current_state(TASK_INTERRUPTIBLE);
 
                rbuf = n_hdlc_buf_get(&n_hdlc->rx_buf_list);
-               if (rbuf)
+               if (rbuf) {
+                       if (rbuf->count > nr) {
+                               /* too large for caller's buffer */
+                               ret = -EOVERFLOW;
+                       } else {
+                               if (copy_to_user(buf, rbuf->buf, rbuf->count))
+                                       ret = -EFAULT;
+                               else
+                                       ret = rbuf->count;
+                       }
+
+                       if (n_hdlc->rx_free_buf_list.count >
+                           DEFAULT_RX_BUF_COUNT)
+                               kfree(rbuf);
+                       else
+                               n_hdlc_buf_put(&n_hdlc->rx_free_buf_list, rbuf);
                        break;
+               }
                        
                /* no data */
                if (file->f_flags & O_NONBLOCK) {
-                       tty_unlock();
-                       return -EAGAIN;
+                       ret = -EAGAIN;
+                       break;
                }
-                       
-               interruptible_sleep_on (&tty->read_wait);
+
+               schedule();
+
                if (signal_pending(current)) {
-                       tty_unlock();
-                       return -EINTR;
+                       ret = -EINTR;
+                       break;
                }
        }
-               
-       if (rbuf->count > nr)
-               /* frame too large for caller's buffer (discard frame) */
-               ret = -EOVERFLOW;
-       else {
-               /* Copy the data to the caller's buffer */
-               if (copy_to_user(buf, rbuf->buf, rbuf->count))
-                       ret = -EFAULT;
-               else
-                       ret = rbuf->count;
-       }
-       
-       /* return HDLC buffer to free list unless the free list */
-       /* count has exceeded the default value, in which case the */
-       /* buffer is freed back to the OS to conserve memory */
-       if (n_hdlc->rx_free_buf_list.count > DEFAULT_RX_BUF_COUNT)
-               kfree(rbuf);
-       else    
-               n_hdlc_buf_put(&n_hdlc->rx_free_buf_list,rbuf);
-       tty_unlock();
+
+       remove_wait_queue(&tty->read_wait, &wait);
+       __set_current_state(TASK_RUNNING);
+
        return ret;
        
 }      /* end of n_hdlc_tty_read() */
@@ -691,14 +690,15 @@ static ssize_t n_hdlc_tty_write(struct tty_struct *tty, struct file *file,
                count = maxframe;
        }
        
-       tty_lock();
-
        add_wait_queue(&tty->write_wait, &wait);
-       set_current_state(TASK_INTERRUPTIBLE);
+
+       for (;;) {
+               set_current_state(TASK_INTERRUPTIBLE);
        
-       /* Allocate transmit buffer */
-       /* sleep until transmit buffer available */             
-       while (!(tbuf = n_hdlc_buf_get(&n_hdlc->tx_free_buf_list))) {
+               tbuf = n_hdlc_buf_get(&n_hdlc->tx_free_buf_list);
+               if (tbuf)
+                       break;
+
                if (file->f_flags & O_NONBLOCK) {
                        error = -EAGAIN;
                        break;
@@ -719,7 +719,7 @@ static ssize_t n_hdlc_tty_write(struct tty_struct *tty, struct file *file,
                }
        }
 
-       set_current_state(TASK_RUNNING);
+       __set_current_state(TASK_RUNNING);
        remove_wait_queue(&tty->write_wait, &wait);
 
        if (!error) {           
@@ -731,7 +731,7 @@ static ssize_t n_hdlc_tty_write(struct tty_struct *tty, struct file *file,
                n_hdlc_buf_put(&n_hdlc->tx_buf_list,tbuf);
                n_hdlc_send_frames(n_hdlc,tty);
        }
-       tty_unlock();
+
        return error;
        
 }      /* end of n_hdlc_tty_write() */
index b25e6e490530d006ab1b465c53e74753d0be5dc7..3975df6f7fdba6f4bff57f9c7fa05a8ae1bbeadf 100644 (file)
@@ -236,7 +236,8 @@ static const struct serial8250_config uart_config[] = {
                .fifo_size      = 128,
                .tx_loadsz      = 128,
                .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
-               .flags          = UART_CAP_FIFO | UART_CAP_EFR | UART_CAP_SLEEP,
+               /* UART_CAP_EFR breaks billionon CF bluetooth card. */
+               .flags          = UART_CAP_FIFO | UART_CAP_SLEEP,
        },
        [PORT_16654] = {
                .name           = "ST16654",
index b1682d7f1d8a2492ad59aea18622cb4294b71813..2b8334601c8b586b957168906f7eb490c1ee8f57 100644 (file)
@@ -1518,6 +1518,7 @@ config SERIAL_BCM63XX_CONSOLE
 config SERIAL_GRLIB_GAISLER_APBUART
        tristate "GRLIB APBUART serial support"
        depends on OF
+       select SERIAL_CORE
        ---help---
        Add support for the GRLIB APBUART serial port.
 
index a2f2b3254499db91428d80934d1811690872e94e..602d9845c52ffa97c00951ad395e504af602cf83 100644 (file)
@@ -829,7 +829,7 @@ static void __init sbd_probe_duarts(void)
 #ifdef CONFIG_SERIAL_SB1250_DUART_CONSOLE
 /*
  * Serial console stuff.  Very basic, polling driver for doing serial
- * console output.  The console_sem is held by the caller, so we
+ * console output.  The console_lock is held by the caller, so we
  * shouldn't be interrupted for more console activity.
  */
 static void sbd_console_putchar(struct uart_port *uport, int ch)
index c556ed9db13d82a4bd7dcff1bb599dce6abd8341..8e0dd254eb11cf3d9f503c7bda32bcb3e75ba09d 100644 (file)
@@ -46,7 +46,7 @@
 #include <asm/irq_regs.h>
 
 /* Whether we react on sysrq keys or just ignore them */
-static int __read_mostly sysrq_enabled = 1;
+static int __read_mostly sysrq_enabled = SYSRQ_DEFAULT_ENABLE;
 static bool __read_mostly sysrq_always_enabled;
 
 static bool sysrq_on(void)
index 464d09d97873dd535df3d9ce9b481be7fa98db55..0065da4b11c1a89eefba4d6c3ac17abb25c9a41d 100644 (file)
@@ -3256,8 +3256,8 @@ static ssize_t show_cons_active(struct device *dev,
        struct console *c;
        ssize_t count = 0;
 
-       acquire_console_sem();
-       for (c = console_drivers; c; c = c->next) {
+       console_lock();
+       for_each_console(c) {
                if (!c->device)
                        continue;
                if (!c->write)
@@ -3271,7 +3271,7 @@ static ssize_t show_cons_active(struct device *dev,
        while (i--)
                count += sprintf(buf + count, "%s%d%c",
                                 cs[i]->name, cs[i]->index, i ? ' ':'\n');
-       release_console_sem();
+       console_unlock();
 
        return count;
 }
@@ -3306,7 +3306,7 @@ int __init tty_init(void)
        if (IS_ERR(consdev))
                consdev = NULL;
        else
-               device_create_file(consdev, &dev_attr_active);
+               WARN_ON(device_create_file(consdev, &dev_attr_active) < 0);
 
 #ifdef CONFIG_VT
        vty_init(&console_fops);
index ebae344ce910443b9d40d4bab4ca1158b910a4bf..c956ed6c83a3b9387936d480e6ea5e2dfe9085ff 100644 (file)
@@ -316,9 +316,9 @@ int paste_selection(struct tty_struct *tty)
        /* always called with BTM from vt_ioctl */
        WARN_ON(!tty_locked());
 
-       acquire_console_sem();
+       console_lock();
        poke_blanked_console();
-       release_console_sem();
+       console_unlock();
 
        ld = tty_ldisc_ref(tty);
        if (!ld) {
index eab3a1ff99e43c2468d35a3c770154e80a9bf7cd..a672ed192d33b038a9e28033d5f526e320ce9504 100644 (file)
@@ -202,7 +202,7 @@ vcs_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
        /* Select the proper current console and verify
         * sanity of the situation under the console lock.
         */
-       acquire_console_sem();
+       console_lock();
 
        attr = (currcons & 128);
        currcons = (currcons & 127);
@@ -336,9 +336,9 @@ vcs_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
                 * the pagefault handling code may want to call printk().
                 */
 
-               release_console_sem();
+               console_unlock();
                ret = copy_to_user(buf, con_buf_start, orig_count);
-               acquire_console_sem();
+               console_lock();
 
                if (ret) {
                        read += (orig_count - ret);
@@ -354,7 +354,7 @@ vcs_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
        if (read)
                ret = read;
 unlock_out:
-       release_console_sem();
+       console_unlock();
        mutex_unlock(&con_buf_mtx);
        return ret;
 }
@@ -379,7 +379,7 @@ vcs_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
        /* Select the proper current console and verify
         * sanity of the situation under the console lock.
         */
-       acquire_console_sem();
+       console_lock();
 
        attr = (currcons & 128);
        currcons = (currcons & 127);
@@ -414,9 +414,9 @@ vcs_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
                /* Temporarily drop the console lock so that we can read
                 * in the write data from userspace safely.
                 */
-               release_console_sem();
+               console_unlock();
                ret = copy_from_user(con_buf, buf, this_round);
-               acquire_console_sem();
+               console_lock();
 
                if (ret) {
                        this_round -= ret;
@@ -542,7 +542,7 @@ vcs_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
                vcs_scr_updated(vc);
 
 unlock_out:
-       release_console_sem();
+       console_unlock();
 
        mutex_unlock(&con_buf_mtx);
 
index 76407eca9ab0101567df390b39ea03b1b50e3d58..147ede3423df6228c781c39100a42937e6437f33 100644 (file)
@@ -1003,9 +1003,9 @@ static int vt_resize(struct tty_struct *tty, struct winsize *ws)
        struct vc_data *vc = tty->driver_data;
        int ret;
 
-       acquire_console_sem();
+       console_lock();
        ret = vc_do_resize(tty, vc, ws->ws_col, ws->ws_row);
-       release_console_sem();
+       console_unlock();
        return ret;
 }
 
@@ -1271,7 +1271,7 @@ static void default_attr(struct vc_data *vc)
        vc->vc_color = vc->vc_def_color;
 }
 
-/* console_sem is held */
+/* console_lock is held */
 static void csi_m(struct vc_data *vc)
 {
        int i;
@@ -1415,7 +1415,7 @@ int mouse_reporting(void)
        return vc_cons[fg_console].d->vc_report_mouse;
 }
 
-/* console_sem is held */
+/* console_lock is held */
 static void set_mode(struct vc_data *vc, int on_off)
 {
        int i;
@@ -1485,7 +1485,7 @@ static void set_mode(struct vc_data *vc, int on_off)
                }
 }
 
-/* console_sem is held */
+/* console_lock is held */
 static void setterm_command(struct vc_data *vc)
 {
        switch(vc->vc_par[0]) {
@@ -1545,7 +1545,7 @@ static void setterm_command(struct vc_data *vc)
        }
 }
 
-/* console_sem is held */
+/* console_lock is held */
 static void csi_at(struct vc_data *vc, unsigned int nr)
 {
        if (nr > vc->vc_cols - vc->vc_x)
@@ -1555,7 +1555,7 @@ static void csi_at(struct vc_data *vc, unsigned int nr)
        insert_char(vc, nr);
 }
 
-/* console_sem is held */
+/* console_lock is held */
 static void csi_L(struct vc_data *vc, unsigned int nr)
 {
        if (nr > vc->vc_rows - vc->vc_y)
@@ -1566,7 +1566,7 @@ static void csi_L(struct vc_data *vc, unsigned int nr)
        vc->vc_need_wrap = 0;
 }
 
-/* console_sem is held */
+/* console_lock is held */
 static void csi_P(struct vc_data *vc, unsigned int nr)
 {
        if (nr > vc->vc_cols - vc->vc_x)
@@ -1576,7 +1576,7 @@ static void csi_P(struct vc_data *vc, unsigned int nr)
        delete_char(vc, nr);
 }
 
-/* console_sem is held */
+/* console_lock is held */
 static void csi_M(struct vc_data *vc, unsigned int nr)
 {
        if (nr > vc->vc_rows - vc->vc_y)
@@ -1587,7 +1587,7 @@ static void csi_M(struct vc_data *vc, unsigned int nr)
        vc->vc_need_wrap = 0;
 }
 
-/* console_sem is held (except via vc_init->reset_terminal */
+/* console_lock is held (except via vc_init->reset_terminal */
 static void save_cur(struct vc_data *vc)
 {
        vc->vc_saved_x          = vc->vc_x;
@@ -1603,7 +1603,7 @@ static void save_cur(struct vc_data *vc)
        vc->vc_saved_G1         = vc->vc_G1_charset;
 }
 
-/* console_sem is held */
+/* console_lock is held */
 static void restore_cur(struct vc_data *vc)
 {
        gotoxy(vc, vc->vc_saved_x, vc->vc_saved_y);
@@ -1625,7 +1625,7 @@ enum { ESnormal, ESesc, ESsquare, ESgetpars, ESgotpars, ESfunckey,
        EShash, ESsetG0, ESsetG1, ESpercent, ESignore, ESnonstd,
        ESpalette };
 
-/* console_sem is held (except via vc_init()) */
+/* console_lock is held (except via vc_init()) */
 static void reset_terminal(struct vc_data *vc, int do_clear)
 {
        vc->vc_top              = 0;
@@ -1685,7 +1685,7 @@ static void reset_terminal(struct vc_data *vc, int do_clear)
            csi_J(vc, 2);
 }
 
-/* console_sem is held */
+/* console_lock is held */
 static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c)
 {
        /*
@@ -2119,7 +2119,7 @@ static int is_double_width(uint32_t ucs)
        return bisearch(ucs, double_width, ARRAY_SIZE(double_width) - 1);
 }
 
-/* acquires console_sem */
+/* acquires console_lock */
 static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int count)
 {
 #ifdef VT_BUF_VRAM_ONLY
@@ -2147,11 +2147,11 @@ static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int co
 
        might_sleep();
 
-       acquire_console_sem();
+       console_lock();
        vc = tty->driver_data;
        if (vc == NULL) {
                printk(KERN_ERR "vt: argh, driver_data is NULL !\n");
-               release_console_sem();
+               console_unlock();
                return 0;
        }
 
@@ -2159,7 +2159,7 @@ static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int co
        if (!vc_cons_allocated(currcons)) {
            /* could this happen? */
                printk_once("con_write: tty %d not allocated\n", currcons+1);
-           release_console_sem();
+           console_unlock();
            return 0;
        }
 
@@ -2375,7 +2375,7 @@ rescan_last_byte:
        }
        FLUSH
        console_conditional_schedule();
-       release_console_sem();
+       console_unlock();
        notify_update(vc);
        return n;
 #undef FLUSH
@@ -2388,11 +2388,11 @@ rescan_last_byte:
  * us to do the switches asynchronously (needed when we want
  * to switch due to a keyboard interrupt).  Synchronization
  * with other console code and prevention of re-entrancy is
- * ensured with console_sem.
+ * ensured with console_lock.
  */
 static void console_callback(struct work_struct *ignored)
 {
-       acquire_console_sem();
+       console_lock();
 
        if (want_console >= 0) {
                if (want_console != fg_console &&
@@ -2422,7 +2422,7 @@ static void console_callback(struct work_struct *ignored)
        }
        notify_update(vc_cons[fg_console].d);
 
-       release_console_sem();
+       console_unlock();
 }
 
 int set_console(int nr)
@@ -2603,7 +2603,7 @@ static struct console vt_console_driver = {
  */
 
 /*
- * Generally a bit racy with respect to console_sem().
+ * Generally a bit racy with respect to console_lock();.
  *
  * There are some functions which don't need it.
  *
@@ -2629,17 +2629,17 @@ int tioclinux(struct tty_struct *tty, unsigned long arg)
        switch (type)
        {
                case TIOCL_SETSEL:
-                       acquire_console_sem();
+                       console_lock();
                        ret = set_selection((struct tiocl_selection __user *)(p+1), tty);
-                       release_console_sem();
+                       console_unlock();
                        break;
                case TIOCL_PASTESEL:
                        ret = paste_selection(tty);
                        break;
                case TIOCL_UNBLANKSCREEN:
-                       acquire_console_sem();
+                       console_lock();
                        unblank_screen();
-                       release_console_sem();
+                       console_unlock();
                        break;
                case TIOCL_SELLOADLUT:
                        ret = sel_loadlut(p);
@@ -2688,10 +2688,10 @@ int tioclinux(struct tty_struct *tty, unsigned long arg)
                        }
                        break;
                case TIOCL_BLANKSCREEN: /* until explicitly unblanked, not only poked */
-                       acquire_console_sem();
+                       console_lock();
                        ignore_poke = 1;
                        do_blank_screen(0);
-                       release_console_sem();
+                       console_unlock();
                        break;
                case TIOCL_BLANKEDSCREEN:
                        ret = console_blanked;
@@ -2790,11 +2790,11 @@ static void con_flush_chars(struct tty_struct *tty)
                return;
 
        /* if we race with con_close(), vt may be null */
-       acquire_console_sem();
+       console_lock();
        vc = tty->driver_data;
        if (vc)
                set_cursor(vc);
-       release_console_sem();
+       console_unlock();
 }
 
 /*
@@ -2805,7 +2805,7 @@ static int con_open(struct tty_struct *tty, struct file *filp)
        unsigned int currcons = tty->index;
        int ret = 0;
 
-       acquire_console_sem();
+       console_lock();
        if (tty->driver_data == NULL) {
                ret = vc_allocate(currcons);
                if (ret == 0) {
@@ -2813,7 +2813,7 @@ static int con_open(struct tty_struct *tty, struct file *filp)
 
                        /* Still being freed */
                        if (vc->port.tty) {
-                               release_console_sem();
+                               console_unlock();
                                return -ERESTARTSYS;
                        }
                        tty->driver_data = vc;
@@ -2827,11 +2827,11 @@ static int con_open(struct tty_struct *tty, struct file *filp)
                                tty->termios->c_iflag |= IUTF8;
                        else
                                tty->termios->c_iflag &= ~IUTF8;
-                       release_console_sem();
+                       console_unlock();
                        return ret;
                }
        }
-       release_console_sem();
+       console_unlock();
        return ret;
 }
 
@@ -2844,9 +2844,9 @@ static void con_shutdown(struct tty_struct *tty)
 {
        struct vc_data *vc = tty->driver_data;
        BUG_ON(vc == NULL);
-       acquire_console_sem();
+       console_lock();
        vc->port.tty = NULL;
-       release_console_sem();
+       console_unlock();
        tty_shutdown(tty);
 }
 
@@ -2893,13 +2893,13 @@ static int __init con_init(void)
        struct vc_data *vc;
        unsigned int currcons = 0, i;
 
-       acquire_console_sem();
+       console_lock();
 
        if (conswitchp)
                display_desc = conswitchp->con_startup();
        if (!display_desc) {
                fg_console = 0;
-               release_console_sem();
+               console_unlock();
                return 0;
        }
 
@@ -2946,7 +2946,7 @@ static int __init con_init(void)
        printable = 1;
        printk("\n");
 
-       release_console_sem();
+       console_unlock();
 
 #ifdef CONFIG_VT_CONSOLE
        register_console(&vt_console_driver);
@@ -2994,7 +2994,7 @@ int __init vty_init(const struct file_operations *console_fops)
        if (IS_ERR(tty0dev))
                tty0dev = NULL;
        else
-               device_create_file(tty0dev, &dev_attr_active);
+               WARN_ON(device_create_file(tty0dev, &dev_attr_active) < 0);
 
        vcs_init();
 
@@ -3037,7 +3037,7 @@ static int bind_con_driver(const struct consw *csw, int first, int last,
        if (!try_module_get(owner))
                return -ENODEV;
 
-       acquire_console_sem();
+       console_lock();
 
        /* check if driver is registered */
        for (i = 0; i < MAX_NR_CON_DRIVER; i++) {
@@ -3122,7 +3122,7 @@ static int bind_con_driver(const struct consw *csw, int first, int last,
 
        retval = 0;
 err:
-       release_console_sem();
+       console_unlock();
        module_put(owner);
        return retval;
 };
@@ -3171,7 +3171,7 @@ int unbind_con_driver(const struct consw *csw, int first, int last, int deflt)
        if (!try_module_get(owner))
                return -ENODEV;
 
-       acquire_console_sem();
+       console_lock();
 
        /* check if driver is registered and if it is unbindable */
        for (i = 0; i < MAX_NR_CON_DRIVER; i++) {
@@ -3185,7 +3185,7 @@ int unbind_con_driver(const struct consw *csw, int first, int last, int deflt)
        }
 
        if (retval) {
-               release_console_sem();
+               console_unlock();
                goto err;
        }
 
@@ -3204,12 +3204,12 @@ int unbind_con_driver(const struct consw *csw, int first, int last, int deflt)
        }
 
        if (retval) {
-               release_console_sem();
+               console_unlock();
                goto err;
        }
 
        if (!con_is_bound(csw)) {
-               release_console_sem();
+               console_unlock();
                goto err;
        }
 
@@ -3238,7 +3238,7 @@ int unbind_con_driver(const struct consw *csw, int first, int last, int deflt)
        if (!con_is_bound(csw))
                con_driver->flag &= ~CON_DRIVER_FLAG_INIT;
 
-       release_console_sem();
+       console_unlock();
        /* ignore return value, binding should not fail */
        bind_con_driver(defcsw, first, last, deflt);
 err:
@@ -3538,14 +3538,14 @@ int register_con_driver(const struct consw *csw, int first, int last)
        if (!try_module_get(owner))
                return -ENODEV;
 
-       acquire_console_sem();
+       console_lock();
 
        for (i = 0; i < MAX_NR_CON_DRIVER; i++) {
                con_driver = &registered_con_driver[i];
 
                /* already registered */
                if (con_driver->con == csw)
-                       retval = -EINVAL;
+                       retval = -EBUSY;
        }
 
        if (retval)
@@ -3592,7 +3592,7 @@ int register_con_driver(const struct consw *csw, int first, int last)
        }
 
 err:
-       release_console_sem();
+       console_unlock();
        module_put(owner);
        return retval;
 }
@@ -3613,7 +3613,7 @@ int unregister_con_driver(const struct consw *csw)
 {
        int i, retval = -ENODEV;
 
-       acquire_console_sem();
+       console_lock();
 
        /* cannot unregister a bound driver */
        if (con_is_bound(csw))
@@ -3639,7 +3639,7 @@ int unregister_con_driver(const struct consw *csw)
                }
        }
 err:
-       release_console_sem();
+       console_unlock();
        return retval;
 }
 EXPORT_SYMBOL(unregister_con_driver);
@@ -3656,7 +3656,12 @@ int take_over_console(const struct consw *csw, int first, int last, int deflt)
        int err;
 
        err = register_con_driver(csw, first, last);
-
+       /* if we get an busy error we still want to bind the console driver
+        * and return success, as we may have unbound the console driver
+       Â * but not unregistered it.
+       */
+       if (err == -EBUSY)
+               err = 0;
        if (!err)
                bind_con_driver(csw, first, last, deflt);
 
@@ -3934,9 +3939,9 @@ int con_set_cmap(unsigned char __user *arg)
 {
        int rc;
 
-       acquire_console_sem();
+       console_lock();
        rc = set_get_cmap (arg,1);
-       release_console_sem();
+       console_unlock();
 
        return rc;
 }
@@ -3945,9 +3950,9 @@ int con_get_cmap(unsigned char __user *arg)
 {
        int rc;
 
-       acquire_console_sem();
+       console_lock();
        rc = set_get_cmap (arg,0);
-       release_console_sem();
+       console_unlock();
 
        return rc;
 }
@@ -3994,12 +3999,12 @@ static int con_font_get(struct vc_data *vc, struct console_font_op *op)
        } else
                font.data = NULL;
 
-       acquire_console_sem();
+       console_lock();
        if (vc->vc_sw->con_font_get)
                rc = vc->vc_sw->con_font_get(vc, &font);
        else
                rc = -ENOSYS;
-       release_console_sem();
+       console_unlock();
 
        if (rc)
                goto out;
@@ -4076,12 +4081,12 @@ static int con_font_set(struct vc_data *vc, struct console_font_op *op)
        font.data = memdup_user(op->data, size);
        if (IS_ERR(font.data))
                return PTR_ERR(font.data);
-       acquire_console_sem();
+       console_lock();
        if (vc->vc_sw->con_font_set)
                rc = vc->vc_sw->con_font_set(vc, &font, op->flags);
        else
                rc = -ENOSYS;
-       release_console_sem();
+       console_unlock();
        kfree(font.data);
        return rc;
 }
@@ -4103,12 +4108,12 @@ static int con_font_default(struct vc_data *vc, struct console_font_op *op)
        else
                name[MAX_FONT_NAME - 1] = 0;
 
-       acquire_console_sem();
+       console_lock();
        if (vc->vc_sw->con_font_default)
                rc = vc->vc_sw->con_font_default(vc, &font, s);
        else
                rc = -ENOSYS;
-       release_console_sem();
+       console_unlock();
        if (!rc) {
                op->width = font.width;
                op->height = font.height;
@@ -4124,7 +4129,7 @@ static int con_font_copy(struct vc_data *vc, struct console_font_op *op)
        if (vc->vc_mode != KD_TEXT)
                return -EINVAL;
 
-       acquire_console_sem();
+       console_lock();
        if (!vc->vc_sw->con_font_copy)
                rc = -ENOSYS;
        else if (con < 0 || !vc_cons_allocated(con))
@@ -4133,7 +4138,7 @@ static int con_font_copy(struct vc_data *vc, struct console_font_op *op)
                rc = 0;
        else
                rc = vc->vc_sw->con_font_copy(vc, con);
-       release_console_sem();
+       console_unlock();
        return rc;
 }
 
index 6b68a0fb461178a671a4dd1c1f74be0c10216fbf..1235ebda6e1c094bba7338e60c180bbd3823d4d3 100644 (file)
@@ -649,12 +649,12 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
                /*
                 * explicitly blank/unblank the screen if switching modes
                 */
-               acquire_console_sem();
+               console_lock();
                if (arg == KD_TEXT)
                        do_unblank_screen(1);
                else
                        do_blank_screen(1);
-               release_console_sem();
+               console_unlock();
                break;
 
        case KDGETMODE:
@@ -893,7 +893,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
                        ret = -EINVAL;
                        goto out;
                }
-               acquire_console_sem();
+               console_lock();
                vc->vt_mode = tmp;
                /* the frsig is ignored, so we set it to 0 */
                vc->vt_mode.frsig = 0;
@@ -901,7 +901,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
                vc->vt_pid = get_pid(task_pid(current));
                /* no switch is required -- saw@shade.msu.ru */
                vc->vt_newvt = -1;
-               release_console_sem();
+               console_unlock();
                break;
        }
 
@@ -910,9 +910,9 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
                struct vt_mode tmp;
                int rc;
 
-               acquire_console_sem();
+               console_lock();
                memcpy(&tmp, &vc->vt_mode, sizeof(struct vt_mode));
-               release_console_sem();
+               console_unlock();
 
                rc = copy_to_user(up, &tmp, sizeof(struct vt_mode));
                if (rc)
@@ -965,9 +965,9 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
                        ret =  -ENXIO;
                else {
                        arg--;
-                       acquire_console_sem();
+                       console_lock();
                        ret = vc_allocate(arg);
-                       release_console_sem();
+                       console_unlock();
                        if (ret)
                                break;
                        set_console(arg);
@@ -990,7 +990,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
                        ret = -ENXIO;
                else {
                        vsa.console--;
-                       acquire_console_sem();
+                       console_lock();
                        ret = vc_allocate(vsa.console);
                        if (ret == 0) {
                                struct vc_data *nvc;
@@ -1003,7 +1003,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
                                put_pid(nvc->vt_pid);
                                nvc->vt_pid = get_pid(task_pid(current));
                        }
-                       release_console_sem();
+                       console_unlock();
                        if (ret)
                                break;
                        /* Commence switch and lock */
@@ -1044,7 +1044,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
                /*
                 * Switching-from response
                 */
-               acquire_console_sem();
+               console_lock();
                if (vc->vt_newvt >= 0) {
                        if (arg == 0)
                                /*
@@ -1063,7 +1063,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
                                vc->vt_newvt = -1;
                                ret = vc_allocate(newvt);
                                if (ret) {
-                                       release_console_sem();
+                                       console_unlock();
                                        break;
                                }
                                /*
@@ -1083,7 +1083,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
                        if (arg != VT_ACKACQ)
                                ret = -EINVAL;
                }
-               release_console_sem();
+               console_unlock();
                break;
 
         /*
@@ -1096,20 +1096,20 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
                }
                if (arg == 0) {
                    /* deallocate all unused consoles, but leave 0 */
-                       acquire_console_sem();
+                       console_lock();
                        for (i=1; i<MAX_NR_CONSOLES; i++)
                                if (! VT_BUSY(i))
                                        vc_deallocate(i);
-                       release_console_sem();
+                       console_unlock();
                } else {
                        /* deallocate a single console, if possible */
                        arg--;
                        if (VT_BUSY(arg))
                                ret = -EBUSY;
                        else if (arg) {                       /* leave 0 */
-                               acquire_console_sem();
+                               console_lock();
                                vc_deallocate(arg);
-                               release_console_sem();
+                               console_unlock();
                        }
                }
                break;
@@ -1126,7 +1126,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
                    get_user(cc, &vtsizes->v_cols))
                        ret = -EFAULT;
                else {
-                       acquire_console_sem();
+                       console_lock();
                        for (i = 0; i < MAX_NR_CONSOLES; i++) {
                                vc = vc_cons[i].d;
 
@@ -1135,7 +1135,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
                                        vc_resize(vc_cons[i].d, cc, ll);
                                }
                        }
-                       release_console_sem();
+                       console_unlock();
                }
                break;
        }
@@ -1187,14 +1187,14 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
                for (i = 0; i < MAX_NR_CONSOLES; i++) {
                        if (!vc_cons[i].d)
                                continue;
-                       acquire_console_sem();
+                       console_lock();
                        if (vlin)
                                vc_cons[i].d->vc_scan_lines = vlin;
                        if (clin)
                                vc_cons[i].d->vc_font.height = clin;
                        vc_cons[i].d->vc_resize_user = 1;
                        vc_resize(vc_cons[i].d, cc, ll);
-                       release_console_sem();
+                       console_unlock();
                }
                break;
        }
@@ -1367,7 +1367,7 @@ void vc_SAK(struct work_struct *work)
        struct vc_data *vc;
        struct tty_struct *tty;
 
-       acquire_console_sem();
+       console_lock();
        vc = vc_con->d;
        if (vc) {
                tty = vc->port.tty;
@@ -1379,7 +1379,7 @@ void vc_SAK(struct work_struct *work)
                        __do_SAK(tty);
                reset_vc(vc);
        }
-       release_console_sem();
+       console_unlock();
 }
 
 #ifdef CONFIG_COMPAT
@@ -1737,10 +1737,10 @@ int vt_move_to_console(unsigned int vt, int alloc)
 {
        int prev;
 
-       acquire_console_sem();
+       console_lock();
        /* Graphics mode - up to X */
        if (disable_vt_switch) {
-               release_console_sem();
+               console_unlock();
                return 0;
        }
        prev = fg_console;
@@ -1748,7 +1748,7 @@ int vt_move_to_console(unsigned int vt, int alloc)
        if (alloc && vc_allocate(vt)) {
                /* we can't have a free VC for now. Too bad,
                 * we don't want to mess the screen for now. */
-               release_console_sem();
+               console_unlock();
                return -ENOSPC;
        }
 
@@ -1758,10 +1758,10 @@ int vt_move_to_console(unsigned int vt, int alloc)
                 * Let the calling function know so it can decide
                 * what to do.
                 */
-               release_console_sem();
+               console_unlock();
                return -EIO;
        }
-       release_console_sem();
+       console_unlock();
        tty_lock();
        if (vt_waitactive(vt + 1)) {
                pr_debug("Suspend: Can't switch VCs.");
@@ -1781,8 +1781,8 @@ int vt_move_to_console(unsigned int vt, int alloc)
  */
 void pm_set_vt_switch(int do_switch)
 {
-       acquire_console_sem();
+       console_lock();
        disable_vt_switch = !do_switch;
-       release_console_sem();
+       console_unlock();
 }
 EXPORT_SYMBOL(pm_set_vt_switch);
index 6ee4451bfe2d204ebc8ecba57c7129fd494308e8..47085e5879abb57758601722bb62c7734380a254 100644 (file)
@@ -342,7 +342,7 @@ static ssize_t wdm_write
                goto outnp;
        }
 
-       if (!file->f_flags && O_NONBLOCK)
+       if (!(file->f_flags & O_NONBLOCK))
                r = wait_event_interruptible(desc->wait, !test_bit(WDM_IN_USE,
                                                                &desc->flags));
        else
index 9da250563027630330d92831ac0adbe428feb1cb..df502a98d0df0611e206d7e32e12c1bf1a5b39df 100644 (file)
@@ -192,12 +192,12 @@ int usb_create_ep_devs(struct device *parent,
        ep_dev->dev.parent = parent;
        ep_dev->dev.release = ep_device_release;
        dev_set_name(&ep_dev->dev, "ep_%02x", endpoint->desc.bEndpointAddress);
-       device_enable_async_suspend(&ep_dev->dev);
 
        retval = device_register(&ep_dev->dev);
        if (retval)
                goto error_register;
 
+       device_enable_async_suspend(&ep_dev->dev);
        endpoint->ep_dev = ep_dev;
        return retval;
 
index b55d46070a2519cc6d0b38f5c7b49daf241f5337..f71e8e307e0f0c0b513c763b1ddfcb7b81f0cded 100644 (file)
@@ -405,7 +405,12 @@ static int suspend_common(struct device *dev, bool do_wakeup)
                        return retval;
        }
 
-       synchronize_irq(pci_dev->irq);
+       /* If MSI-X is enabled, the driver will have synchronized all vectors
+        * in pci_suspend(). If MSI or legacy PCI is enabled, that will be
+        * synchronized here.
+        */
+       if (!hcd->msix_enabled)
+               synchronize_irq(pci_dev->irq);
 
        /* Downstream ports from this root hub should already be quiesced, so
         * there will be no DMA activity.  Now we can shut down the upstream
index b98efae6a1cfdaaa08b786b45da8c92b56d7f73c..4310cc4b1cb5d5c019f9e032232de1e1dcc00ddb 100644 (file)
@@ -676,6 +676,8 @@ static void hub_init_func3(struct work_struct *ws);
 static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
 {
        struct usb_device *hdev = hub->hdev;
+       struct usb_hcd *hcd;
+       int ret;
        int port1;
        int status;
        bool need_debounce_delay = false;
@@ -714,6 +716,25 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
                        usb_autopm_get_interface_no_resume(
                                        to_usb_interface(hub->intfdev));
                        return;         /* Continues at init2: below */
+               } else if (type == HUB_RESET_RESUME) {
+                       /* The internal host controller state for the hub device
+                        * may be gone after a host power loss on system resume.
+                        * Update the device's info so the HW knows it's a hub.
+                        */
+                       hcd = bus_to_hcd(hdev->bus);
+                       if (hcd->driver->update_hub_device) {
+                               ret = hcd->driver->update_hub_device(hcd, hdev,
+                                               &hub->tt, GFP_NOIO);
+                               if (ret < 0) {
+                                       dev_err(hub->intfdev, "Host not "
+                                                       "accepting hub info "
+                                                       "update.\n");
+                                       dev_err(hub->intfdev, "LS/FS devices "
+                                                       "and hubs may not work "
+                                                       "under this hub\n.");
+                               }
+                       }
+                       hub_power_on(hub, true);
                } else {
                        hub_power_on(hub, true);
                }
index 1dc9739277b4941498619b88a98e6731e93fdcaf..06bb9d4587e936d3b052e9302deff3993d43ba95 100644 (file)
@@ -509,7 +509,7 @@ config USB_LANGWELL
        select USB_GADGET_SELECTED
 
 config USB_GADGET_EG20T
-       boolean "Intel EG20T(Topcliff) USB Device controller"
+       boolean "Intel EG20T PCH/OKI SEMICONDUCTOR ML7213 IOH UDC"
        depends on PCI
        select USB_GADGET_DUALSPEED
        help
@@ -525,6 +525,11 @@ config USB_GADGET_EG20T
          This driver dose not support interrupt transfer or isochronous
          transfer modes.
 
+         This driver also can be used for OKI SEMICONDUCTOR's ML7213 which is
+         for IVI(In-Vehicle Infotainment) use.
+         ML7213 is companion chip for Intel Atom E6xx series.
+         ML7213 is completely compatible for Intel EG20T PCH.
+
 config USB_EG20T
        tristate
        depends on USB_GADGET_EG20T
index 31656a2b4ab487a1ec14500664930c1c82401b70..a1c67ae1572a2b8abf57ed9688d0a917a413aab7 100644 (file)
@@ -76,10 +76,21 @@ static DEFINE_SPINLOCK(udc_lock);
 
 /* control endpoint description */
 static const struct usb_endpoint_descriptor
-ctrl_endpt_desc = {
+ctrl_endpt_out_desc = {
        .bLength         = USB_DT_ENDPOINT_SIZE,
        .bDescriptorType = USB_DT_ENDPOINT,
 
+       .bEndpointAddress = USB_DIR_OUT,
+       .bmAttributes    = USB_ENDPOINT_XFER_CONTROL,
+       .wMaxPacketSize  = cpu_to_le16(CTRL_PAYLOAD_MAX),
+};
+
+static const struct usb_endpoint_descriptor
+ctrl_endpt_in_desc = {
+       .bLength         = USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType = USB_DT_ENDPOINT,
+
+       .bEndpointAddress = USB_DIR_IN,
        .bmAttributes    = USB_ENDPOINT_XFER_CONTROL,
        .wMaxPacketSize  = cpu_to_le16(CTRL_PAYLOAD_MAX),
 };
@@ -265,10 +276,10 @@ static int hw_device_init(void __iomem *base)
        hw_bank.size /= sizeof(u32);
 
        reg = hw_aread(ABS_DCCPARAMS, DCCPARAMS_DEN) >> ffs_nr(DCCPARAMS_DEN);
-       if (reg == 0 || reg > ENDPT_MAX)
-               return -ENODEV;
+       hw_ep_max = reg * 2;   /* cache hw ENDPT_MAX */
 
-       hw_ep_max = reg;   /* cache hw ENDPT_MAX */
+       if (hw_ep_max == 0 || hw_ep_max > ENDPT_MAX)
+               return -ENODEV;
 
        /* setup lock mode ? */
 
@@ -1197,16 +1208,17 @@ static ssize_t show_qheads(struct device *dev, struct device_attribute *attr,
        }
 
        spin_lock_irqsave(udc->lock, flags);
-       for (i = 0; i < hw_ep_max; i++) {
-               struct ci13xxx_ep *mEp = &udc->ci13xxx_ep[i];
+       for (i = 0; i < hw_ep_max/2; i++) {
+               struct ci13xxx_ep *mEpRx = &udc->ci13xxx_ep[i];
+               struct ci13xxx_ep *mEpTx = &udc->ci13xxx_ep[i + hw_ep_max/2];
                n += scnprintf(buf + n, PAGE_SIZE - n,
                               "EP=%02i: RX=%08X TX=%08X\n",
-                              i, (u32)mEp->qh[RX].dma, (u32)mEp->qh[TX].dma);
+                              i, (u32)mEpRx->qh.dma, (u32)mEpTx->qh.dma);
                for (j = 0; j < (sizeof(struct ci13xxx_qh)/sizeof(u32)); j++) {
                        n += scnprintf(buf + n, PAGE_SIZE - n,
                                       " %04X:    %08X    %08X\n", j,
-                                      *((u32 *)mEp->qh[RX].ptr + j),
-                                      *((u32 *)mEp->qh[TX].ptr + j));
+                                      *((u32 *)mEpRx->qh.ptr + j),
+                                      *((u32 *)mEpTx->qh.ptr + j));
                }
        }
        spin_unlock_irqrestore(udc->lock, flags);
@@ -1293,7 +1305,7 @@ static ssize_t show_requests(struct device *dev, struct device_attribute *attr,
        unsigned long flags;
        struct list_head   *ptr = NULL;
        struct ci13xxx_req *req = NULL;
-       unsigned i, j, k, n = 0, qSize = sizeof(struct ci13xxx_td)/sizeof(u32);
+       unsigned i, j, n = 0, qSize = sizeof(struct ci13xxx_td)/sizeof(u32);
 
        dbg_trace("[%s] %p\n", __func__, buf);
        if (attr == NULL || buf == NULL) {
@@ -1303,22 +1315,20 @@ static ssize_t show_requests(struct device *dev, struct device_attribute *attr,
 
        spin_lock_irqsave(udc->lock, flags);
        for (i = 0; i < hw_ep_max; i++)
-               for (k = RX; k <= TX; k++)
-                       list_for_each(ptr, &udc->ci13xxx_ep[i].qh[k].queue)
-                       {
-                               req = list_entry(ptr,
-                                                struct ci13xxx_req, queue);
+               list_for_each(ptr, &udc->ci13xxx_ep[i].qh.queue)
+               {
+                       req = list_entry(ptr, struct ci13xxx_req, queue);
+
+                       n += scnprintf(buf + n, PAGE_SIZE - n,
+                                       "EP=%02i: TD=%08X %s\n",
+                                       i % hw_ep_max/2, (u32)req->dma,
+                                       ((i < hw_ep_max/2) ? "RX" : "TX"));
 
+                       for (j = 0; j < qSize; j++)
                                n += scnprintf(buf + n, PAGE_SIZE - n,
-                                              "EP=%02i: TD=%08X %s\n",
-                                              i, (u32)req->dma,
-                                              ((k == RX) ? "RX" : "TX"));
-
-                               for (j = 0; j < qSize; j++)
-                                       n += scnprintf(buf + n, PAGE_SIZE - n,
-                                                      " %04X:    %08X\n", j,
-                                                      *((u32 *)req->ptr + j));
-                       }
+                                               " %04X:    %08X\n", j,
+                                               *((u32 *)req->ptr + j));
+               }
        spin_unlock_irqrestore(udc->lock, flags);
 
        return n;
@@ -1467,12 +1477,12 @@ static int _hardware_enqueue(struct ci13xxx_ep *mEp, struct ci13xxx_req *mReq)
         *  At this point it's guaranteed exclusive access to qhead
         *  (endpt is not primed) so it's no need to use tripwire
         */
-       mEp->qh[mEp->dir].ptr->td.next   = mReq->dma;    /* TERMINATE = 0 */
-       mEp->qh[mEp->dir].ptr->td.token &= ~TD_STATUS;   /* clear status */
+       mEp->qh.ptr->td.next   = mReq->dma;    /* TERMINATE = 0 */
+       mEp->qh.ptr->td.token &= ~TD_STATUS;   /* clear status */
        if (mReq->req.zero == 0)
-               mEp->qh[mEp->dir].ptr->cap |=  QH_ZLT;
+               mEp->qh.ptr->cap |=  QH_ZLT;
        else
-               mEp->qh[mEp->dir].ptr->cap &= ~QH_ZLT;
+               mEp->qh.ptr->cap &= ~QH_ZLT;
 
        wmb();   /* synchronize before ep prime */
 
@@ -1542,11 +1552,11 @@ __acquires(mEp->lock)
 
        hw_ep_flush(mEp->num, mEp->dir);
 
-       while (!list_empty(&mEp->qh[mEp->dir].queue)) {
+       while (!list_empty(&mEp->qh.queue)) {
 
                /* pop oldest request */
                struct ci13xxx_req *mReq = \
-                       list_entry(mEp->qh[mEp->dir].queue.next,
+                       list_entry(mEp->qh.queue.next,
                                   struct ci13xxx_req, queue);
                list_del_init(&mReq->queue);
                mReq->req.status = -ESHUTDOWN;
@@ -1571,8 +1581,6 @@ static int _gadget_stop_activity(struct usb_gadget *gadget)
 {
        struct usb_ep *ep;
        struct ci13xxx    *udc = container_of(gadget, struct ci13xxx, gadget);
-       struct ci13xxx_ep *mEp = container_of(gadget->ep0,
-                                             struct ci13xxx_ep, ep);
 
        trace("%p", gadget);
 
@@ -1583,7 +1591,8 @@ static int _gadget_stop_activity(struct usb_gadget *gadget)
        gadget_for_each_ep(ep, gadget) {
                usb_ep_fifo_flush(ep);
        }
-       usb_ep_fifo_flush(gadget->ep0);
+       usb_ep_fifo_flush(&udc->ep0out.ep);
+       usb_ep_fifo_flush(&udc->ep0in.ep);
 
        udc->driver->disconnect(gadget);
 
@@ -1591,11 +1600,12 @@ static int _gadget_stop_activity(struct usb_gadget *gadget)
        gadget_for_each_ep(ep, gadget) {
                usb_ep_disable(ep);
        }
-       usb_ep_disable(gadget->ep0);
+       usb_ep_disable(&udc->ep0out.ep);
+       usb_ep_disable(&udc->ep0in.ep);
 
-       if (mEp->status != NULL) {
-               usb_ep_free_request(gadget->ep0, mEp->status);
-               mEp->status = NULL;
+       if (udc->status != NULL) {
+               usb_ep_free_request(&udc->ep0in.ep, udc->status);
+               udc->status = NULL;
        }
 
        return 0;
@@ -1614,7 +1624,6 @@ static void isr_reset_handler(struct ci13xxx *udc)
 __releases(udc->lock)
 __acquires(udc->lock)
 {
-       struct ci13xxx_ep *mEp = &udc->ci13xxx_ep[0];
        int retval;
 
        trace("%p", udc);
@@ -1635,11 +1644,15 @@ __acquires(udc->lock)
        if (retval)
                goto done;
 
-       retval = usb_ep_enable(&mEp->ep, &ctrl_endpt_desc);
+       retval = usb_ep_enable(&udc->ep0out.ep, &ctrl_endpt_out_desc);
+       if (retval)
+               goto done;
+
+       retval = usb_ep_enable(&udc->ep0in.ep, &ctrl_endpt_in_desc);
        if (!retval) {
-               mEp->status = usb_ep_alloc_request(&mEp->ep, GFP_ATOMIC);
-               if (mEp->status == NULL) {
-                       usb_ep_disable(&mEp->ep);
+               udc->status = usb_ep_alloc_request(&udc->ep0in.ep, GFP_ATOMIC);
+               if (udc->status == NULL) {
+                       usb_ep_disable(&udc->ep0out.ep);
                        retval = -ENOMEM;
                }
        }
@@ -1672,16 +1685,17 @@ static void isr_get_status_complete(struct usb_ep *ep, struct usb_request *req)
 
 /**
  * isr_get_status_response: get_status request response
- * @ep:    endpoint
+ * @udc: udc struct
  * @setup: setup request packet
  *
  * This function returns an error code
  */
-static int isr_get_status_response(struct ci13xxx_ep *mEp,
+static int isr_get_status_response(struct ci13xxx *udc,
                                   struct usb_ctrlrequest *setup)
 __releases(mEp->lock)
 __acquires(mEp->lock)
 {
+       struct ci13xxx_ep *mEp = &udc->ep0in;
        struct usb_request *req = NULL;
        gfp_t gfp_flags = GFP_ATOMIC;
        int dir, num, retval;
@@ -1736,27 +1750,23 @@ __acquires(mEp->lock)
 
 /**
  * isr_setup_status_phase: queues the status phase of a setup transation
- * @mEp: endpoint
+ * @udc: udc struct
  *
  * This function returns an error code
  */
-static int isr_setup_status_phase(struct ci13xxx_ep *mEp)
+static int isr_setup_status_phase(struct ci13xxx *udc)
 __releases(mEp->lock)
 __acquires(mEp->lock)
 {
        int retval;
+       struct ci13xxx_ep *mEp;
 
-       trace("%p", mEp);
-
-       /* mEp is always valid & configured */
-
-       if (mEp->type == USB_ENDPOINT_XFER_CONTROL)
-               mEp->dir = (mEp->dir == TX) ? RX : TX;
+       trace("%p", udc);
 
-       mEp->status->no_interrupt = 1;
+       mEp = (udc->ep0_dir == TX) ? &udc->ep0out : &udc->ep0in;
 
        spin_unlock(mEp->lock);
-       retval = usb_ep_queue(&mEp->ep, mEp->status, GFP_ATOMIC);
+       retval = usb_ep_queue(&mEp->ep, udc->status, GFP_ATOMIC);
        spin_lock(mEp->lock);
 
        return retval;
@@ -1778,11 +1788,11 @@ __acquires(mEp->lock)
 
        trace("%p", mEp);
 
-       if (list_empty(&mEp->qh[mEp->dir].queue))
+       if (list_empty(&mEp->qh.queue))
                return -EINVAL;
 
        /* pop oldest request */
-       mReq = list_entry(mEp->qh[mEp->dir].queue.next,
+       mReq = list_entry(mEp->qh.queue.next,
                          struct ci13xxx_req, queue);
        list_del_init(&mReq->queue);
 
@@ -1794,10 +1804,10 @@ __acquires(mEp->lock)
 
        dbg_done(_usb_addr(mEp), mReq->ptr->token, retval);
 
-       if (!list_empty(&mEp->qh[mEp->dir].queue)) {
+       if (!list_empty(&mEp->qh.queue)) {
                struct ci13xxx_req* mReqEnq;
 
-               mReqEnq = list_entry(mEp->qh[mEp->dir].queue.next,
+               mReqEnq = list_entry(mEp->qh.queue.next,
                                  struct ci13xxx_req, queue);
                _hardware_enqueue(mEp, mReqEnq);
        }
@@ -1836,16 +1846,14 @@ __acquires(udc->lock)
                int type, num, err = -EINVAL;
                struct usb_ctrlrequest req;
 
-
                if (mEp->desc == NULL)
                        continue;   /* not configured */
 
-               if ((mEp->dir == RX && hw_test_and_clear_complete(i)) ||
-                   (mEp->dir == TX && hw_test_and_clear_complete(i + 16))) {
+               if (hw_test_and_clear_complete(i)) {
                        err = isr_tr_complete_low(mEp);
                        if (mEp->type == USB_ENDPOINT_XFER_CONTROL) {
                                if (err > 0)   /* needs status phase */
-                                       err = isr_setup_status_phase(mEp);
+                                       err = isr_setup_status_phase(udc);
                                if (err < 0) {
                                        dbg_event(_usb_addr(mEp),
                                                  "ERROR", err);
@@ -1866,15 +1874,22 @@ __acquires(udc->lock)
                        continue;
                }
 
+               /*
+                * Flush data and handshake transactions of previous
+                * setup packet.
+                */
+               _ep_nuke(&udc->ep0out);
+               _ep_nuke(&udc->ep0in);
+
                /* read_setup_packet */
                do {
                        hw_test_and_set_setup_guard();
-                       memcpy(&req, &mEp->qh[RX].ptr->setup, sizeof(req));
+                       memcpy(&req, &mEp->qh.ptr->setup, sizeof(req));
                } while (!hw_test_and_clear_setup_guard());
 
                type = req.bRequestType;
 
-               mEp->dir = (type & USB_DIR_IN) ? TX : RX;
+               udc->ep0_dir = (type & USB_DIR_IN) ? TX : RX;
 
                dbg_setup(_usb_addr(mEp), &req);
 
@@ -1895,7 +1910,7 @@ __acquires(udc->lock)
                                if (err)
                                        break;
                        }
-                       err = isr_setup_status_phase(mEp);
+                       err = isr_setup_status_phase(udc);
                        break;
                case USB_REQ_GET_STATUS:
                        if (type != (USB_DIR_IN|USB_RECIP_DEVICE)   &&
@@ -1905,7 +1920,7 @@ __acquires(udc->lock)
                        if (le16_to_cpu(req.wLength) != 2 ||
                            le16_to_cpu(req.wValue)  != 0)
                                break;
-                       err = isr_get_status_response(mEp, &req);
+                       err = isr_get_status_response(udc, &req);
                        break;
                case USB_REQ_SET_ADDRESS:
                        if (type != (USB_DIR_OUT|USB_RECIP_DEVICE))
@@ -1916,7 +1931,7 @@ __acquires(udc->lock)
                        err = hw_usb_set_address((u8)le16_to_cpu(req.wValue));
                        if (err)
                                break;
-                       err = isr_setup_status_phase(mEp);
+                       err = isr_setup_status_phase(udc);
                        break;
                case USB_REQ_SET_FEATURE:
                        if (type != (USB_DIR_OUT|USB_RECIP_ENDPOINT) &&
@@ -1932,12 +1947,12 @@ __acquires(udc->lock)
                        spin_lock(udc->lock);
                        if (err)
                                break;
-                       err = isr_setup_status_phase(mEp);
+                       err = isr_setup_status_phase(udc);
                        break;
                default:
 delegate:
                        if (req.wLength == 0)   /* no data phase */
-                               mEp->dir = TX;
+                               udc->ep0_dir = TX;
 
                        spin_unlock(udc->lock);
                        err = udc->driver->setup(&udc->gadget, &req);
@@ -1968,7 +1983,7 @@ static int ep_enable(struct usb_ep *ep,
                     const struct usb_endpoint_descriptor *desc)
 {
        struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep);
-       int direction, retval = 0;
+       int retval = 0;
        unsigned long flags;
 
        trace("%p, %p", ep, desc);
@@ -1982,7 +1997,7 @@ static int ep_enable(struct usb_ep *ep,
 
        mEp->desc = desc;
 
-       if (!list_empty(&mEp->qh[mEp->dir].queue))
+       if (!list_empty(&mEp->qh.queue))
                warn("enabling a non-empty endpoint!");
 
        mEp->dir  = usb_endpoint_dir_in(desc) ? TX : RX;
@@ -1991,29 +2006,22 @@ static int ep_enable(struct usb_ep *ep,
 
        mEp->ep.maxpacket = __constant_le16_to_cpu(desc->wMaxPacketSize);
 
-       direction = mEp->dir;
-       do {
-               dbg_event(_usb_addr(mEp), "ENABLE", 0);
+       dbg_event(_usb_addr(mEp), "ENABLE", 0);
 
-               mEp->qh[mEp->dir].ptr->cap = 0;
+       mEp->qh.ptr->cap = 0;
 
-               if (mEp->type == USB_ENDPOINT_XFER_CONTROL)
-                       mEp->qh[mEp->dir].ptr->cap |=  QH_IOS;
-               else if (mEp->type == USB_ENDPOINT_XFER_ISOC)
-                       mEp->qh[mEp->dir].ptr->cap &= ~QH_MULT;
-               else
-                       mEp->qh[mEp->dir].ptr->cap &= ~QH_ZLT;
-
-               mEp->qh[mEp->dir].ptr->cap |=
-                       (mEp->ep.maxpacket << ffs_nr(QH_MAX_PKT)) & QH_MAX_PKT;
-               mEp->qh[mEp->dir].ptr->td.next |= TD_TERMINATE;   /* needed? */
-
-               retval |= hw_ep_enable(mEp->num, mEp->dir, mEp->type);
+       if (mEp->type == USB_ENDPOINT_XFER_CONTROL)
+               mEp->qh.ptr->cap |=  QH_IOS;
+       else if (mEp->type == USB_ENDPOINT_XFER_ISOC)
+               mEp->qh.ptr->cap &= ~QH_MULT;
+       else
+               mEp->qh.ptr->cap &= ~QH_ZLT;
 
-               if (mEp->type == USB_ENDPOINT_XFER_CONTROL)
-                       mEp->dir = (mEp->dir == TX) ? RX : TX;
+       mEp->qh.ptr->cap |=
+               (mEp->ep.maxpacket << ffs_nr(QH_MAX_PKT)) & QH_MAX_PKT;
+       mEp->qh.ptr->td.next |= TD_TERMINATE;   /* needed? */
 
-       } while (mEp->dir != direction);
+       retval |= hw_ep_enable(mEp->num, mEp->dir, mEp->type);
 
        spin_unlock_irqrestore(mEp->lock, flags);
        return retval;
@@ -2146,7 +2154,7 @@ static int ep_queue(struct usb_ep *ep, struct usb_request *req,
        spin_lock_irqsave(mEp->lock, flags);
 
        if (mEp->type == USB_ENDPOINT_XFER_CONTROL &&
-           !list_empty(&mEp->qh[mEp->dir].queue)) {
+           !list_empty(&mEp->qh.queue)) {
                _ep_nuke(mEp);
                retval = -EOVERFLOW;
                warn("endpoint ctrl %X nuked", _usb_addr(mEp));
@@ -2170,9 +2178,9 @@ static int ep_queue(struct usb_ep *ep, struct usb_request *req,
        /* push request */
        mReq->req.status = -EINPROGRESS;
        mReq->req.actual = 0;
-       list_add_tail(&mReq->queue, &mEp->qh[mEp->dir].queue);
+       list_add_tail(&mReq->queue, &mEp->qh.queue);
 
-       if (list_is_singular(&mEp->qh[mEp->dir].queue))
+       if (list_is_singular(&mEp->qh.queue))
                retval = _hardware_enqueue(mEp, mReq);
 
        if (retval == -EALREADY) {
@@ -2199,7 +2207,7 @@ static int ep_dequeue(struct usb_ep *ep, struct usb_request *req)
        trace("%p, %p", ep, req);
 
        if (ep == NULL || req == NULL || mEp->desc == NULL ||
-           list_empty(&mReq->queue)  || list_empty(&mEp->qh[mEp->dir].queue))
+           list_empty(&mReq->queue)  || list_empty(&mEp->qh.queue))
                return -EINVAL;
 
        spin_lock_irqsave(mEp->lock, flags);
@@ -2244,7 +2252,7 @@ static int ep_set_halt(struct usb_ep *ep, int value)
 #ifndef STALL_IN
        /* g_file_storage MS compliant but g_zero fails chapter 9 compliance */
        if (value && mEp->type == USB_ENDPOINT_XFER_BULK && mEp->dir == TX &&
-           !list_empty(&mEp->qh[mEp->dir].queue)) {
+           !list_empty(&mEp->qh.queue)) {
                spin_unlock_irqrestore(mEp->lock, flags);
                return -EAGAIN;
        }
@@ -2355,7 +2363,7 @@ static int ci13xxx_vbus_session(struct usb_gadget *_gadget, int is_active)
                if (is_active) {
                        pm_runtime_get_sync(&_gadget->dev);
                        hw_device_reset(udc);
-                       hw_device_state(udc->ci13xxx_ep[0].qh[RX].dma);
+                       hw_device_state(udc->ep0out.qh.dma);
                } else {
                        hw_device_state(0);
                        if (udc->udc_driver->notify_event)
@@ -2390,7 +2398,8 @@ int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
                int (*bind)(struct usb_gadget *))
 {
        struct ci13xxx *udc = _udc;
-       unsigned long i, k, flags;
+       unsigned long flags;
+       int i, j;
        int retval = -ENOMEM;
 
        trace("%p", driver);
@@ -2427,45 +2436,46 @@ int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
 
        info("hw_ep_max = %d", hw_ep_max);
 
-       udc->driver = driver;
        udc->gadget.dev.driver = NULL;
 
        retval = 0;
-       for (i = 0; i < hw_ep_max; i++) {
-               struct ci13xxx_ep *mEp = &udc->ci13xxx_ep[i];
+       for (i = 0; i < hw_ep_max/2; i++) {
+               for (j = RX; j <= TX; j++) {
+                       int k = i + j * hw_ep_max/2;
+                       struct ci13xxx_ep *mEp = &udc->ci13xxx_ep[k];
 
-               scnprintf(mEp->name, sizeof(mEp->name), "ep%i", (int)i);
+                       scnprintf(mEp->name, sizeof(mEp->name), "ep%i%s", i,
+                                       (j == TX)  ? "in" : "out");
 
-               mEp->lock         = udc->lock;
-               mEp->device       = &udc->gadget.dev;
-               mEp->td_pool      = udc->td_pool;
+                       mEp->lock         = udc->lock;
+                       mEp->device       = &udc->gadget.dev;
+                       mEp->td_pool      = udc->td_pool;
 
-               mEp->ep.name      = mEp->name;
-               mEp->ep.ops       = &usb_ep_ops;
-               mEp->ep.maxpacket = CTRL_PAYLOAD_MAX;
+                       mEp->ep.name      = mEp->name;
+                       mEp->ep.ops       = &usb_ep_ops;
+                       mEp->ep.maxpacket = CTRL_PAYLOAD_MAX;
 
-               /* this allocation cannot be random */
-               for (k = RX; k <= TX; k++) {
-                       INIT_LIST_HEAD(&mEp->qh[k].queue);
+                       INIT_LIST_HEAD(&mEp->qh.queue);
                        spin_unlock_irqrestore(udc->lock, flags);
-                       mEp->qh[k].ptr = dma_pool_alloc(udc->qh_pool,
-                                                       GFP_KERNEL,
-                                                       &mEp->qh[k].dma);
+                       mEp->qh.ptr = dma_pool_alloc(udc->qh_pool, GFP_KERNEL,
+                                       &mEp->qh.dma);
                        spin_lock_irqsave(udc->lock, flags);
-                       if (mEp->qh[k].ptr == NULL)
+                       if (mEp->qh.ptr == NULL)
                                retval = -ENOMEM;
                        else
-                               memset(mEp->qh[k].ptr, 0,
-                                      sizeof(*mEp->qh[k].ptr));
-               }
-               if (i == 0)
-                       udc->gadget.ep0 = &mEp->ep;
-               else
+                               memset(mEp->qh.ptr, 0, sizeof(*mEp->qh.ptr));
+
+                       /* skip ep0 out and in endpoints */
+                       if (i == 0)
+                               continue;
+
                        list_add_tail(&mEp->ep.ep_list, &udc->gadget.ep_list);
+               }
        }
        if (retval)
                goto done;
 
+       udc->gadget.ep0 = &udc->ep0in.ep;
        /* bind gadget */
        driver->driver.bus     = NULL;
        udc->gadget.dev.driver = &driver->driver;
@@ -2479,6 +2489,7 @@ int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
                goto done;
        }
 
+       udc->driver = driver;
        pm_runtime_get_sync(&udc->gadget.dev);
        if (udc->udc_driver->flags & CI13XXX_PULLUP_ON_VBUS) {
                if (udc->vbus_active) {
@@ -2490,14 +2501,12 @@ int usb_gadget_probe_driver(struct usb_gadget_driver *driver,
                }
        }
 
-       retval = hw_device_state(udc->ci13xxx_ep[0].qh[RX].dma);
+       retval = hw_device_state(udc->ep0out.qh.dma);
        if (retval)
                pm_runtime_put_sync(&udc->gadget.dev);
 
  done:
        spin_unlock_irqrestore(udc->lock, flags);
-       if (retval)
-               usb_gadget_unregister_driver(driver);
        return retval;
 }
 EXPORT_SYMBOL(usb_gadget_probe_driver);
@@ -2510,7 +2519,7 @@ EXPORT_SYMBOL(usb_gadget_probe_driver);
 int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
 {
        struct ci13xxx *udc = _udc;
-       unsigned long i, k, flags;
+       unsigned long i, flags;
 
        trace("%p", driver);
 
@@ -2546,17 +2555,14 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
        for (i = 0; i < hw_ep_max; i++) {
                struct ci13xxx_ep *mEp = &udc->ci13xxx_ep[i];
 
-               if (i == 0)
-                       udc->gadget.ep0 = NULL;
-               else if (!list_empty(&mEp->ep.ep_list))
+               if (!list_empty(&mEp->ep.ep_list))
                        list_del_init(&mEp->ep.ep_list);
 
-               for (k = RX; k <= TX; k++)
-                       if (mEp->qh[k].ptr != NULL)
-                               dma_pool_free(udc->qh_pool,
-                                             mEp->qh[k].ptr, mEp->qh[k].dma);
+               if (mEp->qh.ptr != NULL)
+                       dma_pool_free(udc->qh_pool, mEp->qh.ptr, mEp->qh.dma);
        }
 
+       udc->gadget.ep0 = NULL;
        udc->driver = NULL;
 
        spin_unlock_irqrestore(udc->lock, flags);
index f61fed07f76bb89d535cd181faf941b4178453d2..a2492b65f98c41a3b57e795c546f73eb6b551d46 100644 (file)
@@ -20,7 +20,7 @@
  * DEFINE
  *****************************************************************************/
 #define CI13XXX_PAGE_SIZE  4096ul /* page size for TD's */
-#define ENDPT_MAX          (16)
+#define ENDPT_MAX          (32)
 #define CTRL_PAYLOAD_MAX   (64)
 #define RX        (0)  /* similar to USB_DIR_OUT but can be used as an index */
 #define TX        (1)  /* similar to USB_DIR_IN  but can be used as an index */
@@ -88,8 +88,7 @@ struct ci13xxx_ep {
                struct list_head   queue;
                struct ci13xxx_qh *ptr;
                dma_addr_t         dma;
-       }                                      qh[2];
-       struct usb_request                    *status;
+       }                                      qh;
        int                                    wedge;
 
        /* global resources */
@@ -119,9 +118,13 @@ struct ci13xxx {
 
        struct dma_pool           *qh_pool;   /* DMA pool for queue heads */
        struct dma_pool           *td_pool;   /* DMA pool for transfer descs */
+       struct usb_request        *status;    /* ep0 status request */
 
        struct usb_gadget          gadget;     /* USB slave device */
        struct ci13xxx_ep          ci13xxx_ep[ENDPT_MAX]; /* extended endpts */
+       u32                        ep0_dir;    /* ep0 direction */
+#define ep0out ci13xxx_ep[0]
+#define ep0in  ci13xxx_ep[16]
 
        struct usb_gadget_driver  *driver;     /* 3rd party gadget driver */
        struct ci13xxx_udc_driver *udc_driver; /* device controller driver */
index f6ff8456d52d59fe027f88bbabf678982299282e..1ba4befe336b6b77741f163510c6e5890e7d0df6 100644 (file)
@@ -928,8 +928,9 @@ unknown:
                 */
                switch (ctrl->bRequestType & USB_RECIP_MASK) {
                case USB_RECIP_INTERFACE:
-                       if (cdev->config)
-                               f = cdev->config->interface[intf];
+                       if (!cdev->config || w_index >= MAX_CONFIG_INTERFACES)
+                               break;
+                       f = cdev->config->interface[intf];
                        break;
 
                case USB_RECIP_ENDPOINT:
index 0c8dd81dddcab5d10b38b9ce967d6e5d9e6cfab4..b120dbb64d0f385c24d73e75b5411d54edbe9119 100644 (file)
 #define PCH_UDC_BRLEN          0x0F    /* Burst length */
 #define PCH_UDC_THLEN          0x1F    /* Threshold length */
 /* Value of EP Buffer Size */
-#define UDC_EP0IN_BUFF_SIZE    64
-#define UDC_EPIN_BUFF_SIZE     512
-#define UDC_EP0OUT_BUFF_SIZE   64
-#define UDC_EPOUT_BUFF_SIZE    512
+#define UDC_EP0IN_BUFF_SIZE    16
+#define UDC_EPIN_BUFF_SIZE     256
+#define UDC_EP0OUT_BUFF_SIZE   16
+#define UDC_EPOUT_BUFF_SIZE    256
 /* Value of EP maximum packet size */
 #define UDC_EP0IN_MAX_PKT_SIZE 64
 #define UDC_EP0OUT_MAX_PKT_SIZE        64
@@ -351,7 +351,7 @@ struct pch_udc_dev {
        struct pci_pool         *data_requests;
        struct pci_pool         *stp_requests;
        dma_addr_t                      dma_addr;
-       unsigned long                   ep0out_buf[64];
+       void                            *ep0out_buf;
        struct usb_ctrlrequest          setup_data;
        unsigned long                   phys_addr;
        void __iomem                    *base_addr;
@@ -361,6 +361,8 @@ struct pch_udc_dev {
 
 #define PCH_UDC_PCI_BAR                        1
 #define PCI_DEVICE_ID_INTEL_EG20T_UDC  0x8808
+#define PCI_VENDOR_ID_ROHM             0x10DB
+#define PCI_DEVICE_ID_ML7213_IOH_UDC   0x801D
 
 static const char      ep0_string[] = "ep0in";
 static DEFINE_SPINLOCK(udc_stall_spinlock);    /* stall spin lock */
@@ -1219,11 +1221,11 @@ static void complete_req(struct pch_udc_ep *ep, struct pch_udc_request *req,
        dev = ep->dev;
        if (req->dma_mapped) {
                if (ep->in)
-                       pci_unmap_single(dev->pdev, req->req.dma,
-                                        req->req.length, PCI_DMA_TODEVICE);
+                       dma_unmap_single(&dev->pdev->dev, req->req.dma,
+                                        req->req.length, DMA_TO_DEVICE);
                else
-                       pci_unmap_single(dev->pdev, req->req.dma,
-                                        req->req.length, PCI_DMA_FROMDEVICE);
+                       dma_unmap_single(&dev->pdev->dev, req->req.dma,
+                                        req->req.length, DMA_FROM_DEVICE);
                req->dma_mapped = 0;
                req->req.dma = DMA_ADDR_INVALID;
        }
@@ -1414,7 +1416,6 @@ static void pch_udc_start_rxrequest(struct pch_udc_ep *ep,
 
        pch_udc_clear_dma(ep->dev, DMA_DIR_RX);
        td_data = req->td_data;
-       ep->td_data = req->td_data;
        /* Set the status bits for all descriptors */
        while (1) {
                td_data->status = (td_data->status & ~PCH_UDC_BUFF_STS) |
@@ -1613,15 +1614,19 @@ static int pch_udc_pcd_queue(struct usb_ep *usbep, struct usb_request *usbreq,
        if (usbreq->length &&
            ((usbreq->dma == DMA_ADDR_INVALID) || !usbreq->dma)) {
                if (ep->in)
-                       usbreq->dma = pci_map_single(dev->pdev, usbreq->buf,
-                                       usbreq->length, PCI_DMA_TODEVICE);
+                       usbreq->dma = dma_map_single(&dev->pdev->dev,
+                                                    usbreq->buf,
+                                                    usbreq->length,
+                                                    DMA_TO_DEVICE);
                else
-                       usbreq->dma = pci_map_single(dev->pdev, usbreq->buf,
-                                       usbreq->length, PCI_DMA_FROMDEVICE);
+                       usbreq->dma = dma_map_single(&dev->pdev->dev,
+                                                    usbreq->buf,
+                                                    usbreq->length,
+                                                    DMA_FROM_DEVICE);
                req->dma_mapped = 1;
        }
        if (usbreq->length > 0) {
-               retval = prepare_dma(ep, req, gfp);
+               retval = prepare_dma(ep, req, GFP_ATOMIC);
                if (retval)
                        goto probe_end;
        }
@@ -1646,7 +1651,6 @@ static int pch_udc_pcd_queue(struct usb_ep *usbep, struct usb_request *usbreq,
                        pch_udc_wait_ep_stall(ep);
                        pch_udc_ep_clear_nak(ep);
                        pch_udc_enable_ep_interrupts(ep->dev, (1 << ep->num));
-                       pch_udc_set_dma(dev, DMA_DIR_TX);
                }
        }
        /* Now add this request to the ep's pending requests */
@@ -1926,6 +1930,7 @@ static void pch_udc_complete_receiver(struct pch_udc_ep *ep)
            PCH_UDC_BS_DMA_DONE)
                return;
        pch_udc_clear_dma(ep->dev, DMA_DIR_RX);
+       pch_udc_ep_set_ddptr(ep, 0);
        if ((req->td_data_last->status & PCH_UDC_RXTX_STS) !=
            PCH_UDC_RTS_SUCC) {
                dev_err(&dev->pdev->dev, "Invalid RXTX status (0x%08x) "
@@ -1963,7 +1968,7 @@ static void pch_udc_svc_data_in(struct pch_udc_dev *dev, int ep_num)
        u32     epsts;
        struct pch_udc_ep       *ep;
 
-       ep = &dev->ep[2*ep_num];
+       ep = &dev->ep[UDC_EPIN_IDX(ep_num)];
        epsts = ep->epsts;
        ep->epsts = 0;
 
@@ -2008,7 +2013,7 @@ static void pch_udc_svc_data_out(struct pch_udc_dev *dev, int ep_num)
        struct pch_udc_ep               *ep;
        struct pch_udc_request          *req = NULL;
 
-       ep = &dev->ep[2*ep_num + 1];
+       ep = &dev->ep[UDC_EPOUT_IDX(ep_num)];
        epsts = ep->epsts;
        ep->epsts = 0;
 
@@ -2025,10 +2030,11 @@ static void pch_udc_svc_data_out(struct pch_udc_dev *dev, int ep_num)
        }
        if (epsts & UDC_EPSTS_HE)
                return;
-       if (epsts & UDC_EPSTS_RSS)
+       if (epsts & UDC_EPSTS_RSS) {
                pch_udc_ep_set_stall(ep);
                pch_udc_enable_ep_interrupts(ep->dev,
                                             PCH_UDC_EPINT(ep->in, ep->num));
+       }
        if (epsts & UDC_EPSTS_RCS) {
                if (!dev->prot_stall) {
                        pch_udc_ep_clear_stall(ep);
@@ -2060,8 +2066,10 @@ static void pch_udc_svc_control_in(struct pch_udc_dev *dev)
 {
        u32     epsts;
        struct pch_udc_ep       *ep;
+       struct pch_udc_ep       *ep_out;
 
        ep = &dev->ep[UDC_EP0IN_IDX];
+       ep_out = &dev->ep[UDC_EP0OUT_IDX];
        epsts = ep->epsts;
        ep->epsts = 0;
 
@@ -2073,8 +2081,16 @@ static void pch_udc_svc_control_in(struct pch_udc_dev *dev)
                return;
        if (epsts & UDC_EPSTS_HE)
                return;
-       if ((epsts & UDC_EPSTS_TDC) && (!dev->stall))
+       if ((epsts & UDC_EPSTS_TDC) && (!dev->stall)) {
                pch_udc_complete_transfer(ep);
+               pch_udc_clear_dma(dev, DMA_DIR_RX);
+               ep_out->td_data->status = (ep_out->td_data->status &
+                                       ~PCH_UDC_BUFF_STS) |
+                                       PCH_UDC_BS_HST_RDY;
+               pch_udc_ep_clear_nak(ep_out);
+               pch_udc_set_dma(dev, DMA_DIR_RX);
+               pch_udc_ep_set_rrdy(ep_out);
+       }
        /* On IN interrupt, provide data if we have any */
        if ((epsts & UDC_EPSTS_IN) && !(epsts & UDC_EPSTS_TDC) &&
             !(epsts & UDC_EPSTS_TXEMPTY))
@@ -2102,11 +2118,9 @@ static void pch_udc_svc_control_out(struct pch_udc_dev *dev)
                dev->stall = 0;
                dev->ep[UDC_EP0IN_IDX].halted = 0;
                dev->ep[UDC_EP0OUT_IDX].halted = 0;
-               /* In data not ready */
-               pch_udc_ep_set_nak(&(dev->ep[UDC_EP0IN_IDX]));
                dev->setup_data = ep->td_stp->request;
                pch_udc_init_setup_buff(ep->td_stp);
-               pch_udc_clear_dma(dev, DMA_DIR_TX);
+               pch_udc_clear_dma(dev, DMA_DIR_RX);
                pch_udc_ep_fifo_flush(&(dev->ep[UDC_EP0IN_IDX]),
                                      dev->ep[UDC_EP0IN_IDX].in);
                if ((dev->setup_data.bRequestType & USB_DIR_IN))
@@ -2122,14 +2136,23 @@ static void pch_udc_svc_control_out(struct pch_udc_dev *dev)
                setup_supported = dev->driver->setup(&dev->gadget,
                                                     &dev->setup_data);
                spin_lock(&dev->lock);
+
+               if (dev->setup_data.bRequestType & USB_DIR_IN) {
+                       ep->td_data->status = (ep->td_data->status &
+                                               ~PCH_UDC_BUFF_STS) |
+                                               PCH_UDC_BS_HST_RDY;
+                       pch_udc_ep_set_ddptr(ep, ep->td_data_phys);
+               }
                /* ep0 in returns data on IN phase */
                if (setup_supported >= 0 && setup_supported <
                                            UDC_EP0IN_MAX_PKT_SIZE) {
                        pch_udc_ep_clear_nak(&(dev->ep[UDC_EP0IN_IDX]));
                        /* Gadget would have queued a request when
                         * we called the setup */
-                       pch_udc_set_dma(dev, DMA_DIR_RX);
-                       pch_udc_ep_clear_nak(ep);
+                       if (!(dev->setup_data.bRequestType & USB_DIR_IN)) {
+                               pch_udc_set_dma(dev, DMA_DIR_RX);
+                               pch_udc_ep_clear_nak(ep);
+                       }
                } else if (setup_supported < 0) {
                        /* if unsupported request, then stall */
                        pch_udc_ep_set_stall(&(dev->ep[UDC_EP0IN_IDX]));
@@ -2142,22 +2165,13 @@ static void pch_udc_svc_control_out(struct pch_udc_dev *dev)
                }
        } else if ((((stat & UDC_EPSTS_OUT_MASK) >> UDC_EPSTS_OUT_SHIFT) ==
                     UDC_EPSTS_OUT_DATA) && !dev->stall) {
-               if (list_empty(&ep->queue)) {
-                       dev_err(&dev->pdev->dev, "%s: No request\n", __func__);
-                       ep->td_data->status = (ep->td_data->status &
-                                              ~PCH_UDC_BUFF_STS) |
-                                              PCH_UDC_BS_HST_RDY;
-                       pch_udc_set_dma(dev, DMA_DIR_RX);
-               } else {
-                       /* control write */
-                       /* next function will pickuo an clear the status */
+               pch_udc_clear_dma(dev, DMA_DIR_RX);
+               pch_udc_ep_set_ddptr(ep, 0);
+               if (!list_empty(&ep->queue)) {
                        ep->epsts = stat;
-
-                       pch_udc_svc_data_out(dev, 0);
-                       /* re-program desc. pointer for possible ZLPs */
-                       pch_udc_ep_set_ddptr(ep, ep->td_data_phys);
-                       pch_udc_set_dma(dev, DMA_DIR_RX);
+                       pch_udc_svc_data_out(dev, PCH_UDC_EP0);
                }
+               pch_udc_set_dma(dev, DMA_DIR_RX);
        }
        pch_udc_ep_set_rrdy(ep);
 }
@@ -2174,7 +2188,7 @@ static void pch_udc_postsvc_epinters(struct pch_udc_dev *dev, int ep_num)
        struct pch_udc_ep       *ep;
        struct pch_udc_request *req;
 
-       ep = &dev->ep[2*ep_num];
+       ep = &dev->ep[UDC_EPIN_IDX(ep_num)];
        if (!list_empty(&ep->queue)) {
                req = list_entry(ep->queue.next, struct pch_udc_request, queue);
                pch_udc_enable_ep_interrupts(ep->dev,
@@ -2196,13 +2210,13 @@ static void pch_udc_read_all_epstatus(struct pch_udc_dev *dev, u32 ep_intr)
        for (i = 0; i < PCH_UDC_USED_EP_NUM; i++) {
                /* IN */
                if (ep_intr & (0x1 << i)) {
-                       ep = &dev->ep[2*i];
+                       ep = &dev->ep[UDC_EPIN_IDX(i)];
                        ep->epsts = pch_udc_read_ep_status(ep);
                        pch_udc_clear_ep_status(ep, ep->epsts);
                }
                /* OUT */
                if (ep_intr & (0x10000 << i)) {
-                       ep = &dev->ep[2*i+1];
+                       ep = &dev->ep[UDC_EPOUT_IDX(i)];
                        ep->epsts = pch_udc_read_ep_status(ep);
                        pch_udc_clear_ep_status(ep, ep->epsts);
                }
@@ -2563,9 +2577,6 @@ static void pch_udc_pcd_reinit(struct pch_udc_dev *dev)
        dev->ep[UDC_EP0IN_IDX].ep.maxpacket = UDC_EP0IN_MAX_PKT_SIZE;
        dev->ep[UDC_EP0OUT_IDX].ep.maxpacket = UDC_EP0OUT_MAX_PKT_SIZE;
 
-       dev->dma_addr = pci_map_single(dev->pdev, dev->ep0out_buf, 256,
-                                 PCI_DMA_FROMDEVICE);
-
        /* remove ep0 in and out from the list.  They have own pointer */
        list_del_init(&dev->ep[UDC_EP0IN_IDX].ep.ep_list);
        list_del_init(&dev->ep[UDC_EP0OUT_IDX].ep.ep_list);
@@ -2637,6 +2648,13 @@ static int init_dma_pools(struct pch_udc_dev *dev)
        dev->ep[UDC_EP0IN_IDX].td_stp_phys = 0;
        dev->ep[UDC_EP0IN_IDX].td_data = NULL;
        dev->ep[UDC_EP0IN_IDX].td_data_phys = 0;
+
+       dev->ep0out_buf = kzalloc(UDC_EP0OUT_BUFF_SIZE * 4, GFP_KERNEL);
+       if (!dev->ep0out_buf)
+               return -ENOMEM;
+       dev->dma_addr = dma_map_single(&dev->pdev->dev, dev->ep0out_buf,
+                                      UDC_EP0OUT_BUFF_SIZE * 4,
+                                      DMA_FROM_DEVICE);
        return 0;
 }
 
@@ -2700,7 +2718,8 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
 
        pch_udc_disable_interrupts(dev, UDC_DEVINT_MSK);
 
-       /* Assues that there are no pending requets with this driver */
+       /* Assures that there are no pending requests with this driver */
+       driver->disconnect(&dev->gadget);
        driver->unbind(&dev->gadget);
        dev->gadget.dev.driver = NULL;
        dev->driver = NULL;
@@ -2750,6 +2769,11 @@ static void pch_udc_remove(struct pci_dev *pdev)
                pci_pool_destroy(dev->stp_requests);
        }
 
+       if (dev->dma_addr)
+               dma_unmap_single(&dev->pdev->dev, dev->dma_addr,
+                                UDC_EP0OUT_BUFF_SIZE * 4, DMA_FROM_DEVICE);
+       kfree(dev->ep0out_buf);
+
        pch_udc_exit(dev);
 
        if (dev->irq_registered)
@@ -2792,11 +2816,7 @@ static int pch_udc_resume(struct pci_dev *pdev)
        int ret;
 
        pci_set_power_state(pdev, PCI_D0);
-       ret = pci_restore_state(pdev);
-       if (ret) {
-               dev_err(&pdev->dev, "%s: pci_restore_state failed\n", __func__);
-               return ret;
-       }
+       pci_restore_state(pdev);
        ret = pci_enable_device(pdev);
        if (ret) {
                dev_err(&pdev->dev, "%s: pci_enable_device failed\n", __func__);
@@ -2914,6 +2934,11 @@ static DEFINE_PCI_DEVICE_TABLE(pch_udc_pcidev_id) = {
                .class = (PCI_CLASS_SERIAL_USB << 8) | 0xfe,
                .class_mask = 0xffffffff,
        },
+       {
+               PCI_DEVICE(PCI_VENDOR_ID_ROHM, PCI_DEVICE_ID_ML7213_IOH_UDC),
+               .class = (PCI_CLASS_SERIAL_USB << 8) | 0xfe,
+               .class_mask = 0xffffffff,
+       },
        { 0 },
 };
 
index 2fc8636316c550eb8019799e99299e5551f2aac0..12ff6cffedc9d481fd2429fc537acd9d8ea6d41d 100644 (file)
@@ -131,31 +131,31 @@ static struct printer_dev usb_printer_gadget;
  * parameters are in UTF-8 (superset of ASCII's 7 bit characters).
  */
 
-static ushort __initdata idVendor;
+static ushort idVendor;
 module_param(idVendor, ushort, S_IRUGO);
 MODULE_PARM_DESC(idVendor, "USB Vendor ID");
 
-static ushort __initdata idProduct;
+static ushort idProduct;
 module_param(idProduct, ushort, S_IRUGO);
 MODULE_PARM_DESC(idProduct, "USB Product ID");
 
-static ushort __initdata bcdDevice;
+static ushort bcdDevice;
 module_param(bcdDevice, ushort, S_IRUGO);
 MODULE_PARM_DESC(bcdDevice, "USB Device version (BCD)");
 
-static char *__initdata iManufacturer;
+static char *iManufacturer;
 module_param(iManufacturer, charp, S_IRUGO);
 MODULE_PARM_DESC(iManufacturer, "USB Manufacturer string");
 
-static char *__initdata iProduct;
+static char *iProduct;
 module_param(iProduct, charp, S_IRUGO);
 MODULE_PARM_DESC(iProduct, "USB Product string");
 
-static char *__initdata iSerialNum;
+static char *iSerialNum;
 module_param(iSerialNum, charp, S_IRUGO);
 MODULE_PARM_DESC(iSerialNum, "1");
 
-static char *__initdata iPNPstring;
+static char *iPNPstring;
 module_param(iPNPstring, charp, S_IRUGO);
 MODULE_PARM_DESC(iPNPstring, "MFG:linux;MDL:g_printer;CLS:PRINTER;SN:1;");
 
@@ -1596,13 +1596,12 @@ cleanup(void)
        int status;
 
        mutex_lock(&usb_printer_gadget.lock_printer_io);
-       class_destroy(usb_gadget_class);
-       unregister_chrdev_region(g_printer_devno, 2);
-
        status = usb_gadget_unregister_driver(&printer_driver);
        if (status)
                ERROR(dev, "usb_gadget_unregister_driver %x\n", status);
 
+       unregister_chrdev_region(g_printer_devno, 2);
+       class_destroy(usb_gadget_class);
        mutex_unlock(&usb_printer_gadget.lock_printer_io);
 }
 module_exit(cleanup);
index 86e42892016d29564dd89bef520138cadd3263ce..5c761df7fa83cfb212943009bc7a10beb4a619fe 100644 (file)
@@ -52,7 +52,6 @@ static int usb_hcd_fsl_probe(const struct hc_driver *driver,
        struct resource *res;
        int irq;
        int retval;
-       unsigned int temp;
 
        pr_debug("initializing FSL-SOC USB Controller\n");
 
@@ -126,18 +125,6 @@ static int usb_hcd_fsl_probe(const struct hc_driver *driver,
                goto err3;
        }
 
-       /*
-        * Check if it is MPC5121 SoC, otherwise set pdata->have_sysif_regs
-        * flag for 83xx or 8536 system interface registers.
-        */
-       if (pdata->big_endian_mmio)
-               temp = in_be32(hcd->regs + FSL_SOC_USB_ID);
-       else
-               temp = in_le32(hcd->regs + FSL_SOC_USB_ID);
-
-       if ((temp & ID_MSK) != (~((temp & NID_MSK) >> 8) & ID_MSK))
-               pdata->have_sysif_regs = 1;
-
        /* Enable USB controller, 83xx or 8536 */
        if (pdata->have_sysif_regs)
                setbits32(hcd->regs + FSL_SOC_USB_CTRL, 0x4);
index 2c8353795226b7f87a3c957c5bc21f6224c477b3..3fabed33d940d9f2f6bbb094de137b82f5282bbc 100644 (file)
@@ -19,9 +19,6 @@
 #define _EHCI_FSL_H
 
 /* offsets for the non-ehci registers in the FSL SOC USB controller */
-#define FSL_SOC_USB_ID         0x0
-#define ID_MSK                 0x3f
-#define NID_MSK                        0x3f00
 #define FSL_SOC_USB_ULPIVP     0x170
 #define FSL_SOC_USB_PORTSC1    0x184
 #define PORT_PTS_MSK           (3<<30)
index 6fee3cd58efe30db9f74137c47cdbf16339c5863..74dcf49bd015a99384b04678dff4f9f576f4a809 100644 (file)
@@ -572,6 +572,8 @@ static int ehci_init(struct usb_hcd *hcd)
        ehci->iaa_watchdog.function = ehci_iaa_watchdog;
        ehci->iaa_watchdog.data = (unsigned long) ehci;
 
+       hcc_params = ehci_readl(ehci, &ehci->caps->hcc_params);
+
        /*
         * hw default: 1K periodic list heads, one per frame.
         * periodic_size can shrink by USBCMD update if hcc_params allows.
@@ -579,11 +581,20 @@ static int ehci_init(struct usb_hcd *hcd)
        ehci->periodic_size = DEFAULT_I_TDPS;
        INIT_LIST_HEAD(&ehci->cached_itd_list);
        INIT_LIST_HEAD(&ehci->cached_sitd_list);
+
+       if (HCC_PGM_FRAMELISTLEN(hcc_params)) {
+               /* periodic schedule size can be smaller than default */
+               switch (EHCI_TUNE_FLS) {
+               case 0: ehci->periodic_size = 1024; break;
+               case 1: ehci->periodic_size = 512; break;
+               case 2: ehci->periodic_size = 256; break;
+               default:        BUG();
+               }
+       }
        if ((retval = ehci_mem_init(ehci, GFP_KERNEL)) < 0)
                return retval;
 
        /* controllers may cache some of the periodic schedule ... */
-       hcc_params = ehci_readl(ehci, &ehci->caps->hcc_params);
        if (HCC_ISOC_CACHE(hcc_params))         // full frame cache
                ehci->i_thresh = 2 + 8;
        else                                    // N microframes cached
@@ -637,12 +648,6 @@ static int ehci_init(struct usb_hcd *hcd)
                /* periodic schedule size can be smaller than default */
                temp &= ~(3 << 2);
                temp |= (EHCI_TUNE_FLS << 2);
-               switch (EHCI_TUNE_FLS) {
-               case 0: ehci->periodic_size = 1024; break;
-               case 1: ehci->periodic_size = 512; break;
-               case 2: ehci->periodic_size = 256; break;
-               default:        BUG();
-               }
        }
        if (HCC_LPM(hcc_params)) {
                /* support link power management EHCI 1.1 addendum */
index fa59b26fc5bce0c7812dd933a169fddb52ef2837..c8e360d7d9759dbde4eff329781c252d5d27e806 100644 (file)
 #include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/usb/otg.h>
+#include <linux/usb/ulpi.h>
 #include <linux/slab.h>
 
 #include <mach/mxc_ehci.h>
 
+#include <asm/mach-types.h>
+
 #define ULPI_VIEWPORT_OFFSET   0x170
 
 struct ehci_mxc_priv {
@@ -114,6 +117,7 @@ static int ehci_mxc_drv_probe(struct platform_device *pdev)
        struct usb_hcd *hcd;
        struct resource *res;
        int irq, ret;
+       unsigned int flags;
        struct ehci_mxc_priv *priv;
        struct device *dev = &pdev->dev;
        struct ehci_hcd *ehci;
@@ -177,8 +181,8 @@ static int ehci_mxc_drv_probe(struct platform_device *pdev)
                clk_enable(priv->ahbclk);
        }
 
-       /* "dr" device has its own clock */
-       if (pdev->id == 0) {
+       /* "dr" device has its own clock on i.MX51 */
+       if (cpu_is_mx51() && (pdev->id == 0)) {
                priv->phy1clk = clk_get(dev, "usb_phy1");
                if (IS_ERR(priv->phy1clk)) {
                        ret = PTR_ERR(priv->phy1clk);
@@ -240,6 +244,23 @@ static int ehci_mxc_drv_probe(struct platform_device *pdev)
        if (ret)
                goto err_add;
 
+       if (pdata->otg) {
+               /*
+                * efikamx and efikasb have some hardware bug which is
+                * preventing usb to work unless CHRGVBUS is set.
+                * It's in violation of USB specs
+                */
+               if (machine_is_mx51_efikamx() || machine_is_mx51_efikasb()) {
+                       flags = otg_io_read(pdata->otg, ULPI_OTG_CTRL);
+                       flags |= ULPI_OTG_CTRL_CHRGVBUS;
+                       ret = otg_io_write(pdata->otg, flags, ULPI_OTG_CTRL);
+                       if (ret) {
+                               dev_err(dev, "unable to set CHRVBUS\n");
+                               goto err_add;
+                       }
+               }
+       }
+
        return 0;
 
 err_add:
index 76179c39c0e3490b0a5e9240619b9e4ba18affb9..bed07d4aab0638c6065f1d1eb87350bf0f0fc428 100644 (file)
@@ -44,28 +44,35 @@ static int ehci_pci_reinit(struct ehci_hcd *ehci, struct pci_dev *pdev)
        return 0;
 }
 
-static int ehci_quirk_amd_SB800(struct ehci_hcd *ehci)
+static int ehci_quirk_amd_hudson(struct ehci_hcd *ehci)
 {
        struct pci_dev *amd_smbus_dev;
        u8 rev = 0;
 
        amd_smbus_dev = pci_get_device(PCI_VENDOR_ID_ATI, 0x4385, NULL);
-       if (!amd_smbus_dev)
-               return 0;
-
-       pci_read_config_byte(amd_smbus_dev, PCI_REVISION_ID, &rev);
-       if (rev < 0x40) {
-               pci_dev_put(amd_smbus_dev);
-               amd_smbus_dev = NULL;
-               return 0;
+       if (amd_smbus_dev) {
+               pci_read_config_byte(amd_smbus_dev, PCI_REVISION_ID, &rev);
+               if (rev < 0x40) {
+                       pci_dev_put(amd_smbus_dev);
+                       amd_smbus_dev = NULL;
+                       return 0;
+               }
+       } else {
+               amd_smbus_dev = pci_get_device(PCI_VENDOR_ID_AMD, 0x780b, NULL);
+               if (!amd_smbus_dev)
+                       return 0;
+               pci_read_config_byte(amd_smbus_dev, PCI_REVISION_ID, &rev);
+               if (rev < 0x11 || rev > 0x18) {
+                       pci_dev_put(amd_smbus_dev);
+                       amd_smbus_dev = NULL;
+                       return 0;
+               }
        }
 
        if (!amd_nb_dev)
                amd_nb_dev = pci_get_device(PCI_VENDOR_ID_AMD, 0x1510, NULL);
-       if (!amd_nb_dev)
-               ehci_err(ehci, "QUIRK: unable to get AMD NB device\n");
 
-       ehci_info(ehci, "QUIRK: Enable AMD SB800 L1 fix\n");
+       ehci_info(ehci, "QUIRK: Enable exception for AMD Hudson ASPM\n");
 
        pci_dev_put(amd_smbus_dev);
        amd_smbus_dev = NULL;
@@ -131,7 +138,7 @@ static int ehci_pci_setup(struct usb_hcd *hcd)
        /* cache this readonly data; minimize chip reads */
        ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params);
 
-       if (ehci_quirk_amd_SB800(ehci))
+       if (ehci_quirk_amd_hudson(ehci))
                ehci->amd_l1_fix = 1;
 
        retval = ehci_halt(ehci);
index 574b99ea07009a2467daa902d997a58c1b8657e9..79a66d622f9c265bdc2c8f6780f0df7c299a1235 100644 (file)
@@ -262,19 +262,24 @@ static void fsl_usb2_mpc5121_exit(struct platform_device *pdev)
        }
 }
 
-struct fsl_usb2_platform_data fsl_usb2_mpc5121_pd = {
+static struct fsl_usb2_platform_data fsl_usb2_mpc5121_pd = {
        .big_endian_desc = 1,
        .big_endian_mmio = 1,
        .es = 1,
+       .have_sysif_regs = 0,
        .le_setup_buf = 1,
        .init = fsl_usb2_mpc5121_init,
        .exit = fsl_usb2_mpc5121_exit,
 };
 #endif /* CONFIG_PPC_MPC512x */
 
+static struct fsl_usb2_platform_data fsl_usb2_mpc8xxx_pd = {
+       .have_sysif_regs = 1,
+};
+
 static const struct of_device_id fsl_usb2_mph_dr_of_match[] = {
-       { .compatible = "fsl-usb2-mph", },
-       { .compatible = "fsl-usb2-dr", },
+       { .compatible = "fsl-usb2-mph", .data = &fsl_usb2_mpc8xxx_pd, },
+       { .compatible = "fsl-usb2-dr", .data = &fsl_usb2_mpc8xxx_pd, },
 #ifdef CONFIG_PPC_MPC512x
        { .compatible = "fsl,mpc5121-usb2-dr", .data = &fsl_usb2_mpc5121_pd, },
 #endif
index df558f6f84e30eff6d6df0fc61c3bd67fb183387..3e8211c1ce5adaee7ebfd4ecb59a4ee6fbfa160f 100644 (file)
@@ -308,11 +308,8 @@ static int room_on_ring(struct xhci_hcd *xhci, struct xhci_ring *ring,
 /* Ring the host controller doorbell after placing a command on the ring */
 void xhci_ring_cmd_db(struct xhci_hcd *xhci)
 {
-       u32 temp;
-
        xhci_dbg(xhci, "// Ding dong!\n");
-       temp = xhci_readl(xhci, &xhci->dba->doorbell[0]) & DB_MASK;
-       xhci_writel(xhci, temp | DB_TARGET_HOST, &xhci->dba->doorbell[0]);
+       xhci_writel(xhci, DB_VALUE_HOST, &xhci->dba->doorbell[0]);
        /* Flush PCI posted writes */
        xhci_readl(xhci, &xhci->dba->doorbell[0]);
 }
@@ -322,26 +319,24 @@ void xhci_ring_ep_doorbell(struct xhci_hcd *xhci,
                unsigned int ep_index,
                unsigned int stream_id)
 {
-       struct xhci_virt_ep *ep;
-       unsigned int ep_state;
-       u32 field;
        __u32 __iomem *db_addr = &xhci->dba->doorbell[slot_id];
+       struct xhci_virt_ep *ep = &xhci->devs[slot_id]->eps[ep_index];
+       unsigned int ep_state = ep->ep_state;
 
-       ep = &xhci->devs[slot_id]->eps[ep_index];
-       ep_state = ep->ep_state;
        /* Don't ring the doorbell for this endpoint if there are pending
-        * cancellations because the we don't want to interrupt processing.
+        * cancellations because we don't want to interrupt processing.
         * We don't want to restart any stream rings if there's a set dequeue
         * pointer command pending because the device can choose to start any
         * stream once the endpoint is on the HW schedule.
         * FIXME - check all the stream rings for pending cancellations.
         */
-       if (!(ep_state & EP_HALT_PENDING) && !(ep_state & SET_DEQ_PENDING)
-                       && !(ep_state & EP_HALTED)) {
-               field = xhci_readl(xhci, db_addr) & DB_MASK;
-               field |= EPI_TO_DB(ep_index) | STREAM_ID_TO_DB(stream_id);
-               xhci_writel(xhci, field, db_addr);
-       }
+       if ((ep_state & EP_HALT_PENDING) || (ep_state & SET_DEQ_PENDING) ||
+           (ep_state & EP_HALTED))
+               return;
+       xhci_writel(xhci, DB_VALUE(ep_index, stream_id), db_addr);
+       /* The CPU has better things to do at this point than wait for a
+        * write-posting flush.  It'll get there soon enough.
+        */
 }
 
 /* Ring the doorbell for any rings with pending URBs */
@@ -1188,7 +1183,7 @@ static void handle_port_status(struct xhci_hcd *xhci,
 
        addr = &xhci->op_regs->port_status_base + NUM_PORT_REGS * (port_id - 1);
        temp = xhci_readl(xhci, addr);
-       if ((temp & PORT_CONNECT) && (hcd->state == HC_STATE_SUSPENDED)) {
+       if (hcd->state == HC_STATE_SUSPENDED) {
                xhci_dbg(xhci, "resume root hub\n");
                usb_hcd_resume_root_hub(hcd);
        }
@@ -1710,8 +1705,7 @@ static int process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_td *td,
                /* Others already handled above */
                break;
        }
-       dev_dbg(&td->urb->dev->dev,
-                       "ep %#x - asked for %d bytes, "
+       xhci_dbg(xhci, "ep %#x - asked for %d bytes, "
                        "%d bytes untransferred\n",
                        td->urb->ep->desc.bEndpointAddress,
                        td->urb->transfer_buffer_length,
@@ -2389,7 +2383,8 @@ static unsigned int count_sg_trbs_needed(struct xhci_hcd *xhci, struct urb *urb)
        }
        xhci_dbg(xhci, "\n");
        if (!in_interrupt())
-               dev_dbg(&urb->dev->dev, "ep %#x - urb len = %d, sglist used, num_trbs = %d\n",
+               xhci_dbg(xhci, "ep %#x - urb len = %d, sglist used, "
+                               "num_trbs = %d\n",
                                urb->ep->desc.bEndpointAddress,
                                urb->transfer_buffer_length,
                                num_trbs);
@@ -2414,14 +2409,17 @@ static void check_trb_math(struct urb *urb, int num_trbs, int running_total)
 
 static void giveback_first_trb(struct xhci_hcd *xhci, int slot_id,
                unsigned int ep_index, unsigned int stream_id, int start_cycle,
-               struct xhci_generic_trb *start_trb, struct xhci_td *td)
+               struct xhci_generic_trb *start_trb)
 {
        /*
         * Pass all the TRBs to the hardware at once and make sure this write
         * isn't reordered.
         */
        wmb();
-       start_trb->field[3] |= start_cycle;
+       if (start_cycle)
+               start_trb->field[3] |= start_cycle;
+       else
+               start_trb->field[3] &= ~0x1;
        xhci_ring_ep_doorbell(xhci, slot_id, ep_index, stream_id);
 }
 
@@ -2449,7 +2447,7 @@ int xhci_queue_intr_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
         * to set the polling interval (once the API is added).
         */
        if (xhci_interval != ep_interval) {
-               if (!printk_ratelimit())
+               if (printk_ratelimit())
                        dev_dbg(&urb->dev->dev, "Driver uses different interval"
                                        " (%d microframe%s) than xHCI "
                                        "(%d microframe%s)\n",
@@ -2551,9 +2549,11 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
                u32 remainder = 0;
 
                /* Don't change the cycle bit of the first TRB until later */
-               if (first_trb)
+               if (first_trb) {
                        first_trb = false;
-               else
+                       if (start_cycle == 0)
+                               field |= 0x1;
+               } else
                        field |= ep_ring->cycle_state;
 
                /* Chain all the TRBs together; clear the chain bit in the last
@@ -2625,7 +2625,7 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
 
        check_trb_math(urb, num_trbs, running_total);
        giveback_first_trb(xhci, slot_id, ep_index, urb->stream_id,
-                       start_cycle, start_trb, td);
+                       start_cycle, start_trb);
        return 0;
 }
 
@@ -2671,7 +2671,8 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
        /* FIXME: this doesn't deal with URB_ZERO_PACKET - need one more */
 
        if (!in_interrupt())
-               dev_dbg(&urb->dev->dev, "ep %#x - urb len = %#x (%d), addr = %#llx, num_trbs = %d\n",
+               xhci_dbg(xhci, "ep %#x - urb len = %#x (%d), "
+                               "addr = %#llx, num_trbs = %d\n",
                                urb->ep->desc.bEndpointAddress,
                                urb->transfer_buffer_length,
                                urb->transfer_buffer_length,
@@ -2711,9 +2712,11 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
                field = 0;
 
                /* Don't change the cycle bit of the first TRB until later */
-               if (first_trb)
+               if (first_trb) {
                        first_trb = false;
-               else
+                       if (start_cycle == 0)
+                               field |= 0x1;
+               } else
                        field |= ep_ring->cycle_state;
 
                /* Chain all the TRBs together; clear the chain bit in the last
@@ -2757,7 +2760,7 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
 
        check_trb_math(urb, num_trbs, running_total);
        giveback_first_trb(xhci, slot_id, ep_index, urb->stream_id,
-                       start_cycle, start_trb, td);
+                       start_cycle, start_trb);
        return 0;
 }
 
@@ -2818,13 +2821,17 @@ int xhci_queue_ctrl_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
        /* Queue setup TRB - see section 6.4.1.2.1 */
        /* FIXME better way to translate setup_packet into two u32 fields? */
        setup = (struct usb_ctrlrequest *) urb->setup_packet;
+       field = 0;
+       field |= TRB_IDT | TRB_TYPE(TRB_SETUP);
+       if (start_cycle == 0)
+               field |= 0x1;
        queue_trb(xhci, ep_ring, false, true,
                        /* FIXME endianness is probably going to bite my ass here. */
                        setup->bRequestType | setup->bRequest << 8 | setup->wValue << 16,
                        setup->wIndex | setup->wLength << 16,
                        TRB_LEN(8) | TRB_INTR_TARGET(0),
                        /* Immediate data in pointer */
-                       TRB_IDT | TRB_TYPE(TRB_SETUP));
+                       field);
 
        /* If there's data, queue data TRBs */
        field = 0;
@@ -2859,7 +2866,7 @@ int xhci_queue_ctrl_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
                        field | TRB_IOC | TRB_TYPE(TRB_STATUS) | ep_ring->cycle_state);
 
        giveback_first_trb(xhci, slot_id, ep_index, 0,
-                       start_cycle, start_trb, td);
+                       start_cycle, start_trb);
        return 0;
 }
 
@@ -2900,6 +2907,7 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
        int running_total, trb_buff_len, td_len, td_remain_len, ret;
        u64 start_addr, addr;
        int i, j;
+       bool more_trbs_coming;
 
        ep_ring = xhci->devs[slot_id]->eps[ep_index].ring;
 
@@ -2910,7 +2918,7 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
        }
 
        if (!in_interrupt())
-               dev_dbg(&urb->dev->dev, "ep %#x - urb len = %#x (%d),"
+               xhci_dbg(xhci, "ep %#x - urb len = %#x (%d),"
                                " addr = %#llx, num_tds = %d\n",
                                urb->ep->desc.bEndpointAddress,
                                urb->transfer_buffer_length,
@@ -2950,7 +2958,10 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
                                field |= TRB_TYPE(TRB_ISOC);
                                /* Assume URB_ISO_ASAP is set */
                                field |= TRB_SIA;
-                               if (i > 0)
+                               if (i == 0) {
+                                       if (start_cycle == 0)
+                                               field |= 0x1;
+                               } else
                                        field |= ep_ring->cycle_state;
                                first_trb = false;
                        } else {
@@ -2965,9 +2976,11 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
                         */
                        if (j < trbs_per_td - 1) {
                                field |= TRB_CHAIN;
+                               more_trbs_coming = true;
                        } else {
                                td->last_trb = ep_ring->enqueue;
                                field |= TRB_IOC;
+                               more_trbs_coming = false;
                        }
 
                        /* Calculate TRB length */
@@ -2980,7 +2993,7 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
                        length_field = TRB_LEN(trb_buff_len) |
                                remainder |
                                TRB_INTR_TARGET(0);
-                       queue_trb(xhci, ep_ring, false, false,
+                       queue_trb(xhci, ep_ring, false, more_trbs_coming,
                                lower_32_bits(addr),
                                upper_32_bits(addr),
                                length_field,
@@ -3003,10 +3016,8 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
                }
        }
 
-       wmb();
-       start_trb->field[3] |= start_cycle;
-
-       xhci_ring_ep_doorbell(xhci, slot_id, ep_index, urb->stream_id);
+       giveback_first_trb(xhci, slot_id, ep_index, urb->stream_id,
+                       start_cycle, start_trb);
        return 0;
 }
 
@@ -3064,7 +3075,7 @@ int xhci_queue_isoc_tx_prepare(struct xhci_hcd *xhci, gfp_t mem_flags,
         * to set the polling interval (once the API is added).
         */
        if (xhci_interval != ep_interval) {
-               if (!printk_ratelimit())
+               if (printk_ratelimit())
                        dev_dbg(&urb->dev->dev, "Driver uses different interval"
                                        " (%d microframe%s) than xHCI "
                                        "(%d microframe%s)\n",
index 45e4a3108cc31285fcb41c7a83972a621a72a68b..34cf4e1658773d870fc857c1338e4fe01df3af02 100644 (file)
@@ -226,7 +226,8 @@ static int xhci_setup_msi(struct xhci_hcd *xhci)
 static int xhci_setup_msix(struct xhci_hcd *xhci)
 {
        int i, ret = 0;
-       struct pci_dev *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller);
+       struct usb_hcd *hcd = xhci_to_hcd(xhci);
+       struct pci_dev *pdev = to_pci_dev(hcd->self.controller);
 
        /*
         * calculate number of msi-x vectors supported.
@@ -265,6 +266,7 @@ static int xhci_setup_msix(struct xhci_hcd *xhci)
                        goto disable_msix;
        }
 
+       hcd->msix_enabled = 1;
        return ret;
 
 disable_msix:
@@ -280,7 +282,8 @@ free_entries:
 /* Free any IRQs and disable MSI-X */
 static void xhci_cleanup_msix(struct xhci_hcd *xhci)
 {
-       struct pci_dev *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller);
+       struct usb_hcd *hcd = xhci_to_hcd(xhci);
+       struct pci_dev *pdev = to_pci_dev(hcd->self.controller);
 
        xhci_free_irq(xhci);
 
@@ -292,6 +295,7 @@ static void xhci_cleanup_msix(struct xhci_hcd *xhci)
                pci_disable_msi(pdev);
        }
 
+       hcd->msix_enabled = 0;
        return;
 }
 
@@ -508,9 +512,10 @@ void xhci_stop(struct usb_hcd *hcd)
        spin_lock_irq(&xhci->lock);
        xhci_halt(xhci);
        xhci_reset(xhci);
-       xhci_cleanup_msix(xhci);
        spin_unlock_irq(&xhci->lock);
 
+       xhci_cleanup_msix(xhci);
+
 #ifdef CONFIG_USB_XHCI_HCD_DEBUGGING
        /* Tell the event ring poll function not to reschedule */
        xhci->zombie = 1;
@@ -544,9 +549,10 @@ void xhci_shutdown(struct usb_hcd *hcd)
 
        spin_lock_irq(&xhci->lock);
        xhci_halt(xhci);
-       xhci_cleanup_msix(xhci);
        spin_unlock_irq(&xhci->lock);
 
+       xhci_cleanup_msix(xhci);
+
        xhci_dbg(xhci, "xhci_shutdown completed - status = %x\n",
                    xhci_readl(xhci, &xhci->op_regs->status));
 }
@@ -647,6 +653,7 @@ int xhci_suspend(struct xhci_hcd *xhci)
        int                     rc = 0;
        struct usb_hcd          *hcd = xhci_to_hcd(xhci);
        u32                     command;
+       int                     i;
 
        spin_lock_irq(&xhci->lock);
        clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
@@ -677,10 +684,15 @@ int xhci_suspend(struct xhci_hcd *xhci)
                spin_unlock_irq(&xhci->lock);
                return -ETIMEDOUT;
        }
-       /* step 5: remove core well power */
-       xhci_cleanup_msix(xhci);
        spin_unlock_irq(&xhci->lock);
 
+       /* step 5: remove core well power */
+       /* synchronize irq when using MSI-X */
+       if (xhci->msix_entries) {
+               for (i = 0; i < xhci->msix_count; i++)
+                       synchronize_irq(xhci->msix_entries[i].vector);
+       }
+
        return rc;
 }
 
@@ -694,7 +706,6 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
 {
        u32                     command, temp = 0;
        struct usb_hcd          *hcd = xhci_to_hcd(xhci);
-       struct pci_dev          *pdev = to_pci_dev(hcd->self.controller);
        int     old_state, retval;
 
        old_state = hcd->state;
@@ -729,9 +740,8 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
                xhci_dbg(xhci, "Stop HCD\n");
                xhci_halt(xhci);
                xhci_reset(xhci);
-               if (hibernated)
-                       xhci_cleanup_msix(xhci);
                spin_unlock_irq(&xhci->lock);
+               xhci_cleanup_msix(xhci);
 
 #ifdef CONFIG_USB_XHCI_HCD_DEBUGGING
                /* Tell the event ring poll function not to reschedule */
@@ -765,30 +775,6 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
                return retval;
        }
 
-       spin_unlock_irq(&xhci->lock);
-       /* Re-setup MSI-X */
-       if (hcd->irq)
-               free_irq(hcd->irq, hcd);
-       hcd->irq = -1;
-
-       retval = xhci_setup_msix(xhci);
-       if (retval)
-               /* fall back to msi*/
-               retval = xhci_setup_msi(xhci);
-
-       if (retval) {
-               /* fall back to legacy interrupt*/
-               retval = request_irq(pdev->irq, &usb_hcd_irq, IRQF_SHARED,
-                                       hcd->irq_descr, hcd);
-               if (retval) {
-                       xhci_err(xhci, "request interrupt %d failed\n",
-                                       pdev->irq);
-                       return retval;
-               }
-               hcd->irq = pdev->irq;
-       }
-
-       spin_lock_irq(&xhci->lock);
        /* step 4: set Run/Stop bit */
        command = xhci_readl(xhci, &xhci->op_regs->command);
        command |= CMD_RUN;
@@ -2445,8 +2431,12 @@ int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev)
                xhci_err(xhci, "Error while assigning device slot ID\n");
                return 0;
        }
-       /* xhci_alloc_virt_device() does not touch rings; no need to lock */
-       if (!xhci_alloc_virt_device(xhci, xhci->slot_id, udev, GFP_KERNEL)) {
+       /* xhci_alloc_virt_device() does not touch rings; no need to lock.
+        * Use GFP_NOIO, since this function can be called from
+        * xhci_discover_or_reset_device(), which may be called as part of
+        * mass storage driver error handling.
+        */
+       if (!xhci_alloc_virt_device(xhci, xhci->slot_id, udev, GFP_NOIO)) {
                /* Disable slot, if we can do it without mem alloc */
                xhci_warn(xhci, "Could not allocate xHCI USB device data structures\n");
                spin_lock_irqsave(&xhci->lock, flags);
index 170c367112d2e8046f39ec596703c126f2050f84..7f236fd220151ca5fa4f43cee6733e97867f2d5f 100644 (file)
@@ -436,22 +436,18 @@ struct xhci_run_regs {
 /**
  * struct doorbell_array
  *
+ * Bits  0 -  7: Endpoint target
+ * Bits  8 - 15: RsvdZ
+ * Bits 16 - 31: Stream ID
+ *
  * Section 5.6
  */
 struct xhci_doorbell_array {
        u32     doorbell[256];
 };
 
-#define        DB_TARGET_MASK          0xFFFFFF00
-#define        DB_STREAM_ID_MASK       0x0000FFFF
-#define        DB_TARGET_HOST          0x0
-#define        DB_STREAM_ID_HOST       0x0
-#define        DB_MASK                 (0xff << 8)
-
-/* Endpoint Target - bits 0:7 */
-#define EPI_TO_DB(p)           (((p) + 1) & 0xff)
-#define STREAM_ID_TO_DB(p)     (((p) & 0xffff) << 16)
-
+#define DB_VALUE(ep, stream)   ((((ep) + 1) & 0xff) | ((stream) << 16))
+#define DB_VALUE_HOST          0x00000000
 
 /**
  * struct xhci_protocol_caps
index 1732d9bc097eb1ff1b867a963e0a80d7ea6b7a8d..1616ad1793a4ac28970e33a5b0a58efd0fcb56a6 100644 (file)
@@ -45,7 +45,7 @@ struct usb_led {
 
 static void change_color(struct usb_led *led)
 {
-       int retval;
+       int retval = 0;
        unsigned char *buffer;
 
        buffer = kmalloc(8, GFP_KERNEL);
index 4ff21587ab03214373364681a664df5d56a66a16..f7a2057380321fa7c102b140ce0bf2f4374e9db1 100644 (file)
@@ -776,7 +776,6 @@ static const struct usb_device_id uss720_table[] = {
        { USB_DEVICE(0x0557, 0x2001) },
        { USB_DEVICE(0x0729, 0x1284) },
        { USB_DEVICE(0x1293, 0x0002) },
-       { USB_DEVICE(0x1293, 0x0002) },
        { USB_DEVICE(0x050d, 0x0002) },
        { }                                             /* Terminating entry */
 };
index e70014ab0976ae0ea737c8faa210544c233d4dcd..8acf165fe13b84e4fdefcdd8e94d8b008ead9666 100644 (file)
@@ -132,6 +132,8 @@ static int __devinit nop_usb_xceiv_probe(struct platform_device *pdev)
 
        platform_set_drvdata(pdev, nop);
 
+       BLOCKING_INIT_NOTIFIER_HEAD(&nop->otg.notifier);
+
        return 0;
 exit:
        kfree(nop);
index 059d9ac0ab5b14f4bb80895d1d69fbeb921970d9..770d799d5afb8ec0eadd650dc2c1f348dc7648c5 100644 (file)
@@ -45,7 +45,7 @@ struct ulpi_info {
 /* ULPI hardcoded IDs, used for probing */
 static struct ulpi_info ulpi_ids[] = {
        ULPI_INFO(ULPI_ID(0x04cc, 0x1504), "NXP ISP1504"),
-       ULPI_INFO(ULPI_ID(0x0424, 0x0006), "SMSC USB3319"),
+       ULPI_INFO(ULPI_ID(0x0424, 0x0006), "SMSC USB331x"),
 };
 
 static int ulpi_set_otg_flags(struct otg_transceiver *otg)
index 63f7cc45bcaca15b34691ce081fdd30b7b0007d8..7b8815ddf3688e725a1cbde438d1b74ea6120999 100644 (file)
@@ -486,12 +486,22 @@ static void ch341_read_int_callback(struct urb *urb)
        if (actual_length >= 4) {
                struct ch341_private *priv = usb_get_serial_port_data(port);
                unsigned long flags;
+               u8 prev_line_status = priv->line_status;
 
                spin_lock_irqsave(&priv->lock, flags);
                priv->line_status = (~(data[2])) & CH341_BITS_MODEM_STAT;
                if ((data[1] & CH341_MULT_STAT))
                        priv->multi_status_change = 1;
                spin_unlock_irqrestore(&priv->lock, flags);
+
+               if ((priv->line_status ^ prev_line_status) & CH341_BIT_DCD) {
+                       struct tty_struct *tty = tty_port_tty_get(&port->port);
+                       if (tty)
+                               usb_serial_handle_dcd_change(port, tty,
+                                           priv->line_status & CH341_BIT_DCD);
+                       tty_kref_put(tty);
+               }
+
                wake_up_interruptible(&priv->delta_msr_wait);
        }
 
index 8d7731dbf478f9592d8dff350374dc6375649c44..735ea03157abad3e9692978767a9d0e61d92eabd 100644 (file)
@@ -49,7 +49,6 @@ 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_dtr_rts(struct usb_serial_port *p, int on);
-static int cp210x_carrier_raised(struct usb_serial_port *p);
 
 static int debug;
 
@@ -87,7 +86,6 @@ static const struct usb_device_id id_table[] = {
        { USB_DEVICE(0x10C4, 0x8115) }, /* Arygon NFC/Mifare Reader */
        { USB_DEVICE(0x10C4, 0x813D) }, /* Burnside Telecom Deskmobile */
        { USB_DEVICE(0x10C4, 0x813F) }, /* Tams Master Easy Control */
-       { USB_DEVICE(0x10C4, 0x8149) }, /* West Mountain Radio Computerized Battery Analyzer */
        { USB_DEVICE(0x10C4, 0x814A) }, /* West Mountain Radio RIGblaster P&P */
        { USB_DEVICE(0x10C4, 0x814B) }, /* West Mountain Radio RIGtalk */
        { USB_DEVICE(0x10C4, 0x8156) }, /* B&G H3000 link cable */
@@ -110,7 +108,9 @@ static const struct usb_device_id id_table[] = {
        { USB_DEVICE(0x10C4, 0x8341) }, /* Siemens MC35PU GPRS Modem */
        { USB_DEVICE(0x10C4, 0x8382) }, /* Cygnal Integrated Products, Inc. */
        { USB_DEVICE(0x10C4, 0x83A8) }, /* Amber Wireless AMB2560 */
+       { USB_DEVICE(0x10C4, 0x83D8) }, /* DekTec DTA Plus VHF/UHF Booster/Attenuator */
        { USB_DEVICE(0x10C4, 0x8411) }, /* Kyocera GPS Module */
+       { USB_DEVICE(0x10C4, 0x8418) }, /* IRZ Automation Teleport SG-10 GSM/GPRS Modem */
        { USB_DEVICE(0x10C4, 0x846E) }, /* BEI USB Sensor Interface (VCP) */
        { USB_DEVICE(0x10C4, 0x8477) }, /* Balluff RFID */
        { USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */
@@ -165,8 +165,7 @@ static struct usb_serial_driver cp210x_device = {
        .tiocmget               = cp210x_tiocmget,
        .tiocmset               = cp210x_tiocmset,
        .attach                 = cp210x_startup,
-       .dtr_rts                = cp210x_dtr_rts,
-       .carrier_raised         = cp210x_carrier_raised
+       .dtr_rts                = cp210x_dtr_rts
 };
 
 /* Config request types */
@@ -765,15 +764,6 @@ 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 b92070c103cd4b4854ccee1aad7bc807b829b874..666e5a6edd827edcf9e7e3a2e65532104dc55ec9 100644 (file)
@@ -455,7 +455,6 @@ static int digi_write_room(struct tty_struct *tty);
 static int digi_chars_in_buffer(struct tty_struct *tty);
 static int digi_open(struct tty_struct *tty, struct usb_serial_port *port);
 static void digi_close(struct usb_serial_port *port);
-static int digi_carrier_raised(struct usb_serial_port *port);
 static void digi_dtr_rts(struct usb_serial_port *port, int on);
 static int digi_startup_device(struct usb_serial *serial);
 static int digi_startup(struct usb_serial *serial);
@@ -511,7 +510,6 @@ static struct usb_serial_driver digi_acceleport_2_device = {
        .open =                         digi_open,
        .close =                        digi_close,
        .dtr_rts =                      digi_dtr_rts,
-       .carrier_raised =               digi_carrier_raised,
        .write =                        digi_write,
        .write_room =                   digi_write_room,
        .write_bulk_callback =          digi_write_bulk_callback,
@@ -1339,14 +1337,6 @@ static void digi_dtr_rts(struct usb_serial_port *port, int on)
        digi_set_modem_signals(port, on * (TIOCM_DTR|TIOCM_RTS), 1);
 }
 
-static int digi_carrier_raised(struct usb_serial_port *port)
-{
-       struct digi_port *priv = usb_get_serial_port_data(port);
-       if (priv->dp_modem_signals & TIOCM_CD)
-               return 1;
-       return 0;
-}
-
 static int digi_open(struct tty_struct *tty, struct usb_serial_port *port)
 {
        int ret;
index a2668d08926096f827de803289fa7029d7475671..4787c0cd063fd7e8ef15082adbcc489a7bca9945 100644 (file)
@@ -676,7 +676,17 @@ static struct usb_device_id id_table_combined [] = {
        { USB_DEVICE(FTDI_VID, FTDI_PCDJ_DAC2_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_RRCIRKITS_LOCOBUFFER_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_ASK_RDR400_PID) },
-       { USB_DEVICE(ICOM_ID1_VID, ICOM_ID1_PID) },
+       { USB_DEVICE(ICOM_VID, ICOM_ID_1_PID) },
+       { USB_DEVICE(ICOM_VID, ICOM_OPC_U_UC_PID) },
+       { USB_DEVICE(ICOM_VID, ICOM_ID_RP2C1_PID) },
+       { USB_DEVICE(ICOM_VID, ICOM_ID_RP2C2_PID) },
+       { USB_DEVICE(ICOM_VID, ICOM_ID_RP2D_PID) },
+       { USB_DEVICE(ICOM_VID, ICOM_ID_RP2VT_PID) },
+       { USB_DEVICE(ICOM_VID, ICOM_ID_RP2VR_PID) },
+       { USB_DEVICE(ICOM_VID, ICOM_ID_RP4KVT_PID) },
+       { USB_DEVICE(ICOM_VID, ICOM_ID_RP4KVR_PID) },
+       { USB_DEVICE(ICOM_VID, ICOM_ID_RP2KVT_PID) },
+       { USB_DEVICE(ICOM_VID, ICOM_ID_RP2KVR_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_ACG_HFDUAL_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_YEI_SERVOCENTER31_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_THORLABS_PID) },
index bf0867285481bef7f839c5e2c2e7e5fa124f52bd..ed160def85847c44710c77c12436ec97b711c570 100644 (file)
 #define OCT_US101_PID          0x0421  /* OCT US101 USB to RS-232 */
 
 /*
- * Icom ID-1 digital transceiver
- */
-
-#define ICOM_ID1_VID            0x0C26
-#define ICOM_ID1_PID            0x0004
+ * Definitions for Icom Inc. devices
+ */
+#define ICOM_VID               0x0C26 /* Icom vendor ID */
+/* Note: ID-1 is a communications tranceiver for HAM-radio operators */
+#define ICOM_ID_1_PID          0x0004 /* ID-1 USB to RS-232 */
+/* Note: OPC is an Optional cable to connect an Icom Tranceiver */
+#define ICOM_OPC_U_UC_PID      0x0018 /* OPC-478UC, OPC-1122U cloning cable */
+/* Note: ID-RP* devices are Icom Repeater Devices for HAM-radio */
+#define ICOM_ID_RP2C1_PID      0x0009 /* ID-RP2C Asset 1 to RS-232 */
+#define ICOM_ID_RP2C2_PID      0x000A /* ID-RP2C Asset 2 to RS-232 */
+#define ICOM_ID_RP2D_PID       0x000B /* ID-RP2D configuration port*/
+#define ICOM_ID_RP2VT_PID      0x000C /* ID-RP2V Transmit config port */
+#define ICOM_ID_RP2VR_PID      0x000D /* ID-RP2V Receive config port */
+#define ICOM_ID_RP4KVT_PID     0x0010 /* ID-RP4000V Transmit config port */
+#define ICOM_ID_RP4KVR_PID     0x0011 /* ID-RP4000V Receive config port */
+#define ICOM_ID_RP2KVT_PID     0x0012 /* ID-RP2000V Transmit config port */
+#define ICOM_ID_RP2KVR_PID     0x0013 /* ID-RP2000V Receive config port */
 
 /*
  * GN Otometrics (http://www.otometrics.com)
index e6833e216fc9fa4e3628813d57f14891835caf6a..e4db5ad2bc55f1c37f2da2b15c086534e98248c7 100644 (file)
@@ -479,6 +479,26 @@ int usb_serial_handle_break(struct usb_serial_port *port)
 }
 EXPORT_SYMBOL_GPL(usb_serial_handle_break);
 
+/**
+ *     usb_serial_handle_dcd_change - handle a change of carrier detect state
+ *     @port: usb_serial_port structure for the open port
+ *     @tty: tty_struct structure for the port
+ *     @status: new carrier detect status, nonzero if active
+ */
+void usb_serial_handle_dcd_change(struct usb_serial_port *usb_port,
+                               struct tty_struct *tty, unsigned int status)
+{
+       struct tty_port *port = &usb_port->port;
+
+       dbg("%s - port %d, status %d", __func__, usb_port->number, status);
+
+       if (status)
+               wake_up_interruptible(&port->open_wait);
+       else if (tty && !C_CLOCAL(tty))
+               tty_hangup(tty);
+}
+EXPORT_SYMBOL_GPL(usb_serial_handle_dcd_change);
+
 int usb_serial_generic_resume(struct usb_serial *serial)
 {
        struct usb_serial_port *port;
index 6ab2a3f97fe832a1fdd0b2778c8bee1c713d63b7..178b22eb32b17f65a9a25ab67ad55a54ae786914 100644 (file)
@@ -199,6 +199,7 @@ static struct usb_serial_driver epic_device = {
                .name           = "epic",
        },
        .description            = "EPiC device",
+       .usb_driver             = &io_driver,
        .id_table               = Epic_port_id_table,
        .num_ports              = 1,
        .open                   = edge_open,
index 12ed594f5f808f63106ad4dedbcb9f7d35983237..99b97c04896f9402b37458106e6e3288c01575bb 100644 (file)
@@ -1275,6 +1275,7 @@ static struct usb_serial_driver iuu_device = {
                   .name = "iuu_phoenix",
                   },
        .id_table = id_table,
+       .usb_driver = &iuu_driver,
        .num_ports = 1,
        .bulk_in_size = 512,
        .bulk_out_size = 512,
index 2d8baf6ac472c3be9356f3aaa84aa1582d0fbf97..ce134dc28ddfb457997f7465d1bd1e62d0bef192 100644 (file)
@@ -546,6 +546,7 @@ static struct usb_serial_driver keyspan_pre_device = {
                .name           = "keyspan_no_firm",
        },
        .description            = "Keyspan - (without firmware)",
+       .usb_driver             = &keyspan_driver,
        .id_table               = keyspan_pre_ids,
        .num_ports              = 1,
        .attach                 = keyspan_fake_startup,
@@ -557,6 +558,7 @@ static struct usb_serial_driver keyspan_1port_device = {
                .name           = "keyspan_1",
        },
        .description            = "Keyspan 1 port adapter",
+       .usb_driver             = &keyspan_driver,
        .id_table               = keyspan_1port_ids,
        .num_ports              = 1,
        .open                   = keyspan_open,
@@ -579,6 +581,7 @@ static struct usb_serial_driver keyspan_2port_device = {
                .name           = "keyspan_2",
        },
        .description            = "Keyspan 2 port adapter",
+       .usb_driver             = &keyspan_driver,
        .id_table               = keyspan_2port_ids,
        .num_ports              = 2,
        .open                   = keyspan_open,
@@ -601,6 +604,7 @@ static struct usb_serial_driver keyspan_4port_device = {
                .name           = "keyspan_4",
        },
        .description            = "Keyspan 4 port adapter",
+       .usb_driver             = &keyspan_driver,
        .id_table               = keyspan_4port_ids,
        .num_ports              = 4,
        .open                   = keyspan_open,
index a10dd5676ccc0e70a930e0c7048daa675adc6f76..554a8693a463aabda0f4b514cad5574ab623b0be 100644 (file)
@@ -679,22 +679,6 @@ static void keyspan_pda_dtr_rts(struct usb_serial_port *port, int on)
        }
 }
 
-static int keyspan_pda_carrier_raised(struct usb_serial_port *port)
-{
-       struct usb_serial *serial = port->serial;
-       unsigned char modembits;
-
-       /* If we can read the modem status and the DCD is low then
-          carrier is not raised yet */
-       if (keyspan_pda_get_modem_info(serial, &modembits) >= 0) {
-               if (!(modembits & (1>>6)))
-                       return 0;
-       }
-       /* Carrier raised, or we failed (eg disconnected) so
-          progress accordingly */
-       return 1;
-}
-
 
 static int keyspan_pda_open(struct tty_struct *tty,
                                        struct usb_serial_port *port)
@@ -881,7 +865,6 @@ static struct usb_serial_driver keyspan_pda_device = {
        .id_table =             id_table_std,
        .num_ports =            1,
        .dtr_rts =              keyspan_pda_dtr_rts,
-       .carrier_raised =       keyspan_pda_carrier_raised,
        .open =                 keyspan_pda_open,
        .close =                keyspan_pda_close,
        .write =                keyspan_pda_write,
index cf1718394e18e3079452104948caf233292490c4..653465f61d4a9345f78a01ac9774684695c3cad4 100644 (file)
@@ -44,6 +44,7 @@ static struct usb_serial_driver moto_device = {
                .name =         "moto-modem",
        },
        .id_table =             id_table,
+       .usb_driver =           &moto_driver,
        .num_ports =            1,
 };
 
index 748778288d94b649f4dec1cbad1f25ceac85ecb6..5f46838dfee5d842aa5863fc0c13171dde45bb21 100644 (file)
@@ -382,7 +382,16 @@ static void option_instat_callback(struct urb *urb);
 #define HAIER_VENDOR_ID                                0x201e
 #define HAIER_PRODUCT_CE100                    0x2009
 
-#define CINTERION_VENDOR_ID                    0x0681
+/* Cinterion (formerly Siemens) products */
+#define SIEMENS_VENDOR_ID                              0x0681
+#define CINTERION_VENDOR_ID                            0x1e2d
+#define CINTERION_PRODUCT_HC25_MDM             0x0047
+#define CINTERION_PRODUCT_HC25_MDMNET  0x0040
+#define CINTERION_PRODUCT_HC28_MDM             0x004C
+#define CINTERION_PRODUCT_HC28_MDMNET  0x004A /* same for HC28J */
+#define CINTERION_PRODUCT_EU3_E                        0x0051
+#define CINTERION_PRODUCT_EU3_P                        0x0052
+#define CINTERION_PRODUCT_PH8                  0x0053
 
 /* Olivetti products */
 #define OLIVETTI_VENDOR_ID                     0x0b3c
@@ -944,7 +953,17 @@ static const struct usb_device_id option_ids[] = {
        { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100F) },
        { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1011)},
        { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1012)},
-       { USB_DEVICE(CINTERION_VENDOR_ID, 0x0047) },
+       /* Cinterion */
+       { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_EU3_E) },
+       { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_EU3_P) },
+       { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_PH8) },
+       { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_HC28_MDM) }, 
+       { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_HC28_MDMNET) },
+       { USB_DEVICE(SIEMENS_VENDOR_ID, CINTERION_PRODUCT_HC25_MDM) },
+       { USB_DEVICE(SIEMENS_VENDOR_ID, CINTERION_PRODUCT_HC25_MDMNET) },
+       { USB_DEVICE(SIEMENS_VENDOR_ID, CINTERION_PRODUCT_HC28_MDM) }, /* HC28 enumerates with Siemens or Cinterion VID depending on FW revision */
+       { USB_DEVICE(SIEMENS_VENDOR_ID, CINTERION_PRODUCT_HC28_MDMNET) },
+
        { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD100) },
        { USB_DEVICE(CELOT_VENDOR_ID, CELOT_PRODUCT_CT680M) }, /* CT-650 CDMA 450 1xEVDO modem */
        { USB_DEVICE(ONDA_VENDOR_ID, ONDA_MT825UP) }, /* ONDA MT825UP modem */
index 5be866bb7a4132a1e078939abda73daecaf2e434..73613205be7ad283ec9f820f86c861ca9af6dec6 100644 (file)
@@ -157,6 +157,7 @@ static struct usb_serial_driver oti6858_device = {
                .name =         "oti6858",
        },
        .id_table =             id_table,
+       .usb_driver =           &oti6858_driver,
        .num_ports =            1,
        .open =                 oti6858_open,
        .close =                oti6858_close,
index 8ae4c6cbc38a04ea250d43aad68aa43081098245..08c9181b8e4823192ec880181bcccdb1fe3b4fd2 100644 (file)
@@ -50,6 +50,7 @@ static const struct usb_device_id id_table[] = {
        { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_MMX) },
        { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_GPRS) },
        { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_HCR331) },
+       { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_MOTOROLA) },
        { USB_DEVICE(IODATA_VENDOR_ID, IODATA_PRODUCT_ID) },
        { USB_DEVICE(IODATA_VENDOR_ID, IODATA_PRODUCT_ID_RSAQ5) },
        { USB_DEVICE(ATEN_VENDOR_ID, ATEN_PRODUCT_ID) },
@@ -677,9 +678,11 @@ static void pl2303_update_line_status(struct usb_serial_port *port,
 {
 
        struct pl2303_private *priv = usb_get_serial_port_data(port);
+       struct tty_struct *tty;
        unsigned long flags;
        u8 status_idx = UART_STATE;
        u8 length = UART_STATE + 1;
+       u8 prev_line_status;
        u16 idv, idp;
 
        idv = le16_to_cpu(port->serial->dev->descriptor.idVendor);
@@ -701,11 +704,20 @@ static void pl2303_update_line_status(struct usb_serial_port *port,
 
        /* Save off the uart status for others to look at */
        spin_lock_irqsave(&priv->lock, flags);
+       prev_line_status = priv->line_status;
        priv->line_status = data[status_idx];
        spin_unlock_irqrestore(&priv->lock, flags);
        if (priv->line_status & UART_BREAK_ERROR)
                usb_serial_handle_break(port);
        wake_up_interruptible(&priv->delta_msr_wait);
+
+       tty = tty_port_tty_get(&port->port);
+       if (!tty)
+               return;
+       if ((priv->line_status ^ prev_line_status) & UART_DCD)
+               usb_serial_handle_dcd_change(port, tty,
+                               priv->line_status & UART_DCD);
+       tty_kref_put(tty);
 }
 
 static void pl2303_read_int_callback(struct urb *urb)
index 43eb9bdad422c91e4290f2204ee2f178d393b002..1b025f75dafd29c0868766bab5107d506168cbbf 100644 (file)
@@ -21,6 +21,7 @@
 #define PL2303_PRODUCT_ID_MMX          0x0612
 #define PL2303_PRODUCT_ID_GPRS         0x0609
 #define PL2303_PRODUCT_ID_HCR331       0x331a
+#define PL2303_PRODUCT_ID_MOTOROLA     0x0307
 
 #define ATEN_VENDOR_ID         0x0557
 #define ATEN_VENDOR_ID2                0x0547
index 214a3e504292e2f5c7066ec41b7ce27acd3886e9..30b73e68a904d65e7dadb3fdeee8acd73f65607c 100644 (file)
@@ -36,6 +36,7 @@
 #define UTSTARCOM_PRODUCT_UM175_V1             0x3712
 #define UTSTARCOM_PRODUCT_UM175_V2             0x3714
 #define UTSTARCOM_PRODUCT_UM175_ALLTEL         0x3715
+#define PANTECH_PRODUCT_UML290_VZW             0x3718
 
 /* CMOTECH devices */
 #define CMOTECH_VENDOR_ID                      0x16d8
@@ -66,6 +67,7 @@ static struct usb_device_id id_table[] = {
        { USB_DEVICE_AND_INTERFACE_INFO(LG_VENDOR_ID, LG_PRODUCT_VX4400_6000, 0xff, 0xff, 0x00) },
        { USB_DEVICE_AND_INTERFACE_INFO(SANYO_VENDOR_ID, SANYO_PRODUCT_KATANA_LX, 0xff, 0xff, 0x00) },
        { USB_DEVICE_AND_INTERFACE_INFO(SAMSUNG_VENDOR_ID, SAMSUNG_PRODUCT_U520, 0xff, 0x00, 0x00) },
+       { USB_DEVICE_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, PANTECH_PRODUCT_UML290_VZW, 0xff, 0xff, 0xff) },
        { },
 };
 MODULE_DEVICE_TABLE(usb, id_table);
@@ -84,6 +86,7 @@ static struct usb_serial_driver qcaux_device = {
                .name =         "qcaux",
        },
        .id_table =             id_table,
+       .usb_driver =           &qcaux_driver,
        .num_ports =            1,
 };
 
index cb8195cabfde82d0ce0cb9c16c5e441100ca1757..74cd4ccdb3fcc1b344de2e969df87c4882825ea4 100644 (file)
@@ -42,6 +42,7 @@ static struct usb_serial_driver siemens_usb_mpi_device = {
                .name =         "siemens_mpi",
        },
        .id_table =             id_table,
+       .usb_driver =           &siemens_usb_mpi_driver,
        .num_ports =            1,
 };
 
index 765aa983bf58e6e3548a079d2e92223b03cd6eff..cbfb70bffdd05e842a9e9479297ffb95edb2a6e0 100644 (file)
@@ -133,7 +133,7 @@ struct spcp8x5_usb_ctrl_arg {
 
 /* how come ??? */
 #define UART_STATE                     0x08
-#define UART_STATE_TRANSIENT_MASK      0x74
+#define UART_STATE_TRANSIENT_MASK      0x75
 #define UART_DCD                       0x01
 #define UART_DSR                       0x02
 #define UART_BREAK_ERROR               0x04
@@ -525,6 +525,10 @@ static void spcp8x5_process_read_urb(struct urb *urb)
                /* overrun is special, not associated with a char */
                if (status & UART_OVERRUN_ERROR)
                        tty_insert_flip_char(tty, 0, TTY_OVERRUN);
+
+               if (status & UART_DCD)
+                       usb_serial_handle_dcd_change(port, tty,
+                                  priv->line_status & MSR_STATUS_LINE_DCD);
        }
 
        tty_insert_flip_string_fixed_flag(tty, data, tty_flag,
@@ -645,6 +649,7 @@ static struct usb_serial_driver spcp8x5_device = {
                .name =         "SPCP8x5",
        },
        .id_table               = id_table,
+       .usb_driver             = &spcp8x5_driver,
        .num_ports              = 1,
        .open                   = spcp8x5_open,
        .dtr_rts                = spcp8x5_dtr_rts,
index 6954de50c0ffe5e22cc85ad909af0ceef1dde4fd..546a52179becbc783a825bda99efd61c8a2d8bff 100644 (file)
@@ -1344,11 +1344,15 @@ int usb_serial_register(struct usb_serial_driver *driver)
                return -ENODEV;
 
        fixup_generic(driver);
-       if (driver->usb_driver)
-               driver->usb_driver->supports_autosuspend = 1;
 
        if (!driver->description)
                driver->description = driver->driver.name;
+       if (!driver->usb_driver) {
+               WARN(1, "Serial driver %s has no usb_driver\n",
+                               driver->description);
+               return -EINVAL;
+       }
+       driver->usb_driver->supports_autosuspend = 1;
 
        /* Add this device to our list of devices */
        mutex_lock(&table_lock);
index f2ed6a31be77288733235eec2f60437d01d7ea91..95a82148ee81ec448e866b2b5b3b91ef93690c22 100644 (file)
@@ -75,6 +75,7 @@ static struct usb_serial_driver debug_device = {
                .name =         "debug",
        },
        .id_table =             id_table,
+       .usb_driver =           &debug_driver,
        .num_ports =            1,
        .bulk_out_size =        USB_DEBUG_MAX_PACKET_SIZE,
        .break_ctl =            usb_debug_break_ctl,
index c854fdebe0aecc1755f8fa604cd21f3fd841c165..2c8553026222fb178a4b11d2ae4380751ce716c6 100644 (file)
@@ -31,4 +31,9 @@ UNUSUAL_DEV(  0x04b4, 0x6831, 0x0000, 0x9999,
                "Cypress ISD-300LP",
                USB_SC_CYP_ATACB, USB_PR_DEVICE, NULL, 0),
 
+UNUSUAL_DEV( 0x14cd, 0x6116, 0x0000, 0x9999,
+               "Super Top",
+               "USB 2.0  SATA BRIDGE",
+               USB_SC_CYP_ATACB, USB_PR_DEVICE, NULL, 0),
+
 #endif /* defined(CONFIG_USB_STORAGE_CYPRESS_ATACB) || ... */
index fcc1e32ce2566332a3bc6ad41b35fdaf5a23e8ff..24bd5d7c3deb49beeaa5b3d1837fa015c53bd7ae 100644 (file)
@@ -1044,6 +1044,15 @@ UNUSUAL_DEV(  0x084d, 0x0011, 0x0110, 0x0110,
                USB_SC_DEVICE, USB_PR_DEVICE, NULL,
                US_FL_BULK32),
 
+/* Reported by <ttkspam@free.fr>
+ * The device reports a vendor-specific device class, requiring an
+ * explicit vendor/product match.
+ */
+UNUSUAL_DEV(  0x0851, 0x1542, 0x0002, 0x0002,
+               "MagicPixel",
+               "FW_Omega2",
+               USB_SC_DEVICE, USB_PR_DEVICE, NULL, 0),
+
 /* Andrew Lunn <andrew@lunn.ch>
  * PanDigital Digital Picture Frame. Does not like ALLOW_MEDIUM_REMOVAL
  * on LUN 4.
@@ -1872,6 +1881,15 @@ UNUSUAL_DEV( 0x1908, 0x3335, 0x0200, 0x0200,
                USB_SC_DEVICE, USB_PR_DEVICE, NULL,
                US_FL_NO_READ_DISC_INFO ),
 
+/* Patch by Richard Schütz <r.schtz@t-online.de>
+ * This external hard drive enclosure uses a JMicron chip which
+ * needs the US_FL_IGNORE_RESIDUE flag to work properly. */
+UNUSUAL_DEV(  0x1e68, 0x001b, 0x0000, 0x0000,
+               "TrekStor GmbH & Co. KG",
+               "DataStation maxi g.u",
+               USB_SC_DEVICE, USB_PR_DEVICE, NULL,
+               US_FL_IGNORE_RESIDUE | US_FL_SANE_SENSE ),
+
 UNUSUAL_DEV( 0x2116, 0x0320, 0x0001, 0x0001,
                "ST",
                "2A",
index d583bea608fd755bfe1f16c24d5dc95e184aa316..391ac939f011cd9102184154c1cbcd42e09878b7 100644 (file)
@@ -23,7 +23,7 @@
 #include <linux/svga.h>
 #include <linux/init.h>
 #include <linux/pci.h>
-#include <linux/console.h> /* Why should fb driver call console functions? because acquire_console_sem() */
+#include <linux/console.h> /* Why should fb driver call console functions? because console_lock() */
 #include <video/vga.h>
 
 #ifdef CONFIG_MTRR
@@ -1091,12 +1091,12 @@ static int ark_pci_suspend (struct pci_dev* dev, pm_message_t state)
 
        dev_info(info->device, "suspend\n");
 
-       acquire_console_sem();
+       console_lock();
        mutex_lock(&(par->open_lock));
 
        if ((state.event == PM_EVENT_FREEZE) || (par->ref_count == 0)) {
                mutex_unlock(&(par->open_lock));
-               release_console_sem();
+               console_unlock();
                return 0;
        }
 
@@ -1107,7 +1107,7 @@ static int ark_pci_suspend (struct pci_dev* dev, pm_message_t state)
        pci_set_power_state(dev, pci_choose_state(dev, state));
 
        mutex_unlock(&(par->open_lock));
-       release_console_sem();
+       console_unlock();
 
        return 0;
 }
@@ -1122,7 +1122,7 @@ static int ark_pci_resume (struct pci_dev* dev)
 
        dev_info(info->device, "resume\n");
 
-       acquire_console_sem();
+       console_lock();
        mutex_lock(&(par->open_lock));
 
        if (par->ref_count == 0)
@@ -1141,7 +1141,7 @@ static int ark_pci_resume (struct pci_dev* dev)
 
 fail:
        mutex_unlock(&(par->open_lock));
-       release_console_sem();
+       console_unlock();
        return 0;
 }
 #else
index dd9de2e8058051e0a9b4c3e086f83f8ad071fb4a..4cb6a576c5672ea1576ed12c80fc46fbacbff8c8 100644 (file)
@@ -1860,11 +1860,11 @@ static void aty128_early_resume(void *data)
 {
         struct aty128fb_par *par = data;
 
-       if (try_acquire_console_sem())
+       if (!console_trylock())
                return;
        pci_restore_state(par->pdev);
        aty128_do_resume(par->pdev);
-       release_console_sem();
+       console_unlock();
 }
 #endif /* CONFIG_PPC_PMAC */
 
@@ -2438,7 +2438,7 @@ static int aty128_pci_suspend(struct pci_dev *pdev, pm_message_t state)
 
        printk(KERN_DEBUG "aty128fb: suspending...\n");
        
-       acquire_console_sem();
+       console_lock();
 
        fb_set_suspend(info, 1);
 
@@ -2470,7 +2470,7 @@ static int aty128_pci_suspend(struct pci_dev *pdev, pm_message_t state)
        if (state.event != PM_EVENT_ON)
                aty128_set_suspend(par, 1);
 
-       release_console_sem();
+       console_unlock();
 
        pdev->dev.power.power_state = state;
 
@@ -2527,9 +2527,9 @@ static int aty128_pci_resume(struct pci_dev *pdev)
 {
        int rc;
 
-       acquire_console_sem();
+       console_lock();
        rc = aty128_do_resume(pdev);
-       release_console_sem();
+       console_unlock();
 
        return rc;
 }
index 767ab4fb1a053185feb354745e3e71f508e087bb..94e293fce1d2c8f6eb66f6fc03e44064eb270e0d 100644 (file)
@@ -2069,7 +2069,7 @@ static int atyfb_pci_suspend(struct pci_dev *pdev, pm_message_t state)
        if (state.event == pdev->dev.power.power_state.event)
                return 0;
 
-       acquire_console_sem();
+       console_lock();
 
        fb_set_suspend(info, 1);
 
@@ -2097,14 +2097,14 @@ static int atyfb_pci_suspend(struct pci_dev *pdev, pm_message_t state)
                par->lock_blank = 0;
                atyfb_blank(FB_BLANK_UNBLANK, info);
                fb_set_suspend(info, 0);
-               release_console_sem();
+               console_unlock();
                return -EIO;
        }
 #else
        pci_set_power_state(pdev, pci_choose_state(pdev, state));
 #endif
 
-       release_console_sem();
+       console_unlock();
 
        pdev->dev.power.power_state = state;
 
@@ -2133,7 +2133,7 @@ static int atyfb_pci_resume(struct pci_dev *pdev)
        if (pdev->dev.power.power_state.event == PM_EVENT_ON)
                return 0;
 
-       acquire_console_sem();
+       console_lock();
 
        /*
         * PCI state will have been restored by the core, so
@@ -2161,7 +2161,7 @@ static int atyfb_pci_resume(struct pci_dev *pdev)
        par->lock_blank = 0;
        atyfb_blank(FB_BLANK_UNBLANK, info);
 
-       release_console_sem();
+       console_unlock();
 
        pdev->dev.power.power_state = PMSG_ON;
 
index c4e17642d9c5b9e4a8bbbd61dad399311f0a58ee..92bda58485165a55ac2acc711ddfed5781bf49fe 100644 (file)
@@ -2626,7 +2626,7 @@ int radeonfb_pci_suspend(struct pci_dev *pdev, pm_message_t mesg)
                goto done;
        }
 
-       acquire_console_sem();
+       console_lock();
 
        fb_set_suspend(info, 1);
 
@@ -2690,7 +2690,7 @@ int radeonfb_pci_suspend(struct pci_dev *pdev, pm_message_t mesg)
        if (rinfo->pm_mode & radeon_pm_d2)
                radeon_set_suspend(rinfo, 1);
 
-       release_console_sem();
+       console_unlock();
 
  done:
        pdev->dev.power.power_state = mesg;
@@ -2715,10 +2715,10 @@ int radeonfb_pci_resume(struct pci_dev *pdev)
                return 0;
 
        if (rinfo->no_schedule) {
-               if (try_acquire_console_sem())
+               if (!console_trylock())
                        return 0;
        } else
-               acquire_console_sem();
+               console_lock();
 
        printk(KERN_DEBUG "radeonfb (%s): resuming from state: %d...\n",
               pci_name(pdev), pdev->dev.power.power_state.event);
@@ -2783,7 +2783,7 @@ int radeonfb_pci_resume(struct pci_dev *pdev)
        pdev->dev.power.power_state = PMSG_ON;
 
  bail:
-       release_console_sem();
+       console_unlock();
 
        return rc;
 }
index 18c507874ff1476c372495f8ed7f1339dced996f..47c21fb2c82fc50b2ac1329c30c1055b96874391 100644 (file)
@@ -696,6 +696,7 @@ static int __devinit bfin_lq035_probe(struct platform_device *pdev)
 {
        struct backlight_properties props;
        dma_addr_t dma_handle;
+       int ret;
 
        if (request_dma(CH_PPI, KBUILD_MODNAME)) {
                pr_err("couldn't request PPI DMA\n");
@@ -704,17 +705,16 @@ static int __devinit bfin_lq035_probe(struct platform_device *pdev)
 
        if (request_ports()) {
                pr_err("couldn't request gpio port\n");
-               free_dma(CH_PPI);
-               return -EFAULT;
+               ret = -EFAULT;
+               goto out_ports;
        }
 
        fb_buffer = dma_alloc_coherent(NULL, TOTAL_VIDEO_MEM_SIZE,
                                       &dma_handle, GFP_KERNEL);
        if (fb_buffer == NULL) {
                pr_err("couldn't allocate dma buffer\n");
-               free_dma(CH_PPI);
-               free_ports();
-               return -ENOMEM;
+               ret = -ENOMEM;
+               goto out_dma_coherent;
        }
 
        if (L1_DATA_A_LENGTH)
@@ -725,10 +725,8 @@ static int __devinit bfin_lq035_probe(struct platform_device *pdev)
 
        if (dma_desc_table == NULL) {
                pr_err("couldn't allocate dma descriptor\n");
-               free_dma(CH_PPI);
-               free_ports();
-               dma_free_coherent(NULL, TOTAL_VIDEO_MEM_SIZE, fb_buffer, 0);
-               return -ENOMEM;
+               ret = -ENOMEM;
+               goto out_table;
        }
 
        bfin_lq035_fb.screen_base = (void *)fb_buffer;
@@ -771,31 +769,21 @@ static int __devinit bfin_lq035_probe(struct platform_device *pdev)
        bfin_lq035_fb.pseudo_palette = kzalloc(sizeof(u32) * 16, GFP_KERNEL);
        if (bfin_lq035_fb.pseudo_palette == NULL) {
                pr_err("failed to allocate pseudo_palette\n");
-               free_dma(CH_PPI);
-               free_ports();
-               dma_free_coherent(NULL, TOTAL_VIDEO_MEM_SIZE, fb_buffer, 0);
-               return -ENOMEM;
+               ret = -ENOMEM;
+               goto out_palette;
        }
 
        if (fb_alloc_cmap(&bfin_lq035_fb.cmap, NBR_PALETTE, 0) < 0) {
                pr_err("failed to allocate colormap (%d entries)\n",
                        NBR_PALETTE);
-               free_dma(CH_PPI);
-               free_ports();
-               dma_free_coherent(NULL, TOTAL_VIDEO_MEM_SIZE, fb_buffer, 0);
-               kfree(bfin_lq035_fb.pseudo_palette);
-               return -EFAULT;
+               ret = -EFAULT;
+               goto out_cmap;
        }
 
        if (register_framebuffer(&bfin_lq035_fb) < 0) {
                pr_err("unable to register framebuffer\n");
-               free_dma(CH_PPI);
-               free_ports();
-               dma_free_coherent(NULL, TOTAL_VIDEO_MEM_SIZE, fb_buffer, 0);
-               fb_buffer = NULL;
-               kfree(bfin_lq035_fb.pseudo_palette);
-               fb_dealloc_cmap(&bfin_lq035_fb.cmap);
-               return -EINVAL;
+               ret = -EINVAL;
+               goto out_reg;
        }
 
        i2c_add_driver(&ad5280_driver);
@@ -807,11 +795,31 @@ static int __devinit bfin_lq035_probe(struct platform_device *pdev)
 
        lcd_dev = lcd_device_register(KBUILD_MODNAME, &pdev->dev, NULL,
                                      &bfin_lcd_ops);
+       if (IS_ERR(lcd_dev)) {
+               pr_err("unable to register lcd\n");
+               ret = PTR_ERR(lcd_dev);
+               goto out_lcd;
+       }
        lcd_dev->props.max_contrast = 255,
 
        pr_info("initialized");
 
        return 0;
+out_lcd:
+       unregister_framebuffer(&bfin_lq035_fb);
+out_reg:
+       fb_dealloc_cmap(&bfin_lq035_fb.cmap);
+out_cmap:
+       kfree(bfin_lq035_fb.pseudo_palette);
+out_palette:
+out_table:
+       dma_free_coherent(NULL, TOTAL_VIDEO_MEM_SIZE, fb_buffer, 0);
+       fb_buffer = NULL;
+out_dma_coherent:
+       free_ports();
+out_ports:
+       free_dma(CH_PPI);
+       return ret;
 }
 
 static int __devexit bfin_lq035_remove(struct platform_device *pdev)
index d637e1f53172ac8180fcfec902cbe580dbca3072..cff742abdc5d4ce998e9e7819487cee271761f80 100644 (file)
@@ -460,10 +460,10 @@ static int chipsfb_pci_suspend(struct pci_dev *pdev, pm_message_t state)
        if (!(state.event & PM_EVENT_SLEEP))
                goto done;
 
-       acquire_console_sem();
+       console_lock();
        chipsfb_blank(1, p);
        fb_set_suspend(p, 1);
-       release_console_sem();
+       console_unlock();
  done:
        pdev->dev.power.power_state = state;
        return 0;
@@ -473,10 +473,10 @@ static int chipsfb_pci_resume(struct pci_dev *pdev)
 {
         struct fb_info *p = pci_get_drvdata(pdev);
 
-       acquire_console_sem();
+       console_lock();
        fb_set_suspend(p, 0);
        chipsfb_blank(0, p);
-       release_console_sem();
+       console_unlock();
 
        pdev->dev.power.power_state = PMSG_ON;
        return 0;
index 7ccc967831f05bca5aba179bb88ff7880f55b92f..9c092b8d64e6a5d0a205a71002afa5f917adf20b 100644 (file)
@@ -375,14 +375,14 @@ static void fb_flashcursor(struct work_struct *work)
        int c;
        int mode;
 
-       acquire_console_sem();
+       console_lock();
        if (ops && ops->currcon != -1)
                vc = vc_cons[ops->currcon].d;
 
        if (!vc || !CON_IS_VISIBLE(vc) ||
            registered_fb[con2fb_map[vc->vc_num]] != info ||
            vc->vc_deccm != 1) {
-               release_console_sem();
+               console_unlock();
                return;
        }
 
@@ -392,7 +392,7 @@ static void fb_flashcursor(struct work_struct *work)
                CM_ERASE : CM_DRAW;
        ops->cursor(vc, info, mode, softback_lines, get_color(vc, info, c, 1),
                    get_color(vc, info, c, 0));
-       release_console_sem();
+       console_unlock();
 }
 
 static void cursor_timer_handler(unsigned long dev_addr)
@@ -836,7 +836,7 @@ static int set_con2fb_map(int unit, int newidx, int user)
 
        found = search_fb_in_map(newidx);
 
-       acquire_console_sem();
+       console_lock();
        con2fb_map[unit] = newidx;
        if (!err && !found)
                err = con2fb_acquire_newinfo(vc, info, unit, oldidx);
@@ -863,7 +863,7 @@ static int set_con2fb_map(int unit, int newidx, int user)
        if (!search_fb_in_map(info_idx))
                info_idx = newidx;
 
-       release_console_sem();
+       console_unlock();
        return err;
 }
 
@@ -3321,7 +3321,7 @@ static ssize_t store_rotate(struct device *device,
        if (fbcon_has_exited)
                return count;
 
-       acquire_console_sem();
+       console_lock();
        idx = con2fb_map[fg_console];
 
        if (idx == -1 || registered_fb[idx] == NULL)
@@ -3331,7 +3331,7 @@ static ssize_t store_rotate(struct device *device,
        rotate = simple_strtoul(buf, last, 0);
        fbcon_rotate(info, rotate);
 err:
-       release_console_sem();
+       console_unlock();
        return count;
 }
 
@@ -3346,7 +3346,7 @@ static ssize_t store_rotate_all(struct device *device,
        if (fbcon_has_exited)
                return count;
 
-       acquire_console_sem();
+       console_lock();
        idx = con2fb_map[fg_console];
 
        if (idx == -1 || registered_fb[idx] == NULL)
@@ -3356,7 +3356,7 @@ static ssize_t store_rotate_all(struct device *device,
        rotate = simple_strtoul(buf, last, 0);
        fbcon_rotate_all(info, rotate);
 err:
-       release_console_sem();
+       console_unlock();
        return count;
 }
 
@@ -3369,7 +3369,7 @@ static ssize_t show_rotate(struct device *device,
        if (fbcon_has_exited)
                return 0;
 
-       acquire_console_sem();
+       console_lock();
        idx = con2fb_map[fg_console];
 
        if (idx == -1 || registered_fb[idx] == NULL)
@@ -3378,7 +3378,7 @@ static ssize_t show_rotate(struct device *device,
        info = registered_fb[idx];
        rotate = fbcon_get_rotate(info);
 err:
-       release_console_sem();
+       console_unlock();
        return snprintf(buf, PAGE_SIZE, "%d\n", rotate);
 }
 
@@ -3392,7 +3392,7 @@ static ssize_t show_cursor_blink(struct device *device,
        if (fbcon_has_exited)
                return 0;
 
-       acquire_console_sem();
+       console_lock();
        idx = con2fb_map[fg_console];
 
        if (idx == -1 || registered_fb[idx] == NULL)
@@ -3406,7 +3406,7 @@ static ssize_t show_cursor_blink(struct device *device,
 
        blink = (ops->flags & FBCON_FLAGS_CURSOR_TIMER) ? 1 : 0;
 err:
-       release_console_sem();
+       console_unlock();
        return snprintf(buf, PAGE_SIZE, "%d\n", blink);
 }
 
@@ -3421,7 +3421,7 @@ static ssize_t store_cursor_blink(struct device *device,
        if (fbcon_has_exited)
                return count;
 
-       acquire_console_sem();
+       console_lock();
        idx = con2fb_map[fg_console];
 
        if (idx == -1 || registered_fb[idx] == NULL)
@@ -3443,7 +3443,7 @@ static ssize_t store_cursor_blink(struct device *device,
        }
 
 err:
-       release_console_sem();
+       console_unlock();
        return count;
 }
 
@@ -3482,7 +3482,7 @@ static void fbcon_start(void)
        if (num_registered_fb) {
                int i;
 
-               acquire_console_sem();
+               console_lock();
 
                for (i = 0; i < FB_MAX; i++) {
                        if (registered_fb[i] != NULL) {
@@ -3491,7 +3491,7 @@ static void fbcon_start(void)
                        }
                }
 
-               release_console_sem();
+               console_unlock();
                fbcon_takeover(0);
        }
 }
@@ -3552,7 +3552,7 @@ static int __init fb_console_init(void)
 {
        int i;
 
-       acquire_console_sem();
+       console_lock();
        fb_register_client(&fbcon_event_notifier);
        fbcon_device = device_create(fb_class, NULL, MKDEV(0, 0), NULL,
                                     "fbcon");
@@ -3568,7 +3568,7 @@ static int __init fb_console_init(void)
        for (i = 0; i < MAX_NR_CONSOLES; i++)
                con2fb_map[i] = -1;
 
-       release_console_sem();
+       console_unlock();
        fbcon_start();
        return 0;
 }
@@ -3591,12 +3591,12 @@ static void __exit fbcon_deinit_device(void)
 
 static void __exit fb_console_exit(void)
 {
-       acquire_console_sem();
+       console_lock();
        fb_unregister_client(&fbcon_event_notifier);
        fbcon_deinit_device();
        device_destroy(fb_class, MKDEV(0, 0));
        fbcon_exit();
-       release_console_sem();
+       console_unlock();
        unregister_con_driver(&fb_con);
 }      
 
index c97491b8b39b1eb51f830f76f23469a1c655ef7e..915fd74da7a2554ae14c77be007667219f7fef19 100644 (file)
@@ -202,11 +202,7 @@ static void vgacon_scrollback_init(int pitch)
        }
 }
 
-/*
- * Called only duing init so call of alloc_bootmen is ok.
- * Marked __init_refok to silence modpost.
- */
-static void __init_refok vgacon_scrollback_startup(void)
+static void vgacon_scrollback_startup(void)
 {
        vgacon_scrollback = kcalloc(CONFIG_VGACON_SOFT_SCROLLBACK_SIZE, 1024, GFP_NOWAIT);
        vgacon_scrollback_init(vga_video_num_columns * 2);
index c265aed09e04a2061ca224dd4354ffd178d9ccdc..8d61ef96eedd5b7942346950223513eaf4ed52e9 100644 (file)
@@ -1092,9 +1092,10 @@ static int __init fb_probe(struct platform_device *device)
 
 irq_freq:
 #ifdef CONFIG_CPU_FREQ
+       lcd_da8xx_cpufreq_deregister(par);
+#endif
 err_cpu_freq:
        unregister_framebuffer(da8xx_fb_info);
-#endif
 
 err_dealloc_cmap:
        fb_dealloc_cmap(&da8xx_fb_info->cmap);
@@ -1130,14 +1131,14 @@ static int fb_suspend(struct platform_device *dev, pm_message_t state)
        struct fb_info *info = platform_get_drvdata(dev);
        struct da8xx_fb_par *par = info->par;
 
-       acquire_console_sem();
+       console_lock();
        if (par->panel_power_ctrl)
                par->panel_power_ctrl(0);
 
        fb_set_suspend(info, 1);
        lcd_disable_raster();
        clk_disable(par->lcdc_clk);
-       release_console_sem();
+       console_unlock();
 
        return 0;
 }
@@ -1146,14 +1147,14 @@ static int fb_resume(struct platform_device *dev)
        struct fb_info *info = platform_get_drvdata(dev);
        struct da8xx_fb_par *par = info->par;
 
-       acquire_console_sem();
+       console_lock();
        if (par->panel_power_ctrl)
                par->panel_power_ctrl(1);
 
        clk_enable(par->lcdc_clk);
        lcd_enable_raster();
        fb_set_suspend(info, 0);
-       release_console_sem();
+       console_unlock();
 
        return 0;
 }
index 4ac1201ad6c2fb3229a60e1377f29b4eef78a2eb..e2bf95370e40bd63a5743b2ee26f5b6cd302095b 100644 (file)
@@ -1036,11 +1036,11 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd,
                        return -EFAULT;
                if (!lock_fb_info(info))
                        return -ENODEV;
-               acquire_console_sem();
+               console_lock();
                info->flags |= FBINFO_MISC_USEREVENT;
                ret = fb_set_var(info, &var);
                info->flags &= ~FBINFO_MISC_USEREVENT;
-               release_console_sem();
+               console_unlock();
                unlock_fb_info(info);
                if (!ret && copy_to_user(argp, &var, sizeof(var)))
                        ret = -EFAULT;
@@ -1072,9 +1072,9 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd,
                        return -EFAULT;
                if (!lock_fb_info(info))
                        return -ENODEV;
-               acquire_console_sem();
+               console_lock();
                ret = fb_pan_display(info, &var);
-               release_console_sem();
+               console_unlock();
                unlock_fb_info(info);
                if (ret == 0 && copy_to_user(argp, &var, sizeof(var)))
                        return -EFAULT;
@@ -1119,11 +1119,11 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd,
        case FBIOBLANK:
                if (!lock_fb_info(info))
                        return -ENODEV;
-               acquire_console_sem();
+               console_lock();
                info->flags |= FBINFO_MISC_USEREVENT;
                ret = fb_blank(info, arg);
                info->flags &= ~FBINFO_MISC_USEREVENT;
-               release_console_sem();
+               console_unlock();
                unlock_fb_info(info);
                break;
        default:
index 0a08f134122761df00476ffcc6243b566195db79..f4a32779168bb9cadb739ae0acd438ed3d635296 100644 (file)
@@ -90,11 +90,11 @@ static int activate(struct fb_info *fb_info, struct fb_var_screeninfo *var)
        int err;
 
        var->activate |= FB_ACTIVATE_FORCE;
-       acquire_console_sem();
+       console_lock();
        fb_info->flags |= FBINFO_MISC_USEREVENT;
        err = fb_set_var(fb_info, var);
        fb_info->flags &= ~FBINFO_MISC_USEREVENT;
-       release_console_sem();
+       console_unlock();
        if (err)
                return err;
        return 0;
@@ -175,7 +175,7 @@ static ssize_t store_modes(struct device *device,
        if (i * sizeof(struct fb_videomode) != count)
                return -EINVAL;
 
-       acquire_console_sem();
+       console_lock();
        list_splice(&fb_info->modelist, &old_list);
        fb_videomode_to_modelist((const struct fb_videomode *)buf, i,
                                 &fb_info->modelist);
@@ -185,7 +185,7 @@ static ssize_t store_modes(struct device *device,
        } else
                fb_destroy_modelist(&old_list);
 
-       release_console_sem();
+       console_unlock();
 
        return 0;
 }
@@ -301,11 +301,11 @@ static ssize_t store_blank(struct device *device,
        char *last = NULL;
        int err;
 
-       acquire_console_sem();
+       console_lock();
        fb_info->flags |= FBINFO_MISC_USEREVENT;
        err = fb_blank(fb_info, simple_strtoul(buf, &last, 0));
        fb_info->flags &= ~FBINFO_MISC_USEREVENT;
-       release_console_sem();
+       console_unlock();
        if (err < 0)
                return err;
        return count;
@@ -364,9 +364,9 @@ static ssize_t store_pan(struct device *device,
                return -EINVAL;
        var.yoffset = simple_strtoul(last, &last, 0);
 
-       acquire_console_sem();
+       console_lock();
        err = fb_pan_display(fb_info, &var);
-       release_console_sem();
+       console_unlock();
 
        if (err < 0)
                return err;
@@ -399,9 +399,9 @@ static ssize_t store_fbstate(struct device *device,
 
        state = simple_strtoul(buf, &last, 0);
 
-       acquire_console_sem();
+       console_lock();
        fb_set_suspend(fb_info, (int)state);
-       release_console_sem();
+       console_unlock();
 
        return count;
 }
index 70b1d9d51c9601e2c4c338f58d29f7d4f59214dd..b4f19db9bb542ddfb453298498ca5e96413fe2a5 100644 (file)
@@ -344,10 +344,10 @@ static int gxfb_suspend(struct pci_dev *pdev, pm_message_t state)
        struct fb_info *info = pci_get_drvdata(pdev);
 
        if (state.event == PM_EVENT_SUSPEND) {
-               acquire_console_sem();
+               console_lock();
                gx_powerdown(info);
                fb_set_suspend(info, 1);
-               release_console_sem();
+               console_unlock();
        }
 
        /* there's no point in setting PCI states; we emulate PCI, so
@@ -361,7 +361,7 @@ static int gxfb_resume(struct pci_dev *pdev)
        struct fb_info *info = pci_get_drvdata(pdev);
        int ret;
 
-       acquire_console_sem();
+       console_lock();
        ret = gx_powerup(info);
        if (ret) {
                printk(KERN_ERR "gxfb:  power up failed!\n");
@@ -369,7 +369,7 @@ static int gxfb_resume(struct pci_dev *pdev)
        }
 
        fb_set_suspend(info, 0);
-       release_console_sem();
+       console_unlock();
        return 0;
 }
 #endif
index 39bdbedf43b481253e7eb3586d15050c83abb94c..416851ca8754bec70bb54108c0a7c9cb663dde47 100644 (file)
@@ -465,10 +465,10 @@ static int lxfb_suspend(struct pci_dev *pdev, pm_message_t state)
        struct fb_info *info = pci_get_drvdata(pdev);
 
        if (state.event == PM_EVENT_SUSPEND) {
-               acquire_console_sem();
+               console_lock();
                lx_powerdown(info);
                fb_set_suspend(info, 1);
-               release_console_sem();
+               console_unlock();
        }
 
        /* there's no point in setting PCI states; we emulate PCI, so
@@ -482,7 +482,7 @@ static int lxfb_resume(struct pci_dev *pdev)
        struct fb_info *info = pci_get_drvdata(pdev);
        int ret;
 
-       acquire_console_sem();
+       console_lock();
        ret = lx_powerup(info);
        if (ret) {
                printk(KERN_ERR "lxfb:  power up failed!\n");
@@ -490,7 +490,7 @@ static int lxfb_resume(struct pci_dev *pdev)
        }
 
        fb_set_suspend(info, 0);
-       release_console_sem();
+       console_unlock();
        return 0;
 }
 #else
index 5743ea25e818814887fada1f82562e553dbfe2c2..318f6fb895b289d2c2b5b884dd7deebc8e1616cf 100644 (file)
@@ -1574,7 +1574,7 @@ static int i810fb_suspend(struct pci_dev *dev, pm_message_t mesg)
                return 0;
        }
 
-       acquire_console_sem();
+       console_lock();
        fb_set_suspend(info, 1);
 
        if (info->fbops->fb_sync)
@@ -1587,7 +1587,7 @@ static int i810fb_suspend(struct pci_dev *dev, pm_message_t mesg)
        pci_save_state(dev);
        pci_disable_device(dev);
        pci_set_power_state(dev, pci_choose_state(dev, mesg));
-       release_console_sem();
+       console_unlock();
 
        return 0;
 }
@@ -1605,7 +1605,7 @@ static int i810fb_resume(struct pci_dev *dev)
                return 0;
        }
 
-       acquire_console_sem();
+       console_lock();
        pci_set_power_state(dev, PCI_D0);
        pci_restore_state(dev);
 
@@ -1621,7 +1621,7 @@ static int i810fb_resume(struct pci_dev *dev)
        fb_set_suspend (info, 0);
        info->fbops->fb_blank(VESA_NO_BLANKING, info);
 fail:
-       release_console_sem();
+       console_unlock();
        return 0;
 }
 /***********************************************************************
index 670ecaa0385a94f396acb74eadeb6e29d71edb1f..de366937c93362a68c73bcd6c18ba7e3f035241a 100644 (file)
@@ -778,9 +778,9 @@ static int jzfb_suspend(struct device *dev)
 {
        struct jzfb *jzfb = dev_get_drvdata(dev);
 
-       acquire_console_sem();
+       console_lock();
        fb_set_suspend(jzfb->fb, 1);
-       release_console_sem();
+       console_unlock();
 
        mutex_lock(&jzfb->lock);
        if (jzfb->is_enabled)
@@ -800,9 +800,9 @@ static int jzfb_resume(struct device *dev)
                jzfb_enable(jzfb);
        mutex_unlock(&jzfb->lock);
 
-       acquire_console_sem();
+       console_lock();
        fb_set_suspend(jzfb->fb, 0);
-       release_console_sem();
+       console_unlock();
 
        return 0;
 }
index cb013919e9ce5fbfd29bb3f27521f62c99e394e1..7e3a490e8d76d882555f58a752242360a6ed948b 100644 (file)
@@ -1177,9 +1177,9 @@ static int mx3fb_suspend(struct platform_device *pdev, pm_message_t state)
        struct mx3fb_data *mx3fb = platform_get_drvdata(pdev);
        struct mx3fb_info *mx3_fbi = mx3fb->fbi->par;
 
-       acquire_console_sem();
+       console_lock();
        fb_set_suspend(mx3fb->fbi, 1);
-       release_console_sem();
+       console_unlock();
 
        if (mx3_fbi->blank == FB_BLANK_UNBLANK) {
                sdc_disable_channel(mx3_fbi);
@@ -1202,9 +1202,9 @@ static int mx3fb_resume(struct platform_device *pdev)
                sdc_set_brightness(mx3fb, mx3fb->backlight_level);
        }
 
-       acquire_console_sem();
+       console_lock();
        fb_set_suspend(mx3fb->fbi, 0);
-       release_console_sem();
+       console_unlock();
 
        return 0;
 }
index 62498bd662fc91bab443c19da41797fd0f57e33e..f838d9e277f05e4fb5c9ee724d1f028a560e07a2 100644 (file)
@@ -696,6 +696,8 @@ static int nuc900fb_remove(struct platform_device *pdev)
        nuc900fb_stop_lcd(fbinfo);
        msleep(1);
 
+       unregister_framebuffer(fbinfo);
+       nuc900fb_cpufreq_deregister(fbi);
        nuc900fb_unmap_video_memory(fbinfo);
 
        iounmap(fbi->io);
@@ -723,7 +725,7 @@ static int nuc900fb_suspend(struct platform_device *dev, pm_message_t state)
        struct fb_info     *fbinfo = platform_get_drvdata(dev);
        struct nuc900fb_info *info = fbinfo->par;
 
-       nuc900fb_stop_lcd();
+       nuc900fb_stop_lcd(fbinfo);
        msleep(1);
        clk_disable(info->clk);
        return 0;
@@ -740,7 +742,7 @@ static int nuc900fb_resume(struct platform_device *dev)
        msleep(1);
 
        nuc900fb_init_registers(fbinfo);
-       nuc900fb_activate_var(bfinfo);
+       nuc900fb_activate_var(fbinfo);
 
        return 0;
 }
index efe10ff86d6365ceaf5ab6f4fb3a0425b8f82c78..081dc47452742a769235d74c18cf49545efe72fd 100644 (file)
@@ -1057,7 +1057,7 @@ static int nvidiafb_suspend(struct pci_dev *dev, pm_message_t mesg)
 
        if (mesg.event == PM_EVENT_PRETHAW)
                mesg.event = PM_EVENT_FREEZE;
-       acquire_console_sem();
+       console_lock();
        par->pm_state = mesg.event;
 
        if (mesg.event & PM_EVENT_SLEEP) {
@@ -1070,7 +1070,7 @@ static int nvidiafb_suspend(struct pci_dev *dev, pm_message_t mesg)
        }
        dev->dev.power.power_state = mesg;
 
-       release_console_sem();
+       console_unlock();
        return 0;
 }
 
@@ -1079,7 +1079,7 @@ static int nvidiafb_resume(struct pci_dev *dev)
        struct fb_info *info = pci_get_drvdata(dev);
        struct nvidia_par *par = info->par;
 
-       acquire_console_sem();
+       console_lock();
        pci_set_power_state(dev, PCI_D0);
 
        if (par->pm_state != PM_EVENT_FREEZE) {
@@ -1097,7 +1097,7 @@ static int nvidiafb_resume(struct pci_dev *dev)
        nvidiafb_blank(FB_BLANK_UNBLANK, info);
 
 fail:
-       release_console_sem();
+       console_unlock();
        return 0;
 }
 #else
index 9c0144ee7ae516f6d0042127f8acad4279249f46..65560a1a04392a14602533eaa23d5536941b0573 100644 (file)
@@ -513,9 +513,9 @@ static int ps3fb_release(struct fb_info *info, int user)
        if (atomic_dec_and_test(&ps3fb.f_count)) {
                if (atomic_read(&ps3fb.ext_flip)) {
                        atomic_set(&ps3fb.ext_flip, 0);
-                       if (!try_acquire_console_sem()) {
+                       if (console_trylock()) {
                                ps3fb_sync(info, 0);    /* single buffer */
-                               release_console_sem();
+                               console_unlock();
                        }
                }
        }
@@ -830,14 +830,14 @@ static int ps3fb_ioctl(struct fb_info *info, unsigned int cmd,
                        if (vmode) {
                                var = info->var;
                                fb_videomode_to_var(&var, vmode);
-                               acquire_console_sem();
+                               console_lock();
                                info->flags |= FBINFO_MISC_USEREVENT;
                                /* Force, in case only special bits changed */
                                var.activate |= FB_ACTIVATE_FORCE;
                                par->new_mode_id = val;
                                retval = fb_set_var(info, &var);
                                info->flags &= ~FBINFO_MISC_USEREVENT;
-                               release_console_sem();
+                               console_unlock();
                        }
                        break;
                }
@@ -881,9 +881,9 @@ static int ps3fb_ioctl(struct fb_info *info, unsigned int cmd,
                        break;
 
                dev_dbg(info->device, "PS3FB_IOCTL_FSEL:%d\n", val);
-               acquire_console_sem();
+               console_lock();
                retval = ps3fb_sync(info, val);
-               release_console_sem();
+               console_unlock();
                break;
 
        default:
@@ -903,9 +903,9 @@ static int ps3fbd(void *arg)
                set_current_state(TASK_INTERRUPTIBLE);
                if (ps3fb.is_kicked) {
                        ps3fb.is_kicked = 0;
-                       acquire_console_sem();
+                       console_lock();
                        ps3fb_sync(info, 0);    /* single buffer */
-                       release_console_sem();
+                       console_unlock();
                }
                schedule();
        }
index cea6403ae71c16ffbcded14282db1552244f8833..35f61dd0cb3a43f5a9e3f70ac0dc5a07136a91b1 100644 (file)
@@ -701,16 +701,12 @@ static int __devinit pxa168fb_probe(struct platform_device *pdev)
         */
        pxa168fb_init_mode(info, mi);
 
-       ret = pxa168fb_check_var(&info->var, info);
-       if (ret)
-               goto failed_free_fbmem;
-
        /*
         * Fill in sane defaults.
         */
        ret = pxa168fb_check_var(&info->var, info);
        if (ret)
-               goto failed;
+               goto failed_free_fbmem;
 
        /*
         * enable controller clock
index b81168df253dbff37e562dc8ff70e0872a57a686..cf4beb9dc9bb5a9603679eaa35dc0e7e652d1fb1 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  pxa3xx-gc.c - Linux kernel module for PXA3xx graphics controllers
+ *  pxa3xx-gcu.c - Linux kernel module for PXA3xx graphics controllers
  *
  *  This driver needs a DirectFB counterpart in user space, communication
  *  is handled via mmap()ed memory areas and an ioctl.
@@ -421,7 +421,7 @@ pxa3xx_gcu_misc_write(struct file *filp, const char *buff,
                buffer->next = priv->free;
                priv->free = buffer;
                spin_unlock_irqrestore(&priv->spinlock, flags);
-               return ret;
+               return -EFAULT;
        }
 
        buffer->length = words;
index dce8c97b4333b4871f356b6d5cac1c17f351a600..75738a92861000a75b87c7694d9980a241b9ca10 100644 (file)
@@ -22,7 +22,7 @@
 #include <linux/svga.h>
 #include <linux/init.h>
 #include <linux/pci.h>
-#include <linux/console.h> /* Why should fb driver call console functions? because acquire_console_sem() */
+#include <linux/console.h> /* Why should fb driver call console functions? because console_lock() */
 #include <video/vga.h>
 
 #ifdef CONFIG_MTRR
@@ -1113,12 +1113,12 @@ static int s3_pci_suspend(struct pci_dev* dev, pm_message_t state)
 
        dev_info(info->device, "suspend\n");
 
-       acquire_console_sem();
+       console_lock();
        mutex_lock(&(par->open_lock));
 
        if ((state.event == PM_EVENT_FREEZE) || (par->ref_count == 0)) {
                mutex_unlock(&(par->open_lock));
-               release_console_sem();
+               console_unlock();
                return 0;
        }
 
@@ -1129,7 +1129,7 @@ static int s3_pci_suspend(struct pci_dev* dev, pm_message_t state)
        pci_set_power_state(dev, pci_choose_state(dev, state));
 
        mutex_unlock(&(par->open_lock));
-       release_console_sem();
+       console_unlock();
 
        return 0;
 }
@@ -1145,12 +1145,12 @@ static int s3_pci_resume(struct pci_dev* dev)
 
        dev_info(info->device, "resume\n");
 
-       acquire_console_sem();
+       console_lock();
        mutex_lock(&(par->open_lock));
 
        if (par->ref_count == 0) {
                mutex_unlock(&(par->open_lock));
-               release_console_sem();
+               console_unlock();
                return 0;
        }
 
@@ -1159,7 +1159,7 @@ static int s3_pci_resume(struct pci_dev* dev)
        err = pci_enable_device(dev);
        if (err) {
                mutex_unlock(&(par->open_lock));
-               release_console_sem();
+               console_unlock();
                dev_err(info->device, "error %d enabling device for resume\n", err);
                return err;
        }
@@ -1169,7 +1169,7 @@ static int s3_pci_resume(struct pci_dev* dev)
        fb_set_suspend(info, 0);
 
        mutex_unlock(&(par->open_lock));
-       release_console_sem();
+       console_unlock();
 
        return 0;
 }
index 842d157e10258e5ed62d37c9fa628ada1d4afa8f..487911e2926cbc6a8924a477240fc083943bf8c5 100644 (file)
@@ -2373,7 +2373,7 @@ static int savagefb_suspend(struct pci_dev *dev, pm_message_t mesg)
        if (mesg.event == PM_EVENT_FREEZE)
                return 0;
 
-       acquire_console_sem();
+       console_lock();
        fb_set_suspend(info, 1);
 
        if (info->fbops->fb_sync)
@@ -2385,7 +2385,7 @@ static int savagefb_suspend(struct pci_dev *dev, pm_message_t mesg)
        pci_save_state(dev);
        pci_disable_device(dev);
        pci_set_power_state(dev, pci_choose_state(dev, mesg));
-       release_console_sem();
+       console_unlock();
 
        return 0;
 }
@@ -2409,7 +2409,7 @@ static int savagefb_resume(struct pci_dev* dev)
                return 0;
        }
 
-       acquire_console_sem();
+       console_lock();
 
        pci_set_power_state(dev, PCI_D0);
        pci_restore_state(dev);
@@ -2423,7 +2423,7 @@ static int savagefb_resume(struct pci_dev* dev)
        savagefb_set_par(info);
        fb_set_suspend(info, 0);
        savagefb_blank(FB_BLANK_UNBLANK, info);
-       release_console_sem();
+       console_unlock();
 
        return 0;
 }
index 74d9f546a2e8012b50ee4503fdebdb50297ce4fa..2b9e56a6bde4780933d444b1f7e29aada38274eb 100644 (file)
@@ -1151,7 +1151,7 @@ static void sh_hdmi_edid_work_fn(struct work_struct *work)
 
                ch = info->par;
 
-               acquire_console_sem();
+               console_lock();
 
                /* HDMI plug in */
                if (!sh_hdmi_must_reconfigure(hdmi) &&
@@ -1171,7 +1171,7 @@ static void sh_hdmi_edid_work_fn(struct work_struct *work)
                        fb_set_suspend(info, 0);
                }
 
-               release_console_sem();
+               console_unlock();
        } else {
                ret = 0;
                if (!hdmi->info)
@@ -1181,12 +1181,12 @@ static void sh_hdmi_edid_work_fn(struct work_struct *work)
                fb_destroy_modedb(hdmi->monspec.modedb);
                hdmi->monspec.modedb = NULL;
 
-               acquire_console_sem();
+               console_lock();
 
                /* HDMI disconnect */
                fb_set_suspend(hdmi->info, 1);
 
-               release_console_sem();
+               console_unlock();
                pm_runtime_put(hdmi->dev);
        }
 
index bd4840a8a6b772f84c13f4356705e92302e21a39..bf12e53aed5cb6059568149b40d4c86692bf1b90 100644 (file)
@@ -912,9 +912,9 @@ static int sh_mobile_release(struct fb_info *info, int user)
 
        /* Nothing to reconfigure, when called from fbcon */
        if (user) {
-               acquire_console_sem();
+               console_lock();
                sh_mobile_fb_reconfig(info);
-               release_console_sem();
+               console_unlock();
        }
 
        mutex_unlock(&ch->open_lock);
index b7dc1800efa98b141665035d50463765ef623fef..bcb44a594ebcb944821cfe2f09d621f470cfa056 100644 (file)
@@ -2010,9 +2010,9 @@ static int sm501fb_suspend_fb(struct sm501fb_info *info,
 
        /* tell console/fb driver we are suspending */
 
-       acquire_console_sem();
+       console_lock();
        fb_set_suspend(fbi, 1);
-       release_console_sem();
+       console_unlock();
 
        /* backup copies in case chip is powered down over suspend */
 
@@ -2069,9 +2069,9 @@ static void sm501fb_resume_fb(struct sm501fb_info *info,
                memcpy_toio(par->cursor.k_addr, par->store_cursor,
                            par->cursor.size);
 
-       acquire_console_sem();
+       console_lock();
        fb_set_suspend(fbi, 0);
-       release_console_sem();
+       console_unlock();
 
        vfree(par->store_fb);
        vfree(par->store_cursor);
index 6913fe168c25f6d4249b2898c5663ede06fe2d8c..dfef88c803d45ec48129cb31236ad156231cfd4c 100644 (file)
@@ -25,7 +25,7 @@
 #include <linux/fb.h>
 #include <linux/interrupt.h>
 #include <linux/delay.h>
-/* Why should fb driver call console functions? because acquire_console_sem() */
+/* Why should fb driver call console functions? because console_lock() */
 #include <linux/console.h>
 #include <linux/mfd/core.h>
 #include <linux/mfd/tmio.h>
@@ -944,7 +944,7 @@ static int tmiofb_suspend(struct platform_device *dev, pm_message_t state)
        struct mfd_cell *cell = dev->dev.platform_data;
        int retval = 0;
 
-       acquire_console_sem();
+       console_lock();
 
        fb_set_suspend(info, 1);
 
@@ -965,7 +965,7 @@ static int tmiofb_suspend(struct platform_device *dev, pm_message_t state)
        if (cell->suspend)
                retval = cell->suspend(dev);
 
-       release_console_sem();
+       console_unlock();
 
        return retval;
 }
@@ -976,7 +976,7 @@ static int tmiofb_resume(struct platform_device *dev)
        struct mfd_cell *cell = dev->dev.platform_data;
        int retval = 0;
 
-       acquire_console_sem();
+       console_lock();
 
        if (cell->resume) {
                retval = cell->resume(dev);
@@ -992,7 +992,7 @@ static int tmiofb_resume(struct platform_device *dev)
 
        fb_set_suspend(info, 0);
 out:
-       release_console_sem();
+       console_unlock();
        return retval;
 }
 #else
index 289edd519527ff948570261db01747be8c26e20f..4e66349e4366711a3e42c444a400e37fb2b8e1a7 100644 (file)
@@ -1674,17 +1674,17 @@ static int parse_mode(const char *str, u32 *xres, u32 *yres)
 #ifdef CONFIG_PM
 static int viafb_suspend(void *unused)
 {
-       acquire_console_sem();
+       console_lock();
        fb_set_suspend(viafbinfo, 1);
        viafb_sync(viafbinfo);
-       release_console_sem();
+       console_unlock();
 
        return 0;
 }
 
 static int viafb_resume(void *unused)
 {
-       acquire_console_sem();
+       console_lock();
        if (viaparinfo->shared->vdev->engine_mmio)
                viafb_reset_engine(viaparinfo);
        viafb_set_par(viafbinfo);
@@ -1692,7 +1692,7 @@ static int viafb_resume(void *unused)
                viafb_set_par(viafbinfo1);
        fb_set_suspend(viafbinfo, 0);
 
-       release_console_sem();
+       console_unlock();
        return 0;
 }
 
index 85d76ec4c63e0c7ea2f65f10d072749256f9aeee..a2965ab92cfb815a289b21d8a30884e32db8c999 100644 (file)
@@ -23,7 +23,7 @@
 #include <linux/svga.h>
 #include <linux/init.h>
 #include <linux/pci.h>
-#include <linux/console.h> /* Why should fb driver call console functions? because acquire_console_sem() */
+#include <linux/console.h> /* Why should fb driver call console functions? because console_lock() */
 #include <video/vga.h>
 
 #ifdef CONFIG_MTRR
@@ -819,12 +819,12 @@ static int vt8623_pci_suspend(struct pci_dev* dev, pm_message_t state)
 
        dev_info(info->device, "suspend\n");
 
-       acquire_console_sem();
+       console_lock();
        mutex_lock(&(par->open_lock));
 
        if ((state.event == PM_EVENT_FREEZE) || (par->ref_count == 0)) {
                mutex_unlock(&(par->open_lock));
-               release_console_sem();
+               console_unlock();
                return 0;
        }
 
@@ -835,7 +835,7 @@ static int vt8623_pci_suspend(struct pci_dev* dev, pm_message_t state)
        pci_set_power_state(dev, pci_choose_state(dev, state));
 
        mutex_unlock(&(par->open_lock));
-       release_console_sem();
+       console_unlock();
 
        return 0;
 }
@@ -850,7 +850,7 @@ static int vt8623_pci_resume(struct pci_dev* dev)
 
        dev_info(info->device, "resume\n");
 
-       acquire_console_sem();
+       console_lock();
        mutex_lock(&(par->open_lock));
 
        if (par->ref_count == 0)
@@ -869,7 +869,7 @@ static int vt8623_pci_resume(struct pci_dev* dev)
 
 fail:
        mutex_unlock(&(par->open_lock));
-       release_console_sem();
+       console_unlock();
 
        return 0;
 }
index 3e6934d4bea8eb24a7a538235eaf71141c84d02f..a20218c2fda8be0a98b4a219bff743db2a0b5018 100644 (file)
@@ -491,12 +491,12 @@ xenfb_make_preferred_console(void)
        if (console_set_on_cmdline)
                return;
 
-       acquire_console_sem();
+       console_lock();
        for_each_console(c) {
                if (!strcmp(c->name, "tty") && c->index == 0)
                        break;
        }
-       release_console_sem();
+       console_unlock();
        if (c) {
                unregister_console(c);
                c->flags |= CON_CONSDEV;
index 60d27bc9eb83d82f61e448031495625e42c752d3..6b61ded701e10a23b61199b91536f2178c629275 100644 (file)
@@ -1560,9 +1560,10 @@ retry_locked:
                /* NOTE: no side-effects allowed, until we take s_mutex */
 
                revoking = cap->implemented & ~cap->issued;
-               if (revoking)
-                       dout(" mds%d revoking %s\n", cap->mds,
-                            ceph_cap_string(revoking));
+               dout(" mds%d cap %p issued %s implemented %s revoking %s\n",
+                    cap->mds, cap, ceph_cap_string(cap->issued),
+                    ceph_cap_string(cap->implemented),
+                    ceph_cap_string(revoking));
 
                if (cap == ci->i_auth_cap &&
                    (cap->issued & CEPH_CAP_FILE_WR)) {
@@ -1658,6 +1659,8 @@ ack:
 
                if (cap == ci->i_auth_cap && ci->i_dirty_caps)
                        flushing = __mark_caps_flushing(inode, session);
+               else
+                       flushing = 0;
 
                mds = cap->mds;  /* remember mds, so we don't repeat */
                sent++;
@@ -1940,6 +1943,35 @@ void ceph_kick_flushing_caps(struct ceph_mds_client *mdsc,
        }
 }
 
+static void kick_flushing_inode_caps(struct ceph_mds_client *mdsc,
+                                    struct ceph_mds_session *session,
+                                    struct inode *inode)
+{
+       struct ceph_inode_info *ci = ceph_inode(inode);
+       struct ceph_cap *cap;
+       int delayed = 0;
+
+       spin_lock(&inode->i_lock);
+       cap = ci->i_auth_cap;
+       dout("kick_flushing_inode_caps %p flushing %s flush_seq %lld\n", inode,
+            ceph_cap_string(ci->i_flushing_caps), ci->i_cap_flush_seq);
+       __ceph_flush_snaps(ci, &session, 1);
+       if (ci->i_flushing_caps) {
+               delayed = __send_cap(mdsc, cap, CEPH_CAP_OP_FLUSH,
+                                    __ceph_caps_used(ci),
+                                    __ceph_caps_wanted(ci),
+                                    cap->issued | cap->implemented,
+                                    ci->i_flushing_caps, NULL);
+               if (delayed) {
+                       spin_lock(&inode->i_lock);
+                       __cap_delay_requeue(mdsc, ci);
+                       spin_unlock(&inode->i_lock);
+               }
+       } else {
+               spin_unlock(&inode->i_lock);
+       }
+}
+
 
 /*
  * Take references to capabilities we hold, so that we don't release
@@ -2687,7 +2719,7 @@ static void handle_cap_import(struct ceph_mds_client *mdsc,
        ceph_add_cap(inode, session, cap_id, -1,
                     issued, wanted, seq, mseq, realmino, CEPH_CAP_FLAG_AUTH,
                     NULL /* no caps context */);
-       try_flush_caps(inode, session, NULL);
+       kick_flushing_inode_caps(mdsc, session, inode);
        up_read(&mdsc->snap_rwsem);
 
        /* make sure we re-request max_size, if necessary */
@@ -2785,8 +2817,7 @@ void ceph_handle_caps(struct ceph_mds_session *session,
        case CEPH_CAP_OP_IMPORT:
                handle_cap_import(mdsc, inode, h, session,
                                  snaptrace, snaptrace_len);
-               ceph_check_caps(ceph_inode(inode), CHECK_CAPS_NODELAY,
-                               session);
+               ceph_check_caps(ceph_inode(inode), 0, session);
                goto done_unlocked;
        }
 
index e835eff551e342156ff1f1b1f1e657c089f435eb..5625463aa4796f3df3678dd29ed1bfb1135a32af 100644 (file)
@@ -710,10 +710,6 @@ static int fill_inode(struct inode *inode,
                        ci->i_ceph_flags |= CEPH_I_COMPLETE;
                        ci->i_max_offset = 2;
                }
-
-               /* it may be better to set st_size in getattr instead? */
-               if (ceph_test_mount_opt(ceph_sb_to_client(inode->i_sb), RBYTES))
-                       inode->i_size = ci->i_rbytes;
                break;
        default:
                pr_err("fill_inode %llx.%llx BAD mode 0%o\n",
@@ -1819,7 +1815,11 @@ int ceph_getattr(struct vfsmount *mnt, struct dentry *dentry,
                else
                        stat->dev = 0;
                if (S_ISDIR(inode->i_mode)) {
-                       stat->size = ci->i_rbytes;
+                       if (ceph_test_mount_opt(ceph_sb_to_client(inode->i_sb),
+                                               RBYTES))
+                               stat->size = ci->i_rbytes;
+                       else
+                               stat->size = ci->i_files + ci->i_subdirs;
                        stat->blocks = 0;
                        stat->blksize = 65536;
                }
index 1e30d194a8e349f4f8a2bc951681a63c9c8d70b3..a1ee8fa3a8e7a4e8778fa624ef44154f67e2acf9 100644 (file)
@@ -693,9 +693,11 @@ static int __choose_mds(struct ceph_mds_client *mdsc,
                                dout("choose_mds %p %llx.%llx "
                                     "frag %u mds%d (%d/%d)\n",
                                     inode, ceph_vinop(inode),
-                                    frag.frag, frag.mds,
+                                    frag.frag, mds,
                                     (int)r, frag.ndist);
-                               return mds;
+                               if (ceph_mdsmap_get_state(mdsc->mdsmap, mds) >=
+                                   CEPH_MDS_STATE_ACTIVE)
+                                       return mds;
                        }
 
                        /* since this file/dir wasn't known to be
@@ -708,7 +710,9 @@ static int __choose_mds(struct ceph_mds_client *mdsc,
                                dout("choose_mds %p %llx.%llx "
                                     "frag %u mds%d (auth)\n",
                                     inode, ceph_vinop(inode), frag.frag, mds);
-                               return mds;
+                               if (ceph_mdsmap_get_state(mdsc->mdsmap, mds) >=
+                                   CEPH_MDS_STATE_ACTIVE)
+                                       return mds;
                        }
                }
        }
index bf6f0f34082a082d1a39d3640f5a30956dbcb13d..9c5085465a63056ac493a5febe8b184163c933a6 100644 (file)
@@ -290,6 +290,8 @@ static int parse_mount_options(struct ceph_mount_options **pfsopt,
 
         fsopt->rsize = CEPH_MOUNT_RSIZE_DEFAULT;
         fsopt->snapdir_name = kstrdup(CEPH_SNAPDIRNAME_DEFAULT, GFP_KERNEL);
+       fsopt->caps_wanted_delay_min = CEPH_CAPS_WANTED_DELAY_MIN_DEFAULT;
+       fsopt->caps_wanted_delay_max = CEPH_CAPS_WANTED_DELAY_MAX_DEFAULT;
         fsopt->cap_release_safety = CEPH_CAP_RELEASE_SAFETY_DEFAULT;
         fsopt->max_readdir = CEPH_MAX_READDIR_DEFAULT;
         fsopt->max_readdir_bytes = CEPH_MAX_READDIR_BYTES_DEFAULT;
index 6e12a6ba5f79daabc1bc455a3a4db464b240c00a..8c9eba6ef9df4999ce4894893900984d943695e5 100644 (file)
@@ -219,6 +219,7 @@ static struct ceph_inode_xattr *__get_xattr(struct ceph_inode_info *ci,
        struct rb_node **p;
        struct rb_node *parent = NULL;
        struct ceph_inode_xattr *xattr = NULL;
+       int name_len = strlen(name);
        int c;
 
        p = &ci->i_xattrs.index.rb_node;
@@ -226,6 +227,8 @@ static struct ceph_inode_xattr *__get_xattr(struct ceph_inode_info *ci,
                parent = *p;
                xattr = rb_entry(parent, struct ceph_inode_xattr, node);
                c = strncmp(name, xattr->name, xattr->name_len);
+               if (c == 0 && name_len > xattr->name_len)
+                       c = 1;
                if (c < 0)
                        p = &(*p)->rb_left;
                else if (c > 0)
index ee45648b0d1a9fead5722811171c6f5bcc3d8043..7cb0f7f847e4c29b7114318b2d128e4eedffccbe 100644 (file)
@@ -3,6 +3,7 @@ config CIFS
        depends on INET
        select NLS
        select CRYPTO
+       select CRYPTO_MD4
        select CRYPTO_MD5
        select CRYPTO_HMAC
        select CRYPTO_ARC4
index 43b19dd391912476c395ffbabaaabbacc28d0146..d87558448e3dd87628d520f68e4f976806e260f3 100644 (file)
@@ -5,7 +5,7 @@ obj-$(CONFIG_CIFS) += cifs.o
 
 cifs-y := cifsfs.o cifssmb.o cifs_debug.o connect.o dir.o file.o inode.o \
          link.o misc.o netmisc.o smbdes.o smbencrypt.o transport.o asn1.o \
-         md4.o md5.o cifs_unicode.o nterr.o xattr.o cifsencrypt.o \
+         cifs_unicode.o nterr.o xattr.o cifsencrypt.o \
          readdir.o ioctl.o sess.o export.o
 
 cifs-$(CONFIG_CIFS_ACL) += cifsacl.o
index 46af99ab3614d545675e41e788686b39fd51204b..fe1683590828a0ed011fa4a2e6ca6cc157292dca 100644 (file)
@@ -452,6 +452,11 @@ A partial list of the supported mount options follows:
                if oplock (caching token) is granted and held. Note that
                direct allows write operations larger than page size
                to be sent to the server.
+  strictcache   Use for switching on strict cache mode. In this mode the
+               client read from the cache all the time it has Oplock Level II,
+               otherwise - read from the server. All written data are stored
+               in the cache, but if the client doesn't have Exclusive Oplock,
+               it writes the data to the server.
   acl          Allow setfacl and getfacl to manage posix ACLs if server
                supports them.  (default)
   noacl        Do not allow setfacl and getfacl calls on this mount
index 7ed36536e7540171cd2bcca9f20b79555a5f73d8..0a265ad9e426ef0e9ec217604454db666290ff10 100644 (file)
@@ -282,8 +282,6 @@ static struct vfsmount *cifs_dfs_do_automount(struct dentry *mntpt)
        cFYI(1, "in %s", __func__);
        BUG_ON(IS_ROOT(mntpt));
 
-       xid = GetXid();
-
        /*
         * The MSDFS spec states that paths in DFS referral requests and
         * responses must be prefixed by a single '\' character instead of
@@ -293,20 +291,21 @@ static struct vfsmount *cifs_dfs_do_automount(struct dentry *mntpt)
        mnt = ERR_PTR(-ENOMEM);
        full_path = build_path_from_dentry(mntpt);
        if (full_path == NULL)
-               goto free_xid;
+               goto cdda_exit;
 
        cifs_sb = CIFS_SB(mntpt->d_inode->i_sb);
        tlink = cifs_sb_tlink(cifs_sb);
-       mnt = ERR_PTR(-EINVAL);
        if (IS_ERR(tlink)) {
                mnt = ERR_CAST(tlink);
                goto free_full_path;
        }
        ses = tlink_tcon(tlink)->ses;
 
+       xid = GetXid();
        rc = get_dfs_path(xid, ses, full_path + 1, cifs_sb->local_nls,
                &num_referrals, &referrals,
                cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
+       FreeXid(xid);
 
        cifs_put_tlink(tlink);
 
@@ -339,8 +338,7 @@ success:
        free_dfs_info_array(referrals, num_referrals);
 free_full_path:
        kfree(full_path);
-free_xid:
-       FreeXid(xid);
+cdda_exit:
        cFYI(1, "leaving %s" , __func__);
        return mnt;
 }
index 66f3d50d067682aa2203e30676550cce6421ec3a..a51585f9852b4627735e318e83478cbf512c9fbc 100644 (file)
@@ -24,7 +24,6 @@
 #include "cifspdu.h"
 #include "cifsglob.h"
 #include "cifs_debug.h"
-#include "md5.h"
 #include "cifs_unicode.h"
 #include "cifsproto.h"
 #include "ntlmssp.h"
 /* Note that the smb header signature field on input contains the
        sequence number before this function is called */
 
-extern void mdfour(unsigned char *out, unsigned char *in, int n);
-extern void E_md4hash(const unsigned char *passwd, unsigned char *p16);
-extern void SMBencrypt(unsigned char *passwd, const unsigned char *c8,
-                      unsigned char *p24);
-
 static int cifs_calculate_signature(const struct smb_hdr *cifs_pdu,
                                struct TCP_Server_Info *server, char *signature)
 {
@@ -234,6 +228,7 @@ int cifs_verify_signature(struct smb_hdr *cifs_pdu,
 /* first calculate 24 bytes ntlm response and then 16 byte session key */
 int setup_ntlm_response(struct cifsSesInfo *ses)
 {
+       int rc = 0;
        unsigned int temp_len = CIFS_SESS_KEY_SIZE + CIFS_AUTH_RESP_SIZE;
        char temp_key[CIFS_SESS_KEY_SIZE];
 
@@ -247,13 +242,26 @@ int setup_ntlm_response(struct cifsSesInfo *ses)
        }
        ses->auth_key.len = temp_len;
 
-       SMBNTencrypt(ses->password, ses->server->cryptkey,
+       rc = SMBNTencrypt(ses->password, ses->server->cryptkey,
                        ses->auth_key.response + CIFS_SESS_KEY_SIZE);
+       if (rc) {
+               cFYI(1, "%s Can't generate NTLM response, error: %d",
+                       __func__, rc);
+               return rc;
+       }
 
-       E_md4hash(ses->password, temp_key);
-       mdfour(ses->auth_key.response, temp_key, CIFS_SESS_KEY_SIZE);
+       rc = E_md4hash(ses->password, temp_key);
+       if (rc) {
+               cFYI(1, "%s Can't generate NT hash, error: %d", __func__, rc);
+               return rc;
+       }
 
-       return 0;
+       rc = mdfour(ses->auth_key.response, temp_key, CIFS_SESS_KEY_SIZE);
+       if (rc)
+               cFYI(1, "%s Can't generate NTLM session key, error: %d",
+                       __func__, rc);
+
+       return rc;
 }
 
 #ifdef CONFIG_CIFS_WEAK_PW_HASH
@@ -649,9 +657,10 @@ calc_seckey(struct cifsSesInfo *ses)
        get_random_bytes(sec_key, CIFS_SESS_KEY_SIZE);
 
        tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC);
-       if (!tfm_arc4 || IS_ERR(tfm_arc4)) {
+       if (IS_ERR(tfm_arc4)) {
+               rc = PTR_ERR(tfm_arc4);
                cERROR(1, "could not allocate crypto API arc4\n");
-               return PTR_ERR(tfm_arc4);
+               return rc;
        }
 
        desc.tfm = tfm_arc4;
@@ -700,14 +709,13 @@ cifs_crypto_shash_allocate(struct TCP_Server_Info *server)
        unsigned int size;
 
        server->secmech.hmacmd5 = crypto_alloc_shash("hmac(md5)", 0, 0);
-       if (!server->secmech.hmacmd5 ||
-                       IS_ERR(server->secmech.hmacmd5)) {
+       if (IS_ERR(server->secmech.hmacmd5)) {
                cERROR(1, "could not allocate crypto hmacmd5\n");
                return PTR_ERR(server->secmech.hmacmd5);
        }
 
        server->secmech.md5 = crypto_alloc_shash("md5", 0, 0);
-       if (!server->secmech.md5 || IS_ERR(server->secmech.md5)) {
+       if (IS_ERR(server->secmech.md5)) {
                cERROR(1, "could not allocate crypto md5\n");
                rc = PTR_ERR(server->secmech.md5);
                goto crypto_allocate_md5_fail;
diff --git a/fs/cifs/cifsencrypt.h b/fs/cifs/cifsencrypt.h
deleted file mode 100644 (file)
index 15d2ec0..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- *   fs/cifs/cifsencrypt.h
- *
- *   Copyright (c) International Business Machines  Corp., 2005
- *   Author(s): Steve French (sfrench@us.ibm.com)
- *
- *   Externs for misc. small encryption routines
- *   so we do not have to put them in cifsproto.h
- *
- *   This library is free software; you can redistribute it and/or modify
- *   it under the terms of the GNU Lesser General Public License as published
- *   by the Free Software Foundation; either version 2.1 of the License, or
- *   (at your option) any later version.
- *
- *   This library 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 Lesser General Public License for more details.
- *
- *   You should have received a copy of the GNU Lesser General Public License
- *   along with this library; if not, write to the Free Software
- *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/* md4.c */
-extern void mdfour(unsigned char *out, unsigned char *in, int n);
-/* smbdes.c */
-extern void E_P16(unsigned char *p14, unsigned char *p16);
-extern void E_P24(unsigned char *p21, const unsigned char *c8,
-                 unsigned char *p24);
-
-
-
index a8323f1dc1c48cf29b33a8c0323005adb270b296..f2970136d17d06c27e0654bbf4f13e302b3dc815 100644 (file)
@@ -600,10 +600,17 @@ static ssize_t cifs_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
 {
        struct inode *inode = iocb->ki_filp->f_path.dentry->d_inode;
        ssize_t written;
+       int rc;
 
        written = generic_file_aio_write(iocb, iov, nr_segs, pos);
-       if (!CIFS_I(inode)->clientCanCacheAll)
-               filemap_fdatawrite(inode->i_mapping);
+
+       if (CIFS_I(inode)->clientCanCacheAll)
+               return written;
+
+       rc = filemap_fdatawrite(inode->i_mapping);
+       if (rc)
+               cFYI(1, "cifs_file_aio_write: %d rc on %p inode", rc, inode);
+
        return written;
 }
 
@@ -737,7 +744,7 @@ const struct file_operations cifs_file_strict_ops = {
        .read = do_sync_read,
        .write = do_sync_write,
        .aio_read = cifs_strict_readv,
-       .aio_write = cifs_file_aio_write,
+       .aio_write = cifs_strict_writev,
        .open = cifs_open,
        .release = cifs_close,
        .lock = cifs_lock,
@@ -793,7 +800,7 @@ const struct file_operations cifs_file_strict_nobrl_ops = {
        .read = do_sync_read,
        .write = do_sync_write,
        .aio_read = cifs_strict_readv,
-       .aio_write = cifs_file_aio_write,
+       .aio_write = cifs_strict_writev,
        .open = cifs_open,
        .release = cifs_close,
        .fsync = cifs_strict_fsync,
index f23206d46531f7fe9a5664ac26a7dd04455c4d23..4a3330235d55f373523d99885ec77c50e5edeeb2 100644 (file)
@@ -85,7 +85,9 @@ extern ssize_t cifs_user_read(struct file *file, char __user *read_data,
 extern ssize_t cifs_strict_readv(struct kiocb *iocb, const struct iovec *iov,
                                 unsigned long nr_segs, loff_t pos);
 extern ssize_t cifs_user_write(struct file *file, const char __user *write_data,
-                        size_t write_size, loff_t *poffset);
+                              size_t write_size, loff_t *poffset);
+extern ssize_t cifs_strict_writev(struct kiocb *iocb, const struct iovec *iov,
+                                 unsigned long nr_segs, loff_t pos);
 extern int cifs_lock(struct file *, int, struct file_lock *);
 extern int cifs_fsync(struct file *, int);
 extern int cifs_strict_fsync(struct file *, int);
@@ -125,5 +127,5 @@ extern long cifs_ioctl(struct file *filep, unsigned int cmd, unsigned long arg);
 extern const struct export_operations cifs_export_ops;
 #endif /* EXPERIMENTAL */
 
-#define CIFS_VERSION   "1.69"
+#define CIFS_VERSION   "1.70"
 #endif                         /* _CIFSFS_H */
index 5bfb75346cb03c20780f604866e4f8e9c625cff5..edd5b29b53c9a354ac6c0a8d934a793c0221cea0 100644 (file)
@@ -166,6 +166,9 @@ struct TCP_Server_Info {
        struct socket *ssocket;
        struct sockaddr_storage dstaddr;
        struct sockaddr_storage srcaddr; /* locally bind to this IP */
+#ifdef CONFIG_NET_NS
+       struct net *net;
+#endif
        wait_queue_head_t response_q;
        wait_queue_head_t request_q; /* if more than maxmpx to srvr must block*/
        struct list_head pending_mid_q;
@@ -216,6 +219,36 @@ struct TCP_Server_Info {
 #endif
 };
 
+/*
+ * Macros to allow the TCP_Server_Info->net field and related code to drop out
+ * when CONFIG_NET_NS isn't set.
+ */
+
+#ifdef CONFIG_NET_NS
+
+static inline struct net *cifs_net_ns(struct TCP_Server_Info *srv)
+{
+       return srv->net;
+}
+
+static inline void cifs_set_net_ns(struct TCP_Server_Info *srv, struct net *net)
+{
+       srv->net = net;
+}
+
+#else
+
+static inline struct net *cifs_net_ns(struct TCP_Server_Info *srv)
+{
+       return &init_net;
+}
+
+static inline void cifs_set_net_ns(struct TCP_Server_Info *srv, struct net *net)
+{
+}
+
+#endif
+
 /*
  * Session structure.  One of these for each uid session with a particular host
  */
index 982895fa76152b7962c3e5fbd7e0cd8df4e8b699..8096f27ad9a86405731bf7edcc35b1e66fbe5e4d 100644 (file)
@@ -85,6 +85,8 @@ extern int checkSMB(struct smb_hdr *smb, __u16 mid, unsigned int length);
 extern bool is_valid_oplock_break(struct smb_hdr *smb,
                                  struct TCP_Server_Info *);
 extern bool is_size_safe_to_change(struct cifsInodeInfo *, __u64 eof);
+extern void cifs_update_eof(struct cifsInodeInfo *cifsi, loff_t offset,
+                           unsigned int bytes_written);
 extern struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *, bool);
 extern struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *, bool);
 extern unsigned int smbCalcSize(struct smb_hdr *ptr);
@@ -373,7 +375,7 @@ extern int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *,
 extern int cifs_verify_signature(struct smb_hdr *,
                                 struct TCP_Server_Info *server,
                                __u32 expected_sequence_number);
-extern void SMBNTencrypt(unsigned char *, unsigned char *, unsigned char *);
+extern int SMBNTencrypt(unsigned char *, unsigned char *, unsigned char *);
 extern int setup_ntlm_response(struct cifsSesInfo *);
 extern int setup_ntlmv2_rsp(struct cifsSesInfo *, const struct nls_table *);
 extern int cifs_crypto_shash_allocate(struct TCP_Server_Info *);
@@ -423,4 +425,11 @@ extern bool CIFSCouldBeMFSymlink(const struct cifs_fattr *fattr);
 extern int CIFSCheckMFSymlink(struct cifs_fattr *fattr,
                const unsigned char *path,
                struct cifs_sb_info *cifs_sb, int xid);
+extern int mdfour(unsigned char *, unsigned char *, int);
+extern int E_md4hash(const unsigned char *passwd, unsigned char *p16);
+extern void SMBencrypt(unsigned char *passwd, const unsigned char *c8,
+                       unsigned char *p24);
+extern void E_P16(unsigned char *p14, unsigned char *p16);
+extern void E_P24(unsigned char *p21, const unsigned char *c8,
+                       unsigned char *p24);
 #endif                 /* _CIFSPROTO_H */
index 3106f5e5c63301609b21df1bf1f93251a2b7beda..46c66ed01af43d92a732864cb7b9a76ea6fdd653 100644 (file)
@@ -4914,7 +4914,6 @@ CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon, __u64 size,
                   __u16 fid, __u32 pid_of_opener, bool SetAllocation)
 {
        struct smb_com_transaction2_sfi_req *pSMB  = NULL;
-       char *data_offset;
        struct file_end_of_file_info *parm_data;
        int rc = 0;
        __u16 params, param_offset, offset, byte_count, count;
@@ -4938,8 +4937,6 @@ CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon, __u64 size,
        param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
        offset = param_offset + params;
 
-       data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
-
        count = sizeof(struct file_end_of_file_info);
        pSMB->MaxParameterCount = cpu_to_le16(2);
        /* BB find exact max SMB PDU from sess structure BB */
index 18d3c7724d6e0dce8f63336e2f64424fdf913961..47d8ff623683524a4a264e7317a8e707a5a209ed 100644 (file)
@@ -55,9 +55,6 @@
 /* SMB echo "timeout" -- FIXME: tunable? */
 #define SMB_ECHO_INTERVAL (60 * HZ)
 
-extern void SMBNTencrypt(unsigned char *passwd, unsigned char *c8,
-                        unsigned char *p24);
-
 extern mempool_t *cifs_req_poolp;
 
 struct smb_vol {
@@ -87,6 +84,7 @@ struct smb_vol {
        bool no_xattr:1;   /* set if xattr (EA) support should be disabled*/
        bool server_ino:1; /* use inode numbers from server ie UniqueId */
        bool direct_io:1;
+       bool strict_io:1; /* strict cache behavior */
        bool remap:1;      /* set to remap seven reserved chars in filenames */
        bool posix_paths:1; /* unset to not ask for posix pathnames. */
        bool no_linux_ext:1;
@@ -1344,6 +1342,8 @@ cifs_parse_mount_options(char *options, const char *devname,
                        vol->direct_io = 1;
                } else if (strnicmp(data, "forcedirectio", 13) == 0) {
                        vol->direct_io = 1;
+               } else if (strnicmp(data, "strictcache", 11) == 0) {
+                       vol->strict_io = 1;
                } else if (strnicmp(data, "noac", 4) == 0) {
                        printk(KERN_WARNING "CIFS: Mount option noac not "
                                "supported. Instead set "
@@ -1568,6 +1568,9 @@ cifs_find_tcp_session(struct sockaddr *addr, struct smb_vol *vol)
 
        spin_lock(&cifs_tcp_ses_lock);
        list_for_each_entry(server, &cifs_tcp_ses_list, tcp_ses_list) {
+               if (!net_eq(cifs_net_ns(server), current->nsproxy->net_ns))
+                       continue;
+
                if (!match_address(server, addr,
                                   (struct sockaddr *)&vol->srcaddr))
                        continue;
@@ -1598,6 +1601,8 @@ cifs_put_tcp_session(struct TCP_Server_Info *server)
                return;
        }
 
+       put_net(cifs_net_ns(server));
+
        list_del_init(&server->tcp_ses_list);
        spin_unlock(&cifs_tcp_ses_lock);
 
@@ -1672,6 +1677,7 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
                goto out_err;
        }
 
+       cifs_set_net_ns(tcp_ses, get_net(current->nsproxy->net_ns));
        tcp_ses->hostname = extract_hostname(volume_info->UNC);
        if (IS_ERR(tcp_ses->hostname)) {
                rc = PTR_ERR(tcp_ses->hostname);
@@ -1752,6 +1758,8 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
 out_err_crypto_release:
        cifs_crypto_shash_release(tcp_ses);
 
+       put_net(cifs_net_ns(tcp_ses));
+
 out_err:
        if (tcp_ses) {
                if (!IS_ERR(tcp_ses->hostname))
@@ -2263,8 +2271,8 @@ generic_ip_connect(struct TCP_Server_Info *server)
        }
 
        if (socket == NULL) {
-               rc = sock_create_kern(sfamily, SOCK_STREAM,
-                                     IPPROTO_TCP, &socket);
+               rc = __sock_create(cifs_net_ns(server), sfamily, SOCK_STREAM,
+                                  IPPROTO_TCP, &socket, 1);
                if (rc < 0) {
                        cERROR(1, "Error %d creating socket", rc);
                        server->ssocket = NULL;
@@ -2576,6 +2584,8 @@ static void setup_cifs_sb(struct smb_vol *pvolume_info,
        if (pvolume_info->multiuser)
                cifs_sb->mnt_cifs_flags |= (CIFS_MOUNT_MULTIUSER |
                                            CIFS_MOUNT_NO_PERM);
+       if (pvolume_info->strict_io)
+               cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_STRICT_IO;
        if (pvolume_info->direct_io) {
                cFYI(1, "mounting share using direct i/o");
                cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO;
@@ -2977,7 +2987,8 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
                                         bcc_ptr);
                else
 #endif /* CIFS_WEAK_PW_HASH */
-               SMBNTencrypt(tcon->password, ses->server->cryptkey, bcc_ptr);
+               rc = SMBNTencrypt(tcon->password, ses->server->cryptkey,
+                                       bcc_ptr);
 
                bcc_ptr += CIFS_AUTH_RESP_SIZE;
                if (ses->capabilities & CAP_UNICODE) {
index d7d65a70678e48b2b2cebf97f80fea1f14a97079..74c0a282d012eeb96c3022b1a4616a47f4859636 100644 (file)
@@ -346,7 +346,6 @@ int cifs_open(struct inode *inode, struct file *file)
        struct cifsTconInfo *tcon;
        struct tcon_link *tlink;
        struct cifsFileInfo *pCifsFile = NULL;
-       struct cifsInodeInfo *pCifsInode;
        char *full_path = NULL;
        bool posix_open_ok = false;
        __u16 netfid;
@@ -361,8 +360,6 @@ int cifs_open(struct inode *inode, struct file *file)
        }
        tcon = tlink_tcon(tlink);
 
-       pCifsInode = CIFS_I(file->f_path.dentry->d_inode);
-
        full_path = build_path_from_dentry(file->f_path.dentry);
        if (full_path == NULL) {
                rc = -ENOMEM;
@@ -848,7 +845,7 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
 }
 
 /* update the file size (if needed) after a write */
-static void
+void
 cifs_update_eof(struct cifsInodeInfo *cifsi, loff_t offset,
                      unsigned int bytes_written)
 {
@@ -1146,7 +1143,6 @@ static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to)
        char *write_data;
        int rc = -EFAULT;
        int bytes_written = 0;
-       struct cifs_sb_info *cifs_sb;
        struct inode *inode;
        struct cifsFileInfo *open_file;
 
@@ -1154,7 +1150,6 @@ static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to)
                return -EFAULT;
 
        inode = page->mapping->host;
-       cifs_sb = CIFS_SB(inode->i_sb);
 
        offset += (loff_t)from;
        write_data = kmap(page);
@@ -1619,6 +1614,207 @@ int cifs_flush(struct file *file, fl_owner_t id)
        return rc;
 }
 
+static int
+cifs_write_allocate_pages(struct page **pages, unsigned long num_pages)
+{
+       int rc = 0;
+       unsigned long i;
+
+       for (i = 0; i < num_pages; i++) {
+               pages[i] = alloc_page(__GFP_HIGHMEM);
+               if (!pages[i]) {
+                       /*
+                        * save number of pages we have already allocated and
+                        * return with ENOMEM error
+                        */
+                       num_pages = i;
+                       rc = -ENOMEM;
+                       goto error;
+               }
+       }
+
+       return rc;
+
+error:
+       for (i = 0; i < num_pages; i++)
+               put_page(pages[i]);
+       return rc;
+}
+
+static inline
+size_t get_numpages(const size_t wsize, const size_t len, size_t *cur_len)
+{
+       size_t num_pages;
+       size_t clen;
+
+       clen = min_t(const size_t, len, wsize);
+       num_pages = clen / PAGE_CACHE_SIZE;
+       if (clen % PAGE_CACHE_SIZE)
+               num_pages++;
+
+       if (cur_len)
+               *cur_len = clen;
+
+       return num_pages;
+}
+
+static ssize_t
+cifs_iovec_write(struct file *file, const struct iovec *iov,
+                unsigned long nr_segs, loff_t *poffset)
+{
+       size_t total_written = 0;
+       unsigned int written = 0;
+       unsigned long num_pages, npages;
+       size_t copied, len, cur_len, i;
+       struct kvec *to_send;
+       struct page **pages;
+       struct iov_iter it;
+       struct inode *inode;
+       struct cifsFileInfo *open_file;
+       struct cifsTconInfo *pTcon;
+       struct cifs_sb_info *cifs_sb;
+       int xid, rc;
+
+       len = iov_length(iov, nr_segs);
+       if (!len)
+               return 0;
+
+       rc = generic_write_checks(file, poffset, &len, 0);
+       if (rc)
+               return rc;
+
+       cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
+       num_pages = get_numpages(cifs_sb->wsize, len, &cur_len);
+
+       pages = kmalloc(sizeof(struct pages *)*num_pages, GFP_KERNEL);
+       if (!pages)
+               return -ENOMEM;
+
+       to_send = kmalloc(sizeof(struct kvec)*(num_pages + 1), GFP_KERNEL);
+       if (!to_send) {
+               kfree(pages);
+               return -ENOMEM;
+       }
+
+       rc = cifs_write_allocate_pages(pages, num_pages);
+       if (rc) {
+               kfree(pages);
+               kfree(to_send);
+               return rc;
+       }
+
+       xid = GetXid();
+       open_file = file->private_data;
+       pTcon = tlink_tcon(open_file->tlink);
+       inode = file->f_path.dentry->d_inode;
+
+       iov_iter_init(&it, iov, nr_segs, len, 0);
+       npages = num_pages;
+
+       do {
+               size_t save_len = cur_len;
+               for (i = 0; i < npages; i++) {
+                       copied = min_t(const size_t, cur_len, PAGE_CACHE_SIZE);
+                       copied = iov_iter_copy_from_user(pages[i], &it, 0,
+                                                        copied);
+                       cur_len -= copied;
+                       iov_iter_advance(&it, copied);
+                       to_send[i+1].iov_base = kmap(pages[i]);
+                       to_send[i+1].iov_len = copied;
+               }
+
+               cur_len = save_len - cur_len;
+
+               do {
+                       if (open_file->invalidHandle) {
+                               rc = cifs_reopen_file(open_file, false);
+                               if (rc != 0)
+                                       break;
+                       }
+                       rc = CIFSSMBWrite2(xid, pTcon, open_file->netfid,
+                                          cur_len, *poffset, &written,
+                                          to_send, npages, 0);
+               } while (rc == -EAGAIN);
+
+               for (i = 0; i < npages; i++)
+                       kunmap(pages[i]);
+
+               if (written) {
+                       len -= written;
+                       total_written += written;
+                       cifs_update_eof(CIFS_I(inode), *poffset, written);
+                       *poffset += written;
+               } else if (rc < 0) {
+                       if (!total_written)
+                               total_written = rc;
+                       break;
+               }
+
+               /* get length and number of kvecs of the next write */
+               npages = get_numpages(cifs_sb->wsize, len, &cur_len);
+       } while (len > 0);
+
+       if (total_written > 0) {
+               spin_lock(&inode->i_lock);
+               if (*poffset > inode->i_size)
+                       i_size_write(inode, *poffset);
+               spin_unlock(&inode->i_lock);
+       }
+
+       cifs_stats_bytes_written(pTcon, total_written);
+       mark_inode_dirty_sync(inode);
+
+       for (i = 0; i < num_pages; i++)
+               put_page(pages[i]);
+       kfree(to_send);
+       kfree(pages);
+       FreeXid(xid);
+       return total_written;
+}
+
+static ssize_t cifs_user_writev(struct kiocb *iocb, const struct iovec *iov,
+                               unsigned long nr_segs, loff_t pos)
+{
+       ssize_t written;
+       struct inode *inode;
+
+       inode = iocb->ki_filp->f_path.dentry->d_inode;
+
+       /*
+        * BB - optimize the way when signing is disabled. We can drop this
+        * extra memory-to-memory copying and use iovec buffers for constructing
+        * write request.
+        */
+
+       written = cifs_iovec_write(iocb->ki_filp, iov, nr_segs, &pos);
+       if (written > 0) {
+               CIFS_I(inode)->invalid_mapping = true;
+               iocb->ki_pos = pos;
+       }
+
+       return written;
+}
+
+ssize_t cifs_strict_writev(struct kiocb *iocb, const struct iovec *iov,
+                          unsigned long nr_segs, loff_t pos)
+{
+       struct inode *inode;
+
+       inode = iocb->ki_filp->f_path.dentry->d_inode;
+
+       if (CIFS_I(inode)->clientCanCacheAll)
+               return generic_file_aio_write(iocb, iov, nr_segs, pos);
+
+       /*
+        * In strict cache mode we need to write the data to the server exactly
+        * from the pos to pos+len-1 rather than flush all affected pages
+        * because it may cause a error with mandatory locks on these pages but
+        * not on the region from pos to ppos+len-1.
+        */
+
+       return cifs_user_writev(iocb, iov, nr_segs, pos);
+}
+
 static ssize_t
 cifs_iovec_read(struct file *file, const struct iovec *iov,
                 unsigned long nr_segs, loff_t *poffset)
index 306769de2fb5369e221df1975dba3b904b6b1d5c..e8804d3734044f578da6d4427e4961431d61ae5a 100644 (file)
@@ -28,7 +28,6 @@
 #include "cifsproto.h"
 #include "cifs_debug.h"
 #include "cifs_fs_sb.h"
-#include "md5.h"
 
 #define CIFS_MF_SYMLINK_LEN_OFFSET (4+1)
 #define CIFS_MF_SYMLINK_MD5_OFFSET (CIFS_MF_SYMLINK_LEN_OFFSET+(4+1))
        md5_hash[8],  md5_hash[9],  md5_hash[10], md5_hash[11],\
        md5_hash[12], md5_hash[13], md5_hash[14], md5_hash[15]
 
+static int
+symlink_hash(unsigned int link_len, const char *link_str, u8 *md5_hash)
+{
+       int rc;
+       unsigned int size;
+       struct crypto_shash *md5;
+       struct sdesc *sdescmd5;
+
+       md5 = crypto_alloc_shash("md5", 0, 0);
+       if (IS_ERR(md5)) {
+               rc = PTR_ERR(md5);
+               cERROR(1, "%s: Crypto md5 allocation error %d\n", __func__, rc);
+               return rc;
+       }
+       size = sizeof(struct shash_desc) + crypto_shash_descsize(md5);
+       sdescmd5 = kmalloc(size, GFP_KERNEL);
+       if (!sdescmd5) {
+               rc = -ENOMEM;
+               cERROR(1, "%s: Memory allocation failure\n", __func__);
+               goto symlink_hash_err;
+       }
+       sdescmd5->shash.tfm = md5;
+       sdescmd5->shash.flags = 0x0;
+
+       rc = crypto_shash_init(&sdescmd5->shash);
+       if (rc) {
+               cERROR(1, "%s: Could not init md5 shash\n", __func__);
+               goto symlink_hash_err;
+       }
+       crypto_shash_update(&sdescmd5->shash, link_str, link_len);
+       rc = crypto_shash_final(&sdescmd5->shash, md5_hash);
+
+symlink_hash_err:
+       crypto_free_shash(md5);
+       kfree(sdescmd5);
+
+       return rc;
+}
+
 static int
 CIFSParseMFSymlink(const u8 *buf,
                   unsigned int buf_len,
@@ -56,7 +94,6 @@ CIFSParseMFSymlink(const u8 *buf,
        unsigned int link_len;
        const char *md5_str1;
        const char *link_str;
-       struct MD5Context md5_ctx;
        u8 md5_hash[16];
        char md5_str2[34];
 
@@ -70,9 +107,11 @@ CIFSParseMFSymlink(const u8 *buf,
        if (rc != 1)
                return -EINVAL;
 
-       cifs_MD5_init(&md5_ctx);
-       cifs_MD5_update(&md5_ctx, (const u8 *)link_str, link_len);
-       cifs_MD5_final(md5_hash, &md5_ctx);
+       rc = symlink_hash(link_len, link_str, md5_hash);
+       if (rc) {
+               cFYI(1, "%s: MD5 hash failure: %d\n", __func__, rc);
+               return rc;
+       }
 
        snprintf(md5_str2, sizeof(md5_str2),
                 CIFS_MF_SYMLINK_MD5_FORMAT,
@@ -94,9 +133,9 @@ CIFSParseMFSymlink(const u8 *buf,
 static int
 CIFSFormatMFSymlink(u8 *buf, unsigned int buf_len, const char *link_str)
 {
+       int rc;
        unsigned int link_len;
        unsigned int ofs;
-       struct MD5Context md5_ctx;
        u8 md5_hash[16];
 
        if (buf_len != CIFS_MF_SYMLINK_FILE_SIZE)
@@ -107,9 +146,11 @@ CIFSFormatMFSymlink(u8 *buf, unsigned int buf_len, const char *link_str)
        if (link_len > CIFS_MF_SYMLINK_LINK_MAXLEN)
                return -ENAMETOOLONG;
 
-       cifs_MD5_init(&md5_ctx);
-       cifs_MD5_update(&md5_ctx, (const u8 *)link_str, link_len);
-       cifs_MD5_final(md5_hash, &md5_ctx);
+       rc = symlink_hash(link_len, link_str, md5_hash);
+       if (rc) {
+               cFYI(1, "%s: MD5 hash failure: %d\n", __func__, rc);
+               return rc;
+       }
 
        snprintf(buf, buf_len,
                 CIFS_MF_SYMLINK_LEN_FORMAT CIFS_MF_SYMLINK_MD5_FORMAT,
diff --git a/fs/cifs/md4.c b/fs/cifs/md4.c
deleted file mode 100644 (file)
index a725c26..0000000
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
-   Unix SMB/Netbios implementation.
-   Version 1.9.
-   a implementation of MD4 designed for use in the SMB authentication protocol
-   Copyright (C) Andrew Tridgell 1997-1998.
-   Modified by Steve French (sfrench@us.ibm.com) 2002-2003
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
-   (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-#include <linux/module.h>
-#include <linux/fs.h>
-#include "cifsencrypt.h"
-
-/* NOTE: This code makes no attempt to be fast! */
-
-static __u32
-F(__u32 X, __u32 Y, __u32 Z)
-{
-       return (X & Y) | ((~X) & Z);
-}
-
-static __u32
-G(__u32 X, __u32 Y, __u32 Z)
-{
-       return (X & Y) | (X & Z) | (Y & Z);
-}
-
-static __u32
-H(__u32 X, __u32 Y, __u32 Z)
-{
-       return X ^ Y ^ Z;
-}
-
-static __u32
-lshift(__u32 x, int s)
-{
-       x &= 0xFFFFFFFF;
-       return ((x << s) & 0xFFFFFFFF) | (x >> (32 - s));
-}
-
-#define ROUND1(a,b,c,d,k,s) (*a) = lshift((*a) + F(*b,*c,*d) + X[k], s)
-#define ROUND2(a,b,c,d,k,s) (*a) = lshift((*a) + G(*b,*c,*d) + X[k] + (__u32)0x5A827999,s)
-#define ROUND3(a,b,c,d,k,s) (*a) = lshift((*a) + H(*b,*c,*d) + X[k] + (__u32)0x6ED9EBA1,s)
-
-/* this applies md4 to 64 byte chunks */
-static void
-mdfour64(__u32 *M, __u32 *A, __u32 *B, __u32 *C, __u32 *D)
-{
-       int j;
-       __u32 AA, BB, CC, DD;
-       __u32 X[16];
-
-
-       for (j = 0; j < 16; j++)
-               X[j] = M[j];
-
-       AA = *A;
-       BB = *B;
-       CC = *C;
-       DD = *D;
-
-       ROUND1(A, B, C, D, 0, 3);
-       ROUND1(D, A, B, C, 1, 7);
-       ROUND1(C, D, A, B, 2, 11);
-       ROUND1(B, C, D, A, 3, 19);
-       ROUND1(A, B, C, D, 4, 3);
-       ROUND1(D, A, B, C, 5, 7);
-       ROUND1(C, D, A, B, 6, 11);
-       ROUND1(B, C, D, A, 7, 19);
-       ROUND1(A, B, C, D, 8, 3);
-       ROUND1(D, A, B, C, 9, 7);
-       ROUND1(C, D, A, B, 10, 11);
-       ROUND1(B, C, D, A, 11, 19);
-       ROUND1(A, B, C, D, 12, 3);
-       ROUND1(D, A, B, C, 13, 7);
-       ROUND1(C, D, A, B, 14, 11);
-       ROUND1(B, C, D, A, 15, 19);
-
-       ROUND2(A, B, C, D, 0, 3);
-       ROUND2(D, A, B, C, 4, 5);
-       ROUND2(C, D, A, B, 8, 9);
-       ROUND2(B, C, D, A, 12, 13);
-       ROUND2(A, B, C, D, 1, 3);
-       ROUND2(D, A, B, C, 5, 5);
-       ROUND2(C, D, A, B, 9, 9);
-       ROUND2(B, C, D, A, 13, 13);
-       ROUND2(A, B, C, D, 2, 3);
-       ROUND2(D, A, B, C, 6, 5);
-       ROUND2(C, D, A, B, 10, 9);
-       ROUND2(B, C, D, A, 14, 13);
-       ROUND2(A, B, C, D, 3, 3);
-       ROUND2(D, A, B, C, 7, 5);
-       ROUND2(C, D, A, B, 11, 9);
-       ROUND2(B, C, D, A, 15, 13);
-
-       ROUND3(A, B, C, D, 0, 3);
-       ROUND3(D, A, B, C, 8, 9);
-       ROUND3(C, D, A, B, 4, 11);
-       ROUND3(B, C, D, A, 12, 15);
-       ROUND3(A, B, C, D, 2, 3);
-       ROUND3(D, A, B, C, 10, 9);
-       ROUND3(C, D, A, B, 6, 11);
-       ROUND3(B, C, D, A, 14, 15);
-       ROUND3(A, B, C, D, 1, 3);
-       ROUND3(D, A, B, C, 9, 9);
-       ROUND3(C, D, A, B, 5, 11);
-       ROUND3(B, C, D, A, 13, 15);
-       ROUND3(A, B, C, D, 3, 3);
-       ROUND3(D, A, B, C, 11, 9);
-       ROUND3(C, D, A, B, 7, 11);
-       ROUND3(B, C, D, A, 15, 15);
-
-       *A += AA;
-       *B += BB;
-       *C += CC;
-       *D += DD;
-
-       *A &= 0xFFFFFFFF;
-       *B &= 0xFFFFFFFF;
-       *C &= 0xFFFFFFFF;
-       *D &= 0xFFFFFFFF;
-
-       for (j = 0; j < 16; j++)
-               X[j] = 0;
-}
-
-static void
-copy64(__u32 *M, unsigned char *in)
-{
-       int i;
-
-       for (i = 0; i < 16; i++)
-               M[i] = (in[i * 4 + 3] << 24) | (in[i * 4 + 2] << 16) |
-                   (in[i * 4 + 1] << 8) | (in[i * 4 + 0] << 0);
-}
-
-static void
-copy4(unsigned char *out, __u32 x)
-{
-       out[0] = x & 0xFF;
-       out[1] = (x >> 8) & 0xFF;
-       out[2] = (x >> 16) & 0xFF;
-       out[3] = (x >> 24) & 0xFF;
-}
-
-/* produce a md4 message digest from data of length n bytes */
-void
-mdfour(unsigned char *out, unsigned char *in, int n)
-{
-       unsigned char buf[128];
-       __u32 M[16];
-       __u32 b = n * 8;
-       int i;
-       __u32 A = 0x67452301;
-       __u32 B = 0xefcdab89;
-       __u32 C = 0x98badcfe;
-       __u32 D = 0x10325476;
-
-       while (n > 64) {
-               copy64(M, in);
-               mdfour64(M, &A, &B, &C, &D);
-               in += 64;
-               n -= 64;
-       }
-
-       for (i = 0; i < 128; i++)
-               buf[i] = 0;
-       memcpy(buf, in, n);
-       buf[n] = 0x80;
-
-       if (n <= 55) {
-               copy4(buf + 56, b);
-               copy64(M, buf);
-               mdfour64(M, &A, &B, &C, &D);
-       } else {
-               copy4(buf + 120, b);
-               copy64(M, buf);
-               mdfour64(M, &A, &B, &C, &D);
-               copy64(M, buf + 64);
-               mdfour64(M, &A, &B, &C, &D);
-       }
-
-       for (i = 0; i < 128; i++)
-               buf[i] = 0;
-       copy64(M, buf);
-
-       copy4(out, A);
-       copy4(out + 4, B);
-       copy4(out + 8, C);
-       copy4(out + 12, D);
-
-       A = B = C = D = 0;
-}
diff --git a/fs/cifs/md5.c b/fs/cifs/md5.c
deleted file mode 100644 (file)
index 98b66a5..0000000
+++ /dev/null
@@ -1,366 +0,0 @@
-/*
- * This code implements the MD5 message-digest algorithm.
- * The algorithm is due to Ron Rivest.  This code was
- * written by Colin Plumb in 1993, no copyright is claimed.
- * This code is in the public domain; do with it what you wish.
- *
- * Equivalent code is available from RSA Data Security, Inc.
- * This code has been tested against that, and is equivalent,
- * except that you don't need to include two pages of legalese
- * with every copy.
- *
- * To compute the message digest of a chunk of bytes, declare an
- * MD5Context structure, pass it to cifs_MD5_init, call cifs_MD5_update as
- * needed on buffers full of bytes, and then call cifs_MD5_final, which
- * will fill a supplied 16-byte array with the digest.
- */
-
-/* This code slightly modified to fit into Samba by
-   abartlet@samba.org Jun 2001
-   and to fit the cifs vfs by
-   Steve French sfrench@us.ibm.com */
-
-#include <linux/string.h>
-#include "md5.h"
-
-static void MD5Transform(__u32 buf[4], __u32 const in[16]);
-
-/*
- * Note: this code is harmless on little-endian machines.
- */
-static void
-byteReverse(unsigned char *buf, unsigned longs)
-{
-       __u32 t;
-       do {
-               t = (__u32) ((unsigned) buf[3] << 8 | buf[2]) << 16 |
-                   ((unsigned) buf[1] << 8 | buf[0]);
-               *(__u32 *) buf = t;
-               buf += 4;
-       } while (--longs);
-}
-
-/*
- * Start MD5 accumulation.  Set bit count to 0 and buffer to mysterious
- * initialization constants.
- */
-void
-cifs_MD5_init(struct MD5Context *ctx)
-{
-       ctx->buf[0] = 0x67452301;
-       ctx->buf[1] = 0xefcdab89;
-       ctx->buf[2] = 0x98badcfe;
-       ctx->buf[3] = 0x10325476;
-
-       ctx->bits[0] = 0;
-       ctx->bits[1] = 0;
-}
-
-/*
- * Update context to reflect the concatenation of another buffer full
- * of bytes.
- */
-void
-cifs_MD5_update(struct MD5Context *ctx, unsigned char const *buf, unsigned len)
-{
-       register __u32 t;
-
-       /* Update bitcount */
-
-       t = ctx->bits[0];
-       if ((ctx->bits[0] = t + ((__u32) len << 3)) < t)
-               ctx->bits[1]++; /* Carry from low to high */
-       ctx->bits[1] += len >> 29;
-
-       t = (t >> 3) & 0x3f;    /* Bytes already in shsInfo->data */
-
-       /* Handle any leading odd-sized chunks */
-
-       if (t) {
-               unsigned char *p = (unsigned char *) ctx->in + t;
-
-               t = 64 - t;
-               if (len < t) {
-                       memmove(p, buf, len);
-                       return;
-               }
-               memmove(p, buf, t);
-               byteReverse(ctx->in, 16);
-               MD5Transform(ctx->buf, (__u32 *) ctx->in);
-               buf += t;
-               len -= t;
-       }
-       /* Process data in 64-byte chunks */
-
-       while (len >= 64) {
-               memmove(ctx->in, buf, 64);
-               byteReverse(ctx->in, 16);
-               MD5Transform(ctx->buf, (__u32 *) ctx->in);
-               buf += 64;
-               len -= 64;
-       }
-
-       /* Handle any remaining bytes of data. */
-
-       memmove(ctx->in, buf, len);
-}
-
-/*
- * Final wrapup - pad to 64-byte boundary with the bit pattern
- * 1 0* (64-bit count of bits processed, MSB-first)
- */
-void
-cifs_MD5_final(unsigned char digest[16], struct MD5Context *ctx)
-{
-       unsigned int count;
-       unsigned char *p;
-
-       /* Compute number of bytes mod 64 */
-       count = (ctx->bits[0] >> 3) & 0x3F;
-
-       /* Set the first char of padding to 0x80.  This is safe since there is
-          always at least one byte free */
-       p = ctx->in + count;
-       *p++ = 0x80;
-
-       /* Bytes of padding needed to make 64 bytes */
-       count = 64 - 1 - count;
-
-       /* Pad out to 56 mod 64 */
-       if (count < 8) {
-               /* Two lots of padding:  Pad the first block to 64 bytes */
-               memset(p, 0, count);
-               byteReverse(ctx->in, 16);
-               MD5Transform(ctx->buf, (__u32 *) ctx->in);
-
-               /* Now fill the next block with 56 bytes */
-               memset(ctx->in, 0, 56);
-       } else {
-               /* Pad block to 56 bytes */
-               memset(p, 0, count - 8);
-       }
-       byteReverse(ctx->in, 14);
-
-       /* Append length in bits and transform */
-       ((__u32 *) ctx->in)[14] = ctx->bits[0];
-       ((__u32 *) ctx->in)[15] = ctx->bits[1];
-
-       MD5Transform(ctx->buf, (__u32 *) ctx->in);
-       byteReverse((unsigned char *) ctx->buf, 4);
-       memmove(digest, ctx->buf, 16);
-       memset(ctx, 0, sizeof(*ctx));   /* In case it's sensitive */
-}
-
-/* The four core functions - F1 is optimized somewhat */
-
-/* #define F1(x, y, z) (x & y | ~x & z) */
-#define F1(x, y, z) (z ^ (x & (y ^ z)))
-#define F2(x, y, z) F1(z, x, y)
-#define F3(x, y, z) (x ^ y ^ z)
-#define F4(x, y, z) (y ^ (x | ~z))
-
-/* This is the central step in the MD5 algorithm. */
-#define MD5STEP(f, w, x, y, z, data, s) \
-       (w += f(x, y, z) + data,  w = w<<s | w>>(32-s),  w += x)
-
-/*
- * The core of the MD5 algorithm, this alters an existing MD5 hash to
- * reflect the addition of 16 longwords of new data.  cifs_MD5_update blocks
- * the data and converts bytes into longwords for this routine.
- */
-static void
-MD5Transform(__u32 buf[4], __u32 const in[16])
-{
-       register __u32 a, b, c, d;
-
-       a = buf[0];
-       b = buf[1];
-       c = buf[2];
-       d = buf[3];
-
-       MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
-       MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
-       MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
-       MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
-       MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
-       MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
-       MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
-       MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
-       MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
-       MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
-       MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
-       MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
-       MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
-       MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
-       MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
-       MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
-
-       MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
-       MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
-       MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
-       MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
-       MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
-       MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
-       MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
-       MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
-       MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
-       MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
-       MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
-       MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
-       MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
-       MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
-       MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
-       MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
-
-       MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
-       MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
-       MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
-       MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
-       MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
-       MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
-       MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
-       MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
-       MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
-       MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
-       MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
-       MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
-       MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
-       MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
-       MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
-       MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
-
-       MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
-       MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
-       MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
-       MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
-       MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
-       MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
-       MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
-       MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
-       MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
-       MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
-       MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
-       MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
-       MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
-       MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
-       MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
-       MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
-
-       buf[0] += a;
-       buf[1] += b;
-       buf[2] += c;
-       buf[3] += d;
-}
-
-#if 0   /* currently unused */
-/***********************************************************************
- the rfc 2104 version of hmac_md5 initialisation.
-***********************************************************************/
-static void
-hmac_md5_init_rfc2104(unsigned char *key, int key_len,
-                     struct HMACMD5Context *ctx)
-{
-       int i;
-
-       /* if key is longer than 64 bytes reset it to key=MD5(key) */
-       if (key_len > 64) {
-               unsigned char tk[16];
-               struct MD5Context tctx;
-
-               cifs_MD5_init(&tctx);
-               cifs_MD5_update(&tctx, key, key_len);
-               cifs_MD5_final(tk, &tctx);
-
-               key = tk;
-               key_len = 16;
-       }
-
-       /* start out by storing key in pads */
-       memset(ctx->k_ipad, 0, sizeof(ctx->k_ipad));
-       memset(ctx->k_opad, 0, sizeof(ctx->k_opad));
-       memcpy(ctx->k_ipad, key, key_len);
-       memcpy(ctx->k_opad, key, key_len);
-
-       /* XOR key with ipad and opad values */
-       for (i = 0; i < 64; i++) {
-               ctx->k_ipad[i] ^= 0x36;
-               ctx->k_opad[i] ^= 0x5c;
-       }
-
-       cifs_MD5_init(&ctx->ctx);
-       cifs_MD5_update(&ctx->ctx, ctx->k_ipad, 64);
-}
-#endif
-
-/***********************************************************************
- the microsoft version of hmac_md5 initialisation.
-***********************************************************************/
-void
-hmac_md5_init_limK_to_64(const unsigned char *key, int key_len,
-                        struct HMACMD5Context *ctx)
-{
-       int i;
-
-       /* if key is longer than 64 bytes truncate it */
-       if (key_len > 64)
-               key_len = 64;
-
-       /* start out by storing key in pads */
-       memset(ctx->k_ipad, 0, sizeof(ctx->k_ipad));
-       memset(ctx->k_opad, 0, sizeof(ctx->k_opad));
-       memcpy(ctx->k_ipad, key, key_len);
-       memcpy(ctx->k_opad, key, key_len);
-
-       /* XOR key with ipad and opad values */
-       for (i = 0; i < 64; i++) {
-               ctx->k_ipad[i] ^= 0x36;
-               ctx->k_opad[i] ^= 0x5c;
-       }
-
-       cifs_MD5_init(&ctx->ctx);
-       cifs_MD5_update(&ctx->ctx, ctx->k_ipad, 64);
-}
-
-/***********************************************************************
- update hmac_md5 "inner" buffer
-***********************************************************************/
-void
-hmac_md5_update(const unsigned char *text, int text_len,
-               struct HMACMD5Context *ctx)
-{
-       cifs_MD5_update(&ctx->ctx, text, text_len);     /* then text of datagram */
-}
-
-/***********************************************************************
- finish off hmac_md5 "inner" buffer and generate outer one.
-***********************************************************************/
-void
-hmac_md5_final(unsigned char *digest, struct HMACMD5Context *ctx)
-{
-       struct MD5Context ctx_o;
-
-       cifs_MD5_final(digest, &ctx->ctx);
-
-       cifs_MD5_init(&ctx_o);
-       cifs_MD5_update(&ctx_o, ctx->k_opad, 64);
-       cifs_MD5_update(&ctx_o, digest, 16);
-       cifs_MD5_final(digest, &ctx_o);
-}
-
-/***********************************************************
- single function to calculate an HMAC MD5 digest from data.
- use the microsoft hmacmd5 init method because the key is 16 bytes.
-************************************************************/
-#if 0 /* currently unused */
-static void
-hmac_md5(unsigned char key[16], unsigned char *data, int data_len,
-        unsigned char *digest)
-{
-       struct HMACMD5Context ctx;
-       hmac_md5_init_limK_to_64(key, 16, &ctx);
-       if (data_len != 0)
-               hmac_md5_update(data, data_len, &ctx);
-
-       hmac_md5_final(digest, &ctx);
-}
-#endif
diff --git a/fs/cifs/md5.h b/fs/cifs/md5.h
deleted file mode 100644 (file)
index 6fba8cb..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-#ifndef MD5_H
-#define MD5_H
-#ifndef HEADER_MD5_H
-/* Try to avoid clashes with OpenSSL */
-#define HEADER_MD5_H
-#endif
-
-struct MD5Context {
-       __u32 buf[4];
-       __u32 bits[2];
-       unsigned char in[64];
-};
-#endif                         /* !MD5_H */
-
-#ifndef _HMAC_MD5_H
-struct HMACMD5Context {
-       struct MD5Context ctx;
-       unsigned char k_ipad[65];
-       unsigned char k_opad[65];
-};
-#endif                         /* _HMAC_MD5_H */
-
-void cifs_MD5_init(struct MD5Context *context);
-void cifs_MD5_update(struct MD5Context *context, unsigned char const *buf,
-                       unsigned len);
-void cifs_MD5_final(unsigned char digest[16], struct MD5Context *context);
-
-/* The following definitions come from lib/hmacmd5.c  */
-
-/* void hmac_md5_init_rfc2104(unsigned char *key, int key_len,
-                       struct HMACMD5Context *ctx);*/
-void hmac_md5_init_limK_to_64(const unsigned char *key, int key_len,
-                       struct HMACMD5Context *ctx);
-void hmac_md5_update(const unsigned char *text, int text_len,
-                       struct HMACMD5Context *ctx);
-void hmac_md5_final(unsigned char *digest, struct HMACMD5Context *ctx);
-/* void hmac_md5(unsigned char key[16], unsigned char *data, int data_len,
-                       unsigned char *digest);*/
index a09e077ba92531e7d8614fc2ce0f8878613c36fb..2a930a752a784faea9ee912211c3f7a88e1ce9d5 100644 (file)
@@ -236,10 +236,7 @@ __u16 GetNextMid(struct TCP_Server_Info *server)
 {
        __u16 mid = 0;
        __u16 last_mid;
-       int   collision;
-
-       if (server == NULL)
-               return mid;
+       bool collision;
 
        spin_lock(&GlobalMid_Lock);
        last_mid = server->CurrentMid; /* we do not want to loop forever */
@@ -252,24 +249,38 @@ __u16 GetNextMid(struct TCP_Server_Info *server)
        (and it would also have to have been a request that
         did not time out) */
        while (server->CurrentMid != last_mid) {
-               struct list_head *tmp;
                struct mid_q_entry *mid_entry;
+               unsigned int num_mids;
 
-               collision = 0;
+               collision = false;
                if (server->CurrentMid == 0)
                        server->CurrentMid++;
 
-               list_for_each(tmp, &server->pending_mid_q) {
-                       mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
-
-                       if ((mid_entry->mid == server->CurrentMid) &&
-                           (mid_entry->midState == MID_REQUEST_SUBMITTED)) {
+               num_mids = 0;
+               list_for_each_entry(mid_entry, &server->pending_mid_q, qhead) {
+                       ++num_mids;
+                       if (mid_entry->mid == server->CurrentMid &&
+                           mid_entry->midState == MID_REQUEST_SUBMITTED) {
                                /* This mid is in use, try a different one */
-                               collision = 1;
+                               collision = true;
                                break;
                        }
                }
-               if (collision == 0) {
+
+               /*
+                * if we have more than 32k mids in the list, then something
+                * is very wrong. Possibly a local user is trying to DoS the
+                * box by issuing long-running calls and SIGKILL'ing them. If
+                * we get to 2^16 mids then we're in big trouble as this
+                * function could loop forever.
+                *
+                * Go ahead and assign out the mid in this situation, but force
+                * an eventual reconnect to clean out the pending_mid_q.
+                */
+               if (num_mids > 32768)
+                       server->tcpStatus = CifsNeedReconnect;
+
+               if (!collision) {
                        mid = server->CurrentMid;
                        break;
                }
@@ -381,29 +392,31 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ ,
 }
 
 static int
-checkSMBhdr(struct smb_hdr *smb, __u16 mid)
+check_smb_hdr(struct smb_hdr *smb, __u16 mid)
 {
-       /* Make sure that this really is an SMB, that it is a response,
-          and that the message ids match */
-       if ((*(__le32 *) smb->Protocol == cpu_to_le32(0x424d53ff)) &&
-               (mid == smb->Mid)) {
-               if (smb->Flags & SMBFLG_RESPONSE)
-                       return 0;
-               else {
-               /* only one valid case where server sends us request */
-                       if (smb->Command == SMB_COM_LOCKING_ANDX)
-                               return 0;
-                       else
-                               cERROR(1, "Received Request not response");
-               }
-       } else { /* bad signature or mid */
-               if (*(__le32 *) smb->Protocol != cpu_to_le32(0x424d53ff))
-                       cERROR(1, "Bad protocol string signature header %x",
-                               *(unsigned int *) smb->Protocol);
-               if (mid != smb->Mid)
-                       cERROR(1, "Mids do not match");
+       /* does it have the right SMB "signature" ? */
+       if (*(__le32 *) smb->Protocol != cpu_to_le32(0x424d53ff)) {
+               cERROR(1, "Bad protocol string signature header 0x%x",
+                       *(unsigned int *)smb->Protocol);
+               return 1;
+       }
+
+       /* Make sure that message ids match */
+       if (mid != smb->Mid) {
+               cERROR(1, "Mids do not match. received=%u expected=%u",
+                       smb->Mid, mid);
+               return 1;
        }
-       cERROR(1, "bad smb detected. The Mid=%d", smb->Mid);
+
+       /* if it's a response then accept */
+       if (smb->Flags & SMBFLG_RESPONSE)
+               return 0;
+
+       /* only one valid case where server sends us request */
+       if (smb->Command == SMB_COM_LOCKING_ANDX)
+               return 0;
+
+       cERROR(1, "Server sent request, not response. mid=%u", smb->Mid);
        return 1;
 }
 
@@ -448,7 +461,7 @@ checkSMB(struct smb_hdr *smb, __u16 mid, unsigned int length)
                return 1;
        }
 
-       if (checkSMBhdr(smb, mid))
+       if (check_smb_hdr(smb, mid))
                return 1;
        clc_len = smbCalcSize_LE(smb);
 
@@ -465,25 +478,26 @@ checkSMB(struct smb_hdr *smb, __u16 mid, unsigned int length)
                        if (((4 + len) & 0xFFFF) == (clc_len & 0xFFFF))
                                return 0; /* bcc wrapped */
                }
-               cFYI(1, "Calculated size %d vs length %d mismatch for mid %d",
+               cFYI(1, "Calculated size %u vs length %u mismatch for mid=%u",
                                clc_len, 4 + len, smb->Mid);
-               /* Windows XP can return a few bytes too much, presumably
-               an illegal pad, at the end of byte range lock responses
-               so we allow for that three byte pad, as long as actual
-               received length is as long or longer than calculated length */
-               /* We have now had to extend this more, since there is a
-               case in which it needs to be bigger still to handle a
-               malformed response to transact2 findfirst from WinXP when
-               access denied is returned and thus bcc and wct are zero
-               but server says length is 0x21 bytes too long as if the server
-               forget to reset the smb rfc1001 length when it reset the
-               wct and bcc to minimum size and drop the t2 parms and data */
-               if ((4+len > clc_len) && (len <= clc_len + 512))
-                       return 0;
-               else {
-                       cERROR(1, "RFC1001 size %d bigger than SMB for Mid=%d",
+
+               if (4 + len < clc_len) {
+                       cERROR(1, "RFC1001 size %u smaller than SMB for mid=%u",
                                        len, smb->Mid);
                        return 1;
+               } else if (len > clc_len + 512) {
+                       /*
+                        * Some servers (Windows XP in particular) send more
+                        * data than the lengths in the SMB packet would
+                        * indicate on certain calls (byte range locks and
+                        * trans2 find first calls in particular). While the
+                        * client can handle such a frame by ignoring the
+                        * trailing data, we choose limit the amount of extra
+                        * data to 512 bytes.
+                        */
+                       cERROR(1, "RFC1001 size %u more than 512 bytes larger "
+                                 "than SMB for mid=%u", len, smb->Mid);
+                       return 1;
                }
        }
        return 0;
index 7f25cc3d22569509cd59ac27f6b9e3acc2ddaf5f..f8e4cd2a79127a855b8c319b4d6c2d9fbfa5f2c1 100644 (file)
@@ -764,7 +764,6 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
 {
        int rc = 0;
        int xid, i;
-       struct cifs_sb_info *cifs_sb;
        struct cifsTconInfo *pTcon;
        struct cifsFileInfo *cifsFile = NULL;
        char *current_entry;
@@ -775,8 +774,6 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
 
        xid = GetXid();
 
-       cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
-
        /*
         * Ensure FindFirst doesn't fail before doing filldir() for '.' and
         * '..'. Otherwise we won't be able to notify VFS in case of failure.
index b6b6dcb500bf5e11d017a05cae57778edd4e18da..04721485925d9ffc763e5cfd3233a6de34cd789b 100644 (file)
@@ -45,7 +45,6 @@
    up with a different answer to the one above)
 */
 #include <linux/slab.h>
-#include "cifsencrypt.h"
 #define uchar unsigned char
 
 static uchar perm1[56] = { 57, 49, 41, 33, 25, 17, 9,
index 192ea51af20f49c8976fa734ca44f79e988d7f6b..b5041c84998137a6bbe251df2c7c55806def0cb4 100644 (file)
@@ -32,9 +32,8 @@
 #include "cifs_unicode.h"
 #include "cifspdu.h"
 #include "cifsglob.h"
-#include "md5.h"
 #include "cifs_debug.h"
-#include "cifsencrypt.h"
+#include "cifsproto.h"
 
 #ifndef false
 #define false 0
 #define SSVALX(buf,pos,val) (CVAL(buf,pos)=(val)&0xFF,CVAL(buf,pos+1)=(val)>>8)
 #define SSVAL(buf,pos,val) SSVALX((buf),(pos),((__u16)(val)))
 
-/*The following definitions come from  libsmb/smbencrypt.c  */
+/* produce a md4 message digest from data of length n bytes */
+int
+mdfour(unsigned char *md4_hash, unsigned char *link_str, int link_len)
+{
+       int rc;
+       unsigned int size;
+       struct crypto_shash *md4;
+       struct sdesc *sdescmd4;
+
+       md4 = crypto_alloc_shash("md4", 0, 0);
+       if (IS_ERR(md4)) {
+               rc = PTR_ERR(md4);
+               cERROR(1, "%s: Crypto md4 allocation error %d\n", __func__, rc);
+               return rc;
+       }
+       size = sizeof(struct shash_desc) + crypto_shash_descsize(md4);
+       sdescmd4 = kmalloc(size, GFP_KERNEL);
+       if (!sdescmd4) {
+               rc = -ENOMEM;
+               cERROR(1, "%s: Memory allocation failure\n", __func__);
+               goto mdfour_err;
+       }
+       sdescmd4->shash.tfm = md4;
+       sdescmd4->shash.flags = 0x0;
+
+       rc = crypto_shash_init(&sdescmd4->shash);
+       if (rc) {
+               cERROR(1, "%s: Could not init md4 shash\n", __func__);
+               goto mdfour_err;
+       }
+       crypto_shash_update(&sdescmd4->shash, link_str, link_len);
+       rc = crypto_shash_final(&sdescmd4->shash, md4_hash);
 
-void SMBencrypt(unsigned char *passwd, const unsigned char *c8,
-               unsigned char *p24);
-void E_md4hash(const unsigned char *passwd, unsigned char *p16);
-static void SMBOWFencrypt(unsigned char passwd[16], const unsigned char *c8,
-                  unsigned char p24[24]);
-void SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24);
+mdfour_err:
+       crypto_free_shash(md4);
+       kfree(sdescmd4);
+
+       return rc;
+}
+
+/* Does the des encryption from the NT or LM MD4 hash. */
+static void
+SMBOWFencrypt(unsigned char passwd[16], const unsigned char *c8,
+             unsigned char p24[24])
+{
+       unsigned char p21[21];
+
+       memset(p21, '\0', 21);
+
+       memcpy(p21, passwd, 16);
+       E_P24(p21, c8, p24);
+}
 
 /*
    This implements the X/Open SMB password encryption
@@ -118,9 +161,10 @@ _my_mbstowcs(__u16 *dst, const unsigned char *src, int len)
  * Creates the MD4 Hash of the users password in NT UNICODE.
  */
 
-void
+int
 E_md4hash(const unsigned char *passwd, unsigned char *p16)
 {
+       int rc;
        int len;
        __u16 wpwd[129];
 
@@ -139,8 +183,10 @@ E_md4hash(const unsigned char *passwd, unsigned char *p16)
        /* Calculate length in bytes */
        len = _my_wcslen(wpwd) * sizeof(__u16);
 
-       mdfour(p16, (unsigned char *) wpwd, len);
+       rc = mdfour(p16, (unsigned char *) wpwd, len);
        memset(wpwd, 0, 129 * 2);
+
+       return rc;
 }
 
 #if 0 /* currently unused */
@@ -212,19 +258,6 @@ ntv2_owf_gen(const unsigned char owf[16], const char *user_n,
 }
 #endif
 
-/* Does the des encryption from the NT or LM MD4 hash. */
-static void
-SMBOWFencrypt(unsigned char passwd[16], const unsigned char *c8,
-             unsigned char p24[24])
-{
-       unsigned char p21[21];
-
-       memset(p21, '\0', 21);
-
-       memcpy(p21, passwd, 16);
-       E_P24(p21, c8, p24);
-}
-
 /* Does the des encryption from the FIRST 8 BYTES of the NT or LM MD4 hash. */
 #if 0 /* currently unused */
 static void
@@ -242,16 +275,21 @@ NTLMSSPOWFencrypt(unsigned char passwd[8],
 #endif
 
 /* Does the NT MD4 hash then des encryption. */
-
-void
+int
 SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24)
 {
+       int rc;
        unsigned char p21[21];
 
        memset(p21, '\0', 21);
 
-       E_md4hash(passwd, p21);
+       rc = E_md4hash(passwd, p21);
+       if (rc) {
+               cFYI(1, "%s Can't generate NT hash, error: %d", __func__, rc);
+               return rc;
+       }
        SMBOWFencrypt(p21, c8, p24);
+       return rc;
 }
 
 
index c1ccca1a933ffca32d96800dd697bbb1d504d761..b8c5e2eb43d0866d59d293afafc72873867a0e93 100644 (file)
@@ -236,9 +236,9 @@ smb_sendv(struct TCP_Server_Info *server, struct kvec *iov, int n_vec)
                server->tcpStatus = CifsNeedReconnect;
        }
 
-       if (rc < 0) {
+       if (rc < 0 && rc != -EINTR)
                cERROR(1, "Error %d sending data on socket to server", rc);
-       else
+       else
                rc = 0;
 
        /* Don't want to modify the buffer as a
@@ -570,17 +570,33 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
 #endif
 
        mutex_unlock(&ses->server->srv_mutex);
-       cifs_small_buf_release(in_buf);
 
-       if (rc < 0)
+       if (rc < 0) {
+               cifs_small_buf_release(in_buf);
                goto out;
+       }
 
-       if (long_op == CIFS_ASYNC_OP)
+       if (long_op == CIFS_ASYNC_OP) {
+               cifs_small_buf_release(in_buf);
                goto out;
+       }
 
        rc = wait_for_response(ses->server, midQ);
-       if (rc != 0)
-               goto out;
+       if (rc != 0) {
+               send_nt_cancel(ses->server, in_buf, midQ);
+               spin_lock(&GlobalMid_Lock);
+               if (midQ->midState == MID_REQUEST_SUBMITTED) {
+                       midQ->callback = DeleteMidQEntry;
+                       spin_unlock(&GlobalMid_Lock);
+                       cifs_small_buf_release(in_buf);
+                       atomic_dec(&ses->server->inFlight);
+                       wake_up(&ses->server->request_q);
+                       return rc;
+               }
+               spin_unlock(&GlobalMid_Lock);
+       }
+
+       cifs_small_buf_release(in_buf);
 
        rc = sync_mid_result(midQ, ses->server);
        if (rc != 0) {
@@ -724,8 +740,19 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
                goto out;
 
        rc = wait_for_response(ses->server, midQ);
-       if (rc != 0)
-               goto out;
+       if (rc != 0) {
+               send_nt_cancel(ses->server, in_buf, midQ);
+               spin_lock(&GlobalMid_Lock);
+               if (midQ->midState == MID_REQUEST_SUBMITTED) {
+                       /* no longer considered to be "in-flight" */
+                       midQ->callback = DeleteMidQEntry;
+                       spin_unlock(&GlobalMid_Lock);
+                       atomic_dec(&ses->server->inFlight);
+                       wake_up(&ses->server->request_q);
+                       return rc;
+               }
+               spin_unlock(&GlobalMid_Lock);
+       }
 
        rc = sync_mid_result(midQ, ses->server);
        if (rc != 0) {
@@ -922,10 +949,21 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon,
                        }
                }
 
-               if (wait_for_response(ses->server, midQ) == 0) {
-                       /* We got the response - restart system call. */
-                       rstart = 1;
+               rc = wait_for_response(ses->server, midQ);
+               if (rc) {
+                       send_nt_cancel(ses->server, in_buf, midQ);
+                       spin_lock(&GlobalMid_Lock);
+                       if (midQ->midState == MID_REQUEST_SUBMITTED) {
+                               /* no longer considered to be "in-flight" */
+                               midQ->callback = DeleteMidQEntry;
+                               spin_unlock(&GlobalMid_Lock);
+                               return rc;
+                       }
+                       spin_unlock(&GlobalMid_Lock);
                }
+
+               /* We got the response - restart system call. */
+               rstart = 1;
        }
 
        rc = sync_mid_result(midQ, ses->server);
index 9f493ee4dcba79c6c590692a15ea088ff94522b0..2a6bd9a4ae975fdc3eedf9723b551fc9e5f65836 100644 (file)
@@ -176,6 +176,7 @@ static void d_free(struct dentry *dentry)
 
 /**
  * dentry_rcuwalk_barrier - invalidate in-progress rcu-walk lookups
+ * @dentry: the target dentry
  * After this call, in-progress rcu-walk path lookup will fail. This
  * should be called after unhashing, and after changing d_inode (if
  * the dentry has not already been unhashed).
@@ -281,6 +282,7 @@ static void dentry_lru_move_tail(struct dentry *dentry)
 /**
  * d_kill - kill dentry and return parent
  * @dentry: dentry to kill
+ * @parent: parent dentry
  *
  * The dentry must already be unhashed and removed from the LRU.
  *
@@ -1973,7 +1975,7 @@ out:
 /**
  * d_validate - verify dentry provided from insecure source (deprecated)
  * @dentry: The dentry alleged to be valid child of @dparent
- * @parent: The parent dentry (known to be valid)
+ * @dparent: The parent dentry (known to be valid)
  *
  * An insecure source has sent us a dentry, here we verify it and dget() it.
  * This is used by ncpfs in its readdir implementation.
index cc8a9b7d606494d5b556927808feeba29f858d45..267d0ada45414a6f9cd8e90efeb9714e52e65de9 100644 (file)
@@ -1114,6 +1114,17 @@ static int ep_send_events(struct eventpoll *ep,
        return ep_scan_ready_list(ep, ep_send_events_proc, &esed);
 }
 
+static inline struct timespec ep_set_mstimeout(long ms)
+{
+       struct timespec now, ts = {
+               .tv_sec = ms / MSEC_PER_SEC,
+               .tv_nsec = NSEC_PER_MSEC * (ms % MSEC_PER_SEC),
+       };
+
+       ktime_get_ts(&now);
+       return timespec_add_safe(now, ts);
+}
+
 static int ep_poll(struct eventpoll *ep, struct epoll_event __user *events,
                   int maxevents, long timeout)
 {
@@ -1121,12 +1132,11 @@ static int ep_poll(struct eventpoll *ep, struct epoll_event __user *events,
        unsigned long flags;
        long slack;
        wait_queue_t wait;
-       struct timespec end_time;
        ktime_t expires, *to = NULL;
 
        if (timeout > 0) {
-               ktime_get_ts(&end_time);
-               timespec_add_ns(&end_time, (u64)timeout * NSEC_PER_MSEC);
+               struct timespec end_time = ep_set_mstimeout(timeout);
+
                slack = select_estimate_accuracy(&end_time);
                to = &expires;
                *to = timespec_to_ktime(end_time);
index c62efcb959c73fc458367d811c576e634fb49634..52a447d9b6abd3495b4c79ec19259455c652f786 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -120,7 +120,7 @@ SYSCALL_DEFINE1(uselib, const char __user *, library)
                goto out;
 
        file = do_filp_open(AT_FDCWD, tmp,
-                               O_LARGEFILE | O_RDONLY | FMODE_EXEC, 0,
+                               O_LARGEFILE | O_RDONLY | __FMODE_EXEC, 0,
                                MAY_READ | MAY_EXEC | MAY_OPEN);
        putname(tmp);
        error = PTR_ERR(file);
@@ -723,7 +723,7 @@ struct file *open_exec(const char *name)
        int err;
 
        file = do_filp_open(AT_FDCWD, name,
-                               O_LARGEFILE | O_RDONLY | FMODE_EXEC, 0,
+                               O_LARGEFILE | O_RDONLY | __FMODE_EXEC, 0,
                                MAY_EXEC | MAY_OPEN);
        if (IS_ERR(file))
                goto out;
index ecc8b3954ed6ca2558cf9a34e1b60fa3b9513290..cb1026181bdcc29683edfaf3236f49260c0399a7 100644 (file)
@@ -815,7 +815,7 @@ static int __init fcntl_init(void)
                __O_SYNC        | O_DSYNC       | FASYNC        |
                O_DIRECT        | O_LARGEFILE   | O_DIRECTORY   |
                O_NOFOLLOW      | O_NOATIME     | O_CLOEXEC     |
-               FMODE_EXEC
+               __FMODE_EXEC
                ));
 
        fasync_cache = kmem_cache_create("fasync_cache",
index a59635e295facb69265797bc660c823ffa456b3c..1eebeb72b20276191fcad6199d8bf0b79a4d9921 100644 (file)
@@ -273,6 +273,13 @@ int __generic_block_fiemap(struct inode *inode,
                len = isize;
        }
 
+       /*
+        * Some filesystems can't deal with being asked to map less than
+        * blocksize, so make sure our len is at least block length.
+        */
+       if (logical_to_blk(inode, len) == 0)
+               len = blk_to_logical(inode, 1);
+
        start_blk = logical_to_blk(inode, start);
        last_blk = logical_to_blk(inode, start + len - 1);
 
index 5f1bcb2f06f3e89878bed401d1ad2a23f2e0070f..b7c99bfb3da6dcb9897a85b201f1a2212b03bace 100644 (file)
@@ -520,7 +520,7 @@ static struct nlm_host *next_host_state(struct hlist_head *cache,
                                        struct nsm_handle *nsm,
                                        const struct nlm_reboot *info)
 {
-       struct nlm_host *host = NULL;
+       struct nlm_host *host;
        struct hlist_head *chain;
        struct hlist_node *pos;
 
@@ -532,12 +532,13 @@ static struct nlm_host *next_host_state(struct hlist_head *cache,
                        host->h_state++;
 
                        nlm_get_host(host);
-                       goto out;
+                       mutex_unlock(&nlm_host_mutex);
+                       return host;
                }
        }
-out:
+
        mutex_unlock(&nlm_host_mutex);
-       return host;
+       return NULL;
 }
 
 /**
index 199016528fcbefa5f7a59ece47380568b0cf0f4d..e3d29426905848101510bf0fea21f4fa2378794a 100644 (file)
@@ -134,33 +134,6 @@ out_err:
 }
 
 #if defined(CONFIG_NFS_V4_1)
-/*
- *  * CB_SEQUENCE operations will fail until the callback sessionid is set.
- *   */
-int nfs4_set_callback_sessionid(struct nfs_client *clp)
-{
-       struct svc_serv *serv = clp->cl_rpcclient->cl_xprt->bc_serv;
-       struct nfs4_sessionid *bc_sid;
-
-       if (!serv->sv_bc_xprt)
-               return -EINVAL;
-
-       /* on success freed in xprt_free */
-       bc_sid = kmalloc(sizeof(struct nfs4_sessionid), GFP_KERNEL);
-       if (!bc_sid)
-               return -ENOMEM;
-       memcpy(bc_sid->data, &clp->cl_session->sess_id.data,
-               NFS4_MAX_SESSIONID_LEN);
-       spin_lock_bh(&serv->sv_cb_lock);
-       serv->sv_bc_xprt->xpt_bc_sid = bc_sid;
-       spin_unlock_bh(&serv->sv_cb_lock);
-       dprintk("%s set xpt_bc_sid=%u:%u:%u:%u for sv_bc_xprt %p\n", __func__,
-               ((u32 *)bc_sid->data)[0], ((u32 *)bc_sid->data)[1],
-               ((u32 *)bc_sid->data)[2], ((u32 *)bc_sid->data)[3],
-               serv->sv_bc_xprt);
-       return 0;
-}
-
 /*
  * The callback service for NFSv4.1 callbacks
  */
@@ -266,10 +239,6 @@ static inline void nfs_callback_bc_serv(u32 minorversion, struct rpc_xprt *xprt,
                struct nfs_callback_data *cb_info)
 {
 }
-int nfs4_set_callback_sessionid(struct nfs_client *clp)
-{
-       return 0;
-}
 #endif /* CONFIG_NFS_V4_1 */
 
 /*
@@ -359,78 +328,58 @@ void nfs_callback_down(int minorversion)
        mutex_unlock(&nfs_callback_mutex);
 }
 
-static int check_gss_callback_principal(struct nfs_client *clp,
-                                       struct svc_rqst *rqstp)
+/* Boolean check of RPC_AUTH_GSS principal */
+int
+check_gss_callback_principal(struct nfs_client *clp, struct svc_rqst *rqstp)
 {
        struct rpc_clnt *r = clp->cl_rpcclient;
        char *p = svc_gss_principal(rqstp);
 
+       if (rqstp->rq_authop->flavour != RPC_AUTH_GSS)
+               return 1;
+
        /* No RPC_AUTH_GSS on NFSv4.1 back channel yet */
        if (clp->cl_minorversion != 0)
-               return SVC_DROP;
+               return 0;
        /*
         * It might just be a normal user principal, in which case
         * userspace won't bother to tell us the name at all.
         */
        if (p == NULL)
-               return SVC_DENIED;
+               return 0;
 
        /* Expect a GSS_C_NT_HOSTBASED_NAME like "nfs@serverhostname" */
 
        if (memcmp(p, "nfs@", 4) != 0)
-               return SVC_DENIED;
+               return 0;
        p += 4;
        if (strcmp(p, r->cl_server) != 0)
-               return SVC_DENIED;
-       return SVC_OK;
+               return 0;
+       return 1;
 }
 
-/* pg_authenticate method helper */
-static struct nfs_client *nfs_cb_find_client(struct svc_rqst *rqstp)
-{
-       struct nfs4_sessionid *sessionid = bc_xprt_sid(rqstp);
-       int is_cb_compound = rqstp->rq_proc == CB_COMPOUND ? 1 : 0;
-
-       dprintk("--> %s rq_proc %d\n", __func__, rqstp->rq_proc);
-       if (svc_is_backchannel(rqstp))
-               /* Sessionid (usually) set after CB_NULL ping */
-               return nfs4_find_client_sessionid(svc_addr(rqstp), sessionid,
-                                                 is_cb_compound);
-       else
-               /* No callback identifier in pg_authenticate */
-               return nfs4_find_client_no_ident(svc_addr(rqstp));
-}
-
-/* pg_authenticate method for nfsv4 callback threads. */
+/*
+ * pg_authenticate method for nfsv4 callback threads.
+ *
+ * The authflavor has been negotiated, so an incorrect flavor is a server
+ * bug. Drop packets with incorrect authflavor.
+ *
+ * All other checking done after NFS decoding where the nfs_client can be
+ * found in nfs4_callback_compound
+ */
 static int nfs_callback_authenticate(struct svc_rqst *rqstp)
 {
-       struct nfs_client *clp;
-       RPC_IFDEBUG(char buf[RPC_MAX_ADDRBUFLEN]);
-       int ret = SVC_OK;
-
-       /* Don't talk to strangers */
-       clp = nfs_cb_find_client(rqstp);
-       if (clp == NULL)
-               return SVC_DROP;
-
-       dprintk("%s: %s NFSv4 callback!\n", __func__,
-                       svc_print_addr(rqstp, buf, sizeof(buf)));
-
        switch (rqstp->rq_authop->flavour) {
-               case RPC_AUTH_NULL:
-                       if (rqstp->rq_proc != CB_NULL)
-                               ret = SVC_DENIED;
-                       break;
-               case RPC_AUTH_UNIX:
-                       break;
-               case RPC_AUTH_GSS:
-                       ret = check_gss_callback_principal(clp, rqstp);
-                       break;
-               default:
-                       ret = SVC_DENIED;
+       case RPC_AUTH_NULL:
+               if (rqstp->rq_proc != CB_NULL)
+                       return SVC_DROP;
+               break;
+       case RPC_AUTH_GSS:
+               /* No RPC_AUTH_GSS support yet in NFSv4.1 */
+                if (svc_is_backchannel(rqstp))
+                       return SVC_DROP;
        }
-       nfs_put_client(clp);
-       return ret;
+       return SVC_OK;
 }
 
 /*
index d3b44f9bd747a2e4516595bdcff096d6f132543a..46d93ce7311bb107a39005e0a66c818064e41ef2 100644 (file)
@@ -7,6 +7,7 @@
  */
 #ifndef __LINUX_FS_NFS_CALLBACK_H
 #define __LINUX_FS_NFS_CALLBACK_H
+#include <linux/sunrpc/svc.h>
 
 #define NFS4_CALLBACK 0x40000000
 #define NFS4_CALLBACK_XDRSIZE 2048
@@ -37,7 +38,6 @@ enum nfs4_callback_opnum {
 struct cb_process_state {
        __be32                  drc_status;
        struct nfs_client       *clp;
-       struct nfs4_sessionid   *svc_sid; /* v4.1 callback service sessionid */
 };
 
 struct cb_compound_hdr_arg {
@@ -168,7 +168,7 @@ extern unsigned nfs4_callback_layoutrecall(
 extern void nfs4_check_drain_bc_complete(struct nfs4_session *ses);
 extern void nfs4_cb_take_slot(struct nfs_client *clp);
 #endif /* CONFIG_NFS_V4_1 */
-
+extern int check_gss_callback_principal(struct nfs_client *, struct svc_rqst *);
 extern __be32 nfs4_callback_getattr(struct cb_getattrargs *args,
                                    struct cb_getattrres *res,
                                    struct cb_process_state *cps);
index 4bb91cb2620d8c389b1f021e2d996955f3550b8a..89587573fe50660ee9a13ebc8890b94f1c4adfd8 100644 (file)
@@ -373,17 +373,11 @@ __be32 nfs4_callback_sequence(struct cb_sequenceargs *args,
 {
        struct nfs_client *clp;
        int i;
-       __be32 status;
+       __be32 status = htonl(NFS4ERR_BADSESSION);
 
        cps->clp = NULL;
 
-       status = htonl(NFS4ERR_BADSESSION);
-       /* Incoming session must match the callback session */
-       if (memcmp(&args->csa_sessionid, cps->svc_sid, NFS4_MAX_SESSIONID_LEN))
-               goto out;
-
-       clp = nfs4_find_client_sessionid(args->csa_addr,
-                                        &args->csa_sessionid, 1);
+       clp = nfs4_find_client_sessionid(args->csa_addr, &args->csa_sessionid);
        if (clp == NULL)
                goto out;
 
@@ -414,9 +408,9 @@ __be32 nfs4_callback_sequence(struct cb_sequenceargs *args,
        res->csr_highestslotid = NFS41_BC_MAX_CALLBACKS - 1;
        res->csr_target_highestslotid = NFS41_BC_MAX_CALLBACKS - 1;
        nfs4_cb_take_slot(clp);
-       cps->clp = clp; /* put in nfs4_callback_compound */
 
 out:
+       cps->clp = clp; /* put in nfs4_callback_compound */
        for (i = 0; i < args->csa_nrclists; i++)
                kfree(args->csa_rclists[i].rcl_refcalls);
        kfree(args->csa_rclists);
index 23112c263f81902cb4e8ba1b09c0a31ce3bf7596..14e0f9371d1463900258ef60c361c3079f55c707 100644 (file)
@@ -794,10 +794,9 @@ static __be32 nfs4_callback_compound(struct svc_rqst *rqstp, void *argp, void *r
 
        if (hdr_arg.minorversion == 0) {
                cps.clp = nfs4_find_client_ident(hdr_arg.cb_ident);
-               if (!cps.clp)
+               if (!cps.clp || !check_gss_callback_principal(cps.clp, rqstp))
                        return rpc_drop_reply;
-       } else
-               cps.svc_sid = bc_xprt_sid(rqstp);
+       }
 
        hdr_res.taglen = hdr_arg.taglen;
        hdr_res.tag = hdr_arg.tag;
index 192f2f8602659fffb693625ef93fb474d499f08e..bd3ca32879e79db9de680e650475e2704de7d566 100644 (file)
@@ -1206,16 +1206,11 @@ nfs4_find_client_ident(int cb_ident)
  * For CB_COMPOUND calls, find a client by IP address, protocol version,
  * minorversion, and sessionID
  *
- * CREATE_SESSION triggers a CB_NULL ping from servers. The callback service
- * sessionid can only be set after the CREATE_SESSION return, so a CB_NULL
- * can arrive before the callback sessionid is set. For CB_NULL calls,
- * find a client by IP address protocol version, and minorversion.
- *
  * Returns NULL if no such client
  */
 struct nfs_client *
 nfs4_find_client_sessionid(const struct sockaddr *addr,
-                          struct nfs4_sessionid *sid, int is_cb_compound)
+                          struct nfs4_sessionid *sid)
 {
        struct nfs_client *clp;
 
@@ -1227,9 +1222,9 @@ nfs4_find_client_sessionid(const struct sockaddr *addr,
                if (!nfs4_has_session(clp))
                        continue;
 
-               /* Match sessionid unless cb_null call*/
-               if (is_cb_compound && (memcmp(clp->cl_session->sess_id.data,
-                   sid->data, NFS4_MAX_SESSIONID_LEN) != 0))
+               /* Match sessionid*/
+               if (memcmp(clp->cl_session->sess_id.data,
+                   sid->data, NFS4_MAX_SESSIONID_LEN) != 0)
                        continue;
 
                atomic_inc(&clp->cl_count);
@@ -1244,7 +1239,7 @@ nfs4_find_client_sessionid(const struct sockaddr *addr,
 
 struct nfs_client *
 nfs4_find_client_sessionid(const struct sockaddr *addr,
-                          struct nfs4_sessionid *sid, int is_cb_compound)
+                          struct nfs4_sessionid *sid)
 {
        return NULL;
 }
index 364e4328f3923851f427fd5951e1cd3b309e9949..bbbc6bf5cb2e42a8b1440c31eafa2e0f2c0c5a77 100644 (file)
@@ -23,8 +23,6 @@
 
 static void nfs_do_free_delegation(struct nfs_delegation *delegation)
 {
-       if (delegation->cred)
-               put_rpccred(delegation->cred);
        kfree(delegation);
 }
 
@@ -37,6 +35,10 @@ static void nfs_free_delegation_callback(struct rcu_head *head)
 
 static void nfs_free_delegation(struct nfs_delegation *delegation)
 {
+       if (delegation->cred) {
+               put_rpccred(delegation->cred);
+               delegation->cred = NULL;
+       }
        call_rcu(&delegation->rcu, nfs_free_delegation_callback);
 }
 
index e6ace0d93c71485870be33434830740941aa43ac..9943a75bb6d1d94766c7992be26034372152e4ad 100644 (file)
@@ -407,15 +407,18 @@ static ssize_t nfs_direct_read_schedule_iovec(struct nfs_direct_req *dreq,
                pos += vec->iov_len;
        }
 
+       /*
+        * If no bytes were started, return the error, and let the
+        * generic layer handle the completion.
+        */
+       if (requested_bytes == 0) {
+               nfs_direct_req_release(dreq);
+               return result < 0 ? result : -EIO;
+       }
+
        if (put_dreq(dreq))
                nfs_direct_complete(dreq);
-
-       if (requested_bytes != 0)
-               return 0;
-
-       if (result < 0)
-               return result;
-       return -EIO;
+       return 0;
 }
 
 static ssize_t nfs_direct_read(struct kiocb *iocb, const struct iovec *iov,
@@ -841,15 +844,18 @@ static ssize_t nfs_direct_write_schedule_iovec(struct nfs_direct_req *dreq,
                pos += vec->iov_len;
        }
 
+       /*
+        * If no bytes were started, return the error, and let the
+        * generic layer handle the completion.
+        */
+       if (requested_bytes == 0) {
+               nfs_direct_req_release(dreq);
+               return result < 0 ? result : -EIO;
+       }
+
        if (put_dreq(dreq))
                nfs_direct_write_complete(dreq, dreq->inode);
-
-       if (requested_bytes != 0)
-               return 0;
-
-       if (result < 0)
-               return result;
-       return -EIO;
+       return 0;
 }
 
 static ssize_t nfs_direct_write(struct kiocb *iocb, const struct iovec *iov,
index d8512423ba7298ee56368fd27e42d4d01fd7cee2..1cc600e77bb43aa14ba3d1547d5780c2a0e7c0a5 100644 (file)
@@ -881,9 +881,10 @@ out:
        return ret;
 }
 
-static void nfs_wcc_update_inode(struct inode *inode, struct nfs_fattr *fattr)
+static unsigned long nfs_wcc_update_inode(struct inode *inode, struct nfs_fattr *fattr)
 {
        struct nfs_inode *nfsi = NFS_I(inode);
+       unsigned long ret = 0;
 
        if ((fattr->valid & NFS_ATTR_FATTR_PRECHANGE)
                        && (fattr->valid & NFS_ATTR_FATTR_CHANGE)
@@ -891,25 +892,32 @@ static void nfs_wcc_update_inode(struct inode *inode, struct nfs_fattr *fattr)
                nfsi->change_attr = fattr->change_attr;
                if (S_ISDIR(inode->i_mode))
                        nfsi->cache_validity |= NFS_INO_INVALID_DATA;
+               ret |= NFS_INO_INVALID_ATTR;
        }
        /* If we have atomic WCC data, we may update some attributes */
        if ((fattr->valid & NFS_ATTR_FATTR_PRECTIME)
                        && (fattr->valid & NFS_ATTR_FATTR_CTIME)
-                       && timespec_equal(&inode->i_ctime, &fattr->pre_ctime))
-                       memcpy(&inode->i_ctime, &fattr->ctime, sizeof(inode->i_ctime));
+                       && timespec_equal(&inode->i_ctime, &fattr->pre_ctime)) {
+               memcpy(&inode->i_ctime, &fattr->ctime, sizeof(inode->i_ctime));
+               ret |= NFS_INO_INVALID_ATTR;
+       }
 
        if ((fattr->valid & NFS_ATTR_FATTR_PREMTIME)
                        && (fattr->valid & NFS_ATTR_FATTR_MTIME)
                        && timespec_equal(&inode->i_mtime, &fattr->pre_mtime)) {
-                       memcpy(&inode->i_mtime, &fattr->mtime, sizeof(inode->i_mtime));
-                       if (S_ISDIR(inode->i_mode))
-                               nfsi->cache_validity |= NFS_INO_INVALID_DATA;
+               memcpy(&inode->i_mtime, &fattr->mtime, sizeof(inode->i_mtime));
+               if (S_ISDIR(inode->i_mode))
+                       nfsi->cache_validity |= NFS_INO_INVALID_DATA;
+               ret |= NFS_INO_INVALID_ATTR;
        }
        if ((fattr->valid & NFS_ATTR_FATTR_PRESIZE)
                        && (fattr->valid & NFS_ATTR_FATTR_SIZE)
                        && i_size_read(inode) == nfs_size_to_loff_t(fattr->pre_size)
-                       && nfsi->npages == 0)
-                       i_size_write(inode, nfs_size_to_loff_t(fattr->size));
+                       && nfsi->npages == 0) {
+               i_size_write(inode, nfs_size_to_loff_t(fattr->size));
+               ret |= NFS_INO_INVALID_ATTR;
+       }
+       return ret;
 }
 
 /**
@@ -1223,7 +1231,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
                        | NFS_INO_REVAL_PAGECACHE);
 
        /* Do atomic weak cache consistency updates */
-       nfs_wcc_update_inode(inode, fattr);
+       invalid |= nfs_wcc_update_inode(inode, fattr);
 
        /* More cache consistency checks */
        if (fattr->valid & NFS_ATTR_FATTR_CHANGE) {
index 4644f04b4b46661bab07f5fe2d5b38d4373d602d..cf9fdbdabc675ad635e7d2183904d930d6995f5c 100644 (file)
@@ -133,8 +133,7 @@ extern void nfs_put_client(struct nfs_client *);
 extern struct nfs_client *nfs4_find_client_no_ident(const struct sockaddr *);
 extern struct nfs_client *nfs4_find_client_ident(int);
 extern struct nfs_client *
-nfs4_find_client_sessionid(const struct sockaddr *, struct nfs4_sessionid *,
-                          int);
+nfs4_find_client_sessionid(const struct sockaddr *, struct nfs4_sessionid *);
 extern struct nfs_server *nfs_create_server(
                                        const struct nfs_parsed_mount_data *,
                                        struct nfs_fh *);
index 9f88c5f4c7e2a9a192f4579590b9e9f4bb8a334e..27434277165570b4f1f00c06f42dc2ca6818804f 100644 (file)
@@ -311,8 +311,8 @@ static int nfs3_proc_setacls(struct inode *inode, struct posix_acl *acl,
        if (!nfs_server_capable(inode, NFS_CAP_ACLS))
                goto out;
 
-       /* We are doing this here, because XDR marshalling can only
-          return -ENOMEM. */
+       /* We are doing this here because XDR marshalling does not
+        * return any results, it BUGs. */
        status = -ENOSPC;
        if (acl != NULL && acl->a_count > NFS_ACL_MAX_ENTRIES)
                goto out;
index 01c5e8b1941d2faea2732a181b1bec1fcdd85302..183c6b123d0f53bd43209cd6a6634aaa8b9f484f 100644 (file)
@@ -1328,10 +1328,13 @@ static void nfs3_xdr_enc_setacl3args(struct rpc_rqst *req,
 
        encode_nfs_fh3(xdr, NFS_FH(args->inode));
        encode_uint32(xdr, args->mask);
+
+       base = req->rq_slen;
        if (args->npages != 0)
                xdr_write_pages(xdr, args->pages, 0, args->len);
+       else
+               xdr_reserve_space(xdr, NFS_ACL_INLINE_BUFSIZE);
 
-       base = req->rq_slen;
        error = nfsacl_encode(xdr->buf, base, args->inode,
                            (args->mask & NFS_ACL) ?
                            args->acl_access : NULL, 1, 0);
index 51fe64ace55a34523f9f3d6fd461962e364c1b4e..f5c9b125e8ccee997a456bea20e87ae4dade07dd 100644 (file)
@@ -214,7 +214,7 @@ decode_and_add_ds(__be32 **pp, struct inode *inode)
 
        /* ipv6 length plus port is legal */
        if (rlen > INET6_ADDRSTRLEN + 8) {
-               dprintk("%s Invalid address, length %d\n", __func__,
+               dprintk("%s: Invalid address, length %d\n", __func__,
                        rlen);
                goto out_err;
        }
@@ -225,6 +225,11 @@ decode_and_add_ds(__be32 **pp, struct inode *inode)
        /* replace the port dots with dashes for the in4_pton() delimiter*/
        for (i = 0; i < 2; i++) {
                char *res = strrchr(buf, '.');
+               if (!res) {
+                       dprintk("%s: Failed finding expected dots in port\n",
+                               __func__);
+                       goto out_free;
+               }
                *res = '-';
        }
 
@@ -240,7 +245,7 @@ decode_and_add_ds(__be32 **pp, struct inode *inode)
        port = htons((tmp[0] << 8) | (tmp[1]));
 
        ds = nfs4_pnfs_ds_add(inode, ip_addr, port);
-       dprintk("%s Decoded address and port %s\n", __func__, buf);
+       dprintk("%s: Decoded address and port %s\n", __func__, buf);
 out_free:
        kfree(buf);
 out_err:
index 9d992b0346e3fc481e851feb706943fc126e91f2..78936a8f40ab43583dc5bdda2c06e433e294404b 100644 (file)
@@ -50,6 +50,7 @@
 #include <linux/module.h>
 #include <linux/sunrpc/bc_xprt.h>
 #include <linux/xattr.h>
+#include <linux/utsname.h>
 
 #include "nfs4_fs.h"
 #include "delegation.h"
@@ -4572,27 +4573,16 @@ int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred)
        *p = htonl((u32)clp->cl_boot_time.tv_nsec);
        args.verifier = &verifier;
 
-       while (1) {
-               args.id_len = scnprintf(args.id, sizeof(args.id),
-                                       "%s/%s %u",
-                                       clp->cl_ipaddr,
-                                       rpc_peeraddr2str(clp->cl_rpcclient,
-                                                        RPC_DISPLAY_ADDR),
-                                       clp->cl_id_uniquifier);
-
-               status = rpc_call_sync(clp->cl_rpcclient, &msg, 0);
-
-               if (status != -NFS4ERR_CLID_INUSE)
-                       break;
-
-               if (signalled())
-                       break;
-
-               if (++clp->cl_id_uniquifier == 0)
-                       break;
-       }
+       args.id_len = scnprintf(args.id, sizeof(args.id),
+                               "%s/%s.%s/%u",
+                               clp->cl_ipaddr,
+                               init_utsname()->nodename,
+                               init_utsname()->domainname,
+                               clp->cl_rpcclient->cl_auth->au_flavor);
 
-       status = nfs4_check_cl_exchange_flags(clp->cl_exchange_flags);
+       status = rpc_call_sync(clp->cl_rpcclient, &msg, 0);
+       if (!status)
+               status = nfs4_check_cl_exchange_flags(clp->cl_exchange_flags);
        dprintk("<-- %s status= %d\n", __func__, status);
        return status;
 }
index 2336d532cf66c3677441871842fb7b9ec31a9aad..e6742b57a04c725aeebd07ab6a2ad0e27bc95a9e 100644 (file)
@@ -232,12 +232,6 @@ int nfs41_init_clientid(struct nfs_client *clp, struct rpc_cred *cred)
        status = nfs4_proc_create_session(clp);
        if (status != 0)
                goto out;
-       status = nfs4_set_callback_sessionid(clp);
-       if (status != 0) {
-               printk(KERN_WARNING "Sessionid not set. No callback service\n");
-               nfs_callback_down(1);
-               status = 0;
-       }
        nfs41_setup_state_renewal(clp);
        nfs_mark_client_ready(clp, NFS_CS_READY);
 out:
index 2ab8e5cb8f59f6410c4e407e90bd70ddaefd9fc9..4e2c168b6ee96701e9e7d5fd9ffca742d3a115ed 100644 (file)
@@ -6086,11 +6086,11 @@ int nfs4_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry,
        __be32 *p = xdr_inline_decode(xdr, 4);
        if (unlikely(!p))
                goto out_overflow;
-       if (!ntohl(*p++)) {
+       if (*p == xdr_zero) {
                p = xdr_inline_decode(xdr, 4);
                if (unlikely(!p))
                        goto out_overflow;
-               if (!ntohl(*p++))
+               if (*p == xdr_zero)
                        return -EAGAIN;
                entry->eof = 1;
                return -EBADCOOKIE;
@@ -6101,7 +6101,7 @@ int nfs4_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry,
                goto out_overflow;
        entry->prev_cookie = entry->cookie;
        p = xdr_decode_hyper(p, &entry->cookie);
-       entry->len = ntohl(*p++);
+       entry->len = be32_to_cpup(p);
 
        p = xdr_inline_decode(xdr, entry->len);
        if (unlikely(!p))
@@ -6132,9 +6132,6 @@ int nfs4_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry,
        if (entry->fattr->valid & NFS_ATTR_FATTR_TYPE)
                entry->d_type = nfs_umode_to_dtype(entry->fattr->mode);
 
-       if (verify_attr_len(xdr, p, len) < 0)
-               goto out_overflow;
-
        return 0;
 
 out_overflow:
index bc4089769735384073579926047d0347124f5b6b..1b1bc1a0fb0a6f30dcbd1029666242f5b3b8a46f 100644 (file)
@@ -951,7 +951,7 @@ pnfs_put_deviceid_cache(struct nfs_client *clp)
 {
        struct pnfs_deviceid_cache *local = clp->cl_devid_cache;
 
-       dprintk("--> %s cl_devid_cache %p\n", __func__, clp->cl_devid_cache);
+       dprintk("--> %s ({%d})\n", __func__, atomic_read(&local->dc_ref));
        if (atomic_dec_and_lock(&local->dc_ref, &clp->cl_lock)) {
                int i;
                /* Verify cache is empty */
index 10d648ea128bf6345df70da0e15ee8ce443ab8e6..c8278f4046cba5a957705c1e43ee675dba388529 100644 (file)
@@ -932,7 +932,7 @@ out_bad:
        while (!list_empty(&list)) {
                data = list_entry(list.next, struct nfs_write_data, pages);
                list_del(&data->pages);
-               nfs_writedata_release(data);
+               nfs_writedata_free(data);
        }
        nfs_redirty_request(req);
        return -ENOMEM;
index fc1c52571c03ea9eaf0d4e96a4026f119cd026e9..84c27d69d421e494c2c41359f06dd02eb2c32960 100644 (file)
@@ -42,6 +42,11 @@ struct nfsacl_encode_desc {
        gid_t gid;
 };
 
+struct nfsacl_simple_acl {
+       struct posix_acl acl;
+       struct posix_acl_entry ace[4];
+};
+
 static int
 xdr_nfsace_encode(struct xdr_array2_desc *desc, void *elem)
 {
@@ -72,9 +77,20 @@ xdr_nfsace_encode(struct xdr_array2_desc *desc, void *elem)
        return 0;
 }
 
-unsigned int
-nfsacl_encode(struct xdr_buf *buf, unsigned int base, struct inode *inode,
-             struct posix_acl *acl, int encode_entries, int typeflag)
+/**
+ * nfsacl_encode - Encode an NFSv3 ACL
+ *
+ * @buf: destination xdr_buf to contain XDR encoded ACL
+ * @base: byte offset in xdr_buf where XDR'd ACL begins
+ * @inode: inode of file whose ACL this is
+ * @acl: posix_acl to encode
+ * @encode_entries: whether to encode ACEs as well
+ * @typeflag: ACL type: NFS_ACL_DEFAULT or zero
+ *
+ * Returns size of encoded ACL in bytes or a negative errno value.
+ */
+int nfsacl_encode(struct xdr_buf *buf, unsigned int base, struct inode *inode,
+                 struct posix_acl *acl, int encode_entries, int typeflag)
 {
        int entries = (acl && acl->a_count) ? max_t(int, acl->a_count, 4) : 0;
        struct nfsacl_encode_desc nfsacl_desc = {
@@ -88,17 +104,22 @@ nfsacl_encode(struct xdr_buf *buf, unsigned int base, struct inode *inode,
                .uid = inode->i_uid,
                .gid = inode->i_gid,
        };
+       struct nfsacl_simple_acl aclbuf;
        int err;
-       struct posix_acl *acl2 = NULL;
 
        if (entries > NFS_ACL_MAX_ENTRIES ||
            xdr_encode_word(buf, base, entries))
                return -EINVAL;
        if (encode_entries && acl && acl->a_count == 3) {
-               /* Fake up an ACL_MASK entry. */
-               acl2 = posix_acl_alloc(4, GFP_KERNEL);
-               if (!acl2)
-                       return -ENOMEM;
+               struct posix_acl *acl2 = &aclbuf.acl;
+
+               /* Avoid the use of posix_acl_alloc().  nfsacl_encode() is
+                * invoked in contexts where a memory allocation failure is
+                * fatal.  Fortunately this fake ACL is small enough to
+                * construct on the stack. */
+               memset(acl2, 0, sizeof(acl2));
+               posix_acl_init(acl2, 4);
+
                /* Insert entries in canonical order: other orders seem
                 to confuse Solaris VxFS. */
                acl2->a_entries[0] = acl->a_entries[0];  /* ACL_USER_OBJ */
@@ -109,8 +130,6 @@ nfsacl_encode(struct xdr_buf *buf, unsigned int base, struct inode *inode,
                nfsacl_desc.acl = acl2;
        }
        err = xdr_encode_array2(buf, base + 4, &nfsacl_desc.desc);
-       if (acl2)
-               posix_acl_release(acl2);
        if (!err)
                err = 8 + nfsacl_desc.desc.elem_size *
                          nfsacl_desc.desc.array_len;
@@ -224,9 +243,18 @@ posix_acl_from_nfsacl(struct posix_acl *acl)
        return 0;
 }
 
-unsigned int
-nfsacl_decode(struct xdr_buf *buf, unsigned int base, unsigned int *aclcnt,
-             struct posix_acl **pacl)
+/**
+ * nfsacl_decode - Decode an NFSv3 ACL
+ *
+ * @buf: xdr_buf containing XDR'd ACL data to decode
+ * @base: byte offset in xdr_buf where XDR'd ACL begins
+ * @aclcnt: count of ACEs in decoded posix_acl
+ * @pacl: buffer in which to place decoded posix_acl
+ *
+ * Returns the length of the decoded ACL in bytes, or a negative errno value.
+ */
+int nfsacl_decode(struct xdr_buf *buf, unsigned int base, unsigned int *aclcnt,
+                 struct posix_acl **pacl)
 {
        struct nfsacl_decode_desc nfsacl_desc = {
                .desc = {
index 0994f6a76c0799ec86a482288256522a5735f72a..58fd707174e108714091c081604f7daa781d10f5 100644 (file)
@@ -704,7 +704,8 @@ skip_mount_setup:
        sbp[0]->s_state =
                cpu_to_le16(le16_to_cpu(sbp[0]->s_state) & ~NILFS_VALID_FS);
        /* synchronize sbp[1] with sbp[0] */
-       memcpy(sbp[1], sbp[0], nilfs->ns_sbsize);
+       if (sbp[1])
+               memcpy(sbp[1], sbp[0], nilfs->ns_sbsize);
        return nilfs_commit_super(sbi, NILFS_SB_COMMIT_ALL);
 }
 
index b572b672718110e317a6895698bdf612b2e8eced..326e7475a22a40d1323be1786ffa089ffb3182e7 100644 (file)
@@ -1,7 +1,7 @@
 /**
  * mft.c - NTFS kernel mft record operations. Part of the Linux-NTFS project.
  *
- * Copyright (c) 2001-2006 Anton Altaparmakov
+ * Copyright (c) 2001-2011 Anton Altaparmakov and Tuxera Inc.
  * Copyright (c) 2002 Richard Russon
  *
  * This program/include file is free software; you can redistribute it and/or
@@ -2576,6 +2576,8 @@ mft_rec_already_initialized:
        flush_dcache_page(page);
        SetPageUptodate(page);
        if (base_ni) {
+               MFT_RECORD *m_tmp;
+
                /*
                 * Setup the base mft record in the extent mft record.  This
                 * completes initialization of the allocated extent mft record
@@ -2588,11 +2590,11 @@ mft_rec_already_initialized:
                 * attach it to the base inode @base_ni and map, pin, and lock
                 * its, i.e. the allocated, mft record.
                 */
-               m = map_extent_mft_record(base_ni, bit, &ni);
-               if (IS_ERR(m)) {
+               m_tmp = map_extent_mft_record(base_ni, bit, &ni);
+               if (IS_ERR(m_tmp)) {
                        ntfs_error(vol->sb, "Failed to map allocated extent "
                                        "mft record 0x%llx.", (long long)bit);
-                       err = PTR_ERR(m);
+                       err = PTR_ERR(m_tmp);
                        /* Set the mft record itself not in use. */
                        m->flags &= cpu_to_le16(
                                        ~le16_to_cpu(MFT_RECORD_IN_USE));
@@ -2603,6 +2605,7 @@ mft_rec_already_initialized:
                        ntfs_unmap_page(page);
                        goto undo_mftbmp_alloc;
                }
+               BUG_ON(m != m_tmp);
                /*
                 * Make sure the allocated mft record is written out to disk.
                 * No need to set the inode dirty because the caller is going
index 39df95a0ec25edc87e7c3e29aef2b9a707f95f9f..b1cf6bf4b41dea46feb35d8d6d02f4d5c88153f8 100644 (file)
@@ -22,6 +22,7 @@
 
 #include <linux/errno.h>
 
+EXPORT_SYMBOL(posix_acl_init);
 EXPORT_SYMBOL(posix_acl_alloc);
 EXPORT_SYMBOL(posix_acl_clone);
 EXPORT_SYMBOL(posix_acl_valid);
@@ -31,6 +32,16 @@ EXPORT_SYMBOL(posix_acl_create_masq);
 EXPORT_SYMBOL(posix_acl_chmod_masq);
 EXPORT_SYMBOL(posix_acl_permission);
 
+/*
+ * Init a fresh posix_acl
+ */
+void
+posix_acl_init(struct posix_acl *acl, int count)
+{
+       atomic_set(&acl->a_refcount, 1);
+       acl->a_count = count;
+}
+
 /*
  * Allocate a new ACL with the specified number of entries.
  */
@@ -40,10 +51,8 @@ posix_acl_alloc(int count, gfp_t flags)
        const size_t size = sizeof(struct posix_acl) +
                            count * sizeof(struct posix_acl_entry);
        struct posix_acl *acl = kmalloc(size, flags);
-       if (acl) {
-               atomic_set(&acl->a_refcount, 1);
-               acl->a_count = count;
-       }
+       if (acl)
+               posix_acl_init(acl, count);
        return acl;
 }
 
index eafc22ab1fdd5d830ae2c196dd4d7e8f7cd3e074..b701eaa482bfb4cc3d8b8d91c76884b91167fe11 100644 (file)
@@ -67,7 +67,7 @@ static void *c_start(struct seq_file *m, loff_t *pos)
        struct console *con;
        loff_t off = 0;
 
-       acquire_console_sem();
+       console_lock();
        for_each_console(con)
                if (off++ == *pos)
                        break;
@@ -84,7 +84,7 @@ static void *c_next(struct seq_file *m, void *v, loff_t *pos)
 
 static void c_stop(struct seq_file *m, void *v)
 {
-       release_console_sem();
+       console_unlock();
 }
 
 static const struct seq_operations consoles_op = {
index 2fb2882f0fa7b1a1b656f68596ec740d10650cd9..8ab48bc2fa7d4f17f75288ac64544b9894f15dfc 100644 (file)
@@ -63,6 +63,14 @@ static struct buffer_head *get_block_length(struct super_block *sb,
                *length = (unsigned char) bh->b_data[*offset] |
                        (unsigned char) bh->b_data[*offset + 1] << 8;
                *offset += 2;
+
+               if (*offset == msblk->devblksize) {
+                       put_bh(bh);
+                       bh = sb_bread(sb, ++(*cur_index));
+                       if (bh == NULL)
+                               return NULL;
+                       *offset = 0;
+               }
        }
 
        return bh;
index 856756ca5ee493e29631b8e8108119c3268f5c80..c4eb400182564c13728fc88f95edf6db294eb2ac 100644 (file)
@@ -95,12 +95,6 @@ static int squashfs_xz_uncompress(struct squashfs_sb_info *msblk, void **buffer,
                        if (!buffer_uptodate(bh[k]))
                                goto release_mutex;
 
-                       if (avail == 0) {
-                               offset = 0;
-                               put_bh(bh[k++]);
-                               continue;
-                       }
-
                        stream->buf.in = bh[k]->b_data + offset;
                        stream->buf.in_size = avail;
                        stream->buf.in_pos = 0;
index 818a5e063faf37c03c189c8043ec470f52024575..4661ae2b1cec8040adcadc4018deb63735309f92 100644 (file)
@@ -82,12 +82,6 @@ static int zlib_uncompress(struct squashfs_sb_info *msblk, void **buffer,
                        if (!buffer_uptodate(bh[k]))
                                goto release_mutex;
 
-                       if (avail == 0) {
-                               offset = 0;
-                               put_bh(bh[k++]);
-                               continue;
-                       }
-
                        stream->next_in = bh[k]->b_data + offset;
                        stream->avail_in = avail;
                        offset = 0;
index b06ede1d0bed4562e60e4067e729b9209de65e1d..f5e2a19e0f8eb25114fa8de3478b289d4972b8a9 100644 (file)
@@ -985,10 +985,22 @@ xfs_ioctl_setattr(
 
                /*
                 * Extent size must be a multiple of the appropriate block
-                * size, if set at all.
+                * size, if set at all. It must also be smaller than the
+                * maximum extent size supported by the filesystem.
+                *
+                * Also, for non-realtime files, limit the extent size hint to
+                * half the size of the AGs in the filesystem so alignment
+                * doesn't result in extents larger than an AG.
                 */
                if (fa->fsx_extsize != 0) {
-                       xfs_extlen_t    size;
+                       xfs_extlen_t    size;
+                       xfs_fsblock_t   extsize_fsb;
+
+                       extsize_fsb = XFS_B_TO_FSB(mp, fa->fsx_extsize);
+                       if (extsize_fsb > MAXEXTLEN) {
+                               code = XFS_ERROR(EINVAL);
+                               goto error_return;
+                       }
 
                        if (XFS_IS_REALTIME_INODE(ip) ||
                            ((mask & FSX_XFLAGS) &&
@@ -997,6 +1009,10 @@ xfs_ioctl_setattr(
                                       mp->m_sb.sb_blocklog;
                        } else {
                                size = mp->m_sb.sb_blocksize;
+                               if (extsize_fsb > mp->m_sb.sb_agblocks / 2) {
+                                       code = XFS_ERROR(EINVAL);
+                                       goto error_return;
+                               }
                        }
 
                        if (fa->fsx_extsize % size) {
index f8e854b4fde87c49f17ff07dc87893b172bb6203..206a2815ced67399c9cfa248a45d185605e12aee 100644 (file)
@@ -1863,12 +1863,14 @@ xfs_qm_dqreclaim_one(void)
        xfs_dquot_t     *dqpout;
        xfs_dquot_t     *dqp;
        int             restarts;
+       int             startagain;
 
        restarts = 0;
        dqpout = NULL;
 
        /* lockorder: hashchainlock, freelistlock, mplistlock, dqlock, dqflock */
-startagain:
+again:
+       startagain = 0;
        mutex_lock(&xfs_Gqm->qm_dqfrlist_lock);
 
        list_for_each_entry(dqp, &xfs_Gqm->qm_dqfrlist, q_freelist) {
@@ -1885,13 +1887,10 @@ startagain:
                        ASSERT(! (dqp->dq_flags & XFS_DQ_INACTIVE));
 
                        trace_xfs_dqreclaim_want(dqp);
-
-                       xfs_dqunlock(dqp);
-                       mutex_unlock(&xfs_Gqm->qm_dqfrlist_lock);
-                       if (++restarts >= XFS_QM_RECLAIM_MAX_RESTARTS)
-                               return NULL;
                        XQM_STATS_INC(xqmstats.xs_qm_dqwants);
-                       goto startagain;
+                       restarts++;
+                       startagain = 1;
+                       goto dqunlock;
                }
 
                /*
@@ -1906,23 +1905,20 @@ startagain:
                        ASSERT(list_empty(&dqp->q_mplist));
                        list_del_init(&dqp->q_freelist);
                        xfs_Gqm->qm_dqfrlist_cnt--;
-                       xfs_dqunlock(dqp);
                        dqpout = dqp;
                        XQM_STATS_INC(xqmstats.xs_qm_dqinact_reclaims);
-                       break;
+                       goto dqunlock;
                }
 
                ASSERT(dqp->q_hash);
                ASSERT(!list_empty(&dqp->q_mplist));
 
                /*
-                * Try to grab the flush lock. If this dquot is in the process of
-                * getting flushed to disk, we don't want to reclaim it.
+                * Try to grab the flush lock. If this dquot is in the process
+                * of getting flushed to disk, we don't want to reclaim it.
                 */
-               if (!xfs_dqflock_nowait(dqp)) {
-                       xfs_dqunlock(dqp);
-                       continue;
-               }
+               if (!xfs_dqflock_nowait(dqp))
+                       goto dqunlock;
 
                /*
                 * We have the flush lock so we know that this is not in the
@@ -1944,8 +1940,7 @@ startagain:
                                xfs_fs_cmn_err(CE_WARN, mp,
                        "xfs_qm_dqreclaim: dquot %p flush failed", dqp);
                        }
-                       xfs_dqunlock(dqp); /* dqflush unlocks dqflock */
-                       continue;
+                       goto dqunlock;
                }
 
                /*
@@ -1967,13 +1962,8 @@ startagain:
                 */
                if (!mutex_trylock(&mp->m_quotainfo->qi_dqlist_lock)) {
                        restarts++;
-                       mutex_unlock(&dqp->q_hash->qh_lock);
-                       xfs_dqfunlock(dqp);
-                       xfs_dqunlock(dqp);
-                       mutex_unlock(&xfs_Gqm->qm_dqfrlist_lock);
-                       if (restarts++ >= XFS_QM_RECLAIM_MAX_RESTARTS)
-                               return NULL;
-                       goto startagain;
+                       startagain = 1;
+                       goto qhunlock;
                }
 
                ASSERT(dqp->q_nrefs == 0);
@@ -1986,14 +1976,20 @@ startagain:
                xfs_Gqm->qm_dqfrlist_cnt--;
                dqpout = dqp;
                mutex_unlock(&mp->m_quotainfo->qi_dqlist_lock);
+qhunlock:
                mutex_unlock(&dqp->q_hash->qh_lock);
 dqfunlock:
                xfs_dqfunlock(dqp);
+dqunlock:
                xfs_dqunlock(dqp);
                if (dqpout)
                        break;
                if (restarts >= XFS_QM_RECLAIM_MAX_RESTARTS)
-                       return NULL;
+                       break;
+               if (startagain) {
+                       mutex_unlock(&xfs_Gqm->qm_dqfrlist_lock);
+                       goto again;
+               }
        }
        mutex_unlock(&xfs_Gqm->qm_dqfrlist_lock);
        return dqpout;
index 0ab56b32c7eb70484ed4a7fdcfdbac3595c1ecab..d0b3bc72005bd147557625e4afabdca058c6e163 100644 (file)
@@ -74,6 +74,22 @@ typedef unsigned int xfs_alloctype_t;
  */
 #define XFS_ALLOC_SET_ASIDE(mp)  (4 + ((mp)->m_sb.sb_agcount * 4))
 
+/*
+ * When deciding how much space to allocate out of an AG, we limit the
+ * allocation maximum size to the size the AG. However, we cannot use all the
+ * blocks in the AG - some are permanently used by metadata. These
+ * blocks are generally:
+ *     - the AG superblock, AGF, AGI and AGFL
+ *     - the AGF (bno and cnt) and AGI btree root blocks
+ *     - 4 blocks on the AGFL according to XFS_ALLOC_SET_ASIDE() limits
+ *
+ * The AG headers are sector sized, so the amount of space they take up is
+ * dependent on filesystem geometry. The others are all single blocks.
+ */
+#define XFS_ALLOC_AG_MAX_USABLE(mp)    \
+       ((mp)->m_sb.sb_agblocks - XFS_BB_TO_FSB(mp, XFS_FSS_TO_BB(mp, 4)) - 7)
+
+
 /*
  * Argument structure for xfs_alloc routines.
  * This is turned into a structure to avoid having 20 arguments passed
index 4111cd3966c764b3c41300d1e7a51a7579ead435..dc3afd7739ff40754d1e04eda13178acc78ef3c2 100644 (file)
@@ -1038,17 +1038,34 @@ xfs_bmap_add_extent_delay_real(
                 * Filling in the middle part of a previous delayed allocation.
                 * Contiguity is impossible here.
                 * This case is avoided almost all the time.
+                *
+                * We start with a delayed allocation:
+                *
+                * +ddddddddddddddddddddddddddddddddddddddddddddddddddddddd+
+                *  PREV @ idx
+                *
+                * and we are allocating:
+                *                     +rrrrrrrrrrrrrrrrr+
+                *                            new
+                *
+                * and we set it up for insertion as:
+                * +ddddddddddddddddddd+rrrrrrrrrrrrrrrrr+ddddddddddddddddd+
+                *                            new
+                *  PREV @ idx          LEFT              RIGHT
+                *                      inserted at idx + 1
                 */
                temp = new->br_startoff - PREV.br_startoff;
-               trace_xfs_bmap_pre_update(ip, idx, 0, _THIS_IP_);
-               xfs_bmbt_set_blockcount(ep, temp);
-               r[0] = *new;
-               r[1].br_state = PREV.br_state;
-               r[1].br_startblock = 0;
-               r[1].br_startoff = new_endoff;
                temp2 = PREV.br_startoff + PREV.br_blockcount - new_endoff;
-               r[1].br_blockcount = temp2;
-               xfs_iext_insert(ip, idx + 1, 2, &r[0], state);
+               trace_xfs_bmap_pre_update(ip, idx, 0, _THIS_IP_);
+               xfs_bmbt_set_blockcount(ep, temp);      /* truncate PREV */
+               LEFT = *new;
+               RIGHT.br_state = PREV.br_state;
+               RIGHT.br_startblock = nullstartblock(
+                               (int)xfs_bmap_worst_indlen(ip, temp2));
+               RIGHT.br_startoff = new_endoff;
+               RIGHT.br_blockcount = temp2;
+               /* insert LEFT (r[0]) and RIGHT (r[1]) at the same time */
+               xfs_iext_insert(ip, idx + 1, 2, &LEFT, state);
                ip->i_df.if_lastex = idx + 1;
                ip->i_d.di_nextents++;
                if (cur == NULL)
@@ -2430,7 +2447,7 @@ xfs_bmap_btalloc_nullfb(
                startag = ag = 0;
 
        pag = xfs_perag_get(mp, ag);
-       while (*blen < ap->alen) {
+       while (*blen < args->maxlen) {
                if (!pag->pagf_init) {
                        error = xfs_alloc_pagf_init(mp, args->tp, ag,
                                                    XFS_ALLOC_FLAG_TRYLOCK);
@@ -2452,7 +2469,7 @@ xfs_bmap_btalloc_nullfb(
                        notinit = 1;
 
                if (xfs_inode_is_filestream(ap->ip)) {
-                       if (*blen >= ap->alen)
+                       if (*blen >= args->maxlen)
                                break;
 
                        if (ap->userdata) {
@@ -2498,14 +2515,14 @@ xfs_bmap_btalloc_nullfb(
         * If the best seen length is less than the request
         * length, use the best as the minimum.
         */
-       else if (*blen < ap->alen)
+       else if (*blen < args->maxlen)
                args->minlen = *blen;
        /*
-        * Otherwise we've seen an extent as big as alen,
+        * Otherwise we've seen an extent as big as maxlen,
         * use that as the minimum.
         */
        else
-               args->minlen = ap->alen;
+               args->minlen = args->maxlen;
 
        /*
         * set the failure fallback case to look in the selected
@@ -2573,7 +2590,9 @@ xfs_bmap_btalloc(
        args.tp = ap->tp;
        args.mp = mp;
        args.fsbno = ap->rval;
-       args.maxlen = MIN(ap->alen, mp->m_sb.sb_agblocks);
+
+       /* Trim the allocation back to the maximum an AG can fit. */
+       args.maxlen = MIN(ap->alen, XFS_ALLOC_AG_MAX_USABLE(mp));
        args.firstblock = ap->firstblock;
        blen = 0;
        if (nullfb) {
@@ -2621,7 +2640,7 @@ xfs_bmap_btalloc(
                        /*
                         * Adjust for alignment
                         */
-                       if (blen > args.alignment && blen <= ap->alen)
+                       if (blen > args.alignment && blen <= args.maxlen)
                                args.minlen = blen - args.alignment;
                        args.minalignslop = 0;
                } else {
@@ -2640,7 +2659,7 @@ xfs_bmap_btalloc(
                         * of minlen+alignment+slop doesn't go up
                         * between the calls.
                         */
-                       if (blen > mp->m_dalign && blen <= ap->alen)
+                       if (blen > mp->m_dalign && blen <= args.maxlen)
                                nextminlen = blen - mp->m_dalign;
                        else
                                nextminlen = args.minlen;
@@ -4485,6 +4504,16 @@ xfs_bmapi(
                                /* Figure out the extent size, adjust alen */
                                extsz = xfs_get_extsz_hint(ip);
                                if (extsz) {
+                                       /*
+                                        * make sure we don't exceed a single
+                                        * extent length when we align the
+                                        * extent by reducing length we are
+                                        * going to allocate by the maximum
+                                        * amount extent size aligment may
+                                        * require.
+                                        */
+                                       alen = XFS_FILBLKS_MIN(len,
+                                                  MAXEXTLEN - (2 * extsz - 1));
                                        error = xfs_bmap_extsize_align(mp,
                                                        &got, &prev, extsz,
                                                        rt, eof,
index 98c6f73b675218bded1a6b326ecdf349cb241a07..6f8c21ce0d6d95fd8c45a5d3eea4ef0240fad1fd 100644 (file)
@@ -427,13 +427,15 @@ xfs_buf_item_unpin(
 
                if (remove) {
                        /*
-                        * We have to remove the log item from the transaction
-                        * as we are about to release our reference to the
-                        * buffer.  If we don't, the unlock that occurs later
-                        * in xfs_trans_uncommit() will ry to reference the
+                        * If we are in a transaction context, we have to
+                        * remove the log item from the transaction as we are
+                        * about to release our reference to the buffer.  If we
+                        * don't, the unlock that occurs later in
+                        * xfs_trans_uncommit() will try to reference the
                         * buffer which we no longer have a hold on.
                         */
-                       xfs_trans_del_item(lip);
+                       if (lip->li_desc)
+                               xfs_trans_del_item(lip);
 
                        /*
                         * Since the transaction no longer refers to the buffer,
index 75f2ef60e579e62f483213fa6a038cb235698054..d22e62623437aafb79d62f5492252e140f3a6cb7 100644 (file)
@@ -138,7 +138,8 @@ xfs_efi_item_unpin(
 
        if (remove) {
                ASSERT(!(lip->li_flags & XFS_LI_IN_AIL));
-               xfs_trans_del_item(lip);
+               if (lip->li_desc)
+                       xfs_trans_del_item(lip);
                xfs_efi_item_free(efip);
                return;
        }
index 55582bd66659140ed9592a85ec0189187bcfd4ac..8a0f044750c3207eff174c4137bcd77580465894 100644 (file)
@@ -337,7 +337,12 @@ xfs_iomap_prealloc_size(
                int shift = 0;
                int64_t freesp;
 
-               alloc_blocks = XFS_B_TO_FSB(mp, ip->i_size);
+               /*
+                * rounddown_pow_of_two() returns an undefined result
+                * if we pass in alloc_blocks = 0. Hence the "+ 1" to
+                * ensure we always pass in a non-zero value.
+                */
+               alloc_blocks = XFS_B_TO_FSB(mp, ip->i_size) + 1;
                alloc_blocks = XFS_FILEOFF_MIN(MAXEXTLEN,
                                        rounddown_pow_of_two(alloc_blocks));
 
index 916eb7db14d9a09ff541882bf12905d9fd5068ea..3bd3291ef8d21fc09697b3c4aa5f7b76df4d1c87 100644 (file)
@@ -191,7 +191,7 @@ void          xfs_log_ticket_put(struct xlog_ticket *ticket);
 
 xlog_tid_t xfs_log_get_trans_ident(struct xfs_trans *tp);
 
-int    xfs_log_commit_cil(struct xfs_mount *mp, struct xfs_trans *tp,
+void   xfs_log_commit_cil(struct xfs_mount *mp, struct xfs_trans *tp,
                                struct xfs_log_vec *log_vector,
                                xfs_lsn_t *commit_lsn, int flags);
 bool   xfs_log_item_in_current_chkpt(struct xfs_log_item *lip);
index 9dc8125d04e5e09188c88695c42b13a4ae9b6a9b..9ca59be089779d6f3c4e570c926545d6441b85da 100644 (file)
@@ -543,7 +543,7 @@ xlog_cil_push(
 
        error = xlog_write(log, &lvhdr, tic, &ctx->start_lsn, NULL, 0);
        if (error)
-               goto out_abort;
+               goto out_abort_free_ticket;
 
        /*
         * now that we've written the checkpoint into the log, strictly
@@ -569,8 +569,9 @@ restart:
        }
        spin_unlock(&cil->xc_cil_lock);
 
+       /* xfs_log_done always frees the ticket on error. */
        commit_lsn = xfs_log_done(log->l_mp, tic, &commit_iclog, 0);
-       if (error || commit_lsn == -1)
+       if (commit_lsn == -1)
                goto out_abort;
 
        /* attach all the transactions w/ busy extents to iclog */
@@ -600,6 +601,8 @@ out_free_ticket:
        kmem_free(new_ctx);
        return 0;
 
+out_abort_free_ticket:
+       xfs_log_ticket_put(tic);
 out_abort:
        xlog_cil_committed(ctx, XFS_LI_ABORTED);
        return XFS_ERROR(EIO);
@@ -622,7 +625,7 @@ out_abort:
  * background commit, returns without it held once background commits are
  * allowed again.
  */
-int
+void
 xfs_log_commit_cil(
        struct xfs_mount        *mp,
        struct xfs_trans        *tp,
@@ -637,11 +640,6 @@ xfs_log_commit_cil(
        if (flags & XFS_TRANS_RELEASE_LOG_RES)
                log_flags = XFS_LOG_REL_PERM_RESERV;
 
-       if (XLOG_FORCED_SHUTDOWN(log)) {
-               xlog_cil_free_logvec(log_vector);
-               return XFS_ERROR(EIO);
-       }
-
        /*
         * do all the hard work of formatting items (including memory
         * allocation) outside the CIL context lock. This prevents stalling CIL
@@ -701,7 +699,6 @@ xfs_log_commit_cil(
         */
        if (push)
                xlog_cil_push(log, 0);
-       return 0;
 }
 
 /*
index 33dbc4e0ad622a94dbbf8aa67b49e0eacef0cbbc..76922793f64fa0d58606a4411f008ba8b9e88259 100644 (file)
@@ -1446,6 +1446,14 @@ xfs_log_item_batch_insert(
  * Bulk operation version of xfs_trans_committed that takes a log vector of
  * items to insert into the AIL. This uses bulk AIL insertion techniques to
  * minimise lock traffic.
+ *
+ * If we are called with the aborted flag set, it is because a log write during
+ * a CIL checkpoint commit has failed. In this case, all the items in the
+ * checkpoint have already gone through IOP_COMMITED and IOP_UNLOCK, which
+ * means that checkpoint commit abort handling is treated exactly the same
+ * as an iclog write error even though we haven't started any IO yet. Hence in
+ * this case all we need to do is IOP_COMMITTED processing, followed by an
+ * IOP_UNPIN(aborted) call.
  */
 void
 xfs_trans_committed_bulk(
@@ -1472,6 +1480,16 @@ xfs_trans_committed_bulk(
                if (XFS_LSN_CMP(item_lsn, (xfs_lsn_t)-1) == 0)
                        continue;
 
+               /*
+                * if we are aborting the operation, no point in inserting the
+                * object into the AIL as we are in a shutdown situation.
+                */
+               if (aborted) {
+                       ASSERT(XFS_FORCED_SHUTDOWN(ailp->xa_mount));
+                       IOP_UNPIN(lip, 1);
+                       continue;
+               }
+
                if (item_lsn != commit_lsn) {
 
                        /*
@@ -1503,20 +1521,24 @@ xfs_trans_committed_bulk(
 }
 
 /*
- * Called from the trans_commit code when we notice that
- * the filesystem is in the middle of a forced shutdown.
+ * Called from the trans_commit code when we notice that the filesystem is in
+ * the middle of a forced shutdown.
+ *
+ * When we are called here, we have already pinned all the items in the
+ * transaction. However, neither IOP_COMMITTING or IOP_UNLOCK has been called
+ * so we can simply walk the items in the transaction, unpin them with an abort
+ * flag and then free the items. Note that unpinning the items can result in
+ * them being freed immediately, so we need to use a safe list traversal method
+ * here.
  */
 STATIC void
 xfs_trans_uncommit(
        struct xfs_trans        *tp,
        uint                    flags)
 {
-       struct xfs_log_item_desc *lidp;
+       struct xfs_log_item_desc *lidp, *n;
 
-       list_for_each_entry(lidp, &tp->t_items, lid_trans) {
-               /*
-                * Unpin all but those that aren't dirty.
-                */
+       list_for_each_entry_safe(lidp, n, &tp->t_items, lid_trans) {
                if (lidp->lid_flags & XFS_LID_DIRTY)
                        IOP_UNPIN(lidp->lid_item, 1);
        }
@@ -1733,7 +1755,6 @@ xfs_trans_commit_cil(
        int                     flags)
 {
        struct xfs_log_vec      *log_vector;
-       int                     error;
 
        /*
         * Get each log item to allocate a vector structure for
@@ -1744,9 +1765,7 @@ xfs_trans_commit_cil(
        if (!log_vector)
                return ENOMEM;
 
-       error = xfs_log_commit_cil(mp, tp, log_vector, commit_lsn, flags);
-       if (error)
-               return error;
+       xfs_log_commit_cil(mp, tp, log_vector, commit_lsn, flags);
 
        current_restore_flags_nested(&tp->t_pflags, PF_FSTRANS);
        xfs_trans_free(tp);
index 68649336c4adf98618ff4d4fd8d9f1d6b2867062..6ebb81030d2d109ce9f99069b130c29a39ccfa11 100644 (file)
                VMLINUX_SYMBOL(__start___param) = .;                    \
                *(__param)                                              \
                VMLINUX_SYMBOL(__stop___param) = .;                     \
+       }                                                               \
+                                                                       \
+       /* Built-in module versions. */                                 \
+       __modver : AT(ADDR(__modver) - LOAD_OFFSET) {                   \
+               VMLINUX_SYMBOL(__start___modver) = .;                   \
+               *(__modver)                                             \
+               VMLINUX_SYMBOL(__stop___modver) = .;                    \
                . = ALIGN((align));                                     \
                VMLINUX_SYMBOL(__end_rodata) = .;                       \
        }                                                               \
index e95a86b8b689b530ec8981ad1525bb6b49c2f142..e5c607a02d57cc337f3329b88bcd881cceef7b43 100644 (file)
@@ -907,6 +907,7 @@ struct drm_radeon_cs {
 #define RADEON_INFO_TILING_CONFIG      0x06
 #define RADEON_INFO_WANT_HYPERZ                0x07
 #define RADEON_INFO_WANT_CMASK         0x08 /* get access to CMASK on r300 */
+#define RADEON_INFO_CLOCK_CRYSTAL_FREQ 0x09 /* clock crystal frequency */
 
 struct drm_radeon_info {
        uint32_t                request;
index 9774fe6a1a9705274bf9aaf96d074eaad86278b5..7453cfd593c813632c3cf103ea918c471266613e 100644 (file)
@@ -139,9 +139,9 @@ extern int update_console_cmdline(char *name, int idx, char *name_new, int idx_n
 extern void register_console(struct console *);
 extern int unregister_console(struct console *);
 extern struct console *console_drivers;
-extern void acquire_console_sem(void);
-extern int try_acquire_console_sem(void);
-extern void release_console_sem(void);
+extern void console_lock(void);
+extern int console_trylock(void);
+extern void console_unlock(void);
 extern void console_conditional_schedule(void);
 extern void console_unblank(void);
 extern struct tty_driver *console_device(int *);
index 32b38cd829d33561163dd340ce1e307150db25d3..bd3215940c3746ec22d8351854649f9b5b485f67 100644 (file)
@@ -2555,9 +2555,12 @@ int proc_nr_inodes(struct ctl_table *table, int write,
                   void __user *buffer, size_t *lenp, loff_t *ppos);
 int __init get_filesystem_list(char *buf);
 
+#define __FMODE_EXEC           ((__force int) FMODE_EXEC)
+#define __FMODE_NONOTIFY       ((__force int) FMODE_NONOTIFY)
+
 #define ACC_MODE(x) ("\004\002\006\006"[(x)&O_ACCMODE])
 #define OPEN_FMODE(flag) ((__force fmode_t)(((flag + 1) & O_ACCMODE) | \
-                                           (flag & FMODE_NONOTIFY)))
+                                           (flag & __FMODE_NONOTIFY)))
 
 #endif /* __KERNEL__ */
 #endif /* _LINUX_FS_H */
index a3b148a918740c509494b44cf2fda690d3261f96..0b84c61607e8ce808dbb6b2e611a01a6ade11646 100644 (file)
@@ -249,7 +249,7 @@ static inline enum zone_type gfp_zone(gfp_t flags)
                                         ((1 << ZONES_SHIFT) - 1);
 
        if (__builtin_constant_p(bit))
-               MAYBE_BUILD_BUG_ON((GFP_ZONE_BAD >> bit) & 1);
+               BUILD_BUG_ON((GFP_ZONE_BAD >> bit) & 1);
        else {
 #ifdef CONFIG_DEBUG_VM
                BUG_ON((GFP_ZONE_BAD >> bit) & 1);
index e470d387dd496b0bb6233dc20f6569ccffe966f8..05e03284b92ac00d1eed1f85b7076a2a5fa0a956 100644 (file)
@@ -12,8 +12,6 @@
  * @cs_en:     pointer to the cs enable function
  * @cs_dis:    pointer to the cs disable function
  * @irq_read_val:    pointer to read the pen irq value function
- * @x_max_res: xmax resolution
- * @y_max_res: ymax resolution
  * @touch_x_max: touch x max
  * @touch_y_max: touch y max
  * @cs_pin: chip select pin
@@ -29,8 +27,6 @@ struct bu21013_platform_device {
        int (*cs_en)(int reset_pin);
        int (*cs_dis)(int reset_pin);
        int (*irq_read_val)(void);
-       int x_max_res;
-       int y_max_res;
        int touch_x_max;
        int touch_y_max;
        unsigned int cs_pin;
index d07d8057e440e9eb685b0ab36d9f29cd64db97d5..2fe6e84894a4bc10006511bbbb67b15d8197958d 100644 (file)
@@ -575,12 +575,6 @@ struct sysinfo {
        char _f[20-2*sizeof(long)-sizeof(int)]; /* Padding: libc5 uses this.. */
 };
 
-/* Force a compilation error if condition is true */
-#define BUILD_BUG_ON(condition) ((void)BUILD_BUG_ON_ZERO(condition))
-
-/* Force a compilation error if condition is constant and true */
-#define MAYBE_BUILD_BUG_ON(cond) ((void)sizeof(char[1 - 2 * !!(cond)]))
-
 /* Force a compilation error if a constant expression is not a power of 2 */
 #define BUILD_BUG_ON_NOT_POWER_OF_2(n)                 \
        BUILD_BUG_ON((n) == 0 || (((n) & ((n) - 1)) != 0))
@@ -592,6 +586,32 @@ struct sysinfo {
 #define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:-!!(e); }))
 #define BUILD_BUG_ON_NULL(e) ((void *)sizeof(struct { int:-!!(e); }))
 
+/**
+ * BUILD_BUG_ON - break compile if a condition is true.
+ * @condition: the condition which the compiler should know is false.
+ *
+ * If you have some code which relies on certain constants being equal, or
+ * other compile-time-evaluated condition, you should use BUILD_BUG_ON to
+ * detect if someone changes it.
+ *
+ * The implementation uses gcc's reluctance to create a negative array, but
+ * gcc (as of 4.4) only emits that error for obvious cases (eg. not arguments
+ * to inline functions).  So as a fallback we use the optimizer; if it can't
+ * prove the condition is false, it will cause a link error on the undefined
+ * "__build_bug_on_failed".  This error message can be harder to track down
+ * though, hence the two different methods.
+ */
+#ifndef __OPTIMIZE__
+#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))
+#else
+extern int __build_bug_on_failed;
+#define BUILD_BUG_ON(condition)                                        \
+       do {                                                    \
+               ((void)sizeof(char[1 - 2*!!(condition)]));      \
+               if (condition) __build_bug_on_failed = 1;       \
+       } while(0)
+#endif
+
 /* Trap pasters of __FUNCTION__ at compile-time */
 #define __FUNCTION__ (__func__)
 
index 08d7dc4ddf40b57047d1f1304be6b02dac2f2063..39f8453239f779edcd0e5dedfc2d293b34bf7b60 100644 (file)
@@ -76,7 +76,7 @@ bool kmemcheck_is_obj_initialized(unsigned long addr, size_t size);
                                                                        \
                _n = (long) &((ptr)->name##_end)                        \
                        - (long) &((ptr)->name##_begin);                \
-               MAYBE_BUILD_BUG_ON(_n < 0);                             \
+               BUILD_BUG_ON(_n < 0);                                   \
                                                                        \
                kmemcheck_mark_initialized(&((ptr)->name##_begin), _n); \
        } while (0)
index bf173502d74418784c0c12128b43419a1242ceb3..38d3930928128b755d98ece1c2f8fe1437dfd19c 100644 (file)
@@ -94,12 +94,12 @@ struct sh_mmcif_plat_data {
 
 static inline u32 sh_mmcif_readl(void __iomem *addr, int reg)
 {
-       return readl(addr + reg);
+       return __raw_readl(addr + reg);
 }
 
 static inline void sh_mmcif_writel(void __iomem *addr, int reg, u32 val)
 {
-       writel(val, addr + reg);
+       __raw_writel(val, addr + reg);
 }
 
 #define SH_MMCIF_BBS 512 /* boot block size */
index 8b17fd8c790d8601f8aff0a33c7b909984e30545..e7c6385c668394240e237f16a92286d2f32aed5e 100644 (file)
@@ -58,6 +58,12 @@ struct module_attribute {
        void (*free)(struct module *);
 };
 
+struct module_version_attribute {
+       struct module_attribute mattr;
+       const char *module_name;
+       const char *version;
+};
+
 struct module_kobject
 {
        struct kobject kobj;
@@ -161,7 +167,28 @@ extern struct module __this_module;
   Using this automatically adds a checksum of the .c files and the
   local headers in "srcversion".
 */
+
+#if defined(MODULE) || !defined(CONFIG_SYSFS)
 #define MODULE_VERSION(_version) MODULE_INFO(version, _version)
+#else
+#define MODULE_VERSION(_version)                                       \
+       extern ssize_t __modver_version_show(struct module_attribute *, \
+                                            struct module *, char *);  \
+       static struct module_version_attribute __modver_version_attr    \
+       __used                                                          \
+    __attribute__ ((__section__ ("__modver"),aligned(sizeof(void *)))) \
+       = {                                                             \
+               .mattr  = {                                             \
+                       .attr   = {                                     \
+                               .name   = "version",                    \
+                               .mode   = S_IRUGO,                      \
+                       },                                              \
+                       .show   = __modver_version_show,                \
+               },                                                      \
+               .module_name    = KBUILD_MODNAME,                       \
+               .version        = _version,                             \
+       }
+#endif
 
 /* Optional firmware file (or files) needed by the module
  * format is simply firmware file name.  Multiple firmware
index 112adf8bd47dd2c1d13800577f340d6cfa9c0b46..07b41951e3fa9eb7894032a4921cdd65a05c05bd 100644 (file)
 /* Chosen so that structs with an unsigned long line up. */
 #define MAX_PARAM_PREFIX_LEN (64 - sizeof(unsigned long))
 
-#ifdef MODULE
 #define ___module_cat(a,b) __mod_ ## a ## b
 #define __module_cat(a,b) ___module_cat(a,b)
+#ifdef MODULE
 #define __MODULE_INFO(tag, name, info)                                   \
 static const char __module_cat(name,__LINE__)[]                                  \
   __used __attribute__((section(".modinfo"), unused, aligned(1)))        \
   = __stringify(tag) "=" info
 #else  /* !MODULE */
-#define __MODULE_INFO(tag, name, info)
+/* This struct is here for syntactic coherency, it is not used */
+#define __MODULE_INFO(tag, name, info)                                   \
+  struct __module_cat(name,__LINE__) {}
 #endif
 #define __MODULE_PARM_TYPE(name, _type)                                          \
   __MODULE_INFO(parmtype, name##type, #name ":" _type)
index f321b578edeb452358497e832815d6cae6b36886..fabcb1e5c460f240ff1f9c5e5b1d6d720505d7c5 100644 (file)
@@ -51,10 +51,10 @@ nfsacl_size(struct posix_acl *acl_access, struct posix_acl *acl_default)
        return w;
 }
 
-extern unsigned int
+extern int
 nfsacl_encode(struct xdr_buf *buf, unsigned int base, struct inode *inode,
              struct posix_acl *acl, int encode_entries, int typeflag);
-extern unsigned int
+extern int
 nfsacl_decode(struct xdr_buf *buf, unsigned int base, unsigned int *aclcnt,
              struct posix_acl **pacl);
 
index d68283a898bb8df089a5f04e29160eaea1c315b3..54211c1cd92634fb4f15bbcf5607948e499e3e52 100644 (file)
@@ -71,6 +71,7 @@ posix_acl_release(struct posix_acl *acl)
 
 /* posix_acl.c */
 
+extern void posix_acl_init(struct posix_acl *, int);
 extern struct posix_acl *posix_acl_alloc(int, gfp_t);
 extern struct posix_acl *posix_acl_clone(const struct posix_acl *, gfp_t);
 extern int posix_acl_valid(const struct posix_acl *);
index fcb9884df6181827120dcb64efd7a2104fd157d7..a5930cb6614577517223ba642854b78ba339197b 100644 (file)
@@ -182,6 +182,26 @@ static inline bool res_counter_check_under_limit(struct res_counter *cnt)
        return ret;
 }
 
+/**
+ * res_counter_check_margin - check if the counter allows charging
+ * @cnt: the resource counter to check
+ * @bytes: the number of bytes to check the remaining space against
+ *
+ * Returns a boolean value on whether the counter can be charged
+ * @bytes or whether this would exceed the limit.
+ */
+static inline bool res_counter_check_margin(struct res_counter *cnt,
+                                           unsigned long bytes)
+{
+       bool ret;
+       unsigned long flags;
+
+       spin_lock_irqsave(&cnt->lock, flags);
+       ret = cnt->limit - cnt->usage >= bytes;
+       spin_unlock_irqrestore(&cnt->lock, flags);
+       return ret;
+}
+
 static inline bool res_counter_check_under_soft_limit(struct res_counter *cnt)
 {
        bool ret;
index 3c995b4d742ccd080b9fc97a5ffdea8ee7d6d58c..a0b639f8e805b2390026999d6e7279b4158c636f 100644 (file)
@@ -235,8 +235,6 @@ extern int rtc_irq_set_freq(struct rtc_device *rtc,
                                struct rtc_task *task, int freq);
 extern int rtc_update_irq_enable(struct rtc_device *rtc, unsigned int enabled);
 extern int rtc_alarm_irq_enable(struct rtc_device *rtc, unsigned int enabled);
-extern int rtc_dev_update_irq_enable_emul(struct rtc_device *rtc,
-                                               unsigned int enabled);
 
 void rtc_aie_update_irq(void *private);
 void rtc_uie_update_irq(void *private);
@@ -246,8 +244,6 @@ int rtc_register(rtc_task_t *task);
 int rtc_unregister(rtc_task_t *task);
 int rtc_control(rtc_task_t *t, unsigned int cmd, unsigned long arg);
 
-void rtc_timer_enqueue(struct rtc_device *rtc, struct rtc_timer *timer);
-void rtc_timer_remove(struct rtc_device *rtc, struct rtc_timer *timer);
 void rtc_timer_init(struct rtc_timer *timer, void (*f)(void* p), void* data);
 int rtc_timer_start(struct rtc_device *rtc, struct rtc_timer* timer,
                        ktime_t expires, ktime_t period);
index c50b458b8a3f48047556c3f120eb538971d26cd5..082884295f80028a9a9aa3ea4255ad2cea3984d0 100644 (file)
@@ -47,14 +47,6 @@ static inline int svc_is_backchannel(const struct svc_rqst *rqstp)
                return 1;
        return 0;
 }
-static inline struct nfs4_sessionid *bc_xprt_sid(struct svc_rqst *rqstp)
-{
-       if (svc_is_backchannel(rqstp))
-               return (struct nfs4_sessionid *)
-                       rqstp->rq_server->sv_bc_xprt->xpt_bc_sid;
-       return NULL;
-}
-
 #else /* CONFIG_NFS_V4_1 */
 static inline int xprt_setup_backchannel(struct rpc_xprt *xprt,
                                         unsigned int min_reqs)
@@ -67,11 +59,6 @@ static inline int svc_is_backchannel(const struct svc_rqst *rqstp)
        return 0;
 }
 
-static inline struct nfs4_sessionid *bc_xprt_sid(struct svc_rqst *rqstp)
-{
-       return NULL;
-}
-
 static inline void xprt_free_bc_request(struct rpc_rqst *req)
 {
 }
index 059877b4d85b7c0734668bd9027745e0c10bea8b..7ad9751a0d8796e677fb2fdfd50cc4854bcf0eb7 100644 (file)
@@ -77,7 +77,6 @@ struct svc_xprt {
        size_t                  xpt_remotelen;  /* length of address */
        struct rpc_wait_queue   xpt_bc_pending; /* backchannel wait queue */
        struct list_head        xpt_users;      /* callbacks on free */
-       void                    *xpt_bc_sid;    /* back channel session ID */
 
        struct net              *xpt_net;
        struct rpc_xprt         *xpt_bc_xprt;   /* NFSv4.1 backchannel */
index 387fa7d05c982b758942f83395e328949324fc1a..7faf933cced7018657d2212d543530484ce17ec9 100644 (file)
@@ -17,6 +17,9 @@
 #include <linux/errno.h>
 #include <linux/types.h>
 
+/* Enable/disable SYSRQ support by default (0==no, 1==yes). */
+#define SYSRQ_DEFAULT_ENABLE   1
+
 /* Possible values of bitmask for enabling sysrq functions */
 /* 0x0001 is reserved for enable everything */
 #define SYSRQ_ENABLE_LOG       0x0002
index dd6ee49a084464e8390041e041b3a2a8a855259a..a854fe89484e4404ed14086fc441498fdfe85e7d 100644 (file)
@@ -112,6 +112,7 @@ struct usb_hcd {
        /* Flags that get set only during HCD registration or removal. */
        unsigned                rh_registered:1;/* is root hub registered? */
        unsigned                rh_pollable:1;  /* may we poll the root hub? */
+       unsigned                msix_enabled:1; /* driver has MSI-X enabled? */
 
        /* The next flag is a stopgap, to be removed when all the HCDs
         * support the new root-hub polling mechanism. */
index 16d682f4f7c3572fd946d736af644cd4ef9c0b27..c9049139a7a5a42f3a8f4d82d727355aeca9bce1 100644 (file)
@@ -347,6 +347,9 @@ extern int usb_serial_generic_prepare_write_buffer(struct usb_serial_port *port,
 extern int usb_serial_handle_sysrq_char(struct usb_serial_port *port,
                                        unsigned int ch);
 extern int usb_serial_handle_break(struct usb_serial_port *port);
+extern void usb_serial_handle_dcd_change(struct usb_serial_port *usb_port,
+                                        struct tty_struct *tty,
+                                        unsigned int status);
 
 
 extern int usb_serial_bus_register(struct usb_serial_driver *device);
index 0093dd7c1d6f0eaf810001851902444269e82f44..800617b4ddd56c3dd0a790f97a4c73f2fa38de64 100644 (file)
@@ -109,7 +109,10 @@ static inline bool virtio_has_feature(const struct virtio_device *vdev,
                                      unsigned int fbit)
 {
        /* Did you forget to fix assumptions on max features? */
-       MAYBE_BUILD_BUG_ON(fbit >= 32);
+       if (__builtin_constant_p(fbit))
+               BUILD_BUG_ON(fbit >= 32);
+       else
+               BUG_ON(fbit >= 32);
 
        if (fbit < VIRTIO_TRANSPORT_F_START)
                virtio_check_driver_offered_feature(vdev, fbit);
index a29feb01854eb9ad0940cc52fe51bbc759614222..d2cf88407690e432f80938985d7cbcf4fb16d0ed 100644 (file)
@@ -184,6 +184,7 @@ struct hci_conn {
        __u32            link_mode;
        __u8             auth_type;
        __u8             sec_level;
+       __u8             pending_sec_level;
        __u8             power_save;
        __u16            disc_timeout;
        unsigned long    pend;
index e9eee99d8b1f4668aef09526341d0e032a6f120b..160a407c19632a2220fa6fc5efc120086fd076ee 100644 (file)
@@ -445,7 +445,6 @@ static inline int __qdisc_enqueue_tail(struct sk_buff *skb, struct Qdisc *sch,
 {
        __skb_queue_tail(list, skb);
        sch->qstats.backlog += qdisc_pkt_len(skb);
-       qdisc_bstats_update(sch, skb);
 
        return NET_XMIT_SUCCESS;
 }
@@ -460,8 +459,10 @@ static inline struct sk_buff *__qdisc_dequeue_head(struct Qdisc *sch,
 {
        struct sk_buff *skb = __skb_dequeue(list);
 
-       if (likely(skb != NULL))
+       if (likely(skb != NULL)) {
                sch->qstats.backlog -= qdisc_pkt_len(skb);
+               qdisc_bstats_update(sch, skb);
+       }
 
        return skb;
 }
@@ -474,10 +475,11 @@ static inline struct sk_buff *qdisc_dequeue_head(struct Qdisc *sch)
 static inline unsigned int __qdisc_queue_drop_head(struct Qdisc *sch,
                                              struct sk_buff_head *list)
 {
-       struct sk_buff *skb = __qdisc_dequeue_head(sch, list);
+       struct sk_buff *skb = __skb_dequeue(list);
 
        if (likely(skb != NULL)) {
                unsigned int len = qdisc_pkt_len(skb);
+               sch->qstats.backlog -= len;
                kfree_skb(skb);
                return len;
        }
index 08107d1817582000af8df78667db22e6d88e5f59..0da1411222b9a2e11c1de4ed228e4028e8aef2b1 100644 (file)
@@ -719,9 +719,7 @@ void destroy_params(const struct kernel_param *params, unsigned num)
                        params[i].ops->free(params[i].arg);
 }
 
-static void __init kernel_add_sysfs_param(const char *name,
-                                         struct kernel_param *kparam,
-                                         unsigned int name_skip)
+static struct module_kobject * __init locate_module_kobject(const char *name)
 {
        struct module_kobject *mk;
        struct kobject *kobj;
@@ -729,10 +727,7 @@ static void __init kernel_add_sysfs_param(const char *name,
 
        kobj = kset_find_obj(module_kset, name);
        if (kobj) {
-               /* We already have one.  Remove params so we can add more. */
                mk = to_module_kobject(kobj);
-               /* We need to remove it before adding parameters. */
-               sysfs_remove_group(&mk->kobj, &mk->mp->grp);
        } else {
                mk = kzalloc(sizeof(struct module_kobject), GFP_KERNEL);
                BUG_ON(!mk);
@@ -743,15 +738,36 @@ static void __init kernel_add_sysfs_param(const char *name,
                                           "%s", name);
                if (err) {
                        kobject_put(&mk->kobj);
-                       printk(KERN_ERR "Module '%s' failed add to sysfs, "
-                              "error number %d\n", name, err);
-                       printk(KERN_ERR "The system will be unstable now.\n");
-                       return;
+                       printk(KERN_ERR
+                               "Module '%s' failed add to sysfs, error number %d\n",
+                               name, err);
+                       printk(KERN_ERR
+                               "The system will be unstable now.\n");
+                       return NULL;
                }
-               /* So that exit path is even. */
+
+               /* So that we hold reference in both cases. */
                kobject_get(&mk->kobj);
        }
 
+       return mk;
+}
+
+static void __init kernel_add_sysfs_param(const char *name,
+                                         struct kernel_param *kparam,
+                                         unsigned int name_skip)
+{
+       struct module_kobject *mk;
+       int err;
+
+       mk = locate_module_kobject(name);
+       if (!mk)
+               return;
+
+       /* We need to remove old parameters before adding more. */
+       if (mk->mp)
+               sysfs_remove_group(&mk->kobj, &mk->mp->grp);
+
        /* These should not fail at boot. */
        err = add_sysfs_param(mk, kparam, kparam->name + name_skip);
        BUG_ON(err);
@@ -796,6 +812,32 @@ static void __init param_sysfs_builtin(void)
        }
 }
 
+ssize_t __modver_version_show(struct module_attribute *mattr,
+                             struct module *mod, char *buf)
+{
+       struct module_version_attribute *vattr =
+               container_of(mattr, struct module_version_attribute, mattr);
+
+       return sprintf(buf, "%s\n", vattr->version);
+}
+
+extern struct module_version_attribute __start___modver[], __stop___modver[];
+
+static void __init version_sysfs_builtin(void)
+{
+       const struct module_version_attribute *vattr;
+       struct module_kobject *mk;
+       int err;
+
+       for (vattr = __start___modver; vattr < __stop___modver; vattr++) {
+               mk = locate_module_kobject(vattr->module_name);
+               if (mk) {
+                       err = sysfs_create_file(&mk->kobj, &vattr->mattr.attr);
+                       kobject_uevent(&mk->kobj, KOBJ_ADD);
+                       kobject_put(&mk->kobj);
+               }
+       }
+}
 
 /* module-related sysfs stuff */
 
@@ -875,6 +917,7 @@ static int __init param_sysfs_init(void)
        }
        module_sysfs_initialized = 1;
 
+       version_sysfs_builtin();
        param_sysfs_builtin();
 
        return 0;
index 84522c7969870fa3a6024086c6a3559546b0e9db..126a302c481c060782e811e92e3fca0386271208 100644 (file)
@@ -2201,13 +2201,6 @@ find_lively_task_by_vpid(pid_t vpid)
        if (!task)
                return ERR_PTR(-ESRCH);
 
-       /*
-        * Can't attach events to a dying task.
-        */
-       err = -ESRCH;
-       if (task->flags & PF_EXITING)
-               goto errout;
-
        /* Reuse ptrace permission checks for now. */
        err = -EACCES;
        if (!ptrace_may_access(task, PTRACE_MODE_READ))
@@ -2268,14 +2261,27 @@ retry:
 
                get_ctx(ctx);
 
-               if (cmpxchg(&task->perf_event_ctxp[ctxn], NULL, ctx)) {
-                       /*
-                        * We raced with some other task; use
-                        * the context they set.
-                        */
+               err = 0;
+               mutex_lock(&task->perf_event_mutex);
+               /*
+                * If it has already passed perf_event_exit_task().
+                * we must see PF_EXITING, it takes this mutex too.
+                */
+               if (task->flags & PF_EXITING)
+                       err = -ESRCH;
+               else if (task->perf_event_ctxp[ctxn])
+                       err = -EAGAIN;
+               else
+                       rcu_assign_pointer(task->perf_event_ctxp[ctxn], ctx);
+               mutex_unlock(&task->perf_event_mutex);
+
+               if (unlikely(err)) {
                        put_task_struct(task);
                        kfree(ctx);
-                       goto retry;
+
+                       if (err == -EAGAIN)
+                               goto retry;
+                       goto errout;
                }
        }
 
@@ -5374,6 +5380,8 @@ free_dev:
        goto out;
 }
 
+static struct lock_class_key cpuctx_mutex;
+
 int perf_pmu_register(struct pmu *pmu, char *name, int type)
 {
        int cpu, ret;
@@ -5422,6 +5430,7 @@ skip_type:
 
                cpuctx = per_cpu_ptr(pmu->pmu_cpu_context, cpu);
                __perf_event_init_context(&cpuctx->ctx);
+               lockdep_set_class(&cpuctx->ctx.mutex, &cpuctx_mutex);
                cpuctx->ctx.type = cpu_context;
                cpuctx->ctx.pmu = pmu;
                cpuctx->jiffies_interval = 1;
@@ -6127,7 +6136,7 @@ static void perf_event_exit_task_context(struct task_struct *child, int ctxn)
         * scheduled, so we are now safe from rescheduling changing
         * our context.
         */
-       child_ctx = child->perf_event_ctxp[ctxn];
+       child_ctx = rcu_dereference_raw(child->perf_event_ctxp[ctxn]);
        task_ctx_sched_out(child_ctx, EVENT_ALL);
 
        /*
@@ -6440,11 +6449,6 @@ int perf_event_init_context(struct task_struct *child, int ctxn)
        unsigned long flags;
        int ret = 0;
 
-       child->perf_event_ctxp[ctxn] = NULL;
-
-       mutex_init(&child->perf_event_mutex);
-       INIT_LIST_HEAD(&child->perf_event_list);
-
        if (likely(!parent->perf_event_ctxp[ctxn]))
                return 0;
 
@@ -6533,6 +6537,10 @@ int perf_event_init_task(struct task_struct *child)
 {
        int ctxn, ret;
 
+       memset(child->perf_event_ctxp, 0, sizeof(child->perf_event_ctxp));
+       mutex_init(&child->perf_event_mutex);
+       INIT_LIST_HEAD(&child->perf_event_list);
+
        for_each_task_context_nr(ctxn) {
                ret = perf_event_init_context(child, ctxn);
                if (ret)
index 53d9a9ec88e6952cde88769ce6cd124c57f541d4..2ddbdc73aade6cbdeadc804575bcf145eb02dd29 100644 (file)
@@ -97,7 +97,7 @@ static int console_locked, console_suspended;
 /*
  * logbuf_lock protects log_buf, log_start, log_end, con_start and logged_chars
  * It is also used in interesting ways to provide interlocking in
- * release_console_sem().
+ * console_unlock();.
  */
 static DEFINE_SPINLOCK(logbuf_lock);
 
@@ -501,7 +501,7 @@ static void _call_console_drivers(unsigned start,
 /*
  * Call the console drivers, asking them to write out
  * log_buf[start] to log_buf[end - 1].
- * The console_sem must be held.
+ * The console_lock must be held.
  */
 static void call_console_drivers(unsigned start, unsigned end)
 {
@@ -604,11 +604,11 @@ static int have_callable_console(void)
  *
  * This is printk().  It can be called from any context.  We want it to work.
  *
- * We try to grab the console_sem.  If we succeed, it's easy - we log the output and
+ * We try to grab the console_lock.  If we succeed, it's easy - we log the output and
  * call the console drivers.  If we fail to get the semaphore we place the output
  * into the log buffer and return.  The current holder of the console_sem will
- * notice the new output in release_console_sem() and will send it to the
- * consoles before releasing the semaphore.
+ * notice the new output in console_unlock(); and will send it to the
+ * consoles before releasing the lock.
  *
  * One effect of this deferred printing is that code which calls printk() and
  * then changes console_loglevel may break. This is because console_loglevel
@@ -659,19 +659,19 @@ static inline int can_use_console(unsigned int cpu)
 /*
  * Try to get console ownership to actually show the kernel
  * messages from a 'printk'. Return true (and with the
- * console_semaphore held, and 'console_locked' set) if it
+ * console_lock held, and 'console_locked' set) if it
  * is successful, false otherwise.
  *
  * This gets called with the 'logbuf_lock' spinlock held and
  * interrupts disabled. It should return with 'lockbuf_lock'
  * released but interrupts still disabled.
  */
-static int acquire_console_semaphore_for_printk(unsigned int cpu)
+static int console_trylock_for_printk(unsigned int cpu)
        __releases(&logbuf_lock)
 {
        int retval = 0;
 
-       if (!try_acquire_console_sem()) {
+       if (console_trylock()) {
                retval = 1;
 
                /*
@@ -827,12 +827,12 @@ asmlinkage int vprintk(const char *fmt, va_list args)
         * actual magic (print out buffers, wake up klogd,
         * etc). 
         *
-        * The acquire_console_semaphore_for_printk() function
+        * The console_trylock_for_printk() function
         * will release 'logbuf_lock' regardless of whether it
         * actually gets the semaphore or not.
         */
-       if (acquire_console_semaphore_for_printk(this_cpu))
-               release_console_sem();
+       if (console_trylock_for_printk(this_cpu))
+               console_unlock();
 
        lockdep_on();
 out_restore_irqs:
@@ -993,7 +993,7 @@ void suspend_console(void)
        if (!console_suspend_enabled)
                return;
        printk("Suspending console(s) (use no_console_suspend to debug)\n");
-       acquire_console_sem();
+       console_lock();
        console_suspended = 1;
        up(&console_sem);
 }
@@ -1004,7 +1004,7 @@ void resume_console(void)
                return;
        down(&console_sem);
        console_suspended = 0;
-       release_console_sem();
+       console_unlock();
 }
 
 /**
@@ -1027,21 +1027,21 @@ static int __cpuinit console_cpu_notify(struct notifier_block *self,
        case CPU_DYING:
        case CPU_DOWN_FAILED:
        case CPU_UP_CANCELED:
-               acquire_console_sem();
-               release_console_sem();
+               console_lock();
+               console_unlock();
        }
        return NOTIFY_OK;
 }
 
 /**
- * acquire_console_sem - lock the console system for exclusive use.
+ * console_lock - lock the console system for exclusive use.
  *
- * Acquires a semaphore which guarantees that the caller has
+ * Acquires a lock which guarantees that the caller has
  * exclusive access to the console system and the console_drivers list.
  *
  * Can sleep, returns nothing.
  */
-void acquire_console_sem(void)
+void console_lock(void)
 {
        BUG_ON(in_interrupt());
        down(&console_sem);
@@ -1050,21 +1050,29 @@ void acquire_console_sem(void)
        console_locked = 1;
        console_may_schedule = 1;
 }
-EXPORT_SYMBOL(acquire_console_sem);
+EXPORT_SYMBOL(console_lock);
 
-int try_acquire_console_sem(void)
+/**
+ * console_trylock - try to lock the console system for exclusive use.
+ *
+ * Tried to acquire a lock which guarantees that the caller has
+ * exclusive access to the console system and the console_drivers list.
+ *
+ * returns 1 on success, and 0 on failure to acquire the lock.
+ */
+int console_trylock(void)
 {
        if (down_trylock(&console_sem))
-               return -1;
+               return 0;
        if (console_suspended) {
                up(&console_sem);
-               return -1;
+               return 0;
        }
        console_locked = 1;
        console_may_schedule = 0;
-       return 0;
+       return 1;
 }
-EXPORT_SYMBOL(try_acquire_console_sem);
+EXPORT_SYMBOL(console_trylock);
 
 int is_console_locked(void)
 {
@@ -1095,20 +1103,20 @@ void wake_up_klogd(void)
 }
 
 /**
- * release_console_sem - unlock the console system
+ * console_unlock - unlock the console system
  *
- * Releases the semaphore which the caller holds on the console system
+ * Releases the console_lock which the caller holds on the console system
  * and the console driver list.
  *
- * While the semaphore was held, console output may have been buffered
- * by printk().  If this is the case, release_console_sem() emits
- * the output prior to releasing the semaphore.
+ * While the console_lock was held, console output may have been buffered
+ * by printk().  If this is the case, console_unlock(); emits
+ * the output prior to releasing the lock.
  *
  * If there is output waiting for klogd, we wake it up.
  *
- * release_console_sem() may be called from any context.
+ * console_unlock(); may be called from any context.
  */
-void release_console_sem(void)
+void console_unlock(void)
 {
        unsigned long flags;
        unsigned _con_start, _log_end;
@@ -1141,7 +1149,7 @@ void release_console_sem(void)
        if (wake_klogd)
                wake_up_klogd();
 }
-EXPORT_SYMBOL(release_console_sem);
+EXPORT_SYMBOL(console_unlock);
 
 /**
  * console_conditional_schedule - yield the CPU if required
@@ -1150,7 +1158,7 @@ EXPORT_SYMBOL(release_console_sem);
  * if this CPU should yield the CPU to another task, do
  * so here.
  *
- * Must be called within acquire_console_sem().
+ * Must be called within console_lock();.
  */
 void __sched console_conditional_schedule(void)
 {
@@ -1171,14 +1179,14 @@ void console_unblank(void)
                if (down_trylock(&console_sem) != 0)
                        return;
        } else
-               acquire_console_sem();
+               console_lock();
 
        console_locked = 1;
        console_may_schedule = 0;
        for_each_console(c)
                if ((c->flags & CON_ENABLED) && c->unblank)
                        c->unblank();
-       release_console_sem();
+       console_unlock();
 }
 
 /*
@@ -1189,7 +1197,7 @@ struct tty_driver *console_device(int *index)
        struct console *c;
        struct tty_driver *driver = NULL;
 
-       acquire_console_sem();
+       console_lock();
        for_each_console(c) {
                if (!c->device)
                        continue;
@@ -1197,7 +1205,7 @@ struct tty_driver *console_device(int *index)
                if (driver)
                        break;
        }
-       release_console_sem();
+       console_unlock();
        return driver;
 }
 
@@ -1208,17 +1216,17 @@ struct tty_driver *console_device(int *index)
  */
 void console_stop(struct console *console)
 {
-       acquire_console_sem();
+       console_lock();
        console->flags &= ~CON_ENABLED;
-       release_console_sem();
+       console_unlock();
 }
 EXPORT_SYMBOL(console_stop);
 
 void console_start(struct console *console)
 {
-       acquire_console_sem();
+       console_lock();
        console->flags |= CON_ENABLED;
-       release_console_sem();
+       console_unlock();
 }
 EXPORT_SYMBOL(console_start);
 
@@ -1340,7 +1348,7 @@ void register_console(struct console *newcon)
         *      Put this console in the list - keep the
         *      preferred driver at the head of the list.
         */
-       acquire_console_sem();
+       console_lock();
        if ((newcon->flags & CON_CONSDEV) || console_drivers == NULL) {
                newcon->next = console_drivers;
                console_drivers = newcon;
@@ -1352,14 +1360,14 @@ void register_console(struct console *newcon)
        }
        if (newcon->flags & CON_PRINTBUFFER) {
                /*
-                * release_console_sem() will print out the buffered messages
+                * console_unlock(); will print out the buffered messages
                 * for us.
                 */
                spin_lock_irqsave(&logbuf_lock, flags);
                con_start = log_start;
                spin_unlock_irqrestore(&logbuf_lock, flags);
        }
-       release_console_sem();
+       console_unlock();
        console_sysfs_notify();
 
        /*
@@ -1396,7 +1404,7 @@ int unregister_console(struct console *console)
                return braille_unregister_console(console);
 #endif
 
-       acquire_console_sem();
+       console_lock();
        if (console_drivers == console) {
                console_drivers=console->next;
                res = 0;
@@ -1418,7 +1426,7 @@ int unregister_console(struct console *console)
        if (console_drivers != NULL && console->flags & CON_CONSDEV)
                console_drivers->flags |= CON_CONSDEV;
 
-       release_console_sem();
+       console_unlock();
        console_sysfs_notify();
        return res;
 }
index 77e9166d7bbfe304dcc2bdb9c71276d4a3a3b18b..0c26e2df450ee534e79f1265851100245b30a9cd 100644 (file)
@@ -699,7 +699,8 @@ account_entity_dequeue(struct cfs_rq *cfs_rq, struct sched_entity *se)
        cfs_rq->nr_running--;
 }
 
-#if defined CONFIG_SMP && defined CONFIG_FAIR_GROUP_SCHED
+#ifdef CONFIG_FAIR_GROUP_SCHED
+# ifdef CONFIG_SMP
 static void update_cfs_rq_load_contribution(struct cfs_rq *cfs_rq,
                                            int global_update)
 {
@@ -721,10 +722,10 @@ static void update_cfs_load(struct cfs_rq *cfs_rq, int global_update)
        u64 now, delta;
        unsigned long load = cfs_rq->load.weight;
 
-       if (!cfs_rq)
+       if (cfs_rq->tg == &root_task_group)
                return;
 
-       now = rq_of(cfs_rq)->clock;
+       now = rq_of(cfs_rq)->clock_task;
        delta = now - cfs_rq->load_stamp;
 
        /* truncate load history at 4 idle periods */
@@ -762,6 +763,51 @@ static void update_cfs_load(struct cfs_rq *cfs_rq, int global_update)
                list_del_leaf_cfs_rq(cfs_rq);
 }
 
+static long calc_cfs_shares(struct cfs_rq *cfs_rq, struct task_group *tg,
+                               long weight_delta)
+{
+       long load_weight, load, shares;
+
+       load = cfs_rq->load.weight + weight_delta;
+
+       load_weight = atomic_read(&tg->load_weight);
+       load_weight -= cfs_rq->load_contribution;
+       load_weight += load;
+
+       shares = (tg->shares * load);
+       if (load_weight)
+               shares /= load_weight;
+
+       if (shares < MIN_SHARES)
+               shares = MIN_SHARES;
+       if (shares > tg->shares)
+               shares = tg->shares;
+
+       return shares;
+}
+
+static void update_entity_shares_tick(struct cfs_rq *cfs_rq)
+{
+       if (cfs_rq->load_unacc_exec_time > sysctl_sched_shares_window) {
+               update_cfs_load(cfs_rq, 0);
+               update_cfs_shares(cfs_rq, 0);
+       }
+}
+# else /* CONFIG_SMP */
+static void update_cfs_load(struct cfs_rq *cfs_rq, int global_update)
+{
+}
+
+static inline long calc_cfs_shares(struct cfs_rq *cfs_rq, struct task_group *tg,
+                               long weight_delta)
+{
+       return tg->shares;
+}
+
+static inline void update_entity_shares_tick(struct cfs_rq *cfs_rq)
+{
+}
+# endif /* CONFIG_SMP */
 static void reweight_entity(struct cfs_rq *cfs_rq, struct sched_entity *se,
                            unsigned long weight)
 {
@@ -782,41 +828,20 @@ static void update_cfs_shares(struct cfs_rq *cfs_rq, long weight_delta)
 {
        struct task_group *tg;
        struct sched_entity *se;
-       long load_weight, load, shares;
-
-       if (!cfs_rq)
-               return;
+       long shares;
 
        tg = cfs_rq->tg;
        se = tg->se[cpu_of(rq_of(cfs_rq))];
        if (!se)
                return;
-
-       load = cfs_rq->load.weight + weight_delta;
-
-       load_weight = atomic_read(&tg->load_weight);
-       load_weight -= cfs_rq->load_contribution;
-       load_weight += load;
-
-       shares = (tg->shares * load);
-       if (load_weight)
-               shares /= load_weight;
-
-       if (shares < MIN_SHARES)
-               shares = MIN_SHARES;
-       if (shares > tg->shares)
-               shares = tg->shares;
+#ifndef CONFIG_SMP
+       if (likely(se->load.weight == tg->shares))
+               return;
+#endif
+       shares = calc_cfs_shares(cfs_rq, tg, weight_delta);
 
        reweight_entity(cfs_rq_of(se), se, shares);
 }
-
-static void update_entity_shares_tick(struct cfs_rq *cfs_rq)
-{
-       if (cfs_rq->load_unacc_exec_time > sysctl_sched_shares_window) {
-               update_cfs_load(cfs_rq, 0);
-               update_cfs_shares(cfs_rq, 0);
-       }
-}
 #else /* CONFIG_FAIR_GROUP_SCHED */
 static void update_cfs_load(struct cfs_rq *cfs_rq, int global_update)
 {
@@ -1404,7 +1429,7 @@ static inline unsigned long effective_load(struct task_group *tg, int cpu,
 
 static int wake_affine(struct sched_domain *sd, struct task_struct *p, int sync)
 {
-       unsigned long this_load, load;
+       s64 this_load, load;
        int idx, this_cpu, prev_cpu;
        unsigned long tl_per_task;
        struct task_group *tg;
@@ -1443,8 +1468,8 @@ static int wake_affine(struct sched_domain *sd, struct task_struct *p, int sync)
         * Otherwise check if either cpus are near enough in load to allow this
         * task to be woken on this_cpu.
         */
-       if (this_load) {
-               unsigned long this_eff_load, prev_eff_load;
+       if (this_load > 0) {
+               s64 this_eff_load, prev_eff_load;
 
                this_eff_load = 100;
                this_eff_load *= power_of(prev_cpu);
index 31b71a276b40eda1c64578666ac7e1fadb77642f..18da702ec813c491c758b6f28e86a31a71ba60b5 100644 (file)
@@ -1385,7 +1385,8 @@ static int check_prlimit_permission(struct task_struct *task)
        const struct cred *cred = current_cred(), *tcred;
 
        tcred = __task_cred(task);
-       if ((cred->uid != tcred->euid ||
+       if (current != task &&
+           (cred->uid != tcred->euid ||
             cred->uid != tcred->suid ||
             cred->uid != tcred->uid  ||
             cred->gid != tcred->egid ||
index bc86bb32e12620c463699c9e461c836ce37733c1..0f1bd83db98523333b9fabde37d200512b20b77e 100644 (file)
@@ -170,7 +170,8 @@ static int proc_taint(struct ctl_table *table, int write,
 #endif
 
 #ifdef CONFIG_MAGIC_SYSRQ
-static int __sysrq_enabled; /* Note: sysrq code ises it's own private copy */
+/* Note: sysrq code uses it's own private copy */
+static int __sysrq_enabled = SYSRQ_DEFAULT_ENABLE;
 
 static int sysrq_sysctl_handler(ctl_table *table, int write,
                                void __user *buffer, size_t *lenp,
index 3e216e01bbd19191f440cf8b202af38007d06ece..c55ea2433471c2952bd65283cd72eb165d720bbe 100644 (file)
@@ -642,8 +642,7 @@ static void tick_nohz_switch_to_nohz(void)
        }
        local_irq_enable();
 
-       printk(KERN_INFO "Switched to NOHz mode on CPU #%d\n",
-              smp_processor_id());
+       printk(KERN_INFO "Switched to NOHz mode on CPU #%d\n", smp_processor_id());
 }
 
 /*
@@ -795,8 +794,10 @@ void tick_setup_sched_timer(void)
        }
 
 #ifdef CONFIG_NO_HZ
-       if (tick_nohz_enabled)
+       if (tick_nohz_enabled) {
                ts->nohz_mode = NOHZ_MODE_HIGHRES;
+               printk(KERN_INFO "Switched to NOHz mode on CPU #%d\n", smp_processor_id());
+       }
 #endif
 }
 #endif /* HIGH_RES_TIMERS */
index 5086bb962b4dd9ca6471afb76f0698facb914816..7ea2e033d7153ad23de9dc02c0c0786abc1e11e2 100644 (file)
@@ -736,10 +736,11 @@ next:
                }
        }
        /*
-        * The iftag must have been set somewhere because otherwise
-        * we would return immediated at the beginning of the function
+        * We need not to tag the root tag if there is no tag which is set with
+        * settag within the range from *first_indexp to last_index.
         */
-       root_tag_set(root, settag);
+       if (tagged > 0)
+               root_tag_set(root, settag);
        *first_indexp = index;
 
        return tagged;
index 4693f79195d3bc4fd118a01cda1128c0ea1f9df9..a16be19a130545ce44fc4f8c6a3f9fde866b9159 100644 (file)
@@ -315,6 +315,7 @@ void rb_augment_insert(struct rb_node *node, rb_augment_f func, void *data)
 
        rb_augment_path(node, func, data);
 }
+EXPORT_SYMBOL(rb_augment_insert);
 
 /*
  * before removing the node, find the deepest node on the rebalance path
@@ -340,6 +341,7 @@ struct rb_node *rb_augment_erase_begin(struct rb_node *node)
 
        return deepest;
 }
+EXPORT_SYMBOL(rb_augment_erase_begin);
 
 /*
  * after removal, update the tree to account for the removed entry
@@ -350,6 +352,7 @@ void rb_augment_erase_end(struct rb_node *node, rb_augment_f func, void *data)
        if (node)
                rb_augment_path(node, func, data);
 }
+EXPORT_SYMBOL(rb_augment_erase_end);
 
 /*
  * This function returns the first node (in sort order) of the tree.
index d608331b3e4798c23607471dea52bbc483c69760..e0cc0146ae622a0f48060ccefc53ada28e299c59 100644 (file)
@@ -13,7 +13,7 @@
  *
  * INTRODUCTION
  *
- *   The textsearch infrastructure provides text searching facitilies for
+ *   The textsearch infrastructure provides text searching facilities for
  *   both linear and non-linear data. Individual search algorithms are
  *   implemented in modules and chosen by the user.
  *
@@ -43,7 +43,7 @@
  *       to the algorithm to store persistent variables.
  *   (4) Core eventually resets the search offset and forwards the find()
  *       request to the algorithm.
- *   (5) Algorithm calls get_next_block() provided by the user continously
+ *   (5) Algorithm calls get_next_block() provided by the user continuously
  *       to fetch the data to be searched in block by block.
  *   (6) Algorithm invokes finish() after the last call to get_next_block
  *       to clean up any leftovers from get_next_block. (Optional)
  *   the pattern to look for and flags. As a flag, you can set TS_IGNORECASE
  *   to perform case insensitive matching. But it might slow down
  *   performance of algorithm, so you should use it at own your risk.
- *   The returned configuration may then be used for an arbitary
+ *   The returned configuration may then be used for an arbitrary
  *   amount of times and even in parallel as long as a separate struct
  *   ts_state variable is provided to every instance.
  *
  *   The actual search is performed by either calling textsearch_find_-
  *   continuous() for linear data or by providing an own get_next_block()
  *   implementation and calling textsearch_find(). Both functions return
- *   the position of the first occurrence of the patern or UINT_MAX if
- *   no match was found. Subsequent occurences can be found by calling
+ *   the position of the first occurrence of the pattern or UINT_MAX if
+ *   no match was found. Subsequent occurrences can be found by calling
  *   textsearch_next() regardless of the linearity of the data.
  *
  *   Once you're done using a configuration it must be given back via
index 3ad483bdf505a560dcc3b9c3dfe2de4331539155..e9c0c61f2ddd0881bbb9dee37d3384dae0146ece 100644 (file)
@@ -179,7 +179,7 @@ config SPLIT_PTLOCK_CPUS
 config COMPACTION
        bool "Allow for memory compaction"
        select MIGRATION
-       depends on EXPERIMENTAL && HUGETLB_PAGE && MMU
+       depends on MMU
        help
          Allows the compaction of memory for the allocation of huge pages.
 
index e187454d82f666a70bab08762ca92cd60b8f848c..b6c1ce3c53b548e5a6ffab498889a5c79d1eae69 100644 (file)
@@ -1162,7 +1162,12 @@ static void __split_huge_page_refcount(struct page *page)
                /* after clearing PageTail the gup refcount can be released */
                smp_mb();
 
-               page_tail->flags &= ~PAGE_FLAGS_CHECK_AT_PREP;
+               /*
+                * retain hwpoison flag of the poisoned tail page:
+                *   fix for the unsuitable process killed on Guest Machine(KVM)
+                *   by the memory-failure.
+                */
+               page_tail->flags &= ~PAGE_FLAGS_CHECK_AT_PREP | __PG_HWPOISON;
                page_tail->flags |= (page->flags &
                                     ((1L << PG_referenced) |
                                      (1L << PG_swapbacked) |
index 177a5169bbde178323974f027940957a9b4fa4a9..ff0d9779cec8060fe9a161dd278943a39c29f58e 100644 (file)
@@ -75,13 +75,11 @@ static int __init kmemleak_test_init(void)
         * after the module is removed.
         */
        for (i = 0; i < 10; i++) {
-               elem = kmalloc(sizeof(*elem), GFP_KERNEL);
-               pr_info("kmemleak: kmalloc(sizeof(*elem)) = %p\n", elem);
+               elem = kzalloc(sizeof(*elem), GFP_KERNEL);
+               pr_info("kmemleak: kzalloc(sizeof(*elem)) = %p\n", elem);
                if (!elem)
                        return -ENOMEM;
-               memset(elem, 0, sizeof(*elem));
                INIT_LIST_HEAD(&elem->list);
-
                list_add_tail(&elem->list, &test_list);
        }
 
index bd9bc214091b39b23c7b61182c81d17e2da7bf71..84225f3b71905ba8a2aa639a3007486b97715db1 100644 (file)
 #define BYTES_PER_POINTER      sizeof(void *)
 
 /* GFP bitmask for kmemleak internal allocations */
-#define GFP_KMEMLEAK_MASK      (GFP_KERNEL | GFP_ATOMIC)
+#define gfp_kmemleak_mask(gfp) (((gfp) & (GFP_KERNEL | GFP_ATOMIC)) | \
+                                __GFP_NORETRY | __GFP_NOMEMALLOC | \
+                                __GFP_NOWARN)
 
 /* scanning area inside a memory block */
 struct kmemleak_scan_area {
@@ -511,9 +513,10 @@ static struct kmemleak_object *create_object(unsigned long ptr, size_t size,
        struct kmemleak_object *object;
        struct prio_tree_node *node;
 
-       object = kmem_cache_alloc(object_cache, gfp & GFP_KMEMLEAK_MASK);
+       object = kmem_cache_alloc(object_cache, gfp_kmemleak_mask(gfp));
        if (!object) {
-               kmemleak_stop("Cannot allocate a kmemleak_object structure\n");
+               pr_warning("Cannot allocate a kmemleak_object structure\n");
+               kmemleak_disable();
                return NULL;
        }
 
@@ -734,9 +737,9 @@ static void add_scan_area(unsigned long ptr, size_t size, gfp_t gfp)
                return;
        }
 
-       area = kmem_cache_alloc(scan_area_cache, gfp & GFP_KMEMLEAK_MASK);
+       area = kmem_cache_alloc(scan_area_cache, gfp_kmemleak_mask(gfp));
        if (!area) {
-               kmemleak_warn("Cannot allocate a scan area\n");
+               pr_warning("Cannot allocate a scan area\n");
                goto out;
        }
 
index db76ef726293fa744da16ef8cabbe643980bf07e..da53a252b259f0f36f553e9646187db18d49d76a 100644 (file)
@@ -612,8 +612,10 @@ static void mem_cgroup_charge_statistics(struct mem_cgroup *mem,
        /* pagein of a big page is an event. So, ignore page size */
        if (nr_pages > 0)
                __this_cpu_inc(mem->stat->count[MEM_CGROUP_STAT_PGPGIN_COUNT]);
-       else
+       else {
                __this_cpu_inc(mem->stat->count[MEM_CGROUP_STAT_PGPGOUT_COUNT]);
+               nr_pages = -nr_pages; /* for event */
+       }
 
        __this_cpu_add(mem->stat->count[MEM_CGROUP_EVENTS], nr_pages);
 
@@ -1111,6 +1113,23 @@ static bool mem_cgroup_check_under_limit(struct mem_cgroup *mem)
        return false;
 }
 
+/**
+ * mem_cgroup_check_margin - check if the memory cgroup allows charging
+ * @mem: memory cgroup to check
+ * @bytes: the number of bytes the caller intends to charge
+ *
+ * Returns a boolean value on whether @mem can be charged @bytes or
+ * whether this would exceed the limit.
+ */
+static bool mem_cgroup_check_margin(struct mem_cgroup *mem, unsigned long bytes)
+{
+       if (!res_counter_check_margin(&mem->res, bytes))
+               return false;
+       if (do_swap_account && !res_counter_check_margin(&mem->memsw, bytes))
+               return false;
+       return true;
+}
+
 static unsigned int get_swappiness(struct mem_cgroup *memcg)
 {
        struct cgroup *cgrp = memcg->css.cgroup;
@@ -1832,27 +1851,39 @@ static int __mem_cgroup_do_charge(struct mem_cgroup *mem, gfp_t gfp_mask,
                if (likely(!ret))
                        return CHARGE_OK;
 
+               res_counter_uncharge(&mem->res, csize);
                mem_over_limit = mem_cgroup_from_res_counter(fail_res, memsw);
                flags |= MEM_CGROUP_RECLAIM_NOSWAP;
        } else
                mem_over_limit = mem_cgroup_from_res_counter(fail_res, res);
-
-       if (csize > PAGE_SIZE) /* change csize and retry */
+       /*
+        * csize can be either a huge page (HPAGE_SIZE), a batch of
+        * regular pages (CHARGE_SIZE), or a single regular page
+        * (PAGE_SIZE).
+        *
+        * Never reclaim on behalf of optional batching, retry with a
+        * single page instead.
+        */
+       if (csize == CHARGE_SIZE)
                return CHARGE_RETRY;
 
        if (!(gfp_mask & __GFP_WAIT))
                return CHARGE_WOULDBLOCK;
 
        ret = mem_cgroup_hierarchical_reclaim(mem_over_limit, NULL,
-                                       gfp_mask, flags);
+                                             gfp_mask, flags);
+       if (mem_cgroup_check_margin(mem_over_limit, csize))
+               return CHARGE_RETRY;
        /*
-        * try_to_free_mem_cgroup_pages() might not give us a full
-        * picture of reclaim. Some pages are reclaimed and might be
-        * moved to swap cache or just unmapped from the cgroup.
-        * Check the limit again to see if the reclaim reduced the
-        * current usage of the cgroup before giving up
+        * Even though the limit is exceeded at this point, reclaim
+        * may have been able to free some pages.  Retry the charge
+        * before killing the task.
+        *
+        * Only for regular pages, though: huge pages are rather
+        * unlikely to succeed so close to the limit, and we fall back
+        * to regular pages anyway in case of failure.
         */
-       if (ret || mem_cgroup_check_under_limit(mem_over_limit))
+       if (csize == PAGE_SIZE && ret)
                return CHARGE_RETRY;
 
        /*
@@ -2144,6 +2175,8 @@ void mem_cgroup_split_huge_fixup(struct page *head, struct page *tail)
        struct page_cgroup *tail_pc = lookup_page_cgroup(tail);
        unsigned long flags;
 
+       if (mem_cgroup_disabled())
+               return;
        /*
         * We have no races with charge/uncharge but will have races with
         * page state accounting.
@@ -2233,7 +2266,12 @@ static int mem_cgroup_move_account(struct page_cgroup *pc,
 {
        int ret = -EINVAL;
        unsigned long flags;
-
+       /*
+        * The page is isolated from LRU. So, collapse function
+        * will not handle this page. But page splitting can happen.
+        * Do this check under compound_page_lock(). The caller should
+        * hold it.
+        */
        if ((charge_size > PAGE_SIZE) && !PageTransHuge(pc->page))
                return -EBUSY;
 
@@ -2265,7 +2303,7 @@ static int mem_cgroup_move_parent(struct page_cgroup *pc,
        struct cgroup *cg = child->css.cgroup;
        struct cgroup *pcg = cg->parent;
        struct mem_cgroup *parent;
-       int charge = PAGE_SIZE;
+       int page_size = PAGE_SIZE;
        unsigned long flags;
        int ret;
 
@@ -2278,23 +2316,26 @@ static int mem_cgroup_move_parent(struct page_cgroup *pc,
                goto out;
        if (isolate_lru_page(page))
                goto put;
-       /* The page is isolated from LRU and we have no race with splitting */
-       charge = PAGE_SIZE << compound_order(page);
+
+       if (PageTransHuge(page))
+               page_size = HPAGE_SIZE;
 
        parent = mem_cgroup_from_cont(pcg);
-       ret = __mem_cgroup_try_charge(NULL, gfp_mask, &parent, false, charge);
+       ret = __mem_cgroup_try_charge(NULL, gfp_mask,
+                               &parent, false, page_size);
        if (ret || !parent)
                goto put_back;
 
-       if (charge > PAGE_SIZE)
+       if (page_size > PAGE_SIZE)
                flags = compound_lock_irqsave(page);
 
-       ret = mem_cgroup_move_account(pc, child, parent, true, charge);
+       ret = mem_cgroup_move_account(pc, child, parent, true, page_size);
        if (ret)
-               mem_cgroup_cancel_charge(parent, charge);
-put_back:
-       if (charge > PAGE_SIZE)
+               mem_cgroup_cancel_charge(parent, page_size);
+
+       if (page_size > PAGE_SIZE)
                compound_unlock_irqrestore(page, flags);
+put_back:
        putback_lru_page(page);
 put:
        put_page(page);
@@ -2312,13 +2353,19 @@ static int mem_cgroup_charge_common(struct page *page, struct mm_struct *mm,
                                gfp_t gfp_mask, enum charge_type ctype)
 {
        struct mem_cgroup *mem = NULL;
+       int page_size = PAGE_SIZE;
        struct page_cgroup *pc;
+       bool oom = true;
        int ret;
-       int page_size = PAGE_SIZE;
 
        if (PageTransHuge(page)) {
                page_size <<= compound_order(page);
                VM_BUG_ON(!PageTransHuge(page));
+               /*
+                * Never OOM-kill a process for a huge page.  The
+                * fault handler will fall back to regular pages.
+                */
+               oom = false;
        }
 
        pc = lookup_page_cgroup(page);
@@ -2327,7 +2374,7 @@ static int mem_cgroup_charge_common(struct page *page, struct mm_struct *mm,
                return 0;
        prefetchw(pc);
 
-       ret = __mem_cgroup_try_charge(mm, gfp_mask, &mem, true, page_size);
+       ret = __mem_cgroup_try_charge(mm, gfp_mask, &mem, oom, page_size);
        if (ret || !mem)
                return ret;
 
@@ -5013,9 +5060,9 @@ struct cgroup_subsys mem_cgroup_subsys = {
 static int __init enable_swap_account(char *s)
 {
        /* consider enabled if no parameter or 1 is given */
-       if (!s || !strcmp(s, "1"))
+       if (!(*s) || !strcmp(s, "=1"))
                really_do_swap_account = 1;
-       else if (!strcmp(s, "0"))
+       else if (!strcmp(s, "=0"))
                really_do_swap_account = 0;
        return 1;
 }
@@ -5023,7 +5070,8 @@ __setup("swapaccount", enable_swap_account);
 
 static int __init disable_swap_account(char *s)
 {
-       enable_swap_account("0");
+       printk_once("noswapaccount is deprecated and will be removed in 2.6.40. Use swapaccount=0 instead\n");
+       enable_swap_account("=0");
        return 1;
 }
 __setup("noswapaccount", disable_swap_account);
index 548fbd70f026bfbec6c578630ce1bcd496d7cc59..0207c2f6f8bd73466bff24c2b6d167406d6042e5 100644 (file)
@@ -233,8 +233,8 @@ void shake_page(struct page *p, int access)
        }
 
        /*
-        * Only all shrink_slab here (which would also
-        * shrink other caches) if access is not potentially fatal.
+        * Only call shrink_slab here (which would also shrink other caches) if
+        * access is not potentially fatal.
         */
        if (access) {
                int nr;
@@ -386,8 +386,6 @@ static void collect_procs_anon(struct page *page, struct list_head *to_kill,
        struct task_struct *tsk;
        struct anon_vma *av;
 
-       if (!PageHuge(page) && unlikely(split_huge_page(page)))
-               return;
        read_lock(&tasklist_lock);
        av = page_lock_anon_vma(page);
        if (av == NULL) /* Not actually mapped anymore */
@@ -856,6 +854,7 @@ static int hwpoison_user_mappings(struct page *p, unsigned long pfn,
        int ret;
        int kill = 1;
        struct page *hpage = compound_head(p);
+       struct page *ppage;
 
        if (PageReserved(p) || PageSlab(p))
                return SWAP_SUCCESS;
@@ -896,6 +895,44 @@ static int hwpoison_user_mappings(struct page *p, unsigned long pfn,
                }
        }
 
+       /*
+        * ppage: poisoned page
+        *   if p is regular page(4k page)
+        *        ppage == real poisoned page;
+        *   else p is hugetlb or THP, ppage == head page.
+        */
+       ppage = hpage;
+
+       if (PageTransHuge(hpage)) {
+               /*
+                * Verify that this isn't a hugetlbfs head page, the check for
+                * PageAnon is just for avoid tripping a split_huge_page
+                * internal debug check, as split_huge_page refuses to deal with
+                * anything that isn't an anon page. PageAnon can't go away fro
+                * under us because we hold a refcount on the hpage, without a
+                * refcount on the hpage. split_huge_page can't be safely called
+                * in the first place, having a refcount on the tail isn't
+                * enough * to be safe.
+                */
+               if (!PageHuge(hpage) && PageAnon(hpage)) {
+                       if (unlikely(split_huge_page(hpage))) {
+                               /*
+                                * FIXME: if splitting THP is failed, it is
+                                * better to stop the following operation rather
+                                * than causing panic by unmapping. System might
+                                * survive if the page is freed later.
+                                */
+                               printk(KERN_INFO
+                                       "MCE %#lx: failed to split THP\n", pfn);
+
+                               BUG_ON(!PageHWPoison(p));
+                               return SWAP_FAIL;
+                       }
+                       /* THP is split, so ppage should be the real poisoned page. */
+                       ppage = p;
+               }
+       }
+
        /*
         * First collect all the processes that have the page
         * mapped in dirty form.  This has to be done before try_to_unmap,
@@ -905,12 +942,18 @@ static int hwpoison_user_mappings(struct page *p, unsigned long pfn,
         * there's nothing that can be done.
         */
        if (kill)
-               collect_procs(hpage, &tokill);
+               collect_procs(ppage, &tokill);
+
+       if (hpage != ppage)
+               lock_page_nosync(ppage);
 
-       ret = try_to_unmap(hpage, ttu);
+       ret = try_to_unmap(ppage, ttu);
        if (ret != SWAP_SUCCESS)
                printk(KERN_ERR "MCE %#lx: failed to unmap page (mapcount=%d)\n",
-                               pfn, page_mapcount(hpage));
+                               pfn, page_mapcount(ppage));
+
+       if (hpage != ppage)
+               unlock_page(ppage);
 
        /*
         * Now that the dirty bit has been propagated to the
@@ -921,7 +964,7 @@ static int hwpoison_user_mappings(struct page *p, unsigned long pfn,
         * use a more force-full uncatchable kill to prevent
         * any accesses to the poisoned memory.
         */
-       kill_procs_ao(&tokill, !!PageDirty(hpage), trapno,
+       kill_procs_ao(&tokill, !!PageDirty(ppage), trapno,
                      ret != SWAP_SUCCESS, p, pfn);
 
        return ret;
@@ -1022,19 +1065,22 @@ int __memory_failure(unsigned long pfn, int trapno, int flags)
         * The check (unnecessarily) ignores LRU pages being isolated and
         * walked by the page reclaim code, however that's not a big loss.
         */
-       if (!PageLRU(p) && !PageHuge(p))
-               shake_page(p, 0);
-       if (!PageLRU(p) && !PageHuge(p)) {
-               /*
-                * shake_page could have turned it free.
-                */
-               if (is_free_buddy_page(p)) {
-                       action_result(pfn, "free buddy, 2nd try", DELAYED);
-                       return 0;
+       if (!PageHuge(p) && !PageTransCompound(p)) {
+               if (!PageLRU(p))
+                       shake_page(p, 0);
+               if (!PageLRU(p)) {
+                       /*
+                        * shake_page could have turned it free.
+                        */
+                       if (is_free_buddy_page(p)) {
+                               action_result(pfn, "free buddy, 2nd try",
+                                               DELAYED);
+                               return 0;
+                       }
+                       action_result(pfn, "non LRU", IGNORED);
+                       put_page(p);
+                       return -EBUSY;
                }
-               action_result(pfn, "non LRU", IGNORED);
-               put_page(p);
-               return -EBUSY;
        }
 
        /*
@@ -1064,7 +1110,7 @@ int __memory_failure(unsigned long pfn, int trapno, int flags)
         * For error on the tail page, we should set PG_hwpoison
         * on the head page to show that the hugepage is hwpoisoned
         */
-       if (PageTail(p) && TestSetPageHWPoison(hpage)) {
+       if (PageHuge(p) && PageTail(p) && TestSetPageHWPoison(hpage)) {
                action_result(pfn, "hugepage already hardware poisoned",
                                IGNORED);
                unlock_page(hpage);
@@ -1295,7 +1341,10 @@ static int soft_offline_huge_page(struct page *page, int flags)
        ret = migrate_huge_pages(&pagelist, new_page, MPOL_MF_MOVE_ALL, 0,
                                true);
        if (ret) {
-               putback_lru_pages(&pagelist);
+               struct page *page1, *page2;
+               list_for_each_entry_safe(page1, page2, &pagelist, lru)
+                       put_page(page1);
+
                pr_debug("soft offline: %#lx: migration failed %d, type %lx\n",
                         pfn, ret, page->flags);
                if (ret > 0)
@@ -1419,6 +1468,7 @@ int soft_offline_page(struct page *page, int flags)
                ret = migrate_pages(&pagelist, new_page, MPOL_MF_MOVE_ALL,
                                                                0, true);
                if (ret) {
+                       putback_lru_pages(&pagelist);
                        pr_info("soft offline: %#lx: migration failed %d, type %lx\n",
                                pfn, ret, page->flags);
                        if (ret > 0)
index 46fe8cc13d67f3acf80653434223577084fd8fcf..7661152538074ee8018be8b87e1600021be5dc27 100644 (file)
@@ -772,6 +772,7 @@ uncharge:
 unlock:
        unlock_page(page);
 
+move_newpage:
        if (rc != -EAGAIN) {
                /*
                 * A page that has been migrated has all references
@@ -785,8 +786,6 @@ unlock:
                putback_lru_page(page);
        }
 
-move_newpage:
-
        /*
         * Move the new page to the LRU. If migration was not successful
         * then this will free the page.
@@ -888,7 +887,7 @@ out:
  * are movable anymore because to has become empty
  * or no retryable pages exist anymore.
  * Caller should call putback_lru_pages to return pages to the LRU
- * or free list.
+ * or free list only if ret != 0.
  *
  * Return: Number of pages not migrated or error code.
  */
@@ -981,10 +980,6 @@ int migrate_huge_pages(struct list_head *from,
        }
        rc = 0;
 out:
-
-       list_for_each_entry_safe(page, page2, from, lru)
-               put_page(page);
-
        if (rc)
                return rc;
 
index 13e81ee8be9d9b6a8d93b793c2dd837960b68a13..c3924c7f00bead9d027b222e478a6a97462ac4c3 100644 (file)
@@ -178,6 +178,13 @@ static long __mlock_vma_pages_range(struct vm_area_struct *vma,
        if ((vma->vm_flags & (VM_WRITE | VM_SHARED)) == VM_WRITE)
                gup_flags |= FOLL_WRITE;
 
+       /*
+        * We want mlock to succeed for regions that have any permissions
+        * other than PROT_NONE.
+        */
+       if (vma->vm_flags & (VM_READ | VM_WRITE | VM_EXEC))
+               gup_flags |= FOLL_FORCE;
+
        if (vma->vm_flags & VM_LOCKED)
                gup_flags |= FOLL_MLOCK;
 
index 90c1439549fdf221ab1813b14ae0d5dc74adce45..a873e61e312e6dd7795b4b734a0370bc844d9f29 100644 (file)
@@ -1088,8 +1088,10 @@ static void drain_pages(unsigned int cpu)
                pset = per_cpu_ptr(zone->pageset, cpu);
 
                pcp = &pset->pcp;
-               free_pcppages_bulk(zone, pcp->count, pcp);
-               pcp->count = 0;
+               if (pcp->count) {
+                       free_pcppages_bulk(zone, pcp->count, pcp);
+                       pcp->count = 0;
+               }
                local_irq_restore(flags);
        }
 }
@@ -2034,6 +2036,14 @@ restart:
         */
        alloc_flags = gfp_to_alloc_flags(gfp_mask);
 
+       /*
+        * Find the true preferred zone if the allocation is unconstrained by
+        * cpusets.
+        */
+       if (!(alloc_flags & ALLOC_CPUSET) && !nodemask)
+               first_zones_zonelist(zonelist, high_zoneidx, NULL,
+                                       &preferred_zone);
+
        /* This is the last chance, in general, before the goto nopage. */
        page = get_page_from_freelist(gfp_mask, nodemask, order, zonelist,
                        high_zoneidx, alloc_flags & ~ALLOC_NO_WATERMARKS,
@@ -2192,7 +2202,9 @@ __alloc_pages_nodemask(gfp_t gfp_mask, unsigned int order,
 
        get_mems_allowed();
        /* The preferred zone is used for statistics later */
-       first_zones_zonelist(zonelist, high_zoneidx, nodemask, &preferred_zone);
+       first_zones_zonelist(zonelist, high_zoneidx,
+                               nodemask ? : &cpuset_current_mems_allowed,
+                               &preferred_zone);
        if (!preferred_zone) {
                put_mems_allowed();
                return NULL;
index 0369f5b3ba1b3fcc510e99cdd68c5f7ed7d490c4..eb663fb533e06f45305ac0b348b2365ecb1615bb 100644 (file)
@@ -6,6 +6,7 @@
  *  Copyright (C) 2010  Linus Torvalds
  */
 
+#include <linux/pagemap.h>
 #include <asm/tlb.h>
 #include <asm-generic/pgtable.h>
 
index f5d90dedebbafab2235c6d408a371d40e52d4e54..148c6e630df2002d8f72b35cca1ed79b7bedb334 100644 (file)
@@ -2083,7 +2083,8 @@ static unsigned long do_try_to_free_pages(struct zonelist *zonelist,
                        struct zone *preferred_zone;
 
                        first_zones_zonelist(zonelist, gfp_zone(sc->gfp_mask),
-                                                       NULL, &preferred_zone);
+                                               &cpuset_current_mems_allowed,
+                                               &preferred_zone);
                        wait_iff_congested(preferred_zone, BLK_RW_ASYNC, HZ/10);
                }
        }
index 6b90a41917347826f2a81fea590124a54af1f9bd..99cd8d9d891b475c57925be6ae54a88240f7adc8 100644 (file)
@@ -379,14 +379,10 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8
        hci_conn_hold(acl);
 
        if (acl->state == BT_OPEN || acl->state == BT_CLOSED) {
-               acl->sec_level = sec_level;
+               acl->sec_level = BT_SECURITY_LOW;
+               acl->pending_sec_level = sec_level;
                acl->auth_type = auth_type;
                hci_acl_connect(acl);
-       } else {
-               if (acl->sec_level < sec_level)
-                       acl->sec_level = sec_level;
-               if (acl->auth_type < auth_type)
-                       acl->auth_type = auth_type;
        }
 
        if (type == ACL_LINK)
@@ -442,11 +438,17 @@ static int hci_conn_auth(struct hci_conn *conn, __u8 sec_level, __u8 auth_type)
 {
        BT_DBG("conn %p", conn);
 
+       if (conn->pending_sec_level > sec_level)
+               sec_level = conn->pending_sec_level;
+
        if (sec_level > conn->sec_level)
-               conn->sec_level = sec_level;
+               conn->pending_sec_level = sec_level;
        else if (conn->link_mode & HCI_LM_AUTH)
                return 1;
 
+       /* Make sure we preserve an existing MITM requirement*/
+       auth_type |= (conn->auth_type & 0x01);
+
        conn->auth_type = auth_type;
 
        if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) {
index 8b602d881fd758f88a5d7a8cca8d2e7d03caeb92..9c4541bc488ab9b2a74dda2809929f842b9b97e6 100644 (file)
@@ -1011,6 +1011,10 @@ int hci_unregister_dev(struct hci_dev *hdev)
 
        destroy_workqueue(hdev->workqueue);
 
+       hci_dev_lock_bh(hdev);
+       hci_blacklist_clear(hdev);
+       hci_dev_unlock_bh(hdev);
+
        __hci_dev_put(hdev);
 
        return 0;
index 38100170d380a1f794c1ea75b7723f36312a7212..a290854fdaa6ac68bba2443a51763723d5be7f62 100644 (file)
@@ -692,13 +692,13 @@ static int hci_outgoing_auth_needed(struct hci_dev *hdev,
        if (conn->state != BT_CONFIG || !conn->out)
                return 0;
 
-       if (conn->sec_level == BT_SECURITY_SDP)
+       if (conn->pending_sec_level == BT_SECURITY_SDP)
                return 0;
 
        /* Only request authentication for SSP connections or non-SSP
         * devices with sec_level HIGH */
        if (!(hdev->ssp_mode > 0 && conn->ssp_mode > 0) &&
-                                       conn->sec_level != BT_SECURITY_HIGH)
+                               conn->pending_sec_level != BT_SECURITY_HIGH)
                return 0;
 
        return 1;
@@ -1095,9 +1095,10 @@ static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *s
 
        conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
        if (conn) {
-               if (!ev->status)
+               if (!ev->status) {
                        conn->link_mode |= HCI_LM_AUTH;
-               else
+                       conn->sec_level = conn->pending_sec_level;
+               } else
                        conn->sec_level = BT_SECURITY_LOW;
 
                clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);
index c791fcda7b2d11bc4d2758701f1b200d73841f0c..7550abb0c96a36d60869009daecd20a601eb7263 100644 (file)
@@ -305,33 +305,44 @@ static void l2cap_chan_del(struct sock *sk, int err)
        }
 }
 
-/* Service level security */
-static inline int l2cap_check_security(struct sock *sk)
+static inline u8 l2cap_get_auth_type(struct sock *sk)
 {
-       struct l2cap_conn *conn = l2cap_pi(sk)->conn;
-       __u8 auth_type;
+       if (sk->sk_type == SOCK_RAW) {
+               switch (l2cap_pi(sk)->sec_level) {
+               case BT_SECURITY_HIGH:
+                       return HCI_AT_DEDICATED_BONDING_MITM;
+               case BT_SECURITY_MEDIUM:
+                       return HCI_AT_DEDICATED_BONDING;
+               default:
+                       return HCI_AT_NO_BONDING;
+               }
+       } else if (l2cap_pi(sk)->psm == cpu_to_le16(0x0001)) {
+               if (l2cap_pi(sk)->sec_level == BT_SECURITY_LOW)
+                       l2cap_pi(sk)->sec_level = BT_SECURITY_SDP;
 
-       if (l2cap_pi(sk)->psm == cpu_to_le16(0x0001)) {
                if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
-                       auth_type = HCI_AT_NO_BONDING_MITM;
+                       return HCI_AT_NO_BONDING_MITM;
                else
-                       auth_type = HCI_AT_NO_BONDING;
-
-               if (l2cap_pi(sk)->sec_level == BT_SECURITY_LOW)
-                       l2cap_pi(sk)->sec_level = BT_SECURITY_SDP;
+                       return HCI_AT_NO_BONDING;
        } else {
                switch (l2cap_pi(sk)->sec_level) {
                case BT_SECURITY_HIGH:
-                       auth_type = HCI_AT_GENERAL_BONDING_MITM;
-                       break;
+                       return HCI_AT_GENERAL_BONDING_MITM;
                case BT_SECURITY_MEDIUM:
-                       auth_type = HCI_AT_GENERAL_BONDING;
-                       break;
+                       return HCI_AT_GENERAL_BONDING;
                default:
-                       auth_type = HCI_AT_NO_BONDING;
-                       break;
+                       return HCI_AT_NO_BONDING;
                }
        }
+}
+
+/* Service level security */
+static inline int l2cap_check_security(struct sock *sk)
+{
+       struct l2cap_conn *conn = l2cap_pi(sk)->conn;
+       __u8 auth_type;
+
+       auth_type = l2cap_get_auth_type(sk);
 
        return hci_conn_security(conn->hcon, l2cap_pi(sk)->sec_level,
                                                                auth_type);
@@ -1068,39 +1079,7 @@ static int l2cap_do_connect(struct sock *sk)
 
        err = -ENOMEM;
 
-       if (sk->sk_type == SOCK_RAW) {
-               switch (l2cap_pi(sk)->sec_level) {
-               case BT_SECURITY_HIGH:
-                       auth_type = HCI_AT_DEDICATED_BONDING_MITM;
-                       break;
-               case BT_SECURITY_MEDIUM:
-                       auth_type = HCI_AT_DEDICATED_BONDING;
-                       break;
-               default:
-                       auth_type = HCI_AT_NO_BONDING;
-                       break;
-               }
-       } else if (l2cap_pi(sk)->psm == cpu_to_le16(0x0001)) {
-               if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
-                       auth_type = HCI_AT_NO_BONDING_MITM;
-               else
-                       auth_type = HCI_AT_NO_BONDING;
-
-               if (l2cap_pi(sk)->sec_level == BT_SECURITY_LOW)
-                       l2cap_pi(sk)->sec_level = BT_SECURITY_SDP;
-       } else {
-               switch (l2cap_pi(sk)->sec_level) {
-               case BT_SECURITY_HIGH:
-                       auth_type = HCI_AT_GENERAL_BONDING_MITM;
-                       break;
-               case BT_SECURITY_MEDIUM:
-                       auth_type = HCI_AT_GENERAL_BONDING;
-                       break;
-               default:
-                       auth_type = HCI_AT_NO_BONDING;
-                       break;
-               }
-       }
+       auth_type = l2cap_get_auth_type(sk);
 
        hcon = hci_connect(hdev, ACL_LINK, dst,
                                        l2cap_pi(sk)->sec_level, auth_type);
@@ -1127,7 +1106,8 @@ static int l2cap_do_connect(struct sock *sk)
                if (sk->sk_type != SOCK_SEQPACKET &&
                                sk->sk_type != SOCK_STREAM) {
                        l2cap_sock_clear_timer(sk);
-                       sk->sk_state = BT_CONNECTED;
+                       if (l2cap_check_security(sk))
+                               sk->sk_state = BT_CONNECTED;
                } else
                        l2cap_do_start(sk);
        }
@@ -1893,8 +1873,8 @@ static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct ms
                if (pi->mode == L2CAP_MODE_STREAMING) {
                        l2cap_streaming_send(sk);
                } else {
-                       if (pi->conn_state & L2CAP_CONN_REMOTE_BUSY &&
-                                       pi->conn_state && L2CAP_CONN_WAIT_F) {
+                       if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) &&
+                                       (pi->conn_state & L2CAP_CONN_WAIT_F)) {
                                err = len;
                                break;
                        }
index ff8aaa736650b81caed4058323a79643ce0d2931..6b83776534fb45e29946f9666cb7a23654d4a431 100644 (file)
@@ -1164,7 +1164,8 @@ static int rfcomm_recv_ua(struct rfcomm_session *s, u8 dlci)
                         * initiator rfcomm_process_rx already calls
                         * rfcomm_session_put() */
                        if (s->sock->sk->sk_state != BT_CLOSED)
-                               rfcomm_session_put(s);
+                               if (list_empty(&s->dlcs))
+                                       rfcomm_session_put(s);
                        break;
                }
        }
index 7c6a46f803724633e6539c81186f4ff955f0e297..24ea2d71e7eac37000285ea5cd348e1ecb14f156 100644 (file)
@@ -749,7 +749,8 @@ EXPORT_SYMBOL(dev_get_by_index);
  *     @ha: hardware address
  *
  *     Search for an interface by MAC address. Returns NULL if the device
- *     is not found or a pointer to the device. The caller must hold RCU
+ *     is not found or a pointer to the device.
+ *     The caller must hold RCU or RTNL.
  *     The returned device has not had its ref count increased
  *     and the caller must therefore be careful about locking
  *
index 17741782a345f78328a881da5887f6e81834f5b6..ff2302910b5eb936c7618c24477c018cfdcd159f 100644 (file)
@@ -817,7 +817,7 @@ static int ethtool_get_regs(struct net_device *dev, char __user *useraddr)
        if (regs.len > reglen)
                regs.len = reglen;
 
-       regbuf = vmalloc(reglen);
+       regbuf = vzalloc(reglen);
        if (!regbuf)
                return -ENOMEM;
 
index d31bb36ae0dc21cfdab61b90dd2f2fbfd665ce81..7cd1bc86d5911118a7a7bc6c1bc0ad7f1188ae6a 100644 (file)
@@ -2744,8 +2744,12 @@ int skb_gro_receive(struct sk_buff **head, struct sk_buff *skb)
 
 merge:
        if (offset > headlen) {
-               skbinfo->frags[0].page_offset += offset - headlen;
-               skbinfo->frags[0].size -= offset - headlen;
+               unsigned int eat = offset - headlen;
+
+               skbinfo->frags[0].page_offset += eat;
+               skbinfo->frags[0].size -= eat;
+               skb->data_len -= eat;
+               skb->len -= eat;
                offset = headlen;
        }
 
index d900ab99814a7e54d8d2d9e14cd828314dd4e7ce..6b03f561caecfdd72c1fc0df2785c435acdb3cc4 100644 (file)
@@ -583,7 +583,7 @@ static int dcbnl_getapp(struct net_device *netdev, struct nlattr **tb,
        u8 up, idtype;
        int ret = -EINVAL;
 
-       if (!tb[DCB_ATTR_APP] || !netdev->dcbnl_ops->getapp)
+       if (!tb[DCB_ATTR_APP])
                goto out;
 
        ret = nla_parse_nested(app_tb, DCB_APP_ATTR_MAX, tb[DCB_ATTR_APP],
@@ -604,7 +604,16 @@ static int dcbnl_getapp(struct net_device *netdev, struct nlattr **tb,
                goto out;
 
        id = nla_get_u16(app_tb[DCB_APP_ATTR_ID]);
-       up = netdev->dcbnl_ops->getapp(netdev, idtype, id);
+
+       if (netdev->dcbnl_ops->getapp) {
+               up = netdev->dcbnl_ops->getapp(netdev, idtype, id);
+       } else {
+               struct dcb_app app = {
+                                       .selector = idtype,
+                                       .protocol = id,
+                                    };
+               up = dcb_getapp(netdev, &app);
+       }
 
        /* send this back */
        dcbnl_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
index 0c877a74e1f433699272953712458393045ff13c..3fb14b7c13cf1ed3bc5bb1439e6bfc35f907af96 100644 (file)
@@ -428,7 +428,7 @@ static void __exit dsa_cleanup_module(void)
 }
 module_exit(dsa_cleanup_module);
 
-MODULE_AUTHOR("Lennert Buytenhek <buytenh@wantstofly.org>")
+MODULE_AUTHOR("Lennert Buytenhek <buytenh@wantstofly.org>");
 MODULE_DESCRIPTION("Driver for Distributed Switch Architecture switch chips");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("platform:dsa");
index 04c8b69fd426457b3112aa379382a361fa9e9130..7927589813b54b5baa50ae29904c5b0e21f6a513 100644 (file)
@@ -1017,14 +1017,13 @@ static int arp_req_set_proxy(struct net *net, struct net_device *dev, int on)
                IPV4_DEVCONF_ALL(net, PROXY_ARP) = on;
                return 0;
        }
-       if (__in_dev_get_rcu(dev)) {
-               IN_DEV_CONF_SET(__in_dev_get_rcu(dev), PROXY_ARP, on);
+       if (__in_dev_get_rtnl(dev)) {
+               IN_DEV_CONF_SET(__in_dev_get_rtnl(dev), PROXY_ARP, on);
                return 0;
        }
        return -ENXIO;
 }
 
-/* must be called with rcu_read_lock() */
 static int arp_req_set_public(struct net *net, struct arpreq *r,
                struct net_device *dev)
 {
@@ -1233,10 +1232,10 @@ int arp_ioctl(struct net *net, unsigned int cmd, void __user *arg)
        if (!(r.arp_flags & ATF_NETMASK))
                ((struct sockaddr_in *)&r.arp_netmask)->sin_addr.s_addr =
                                                           htonl(0xFFFFFFFFUL);
-       rcu_read_lock();
+       rtnl_lock();
        if (r.arp_dev[0]) {
                err = -ENODEV;
-               dev = dev_get_by_name_rcu(net, r.arp_dev);
+               dev = __dev_get_by_name(net, r.arp_dev);
                if (dev == NULL)
                        goto out;
 
@@ -1263,7 +1262,7 @@ int arp_ioctl(struct net *net, unsigned int cmd, void __user *arg)
                break;
        }
 out:
-       rcu_read_unlock();
+       rtnl_unlock();
        if (cmd == SIOCGARP && !err && copy_to_user(arg, &r, sizeof(r)))
                err = -EFAULT;
        return err;
index d9bc85751c74c7376568fb2b59da450658b1afd5..a96e65674ac3e694e8e70fec1855324a694ccbf3 100644 (file)
@@ -475,7 +475,7 @@ static int cleanup_once(unsigned long ttl)
 struct inet_peer *inet_getpeer(struct inetpeer_addr *daddr, int create)
 {
        struct inet_peer __rcu **stack[PEER_MAXDEPTH], ***stackptr;
-       struct inet_peer_base *base = family_to_base(AF_INET);
+       struct inet_peer_base *base = family_to_base(daddr->family);
        struct inet_peer *p;
 
        /* Look up for the address quickly, lockless.
index 2549b29b062d00c0cdc5f5a5f6dc069ce8b86e64..eb7f82ebf4a325a1199bbe5610cd4191bc6e2df5 100644 (file)
@@ -4399,7 +4399,7 @@ static void tcp_data_queue(struct sock *sk, struct sk_buff *skb)
                        if (!skb_copy_datagram_iovec(skb, 0, tp->ucopy.iov, chunk)) {
                                tp->ucopy.len -= chunk;
                                tp->copied_seq += chunk;
-                               eaten = (chunk == skb->len && !th->fin);
+                               eaten = (chunk == skb->len);
                                tcp_rcv_space_adjust(sk);
                        }
                        local_bh_disable();
index 856f68466d49a8e0d01d03bf66748bd3ad218a1c..02f583b3744a7b633743e8c998ba1b3b0081a3fb 100644 (file)
@@ -1994,7 +1994,6 @@ static void *listening_get_next(struct seq_file *seq, void *cur)
                                }
                                req = req->dl_next;
                        }
-                       st->offset = 0;
                        if (++st->sbucket >= icsk->icsk_accept_queue.listen_opt->nr_table_entries)
                                break;
 get_req:
index 24a1cf110d8058f11771e77f9a3430d8e0972371..fd6782e3a038a03b2a17f9da188ae1bc8d181f3f 100644 (file)
@@ -2661,14 +2661,12 @@ static int addrconf_ifdown(struct net_device *dev, int how)
        struct net *net = dev_net(dev);
        struct inet6_dev *idev;
        struct inet6_ifaddr *ifa;
-       LIST_HEAD(keep_list);
-       int state;
+       int state, i;
 
        ASSERT_RTNL();
 
-       /* Flush routes if device is being removed or it is not loopback */
-       if (how || !(dev->flags & IFF_LOOPBACK))
-               rt6_ifdown(net, dev);
+       rt6_ifdown(net, dev);
+       neigh_ifdown(&nd_tbl, dev);
 
        idev = __in6_dev_get(dev);
        if (idev == NULL)
@@ -2689,6 +2687,23 @@ static int addrconf_ifdown(struct net_device *dev, int how)
 
        }
 
+       /* Step 2: clear hash table */
+       for (i = 0; i < IN6_ADDR_HSIZE; i++) {
+               struct hlist_head *h = &inet6_addr_lst[i];
+               struct hlist_node *n;
+
+               spin_lock_bh(&addrconf_hash_lock);
+       restart:
+               hlist_for_each_entry_rcu(ifa, n, h, addr_lst) {
+                       if (ifa->idev == idev) {
+                               hlist_del_init_rcu(&ifa->addr_lst);
+                               addrconf_del_timer(ifa);
+                               goto restart;
+                       }
+               }
+               spin_unlock_bh(&addrconf_hash_lock);
+       }
+
        write_lock_bh(&idev->lock);
 
        /* Step 2: clear flags for stateless addrconf */
@@ -2722,52 +2737,23 @@ static int addrconf_ifdown(struct net_device *dev, int how)
                                       struct inet6_ifaddr, if_list);
                addrconf_del_timer(ifa);
 
-               /* If just doing link down, and address is permanent
-                  and not link-local, then retain it. */
-               if (!how &&
-                   (ifa->flags&IFA_F_PERMANENT) &&
-                   !(ipv6_addr_type(&ifa->addr) & IPV6_ADDR_LINKLOCAL)) {
-                       list_move_tail(&ifa->if_list, &keep_list);
-
-                       /* If not doing DAD on this address, just keep it. */
-                       if ((dev->flags&(IFF_NOARP|IFF_LOOPBACK)) ||
-                           idev->cnf.accept_dad <= 0 ||
-                           (ifa->flags & IFA_F_NODAD))
-                               continue;
+               list_del(&ifa->if_list);
 
-                       /* If it was tentative already, no need to notify */
-                       if (ifa->flags & IFA_F_TENTATIVE)
-                               continue;
+               write_unlock_bh(&idev->lock);
 
-                       /* Flag it for later restoration when link comes up */
-                       ifa->flags |= IFA_F_TENTATIVE;
-                       ifa->state = INET6_IFADDR_STATE_DAD;
-               } else {
-                       list_del(&ifa->if_list);
-
-                       /* clear hash table */
-                       spin_lock_bh(&addrconf_hash_lock);
-                       hlist_del_init_rcu(&ifa->addr_lst);
-                       spin_unlock_bh(&addrconf_hash_lock);
-
-                       write_unlock_bh(&idev->lock);
-                       spin_lock_bh(&ifa->state_lock);
-                       state = ifa->state;
-                       ifa->state = INET6_IFADDR_STATE_DEAD;
-                       spin_unlock_bh(&ifa->state_lock);
-
-                       if (state != INET6_IFADDR_STATE_DEAD) {
-                               __ipv6_ifa_notify(RTM_DELADDR, ifa);
-                               atomic_notifier_call_chain(&inet6addr_chain,
-                                                          NETDEV_DOWN, ifa);
-                       }
+               spin_lock_bh(&ifa->state_lock);
+               state = ifa->state;
+               ifa->state = INET6_IFADDR_STATE_DEAD;
+               spin_unlock_bh(&ifa->state_lock);
 
-                       in6_ifa_put(ifa);
-                       write_lock_bh(&idev->lock);
+               if (state != INET6_IFADDR_STATE_DEAD) {
+                       __ipv6_ifa_notify(RTM_DELADDR, ifa);
+                       atomic_notifier_call_chain(&inet6addr_chain, NETDEV_DOWN, ifa);
                }
-       }
+               in6_ifa_put(ifa);
 
-       list_splice(&keep_list, &idev->addr_list);
+               write_lock_bh(&idev->lock);
+       }
 
        write_unlock_bh(&idev->lock);
 
@@ -4156,8 +4142,7 @@ static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp)
                addrconf_leave_solict(ifp->idev, &ifp->addr);
                dst_hold(&ifp->rt->dst);
 
-               if (ifp->state == INET6_IFADDR_STATE_DEAD &&
-                   ip6_del_rt(ifp->rt))
+               if (ip6_del_rt(ifp->rt))
                        dst_free(&ifp->rt->dst);
                break;
        }
index 373bd0416f69f9ad7e4645eebb574a3ec4eb4127..1534508f6c68a3c4f010657e94051e06a7d727c4 100644 (file)
@@ -72,8 +72,6 @@
 #define RT6_TRACE(x...) do { ; } while (0)
 #endif
 
-#define CLONE_OFFLINK_ROUTE 0
-
 static struct rt6_info * ip6_rt_copy(struct rt6_info *ort);
 static struct dst_entry        *ip6_dst_check(struct dst_entry *dst, u32 cookie);
 static unsigned int     ip6_default_advmss(const struct dst_entry *dst);
@@ -738,13 +736,8 @@ restart:
 
        if (!rt->rt6i_nexthop && !(rt->rt6i_flags & RTF_NONEXTHOP))
                nrt = rt6_alloc_cow(rt, &fl->fl6_dst, &fl->fl6_src);
-       else {
-#if CLONE_OFFLINK_ROUTE
+       else
                nrt = rt6_alloc_clone(rt, &fl->fl6_dst);
-#else
-               goto out2;
-#endif
-       }
 
        dst_release(&rt->dst);
        rt = nrt ? : net->ipv6.ip6_null_entry;
index 7e74023ea6e4381ae006eb672369f98fb899cc79..da87428681cccc9d955fdc80ee6f8bd4998356dd 100644 (file)
@@ -98,6 +98,10 @@ static int xfrm6_fill_dst(struct xfrm_dst *xdst, struct net_device *dev,
        if (!xdst->u.rt6.rt6i_idev)
                return -ENODEV;
 
+       xdst->u.rt6.rt6i_peer = rt->rt6i_peer;
+       if (rt->rt6i_peer)
+               atomic_inc(&rt->rt6i_peer->refcnt);
+
        /* Sheit... I remember I did this right. Apparently,
         * it was magically lost, so this code needs audit */
        xdst->u.rt6.rt6i_flags = rt->rt6i_flags & (RTF_ANYCAST |
@@ -216,6 +220,8 @@ static void xfrm6_dst_destroy(struct dst_entry *dst)
 
        if (likely(xdst->u.rt6.rt6i_idev))
                in6_dev_put(xdst->u.rt6.rt6i_idev);
+       if (likely(xdst->u.rt6.rt6i_peer))
+               inet_putpeer(xdst->u.rt6.rt6i_peer);
        xfrm_dst_destroy(xdst);
 }
 
index 5950e3abead9b49a7bfc4a8d17d77ce250d1b578..b64b42bc774be82ce40133237624a848d237289f 100644 (file)
@@ -2230,6 +2230,9 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw,
 
        sdata = vif_to_sdata(vif);
 
+       if (!ieee80211_sdata_running(sdata))
+               goto out;
+
        if (tim_offset)
                *tim_offset = 0;
        if (tim_length)
index c80d1c210c5d621454acf3388a63440c3fbfe740..5f63ec58942c10ac5088c6e6fca6e40463235a0b 100644 (file)
@@ -390,7 +390,6 @@ cbq_enqueue(struct sk_buff *skb, struct Qdisc *sch)
        ret = qdisc_enqueue(skb, cl->q);
        if (ret == NET_XMIT_SUCCESS) {
                sch->q.qlen++;
-               qdisc_bstats_update(sch, skb);
                cbq_mark_toplevel(q, cl);
                if (!cl->next_alive)
                        cbq_activate_class(cl);
@@ -649,7 +648,6 @@ static int cbq_reshape_fail(struct sk_buff *skb, struct Qdisc *child)
                ret = qdisc_enqueue(skb, cl->q);
                if (ret == NET_XMIT_SUCCESS) {
                        sch->q.qlen++;
-                       qdisc_bstats_update(sch, skb);
                        if (!cl->next_alive)
                                cbq_activate_class(cl);
                        return 0;
@@ -971,6 +969,7 @@ cbq_dequeue(struct Qdisc *sch)
 
                skb = cbq_dequeue_1(sch);
                if (skb) {
+                       qdisc_bstats_update(sch, skb);
                        sch->q.qlen--;
                        sch->flags &= ~TCQ_F_THROTTLED;
                        return skb;
index de55e642eafc2924bd2b6220aaac1d38e879954e..6b7fe4a84f138b903928a8c5f5f90f8fe3b855dc 100644 (file)
@@ -376,7 +376,6 @@ static int drr_enqueue(struct sk_buff *skb, struct Qdisc *sch)
        }
 
        bstats_update(&cl->bstats, skb);
-       qdisc_bstats_update(sch, skb);
 
        sch->q.qlen++;
        return err;
@@ -403,6 +402,7 @@ static struct sk_buff *drr_dequeue(struct Qdisc *sch)
                        skb = qdisc_dequeue_peeked(cl->qdisc);
                        if (cl->qdisc->q.qlen == 0)
                                list_del(&cl->alist);
+                       qdisc_bstats_update(sch, skb);
                        sch->q.qlen--;
                        return skb;
                }
index 60f4bdd4408e25888b4575bd9ab7b75441cab8c6..0f7bf3fdfea5a63683d86887e4d9fad99ff40a82 100644 (file)
@@ -260,7 +260,6 @@ static int dsmark_enqueue(struct sk_buff *skb, struct Qdisc *sch)
                return err;
        }
 
-       qdisc_bstats_update(sch, skb);
        sch->q.qlen++;
 
        return NET_XMIT_SUCCESS;
@@ -283,6 +282,7 @@ static struct sk_buff *dsmark_dequeue(struct Qdisc *sch)
        if (skb == NULL)
                return NULL;
 
+       qdisc_bstats_update(sch, skb);
        sch->q.qlen--;
 
        index = skb->tc_index & (p->indices - 1);
index aa4d6337e43cab4f3a094d6b2028be50afdcada5..d468b479aa937f410a665045eb4018bfc08de255 100644 (file)
@@ -46,17 +46,14 @@ static int pfifo_enqueue(struct sk_buff *skb, struct Qdisc* sch)
 
 static int pfifo_tail_enqueue(struct sk_buff *skb, struct Qdisc* sch)
 {
-       struct sk_buff *skb_head;
        struct fifo_sched_data *q = qdisc_priv(sch);
 
        if (likely(skb_queue_len(&sch->q) < q->limit))
                return qdisc_enqueue_tail(skb, sch);
 
        /* queue full, remove one skb to fulfill the limit */
-       skb_head = qdisc_dequeue_head(sch);
+       __qdisc_queue_drop_head(sch, &sch->q);
        sch->qstats.drops++;
-       kfree_skb(skb_head);
-
        qdisc_enqueue_tail(skb, sch);
 
        return NET_XMIT_CN;
index 2e45791d4f6cf7970d590fde138981254b359403..14a799de1c3535ed99c9af448080265fa406fe88 100644 (file)
@@ -1600,7 +1600,6 @@ hfsc_enqueue(struct sk_buff *skb, struct Qdisc *sch)
                set_active(cl, qdisc_pkt_len(skb));
 
        bstats_update(&cl->bstats, skb);
-       qdisc_bstats_update(sch, skb);
        sch->q.qlen++;
 
        return NET_XMIT_SUCCESS;
@@ -1666,6 +1665,7 @@ hfsc_dequeue(struct Qdisc *sch)
        }
 
        sch->flags &= ~TCQ_F_THROTTLED;
+       qdisc_bstats_update(sch, skb);
        sch->q.qlen--;
 
        return skb;
index 984c1b0c68369dd24b4837fd681126abc229ce92..fc12fe6f559796d11aaa8b4e769b26a6a28643e9 100644 (file)
@@ -574,7 +574,6 @@ static int htb_enqueue(struct sk_buff *skb, struct Qdisc *sch)
        }
 
        sch->q.qlen++;
-       qdisc_bstats_update(sch, skb);
        return NET_XMIT_SUCCESS;
 }
 
@@ -842,7 +841,7 @@ next:
 
 static struct sk_buff *htb_dequeue(struct Qdisc *sch)
 {
-       struct sk_buff *skb = NULL;
+       struct sk_buff *skb;
        struct htb_sched *q = qdisc_priv(sch);
        int level;
        psched_time_t next_event;
@@ -851,6 +850,8 @@ static struct sk_buff *htb_dequeue(struct Qdisc *sch)
        /* try to dequeue direct packets as high prio (!) to minimize cpu work */
        skb = __skb_dequeue(&q->direct_queue);
        if (skb != NULL) {
+ok:
+               qdisc_bstats_update(sch, skb);
                sch->flags &= ~TCQ_F_THROTTLED;
                sch->q.qlen--;
                return skb;
@@ -884,11 +885,8 @@ static struct sk_buff *htb_dequeue(struct Qdisc *sch)
                        int prio = ffz(m);
                        m |= 1 << prio;
                        skb = htb_dequeue_tree(q, prio, level);
-                       if (likely(skb != NULL)) {
-                               sch->q.qlen--;
-                               sch->flags &= ~TCQ_F_THROTTLED;
-                               goto fin;
-                       }
+                       if (likely(skb != NULL))
+                               goto ok;
                }
        }
        sch->qstats.overlimits++;
index 21f13da24763977eaea671c19a58357018f72899..436a2e75b322db524764a2483cd385e905aa4534 100644 (file)
@@ -83,7 +83,6 @@ multiq_enqueue(struct sk_buff *skb, struct Qdisc *sch)
 
        ret = qdisc_enqueue(skb, qdisc);
        if (ret == NET_XMIT_SUCCESS) {
-               qdisc_bstats_update(sch, skb);
                sch->q.qlen++;
                return NET_XMIT_SUCCESS;
        }
@@ -112,6 +111,7 @@ static struct sk_buff *multiq_dequeue(struct Qdisc *sch)
                        qdisc = q->queues[q->curband];
                        skb = qdisc->dequeue(qdisc);
                        if (skb) {
+                               qdisc_bstats_update(sch, skb);
                                sch->q.qlen--;
                                return skb;
                        }
index 1c4bce86347977ec93b1fa5a0fdcceaf34cfe257..6a3006b38dc55e65c4629a967a326eed684d7fd1 100644 (file)
@@ -240,7 +240,6 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch)
 
        if (likely(ret == NET_XMIT_SUCCESS)) {
                sch->q.qlen++;
-               qdisc_bstats_update(sch, skb);
        } else if (net_xmit_drop_count(ret)) {
                sch->qstats.drops++;
        }
@@ -289,6 +288,7 @@ static struct sk_buff *netem_dequeue(struct Qdisc *sch)
                                skb->tstamp.tv64 = 0;
 #endif
                        pr_debug("netem_dequeue: return skb=%p\n", skb);
+                       qdisc_bstats_update(sch, skb);
                        sch->q.qlen--;
                        return skb;
                }
@@ -476,7 +476,6 @@ static int tfifo_enqueue(struct sk_buff *nskb, struct Qdisc *sch)
                __skb_queue_after(list, skb, nskb);
 
                sch->qstats.backlog += qdisc_pkt_len(nskb);
-               qdisc_bstats_update(sch, nskb);
 
                return NET_XMIT_SUCCESS;
        }
index 966158d49dd105ce882ece6a6ccd6f072f5676ca..fbd710d619bf372535d21ef38c750c7e6e6c9cf0 100644 (file)
@@ -84,7 +84,6 @@ prio_enqueue(struct sk_buff *skb, struct Qdisc *sch)
 
        ret = qdisc_enqueue(skb, qdisc);
        if (ret == NET_XMIT_SUCCESS) {
-               qdisc_bstats_update(sch, skb);
                sch->q.qlen++;
                return NET_XMIT_SUCCESS;
        }
@@ -116,6 +115,7 @@ static struct sk_buff *prio_dequeue(struct Qdisc* sch)
                struct Qdisc *qdisc = q->queues[prio];
                struct sk_buff *skb = qdisc->dequeue(qdisc);
                if (skb) {
+                       qdisc_bstats_update(sch, skb);
                        sch->q.qlen--;
                        return skb;
                }
index a6009c5a2c97dbe446b162923fb997db00f00ee6..9f98dbd32d4c8176d6c940dd098f71fa0c00cb4d 100644 (file)
@@ -94,7 +94,6 @@ static int red_enqueue(struct sk_buff *skb, struct Qdisc* sch)
 
        ret = qdisc_enqueue(skb, child);
        if (likely(ret == NET_XMIT_SUCCESS)) {
-               qdisc_bstats_update(sch, skb);
                sch->q.qlen++;
        } else if (net_xmit_drop_count(ret)) {
                q->stats.pdrop++;
@@ -114,11 +113,13 @@ static struct sk_buff * red_dequeue(struct Qdisc* sch)
        struct Qdisc *child = q->qdisc;
 
        skb = child->dequeue(child);
-       if (skb)
+       if (skb) {
+               qdisc_bstats_update(sch, skb);
                sch->q.qlen--;
-       else if (!red_is_idling(&q->parms))
-               red_start_of_idle_period(&q->parms);
-
+       } else {
+               if (!red_is_idling(&q->parms))
+                       red_start_of_idle_period(&q->parms);
+       }
        return skb;
 }
 
index 239ec53a634dace6d29a3294c2a98e4c401539b8..edea8cefec6c9502e0a841e4bb4bd3ef11003495 100644 (file)
@@ -402,10 +402,8 @@ sfq_enqueue(struct sk_buff *skb, struct Qdisc *sch)
                q->tail = slot;
                slot->allot = q->scaled_quantum;
        }
-       if (++sch->q.qlen <= q->limit) {
-               qdisc_bstats_update(sch, skb);
+       if (++sch->q.qlen <= q->limit)
                return NET_XMIT_SUCCESS;
-       }
 
        sfq_drop(sch);
        return NET_XMIT_CN;
@@ -445,6 +443,7 @@ next_slot:
        }
        skb = slot_dequeue_head(slot);
        sfq_dec(q, a);
+       qdisc_bstats_update(sch, skb);
        sch->q.qlen--;
        sch->qstats.backlog -= qdisc_pkt_len(skb);
 
index 77565e721811f5cc5789a24987be3b0c04a6b371..e93165820c3f02ec4edc072b26b04dcdd4645ce0 100644 (file)
@@ -134,7 +134,6 @@ static int tbf_enqueue(struct sk_buff *skb, struct Qdisc* sch)
        }
 
        sch->q.qlen++;
-       qdisc_bstats_update(sch, skb);
        return NET_XMIT_SUCCESS;
 }
 
@@ -187,6 +186,7 @@ static struct sk_buff *tbf_dequeue(struct Qdisc* sch)
                        q->ptokens = ptoks;
                        sch->q.qlen--;
                        sch->flags &= ~TCQ_F_THROTTLED;
+                       qdisc_bstats_update(sch, skb);
                        return skb;
                }
 
index 84ce48eadff4952e2552306fae3197858af86c59..d84e7329660fb5f21e5e87d11fae435e27907a8b 100644 (file)
@@ -87,7 +87,6 @@ teql_enqueue(struct sk_buff *skb, struct Qdisc* sch)
 
        if (q->q.qlen < dev->tx_queue_len) {
                __skb_queue_tail(&q->q, skb);
-               qdisc_bstats_update(sch, skb);
                return NET_XMIT_SUCCESS;
        }
 
@@ -111,6 +110,8 @@ teql_dequeue(struct Qdisc* sch)
                        dat->m->slaves = sch;
                        netif_wake_queue(m);
                }
+       } else {
+               qdisc_bstats_update(sch, skb);
        }
        sch->q.qlen = dat->q.qlen + dat_queue->qdisc->q.qlen;
        return skb;
index 7bd3bbba4710d82ff658bd6de998543bca0609a7..d802e941d365e9b53bf7c6be04bd1555bc0d1144 100644 (file)
@@ -1609,9 +1609,7 @@ static struct svc_xprt *svc_bc_create_socket(struct svc_serv *serv,
  */
 static void svc_bc_sock_free(struct svc_xprt *xprt)
 {
-       if (xprt) {
-               kfree(xprt->xpt_bc_sid);
+       if (xprt)
                kfree(container_of(xprt, struct svc_sock, sk_xprt));
-       }
 }
 #endif /* CONFIG_NFS_V4_1 */
index 6c941050f5734d79354e657d0aec167d50923276..1bf090a885feed4791cab9b8a6947bde347f868e 100644 (file)
@@ -13,8 +13,8 @@ obj-y := \
        request_key_auth.o \
        user_defined.o
 
-obj-$(CONFIG_TRUSTED_KEYS) += trusted_defined.o
-obj-$(CONFIG_ENCRYPTED_KEYS) += encrypted_defined.o
+obj-$(CONFIG_TRUSTED_KEYS) += trusted.o
+obj-$(CONFIG_ENCRYPTED_KEYS) += encrypted.o
 obj-$(CONFIG_KEYS_COMPAT) += compat.o
 obj-$(CONFIG_PROC_FS) += proc.o
 obj-$(CONFIG_SYSCTL) += sysctl.o
similarity index 99%
rename from security/keys/encrypted_defined.c
rename to security/keys/encrypted.c
index 28791a65740ef493d5023d567d16c6922b97b499..9e7e4ce3fae820ec55cd64d9932ba1559372cb36 100644 (file)
@@ -30,7 +30,7 @@
 #include <crypto/sha.h>
 #include <crypto/aes.h>
 
-#include "encrypted_defined.h"
+#include "encrypted.h"
 
 static const char KEY_TRUSTED_PREFIX[] = "trusted:";
 static const char KEY_USER_PREFIX[] = "user:";
@@ -888,6 +888,7 @@ static int __init init_encrypted(void)
 out:
        encrypted_shash_release();
        return ret;
+
 }
 
 static void __exit cleanup_encrypted(void)
index edfa50dbd6f575c2b5018aac543c0117208b040e..a52aa7c88b41b48170791abd5eb06c839910dc84 100644 (file)
@@ -87,13 +87,13 @@ extern void key_type_put(struct key_type *ktype);
 extern int __key_link_begin(struct key *keyring,
                            const struct key_type *type,
                            const char *description,
-                           struct keyring_list **_prealloc);
+                           unsigned long *_prealloc);
 extern int __key_link_check_live_key(struct key *keyring, struct key *key);
 extern void __key_link(struct key *keyring, struct key *key,
-                      struct keyring_list **_prealloc);
+                      unsigned long *_prealloc);
 extern void __key_link_end(struct key *keyring,
                           struct key_type *type,
-                          struct keyring_list *prealloc);
+                          unsigned long prealloc);
 
 extern key_ref_t __keyring_search_one(key_ref_t keyring_ref,
                                      const struct key_type *type,
index 84d4eb568b087873d918dafa905b30576e850a73..1c2d43dc5107ecbe66bb8a5077876147ab785719 100644 (file)
@@ -415,7 +415,7 @@ static int __key_instantiate_and_link(struct key *key,
                                      size_t datalen,
                                      struct key *keyring,
                                      struct key *authkey,
-                                     struct keyring_list **_prealloc)
+                                     unsigned long *_prealloc)
 {
        int ret, awaken;
 
@@ -481,7 +481,7 @@ int key_instantiate_and_link(struct key *key,
                             struct key *keyring,
                             struct key *authkey)
 {
-       struct keyring_list *prealloc;
+       unsigned long prealloc;
        int ret;
 
        if (keyring) {
@@ -526,7 +526,7 @@ int key_negate_and_link(struct key *key,
                        struct key *keyring,
                        struct key *authkey)
 {
-       struct keyring_list *prealloc;
+       unsigned long prealloc;
        struct timespec now;
        int ret, awaken, link_ret = 0;
 
@@ -814,7 +814,7 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
                               key_perm_t perm,
                               unsigned long flags)
 {
-       struct keyring_list *prealloc;
+       unsigned long prealloc;
        const struct cred *cred = current_cred();
        struct key_type *ktype;
        struct key *keyring, *key = NULL;
index 92024ed12e0a22157bca33d69a465b5bede0d7b2..5620f084dede47a8887977fe10554b2f32f73b4e 100644 (file)
@@ -25,6 +25,8 @@
                (keyring)->payload.subscriptions,                       \
                rwsem_is_locked((struct rw_semaphore *)&(keyring)->sem)))
 
+#define KEY_LINK_FIXQUOTA 1UL
+
 /*
  * When plumbing the depths of the key tree, this sets a hard limit
  * set on how deep we're willing to go.
@@ -699,11 +701,11 @@ static void keyring_unlink_rcu_disposal(struct rcu_head *rcu)
  * Preallocate memory so that a key can be linked into to a keyring.
  */
 int __key_link_begin(struct key *keyring, const struct key_type *type,
-                    const char *description,
-                    struct keyring_list **_prealloc)
+                    const char *description, unsigned long *_prealloc)
        __acquires(&keyring->sem)
 {
        struct keyring_list *klist, *nklist;
+       unsigned long prealloc;
        unsigned max;
        size_t size;
        int loop, ret;
@@ -746,6 +748,7 @@ int __key_link_begin(struct key *keyring, const struct key_type *type,
 
                                /* note replacement slot */
                                klist->delkey = nklist->delkey = loop;
+                               prealloc = (unsigned long)nklist;
                                goto done;
                        }
                }
@@ -760,6 +763,7 @@ int __key_link_begin(struct key *keyring, const struct key_type *type,
        if (klist && klist->nkeys < klist->maxkeys) {
                /* there's sufficient slack space to append directly */
                nklist = NULL;
+               prealloc = KEY_LINK_FIXQUOTA;
        } else {
                /* grow the key list */
                max = 4;
@@ -794,8 +798,9 @@ int __key_link_begin(struct key *keyring, const struct key_type *type,
                nklist->keys[nklist->delkey] = NULL;
        }
 
+       prealloc = (unsigned long)nklist | KEY_LINK_FIXQUOTA;
 done:
-       *_prealloc = nklist;
+       *_prealloc = prealloc;
        kleave(" = 0");
        return 0;
 
@@ -836,12 +841,12 @@ int __key_link_check_live_key(struct key *keyring, struct key *key)
  * combination.
  */
 void __key_link(struct key *keyring, struct key *key,
-               struct keyring_list **_prealloc)
+               unsigned long *_prealloc)
 {
        struct keyring_list *klist, *nklist;
 
-       nklist = *_prealloc;
-       *_prealloc = NULL;
+       nklist = (struct keyring_list *)(*_prealloc & ~KEY_LINK_FIXQUOTA);
+       *_prealloc = 0;
 
        kenter("%d,%d,%p", keyring->serial, key->serial, nklist);
 
@@ -881,20 +886,22 @@ void __key_link(struct key *keyring, struct key *key,
  * Must be called with __key_link_begin() having being called.
  */
 void __key_link_end(struct key *keyring, struct key_type *type,
-                   struct keyring_list *prealloc)
+                   unsigned long prealloc)
        __releases(&keyring->sem)
 {
        BUG_ON(type == NULL);
        BUG_ON(type->name == NULL);
-       kenter("%d,%s,%p", keyring->serial, type->name, prealloc);
+       kenter("%d,%s,%lx", keyring->serial, type->name, prealloc);
 
        if (type == &key_type_keyring)
                up_write(&keyring_serialise_link_sem);
 
        if (prealloc) {
-               kfree(prealloc);
-               key_payload_reserve(keyring,
-                                   keyring->datalen - KEYQUOTA_LINK_BYTES);
+               if (prealloc & KEY_LINK_FIXQUOTA)
+                       key_payload_reserve(keyring,
+                                           keyring->datalen -
+                                           KEYQUOTA_LINK_BYTES);
+               kfree((struct keyring_list *)(prealloc & ~KEY_LINK_FIXQUOTA));
        }
        up_write(&keyring->sem);
 }
@@ -921,7 +928,7 @@ void __key_link_end(struct key *keyring, struct key_type *type,
  */
 int key_link(struct key *keyring, struct key *key)
 {
-       struct keyring_list *prealloc;
+       unsigned long prealloc;
        int ret;
 
        key_check(keyring);
index 9a7fb3914b27536a5ed047209659af920db310a3..a3dc0d460def505eb2dc053866f0cc457d448c9f 100644 (file)
@@ -352,8 +352,8 @@ static int construct_alloc_key(struct key_type *type,
                               struct key_user *user,
                               struct key **_key)
 {
-       struct keyring_list *prealloc;
        const struct cred *cred = current_cred();
+       unsigned long prealloc;
        struct key *key;
        key_ref_t key_ref;
        int ret;
similarity index 99%
rename from security/keys/trusted_defined.c
rename to security/keys/trusted.c
index 2836c6dc18a31247c839f50d46d1632c9a0e17d5..83fc92e297cd2257a26c6cbeeaca2b0588deac4f 100644 (file)
@@ -29,7 +29,7 @@
 #include <linux/tpm.h>
 #include <linux/tpm_command.h>
 
-#include "trusted_defined.h"
+#include "trusted.h"
 
 static const char hmac_alg[] = "hmac(sha1)";
 static const char hash_alg[] = "sha1";
@@ -1032,6 +1032,7 @@ static int trusted_update(struct key *key, const void *data, size_t datalen)
        ret = datablob_parse(datablob, new_p, new_o);
        if (ret != Opt_update) {
                ret = -EINVAL;
+               kfree(new_p);
                goto out;
        }
        /* copy old key values, and reseal with new pcrs */
index c3f845cbcd48b6019dae5c3ca7df2bf4317a3b01..a53373207fb459223e52fadd718e5a2cc2dbb666 100644 (file)
@@ -178,7 +178,7 @@ int cond_init_bool_indexes(struct policydb *p)
        p->bool_val_to_struct = (struct cond_bool_datum **)
                kmalloc(p->p_bools.nprim * sizeof(struct cond_bool_datum *), GFP_KERNEL);
        if (!p->bool_val_to_struct)
-               return -1;
+               return -ENOMEM;
        return 0;
 }
 
index be9de387283722607dc025fd52095c3fdf6f6883..57363562f0f886a455e900fdf59a56417b379127 100644 (file)
@@ -501,8 +501,8 @@ static int policydb_index(struct policydb *p)
        if (rc)
                goto out;
 
-       rc = -ENOMEM;
-       if (cond_init_bool_indexes(p))
+       rc = cond_init_bool_indexes(p);
+       if (rc)
                goto out;
 
        for (i = 0; i < SYM_NUM; i++) {
index 91acc9a243ec47dec8aabb6a67bcdd9b4f4aa671..24d3013c02312e7773ae1a864ed87e0ba1b571ee 100644 (file)
@@ -30,6 +30,8 @@
 
 #define DRIVER_NAME    "aaci-pl041"
 
+#define FRAME_PERIOD_US        21
+
 /*
  * PM support is not complete.  Turn it off.
  */
@@ -64,8 +66,8 @@ static void aaci_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
                            unsigned short val)
 {
        struct aaci *aaci = ac97->private_data;
+       int timeout;
        u32 v;
-       int timeout = 5000;
 
        if (ac97->num >= 4)
                return;
@@ -81,14 +83,17 @@ static void aaci_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
        writel(val << 4, aaci->base + AACI_SL2TX);
        writel(reg << 12, aaci->base + AACI_SL1TX);
 
-       /*
-        * Wait for the transmission of both slots to complete.
-        */
+       /* Initially, wait one frame period */
+       udelay(FRAME_PERIOD_US);
+
+       /* And then wait an additional eight frame periods for it to be sent */
+       timeout = FRAME_PERIOD_US * 8;
        do {
+               udelay(1);
                v = readl(aaci->base + AACI_SLFR);
        } while ((v & (SLFR_1TXB|SLFR_2TXB)) && --timeout);
 
-       if (!timeout)
+       if (v & (SLFR_1TXB|SLFR_2TXB))
                dev_err(&aaci->dev->dev,
                        "timeout waiting for write to complete\n");
 
@@ -101,9 +106,8 @@ static void aaci_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
 static unsigned short aaci_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
 {
        struct aaci *aaci = ac97->private_data;
+       int timeout, retries = 10;
        u32 v;
-       int timeout = 5000;
-       int retries = 10;
 
        if (ac97->num >= 4)
                return ~0;
@@ -117,35 +121,34 @@ static unsigned short aaci_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
         */
        writel((reg << 12) | (1 << 19), aaci->base + AACI_SL1TX);
 
-       /*
-        * Wait for the transmission to complete.
-        */
+       /* Initially, wait one frame period */
+       udelay(FRAME_PERIOD_US);
+
+       /* And then wait an additional eight frame periods for it to be sent */
+       timeout = FRAME_PERIOD_US * 8;
        do {
+               udelay(1);
                v = readl(aaci->base + AACI_SLFR);
        } while ((v & SLFR_1TXB) && --timeout);
 
-       if (!timeout) {
+       if (v & SLFR_1TXB) {
                dev_err(&aaci->dev->dev, "timeout on slot 1 TX busy\n");
                v = ~0;
                goto out;
        }
 
-       /*
-        * Give the AC'97 codec more than enough time
-        * to respond. (42us = ~2 frames at 48kHz.)
-        */
-       udelay(42);
+       /* Now wait for the response frame */
+       udelay(FRAME_PERIOD_US);
 
-       /*
-        * Wait for slot 2 to indicate data.
-        */
-       timeout = 5000;
+       /* And then wait an additional eight frame periods for data */
+       timeout = FRAME_PERIOD_US * 8;
        do {
+               udelay(1);
                cond_resched();
                v = readl(aaci->base + AACI_SLFR) & (SLFR_1RXV|SLFR_2RXV);
        } while ((v != (SLFR_1RXV|SLFR_2RXV)) && --timeout);
 
-       if (!timeout) {
+       if (v != (SLFR_1RXV|SLFR_2RXV)) {
                dev_err(&aaci->dev->dev, "timeout on RX valid\n");
                v = ~0;
                goto out;
@@ -179,6 +182,7 @@ aaci_chan_wait_ready(struct aaci_runtime *aacirun, unsigned long mask)
        int timeout = 5000;
 
        do {
+               udelay(1);
                val = readl(aacirun->base + AACI_SR);
        } while (val & mask && timeout--);
 }
@@ -874,7 +878,7 @@ static int __devinit aaci_probe_ac97(struct aaci *aaci)
         * Give the AC'97 codec more than enough time
         * to wake up. (42us = ~2 frames at 48kHz.)
         */
-       udelay(42);
+       udelay(FRAME_PERIOD_US * 2);
 
        ret = snd_ac97_bus(aaci->card, 0, &aaci_bus_ops, aaci, &ac97_bus);
        if (ret)
index 10c3a871a12d904bad20cff78dfce56e8373cb92..b310702c646e40ef59afedeed630dc320b5570be 100644 (file)
 #include <linux/dw_dmac.h>
 
 #include <mach/cpu.h>
-#include <mach/hardware.h>
 #include <mach/gpio.h>
 
+#ifdef CONFIG_ARCH_AT91
+#include <mach/hardware.h>
+#endif
+
 #include "ac97c.h"
 
 enum {
index 6117595fc075bba219b7b8a97cbd4de0e9154859..573594bf3225810366186751b70b5ccf9b962a02 100644 (file)
@@ -979,31 +979,25 @@ snd_azf3328_codec_setfmt(struct snd_azf3328_codec_data *codec,
 
        snd_azf3328_dbgcallenter();
        switch (bitrate) {
-#define AZF_FMT_XLATE(in_freq, out_bits) \
-       do { \
-               case AZF_FREQ_ ## in_freq: \
-                       freq = SOUNDFORMAT_FREQ_ ## out_bits; \
-                       break; \
-       } while (0);
-       AZF_FMT_XLATE(4000, SUSPECTED_4000)
-       AZF_FMT_XLATE(4800, SUSPECTED_4800)
-       /* the AZF3328 names it "5510" for some strange reason: */
-       AZF_FMT_XLATE(5512, 5510)
-       AZF_FMT_XLATE(6620, 6620)
-       AZF_FMT_XLATE(8000, 8000)
-       AZF_FMT_XLATE(9600, 9600)
-       AZF_FMT_XLATE(11025, 11025)
-       AZF_FMT_XLATE(13240, SUSPECTED_13240)
-       AZF_FMT_XLATE(16000, 16000)
-       AZF_FMT_XLATE(22050, 22050)
-       AZF_FMT_XLATE(32000, 32000)
+       case AZF_FREQ_4000:  freq = SOUNDFORMAT_FREQ_SUSPECTED_4000; break;
+       case AZF_FREQ_4800:  freq = SOUNDFORMAT_FREQ_SUSPECTED_4800; break;
+       case AZF_FREQ_5512:
+               /* the AZF3328 names it "5510" for some strange reason */
+                            freq = SOUNDFORMAT_FREQ_5510; break;
+       case AZF_FREQ_6620:  freq = SOUNDFORMAT_FREQ_6620; break;
+       case AZF_FREQ_8000:  freq = SOUNDFORMAT_FREQ_8000; break;
+       case AZF_FREQ_9600:  freq = SOUNDFORMAT_FREQ_9600; break;
+       case AZF_FREQ_11025: freq = SOUNDFORMAT_FREQ_11025; break;
+       case AZF_FREQ_13240: freq = SOUNDFORMAT_FREQ_SUSPECTED_13240; break;
+       case AZF_FREQ_16000: freq = SOUNDFORMAT_FREQ_16000; break;
+       case AZF_FREQ_22050: freq = SOUNDFORMAT_FREQ_22050; break;
+       case AZF_FREQ_32000: freq = SOUNDFORMAT_FREQ_32000; break;
        default:
                snd_printk(KERN_WARNING "unknown bitrate %d, assuming 44.1kHz!\n", bitrate);
                /* fall-through */
-       AZF_FMT_XLATE(44100, 44100)
-       AZF_FMT_XLATE(48000, 48000)
-       AZF_FMT_XLATE(66200, SUSPECTED_66200)
-#undef AZF_FMT_XLATE
+       case AZF_FREQ_44100: freq = SOUNDFORMAT_FREQ_44100; break;
+       case AZF_FREQ_48000: freq = SOUNDFORMAT_FREQ_48000; break;
+       case AZF_FREQ_66200: freq = SOUNDFORMAT_FREQ_SUSPECTED_66200; break;
        }
        /* val = 0xff07; 3m27.993s (65301Hz; -> 64000Hz???) hmm, 66120, 65967, 66123 */
        /* val = 0xff09; 17m15.098s (13123,478Hz; -> 12000Hz???) hmm, 13237.2Hz? */
index 4a663471dadc1e1e00d712bd5656577aeba56984..74b0560289c00630aca0ba952d8c80a0316e7fd8 100644 (file)
@@ -381,7 +381,7 @@ static void hdmi_show_short_audio_desc(struct cea_sad *a)
        snd_print_pcm_rates(a->rates, buf, sizeof(buf));
 
        if (a->format == AUDIO_CODING_TYPE_LPCM)
-               snd_print_pcm_bits(a->sample_bits, buf2 + 8, sizeof(buf2 - 8));
+               snd_print_pcm_bits(a->sample_bits, buf2 + 8, sizeof(buf2) - 8);
        else if (a->max_bitrate)
                snprintf(buf2, sizeof(buf2),
                                ", max bitrate = %d", a->max_bitrate);
index be4df4c6fd56bd585ad79b64ddabf6b9344d0f3c..2fa9ed99c32fef3637226677f168a7ebb8e9f0c8 100644 (file)
@@ -14954,9 +14954,11 @@ static struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
        SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
        SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
-       SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE),
-       SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE),
        SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE),
+       SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE),
+       SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE),
+       SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE),
+       SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE),
        SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
        SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
        {}
index 9f72d424969ca8ecede2b1301379cbed4959da3f..252719101c4214030c3ba8d664e68a87a02e2d8b 100644 (file)
@@ -392,7 +392,7 @@ static void dump_d1_registers(struct oxygen *chip,
        unsigned int i;
 
        snd_iprintf(buffer, "\nCS4398: 7?");
-       for (i = 2; i <= 8; ++i)
+       for (i = 2; i < 8; ++i)
                snd_iprintf(buffer, " %02x", data->cs4398_regs[i]);
        snd_iprintf(buffer, "\n");
        dump_cs4362a_registers(data, buffer);
index da2208e06b0d632299b61f1cc01a03fcf61bc911..5e4d499d8434ea7377e68419aa34c9b90f8bacd0 100644 (file)
@@ -129,7 +129,7 @@ static struct snd_soc_dai_link afeb9260_dai = {
        .cpu_dai_name = "atmel-ssc-dai.0",
        .codec_dai_name = "tlv320aic23-hifi",
        .platform_name = "atmel_pcm-audio",
-       .codec_name = "tlv320aic23-codec.0-0x1a",
+       .codec_name = "tlv320aic23-codec.0-001a",
        .init = afeb9260_tlv320aic23_init,
        .ops = &afeb9260_ops,
 };
index e902b24c185605f1eefcfa6fbf5f9e3d7b67d061..ad28663f5bbdf3fe2ee53dacc57cd5ca46cfdb7a 100644 (file)
@@ -119,7 +119,7 @@ static struct snd_soc_dai_link bf5xx_ssm2602_dai = {
        .cpu_dai_name = "bf5xx-i2s",
        .codec_dai_name = "ssm2602-hifi",
        .platform_name = "bf5xx-pcm-audio",
-       .codec_name = "ssm2602-codec.0-0x1b",
+       .codec_name = "ssm2602-codec.0-001b",
        .ops = &bf5xx_ssm2602_ops,
 };
 
index 247a6a99feb8f8cb4d8249e5e83764b897fba15f..3351f77607b39d55a446435a2208fef475927ab7 100644 (file)
@@ -2386,7 +2386,7 @@ static int wm8994_set_tristate(struct snd_soc_dai *codec_dai, int tristate)
        else
                val = 0;
 
-       return snd_soc_update_bits(codec, reg, mask, reg);
+       return snd_soc_update_bits(codec, reg, mask, val);
 }
 
 #define WM8994_RATES SNDRV_PCM_RATE_8000_96000
index 6045cbde492be5149ffd7c0b3002631a614ab15f..608c84c5aa8e6472e3bb43b20b279753f0a4a1c1 100644 (file)
@@ -1223,7 +1223,7 @@ static int wm8995_set_tristate(struct snd_soc_dai *codec_dai, int tristate)
        else
                val = 0;
 
-       return snd_soc_update_bits(codec, reg, mask, reg);
+       return snd_soc_update_bits(codec, reg, mask, val);
 }
 
 /* The size in bits of the FLL divide multiplied by 10
index c466982eed2336706b48c697c39fe53b191376fc..613df5db0b329d338f7f7eec6c16458ffbfe001b 100644 (file)
@@ -91,6 +91,7 @@ static void wait_for_dc_servo(struct snd_soc_codec *codec, unsigned int op)
 static void calibrate_dc_servo(struct snd_soc_codec *codec)
 {
        struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec);
+       s8 offset;
        u16 reg, reg_l, reg_r, dcs_cfg;
 
        /* If we're using a digital only path and have a previously
@@ -149,16 +150,14 @@ static void calibrate_dc_servo(struct snd_soc_codec *codec)
                        hubs->dcs_codes);
 
                /* HPOUT1L */
-               if (reg_l + hubs->dcs_codes > 0 &&
-                   reg_l + hubs->dcs_codes < 0xff)
-                       reg_l += hubs->dcs_codes;
-               dcs_cfg = reg_l << WM8993_DCS_DAC_WR_VAL_1_SHIFT;
+               offset = reg_l;
+               offset += hubs->dcs_codes;
+               dcs_cfg = (u8)offset << WM8993_DCS_DAC_WR_VAL_1_SHIFT;
 
                /* HPOUT1R */
-               if (reg_r + hubs->dcs_codes > 0 &&
-                   reg_r + hubs->dcs_codes < 0xff)
-                       reg_r += hubs->dcs_codes;
-               dcs_cfg |= reg_r;
+               offset = reg_r;
+               offset += hubs->dcs_codes;
+               dcs_cfg |= (u8)offset;
 
                dev_dbg(codec->dev, "DCS result: %x\n", dcs_cfg);
 
index 0c2d6bacc6817847a167541b789fbff7ada7cf91..b36f0b39b0908017cd2b0c716e0447b42d08b564 100644 (file)
@@ -223,7 +223,7 @@ static struct snd_soc_dai_link da8xx_evm_dai = {
        .stream_name = "AIC3X",
        .cpu_dai_name= "davinci-mcasp.0",
        .codec_dai_name = "tlv320aic3x-hifi",
-       .codec_name = "tlv320aic3x-codec.0-001a",
+       .codec_name = "tlv320aic3x-codec.1-0018",
        .platform_name = "davinci-pcm-audio",
        .init = evm_aic3x_init,
        .ops = &evm_ops,
index fc592f0d5fc7886f4786dfe735d1ee6353add878..784cff5f67e81a2c53a32ea5c69279619f716359 100644 (file)
@@ -307,10 +307,10 @@ static int corgi_wm8731_init(struct snd_soc_pcm_runtime *rtd)
 static struct snd_soc_dai_link corgi_dai = {
        .name = "WM8731",
        .stream_name = "WM8731",
-       .cpu_dai_name = "pxa-is2-dai",
+       .cpu_dai_name = "pxa2xx-i2s",
        .codec_dai_name = "wm8731-hifi",
        .platform_name = "pxa-pcm-audio",
-       .codec_name = "wm8731-codec-0.001a",
+       .codec_name = "wm8731-codec-0.001b",
        .init = corgi_wm8731_init,
        .ops = &corgi_ops,
 };
index 6298ee115e2717df4976be9451831f7024da9a60..a7d4999f9b24f4c9d202b9d21647760be483502a 100644 (file)
@@ -276,7 +276,7 @@ static struct snd_soc_dai_link poodle_dai = {
        .cpu_dai_name = "pxa2xx-i2s",
        .codec_dai_name = "wm8731-hifi",
        .platform_name = "pxa-pcm-audio",
-       .codec_name = "wm8731-codec.0-001a",
+       .codec_name = "wm8731-codec.0-001b",
        .init = poodle_wm8731_init,
        .ops = &poodle_ops,
 };
index c2acb69b957a9ca45a23adb0815494512ef589ef..8e1571350630ecfeacacdd93eaab5a6a76c485d8 100644 (file)
@@ -315,10 +315,10 @@ static int spitz_wm8750_init(struct snd_soc_pcm_runtime *rtd)
 static struct snd_soc_dai_link spitz_dai = {
        .name = "wm8750",
        .stream_name = "WM8750",
-       .cpu_dai_name = "pxa-is2",
+       .cpu_dai_name = "pxa2xx-i2s",
        .codec_dai_name = "wm8750-hifi",
        .platform_name = "pxa-pcm-audio",
-       .codec_name = "wm8750-codec.0-001a",
+       .codec_name = "wm8750-codec.0-001b",
        .init = spitz_wm8750_init,
        .ops = &spitz_ops,
 };
index 3eec610c10f95541a6fb59358e8ead3f67ce4b9f..0d0ae2b9eef699075fe1ba2039d373ad44145f0b 100644 (file)
@@ -397,11 +397,11 @@ static struct snd_soc_dai_link neo1973_gta02_dai[] = {
 { /* Hifi Playback - for similatious use with voice below */
        .name = "WM8753",
        .stream_name = "WM8753 HiFi",
-       .cpu_dai_name = "s3c24xx-i2s",
+       .cpu_dai_name = "s3c24xx-iis",
        .codec_dai_name = "wm8753-hifi",
        .init = neo1973_gta02_wm8753_init,
        .platform_name = "samsung-audio",
-       .codec_name = "wm8753-codec.0-0x1a",
+       .codec_name = "wm8753-codec.0-001a",
        .ops = &neo1973_gta02_hifi_ops,
 },
 { /* Voice via BT */
@@ -410,7 +410,7 @@ static struct snd_soc_dai_link neo1973_gta02_dai[] = {
        .cpu_dai_name = "bluetooth-dai",
        .codec_dai_name = "wm8753-voice",
        .ops = &neo1973_gta02_voice_ops,
-       .codec_name = "wm8753-codec.0-0x1a",
+       .codec_name = "wm8753-codec.0-001a",
        .platform_name = "samsung-audio",
 },
 };
index c7a24514beb58c65b349616a52e3733bf3ec6667..d20815d5ab2eea86317f50c664604f6437269d08 100644 (file)
@@ -559,9 +559,9 @@ static struct snd_soc_dai_link neo1973_dai[] = {
        .name = "WM8753",
        .stream_name = "WM8753 HiFi",
        .platform_name = "samsung-audio",
-       .cpu_dai_name = "s3c24xx-i2s",
+       .cpu_dai_name = "s3c24xx-iis",
        .codec_dai_name = "wm8753-hifi",
-       .codec_name = "wm8753-codec.0-0x1a",
+       .codec_name = "wm8753-codec.0-001a",
        .init = neo1973_wm8753_init,
        .ops = &neo1973_hifi_ops,
 },
@@ -571,7 +571,7 @@ static struct snd_soc_dai_link neo1973_dai[] = {
        .platform_name = "samsung-audio",
        .cpu_dai_name = "bluetooth-dai",
        .codec_dai_name = "wm8753-voice",
-       .codec_name = "wm8753-codec.0-0x1a",
+       .codec_name = "wm8753-codec.0-001a",
        .ops = &neo1973_voice_ops,
 },
 };
index bb4292e3596c877ab5d02b118c2f513bfd7fbcaa..08fcaaa66907b3c04cfde7a43327a37c5fca139e 100644 (file)
@@ -94,8 +94,8 @@ static int simtec_hermes_init(struct snd_soc_pcm_runtime *rtd)
 static struct snd_soc_dai_link simtec_dai_aic33 = {
        .name           = "tlv320aic33",
        .stream_name    = "TLV320AIC33",
-       .codec_name     = "tlv320aic3x-codec.0-0x1a",
-       .cpu_dai_name   = "s3c24xx-i2s",
+       .codec_name     = "tlv320aic3x-codec.0-001a",
+       .cpu_dai_name   = "s3c24xx-iis",
        .codec_dai_name = "tlv320aic3x-hifi",
        .platform_name  = "samsung-audio",
        .init           = simtec_hermes_init,
index fbba4e36772926f0891912a97066c06468a08d25..116e3e6701679778f1761b9474aa8d58dde30a0e 100644 (file)
@@ -85,8 +85,8 @@ static int simtec_tlv320aic23_init(struct snd_soc_pcm_runtime *rtd)
 static struct snd_soc_dai_link simtec_dai_aic23 = {
        .name           = "tlv320aic23",
        .stream_name    = "TLV320AIC23",
-       .codec_name     = "tlv320aic3x-codec.0-0x1a",
-       .cpu_dai_name   = "s3c24xx-i2s",
+       .codec_name     = "tlv320aic3x-codec.0-001a",
+       .cpu_dai_name   = "s3c24xx-iis",
        .codec_dai_name = "tlv320aic3x-hifi",
        .platform_name  = "samsung-audio",
        .init           = simtec_tlv320aic23_init,
index cdc8ecbcb8ef6838bc9b22a336b4eecf93c89aad..2c09e93dd566f2a66b46dc5886df5119a017bec1 100644 (file)
@@ -228,7 +228,7 @@ static struct snd_soc_dai_link s3c24xx_uda134x_dai_link = {
        .stream_name = "UDA134X",
        .codec_name = "uda134x-hifi",
        .codec_dai_name = "uda134x-hifi",
-       .cpu_dai_name = "s3c24xx-i2s",
+       .cpu_dai_name = "s3c24xx-iis",
        .ops = &s3c24xx_uda134x_ops,
        .platform_name  = "samsung-audio",
 };
index 2b5387d53ba5116db1f610ab28eaf656f962875a..7141c42e146920b887fe60ca1ba463bfbce90ea8 100644 (file)
@@ -204,13 +204,11 @@ EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wshadow
 EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Winit-self
 EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wpacked
 EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wredundant-decls
-EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wstack-protector
 EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wstrict-aliasing=3
 EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wswitch-default
 EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wswitch-enum
 EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wno-system-headers
 EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wundef
-EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wvolatile-register-var
 EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wwrite-strings
 EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wbad-function-cast
 EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wmissing-declarations
@@ -294,6 +292,13 @@ ifeq ($(call try-cc,$(SOURCE_HELLO),-Werror -fstack-protector-all),y)
        CFLAGS := $(CFLAGS) -fstack-protector-all
 endif
 
+ifeq ($(call try-cc,$(SOURCE_HELLO),-Werror -Wstack-protector),y)
+       CFLAGS := $(CFLAGS) -Wstack-protector
+endif
+
+ifeq ($(call try-cc,$(SOURCE_HELLO),-Werror -Wvolatile-register-var),y)
+       CFLAGS := $(CFLAGS) -Wvolatile-register-var
+endif
 
 ### --- END CONFIGURATION SECTION ---
 
index c056cdc0691258b159665ca3e8c74d2963543ccf..8879463807e4a06269e11e5594731ace4fd80ff2 100644 (file)
@@ -212,7 +212,7 @@ get_source_line(struct hist_entry *he, int len, const char *filename)
                        continue;
 
                offset = start + i;
-               sprintf(cmd, "addr2line -e %s %016llx", filename, offset);
+               sprintf(cmd, "addr2line -e %s %016" PRIx64, filename, offset);
                fp = popen(cmd, "r");
                if (!fp)
                        continue;
@@ -270,9 +270,9 @@ static void hist_entry__print_hits(struct hist_entry *self)
 
        for (offset = 0; offset < len; ++offset)
                if (h->ip[offset] != 0)
-                       printf("%*Lx: %Lu\n", BITS_PER_LONG / 2,
+                       printf("%*" PRIx64 ": %" PRIu64 "\n", BITS_PER_LONG / 2,
                               sym->start + offset, h->ip[offset]);
-       printf("%*s: %Lu\n", BITS_PER_LONG / 2, "h->sum", h->sum);
+       printf("%*s: %" PRIu64 "\n", BITS_PER_LONG / 2, "h->sum", h->sum);
 }
 
 static int hist_entry__tty_annotate(struct hist_entry *he)
index def7ddc2fd4fbc1b1c57795f4c10c519729b035d..d97256d6598044fab9e9d092e190fd70bdca4d93 100644 (file)
@@ -371,10 +371,10 @@ static void __print_result(struct rb_root *root, struct perf_session *session,
                        addr = data->ptr;
 
                if (sym != NULL)
-                       snprintf(buf, sizeof(buf), "%s+%Lx", sym->name,
+                       snprintf(buf, sizeof(buf), "%s+%" PRIx64 "", sym->name,
                                 addr - map->unmap_ip(map, sym->start));
                else
-                       snprintf(buf, sizeof(buf), "%#Lx", addr);
+                       snprintf(buf, sizeof(buf), "%#" PRIx64 "", addr);
                printf(" %-34s |", buf);
 
                printf(" %9llu/%-5lu | %9llu/%-5lu | %8lu | %8lu | %6.3f%%\n",
index b9c6e54329713e326d74da9b08164e562e521d03..2b36defc5d73dd447fbe20ffd2d357c77d2c2058 100644 (file)
@@ -782,9 +782,9 @@ static void print_result(void)
                pr_info("%10u ", st->nr_acquired);
                pr_info("%10u ", st->nr_contended);
 
-               pr_info("%15llu ", st->wait_time_total);
-               pr_info("%15llu ", st->wait_time_max);
-               pr_info("%15llu ", st->wait_time_min == ULLONG_MAX ?
+               pr_info("%15" PRIu64 " ", st->wait_time_total);
+               pr_info("%15" PRIu64 " ", st->wait_time_max);
+               pr_info("%15" PRIu64 " ", st->wait_time_min == ULLONG_MAX ?
                       0 : st->wait_time_min);
                pr_info("\n");
        }
index fcd29e8af29fe7cbb14e4563c906688f62e10f78..b2f729fdb317e36c9677c9b058818a7b7e1bc378 100644 (file)
@@ -817,7 +817,7 @@ static int __cmd_record(int argc, const char **argv)
         * Approximate RIP event size: 24 bytes.
         */
        fprintf(stderr,
-               "[ perf record: Captured and wrote %.3f MB %s (~%lld samples) ]\n",
+               "[ perf record: Captured and wrote %.3f MB %s (~%" PRIu64 " samples) ]\n",
                (double)bytes_written / 1024.0 / 1024.0,
                output_name,
                bytes_written / 24);
index 75183a4518e60d23db05e36e585fc178df731a19..c27e31f289e61b74f980923c88cd402ea2ab5f7c 100644 (file)
@@ -197,7 +197,7 @@ static int process_read_event(event_t *event, struct sample_data *sample __used,
                                           event->read.value);
        }
 
-       dump_printf(": %d %d %s %Lu\n", event->read.pid, event->read.tid,
+       dump_printf(": %d %d %s %" PRIu64 "\n", event->read.pid, event->read.tid,
                    attr ? __event_name(attr->type, attr->config) : "FAIL",
                    event->read.value);
 
index 29e7ffd8569068dea19b4385cc785a94ab9414fb..29acb894e035154432c708e1bf6ae7b7db5c2be1 100644 (file)
@@ -193,7 +193,7 @@ static void calibrate_run_measurement_overhead(void)
        }
        run_measurement_overhead = min_delta;
 
-       printf("run measurement overhead: %Ld nsecs\n", min_delta);
+       printf("run measurement overhead: %" PRIu64 " nsecs\n", min_delta);
 }
 
 static void calibrate_sleep_measurement_overhead(void)
@@ -211,7 +211,7 @@ static void calibrate_sleep_measurement_overhead(void)
        min_delta -= 10000;
        sleep_measurement_overhead = min_delta;
 
-       printf("sleep measurement overhead: %Ld nsecs\n", min_delta);
+       printf("sleep measurement overhead: %" PRIu64 " nsecs\n", min_delta);
 }
 
 static struct sched_atom *
@@ -617,13 +617,13 @@ static void test_calibrations(void)
        burn_nsecs(1e6);
        T1 = get_nsecs();
 
-       printf("the run test took %Ld nsecs\n", T1-T0);
+       printf("the run test took %" PRIu64 " nsecs\n", T1 - T0);
 
        T0 = get_nsecs();
        sleep_nsecs(1e6);
        T1 = get_nsecs();
 
-       printf("the sleep test took %Ld nsecs\n", T1-T0);
+       printf("the sleep test took %" PRIu64 " nsecs\n", T1 - T0);
 }
 
 #define FILL_FIELD(ptr, field, event, data)    \
@@ -816,10 +816,10 @@ replay_switch_event(struct trace_switch_event *switch_event,
                delta = 0;
 
        if (delta < 0)
-               die("hm, delta: %Ld < 0 ?\n", delta);
+               die("hm, delta: %" PRIu64 " < 0 ?\n", delta);
 
        if (verbose) {
-               printf(" ... switch from %s/%d to %s/%d [ran %Ld nsecs]\n",
+               printf(" ... switch from %s/%d to %s/%d [ran %" PRIu64 " nsecs]\n",
                        switch_event->prev_comm, switch_event->prev_pid,
                        switch_event->next_comm, switch_event->next_pid,
                        delta);
@@ -1048,7 +1048,7 @@ latency_switch_event(struct trace_switch_event *switch_event,
                delta = 0;
 
        if (delta < 0)
-               die("hm, delta: %Ld < 0 ?\n", delta);
+               die("hm, delta: %" PRIu64 " < 0 ?\n", delta);
 
 
        sched_out = perf_session__findnew(session, switch_event->prev_pid);
@@ -1221,7 +1221,7 @@ static void output_lat_thread(struct work_atoms *work_list)
 
        avg = work_list->total_lat / work_list->nb_atoms;
 
-       printf("|%11.3f ms |%9llu | avg:%9.3f ms | max:%9.3f ms | max at: %9.6f s\n",
+       printf("|%11.3f ms |%9" PRIu64 " | avg:%9.3f ms | max:%9.3f ms | max at: %9.6f s\n",
              (double)work_list->total_runtime / 1e6,
                 work_list->nb_atoms, (double)avg / 1e6,
                 (double)work_list->max_lat / 1e6,
@@ -1423,7 +1423,7 @@ map_switch_event(struct trace_switch_event *switch_event,
                delta = 0;
 
        if (delta < 0)
-               die("hm, delta: %Ld < 0 ?\n", delta);
+               die("hm, delta: %" PRIu64 " < 0 ?\n", delta);
 
 
        sched_out = perf_session__findnew(session, switch_event->prev_pid);
@@ -1713,7 +1713,7 @@ static void __cmd_lat(void)
        }
 
        printf(" -----------------------------------------------------------------------------------------\n");
-       printf("  TOTAL:                |%11.3f ms |%9Ld |\n",
+       printf("  TOTAL:                |%11.3f ms |%9" PRIu64 " |\n",
                (double)all_runtime/1e6, all_count);
 
        printf(" ---------------------------------------------------\n");
index 150a606002eb7b4eb281e69c9c8287eed1931077..b766c2a9ac975614a7507156b258519ec2a50d0a 100644 (file)
@@ -77,8 +77,8 @@ static int process_sample_event(event_t *event, struct sample_data *sample,
        if (session->sample_type & PERF_SAMPLE_RAW) {
                if (debug_mode) {
                        if (sample->time < last_timestamp) {
-                               pr_err("Samples misordered, previous: %llu "
-                                       "this: %llu\n", last_timestamp,
+                               pr_err("Samples misordered, previous: %" PRIu64
+                                       " this: %" PRIu64 "\n", last_timestamp,
                                        sample->time);
                                nr_unordered++;
                        }
@@ -126,7 +126,7 @@ static int __cmd_script(struct perf_session *session)
        ret = perf_session__process_events(session, &event_ops);
 
        if (debug_mode)
-               pr_err("Misordered timestamps: %llu\n", nr_unordered);
+               pr_err("Misordered timestamps: %" PRIu64 "\n", nr_unordered);
 
        return ret;
 }
index 0ff11d9b13be9cb5bfc9f86259dbd972be148d2e..a482a191a0ca3efac6cafe16ec1c827ba70a97f6 100644 (file)
@@ -206,8 +206,8 @@ static int read_counter_aggr(struct perf_evsel *counter)
                update_stats(&ps->res_stats[i], count[i]);
 
        if (verbose) {
-               fprintf(stderr, "%s: %Ld %Ld %Ld\n", event_name(counter),
-                               count[0], count[1], count[2]);
+               fprintf(stderr, "%s: %" PRIu64 " %" PRIu64 " %" PRIu64 "\n",
+                       event_name(counter), count[0], count[1], count[2]);
        }
 
        /*
index ed5696198d3df6905fe78f1fc623ccaa5a7f1f75..5dcdba653d7021d4ed0e2b04ad53443b034833c7 100644 (file)
@@ -146,7 +146,7 @@ next_pair:
                                if (llabs(skew) < page_size)
                                        continue;
 
-                               pr_debug("%#Lx: diff end addr for %s v: %#Lx k: %#Lx\n",
+                               pr_debug("%#" PRIx64 ": diff end addr for %s v: %#" PRIx64 " k: %#" PRIx64 "\n",
                                         sym->start, sym->name, sym->end, pair->end);
                        } else {
                                struct rb_node *nnd;
@@ -168,11 +168,11 @@ detour:
                                        goto detour;
                                }
 
-                               pr_debug("%#Lx: diff name v: %s k: %s\n",
+                               pr_debug("%#" PRIx64 ": diff name v: %s k: %s\n",
                                         sym->start, sym->name, pair->name);
                        }
                } else
-                       pr_debug("%#Lx: %s not on kallsyms\n", sym->start, sym->name);
+                       pr_debug("%#" PRIx64 ": %s not on kallsyms\n", sym->start, sym->name);
 
                err = -1;
        }
@@ -211,10 +211,10 @@ detour:
 
                if (pair->start == pos->start) {
                        pair->priv = 1;
-                       pr_info(" %Lx-%Lx %Lx %s in kallsyms as",
+                       pr_info(" %" PRIx64 "-%" PRIx64 " %" PRIx64 " %s in kallsyms as",
                                pos->start, pos->end, pos->pgoff, pos->dso->name);
                        if (pos->pgoff != pair->pgoff || pos->end != pair->end)
-                               pr_info(": \n*%Lx-%Lx %Lx",
+                               pr_info(": \n*%" PRIx64 "-%" PRIx64 " %" PRIx64 "",
                                        pair->start, pair->end, pair->pgoff);
                        pr_info(" %s\n", pair->dso->name);
                        pair->priv = 1;
@@ -307,7 +307,7 @@ static int test__open_syscall_event(void)
        }
 
        if (evsel->counts->cpu[0].val != nr_open_calls) {
-               pr_debug("perf_evsel__read_on_cpu: expected to intercept %d calls, got %Ld\n",
+               pr_debug("perf_evsel__read_on_cpu: expected to intercept %d calls, got %" PRIu64 "\n",
                         nr_open_calls, evsel->counts->cpu[0].val);
                goto out_close_fd;
        }
@@ -332,8 +332,7 @@ static int test__open_syscall_event_on_all_cpus(void)
        struct perf_evsel *evsel;
        struct perf_event_attr attr;
        unsigned int nr_open_calls = 111, i;
-       cpu_set_t *cpu_set;
-       size_t cpu_set_size;
+       cpu_set_t cpu_set;
        int id = trace_event__id("sys_enter_open");
 
        if (id < 0) {
@@ -353,13 +352,8 @@ static int test__open_syscall_event_on_all_cpus(void)
                return -1;
        }
 
-       cpu_set = CPU_ALLOC(cpus->nr);
 
-       if (cpu_set == NULL)
-               goto out_thread_map_delete;
-
-       cpu_set_size = CPU_ALLOC_SIZE(cpus->nr);
-       CPU_ZERO_S(cpu_set_size, cpu_set);
+       CPU_ZERO(&cpu_set);
 
        memset(&attr, 0, sizeof(attr));
        attr.type = PERF_TYPE_TRACEPOINT;
@@ -367,7 +361,7 @@ static int test__open_syscall_event_on_all_cpus(void)
        evsel = perf_evsel__new(&attr, 0);
        if (evsel == NULL) {
                pr_debug("perf_evsel__new\n");
-               goto out_cpu_free;
+               goto out_thread_map_delete;
        }
 
        if (perf_evsel__open(evsel, cpus, threads) < 0) {
@@ -379,14 +373,29 @@ static int test__open_syscall_event_on_all_cpus(void)
 
        for (cpu = 0; cpu < cpus->nr; ++cpu) {
                unsigned int ncalls = nr_open_calls + cpu;
+               /*
+                * XXX eventually lift this restriction in a way that
+                * keeps perf building on older glibc installations
+                * without CPU_ALLOC. 1024 cpus in 2010 still seems
+                * a reasonable upper limit tho :-)
+                */
+               if (cpus->map[cpu] >= CPU_SETSIZE) {
+                       pr_debug("Ignoring CPU %d\n", cpus->map[cpu]);
+                       continue;
+               }
 
-               CPU_SET(cpu, cpu_set);
-               sched_setaffinity(0, cpu_set_size, cpu_set);
+               CPU_SET(cpus->map[cpu], &cpu_set);
+               if (sched_setaffinity(0, sizeof(cpu_set), &cpu_set) < 0) {
+                       pr_debug("sched_setaffinity() failed on CPU %d: %s ",
+                                cpus->map[cpu],
+                                strerror(errno));
+                       goto out_close_fd;
+               }
                for (i = 0; i < ncalls; ++i) {
                        fd = open("/etc/passwd", O_RDONLY);
                        close(fd);
                }
-               CPU_CLR(cpucpu_set);
+               CPU_CLR(cpus->map[cpu], &cpu_set);
        }
 
        /*
@@ -402,6 +411,9 @@ static int test__open_syscall_event_on_all_cpus(void)
        for (cpu = 0; cpu < cpus->nr; ++cpu) {
                unsigned int expected;
 
+               if (cpus->map[cpu] >= CPU_SETSIZE)
+                       continue;
+
                if (perf_evsel__read_on_cpu(evsel, cpu, 0) < 0) {
                        pr_debug("perf_evsel__open_read_on_cpu\n");
                        goto out_close_fd;
@@ -409,8 +421,8 @@ static int test__open_syscall_event_on_all_cpus(void)
 
                expected = nr_open_calls + cpu;
                if (evsel->counts->cpu[cpu].val != expected) {
-                       pr_debug("perf_evsel__read_on_cpu: expected to intercept %d calls on cpu %d, got %Ld\n",
-                                expected, cpu, evsel->counts->cpu[cpu].val);
+                       pr_debug("perf_evsel__read_on_cpu: expected to intercept %d calls on cpu %d, got %" PRIu64 "\n",
+                                expected, cpus->map[cpu], evsel->counts->cpu[cpu].val);
                        goto out_close_fd;
                }
        }
@@ -420,8 +432,6 @@ out_close_fd:
        perf_evsel__close_fd(evsel, 1, threads->nr);
 out_evsel_delete:
        perf_evsel__delete(evsel);
-out_cpu_free:
-       CPU_FREE(cpu_set);
 out_thread_map_delete:
        thread_map__delete(threads);
        return err;
index 05344c6210ac7a8a3a1ebd00c4448a0807fbf807..b6998e055767fd68b9d70d2462d6776238fe4e85 100644 (file)
@@ -40,6 +40,7 @@
 #include <stdio.h>
 #include <termios.h>
 #include <unistd.h>
+#include <inttypes.h>
 
 #include <errno.h>
 #include <time.h>
@@ -214,7 +215,7 @@ static int parse_source(struct sym_entry *syme)
        len = sym->end - sym->start;
 
        sprintf(command,
-               "objdump --start-address=%#0*Lx --stop-address=%#0*Lx -dS %s",
+               "objdump --start-address=%#0*" PRIx64 " --stop-address=%#0*" PRIx64 " -dS %s",
                BITS_PER_LONG / 4, map__rip_2objdump(map, sym->start),
                BITS_PER_LONG / 4, map__rip_2objdump(map, sym->end), path);
 
@@ -308,7 +309,7 @@ static void lookup_sym_source(struct sym_entry *syme)
        struct source_line *line;
        char pattern[PATTERN_LEN + 1];
 
-       sprintf(pattern, "%0*Lx <", BITS_PER_LONG / 4,
+       sprintf(pattern, "%0*" PRIx64 " <", BITS_PER_LONG / 4,
                map__rip_2objdump(syme->map, symbol->start));
 
        pthread_mutex_lock(&syme->src->lock);
@@ -537,7 +538,7 @@ static void print_sym_table(void)
        if (nr_counters == 1 || !display_weighted) {
                struct perf_evsel *first;
                first = list_entry(evsel_list.next, struct perf_evsel, node);
-               printf("%Ld", first->attr.sample_period);
+               printf("%" PRIu64, (uint64_t)first->attr.sample_period);
                if (freq)
                        printf("Hz ");
                else
@@ -640,7 +641,7 @@ static void print_sym_table(void)
 
                percent_color_fprintf(stdout, "%4.1f%%", pcnt);
                if (verbose)
-                       printf(" %016llx", sym->start);
+                       printf(" %016" PRIx64, sym->start);
                printf(" %-*.*s", sym_width, sym_width, sym->name);
                printf(" %-*.*s\n", dso_width, dso_width,
                       dso_width >= syme->map->dso->long_name_len ?
index 2302ec051bb4f1b5171bb543b33284b29bf6f8b6..1478ab4ee2221e8dc5d44cd6677bf56e0d79205d 100644 (file)
@@ -459,7 +459,8 @@ int event__process_comm(event_t *self, struct sample_data *sample __used,
 int event__process_lost(event_t *self, struct sample_data *sample __used,
                        struct perf_session *session)
 {
-       dump_printf(": id:%Ld: lost:%Ld\n", self->lost.id, self->lost.lost);
+       dump_printf(": id:%" PRIu64 ": lost:%" PRIu64 "\n",
+                   self->lost.id, self->lost.lost);
        session->hists.stats.total_lost += self->lost.lost;
        return 0;
 }
@@ -575,7 +576,7 @@ int event__process_mmap(event_t *self, struct sample_data *sample __used,
        u8 cpumode = self->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
        int ret = 0;
 
-       dump_printf(" %d/%d: [%#Lx(%#Lx) @ %#Lx]: %s\n",
+       dump_printf(" %d/%d: [%#" PRIx64 "(%#" PRIx64 ") @ %#" PRIx64 "]: %s\n",
                        self->mmap.pid, self->mmap.tid, self->mmap.start,
                        self->mmap.len, self->mmap.pgoff, self->mmap.filename);
 
index 989fa2dee2fd2ae441d98921b9e69a56c4fe50e2..f6a929e74981e48844b0af2d21599ff5bb725ac3 100644 (file)
@@ -798,8 +798,8 @@ static int perf_file_section__process(struct perf_file_section *self,
                                      int feat, int fd)
 {
        if (lseek(fd, self->offset, SEEK_SET) == (off_t)-1) {
-               pr_debug("Failed to lseek to %Ld offset for feature %d, "
-                        "continuing...\n", self->offset, feat);
+               pr_debug("Failed to lseek to %" PRIu64 " offset for feature "
+                         "%d, continuing...\n", self->offset, feat);
                return 0;
        }
 
index c749ba6136a0ac33d7cdae8bf5b6604f1ee524af..32f4f1f2f6e4410c5e94d25fd8a7113d2676f493 100644 (file)
@@ -636,13 +636,13 @@ int hist_entry__snprintf(struct hist_entry *self, char *s, size_t size,
                        }
                }
        } else
-               ret = snprintf(s, size, sep ? "%lld" : "%12lld ", period);
+               ret = snprintf(s, size, sep ? "%" PRIu64 : "%12" PRIu64 " ", period);
 
        if (symbol_conf.show_nr_samples) {
                if (sep)
-                       ret += snprintf(s + ret, size - ret, "%c%lld", *sep, period);
+                       ret += snprintf(s + ret, size - ret, "%c%" PRIu64, *sep, period);
                else
-                       ret += snprintf(s + ret, size - ret, "%11lld", period);
+                       ret += snprintf(s + ret, size - ret, "%11" PRIu64, period);
        }
 
        if (pair_hists) {
@@ -971,7 +971,7 @@ int hist_entry__inc_addr_samples(struct hist_entry *self, u64 ip)
        sym_size = sym->end - sym->start;
        offset = ip - sym->start;
 
-       pr_debug3("%s: ip=%#Lx\n", __func__, self->ms.map->unmap_ip(self->ms.map, ip));
+       pr_debug3("%s: ip=%#" PRIx64 "\n", __func__, self->ms.map->unmap_ip(self->ms.map, ip));
 
        if (offset >= sym_size)
                return 0;
@@ -980,8 +980,9 @@ int hist_entry__inc_addr_samples(struct hist_entry *self, u64 ip)
        h->sum++;
        h->ip[offset]++;
 
-       pr_debug3("%#Lx %s: period++ [ip: %#Lx, %#Lx] => %Ld\n", self->ms.sym->start,
-                 self->ms.sym->name, ip, ip - self->ms.sym->start, h->ip[offset]);
+       pr_debug3("%#" PRIx64 " %s: period++ [ip: %#" PRIx64 ", %#" PRIx64
+                 "] => %" PRIu64 "\n", self->ms.sym->start, self->ms.sym->name,
+                 ip, ip - self->ms.sym->start, h->ip[offset]);
        return 0;
 }
 
@@ -1132,7 +1133,7 @@ fallback:
                goto out_free_filename;
        }
 
-       pr_debug("%s: filename=%s, sym=%s, start=%#Lx, end=%#Lx\n", __func__,
+       pr_debug("%s: filename=%s, sym=%s, start=%#" PRIx64 ", end=%#" PRIx64 "\n", __func__,
                 filename, sym->name, map->unmap_ip(map, sym->start),
                 map->unmap_ip(map, sym->end));
 
@@ -1142,7 +1143,7 @@ fallback:
                 dso, dso->long_name, sym, sym->name);
 
        snprintf(command, sizeof(command),
-                "objdump --start-address=0x%016Lx --stop-address=0x%016Lx -dS -C %s|grep -v %s|expand",
+                "objdump --start-address=0x%016" PRIx64 " --stop-address=0x%016" PRIx64 " -dS -C %s|grep -v %s|expand",
                 map__rip_2objdump(map, sym->start),
                 map__rip_2objdump(map, sym->end),
                 symfs_filename, filename);
index 8be0b968ca0bcfa44c95248e14e3878481887b21..305c8484f200c67eecff39369db873687bc8655c 100644 (file)
@@ -2,6 +2,7 @@
 #define _PERF_LINUX_BITOPS_H_
 
 #include <linux/kernel.h>
+#include <linux/compiler.h>
 #include <asm/hweight.h>
 
 #define BITS_PER_LONG __WORDSIZE
index 3a7eb6ec0eecf2c13dcd2ae098f56b4020d70301..a16ecab5229d3f73a99a2ae81d5dab6c24fdb0bb 100644 (file)
@@ -1,5 +1,6 @@
 #include "symbol.h"
 #include <errno.h>
+#include <inttypes.h>
 #include <limits.h>
 #include <stdlib.h>
 #include <string.h>
@@ -195,7 +196,7 @@ int map__overlap(struct map *l, struct map *r)
 
 size_t map__fprintf(struct map *self, FILE *fp)
 {
-       return fprintf(fp, " %Lx-%Lx %Lx %s\n",
+       return fprintf(fp, " %" PRIx64 "-%" PRIx64 " %" PRIx64 " %s\n",
                       self->start, self->end, self->pgoff, self->dso->name);
 }
 
index bc2732ee23eb3d1de29d56366ffb93afcea8aed9..135f69baf966d8a2a2525c6f9478958cf2932bf2 100644 (file)
@@ -279,7 +279,7 @@ const char *__event_name(int type, u64 config)
        static char buf[32];
 
        if (type == PERF_TYPE_RAW) {
-               sprintf(buf, "raw 0x%llx", config);
+               sprintf(buf, "raw 0x%" PRIx64, config);
                return buf;
        }
 
index b82cafb8377202462d16ef7ed36b8e546201c76b..458e3ecf17af9a829dd0cd82be8044221988af88 100644 (file)
@@ -23,7 +23,7 @@ struct tracepoint_path {
 };
 
 extern struct tracepoint_path *tracepoint_id_to_path(u64 config);
-extern bool have_tracepoints(struct list_head *evsel_list);
+extern bool have_tracepoints(struct list_head *evlist);
 
 extern int                     nr_counters;
 
index 128aaab0aedad86403a0c722211e4d57cb982d8d..6e29d9c9dcccb50f63adac097bc512b56fb3e28c 100644 (file)
@@ -172,7 +172,7 @@ static int kprobe_convert_to_perf_probe(struct probe_trace_point *tp,
        sym = __find_kernel_function_by_name(tp->symbol, &map);
        if (sym) {
                addr = map->unmap_ip(map, sym->start + tp->offset);
-               pr_debug("try to find %s+%ld@%llx\n", tp->symbol,
+               pr_debug("try to find %s+%ld@%" PRIx64 "\n", tp->symbol,
                         tp->offset, addr);
                ret = find_perf_probe_point((unsigned long)addr, pp);
        }
index 313dac2d94ce9f7c9e74ef0e8995383866427dbf..105f00bfd5552b1b878c21b72b86a80705592252 100644 (file)
@@ -652,10 +652,11 @@ static void callchain__printf(struct sample_data *sample)
 {
        unsigned int i;
 
-       printf("... chain: nr:%Lu\n", sample->callchain->nr);
+       printf("... chain: nr:%" PRIu64 "\n", sample->callchain->nr);
 
        for (i = 0; i < sample->callchain->nr; i++)
-               printf("..... %2d: %016Lx\n", i, sample->callchain->ips[i]);
+               printf("..... %2d: %016" PRIx64 "\n",
+                      i, sample->callchain->ips[i]);
 }
 
 static void perf_session__print_tstamp(struct perf_session *session,
@@ -672,7 +673,7 @@ static void perf_session__print_tstamp(struct perf_session *session,
                printf("%u ", sample->cpu);
 
        if (session->sample_type & PERF_SAMPLE_TIME)
-               printf("%Lu ", sample->time);
+               printf("%" PRIu64 " ", sample->time);
 }
 
 static void dump_event(struct perf_session *session, event_t *event,
@@ -681,16 +682,16 @@ static void dump_event(struct perf_session *session, event_t *event,
        if (!dump_trace)
                return;
 
-       printf("\n%#Lx [%#x]: event: %d\n", file_offset, event->header.size,
-              event->header.type);
+       printf("\n%#" PRIx64 " [%#x]: event: %d\n",
+              file_offset, event->header.size, event->header.type);
 
        trace_event(event);
 
        if (sample)
                perf_session__print_tstamp(session, event, sample);
 
-       printf("%#Lx [%#x]: PERF_RECORD_%s", file_offset, event->header.size,
-              event__get_event_name(event->header.type));
+       printf("%#" PRIx64 " [%#x]: PERF_RECORD_%s", file_offset,
+              event->header.size, event__get_event_name(event->header.type));
 }
 
 static void dump_sample(struct perf_session *session, event_t *event,
@@ -699,8 +700,9 @@ static void dump_sample(struct perf_session *session, event_t *event,
        if (!dump_trace)
                return;
 
-       printf("(IP, %d): %d/%d: %#Lx period: %Ld\n", event->header.misc,
-              sample->pid, sample->tid, sample->ip, sample->period);
+       printf("(IP, %d): %d/%d: %#" PRIx64 " period: %" PRIu64 "\n",
+              event->header.misc, sample->pid, sample->tid, sample->ip,
+              sample->period);
 
        if (session->sample_type & PERF_SAMPLE_CALLCHAIN)
                callchain__printf(sample);
@@ -843,8 +845,8 @@ static void perf_session__warn_about_errors(const struct perf_session *session,
 {
        if (ops->lost == event__process_lost &&
            session->hists.stats.total_lost != 0) {
-               ui__warning("Processed %Lu events and LOST %Lu!\n\n"
-                           "Check IO/CPU overload!\n\n",
+               ui__warning("Processed %" PRIu64 " events and LOST %" PRIu64
+                           "!\n\nCheck IO/CPU overload!\n\n",
                            session->hists.stats.total_period,
                            session->hists.stats.total_lost);
        }
@@ -918,7 +920,7 @@ more:
 
        if (size == 0 ||
            (skip = perf_session__process_event(self, &event, ops, head)) < 0) {
-               dump_printf("%#Lx [%#x]: skipping unknown header type: %d\n",
+               dump_printf("%#" PRIx64 " [%#x]: skipping unknown header type: %d\n",
                            head, event.header.size, event.header.type);
                /*
                 * assume we lost track of the stream, check alignment, and
@@ -1023,7 +1025,7 @@ more:
 
        if (size == 0 ||
            perf_session__process_event(session, event, ops, file_pos) < 0) {
-               dump_printf("%#Lx [%#x]: skipping unknown header type: %d\n",
+               dump_printf("%#" PRIx64 " [%#x]: skipping unknown header type: %d\n",
                            file_offset + head, event->header.size,
                            event->header.type);
                /*
index b3637db025a25cba486b824c45c8291a368d7881..fb737fe9be918d093a8f6b377e434c8c74ffe88a 100644 (file)
@@ -12,6 +12,7 @@
  * of the License.
  */
 
+#include <inttypes.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
@@ -43,11 +44,11 @@ static double cpu2y(int cpu)
        return cpu2slot(cpu) * SLOT_MULT;
 }
 
-static double time2pixels(u64 time)
+static double time2pixels(u64 __time)
 {
        double X;
 
-       X = 1.0 * svg_page_width * (time - first_time) / (last_time - first_time);
+       X = 1.0 * svg_page_width * (__time - first_time) / (last_time - first_time);
        return X;
 }
 
@@ -94,7 +95,7 @@ void open_svg(const char *filename, int cpus, int rows, u64 start, u64 end)
 
        total_height = (1 + rows + cpu2slot(cpus)) * SLOT_MULT;
        fprintf(svgfile, "<?xml version=\"1.0\" standalone=\"no\"?> \n");
-       fprintf(svgfile, "<svg width=\"%i\" height=\"%llu\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\">\n", svg_page_width, total_height);
+       fprintf(svgfile, "<svg width=\"%i\" height=\"%" PRIu64 "\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\">\n", svg_page_width, total_height);
 
        fprintf(svgfile, "<defs>\n  <style type=\"text/css\">\n    <![CDATA[\n");
 
@@ -483,7 +484,7 @@ void svg_time_grid(void)
                        color = 128;
                }
 
-               fprintf(svgfile, "<line x1=\"%4.8f\" y1=\"%4.2f\" x2=\"%4.8f\" y2=\"%llu\" style=\"stroke:rgb(%i,%i,%i);stroke-width:%1.3f\"/>\n",
+               fprintf(svgfile, "<line x1=\"%4.8f\" y1=\"%4.2f\" x2=\"%4.8f\" y2=\"%" PRIu64 "\" style=\"stroke:rgb(%i,%i,%i);stroke-width:%1.3f\"/>\n",
                        time2pixels(i), SLOT_MULT/2, time2pixels(i), total_height, color, color, color, thickness);
 
                i += 10000000;
index 15ccfba8cdf805111d56b1e7f3bf71431ef2c1e4..7821d0e6866f10e745762cc02c57237461ae0f8d 100644 (file)
@@ -11,6 +11,7 @@
 #include <sys/param.h>
 #include <fcntl.h>
 #include <unistd.h>
+#include <inttypes.h>
 #include "build-id.h"
 #include "debug.h"
 #include "symbol.h"
@@ -153,7 +154,7 @@ static struct symbol *symbol__new(u64 start, u64 len, u8 binding,
        self->binding = binding;
        self->namelen = namelen - 1;
 
-       pr_debug4("%s: %s %#Lx-%#Lx\n", __func__, name, start, self->end);
+       pr_debug4("%s: %s %#" PRIx64 "-%#" PRIx64 "\n", __func__, name, start, self->end);
 
        memcpy(self->name, name, namelen);
 
@@ -167,7 +168,7 @@ void symbol__delete(struct symbol *self)
 
 static size_t symbol__fprintf(struct symbol *self, FILE *fp)
 {
-       return fprintf(fp, " %llx-%llx %c %s\n",
+       return fprintf(fp, " %" PRIx64 "-%" PRIx64 " %c %s\n",
                       self->start, self->end,
                       self->binding == STB_GLOBAL ? 'g' :
                       self->binding == STB_LOCAL  ? 'l' : 'w',
@@ -1161,6 +1162,13 @@ static int dso__load_sym(struct dso *self, struct map *map, const char *name,
 
                section_name = elf_sec__name(&shdr, secstrs);
 
+               /* On ARM, symbols for thumb functions have 1 added to
+                * the symbol address as a flag - remove it */
+               if ((ehdr.e_machine == EM_ARM) &&
+                   (map->type == MAP__FUNCTION) &&
+                   (sym.st_value & 1))
+                       --sym.st_value;
+
                if (self->kernel != DSO_TYPE_USER || kmodule) {
                        char dso_name[PATH_MAX];
 
@@ -1208,8 +1216,8 @@ static int dso__load_sym(struct dso *self, struct map *map, const char *name,
                }
 
                if (curr_dso->adjust_symbols) {
-                       pr_debug4("%s: adjusting symbol: st_value: %#Lx "
-                                 "sh_addr: %#Lx sh_offset: %#Lx\n", __func__,
+                       pr_debug4("%s: adjusting symbol: st_value: %#" PRIx64 " "
+                                 "sh_addr: %#" PRIx64 " sh_offset: %#" PRIx64 "\n", __func__,
                                  (u64)sym.st_value, (u64)shdr.sh_addr,
                                  (u64)shdr.sh_offset);
                        sym.st_value -= shdr.sh_addr - shdr.sh_offset;
index 7d6b8331f8984764e23260eff33d4a13ea09317f..5f3689a3d0857be7431f8ed06eac3eb5e9707e18 100644 (file)
@@ -1,12 +1,14 @@
 #ifndef __PERF_TYPES_H
 #define __PERF_TYPES_H
 
+#include <stdint.h>
+
 /*
- * We define u64 as unsigned long long for every architecture
- * so that we can print it with %Lx without getting warnings.
+ * We define u64 as uint64_t for every architecture
+ * so that we can print it with "%"PRIx64 without getting warnings.
  */
-typedef unsigned long long u64;
-typedef signed long long   s64;
+typedef uint64_t          u64;
+typedef int64_t                   s64;
 typedef unsigned int      u32;
 typedef signed int        s32;
 typedef unsigned short    u16;
index ebda8c3fde9e6468ddbd84fc2df7e324ba862854..60c463c16028946541560f5f71e37617cfd69c9b 100644 (file)
@@ -350,7 +350,7 @@ static char *callchain_list__sym_name(struct callchain_list *self,
        if (self->ms.sym)
                return self->ms.sym->name;
 
-       snprintf(bf, bfsize, "%#Lx", self->ip);
+       snprintf(bf, bfsize, "%#" PRIx64, self->ip);
        return bf;
 }
 
index e35437dfa5b48aea8a0fb0237b2bf7ed7aaf90cd..e5158369106eee37234baf658d18cddec0539bb5 100644 (file)
@@ -1,5 +1,6 @@
 #include "../libslang.h"
 #include <elf.h>
+#include <inttypes.h>
 #include <sys/ttydefaults.h>
 #include <ctype.h>
 #include <string.h>
@@ -57,7 +58,7 @@ static void map_browser__write(struct ui_browser *self, void *nd, int row)
        int width;
 
        ui_browser__set_percent_color(self, 0, current_entry);
-       slsmg_printf("%*llx %*llx %c ",
+       slsmg_printf("%*" PRIx64 " %*" PRIx64 " %c ",
                     mb->addrlen, sym->start, mb->addrlen, sym->end,
                     sym->binding == STB_GLOBAL ? 'g' :
                     sym->binding == STB_LOCAL  ? 'l' : 'w');
@@ -150,6 +151,6 @@ int map__browse(struct map *self)
                ++mb.b.nr_entries;
        }
 
-       mb.addrlen = snprintf(tmp, sizeof(tmp), "%llx", maxaddr);
+       mb.addrlen = snprintf(tmp, sizeof(tmp), "%" PRIx64, maxaddr);
        return map_browser__run(&mb);
 }
index cfa55d686e3b9689fd6bfce089fb9d7207e85ab9..bdd33470b2356e2574c72719d4f40e620002b983 100644 (file)
@@ -150,7 +150,7 @@ static void perf_read_values__display_pretty(FILE *fp,
                if (width > tidwidth)
                        tidwidth = width;
                for (j = 0; j < values->counters; j++) {
-                       width = snprintf(NULL, 0, "%Lu", values->value[i][j]);
+                       width = snprintf(NULL, 0, "%" PRIu64, values->value[i][j]);
                        if (width > counterwidth[j])
                                counterwidth[j] = width;
                }
@@ -165,7 +165,7 @@ static void perf_read_values__display_pretty(FILE *fp,
                fprintf(fp, "  %*d  %*d", pidwidth, values->pid[i],
                        tidwidth, values->tid[i]);
                for (j = 0; j < values->counters; j++)
-                       fprintf(fp, "  %*Lu",
+                       fprintf(fp, "  %*" PRIu64,
                                counterwidth[j], values->value[i][j]);
                fprintf(fp, "\n");
        }
@@ -196,13 +196,13 @@ static void perf_read_values__display_raw(FILE *fp,
                width = strlen(values->countername[j]);
                if (width > namewidth)
                        namewidth = width;
-               width = snprintf(NULL, 0, "%llx", values->counterrawid[j]);
+               width = snprintf(NULL, 0, "%" PRIx64, values->counterrawid[j]);
                if (width > rawwidth)
                        rawwidth = width;
        }
        for (i = 0; i < values->threads; i++) {
                for (j = 0; j < values->counters; j++) {
-                       width = snprintf(NULL, 0, "%Lu", values->value[i][j]);
+                       width = snprintf(NULL, 0, "%" PRIu64, values->value[i][j]);
                        if (width > countwidth)
                                countwidth = width;
                }
@@ -214,7 +214,7 @@ static void perf_read_values__display_raw(FILE *fp,
                countwidth, "Count");
        for (i = 0; i < values->threads; i++)
                for (j = 0; j < values->counters; j++)
-                       fprintf(fp, "  %*d  %*d  %*s  %*llx  %*Lu\n",
+                       fprintf(fp, "  %*d  %*d  %*s  %*" PRIx64 "  %*" PRIu64,
                                pidwidth, values->pid[i],
                                tidwidth, values->tid[i],
                                namewidth, values->countername[j],