]> git.karo-electronics.de Git - mv-sheeva.git/commitdiff
Merge branch 'sched-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
authorLinus Torvalds <torvalds@linux-foundation.org>
Mon, 25 Aug 2008 18:26:02 +0000 (11:26 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 25 Aug 2008 18:26:02 +0000 (11:26 -0700)
* 'sched-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
  sched_clock: fix cpu_clock()

443 files changed:
Documentation/filesystems/ext4.txt
Documentation/ja_JP/HOWTO
Documentation/ja_JP/SubmitChecklist [new file with mode: 0644]
Documentation/kernel-parameters.txt
Documentation/lguest/lguest.c
Documentation/rfkill.txt
Documentation/scsi/ChangeLog.megaraid_sas
MAINTAINERS
Makefile
arch/arm/mach-integrator/impd1.c
arch/arm/mach-ixp4xx/fsg-setup.c
arch/arm/mach-pxa/clock.c
arch/arm/mach-pxa/clock.h
arch/arm/mach-pxa/eseries.c
arch/arm/mach-pxa/include/mach/irqs.h
arch/arm/mach-pxa/lubbock.c
arch/arm/mach-pxa/pxa25x.c
arch/arm/mach-pxa/pxa300.c
arch/arm/plat-omap/clock.c
arch/cris/arch-v32/kernel/fasttimer.c
arch/mn10300/kernel/mn10300-serial.c
arch/powerpc/kernel/crash_dump.c
arch/powerpc/kernel/ibmebus.c
arch/powerpc/kernel/vio.c
arch/powerpc/platforms/cell/spufs/run.c
arch/powerpc/platforms/cell/spufs/sched.c
arch/powerpc/sysdev/bestcomm/gen_bd.c
arch/s390/defconfig
arch/s390/include/asm/bitops.h
arch/s390/kernel/process.c
arch/s390/kernel/smp.c
arch/sh/boards/board-ap325rxa.c
arch/sh/boards/mach-migor/setup.c
arch/sh/boards/mach-sh7763rdp/setup.c
arch/sh/boards/mach-x3proto/setup.c
arch/sh/configs/sh7763rdp_defconfig
arch/sh/include/asm/flat.h
arch/sh/include/asm/migor.h
arch/sh/include/asm/sh_mobile_lcdc.h
arch/sh/include/cpu-sh3/cpu/cacheflush.h
arch/sh/kernel/cpu/sh4a/setup-sh7723.c
arch/sh/kernel/sh_ksyms_32.c
arch/sh/mm/Kconfig
arch/sh/mm/consistent.c
arch/x86/kernel/amd_iommu.c
arch/x86/kernel/cpu/addon_cpuid_features.c
arch/x86/kernel/cpu/cpufreq/powernow-k8.c
arch/x86/kernel/cpu/cpufreq/powernow-k8.h
arch/x86/kernel/cpu/cyrix.c
arch/x86/kernel/cpu/mtrr/generic.c
arch/x86/kernel/cpu/mtrr/main.c
arch/x86/kernel/genx2apic_uv_x.c
arch/x86/kernel/numaq_32.c
arch/x86/kernel/paravirt.c
arch/x86/kernel/pci-calgary_64.c
arch/x86/kernel/setup.c
arch/x86/kernel/smpboot.c
arch/x86/kernel/tlb_uv.c
arch/x86/kernel/tsc_sync.c
arch/x86/kvm/paging_tmpl.h
arch/x86/mach-rdc321x/platform.c
arch/x86/mm/init_64.c
arch/x86/mm/ioremap.c
arch/x86/mm/mmio-mod.c
arch/x86/mm/pageattr.c
arch/x86/mm/pat.c
arch/x86/oprofile/nmi_int.c
arch/x86/pci/irq.c
arch/x86/pci/legacy.c
arch/x86/pci/mmconfig-shared.c
block/genhd.c
crypto/authenc.c
drivers/ata/ahci.c
drivers/ata/ata_piix.c
drivers/ata/libata-core.c
drivers/ata/libata-eh.c
drivers/ata/pata_acpi.c
drivers/ata/pata_atiixp.c
drivers/ata/pata_cs5530.c
drivers/ata/pata_it821x.c
drivers/ata/pata_oldpiix.c
drivers/ata/pata_sc1200.c
drivers/ata/pata_via.c
drivers/ata/sata_mv.c
drivers/atm/adummy.c
drivers/base/class.c
drivers/base/core.c
drivers/base/driver.c
drivers/base/power/main.c
drivers/base/power/power.h
drivers/block/brd.c
drivers/block/nbd.c
drivers/bluetooth/Kconfig
drivers/bluetooth/bt3c_cs.c
drivers/bluetooth/btusb.c
drivers/bluetooth/hci_ldisc.c
drivers/bluetooth/hci_usb.c
drivers/bluetooth/hci_vhci.c
drivers/char/ipmi/ipmi_si_intf.c
drivers/char/random.c
drivers/char/xilinx_hwicap/buffer_icap.h
drivers/char/xilinx_hwicap/fifo_icap.h
drivers/char/xilinx_hwicap/xilinx_hwicap.h
drivers/edac/edac_core.h
drivers/firewire/Kconfig
drivers/i2c/busses/i2c-at91.c
drivers/ieee1394/nodemgr.c
drivers/ieee1394/nodemgr.h
drivers/ieee1394/sbp2.c
drivers/infiniband/hw/ehca/ehca_tools.h
drivers/infiniband/hw/ipath/ipath_fs.c
drivers/infiniband/hw/ipath/ipath_iba7220.c
drivers/infiniband/hw/ipath/ipath_ud.c
drivers/infiniband/hw/nes/nes.h
drivers/infiniband/ulp/ipoib/ipoib_main.c
drivers/infiniband/ulp/ipoib/ipoib_multicast.c
drivers/infiniband/ulp/iser/iser_verbs.c
drivers/input/evdev.c
drivers/input/keyboard/bf54x-keys.c
drivers/input/keyboard/gpio_keys.c
drivers/input/misc/cobalt_btns.c
drivers/input/mouse/gpio_mouse.c
drivers/input/tablet/gtco.c
drivers/input/touchscreen/mainstone-wm97xx.c
drivers/input/touchscreen/migor_ts.c
drivers/input/touchscreen/wm9705.c
drivers/input/touchscreen/wm9712.c
drivers/input/touchscreen/wm9713.c
drivers/input/touchscreen/wm97xx-core.c
drivers/lguest/lguest_device.c
drivers/mfd/asic3.c
drivers/misc/acer-wmi.c
drivers/misc/eeepc-laptop.c
drivers/misc/eeprom_93cx6.c
drivers/mtd/maps/amd76xrom.c
drivers/mtd/maps/ck804xrom.c
drivers/mtd/maps/esb2rom.c
drivers/mtd/nand/au1550nd.c
drivers/net/Kconfig
drivers/net/acenic.c
drivers/net/arm/ixp4xx_eth.c
drivers/net/atl1e/atl1e_ethtool.c
drivers/net/au1000_eth.c
drivers/net/ax88796.c
drivers/net/bnx2.c
drivers/net/bnx2x_link.c
drivers/net/bnx2x_main.c
drivers/net/cpmac.c
drivers/net/e1000e/defines.h
drivers/net/e1000e/e1000.h
drivers/net/e1000e/ethtool.c
drivers/net/e1000e/netdev.c
drivers/net/e1000e/param.c
drivers/net/gianfar.c
drivers/net/gianfar_sysfs.c
drivers/net/ipg.h
drivers/net/ixgbe/ixgbe_82598.c
drivers/net/ixgbe/ixgbe_main.c
drivers/net/ixgbe/ixgbe_type.h
drivers/net/loopback.c
drivers/net/myri10ge/myri10ge.c
drivers/net/ne.c
drivers/net/netxen/netxen_nic.h
drivers/net/netxen/netxen_nic_ethtool.c
drivers/net/netxen/netxen_nic_hdr.h
drivers/net/netxen/netxen_nic_hw.c
drivers/net/netxen/netxen_nic_init.c
drivers/net/netxen/netxen_nic_main.c
drivers/net/netxen/netxen_nic_phan_reg.h
drivers/net/ppp_mppe.c
drivers/net/pppol2tp.c
drivers/net/r6040.c
drivers/net/sh_eth.c
drivers/net/sky2.c
drivers/net/tehuti.h
drivers/net/tg3.c
drivers/net/tg3.h
drivers/net/tlan.c
drivers/net/tokenring/lanstreamer.c
drivers/net/tokenring/lanstreamer.h
drivers/net/tun.c
drivers/net/typhoon.c
drivers/net/usb/Kconfig
drivers/net/usb/hso.c
drivers/net/wireless/ath5k/base.c
drivers/net/wireless/ath9k/hw.c
drivers/net/wireless/b43/main.c
drivers/net/wireless/b43legacy/main.c
drivers/net/wireless/ipw2100.c
drivers/net/wireless/ipw2200.c
drivers/net/wireless/iwlwifi/iwl-3945-led.c
drivers/net/wireless/iwlwifi/iwl-3945.c
drivers/net/wireless/iwlwifi/iwl-4965.c
drivers/net/wireless/iwlwifi/iwl-5000.c
drivers/net/wireless/iwlwifi/iwl-agn.c
drivers/net/wireless/iwlwifi/iwl-core.c
drivers/net/wireless/iwlwifi/iwl-eeprom.c
drivers/net/wireless/iwlwifi/iwl-hcmd.c
drivers/net/wireless/iwlwifi/iwl-led.c
drivers/net/wireless/iwlwifi/iwl-power.c
drivers/net/wireless/iwlwifi/iwl-rfkill.c
drivers/net/wireless/iwlwifi/iwl-sta.c
drivers/net/wireless/iwlwifi/iwl-tx.c
drivers/net/wireless/iwlwifi/iwl3945-base.c
drivers/net/wireless/p54/p54common.c
drivers/net/wireless/p54/p54common.h
drivers/net/wireless/p54/p54usb.c
drivers/net/wireless/rt2x00/rt2x00queue.h
drivers/net/wireless/rt2x00/rt2x00usb.c
drivers/net/wireless/rtl8187_dev.c
drivers/of/device.c
drivers/pci/hotplug/acpi_pcihp.c
drivers/pci/hotplug/pciehp.h
drivers/pci/hotplug/pciehp_core.c
drivers/pci/hotplug/pciehp_hpc.c
drivers/pci/hotplug/shpchp_core.c
drivers/pci/pcie/aer/aerdrv_acpi.c
drivers/pci/probe.c
drivers/pci/search.c
drivers/pci/setup-bus.c
drivers/rtc/Kconfig
drivers/rtc/rtc-bfin.c
drivers/rtc/rtc-dev.c
drivers/rtc/rtc-ds1374.c
drivers/rtc/rtc-max6902.c
drivers/rtc/rtc-r9701.c
drivers/s390/block/dasd.c
drivers/s390/block/dasd_eckd.h
drivers/s390/block/dasd_eer.c
drivers/s390/block/dcssblk.c
drivers/s390/char/tape_char.c
drivers/s390/char/tape_std.c
drivers/s390/cio/ccwgroup.c
drivers/s390/cio/css.c
drivers/s390/cio/device.c
drivers/s390/cio/device.h
drivers/s390/cio/device_fsm.c
drivers/s390/cio/qdio_debug.h
drivers/s390/cio/qdio_main.c
drivers/s390/cio/qdio_setup.c
drivers/s390/cio/qdio_thinint.c
drivers/s390/net/ctcm_mpc.c
drivers/scsi/device_handler/scsi_dh_rdac.c
drivers/scsi/dpt/dpti_i2o.h
drivers/scsi/ibmvscsi/ibmvfc.c
drivers/scsi/ibmvscsi/ibmvfc.h
drivers/scsi/ibmvscsi/ibmvscsi.c
drivers/scsi/ips.c
drivers/scsi/ips.h
drivers/scsi/lpfc/lpfc_debugfs.c
drivers/scsi/megaraid/megaraid_sas.c
drivers/scsi/megaraid/megaraid_sas.h
drivers/scsi/nsp32.c
drivers/scsi/nsp32.h
drivers/scsi/pcmcia/nsp_cs.c
drivers/scsi/qla2xxx/qla_attr.c
drivers/scsi/qla2xxx/qla_def.h
drivers/scsi/qla2xxx/qla_init.c
drivers/scsi/qla2xxx/qla_isr.c
drivers/scsi/qla2xxx/qla_mbx.c
drivers/scsi/qla2xxx/qla_mid.c
drivers/scsi/qla2xxx/qla_os.c
drivers/scsi/qla2xxx/qla_version.h
drivers/ssb/main.c
drivers/uio/Kconfig
drivers/uio/Makefile
drivers/uio/uio_pdrv.c
drivers/uio/uio_pdrv_genirq.c [new file with mode: 0644]
drivers/usb/atm/ueagle-atm.c
drivers/usb/class/cdc-acm.c
drivers/usb/core/driver.c
drivers/usb/core/hcd.c
drivers/usb/core/hcd.h
drivers/usb/core/hub.c
drivers/usb/core/urb.c
drivers/usb/core/usb.c
drivers/usb/core/usb.h
drivers/usb/gadget/amd5536udc.c
drivers/usb/gadget/pxa27x_udc.c
drivers/usb/gadget/s3c2410_udc.c
drivers/usb/host/isp1760-hcd.c
drivers/usb/host/ohci-at91.c
drivers/usb/host/ohci-au1xxx.c
drivers/usb/host/ohci-ep93xx.c
drivers/usb/host/ohci-hub.c
drivers/usb/host/ohci-lh7a404.c
drivers/usb/host/ohci-omap.c
drivers/usb/host/ohci-pci.c
drivers/usb/host/ohci-pnx4008.c
drivers/usb/host/ohci-pnx8550.c
drivers/usb/host/ohci-ppc-of.c
drivers/usb/host/ohci-ppc-soc.c
drivers/usb/host/ohci-ps3.c
drivers/usb/host/ohci-pxa27x.c
drivers/usb/host/ohci-s3c2410.c
drivers/usb/host/ohci-sa1111.c
drivers/usb/host/ohci-sh.c
drivers/usb/host/ohci-sm501.c
drivers/usb/host/ohci-ssb.c
drivers/usb/host/u132-hcd.c
drivers/usb/misc/iowarrior.c
drivers/usb/misc/sisusbvga/sisusb.c
drivers/usb/musb/Kconfig
drivers/usb/musb/Makefile
drivers/usb/musb/musb_core.c
drivers/usb/musb/musb_core.h
drivers/usb/musb/musb_debug.h
drivers/usb/musb/musb_gadget_ep0.c
drivers/usb/musb/musb_procfs.c [deleted file]
drivers/usb/serial/garmin_gps.c
drivers/usb/serial/option.c
drivers/video/arkfb.c
drivers/video/bf54x-lq043fb.c
drivers/video/fb_defio.c
drivers/video/fbmem.c
drivers/video/pm2fb.c
drivers/video/s3fb.c
drivers/video/sh_mobile_lcdcfb.c
drivers/video/vermilion/vermilion.h
drivers/video/vt8623fb.c
drivers/video/xilinxfb.c
drivers/virtio/virtio_balloon.c
drivers/xen/manage.c
fs/binfmt_flat.c
fs/binfmt_misc.c
fs/cramfs/inode.c
fs/ext4/balloc.c
fs/ext4/dir.c
fs/ext4/ext4.h
fs/ext4/ext4_extents.h
fs/ext4/ext4_jbd2.h
fs/ext4/extents.c
fs/ext4/ialloc.c
fs/ext4/inode.c
fs/ext4/mballoc.c
fs/ext4/migrate.c
fs/ext4/resize.c
fs/ext4/super.c
fs/fat/inode.c
fs/ioprio.c
fs/jffs2/jffs2_fs_i.h
fs/proc/nommu.c
fs/proc/task_mmu.c
fs/xfs/xfs_dmapi.h
include/asm-cris/Kbuild
include/asm-frv/io.h
include/asm-mn10300/io.h
include/asm-x86/genapic_32.h
include/asm-x86/genapic_64.h
include/asm-x86/irq_vectors.h
include/asm-x86/kvm_host.h
include/asm-x86/uv/uv_bau.h
include/asm-x86/xen/hypervisor.h
include/linux/device.h
include/linux/exportfs.h
include/linux/fb.h
include/linux/fs_uart_pd.h
include/linux/if_tun.h
include/linux/kvm.h
include/linux/libata.h
include/linux/pci-acpi.h
include/linux/pci_ids.h
include/linux/pid.h
include/linux/rmap.h
include/linux/skbuff.h
include/linux/stop_machine.h
include/linux/tick.h
include/linux/usb.h
include/net/addrconf.h
include/net/ip6_route.h
include/net/mac80211.h
include/net/pkt_sched.h
include/net/sch_generic.h
include/scsi/scsi_device.h
kernel/module.c
kernel/nsproxy.c
kernel/power/swap.c
kernel/rcupdate.c
kernel/signal.c
kernel/sys.c
kernel/time/tick-sched.c
kernel/user_namespace.c
kernel/utsname.c
kernel/utsname_sysctl.c
lib/kobject.c
mm/bootmem.c
mm/filemap_xip.c
mm/mm_init.c
mm/rmap.c
mm/swap_state.c
net/bluetooth/af_bluetooth.c
net/bluetooth/bnep/core.c
net/bluetooth/hci_sysfs.c
net/bluetooth/l2cap.c
net/bluetooth/rfcomm/core.c
net/bluetooth/sco.c
net/bridge/br_device.c
net/core/datagram.c
net/core/dev.c
net/core/gen_estimator.c
net/core/skbuff.c
net/dccp/input.c
net/ipv4/icmp.c
net/ipv4/netfilter/ipt_addrtype.c
net/ipv4/netfilter/nf_nat_proto_common.c
net/ipv4/route.c
net/ipv6/addrconf.c
net/ipv6/fib6_rules.c
net/ipv6/icmp.c
net/ipv6/ip6_fib.c
net/ipv6/ip6_output.c
net/ipv6/ipv6_sockglue.c
net/ipv6/ndisc.c
net/ipv6/route.c
net/ipv6/xfrm6_policy.c
net/mac80211/mlme.c
net/netfilter/nf_conntrack_netlink.c
net/rfkill/rfkill.c
net/sched/cls_api.c
net/sched/sch_api.c
net/sched/sch_cbq.c
net/sched/sch_generic.c
net/sched/sch_htb.c
net/sched/sch_prio.c
net/sched/sch_tbf.c
net/sctp/endpointola.c
net/sctp/ipv6.c
net/sctp/socket.c
scripts/mod/file2alias.c
sound/mips/au1x00.c
sound/pci/ca0106/ca0106_main.c
sound/pci/hda/hda_intel.c
sound/pci/hda/patch_realtek.c
sound/soc/at91/eti_b1_wm8731.c
sound/soc/codecs/ak4535.c
sound/soc/codecs/tlv320aic3x.c
sound/soc/codecs/uda1380.c
sound/soc/codecs/wm8510.c
sound/soc/codecs/wm8731.c
sound/soc/codecs/wm8750.c
sound/soc/codecs/wm8753.c
sound/soc/codecs/wm8990.c
sound/soc/codecs/wm9712.c

index 80e193d82e2e10415cc828124cec296855398aeb..0d5394920a31c146ef85cc4df64107e37a6ae386 100644 (file)
@@ -26,6 +26,12 @@ Mailing list: linux-ext4@vger.kernel.org
 
     git://git.kernel.org/pub/scm/fs/ext2/e2fsprogs.git
 
+  - Note that it is highly important to install the mke2fs.conf file
+    that comes with the e2fsprogs 1.41.x sources in /etc/mke2fs.conf. If
+    you have edited the /etc/mke2fs.conf file installed on your system,
+    you will need to merge your changes with the version from e2fsprogs
+    1.41.x.
+
   - Create a new filesystem using the ext4dev filesystem type:
 
        # mke2fs -t ext4dev /dev/hda1
index 488c77fa3aae138c41168408d983791819f5a7fb..0775cf4798b22f89d484f171f3a79726712ed695 100644 (file)
@@ -11,14 +11,14 @@ for non English (read: Japanese) speakers and is not intended as a
 fork. So if you have any comments or updates for this file, please try
 to update the original English file first.
 
-Last Updated: 2007/11/16
+Last Updated: 2008/08/21
 ==================================
 これは、
-linux-2.6.24/Documentation/HOWTO
+linux-2.6.27/Documentation/HOWTO
 の和訳です。
 
 翻訳団体: JF プロジェクト < http://www.linux.or.jp/JF/ >
-翻訳日: 2007/11/10
+翻訳日: 2008/8/5
 翻訳者: Tsugikazu Shibata <tshibata at ab dot jp dot nec dot com>
 校正者: 松倉さん <nbh--mats at nifty dot com>
          小林 雅典さん (Masanori Kobayasi) <zap03216 at nifty dot ne dot jp>
@@ -287,13 +287,15 @@ Linux カーネルの開発プロセスは現在幾つかの異なるメイン
     に安定した状態にあると判断したときにリリースされます。目標は毎週新
     しい -rc カーネルをリリースすることです。
 
-   - 以下の URL で各 -rc リリースに存在する既知の後戻り問題のリスト
-     が追跡されます-
-     http://kernelnewbies.org/known_regressions
-
   - このプロセスはカーネルが 「準備ができた」と考えられるまで継続しま
     す。このプロセスはだいたい 6週間継続します。
 
+  - 各リリースでの既知の後戻り問題(regression: このリリースの中で新規
+    に作り込まれた問題を指す) はその都度 Linux-kernel メーリングリスト
+    に投稿されます。ゴールとしては、カーネルが 「準備ができた」と宣言
+    する前にこのリストの長さをゼロに減らすことですが、現実には、数個の
+    後戻り問題がリリース時にたびたび残ってしまいます。
+
 Andrew Morton が Linux-kernel メーリングリストにカーネルリリースについ
 て書いたことをここで言っておくことは価値があります-
   「カーネルがいつリリースされるかは誰も知りません。なぜなら、これは現
@@ -303,18 +305,20 @@ Andrew Morton が Linux-kernel メーリングリストにカーネルリリー
 2.6.x.y -stable カーネルツリー
 ---------------------------
 
-バージョンに4つ目の数字がついたカーネルは -stable カーネルです。これに
\81¯ã\80\812.6.x ã\82«ã\83¼ã\83\8dã\83«ã\81§è¦\8bã\81¤ã\81\8bã\81£ã\81\9fã\82»ã\82­ã\83¥ã\83ªã\83\86ã\82£å\95\8fé¡\8cã\82\84é\87\8d大ã\81ªå¾\8cæ\88»ã\82\8aã\81«å¯¾ã\81\99ã\82\8bæ¯\94
-較的小さい重要な修正が含まれます。
+バージョン番号が4つの数字に分かれているカーネルは -stable カーネルです。
\81\93ã\82\8cã\81«ã\81¯ã\80\812.6.x ã\82«ã\83¼ã\83\8dã\83«ã\81§è¦\8bã\81¤ã\81\8bã\81£ã\81\9fã\82»ã\82­ã\83¥ã\83ªã\83\86ã\82£å\95\8fé¡\8cã\82\84é\87\8d大ã\81ªå¾\8cæ\88»ã\82\8aã\81«å¯¾
+する比較的小さい重要な修正が含まれます。
 
 これは、開発/実験的バージョンのテストに協力することに興味が無く、
 最新の安定したカーネルを使いたいユーザに推奨するブランチです。
 
-もし、2.6.x.y カーネルが存在しない場合には、番号が一番大きい 2.6.x
-最新の安定版カーネルです。
+もし、2.6.x.y カーネルが存在しない場合には、番号が一番大きい 2.6.x が
+最新の安定版カーネルです。
 
-2.6.x.y は "stable" チーム <stable@kernel.org> でメンテされており、だ
-いたい隔週でリリースされています。
+2.6.x.y は "stable" チーム <stable@kernel.org> でメンテされており、必
+要に応じてリリースされます。通常のリリース期間は 2週間毎ですが、差し迫っ
+た問題がなければもう少し長くなることもあります。セキュリティ関連の問題
+の場合はこれに対してだいたいの場合、すぐにリリースがされます。
 
 カーネルツリーに入っている、Documentation/stable_kernel_rules.txt ファ
 イルにはどのような種類の変更が -stable ツリーに受け入れ可能か、またリ
@@ -341,7 +345,9 @@ linux-kernel メーリングリストで収集された多数のパッチと同
 メインラインへ入れるように Linus にプッシュします。
 
 メインカーネルツリーに含めるために Linus に送る前に、すべての新しいパッ
-チが -mm ツリーでテストされることが強く推奨されます。
+チが -mm ツリーでテストされることが強く推奨されています。マージウィン
+ドウが開く前に -mm ツリーに現れなかったパッチはメインラインにマージさ
+れることは困難になります。
 
 これらのカーネルは安定して動作すべきシステムとして使うのには適切ではあ
 りませんし、カーネルブランチの中でももっとも動作にリスクが高いものです。
@@ -395,13 +401,15 @@ linux-kernel メーリングリストで収集された多数のパッチと同
     - pcmcia, Dominik Brodowski <linux@dominikbrodowski.net>
        git.kernel.org:/pub/scm/linux/kernel/git/brodo/pcmcia-2.6.git
 
-    - SCSI, James Bottomley <James.Bottomley@SteelEye.com>
+    - SCSI, James Bottomley <James.Bottomley@hansenpartnership.com>
        git.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6.git
 
+    - x86, Ingo Molnar <mingo@elte.hu>
+       git://git.kernel.org/pub/scm/linux/kernel/git/x86/linux-2.6-x86.git
+
   quilt ツリー-
-    - USB, PCI ドライバコアと I2C, Greg Kroah-Hartman <gregkh@suse.de>
+    - USB, ドライバコアと I2C, Greg Kroah-Hartman <gregkh@suse.de>
        kernel.org/pub/linux/kernel/people/gregkh/gregkh-2.6/
-    - x86-64 と i386 の仲間 Andi Kleen <ak@suse.de>
 
   その他のカーネルツリーは http://git.kernel.org/ と MAINTAINERS ファ
   イルに一覧表があります。
@@ -412,13 +420,32 @@ linux-kernel メーリングリストで収集された多数のパッチと同
 bugzilla.kernel.org は Linux カーネル開発者がカーネルのバグを追跡する
 場所です。ユーザは見つけたバグの全てをこのツールで報告すべきです。
 どう kernel bugzilla を使うかの詳細は、以下を参照してください-
-       http://test.kernel.org/bugzilla/faq.html
-
+       http://bugzilla.kernel.org/page.cgi?id=faq.html
 メインカーネルソースディレクトリにあるファイル REPORTING-BUGS はカーネ
 ルバグらしいものについてどうレポートするかの良いテンプレートであり、問
 題の追跡を助けるためにカーネル開発者にとってどんな情報が必要なのかの詳
 細が書かれています。
 
+バグレポートの管理
+-------------------
+
+あなたのハッキングのスキルを訓練する最高の方法のひとつに、他人がレポー
+トしたバグを修正することがあります。あなたがカーネルをより安定化させる
+こに寄与するということだけでなく、あなたは 現実の問題を修正することを
+学び、自分のスキルも強化でき、また他の開発者があなたの存在に気がつき
+ます。バグを修正することは、多くの開発者の中から自分が功績をあげる最善
+の道です、なぜなら多くの人は他人のバグの修正に時間を浪費することを好ま
+ないからです。
+
+すでにレポートされたバグのために仕事をするためには、
+http://bugzilla.kernel.org に行ってください。もし今後のバグレポートに
+ついてアドバイスを受けたいのであれば、bugme-new メーリングリスト(新し
+いバグレポートだけがここにメールされる) または bugme-janitor メーリン
+グリスト(bugzilla の変更毎にここにメールされる)を購読できます。
+
+       http://lists.linux-foundation.org/mailman/listinfo/bugme-new
+       http://lists.linux-foundation.org/mailman/listinfo/bugme-janitors
+
 メーリングリスト
 -------------
 
diff --git a/Documentation/ja_JP/SubmitChecklist b/Documentation/ja_JP/SubmitChecklist
new file mode 100644 (file)
index 0000000..6c42e07
--- /dev/null
@@ -0,0 +1,111 @@
+NOTE:
+This is a version of Documentation/SubmitChecklist into Japanese.
+This document is maintained by Takenori Nagano <t-nagano@ah.jp.nec.com>
+and the JF Project team <http://www.linux.or.jp/JF/>.
+If you find any difference between this document and the original file
+or a problem with the translation,
+please contact the maintainer of this file or JF project.
+
+Please also note that the purpose of this file is to be easier to read
+for non English (read: Japanese) speakers and is not intended as a
+fork. So if you have any comments or updates of this file, please try
+to update the original English file first.
+
+Last Updated: 2008/07/14
+==================================
+これは、
+linux-2.6.26/Documentation/SubmitChecklist の和訳です。
+
+翻訳団体: JF プロジェクト < http://www.linux.or.jp/JF/ >
+翻訳日: 2008/07/14
+翻訳者: Takenori Nagano <t-nagano at ah dot jp dot nec dot com>
+校正者: Masanori Kobayashi さん <zap03216 at nifty dot ne dot jp>
+==================================
+
+
+Linux カーネルパッチ投稿者向けチェックリスト
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+本書では、パッチをより素早く取り込んでもらいたい開発者が実践すべき基本的な事柄
+をいくつか紹介します。ここにある全ての事柄は、Documentation/SubmittingPatches
+などのLinuxカーネルパッチ投稿に際しての心得を補足するものです。
+
+ 1: 妥当なCONFIGオプションや変更されたCONFIGオプション、つまり =y, =m, =n
+    全てで正しくビルドできることを確認してください。その際、gcc及びリンカが
+    warningやerrorを出していないことも確認してください。
+
+ 2: allnoconfig, allmodconfig オプションを用いて正しくビルドできることを
+    確認してください。
+
+ 3: 手許のクロスコンパイルツールやOSDLのPLMのようなものを用いて、複数の
+    アーキテクチャにおいても正しくビルドできることを確認してください。
+
+ 4: 64bit長の'unsigned long'を使用しているppc64は、クロスコンパイルでの
+    チェックに適当なアーキテクチャです。
+
+ 5: カーネルコーディングスタイルに準拠しているかどうか確認してください(!)
+
+ 6: CONFIGオプションの追加・変更をした場合には、CONFIGメニューが壊れていない
+    ことを確認してください。
+
+ 7: 新しくKconfigのオプションを追加する際には、必ずそのhelpも記述してください。
+
+ 8: 適切なKconfigの依存関係を考えながら慎重にチェックしてください。
+    ただし、この作業はマシンを使ったテストできちんと行うのがとても困難です。
+    うまくやるには、自分の頭で考えることです。
+
+ 9: sparseを利用してちゃんとしたコードチェックをしてください。
+
+10: 'make checkstack' と 'make namespacecheck' を利用し、問題が発見されたら
+    修正してください。'make checkstack' は明示的に問題を示しませんが、どれか
+    1つの関数が512バイトより大きいスタックを使っていれば、修正すべき候補と
+    なります。
+
+11: グローバルなkernel API を説明する kernel-doc をソースの中に含めてください。
+    ( staticな関数においては必須ではありませんが、含めてもらっても結構です )
+    そして、'make htmldocs' もしくは 'make mandocs' を利用して追記した
+    ドキュメントのチェックを行い、問題が見つかった場合には修正を行ってください。
+
+12: CONFIG_PREEMPT, CONFIG_DEBUG_PREEMPT, CONFIG_DEBUG_SLAB,
+    CONFIG_DEBUG_PAGEALLOC, CONFIG_DEBUG_MUTEXES, CONFIG_DEBUG_SPINLOCK,
+    CONFIG_DEBUG_SPINLOCK_SLEEP これら全てを同時に有効にして動作確認を
+    行ってください。
+
+13: CONFIG_SMP, CONFIG_PREEMPT を有効にした場合と無効にした場合の両方で
+    ビルドした上、動作確認を行ってください。
+
+14: もしパッチがディスクのI/O性能などに影響を与えるようであれば、
+    'CONFIG_LBD'オプションを有効にした場合と無効にした場合の両方で
+    テストを実施してみてください。
+
+15: lockdepの機能を全て有効にした上で、全てのコードパスを評価してください。
+
+16: /proc に新しいエントリを追加した場合には、Documentation/ 配下に
+    必ずドキュメントを追加してください。
+
+17: 新しいブートパラメータを追加した場合には、
+    必ずDocumentation/kernel-parameters.txt に説明を追加してください。
+
+18: 新しくmoduleにパラメータを追加した場合には、MODULE_PARM_DESC()を
+    利用して必ずその説明を記述してください。
+
+19: 新しいuserspaceインタフェースを作成した場合には、Documentation/ABI/ に
+    Documentation/ABI/README を参考にして必ずドキュメントを追加してください。
+
+20: 'make headers_check'を実行して全く問題がないことを確認してください。
+
+21: 少なくともslabアロケーションとpageアロケーションに失敗した場合の
+    挙動について、fault-injectionを利用して確認してください。
+    Documentation/fault-injection/ を参照してください。
+
+    追加したコードがかなりの量であったならば、サブシステム特有の
+    fault-injectionを追加したほうが良いかもしれません。
+
+22: 新たに追加したコードは、`gcc -W'でコンパイルしてください。
+    このオプションは大量の不要なメッセージを出力しますが、
+    "warning: comparison between signed and unsigned" のようなメッセージは、
+    バグを見つけるのに役に立ちます。
+
+23: 投稿したパッチが -mm パッチセットにマージされた後、全ての既存のパッチや
+    VM, VFS およびその他のサブシステムに関する様々な変更と、現時点でも共存
+    できることを確認するテストを行ってください。
index e7bea3e853044e54f3ee863ad3d295b0df84a522..1150444a21ab64140f13e706797f16664e28244f 100644 (file)
@@ -365,6 +365,8 @@ and is between 256 and 4096 characters. It is defined in the file
                        no delay (0).
                        Format: integer
 
+       bootmem_debug   [KNL] Enable bootmem allocator debug messages.
+
        bttv.card=      [HW,V4L] bttv (bt848 + bt878 based grabber cards)
        bttv.radio=     Most important insmod options are available as
                        kernel args too.
@@ -1072,6 +1074,9 @@ and is between 256 and 4096 characters. It is defined in the file
 
                        * [no]ncq: Turn on or off NCQ.
 
+                       * nohrst, nosrst, norst: suppress hard, soft
+                          and both resets.
+
                        If there are multiple matching configurations changing
                        the same attribute, the last one is used.
 
index 655414821edc361fae2382104a068bb2c895f0de..7228369d1014b956ff3c8843d8ef642a225682b3 100644 (file)
@@ -895,6 +895,9 @@ static void handle_console_output(int fd, struct virtqueue *vq, bool timeout)
        }
 }
 
+/* This is called when we no longer want to hear about Guest changes to a
+ * virtqueue.  This is more efficient in high-traffic cases, but it means we
+ * have to set a timer to check if any more changes have occurred. */
 static void block_vq(struct virtqueue *vq)
 {
        struct itimerval itm;
@@ -939,6 +942,11 @@ static void handle_net_output(int fd, struct virtqueue *vq, bool timeout)
        if (!timeout && num)
                block_vq(vq);
 
+       /* We never quite know how long should we wait before we check the
+        * queue again for more packets.  We start at 500 microseconds, and if
+        * we get fewer packets than last time, we assume we made the timeout
+        * too small and increase it by 10 microseconds.  Otherwise, we drop it
+        * by one microsecond every time.  It seems to work well enough. */
        if (timeout) {
                if (num < last_timeout_num)
                        timeout_usec += 10;
index 28b6ec87c64209b10a83dfe1a7bfcebf6f231991..6fcb3060dec507ed653a5cc0ce72eb9773cbad56 100644 (file)
@@ -363,6 +363,11 @@ This rule exists because users of the rfkill subsystem expect to get (and set,
 when possible) the overall transmitter rfkill state, not of a particular rfkill
 line.
 
+5. During suspend, the rfkill class will attempt to soft-block the radio
+through a call to rfkill->toggle_radio, and will try to restore its previous
+state during resume.  After a rfkill class is suspended, it will *not* call
+rfkill->toggle_radio until it is resumed.
+
 Example of a WLAN wireless driver connected to the rfkill subsystem:
 --------------------------------------------------------------------
 
index 716fcc1cafb5cac5f1e13aa6be971825687a2f04..c851ef49779566a970e8e64c15385e2cf6f80033 100644 (file)
@@ -1,3 +1,26 @@
+
+1 Release Date    : Thur.July. 24 11:41:51 PST 2008 -
+                       (emaild-id:megaraidlinux@lsi.com)
+                       Sumant Patro
+                       Bo Yang
+
+2 Current Version : 00.00.04.01
+3 Older Version   : 00.00.03.22
+
+1. Add the new controller (0078, 0079) support to the driver
+       Those controllers are LSI's next generatation(gen2) SAS controllers.
+
+1 Release Date    : Mon.June. 23 10:12:45 PST 2008 -
+                       (emaild-id:megaraidlinux@lsi.com)
+                       Sumant Patro
+                       Bo Yang
+
+2 Current Version : 00.00.03.22
+3 Older Version   : 00.00.03.20
+
+1. Add shutdown DCMD cmd to the shutdown routine to make FW shutdown proper.
+2. Unexpected interrupt occurs in HWR Linux driver, add the dumy readl pci flush will fix this issue.
+
 1 Release Date    : Mon. March 10 11:02:31 PDT 2008 -
                        (emaild-id:megaraidlinux@lsi.com)
                        Sumant Patro
index 663485b004fb10da0477888156f46c1c2f1f251a..28c69aaefcd94601a1bf8e3d096e2f89a5d1b5a8 100644 (file)
@@ -942,94 +942,19 @@ M:        joern@lazybastard.org
 L:     linux-mtd@lists.infradead.org
 S:     Maintained
 
-BLUETOOTH SUBSYSTEM
+BLUETOOTH DRIVERS
 P:     Marcel Holtmann
 M:     marcel@holtmann.org
-P:     Maxim Krasnyansky
-M:     maxk@qualcomm.com
 L:     linux-bluetooth@vger.kernel.org
-W:     http://bluez.sf.net
-W:     http://www.bluez.org
-W:     http://www.holtmann.org/linux/bluetooth/
-T:     git kernel.org:/pub/scm/linux/kernel/git/holtmann/bluetooth-2.6.git
-S:     Maintained
-
-BLUETOOTH RFCOMM LAYER
-P:     Marcel Holtmann
-M:     marcel@holtmann.org
-P:     Maxim Krasnyansky
-M:     maxk@qualcomm.com
-S:     Maintained
-
-BLUETOOTH BNEP LAYER
-P:     Marcel Holtmann
-M:     marcel@holtmann.org
-P:     Maxim Krasnyansky
-M:     maxk@qualcomm.com
-S:     Maintained
-
-BLUETOOTH CMTP LAYER
-P:     Marcel Holtmann
-M:     marcel@holtmann.org
+W:     http://www.bluez.org/
 S:     Maintained
 
-BLUETOOTH HIDP LAYER
-P:     Marcel Holtmann
-M:     marcel@holtmann.org
-S:     Maintained
-
-BLUETOOTH HCI UART DRIVER
-P:     Marcel Holtmann
-M:     marcel@holtmann.org
-P:     Maxim Krasnyansky
-M:     maxk@qualcomm.com
-S:     Maintained
-
-BLUETOOTH HCI USB DRIVER
-P:     Marcel Holtmann
-M:     marcel@holtmann.org
-P:     Maxim Krasnyansky
-M:     maxk@qualcomm.com
-S:     Maintained
-
-BLUETOOTH HCI BCM203X DRIVER
-P:     Marcel Holtmann
-M:     marcel@holtmann.org
-S:     Maintained
-
-BLUETOOTH HCI BPA10X DRIVER
-P:     Marcel Holtmann
-M:     marcel@holtmann.org
-S:     Maintained
-
-BLUETOOTH HCI BFUSB DRIVER
-P:     Marcel Holtmann
-M:     marcel@holtmann.org
-S:     Maintained
-
-BLUETOOTH HCI DTL1 DRIVER
-P:     Marcel Holtmann
-M:     marcel@holtmann.org
-S:     Maintained
-
-BLUETOOTH HCI BLUECARD DRIVER
-P:     Marcel Holtmann
-M:     marcel@holtmann.org
-S:     Maintained
-
-BLUETOOTH HCI BT3C DRIVER
-P:     Marcel Holtmann
-M:     marcel@holtmann.org
-S:     Maintained
-
-BLUETOOTH HCI BTUART DRIVER
+BLUETOOTH SUBSYSTEM
 P:     Marcel Holtmann
 M:     marcel@holtmann.org
-S:     Maintained
-
-BLUETOOTH HCI VHCI DRIVER
-P:     Maxim Krasnyansky
-M:     maxk@qualcomm.com
+L:     linux-bluetooth@vger.kernel.org
+W:     http://www.bluez.org/
+T:     git kernel.org:/pub/scm/linux/kernel/git/holtmann/bluetooth-2.6.git
 S:     Maintained
 
 BONDING DRIVER
index 53bf6ec1af9d29fac6682fb6cd4c2e5dbcb84490..2e15e0b4483d68a2bfb37bc8cdca42fe86e12195 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 6
 SUBLEVEL = 27
-EXTRAVERSION = -rc3
+EXTRAVERSION = -rc4
 NAME = Rotary Wombat
 
 # *DOCUMENTATION*
index 0a7b3267c8d8302c3cf84e4392d23d87020444f1..3c8383dbe9e6fac52652215dba190667a610ad4b 100644 (file)
@@ -405,7 +405,7 @@ static int impd1_probe(struct lm_device *dev)
 
                ret = amba_device_register(d, &dev->resource);
                if (ret) {
-                       dev_err(&d->dev, "unable to register device: %d\n");
+                       dev_err(&d->dev, "unable to register device: %d\n", ret);
                        kfree(d);
                }
        }
index 0db3a909ae616310e1406f76ca177222b3a0d7cc..501dfdcc39fe996c86bc87ffb2289c3ae14f4925 100644 (file)
@@ -64,7 +64,7 @@ static struct platform_device fsg_i2c_gpio = {
 
 static struct i2c_board_info __initdata fsg_i2c_board_info [] = {
        {
-               I2C_BOARD_INFO("rtc-isl1208", 0x6f),
+               I2C_BOARD_INFO("isl1208", 0x6f),
        },
 };
 
@@ -179,7 +179,6 @@ static void __init fsg_init(void)
 {
        DECLARE_MAC_BUF(mac_buf);
        uint8_t __iomem *f;
-       int i;
 
        ixp4xx_sys_init();
 
@@ -228,6 +227,7 @@ static void __init fsg_init(void)
        f = ioremap(IXP4XX_EXP_BUS_BASE(0), 0x400000);
        if (f) {
 #ifdef __ARMEB__
+               int i;
                for (i = 0; i < 6; i++) {
                        fsg_plat_eth[0].hwaddr[i] = readb(f + 0x3C0422 + i);
                        fsg_plat_eth[1].hwaddr[i] = readb(f + 0x3C043B + i);
index c01eea88f7874e702ffa50af37b9d56e67d4cb63..ca8e205381577ab07f05fec6e573f77554672c3c 100644 (file)
@@ -125,3 +125,28 @@ void clks_register(struct clk *clks, size_t num)
                list_add(&clks[i].node, &clocks);
        mutex_unlock(&clocks_mutex);
 }
+
+int clk_add_alias(char *alias, struct device *alias_dev, char *id,
+       struct device *dev)
+{
+       struct clk *r = clk_lookup(dev, id);
+       struct clk *new;
+
+       if (!r)
+               return -ENODEV;
+
+       new = kzalloc(sizeof(struct clk), GFP_KERNEL);
+
+       if (!new)
+               return -ENOMEM;
+
+       new->name = alias;
+       new->dev = alias_dev;
+       new->other = r;
+
+       mutex_lock(&clocks_mutex);
+       list_add(&new->node, &clocks);
+       mutex_unlock(&clocks_mutex);
+
+       return 0;
+}
index 1ec8f9178aaf48e41cde86c1c534d76f51283422..73be795fe3bfe5dcb04a25fa95c2488910efa20c 100644 (file)
@@ -1,3 +1,5 @@
+#include <linux/list.h>
+
 struct clk;
 
 struct clkops {
@@ -86,3 +88,6 @@ extern void clk_pxa3xx_cken_disable(struct clk *);
 #endif
 
 void clks_register(struct clk *clks, size_t num);
+int clk_add_alias(char *alias, struct device *alias_dev, char *id,
+       struct device *dev);
+
index 03942450885b14a94bf0dfa33e7c757a13544280..001a252bd514379e677edb0d247b8ac542005b28 100644 (file)
  *
  */
 
+#include <linux/kernel.h>
 #include <linux/init.h>
 
 #include <asm/setup.h>
 #include <asm/mach/arch.h>
-#include <mach/hardware.h>
 #include <asm/mach-types.h>
 
+#include <mach/mfp-pxa25x.h>
+#include <mach/hardware.h>
+
 #include "generic.h"
 
+static unsigned long e740_pin_config[] __initdata = {
+       /* Chip selects */
+       GPIO15_nCS_1,   /* CS1 - Flash */
+       GPIO79_nCS_3,   /* CS3 - IMAGEON */
+       GPIO80_nCS_4,   /* CS4 - TMIO */
+
+       /* Clocks */
+       GPIO12_32KHz,
+
+       /* BTUART */
+       GPIO42_BTUART_RXD,
+       GPIO43_BTUART_TXD,
+       GPIO44_BTUART_CTS,
+       GPIO45_GPIO, /* Used by TMIO for #SUSPEND */
+
+       /* PC Card */
+       GPIO8_GPIO,   /* CD0 */
+       GPIO44_GPIO,  /* CD1 */
+       GPIO11_GPIO,  /* IRQ0 */
+       GPIO6_GPIO,   /* IRQ1 */
+       GPIO27_GPIO,  /* RST0 */
+       GPIO24_GPIO,  /* RST1 */
+       GPIO20_GPIO,  /* PWR0 */
+       GPIO23_GPIO,  /* PWR1 */
+       GPIO48_nPOE,
+       GPIO49_nPWE,
+       GPIO50_nPIOR,
+       GPIO51_nPIOW,
+       GPIO52_nPCE_1,
+       GPIO53_nPCE_2,
+       GPIO54_nPSKTSEL,
+       GPIO55_nPREG,
+       GPIO56_nPWAIT,
+       GPIO57_nIOIS16,
+
+       /* wakeup */
+       GPIO0_GPIO | WAKEUP_ON_EDGE_RISE,
+};
+
+static unsigned long e400_pin_config[] __initdata = {
+       /* Chip selects */
+       GPIO15_nCS_1,   /* CS1 - Flash */
+       GPIO80_nCS_4,   /* CS4 - TMIO */
+
+       /* Clocks */
+       GPIO12_32KHz,
+
+       /* BTUART */
+       GPIO42_BTUART_RXD,
+       GPIO43_BTUART_TXD,
+       GPIO44_BTUART_CTS,
+       GPIO45_GPIO, /* Used by TMIO for #SUSPEND */
+
+       /* wakeup */
+       GPIO0_GPIO | WAKEUP_ON_EDGE_RISE,
+};
+
 /* Only e800 has 128MB RAM */
 static void __init eseries_fixup(struct machine_desc *desc,
-                      struct tag *tags, char **cmdline, struct meminfo *mi)
+       struct tag *tags, char **cmdline, struct meminfo *mi)
 {
        mi->nr_banks=1;
        mi->bank[0].start = 0xa0000000;
@@ -32,83 +92,95 @@ static void __init eseries_fixup(struct machine_desc *desc,
                mi->bank[0].size = (64*1024*1024);
 }
 
+static void __init e740_init(void)
+{
+       pxa2xx_mfp_config(ARRAY_AND_SIZE(e740_pin_config));
+}
+
+static void __init e400_init(void)
+{
+       pxa2xx_mfp_config(ARRAY_AND_SIZE(e400_pin_config));
+}
+
 /* e-series machine definitions */
 
 #ifdef CONFIG_MACH_E330
 MACHINE_START(E330, "Toshiba e330")
-        /* Maintainer: Ian Molton (spyro@f2s.com) */
-        .phys_io        = 0x40000000,
-        .io_pg_offst    = (io_p2v(0x40000000) >> 18) & 0xfffc,
-        .boot_params    = 0xa0000100,
-        .map_io         = pxa_map_io,
-        .init_irq       = pxa25x_init_irq,
-        .fixup          = eseries_fixup,
-        .timer = &pxa_timer,
+       /* Maintainer: Ian Molton (spyro@f2s.com) */
+       .phys_io        = 0x40000000,
+       .io_pg_offst    = (io_p2v(0x40000000) >> 18) & 0xfffc,
+       .boot_params    = 0xa0000100,
+       .map_io         = pxa_map_io,
+       .init_irq       = pxa25x_init_irq,
+       .fixup          = eseries_fixup,
+       .timer          = &pxa_timer,
 MACHINE_END
 #endif
 
 #ifdef CONFIG_MACH_E350
 MACHINE_START(E350, "Toshiba e350")
        /* Maintainer: Ian Molton (spyro@f2s.com) */
-       .phys_io        = 0x40000000,
-       .io_pg_offst    = (io_p2v(0x40000000) >> 18) & 0xfffc,
-       .boot_params    = 0xa0000100,
-       .map_io         = pxa_map_io,
-       .init_irq       = pxa25x_init_irq,
-       .fixup          = eseries_fixup,
-       .timer = &pxa_timer,
+       .phys_io        = 0x40000000,
+       .io_pg_offst    = (io_p2v(0x40000000) >> 18) & 0xfffc,
+       .boot_params    = 0xa0000100,
+       .map_io         = pxa_map_io,
+       .init_irq       = pxa25x_init_irq,
+       .fixup          = eseries_fixup,
+       .timer          = &pxa_timer,
 MACHINE_END
 #endif
 
 #ifdef CONFIG_MACH_E740
 MACHINE_START(E740, "Toshiba e740")
-        /* Maintainer: Ian Molton (spyro@f2s.com) */
-        .phys_io        = 0x40000000,
-        .io_pg_offst    = (io_p2v(0x40000000) >> 18) & 0xfffc,
-        .boot_params    = 0xa0000100,
-        .map_io         = pxa_map_io,
-        .init_irq       = pxa25x_init_irq,
-        .fixup          = eseries_fixup,
-        .timer = &pxa_timer,
+       /* Maintainer: Ian Molton (spyro@f2s.com) */
+       .phys_io        = 0x40000000,
+       .io_pg_offst    = (io_p2v(0x40000000) >> 18) & 0xfffc,
+       .boot_params    = 0xa0000100,
+       .map_io         = pxa_map_io,
+       .init_irq       = pxa25x_init_irq,
+       .fixup          = eseries_fixup,
+       .init_machine   = e740_init,
+       .timer          = &pxa_timer,
 MACHINE_END
 #endif
 
 #ifdef CONFIG_MACH_E750
 MACHINE_START(E750, "Toshiba e750")
-        /* Maintainer: Ian Molton (spyro@f2s.com) */
-        .phys_io        = 0x40000000,
-        .io_pg_offst    = (io_p2v(0x40000000) >> 18) & 0xfffc,
-        .boot_params    = 0xa0000100,
-        .map_io         = pxa_map_io,
-        .init_irq       = pxa25x_init_irq,
-        .fixup          = eseries_fixup,
-        .timer = &pxa_timer,
+       /* Maintainer: Ian Molton (spyro@f2s.com) */
+       .phys_io        = 0x40000000,
+       .io_pg_offst    = (io_p2v(0x40000000) >> 18) & 0xfffc,
+       .boot_params    = 0xa0000100,
+       .map_io         = pxa_map_io,
+       .init_irq       = pxa25x_init_irq,
+       .fixup          = eseries_fixup,
+       .timer          = &pxa_timer,
 MACHINE_END
 #endif
 
 #ifdef CONFIG_MACH_E400
 MACHINE_START(E400, "Toshiba e400")
-        /* Maintainer: Ian Molton (spyro@f2s.com) */
-        .phys_io        = 0x40000000,
-        .io_pg_offst    = (io_p2v(0x40000000) >> 18) & 0xfffc,
-        .boot_params    = 0xa0000100,
-        .map_io         = pxa_map_io,
-        .init_irq       = pxa25x_init_irq,
-        .fixup          = eseries_fixup,
-        .timer = &pxa_timer,
+       /* Maintainer: Ian Molton (spyro@f2s.com) */
+       .phys_io        = 0x40000000,
+       .io_pg_offst    = (io_p2v(0x40000000) >> 18) & 0xfffc,
+       .boot_params    = 0xa0000100,
+       .map_io         = pxa_map_io,
+       .init_irq       = pxa25x_init_irq,
+       .fixup          = eseries_fixup,
+       .init_machine   = e400_init,
+       .timer          = &pxa_timer,
 MACHINE_END
 #endif
 
 #ifdef CONFIG_MACH_E800
 MACHINE_START(E800, "Toshiba e800")
-        /* Maintainer: Ian Molton (spyro@f2s.com) */
-        .phys_io        = 0x40000000,
-        .io_pg_offst    = (io_p2v(0x40000000) >> 18) & 0xfffc,
-        .boot_params    = 0xa0000100,
-        .map_io         = pxa_map_io,
-        .init_irq       = pxa25x_init_irq,
-        .fixup          = eseries_fixup,
-        .timer = &pxa_timer,
+       /* Maintainer: Ian Molton (spyro@f2s.com) */
+       .phys_io        = 0x40000000,
+       .io_pg_offst    = (io_p2v(0x40000000) >> 18) & 0xfffc,
+       .boot_params    = 0xa0000100,
+       .map_io         = pxa_map_io,
+       .init_irq       = pxa25x_init_irq,
+       .fixup          = eseries_fixup,
+       .timer          = &pxa_timer,
 MACHINE_END
 #endif
 
index 32772bc6925c93e699471c4f0903647d2f8806e4..108b5db9b2af67c3d96ef9810184410332bffda4 100644 (file)
       defined(CONFIG_MACH_TOSA) || \
       defined(CONFIG_MACH_MAINSTONE) || \
       defined(CONFIG_MACH_PCM027) || \
+      defined(CONFIG_ARCH_PXA_ESERIES) || \
       defined(CONFIG_MACH_MAGICIAN)
 #define NR_IRQS                        (IRQ_BOARD_END)
 #elif defined(CONFIG_MACH_ZYLONITE)
index bb9e09208b9f48057713608a8a62df476ecbd1ef..4ffdff2d9ff1e188b142816a6f87cd5ee0ffda1c 100644 (file)
@@ -52,6 +52,7 @@
 #include <mach/mmc.h>
 
 #include "generic.h"
+#include "clock.h"
 #include "devices.h"
 
 static unsigned long lubbock_pin_config[] __initdata = {
@@ -485,6 +486,7 @@ static void __init lubbock_init(void)
 
        pxa2xx_mfp_config(ARRAY_AND_SIZE(lubbock_pin_config));
 
+       clk_add_alias("SA1111_CLK", NULL, "GPIO11_CLK", NULL);
        pxa_set_udc_info(&udc_info);
        set_pxa_fb_info(&sharp_lm8v31);
        pxa_set_mci_info(&lubbock_mci_platform_data);
index 9e5d8a8c6424f64a0d3bdead6622373f57a6603e..305452b56e91dfcda49e81c5876c0ed0ca935583 100644 (file)
@@ -166,8 +166,7 @@ static struct clk pxa25x_hwuart_clk =
 ;
 
 /*
- * PXA 2xx clock declarations. Order is important (see aliases below)
- * Please be careful not to disrupt the ordering.
+ * PXA 2xx clock declarations.
  */
 static struct clk pxa25x_clks[] = {
        INIT_CK("LCDCLK", LCD, &clk_pxa25x_lcd_ops, &pxa_device_fb.dev),
@@ -194,11 +193,6 @@ static struct clk pxa25x_clks[] = {
        INIT_CKEN("FICPCLK", FICP, 47923000, 0, NULL),
 };
 
-static struct clk pxa2xx_clk_aliases[] = {
-       INIT_CKOTHER("GPIO7_CLK", &pxa25x_clks[4], NULL),
-       INIT_CKOTHER("SA1111_CLK", &pxa25x_clks[5], NULL),
-};
-
 #ifdef CONFIG_PM
 
 #define SAVE(x)                sleep_save[SLEEP_SAVE_##x] = x
@@ -375,8 +369,6 @@ static int __init pxa25x_init(void)
        if (cpu_is_pxa255())
                ret = platform_device_register(&pxa_device_hwuart);
 
-       clks_register(pxa2xx_clk_aliases, ARRAY_SIZE(pxa2xx_clk_aliases));
-
        return ret;
 }
 
index 494fc1f032dbc1da8e35842a04ae038caef4181e..9adc7fc4618aacb561ca6fe9a5ab02df5c942086 100644 (file)
@@ -90,7 +90,9 @@ static struct clk common_clks[] = {
 };
 
 static struct clk pxa310_clks[] = {
+#ifdef CONFIG_CPU_PXA310
        PXA3xx_CKEN("MMCCLK", MMC3, 19500000, 0, &pxa3xx_device_mci3.dev),
+#endif
 };
 
 static int __init pxa300_init(void)
index 23a07059999307a0569fac8f1e942ededa6c2460..197974defbe4f4b0e41ffebf2aae1f2c96dc6c00 100644 (file)
@@ -10,7 +10,6 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-#include <linux/version.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/module.h>
index 2de9d5849ef023c286d67729b3c6c13a29b06338..111caa1a2efb4105aa0e45ae8552c8de6e5497a1 100644 (file)
@@ -19,8 +19,6 @@
 #include <asm/irq.h>
 #include <asm/system.h>
 
-#include <linux/version.h>
-
 #include <hwregs/reg_map.h>
 #include <hwregs/reg_rdwr.h>
 #include <hwregs/timer_defs.h>
index 8b054e7a8ae8e406b4d3e9ae8c6c9b8ac8bb47bc..aa07d0cd19052b483f002bb27a166e7defd75646 100644 (file)
@@ -17,7 +17,6 @@ static const char serial_revdate[] = "2007-11-06";
 #define SUPPORT_SYSRQ
 #endif
 
-#include <linux/version.h>
 #include <linux/module.h>
 #include <linux/serial.h>
 #include <linux/circ_buf.h>
index e0debcca0bfadaf03dbc6f3c35a56f1ad4a3aee2..a323c9b32ee12f76604631a532e2c5dc85436aa1 100644 (file)
@@ -86,6 +86,19 @@ static int __init parse_savemaxmem(char *p)
 }
 __setup("savemaxmem=", parse_savemaxmem);
 
+
+static size_t copy_oldmem_vaddr(void *vaddr, char *buf, size_t csize,
+                               unsigned long offset, int userbuf)
+{
+       if (userbuf) {
+               if (copy_to_user((char __user *)buf, (vaddr + offset), csize))
+                       return -EFAULT;
+       } else
+               memcpy(buf, (vaddr + offset), csize);
+
+       return csize;
+}
+
 /**
  * copy_oldmem_page - copy one page from "oldmem"
  * @pfn: page frame number to be copied
@@ -107,16 +120,16 @@ ssize_t copy_oldmem_page(unsigned long pfn, char *buf,
        if (!csize)
                return 0;
 
-       vaddr = __ioremap(pfn << PAGE_SHIFT, PAGE_SIZE, 0);
+       csize = min(csize, PAGE_SIZE);
 
-       if (userbuf) {
-               if (copy_to_user((char __user *)buf, (vaddr + offset), csize)) {
-                       iounmap(vaddr);
-                       return -EFAULT;
-               }
-       } else
-               memcpy(buf, (vaddr + offset), csize);
+       if (pfn < max_pfn) {
+               vaddr = __va(pfn << PAGE_SHIFT);
+               csize = copy_oldmem_vaddr(vaddr, buf, csize, offset, userbuf);
+       } else {
+               vaddr = __ioremap(pfn << PAGE_SHIFT, PAGE_SIZE, 0);
+               csize = copy_oldmem_vaddr(vaddr, buf, csize, offset, userbuf);
+               iounmap(vaddr);
+       }
 
-       iounmap(vaddr);
        return csize;
 }
index 9d42eb57aea3305f1ad866f6709c988363681891..a06362223f8d984e699f84ad9a25859609607887 100644 (file)
@@ -233,17 +233,6 @@ void ibmebus_free_irq(u32 ist, void *dev_id)
 }
 EXPORT_SYMBOL(ibmebus_free_irq);
 
-static ssize_t name_show(struct device *dev,
-                        struct device_attribute *attr, char *buf)
-{
-       return sprintf(buf, "%s\n", to_of_device(dev)->node->name);
-}
-
-static struct device_attribute ibmebus_dev_attrs[] = {
-       __ATTR_RO(name),
-       __ATTR_NULL
-};
-
 static char *ibmebus_chomp(const char *in, size_t count)
 {
        char *out = kmalloc(count + 1, GFP_KERNEL);
@@ -327,7 +316,6 @@ static struct bus_attribute ibmebus_bus_attrs[] = {
 
 struct bus_type ibmebus_bus_type = {
        .uevent    = of_device_uevent,
-       .dev_attrs = ibmebus_dev_attrs,
        .bus_attrs = ibmebus_bus_attrs
 };
 EXPORT_SYMBOL(ibmebus_bus_type);
index 22a3c33fd7513c5288cef156f931f62a1c4f41df..2750fbab1975b2e7e4c84d48a67589385aeb9e40 100644 (file)
@@ -1113,7 +1113,7 @@ static int vio_bus_probe(struct device *dev)
                                return error;
                }
                error = viodrv->probe(viodev, id);
-               if (error)
+               if (error && firmware_has_feature(FW_FEATURE_CMO))
                        vio_cmo_bus_remove(viodev);
        }
 
index f7edba6cb795d55944009cc376ff171cdddefa09..c9bb7cfd3dca8069434a9071860a6b99cff19022 100644 (file)
@@ -206,11 +206,6 @@ static int spu_run_init(struct spu_context *ctx, u32 *npc)
                        (SPU_RUNCNTL_RUNNABLE | SPU_RUNCNTL_ISOLATE);
                if (runcntl == 0)
                        runcntl = SPU_RUNCNTL_RUNNABLE;
-       }
-
-       if (ctx->flags & SPU_CREATE_NOSCHED) {
-               spuctx_switch_state(ctx, SPU_UTIL_USER);
-               ctx->ops->runcntl_write(ctx, runcntl);
        } else {
                unsigned long privcntl;
 
@@ -219,9 +214,15 @@ static int spu_run_init(struct spu_context *ctx, u32 *npc)
                else
                        privcntl = SPU_PRIVCNTL_MODE_NORMAL;
 
-               ctx->ops->npc_write(ctx, *npc);
                ctx->ops->privcntl_write(ctx, privcntl);
-               ctx->ops->runcntl_write(ctx, runcntl);
+               ctx->ops->npc_write(ctx, *npc);
+       }
+
+       ctx->ops->runcntl_write(ctx, runcntl);
+
+       if (ctx->flags & SPU_CREATE_NOSCHED) {
+               spuctx_switch_state(ctx, SPU_UTIL_USER);
+       } else {
 
                if (ctx->state == SPU_STATE_SAVED) {
                        ret = spu_activate(ctx, 0);
index 2deeeba7eccfc9c555d5d32aca370507f08268be..1c1b627ee8436dc8e2fce9098d274183b8f18011 100644 (file)
@@ -641,8 +641,10 @@ static struct spu *find_victim(struct spu_context *ctx)
 
                        if (tmp && tmp->prio > ctx->prio &&
                            !(tmp->flags & SPU_CREATE_NOSCHED) &&
-                           (!victim || tmp->prio > victim->prio))
+                           (!victim || tmp->prio > victim->prio)) {
                                victim = spu->ctx;
+                               get_spu_context(victim);
+                       }
                }
                mutex_unlock(&cbe_spu_info[node].list_mutex);
 
@@ -658,6 +660,7 @@ static struct spu *find_victim(struct spu_context *ctx)
                         * look at another context or give up after X retries.
                         */
                        if (!mutex_trylock(&victim->state_mutex)) {
+                               put_spu_context(victim);
                                victim = NULL;
                                goto restart;
                        }
@@ -670,6 +673,7 @@ static struct spu *find_victim(struct spu_context *ctx)
                                 * restart the search.
                                 */
                                mutex_unlock(&victim->state_mutex);
+                               put_spu_context(victim);
                                victim = NULL;
                                goto restart;
                        }
@@ -687,6 +691,7 @@ static struct spu *find_victim(struct spu_context *ctx)
                                spu_add_to_rq(victim);
 
                        mutex_unlock(&victim->state_mutex);
+                       put_spu_context(victim);
 
                        return spu;
                }
@@ -985,9 +990,11 @@ static int spusched_thread(void *unused)
                                struct spu_context *ctx = spu->ctx;
 
                                if (ctx) {
+                                       get_spu_context(ctx);
                                        mutex_unlock(mtx);
                                        spusched_tick(ctx);
                                        mutex_lock(mtx);
+                                       put_spu_context(ctx);
                                }
                        }
                        mutex_unlock(mtx);
@@ -1030,7 +1037,7 @@ void spuctx_switch_state(struct spu_context *ctx,
                node = spu->node;
                if (old_state == SPU_UTIL_USER)
                        atomic_dec(&cbe_spu_info[node].busy_spus);
-               if (new_state == SPU_UTIL_USER);
+               if (new_state == SPU_UTIL_USER)
                        atomic_inc(&cbe_spu_info[node].busy_spus);
        }
 }
index a3a134c35b0ab436f1e54bdf7e41c67f3e4b294e..e0a53e3147b2f159022569192dac6590bd6f8ebd 100644 (file)
@@ -11,7 +11,6 @@
  *
  */
 
-#include <linux/version.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
index c5cdb975d590a0eef102d9b7c277082d9661b42f..9b0bc2c9fba05e17de7730b209ad68c2d0638549 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.26-rc4
-# Fri May 30 09:49:33 2008
+# Linux kernel version: 2.6.27-rc4
+# Thu Aug 21 19:43:29 2008
 #
 CONFIG_SCHED_MC=y
 CONFIG_MMU=y
@@ -68,7 +68,6 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_SYSCTL=y
 # CONFIG_EMBEDDED is not set
 CONFIG_SYSCTL_SYSCALL=y
-CONFIG_SYSCTL_SYSCALL_CHECK=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
@@ -93,11 +92,17 @@ CONFIG_SLAB=y
 # CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 CONFIG_KPROBES=y
+# CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is not set
 CONFIG_KRETPROBES=y
+# CONFIG_HAVE_IOREMAP_PROT is not set
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
+# CONFIG_HAVE_ARCH_TRACEHOOK is not set
 # CONFIG_HAVE_DMA_ATTRS is not set
+# CONFIG_USE_GENERIC_SMP_HELPERS is not set
+# CONFIG_HAVE_CLK is not set
 CONFIG_PROC_PAGE_MONITOR=y
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
@@ -113,6 +118,7 @@ CONFIG_STOP_MACHINE=y
 CONFIG_BLOCK=y
 # CONFIG_BLK_DEV_IO_TRACE is not set
 CONFIG_BLK_DEV_BSG=y
+# CONFIG_BLK_DEV_INTEGRITY is not set
 CONFIG_BLOCK_COMPAT=y
 
 #
@@ -175,6 +181,8 @@ CONFIG_PREEMPT=y
 CONFIG_ARCH_SPARSEMEM_ENABLE=y
 CONFIG_ARCH_SPARSEMEM_DEFAULT=y
 CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
 CONFIG_SELECT_MEMORY_MODEL=y
 # CONFIG_FLATMEM_MANUAL is not set
 # CONFIG_DISCONTIGMEM_MANUAL is not set
@@ -185,8 +193,12 @@ CONFIG_HAVE_MEMORY_PRESENT=y
 CONFIG_SPARSEMEM_EXTREME=y
 CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y
 CONFIG_SPARSEMEM_VMEMMAP=y
+CONFIG_MEMORY_HOTPLUG=y
+CONFIG_MEMORY_HOTPLUG_SPARSE=y
+CONFIG_MEMORY_HOTREMOVE=y
 CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_MIGRATION=y
 CONFIG_RESOURCES_64BIT=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
@@ -198,6 +210,7 @@ CONFIG_VIRT_TO_BUS=y
 CONFIG_MACHCHK_WARNING=y
 CONFIG_QDIO=y
 # CONFIG_QDIO_DEBUG is not set
+CONFIG_CHSC_SCH=m
 
 #
 # Misc
@@ -206,6 +219,7 @@ CONFIG_IPL=y
 # CONFIG_IPL_TAPE is not set
 CONFIG_IPL_VM=y
 CONFIG_BINFMT_ELF=y
+CONFIG_COMPAT_BINFMT_ELF=y
 CONFIG_BINFMT_MISC=m
 CONFIG_FORCE_MAX_ZONEORDER=9
 # CONFIG_PROCESS_DEBUG is not set
@@ -226,10 +240,6 @@ CONFIG_S390_HYPFS_FS=y
 CONFIG_KEXEC=y
 # CONFIG_ZFCPDUMP is not set
 CONFIG_S390_GUEST=y
-
-#
-# Networking
-#
 CONFIG_NET=y
 
 #
@@ -364,7 +374,6 @@ CONFIG_NET_SCH_CBQ=m
 # CONFIG_NET_SCH_HTB is not set
 # CONFIG_NET_SCH_HFSC is not set
 CONFIG_NET_SCH_PRIO=m
-CONFIG_NET_SCH_RR=m
 CONFIG_NET_SCH_RED=m
 CONFIG_NET_SCH_SFQ=m
 CONFIG_NET_SCH_TEQL=m
@@ -430,7 +439,9 @@ CONFIG_CCW=y
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+CONFIG_FW_LOADER=y
+# CONFIG_FIRMWARE_IN_KERNEL is not set
+CONFIG_EXTRA_FIRMWARE=""
 # CONFIG_DEBUG_DRIVER is not set
 # CONFIG_DEBUG_DEVRES is not set
 CONFIG_SYS_HYPERVISOR=y
@@ -507,6 +518,11 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_ISCSI_TCP is not set
 # CONFIG_SCSI_DEBUG is not set
 CONFIG_ZFCP=y
+CONFIG_SCSI_DH=m
+CONFIG_SCSI_DH_RDAC=m
+CONFIG_SCSI_DH_HP_SW=m
+CONFIG_SCSI_DH_EMC=m
+CONFIG_SCSI_DH_ALUA=m
 CONFIG_MD=y
 CONFIG_BLK_DEV_MD=y
 CONFIG_MD_LINEAR=m
@@ -522,14 +538,10 @@ CONFIG_DM_CRYPT=y
 CONFIG_DM_SNAPSHOT=y
 CONFIG_DM_MIRROR=y
 CONFIG_DM_ZERO=y
-CONFIG_DM_MULTIPATH=y
-# CONFIG_DM_MULTIPATH_EMC is not set
-# CONFIG_DM_MULTIPATH_RDAC is not set
-# CONFIG_DM_MULTIPATH_HP is not set
+CONFIG_DM_MULTIPATH=m
 # CONFIG_DM_DELAY is not set
 # CONFIG_DM_UEVENT is not set
 CONFIG_NETDEVICES=y
-# CONFIG_NETDEVICES_MULTIQUEUE is not set
 # CONFIG_IFB is not set
 CONFIG_DUMMY=m
 CONFIG_BONDING=m
@@ -544,7 +556,6 @@ CONFIG_NET_ETHERNET=y
 # CONFIG_IBM_NEW_EMAC_TAH is not set
 # CONFIG_IBM_NEW_EMAC_EMAC4 is not set
 CONFIG_NETDEV_1000=y
-# CONFIG_E1000E_ENABLED is not set
 CONFIG_NETDEV_10000=y
 # CONFIG_TR is not set
 # CONFIG_WAN is not set
@@ -576,7 +587,10 @@ CONFIG_DEVKMEM=y
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
+CONFIG_HVC_DRIVER=y
+CONFIG_VIRTIO_CONSOLE=y
 CONFIG_HW_RANDOM=m
+CONFIG_HW_RANDOM_VIRTIO=m
 # CONFIG_R3964 is not set
 CONFIG_RAW_DRIVER=m
 CONFIG_MAX_RAW_DEVS=256
@@ -616,6 +630,7 @@ CONFIG_MONWRITER=m
 CONFIG_S390_VMUR=m
 # CONFIG_POWER_SUPPLY is not set
 # CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
 # CONFIG_WATCHDOG is not set
 
 #
@@ -693,6 +708,7 @@ CONFIG_CONFIGFS_FS=m
 # CONFIG_CRAMFS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
 # CONFIG_HPFS_FS is not set
 # CONFIG_QNX4FS_FS is not set
 # CONFIG_ROMFS_FS is not set
@@ -712,7 +728,6 @@ CONFIG_LOCKD_V4=y
 CONFIG_EXPORTFS=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_BIND34 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
@@ -780,6 +795,7 @@ CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_INFO is not set
 # CONFIG_DEBUG_VM is not set
 # CONFIG_DEBUG_WRITECOUNT is not set
+CONFIG_DEBUG_MEMORY_INIT=y
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_DEBUG_SG is not set
 # CONFIG_FRAME_POINTER is not set
@@ -789,6 +805,7 @@ CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_LKDTM is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=y
 CONFIG_SAMPLES=y
 # CONFIG_SAMPLE_KOBJECT is not set
 # CONFIG_SAMPLE_KPROBES is not set
@@ -847,6 +864,10 @@ CONFIG_CRYPTO_HMAC=m
 # CONFIG_CRYPTO_MD4 is not set
 CONFIG_CRYPTO_MD5=m
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
+CONFIG_CRYPTO_RMD128=m
+CONFIG_CRYPTO_RMD160=m
+CONFIG_CRYPTO_RMD256=m
+CONFIG_CRYPTO_RMD320=m
 CONFIG_CRYPTO_SHA1=m
 # CONFIG_CRYPTO_SHA256 is not set
 # CONFIG_CRYPTO_SHA512 is not set
@@ -895,6 +916,7 @@ CONFIG_BITREVERSE=m
 # CONFIG_GENERIC_FIND_NEXT_BIT is not set
 # CONFIG_CRC_CCITT is not set
 # CONFIG_CRC16 is not set
+CONFIG_CRC_T10DIF=y
 # CONFIG_CRC_ITU_T is not set
 CONFIG_CRC32=m
 CONFIG_CRC7=m
index b4eb24ab5af97811e5a0ca1845607de238210863..8e9243ae0c19d13524a700c3ffea8aa4961665c8 100644 (file)
@@ -709,7 +709,7 @@ static inline int find_next_zero_bit (const unsigned long * addr,
                 * __ffz_word returns __BITOPS_WORDSIZE
                 * if no zero bit is present in the word.
                 */
-               set = __ffz_word(0, *p >> bit) + bit;
+               set = __ffz_word(bit, *p >> bit);
                if (set >= size)
                        return size + offset;
                if (set < __BITOPS_WORDSIZE)
@@ -824,7 +824,7 @@ static inline int ext2_find_next_zero_bit(void *vaddr, unsigned long size,
                 * s390 version of ffz returns __BITOPS_WORDSIZE
                 * if no zero bit is present in the word.
                 */
-               set = ffz(__load_ulong_le(p, 0) >> bit) + bit;
+               set = __ffz_word(bit, __load_ulong_le(p, 0) >> bit);
                if (set >= size)
                        return size + offset;
                if (set < __BITOPS_WORDSIZE)
@@ -865,7 +865,7 @@ static inline int ext2_find_next_bit(void *vaddr, unsigned long size,
                 * s390 version of ffz returns __BITOPS_WORDSIZE
                 * if no zero bit is present in the word.
                 */
-               set = ffs(__load_ulong_le(p, 0) >> bit) + bit;
+               set = __ffs_word(0, __load_ulong_le(p, 0) & (~0UL << bit));
                if (set >= size)
                        return size + offset;
                if (set < __BITOPS_WORDSIZE)
index 9839767d0842e5d065524181db75aa075c154798..3e2c05cb6a8733683c57d2935536ee936cc52059 100644 (file)
@@ -75,7 +75,9 @@ unsigned long thread_saved_pc(struct task_struct *tsk)
        return sf->gprs[8];
 }
 
-DEFINE_PER_CPU(struct s390_idle_data, s390_idle);
+DEFINE_PER_CPU(struct s390_idle_data, s390_idle) = {
+       .lock = __SPIN_LOCK_UNLOCKED(s390_idle.lock)
+};
 
 static int s390_idle_enter(void)
 {
index b795b3e24afde40a4a0f24b36e26d1759adfb905..00b9b4dec5eb0850aeda9a373227b190a42e8caf 100644 (file)
@@ -610,7 +610,6 @@ static void __init smp_create_idle(unsigned int cpu)
        if (IS_ERR(p))
                panic("failed fork for CPU %u: %li", cpu, PTR_ERR(p));
        current_set[cpu] = p;
-       spin_lock_init(&(&per_cpu(s390_idle, cpu))->lock);
 }
 
 static int __cpuinit smp_alloc_lowcore(int cpu)
@@ -845,7 +844,6 @@ void __init smp_prepare_boot_cpu(void)
        current_set[0] = current;
        smp_cpu_state[0] = CPU_STATE_CONFIGURED;
        smp_cpu_polarization[0] = POLARIZATION_UNKNWN;
-       spin_lock_init(&(&__get_cpu_var(s390_idle))->lock);
 }
 
 void __init smp_cpus_done(unsigned int max_cpus)
index 025d4fe55a581e4ba57e2c50095647c573598905..fd1612590bf4feb96e7d9e714da12203cf300ac5 100644 (file)
@@ -140,6 +140,10 @@ static struct sh_mobile_lcdc_info lcdc_info = {
                        .vsync_len = 1,
                        .sync = 0, /* hsync and vsync are active low */
                },
+               .lcd_size_cfg = { /* 7.0 inch */
+                       .width = 152,
+                       .height = 91,
+               },
                .board_cfg = {
                        .display_on = ap320_wvga_power_on,
                },
index e499ee384d58d79304850b6fefa390768cccb61c..714dce91cc9bbb30684764c33eef963c09844866 100644 (file)
@@ -224,6 +224,10 @@ static struct sh_mobile_lcdc_info sh_mobile_lcdc_info = {
                        .vsync_len = 2,
                        .sync = 0,
                },
+               .lcd_size_cfg = { /* 7.0 inch */
+                       .width = 152,
+                       .height = 91,
+               },
        }
 #endif
 #ifdef CONFIG_SH_MIGOR_QVGA
@@ -245,6 +249,10 @@ static struct sh_mobile_lcdc_info sh_mobile_lcdc_info = {
                        .vsync_len = 2,
                        .sync = FB_SYNC_HOR_HIGH_ACT,
                },
+               .lcd_size_cfg = { /* 2.4 inch */
+                       .width = 49,
+                       .height = 37,
+               },
                .board_cfg = {
                        .setup_sys = migor_lcd_qvga_setup,
                },
index 925f16af71217d1e31bdea1a08d60df4076197ed..23850da05e3c8a6d53ce30b95dc89df59f7ebea3 100644 (file)
 #include <linux/interrupt.h>
 #include <linux/input.h>
 #include <linux/mtd/physmap.h>
-#include <asm/io.h>
+#include <linux/fb.h>
+#include <linux/io.h>
 #include <asm/sh7763rdp.h>
+#include <asm/sh_eth.h>
+#include <asm/sh7760fb.h>
 
 /* NOR Flash */
 static struct mtd_partition sh7763rdp_nor_flash_partitions[] = {
@@ -60,8 +63,85 @@ static struct platform_device sh7763rdp_nor_flash_device = {
        },
 };
 
+/* SH-Ether */
+static struct resource sh_eth_resources[] = {
+       {
+               .start  = 0xFEE00800,   /* use eth1 */
+               .end    = 0xFEE00F7C - 1,
+               .flags  = IORESOURCE_MEM,
+       }, {
+               .start  = 58,   /* irq number */
+               .end    = 58,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct sh_eth_plat_data sh7763_eth_pdata = {
+       .phy = 1,
+       .edmac_endian = EDMAC_LITTLE_ENDIAN,
+};
+
+static struct platform_device sh7763rdp_eth_device = {
+       .name       = "sh-eth",
+       .resource   = sh_eth_resources,
+       .num_resources  = ARRAY_SIZE(sh_eth_resources),
+       .dev        = {
+               .platform_data = &sh7763_eth_pdata,
+       },
+};
+
+/* SH7763 LCDC */
+static struct resource sh7763rdp_fb_resources[] = {
+       {
+               .start  = 0xFFE80000,
+               .end    = 0xFFE80442 - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+};
+
+static struct fb_videomode sh7763fb_videomode = {
+       .refresh = 60,
+       .name = "VGA Monitor",
+       .xres = 640,
+       .yres = 480,
+       .pixclock = 10000,
+       .left_margin = 80,
+       .right_margin = 24,
+       .upper_margin = 30,
+       .lower_margin = 1,
+       .hsync_len = 96,
+       .vsync_len = 1,
+       .sync = 0,
+       .vmode = FB_VMODE_NONINTERLACED,
+       .flag = FBINFO_FLAG_DEFAULT,
+};
+
+static struct sh7760fb_platdata sh7763fb_def_pdata = {
+       .def_mode = &sh7763fb_videomode,
+       .ldmtr = (LDMTR_TFT_COLOR_16|LDMTR_MCNT),
+       .lddfr = LDDFR_16BPP_RGB565,
+       .ldpmmr = 0x0000,
+       .ldpspr = 0xFFFF,
+       .ldaclnr = 0x0001,
+       .ldickr = 0x1102,
+       .rotate = 0,
+       .novsync = 0,
+       .blank = NULL,
+};
+
+static struct platform_device sh7763rdp_fb_device = {
+       .name           = "sh7760-lcdc",
+       .resource       = sh7763rdp_fb_resources,
+       .num_resources = ARRAY_SIZE(sh7763rdp_fb_resources),
+       .dev = {
+               .platform_data = &sh7763fb_def_pdata,
+       },
+};
+
 static struct platform_device *sh7763rdp_devices[] __initdata = {
        &sh7763rdp_nor_flash_device,
+       &sh7763rdp_eth_device,
+       &sh7763rdp_fb_device,
 };
 
 static int __init sh7763rdp_devices_setup(void)
@@ -69,7 +149,7 @@ static int __init sh7763rdp_devices_setup(void)
        return platform_add_devices(sh7763rdp_devices,
                                    ARRAY_SIZE(sh7763rdp_devices));
 }
-__initcall(sh7763rdp_devices_setup);
+device_initcall(sh7763rdp_devices_setup);
 
 static void __init sh7763rdp_setup(char **cmdline_p)
 {
index abc5b6d418fed086e5c82f96c0c33d91892c2f61..a70d23b21788e99db83270818cd71939909d7be7 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Renesas SH-X3 Prototype Board Support.
  *
- * Copyright (C) 2007 Paul Mundt
+ * Copyright (C) 2007 - 2008 Paul Mundt
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
@@ -13,6 +13,7 @@
 #include <linux/platform_device.h>
 #include <linux/kernel.h>
 #include <linux/io.h>
+#include <linux/smc91x.h>
 #include <asm/ilsel.h>
 
 static struct resource heartbeat_resources[] = {
@@ -30,6 +31,10 @@ static struct platform_device heartbeat_device = {
        .resource       = heartbeat_resources,
 };
 
+static struct smc91x_platdata smc91x_info = {
+       .flags  = SMC91X_USE_16BIT | SMC91X_NOWAIT,
+};
+
 static struct resource smc91x_resources[] = {
        [0] = {
                .start          = 0x18000300,
@@ -47,6 +52,9 @@ static struct platform_device smc91x_device = {
        .id             = -1,
        .resource       = smc91x_resources,
        .num_resources  = ARRAY_SIZE(smc91x_resources),
+       .dev    = {
+               .platform_data = &smc91x_info,
+       },
 };
 
 static struct resource r8a66597_usb_host_resources[] = {
index 83f3fe5db3e535d0c4fa4329b68599b15c36d7b7..baf830c4a7e40189616755c9602f17fd78cf71c0 100644 (file)
@@ -1,15 +1,17 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.26-rc4
-# Fri Jun  6 12:20:17 2008
+# Linux kernel version: 2.6.27-rc2
+# Fri Aug  8 13:44:20 2008
 #
 CONFIG_SUPERH=y
 CONFIG_SUPERH32=y
+CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig"
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 CONFIG_GENERIC_BUG=y
 CONFIG_GENERIC_FIND_NEXT_BIT=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 CONFIG_GENERIC_IRQ_PROBE=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_GENERIC_TIME=y
@@ -19,7 +21,6 @@ CONFIG_LOCKDEP_SUPPORT=y
 # CONFIG_ARCH_HAS_ILOG2_U32 is not set
 # CONFIG_ARCH_HAS_ILOG2_U64 is not set
 CONFIG_ARCH_NO_VIRT_TO_BUS=y
-CONFIG_ARCH_SUPPORTS_AOUT=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -83,10 +84,16 @@ CONFIG_PROFILING=y
 # CONFIG_MARKERS is not set
 CONFIG_OPROFILE=y
 CONFIG_HAVE_OPROFILE=y
+# CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is not set
+# CONFIG_HAVE_IOREMAP_PROT is not set
 # CONFIG_HAVE_KPROBES is not set
 # CONFIG_HAVE_KRETPROBES is not set
+# CONFIG_HAVE_ARCH_TRACEHOOK is not set
 # CONFIG_HAVE_DMA_ATTRS is not set
+# CONFIG_USE_GENERIC_SMP_HELPERS is not set
+CONFIG_HAVE_CLK=y
 CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
@@ -96,12 +103,13 @@ CONFIG_MODULES=y
 # CONFIG_MODULE_UNLOAD is not set
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
-# CONFIG_KMOD is not set
+CONFIG_KMOD=y
 CONFIG_BLOCK=y
 # CONFIG_LBD is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_LSF is not set
 # CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
 
 #
 # IO Schedulers
@@ -177,6 +185,7 @@ CONFIG_PAGE_SIZE_4KB=y
 # CONFIG_PAGE_SIZE_8KB is not set
 # CONFIG_PAGE_SIZE_16KB is not set
 # CONFIG_PAGE_SIZE_64KB is not set
+CONFIG_ENTRY_OFFSET=0x00001000
 CONFIG_SELECT_MEMORY_MODEL=y
 # CONFIG_FLATMEM_MANUAL is not set
 # CONFIG_DISCONTIGMEM_MANUAL is not set
@@ -258,6 +267,7 @@ CONFIG_HZ=250
 # CONFIG_SCHED_HRTICK is not set
 # CONFIG_KEXEC is not set
 # CONFIG_CRASH_DUMP is not set
+CONFIG_SECCOMP=y
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
@@ -282,10 +292,6 @@ CONFIG_CMDLINE="console=ttySC2,115200 root=/dev/sda1 rootdelay=10"
 #
 CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
-
-#
-# Networking
-#
 CONFIG_NET=y
 
 #
@@ -361,6 +367,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 #
 # CONFIG_CFG80211 is not set
 CONFIG_WIRELESS_EXT=y
+CONFIG_WIRELESS_EXT_SYSFS=y
 # CONFIG_MAC80211 is not set
 # CONFIG_IEEE80211 is not set
 # CONFIG_RFKILL is not set
@@ -377,6 +384,8 @@ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
 # CONFIG_SYS_HYPERVISOR is not set
 # CONFIG_CONNECTOR is not set
 CONFIG_MTD=y
@@ -471,6 +480,7 @@ CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_RAM is not set
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_ATA_OVER_ETH is not set
+# CONFIG_BLK_DEV_HD is not set
 # CONFIG_MISC_DEVICES is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
@@ -515,10 +525,10 @@ CONFIG_SCSI_WAIT_SCAN=m
 CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_ISCSI_TCP is not set
 # CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_DH is not set
 # CONFIG_ATA is not set
 # CONFIG_MD is not set
 CONFIG_NETDEVICES=y
-# CONFIG_NETDEVICES_MULTIQUEUE is not set
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
@@ -546,7 +556,9 @@ CONFIG_NET_ETHERNET=y
 CONFIG_MII=y
 # CONFIG_AX88796 is not set
 # CONFIG_STNIC is not set
+CONFIG_SH_ETH=y
 # CONFIG_SMC91X is not set
+# CONFIG_SMC911X is not set
 # CONFIG_IBM_NEW_EMAC_ZMII is not set
 # CONFIG_IBM_NEW_EMAC_RGMII is not set
 # CONFIG_IBM_NEW_EMAC_TAH is not set
@@ -613,7 +625,11 @@ CONFIG_INPUT=y
 #
 # Character devices
 #
-# CONFIG_VT is not set
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
 CONFIG_DEVKMEM=y
 # CONFIG_SERIAL_NONSTANDARD is not set
 
@@ -644,6 +660,7 @@ CONFIG_HW_RANDOM=y
 # CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
 # CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
 # CONFIG_WATCHDOG is not set
 
 #
@@ -655,6 +672,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # Multifunction device drivers
 #
+# CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
 
@@ -679,7 +697,34 @@ CONFIG_SSB_POSSIBLE=y
 #
 # CONFIG_VGASTATE is not set
 # CONFIG_VIDEO_OUTPUT_CONTROL is not set
-# CONFIG_FB is not set
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+CONFIG_FB_FOREIGN_ENDIAN=y
+CONFIG_FB_BOTH_ENDIAN=y
+# CONFIG_FB_BIG_ENDIAN is not set
+# CONFIG_FB_LITTLE_ENDIAN is not set
+# CONFIG_FB_SYS_FOPS is not set
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_SH_MOBILE_LCDC is not set
+CONFIG_FB_SH7760=y
+# CONFIG_FB_VIRTUAL is not set
 # CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
@@ -688,8 +733,22 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_DISPLAY_SUPPORT is not set
 
 #
-# Sound
-#
+# Console display driver support
+#
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+# CONFIG_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+CONFIG_LOGO=y
+CONFIG_LOGO_LINUX_MONO=y
+CONFIG_LOGO_LINUX_VGA16=y
+CONFIG_LOGO_LINUX_CLUT224=y
+CONFIG_LOGO_SUPERH_MONO=y
+CONFIG_LOGO_SUPERH_VGA16=y
+CONFIG_LOGO_SUPERH_CLUT224=y
 # CONFIG_SOUND is not set
 # CONFIG_HID_SUPPORT is not set
 CONFIG_USB_SUPPORT=y
@@ -788,11 +847,27 @@ CONFIG_USB_MON=y
 # CONFIG_USB_IOWARRIOR is not set
 # CONFIG_USB_ISIGHTFW is not set
 # CONFIG_USB_GADGET is not set
-# CONFIG_MMC is not set
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
+
+#
+# MMC/SD Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_BOUNCE=y
+# CONFIG_SDIO_UART is not set
+# CONFIG_MMC_TEST is not set
+
+#
+# MMC/SD Host Controller Drivers
+#
+# CONFIG_MMC_SDHCI is not set
 # CONFIG_MEMSTICK is not set
 # CONFIG_NEW_LEDS is not set
 # CONFIG_ACCESSIBILITY is not set
 # CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
 # CONFIG_UIO is not set
 
 #
@@ -865,6 +940,7 @@ CONFIG_TMPFS_POSIX_ACL=y
 # CONFIG_CRAMFS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
 # CONFIG_HPFS_FS is not set
 # CONFIG_QNX4FS_FS is not set
 # CONFIG_ROMFS_FS is not set
@@ -874,12 +950,11 @@ CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 # CONFIG_NFS_V3 is not set
 # CONFIG_NFS_V4 is not set
-# CONFIG_NFSD is not set
 CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
 CONFIG_LOCKD=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_BIND34 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
@@ -949,6 +1024,7 @@ CONFIG_FRAME_WARN=1024
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 # CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_SAMPLES is not set
 # CONFIG_SH_STANDARD_BIOS is not set
 # CONFIG_EARLY_SCIF_CONSOLE is not set
@@ -1003,6 +1079,10 @@ CONFIG_CRYPTO=y
 # CONFIG_CRYPTO_MD4 is not set
 # CONFIG_CRYPTO_MD5 is not set
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
 # CONFIG_CRYPTO_SHA1 is not set
 # CONFIG_CRYPTO_SHA256 is not set
 # CONFIG_CRYPTO_SHA512 is not set
@@ -1042,6 +1122,7 @@ CONFIG_BITREVERSE=y
 # CONFIG_GENERIC_FIND_FIRST_BIT is not set
 # CONFIG_CRC_CCITT is not set
 # CONFIG_CRC16 is not set
+CONFIG_CRC_T10DIF=y
 # CONFIG_CRC_ITU_T is not set
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
index 0cc800299e06176ddda13085fa5369a48e19fdf1..d3b2b4f109e36ec68a61c7244ef7d4d48e9c335f 100644 (file)
 #define        flat_get_relocate_addr(rel)             (rel)
 #define        flat_set_persistent(relval, p)          ({ (void)p; 0; })
 
+#define FLAT_PLAT_INIT(_r) \
+  do { _r->regs[0]=0; _r->regs[1]=0; _r->regs[2]=0; _r->regs[3]=0; \
+       _r->regs[4]=0; _r->regs[5]=0; _r->regs[6]=0; _r->regs[7]=0; \
+       _r->regs[8]=0; _r->regs[9]=0; _r->regs[10]=0; _r->regs[11]=0; \
+       _r->regs[12]=0; _r->regs[13]=0; _r->regs[14]=0; \
+       _r->sr = SR_FD; } while (0)
+
 #endif /* __ASM_SH_FLAT_H */
index 10016e0f4a4e7c0986d5cef42441d566f2d5c432..c12b632c540bc27a18f6d350ff9e680a23a79b9b 100644 (file)
@@ -42,9 +42,6 @@
 
 #define PORT_MSELCRB 0xa4050182
 
-#define MSTPCR1 0xa4150034
-#define MSTPCR2 0xa4150038
-
 #define PORT_PSELA 0xa405014e
 #define PORT_PSELB 0xa4050150
 #define PORT_PSELC 0xa4050152
index 27677727df4dda34aabb60f54dcfd02a677198ab..130102f663f593eaceff1b884a4db798edad6731 100644 (file)
@@ -47,12 +47,18 @@ struct sh_mobile_lcdc_board_cfg {
        void (*display_off)(void *board_data);
 };
 
+struct sh_mobile_lcdc_lcd_size_cfg { /* width and height of panel in mm */
+       unsigned long width;
+       unsigned long height;
+};
+
 struct sh_mobile_lcdc_chan_cfg {
        int chan;
        int bpp;
        int interface_type; /* selects RGBn or SYSn I/F, see above */
        int clock_divider;
        struct fb_videomode lcd_cfg;
+       struct sh_mobile_lcdc_lcd_size_cfg lcd_size_cfg;
        struct sh_mobile_lcdc_board_cfg board_cfg;
        struct sh_mobile_lcdc_sys_bus_cfg sys_bus_cfg; /* only for SYSn I/F */
 };
index abc90988080750041fdbf73befcb057fd19cd95f..1ac27aae6700d377f5f3ea3b46ad8b8ddcd7b021 100644 (file)
@@ -29,6 +29,16 @@ void flush_cache_page(struct vm_area_struct *vma, unsigned long addr, unsigned l
 void flush_dcache_page(struct page *pg);
 void flush_icache_range(unsigned long start, unsigned long end);
 void flush_icache_page(struct vm_area_struct *vma, struct page *page);
+
+#define flush_dcache_mmap_lock(mapping)                do { } while (0)
+#define flush_dcache_mmap_unlock(mapping)      do { } while (0)
+
+/* SH3 has unified cache so no special action needed here */
+#define flush_cache_sigtramp(vaddr)            do { } while (0)
+#define flush_icache_user_range(vma,pg,adr,len)        do { } while (0)
+
+#define p3_cache_init()                                do { } while (0)
+
 #else
 #include <cpu-common/cpu/cacheflush.h>
 #endif
index cd6baffdc89624684f2fe0e88f8d4e173d292e02..a7412cede534f6cd5e3ef16d060cf1324f8bcd4b 100644 (file)
@@ -45,7 +45,7 @@ static struct platform_device vpu_device = {
 };
 
 static struct uio_info veu0_platform_data = {
-       .name = "VEU",
+       .name = "VEU2H",
        .version = "0",
        .irq = 54,
 };
@@ -73,7 +73,7 @@ static struct platform_device veu0_device = {
 };
 
 static struct uio_info veu1_platform_data = {
-       .name = "VEU",
+       .name = "VEU2H",
        .version = "0",
        .irq = 27,
 };
index 8f916536719c81261b443225d85e618baff4bd50..6e1b1c2716584a8bc79ab206098465029a700eea 100644 (file)
@@ -107,10 +107,12 @@ DECLARE_EXPORT(__movmemSI12_i4);
  * GCC >= 4.2 emits these for division, as do GCC 4.1.x versions of the ST
  * compiler which include backported patches.
  */
-DECLARE_EXPORT(__sdivsi3_i4i);
 DECLARE_EXPORT(__udiv_qrnnd_16);
+#if !defined(CONFIG_CPU_SH2)
+DECLARE_EXPORT(__sdivsi3_i4i);
 DECLARE_EXPORT(__udivsi3_i4i);
 #endif
+#endif
 #else /* GCC 3.x */
 DECLARE_EXPORT(__movstr_i4_even);
 DECLARE_EXPORT(__movstr_i4_odd);
index 9c131cac91a4e45a54a7233d430c72a5490f1c7e..8a03926ea84f21076c96b2775b49e4d27c7b0caf 100644 (file)
@@ -181,10 +181,12 @@ config ENTRY_OFFSET
 choice
        prompt "HugeTLB page size"
        depends on HUGETLB_PAGE && (CPU_SH4 || CPU_SH5) && MMU
+       default HUGETLB_PAGE_SIZE_1MB if PAGE_SIZE_64KB
        default HUGETLB_PAGE_SIZE_64K
 
 config HUGETLB_PAGE_SIZE_64K
        bool "64kB"
+       depends on !PAGE_SIZE_64KB
 
 config HUGETLB_PAGE_SIZE_256K
        bool "256kB"
index b2ce014401b5516ed8ae51c4ca98cf5d0c4a026e..895bb3f335c77f39481191e54739e8871674f7a1 100644 (file)
@@ -95,6 +95,29 @@ void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
 }
 EXPORT_SYMBOL(dma_cache_sync);
 
+static int __init memchunk_setup(char *str)
+{
+       return 1; /* accept anything that begins with "memchunk." */
+}
+__setup("memchunk.", memchunk_setup);
+
+static void memchunk_cmdline_override(char *name, unsigned long *sizep)
+{
+       char *p = boot_command_line;
+       int k = strlen(name);
+
+       while ((p = strstr(p, "memchunk."))) {
+               p += 9; /* strlen("memchunk.") */
+               if (!strncmp(name, p, k) && p[k] == '=') {
+                       p += k + 1;
+                       *sizep = memparse(p, NULL);
+                       pr_info("%s: forcing memory chunk size to 0x%08lx\n",
+                               name, *sizep);
+                       break;
+               }
+       }
+}
+
 int platform_resource_setup_memory(struct platform_device *pdev,
                                   char *name, unsigned long memsize)
 {
@@ -109,6 +132,10 @@ int platform_resource_setup_memory(struct platform_device *pdev,
                return -EINVAL;
        }
 
+       memchunk_cmdline_override(name, &memsize);
+       if (!memsize)
+               return 0;
+
        buf = dma_alloc_coherent(NULL, memsize, &dma_handle, GFP_KERNEL);
        if (!buf) {
                pr_warning("%s: unable to allocate memory\n", name);
index de39e1f2ede5f1c820f4abe9fa4f9ec07948419b..69b4d060b21c4c32e8e40b45c9dc2171c1b56505 100644 (file)
@@ -65,7 +65,7 @@ static int __iommu_queue_command(struct amd_iommu *iommu, struct iommu_cmd *cmd)
        u8 *target;
 
        tail = readl(iommu->mmio_base + MMIO_CMD_TAIL_OFFSET);
-       target = (iommu->cmd_buf + tail);
+       target = iommu->cmd_buf + tail;
        memcpy_toio(target, cmd, sizeof(*cmd));
        tail = (tail + sizeof(*cmd)) % iommu->cmd_buf_size;
        head = readl(iommu->mmio_base + MMIO_CMD_HEAD_OFFSET);
index 84a8220a6072c0425b9da95fbb28b5a309cbfda1..a6ef672adbbae01e8da2abb5bf2ae1cb32c091be 100644 (file)
@@ -56,9 +56,22 @@ void __cpuinit validate_pat_support(struct cpuinfo_x86 *c)
 
        switch (c->x86_vendor) {
        case X86_VENDOR_INTEL:
-               if (c->x86 == 0xF || (c->x86 == 6 && c->x86_model >= 15))
+               /*
+                * There is a known erratum on Pentium III and Core Solo
+                * and Core Duo CPUs.
+                * " Page with PAT set to WC while associated MTRR is UC
+                *   may consolidate to UC "
+                * Because of this erratum, it is better to stick with
+                * setting WC in MTRR rather than using PAT on these CPUs.
+                *
+                * Enable PAT WC only on P4, Core 2 or later CPUs.
+                */
+               if (c->x86 > 0x6 || (c->x86 == 6 && c->x86_model >= 15))
                        return;
-               break;
+
+               pat_disable("PAT WC disabled due to known CPU erratum.");
+               return;
+
        case X86_VENDOR_AMD:
        case X86_VENDOR_CENTAUR:
        case X86_VENDOR_TRANSMETA:
index 4e7271999a74e58ccf15203d005a646d9135686a..84bb395038d879823d5beb4e4bf2e181b8bd6b91 100644 (file)
@@ -737,63 +737,44 @@ static int find_psb_table(struct powernow_k8_data *data)
 #ifdef CONFIG_X86_POWERNOW_K8_ACPI
 static void powernow_k8_acpi_pst_values(struct powernow_k8_data *data, unsigned int index)
 {
-       if (!data->acpi_data->state_count || (cpu_family == CPU_HW_PSTATE))
+       if (!data->acpi_data.state_count || (cpu_family == CPU_HW_PSTATE))
                return;
 
-       data->irt = (data->acpi_data->states[index].control >> IRT_SHIFT) & IRT_MASK;
-       data->rvo = (data->acpi_data->states[index].control >> RVO_SHIFT) & RVO_MASK;
-       data->exttype = (data->acpi_data->states[index].control >> EXT_TYPE_SHIFT) & EXT_TYPE_MASK;
-       data->plllock = (data->acpi_data->states[index].control >> PLL_L_SHIFT) & PLL_L_MASK;
-       data->vidmvs = 1 << ((data->acpi_data->states[index].control >> MVS_SHIFT) & MVS_MASK);
-       data->vstable = (data->acpi_data->states[index].control >> VST_SHIFT) & VST_MASK;
-}
-
-
-static struct acpi_processor_performance *acpi_perf_data;
-static int preregister_valid;
-
-static int powernow_k8_cpu_preinit_acpi(void)
-{
-       acpi_perf_data = alloc_percpu(struct acpi_processor_performance);
-       if (!acpi_perf_data)
-               return -ENODEV;
-
-       if (acpi_processor_preregister_performance(acpi_perf_data))
-               return -ENODEV;
-       else
-               preregister_valid = 1;
-       return 0;
+       data->irt = (data->acpi_data.states[index].control >> IRT_SHIFT) & IRT_MASK;
+       data->rvo = (data->acpi_data.states[index].control >> RVO_SHIFT) & RVO_MASK;
+       data->exttype = (data->acpi_data.states[index].control >> EXT_TYPE_SHIFT) & EXT_TYPE_MASK;
+       data->plllock = (data->acpi_data.states[index].control >> PLL_L_SHIFT) & PLL_L_MASK;
+       data->vidmvs = 1 << ((data->acpi_data.states[index].control >> MVS_SHIFT) & MVS_MASK);
+       data->vstable = (data->acpi_data.states[index].control >> VST_SHIFT) & VST_MASK;
 }
 
 static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data)
 {
        struct cpufreq_frequency_table *powernow_table;
        int ret_val;
-       int cpu = 0;
 
-       data->acpi_data = percpu_ptr(acpi_perf_data, cpu);
-       if (acpi_processor_register_performance(data->acpi_data, data->cpu)) {
+       if (acpi_processor_register_performance(&data->acpi_data, data->cpu)) {
                dprintk("register performance failed: bad ACPI data\n");
                return -EIO;
        }
 
        /* verify the data contained in the ACPI structures */
-       if (data->acpi_data->state_count <= 1) {
+       if (data->acpi_data.state_count <= 1) {
                dprintk("No ACPI P-States\n");
                goto err_out;
        }
 
-       if ((data->acpi_data->control_register.space_id != ACPI_ADR_SPACE_FIXED_HARDWARE) ||
-               (data->acpi_data->status_register.space_id != ACPI_ADR_SPACE_FIXED_HARDWARE)) {
+       if ((data->acpi_data.control_register.space_id != ACPI_ADR_SPACE_FIXED_HARDWARE) ||
+               (data->acpi_data.status_register.space_id != ACPI_ADR_SPACE_FIXED_HARDWARE)) {
                dprintk("Invalid control/status registers (%x - %x)\n",
-                       data->acpi_data->control_register.space_id,
-                       data->acpi_data->status_register.space_id);
+                       data->acpi_data.control_register.space_id,
+                       data->acpi_data.status_register.space_id);
                goto err_out;
        }
 
        /* fill in data->powernow_table */
        powernow_table = kmalloc((sizeof(struct cpufreq_frequency_table)
-               * (data->acpi_data->state_count + 1)), GFP_KERNEL);
+               * (data->acpi_data.state_count + 1)), GFP_KERNEL);
        if (!powernow_table) {
                dprintk("powernow_table memory alloc failure\n");
                goto err_out;
@@ -806,12 +787,12 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data)
        if (ret_val)
                goto err_out_mem;
 
-       powernow_table[data->acpi_data->state_count].frequency = CPUFREQ_TABLE_END;
-       powernow_table[data->acpi_data->state_count].index = 0;
+       powernow_table[data->acpi_data.state_count].frequency = CPUFREQ_TABLE_END;
+       powernow_table[data->acpi_data.state_count].index = 0;
        data->powernow_table = powernow_table;
 
        /* fill in data */
-       data->numps = data->acpi_data->state_count;
+       data->numps = data->acpi_data.state_count;
        if (first_cpu(per_cpu(cpu_core_map, data->cpu)) == data->cpu)
                print_basics(data);
        powernow_k8_acpi_pst_values(data, 0);
@@ -819,31 +800,16 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data)
        /* notify BIOS that we exist */
        acpi_processor_notify_smm(THIS_MODULE);
 
-       /* determine affinity, from ACPI if available */
-       if (preregister_valid) {
-               if ((data->acpi_data->shared_type == CPUFREQ_SHARED_TYPE_ALL) ||
-                       (data->acpi_data->shared_type == CPUFREQ_SHARED_TYPE_ANY))
-                       data->starting_core_affinity = data->acpi_data->shared_cpu_map;
-               else
-                       data->starting_core_affinity = cpumask_of_cpu(data->cpu);
-       } else {
-       /* best guess from family if not */
-               if (cpu_family == CPU_HW_PSTATE)
-                       data->starting_core_affinity = cpumask_of_cpu(data->cpu);
-               else
-                       data->starting_core_affinity = per_cpu(cpu_core_map, data->cpu);
-       }
-
        return 0;
 
 err_out_mem:
        kfree(powernow_table);
 
 err_out:
-       acpi_processor_unregister_performance(data->acpi_data, data->cpu);
+       acpi_processor_unregister_performance(&data->acpi_data, data->cpu);
 
        /* data->acpi_data.state_count informs us at ->exit() whether ACPI was used */
-       data->acpi_data->state_count = 0;
+       data->acpi_data.state_count = 0;
 
        return -ENODEV;
 }
@@ -855,10 +821,10 @@ static int fill_powernow_table_pstate(struct powernow_k8_data *data, struct cpuf
        rdmsr(MSR_PSTATE_CUR_LIMIT, hi, lo);
        data->max_hw_pstate = (hi & HW_PSTATE_MAX_MASK) >> HW_PSTATE_MAX_SHIFT;
 
-       for (i = 0; i < data->acpi_data->state_count; i++) {
+       for (i = 0; i < data->acpi_data.state_count; i++) {
                u32 index;
 
-               index = data->acpi_data->states[i].control & HW_PSTATE_MASK;
+               index = data->acpi_data.states[i].control & HW_PSTATE_MASK;
                if (index > data->max_hw_pstate) {
                        printk(KERN_ERR PFX "invalid pstate %d - bad value %d.\n", i, index);
                        printk(KERN_ERR PFX "Please report to BIOS manufacturer\n");
@@ -874,7 +840,7 @@ static int fill_powernow_table_pstate(struct powernow_k8_data *data, struct cpuf
 
                powernow_table[i].index = index;
 
-               powernow_table[i].frequency = data->acpi_data->states[i].core_frequency * 1000;
+               powernow_table[i].frequency = data->acpi_data.states[i].core_frequency * 1000;
        }
        return 0;
 }
@@ -883,16 +849,16 @@ static int fill_powernow_table_fidvid(struct powernow_k8_data *data, struct cpuf
 {
        int i;
        int cntlofreq = 0;
-       for (i = 0; i < data->acpi_data->state_count; i++) {
+       for (i = 0; i < data->acpi_data.state_count; i++) {
                u32 fid;
                u32 vid;
 
                if (data->exttype) {
-                       fid = data->acpi_data->states[i].status & EXT_FID_MASK;
-                       vid = (data->acpi_data->states[i].status >> VID_SHIFT) & EXT_VID_MASK;
+                       fid = data->acpi_data.states[i].status & EXT_FID_MASK;
+                       vid = (data->acpi_data.states[i].status >> VID_SHIFT) & EXT_VID_MASK;
                } else {
-                       fid = data->acpi_data->states[i].control & FID_MASK;
-                       vid = (data->acpi_data->states[i].control >> VID_SHIFT) & VID_MASK;
+                       fid = data->acpi_data.states[i].control & FID_MASK;
+                       vid = (data->acpi_data.states[i].control >> VID_SHIFT) & VID_MASK;
                }
 
                dprintk("   %d : fid 0x%x, vid 0x%x\n", i, fid, vid);
@@ -933,10 +899,10 @@ static int fill_powernow_table_fidvid(struct powernow_k8_data *data, struct cpuf
                                cntlofreq = i;
                }
 
-               if (powernow_table[i].frequency != (data->acpi_data->states[i].core_frequency * 1000)) {
+               if (powernow_table[i].frequency != (data->acpi_data.states[i].core_frequency * 1000)) {
                        printk(KERN_INFO PFX "invalid freq entries %u kHz vs. %u kHz\n",
                                powernow_table[i].frequency,
-                               (unsigned int) (data->acpi_data->states[i].core_frequency * 1000));
+                               (unsigned int) (data->acpi_data.states[i].core_frequency * 1000));
                        powernow_table[i].frequency = CPUFREQ_ENTRY_INVALID;
                        continue;
                }
@@ -946,12 +912,11 @@ static int fill_powernow_table_fidvid(struct powernow_k8_data *data, struct cpuf
 
 static void powernow_k8_cpu_exit_acpi(struct powernow_k8_data *data)
 {
-       if (data->acpi_data->state_count)
-               acpi_processor_unregister_performance(data->acpi_data, data->cpu);
+       if (data->acpi_data.state_count)
+               acpi_processor_unregister_performance(&data->acpi_data, data->cpu);
 }
 
 #else
-static int powernow_k8_cpu_preinit_acpi(void) { return -ENODEV; }
 static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data) { return -ENODEV; }
 static void powernow_k8_cpu_exit_acpi(struct powernow_k8_data *data) { return; }
 static void powernow_k8_acpi_pst_values(struct powernow_k8_data *data, unsigned int index) { return; }
@@ -1136,7 +1101,7 @@ static int powernowk8_verify(struct cpufreq_policy *pol)
 static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol)
 {
        struct powernow_k8_data *data;
-       cpumask_t oldmask = CPU_MASK_ALL;
+       cpumask_t oldmask;
        int rc;
 
        if (!cpu_online(pol->cpu))
@@ -1209,7 +1174,10 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol)
        /* run on any CPU again */
        set_cpus_allowed_ptr(current, &oldmask);
 
-       pol->cpus = data->starting_core_affinity;
+       if (cpu_family == CPU_HW_PSTATE)
+               pol->cpus = cpumask_of_cpu(pol->cpu);
+       else
+               pol->cpus = per_cpu(cpu_core_map, pol->cpu);
        data->available_cores = &(pol->cpus);
 
        /* Take a crude guess here.
@@ -1332,7 +1300,6 @@ static int __cpuinit powernowk8_init(void)
        }
 
        if (supported_cpus == num_online_cpus()) {
-               powernow_k8_cpu_preinit_acpi();
                printk(KERN_INFO PFX "Found %d %s "
                        "processors (%d cpu cores) (" VERSION ")\n",
                        num_online_nodes(),
@@ -1349,10 +1316,6 @@ static void __exit powernowk8_exit(void)
        dprintk("exit\n");
 
        cpufreq_unregister_driver(&cpufreq_amd64_driver);
-
-#ifdef CONFIG_X86_POWERNOW_K8_ACPI
-       free_percpu(acpi_perf_data);
-#endif
 }
 
 MODULE_AUTHOR("Paul Devriendt <paul.devriendt@amd.com> and Mark Langsdorf <mark.langsdorf@amd.com>");
index a62612cd4be89c2e775edf5d9c71da41cf0a4b64..ab48cfed4d96ce5629e29f3a21ffd9c3e25d8a21 100644 (file)
@@ -33,13 +33,12 @@ struct powernow_k8_data {
 #ifdef CONFIG_X86_POWERNOW_K8_ACPI
        /* the acpi table needs to be kept. it's only available if ACPI was
         * used to determine valid frequency/vid/fid states */
-       struct acpi_processor_performance *acpi_data;
+       struct acpi_processor_performance acpi_data;
 #endif
        /* we need to keep track of associated cores, but let cpufreq
         * handle hotplug events - so just point at cpufreq pol->cpus
         * structure */
        cpumask_t *available_cores;
-       cpumask_t starting_core_affinity;
 };
 
 
index 3fd7a67bb06aa7db7f9350e2a34203cb94c3240a..e710a21bb6e8dc0dd9d83a7bd49df69135cbcf7b 100644 (file)
@@ -134,23 +134,6 @@ static void __cpuinit set_cx86_memwb(void)
        setCx86(CX86_CCR2, getCx86(CX86_CCR2) | 0x14);
 }
 
-static void __cpuinit set_cx86_inc(void)
-{
-       unsigned char ccr3;
-
-       printk(KERN_INFO "Enable Incrementor on Cyrix/NSC processor.\n");
-
-       ccr3 = getCx86(CX86_CCR3);
-       setCx86(CX86_CCR3, (ccr3 & 0x0f) | 0x10); /* enable MAPEN */
-       /* PCR1 -- Performance Control */
-       /* Incrementor on, whatever that is */
-       setCx86(CX86_PCR1, getCx86(CX86_PCR1) | 0x02);
-       /* PCR0 -- Performance Control */
-       /* Incrementor Margin 10 */
-       setCx86(CX86_PCR0, getCx86(CX86_PCR0) | 0x04);
-       setCx86(CX86_CCR3, ccr3);       /* disable MAPEN */
-}
-
 /*
  *     Configure later MediaGX and/or Geode processor.
  */
@@ -174,7 +157,6 @@ static void __cpuinit geode_configure(void)
 
        set_cx86_memwb();
        set_cx86_reorder();
-       set_cx86_inc();
 
        local_irq_restore(flags);
 }
index 509bd3d9eacd28da737ade7a365f1a17acf71a11..cb7d3b6a80eb879670bd8a74864d01b587561dec 100644 (file)
@@ -379,6 +379,7 @@ static void generic_get_mtrr(unsigned int reg, unsigned long *base,
                             unsigned long *size, mtrr_type *type)
 {
        unsigned int mask_lo, mask_hi, base_lo, base_hi;
+       unsigned int tmp, hi;
 
        rdmsr(MTRRphysMask_MSR(reg), mask_lo, mask_hi);
        if ((mask_lo & 0x800) == 0) {
@@ -392,8 +393,23 @@ static void generic_get_mtrr(unsigned int reg, unsigned long *base,
        rdmsr(MTRRphysBase_MSR(reg), base_lo, base_hi);
 
        /* Work out the shifted address mask. */
-       mask_lo = size_or_mask | mask_hi << (32 - PAGE_SHIFT)
-           | mask_lo >> PAGE_SHIFT;
+       tmp = mask_hi << (32 - PAGE_SHIFT) | mask_lo >> PAGE_SHIFT;
+       mask_lo = size_or_mask | tmp;
+       /* Expand tmp with high bits to all 1s*/
+       hi = fls(tmp);
+       if (hi > 0) {
+               tmp |= ~((1<<(hi - 1)) - 1);
+
+               if (tmp != mask_lo) {
+                       static int once = 1;
+
+                       if (once) {
+                               printk(KERN_INFO "mtrr: your BIOS has set up an incorrect mask, fixing it up.\n");
+                               once = 0;
+                       }
+                       mask_lo = tmp;
+               }
+       }
 
        /* This works correctly if size is a power of two, i.e. a
           contiguous range. */
index 6f23969c8fafe4f1dd2b4304a910c11483833f2d..b117d7f8a5640fe51091f46247671dff5d61524e 100644 (file)
@@ -1496,11 +1496,8 @@ int __init mtrr_trim_uncached_memory(unsigned long end_pfn)
 
        /* kvm/qemu doesn't have mtrr set right, don't trim them all */
        if (!highest_pfn) {
-               if (!kvm_para_available()) {
-                       printk(KERN_WARNING
+               WARN(!kvm_para_available(), KERN_WARNING
                                "WARNING: strange, CPU MTRRs all blank?\n");
-                       WARN_ON(1);
-               }
                return 0;
        }
 
index 2d7e307c7779c98ea412b67faa1b1dbddc7303f6..bfa837cb16be83799fa1ee7e28bedca5dbe38e40 100644 (file)
@@ -293,7 +293,9 @@ static __init void uv_rtc_init(void)
                sn_rtc_cycles_per_second = ticks_per_sec;
 }
 
-static __init void uv_system_init(void)
+static bool uv_system_inited;
+
+void __init uv_system_init(void)
 {
        union uvh_si_addr_map_config_u m_n_config;
        union uvh_node_id_u node_id;
@@ -383,6 +385,7 @@ static __init void uv_system_init(void)
        map_mmr_high(max_pnode);
        map_config_high(max_pnode);
        map_mmioh_high(max_pnode);
+       uv_system_inited = true;
 }
 
 /*
@@ -391,8 +394,7 @@ static __init void uv_system_init(void)
  */
 void __cpuinit uv_cpu_init(void)
 {
-       if (!uv_node_to_blade)
-               uv_system_init();
+       BUG_ON(!uv_system_inited);
 
        uv_blade_info[uv_numa_blade_id()].nr_online_cpus++;
 
index b8c45610b20a89a6f52f9b266d68de042d688168..eecc8c18f01016a502edf711df6e9ebff61dde8f 100644 (file)
@@ -73,7 +73,7 @@ static void __init smp_dump_qct(void)
 }
 
 
-void __init numaq_tsc_disable(void)
+void __cpuinit numaq_tsc_disable(void)
 {
        if (!found_numaq)
                return;
index 94da4d52d798e8490f21c59c777df72d6bba86d5..300da17e61cbef997d527031a49bb1e81addf897 100644 (file)
@@ -471,7 +471,7 @@ struct pv_lock_ops pv_lock_ops = {
        .spin_unlock = __ticket_spin_unlock,
 #endif
 };
-EXPORT_SYMBOL_GPL(pv_lock_ops);
+EXPORT_SYMBOL(pv_lock_ops);
 
 EXPORT_SYMBOL_GPL(pv_time_ops);
 EXPORT_SYMBOL    (pv_cpu_ops);
index 218d783ed7a8969bae11bd86750a8121e8030fdd..dcdac6c826e98047138f1e915e2d6b6ffbaf5ddd 100644 (file)
@@ -343,9 +343,8 @@ static void iommu_free(struct iommu_table *tbl, dma_addr_t dma_addr,
        /* were we called with bad_dma_address? */
        badend = bad_dma_address + (EMERGENCY_PAGES * PAGE_SIZE);
        if (unlikely((dma_addr >= bad_dma_address) && (dma_addr < badend))) {
-               printk(KERN_ERR "Calgary: driver tried unmapping bad DMA "
+               WARN(1, KERN_ERR "Calgary: driver tried unmapping bad DMA "
                       "address 0x%Lx\n", dma_addr);
-               WARN_ON(1);
                return;
        }
 
@@ -1269,13 +1268,15 @@ static inline int __init determine_tce_table_size(u64 ram)
 static int __init build_detail_arrays(void)
 {
        unsigned long ptr;
-       int i, scal_detail_size, rio_detail_size;
+       unsigned numnodes, i;
+       int scal_detail_size, rio_detail_size;
 
-       if (rio_table_hdr->num_scal_dev > MAX_NUMNODES){
+       numnodes = rio_table_hdr->num_scal_dev;
+       if (numnodes > MAX_NUMNODES){
                printk(KERN_WARNING
                        "Calgary: MAX_NUMNODES too low! Defined as %d, "
                        "but system has %d nodes.\n",
-                       MAX_NUMNODES, rio_table_hdr->num_scal_dev);
+                       MAX_NUMNODES, numnodes);
                return -ENODEV;
        }
 
@@ -1296,8 +1297,7 @@ static int __init build_detail_arrays(void)
        }
 
        ptr = ((unsigned long)rio_table_hdr) + 3;
-       for (i = 0; i < rio_table_hdr->num_scal_dev;
-                   i++, ptr += scal_detail_size)
+       for (i = 0; i < numnodes; i++, ptr += scal_detail_size)
                scal_devs[i] = (struct scal_detail *)ptr;
 
        for (i = 0; i < rio_table_hdr->num_rio_dev;
index a4656adab53b356d36d787b9c2067af703ff0b36..362d4e7f2d389b81e345fa27b13db78e80c5980a 100644 (file)
@@ -604,14 +604,6 @@ void __init setup_arch(char **cmdline_p)
        early_cpu_init();
        early_ioremap_init();
 
-#if defined(CONFIG_VMI) && defined(CONFIG_X86_32)
-       /*
-        * Must be before kernel pagetables are setup
-        * or fixmap area is touched.
-        */
-       vmi_init();
-#endif
-
        ROOT_DEV = old_decode_dev(boot_params.hdr.root_dev);
        screen_info = boot_params.screen_info;
        edid_info = boot_params.edid_info;
@@ -678,6 +670,14 @@ void __init setup_arch(char **cmdline_p)
 
        parse_early_param();
 
+#if defined(CONFIG_VMI) && defined(CONFIG_X86_32)
+       /*
+        * Must be before kernel pagetables are setup
+        * or fixmap area is touched.
+        */
+       vmi_init();
+#endif
+
        /* after early param, so could get panic from serial */
        reserve_early_setup_data();
 
index e139e617f422a932238393b7c5d180f289cd268e..7985c5b3f9162ba14c0817ce25f1297b34a87a5c 100644 (file)
@@ -1221,6 +1221,9 @@ void __init native_smp_prepare_cpus(unsigned int max_cpus)
        printk(KERN_INFO "CPU%d: ", 0);
        print_cpu_info(&cpu_data(0));
        setup_boot_clock();
+
+       if (is_uv_system())
+               uv_system_init();
 out:
        preempt_enable();
 }
index d0fbb7712ab05d5ae0359c0b10db4287db742d9f..8b8c0d6640fa9ba9ca7da73fac2cb4ee52e7be26 100644 (file)
@@ -17,6 +17,7 @@
 #include <asm/genapic.h>
 #include <asm/idle.h>
 #include <asm/tsc.h>
+#include <asm/irq_vectors.h>
 
 #include <mach_apic.h>
 
@@ -783,7 +784,7 @@ static int __init uv_bau_init(void)
                uv_init_blade(blade, node, cur_cpu);
                cur_cpu += uv_blade_nr_possible_cpus(blade);
        }
-       set_intr_gate(UV_BAU_MESSAGE, uv_bau_message_intr1);
+       alloc_intr_gate(UV_BAU_MESSAGE, uv_bau_message_intr1);
        uv_enable_timeouts();
 
        return 0;
index 0577825cf89bad5ecdac456fa13d12f4b8e2fa0e..9ffb01c31c40a8c9083e9949d065a442a62f46b7 100644 (file)
@@ -88,11 +88,9 @@ static __cpuinit void check_tsc_warp(void)
                        __raw_spin_unlock(&sync_lock);
                }
        }
-       if (!(now-start)) {
-               printk("Warning: zero tsc calibration delta: %Ld [max: %Ld]\n",
+       WARN(!(now-start),
+               "Warning: zero tsc calibration delta: %Ld [max: %Ld]\n",
                        now-start, end-start);
-               WARN_ON(1);
-       }
 }
 
 /*
index f72ac1fa35f0bfe07b74b43f2275c28402518c9e..4a814bff21f27cb9b829df36071ffb40b43818ca 100644 (file)
@@ -345,7 +345,7 @@ static u64 *FNAME(fetch)(struct kvm_vcpu *vcpu, gva_t addr,
                shadow_addr = __pa(shadow_page->spt);
                shadow_pte = shadow_addr | PT_PRESENT_MASK | PT_ACCESSED_MASK
                        | PT_WRITABLE_MASK | PT_USER_MASK;
-               *shadow_ent = shadow_pte;
+               set_shadow_pte(shadow_ent, shadow_pte);
        }
 
        mmu_set_spte(vcpu, shadow_ent, access, walker->pte_access & access,
index a037041817c75edcf070a8dc0acfd1f457297c1c..4f4e50c3ad3b1f4a46f327301739fa631442877f 100644 (file)
@@ -25,7 +25,6 @@
 #include <linux/list.h>
 #include <linux/device.h>
 #include <linux/platform_device.h>
-#include <linux/version.h>
 #include <linux/leds.h>
 
 #include <asm/gpio.h>
index a87ea0e4b3dca3e7149aa03321af508cc1216b0d..d3746efb060d1602a9de63d3be955522f0cd2a5d 100644 (file)
@@ -241,7 +241,7 @@ static unsigned long __initdata table_start;
 static unsigned long __meminitdata table_end;
 static unsigned long __meminitdata table_top;
 
-static __meminit void *alloc_low_page(unsigned long *phys)
+static __ref void *alloc_low_page(unsigned long *phys)
 {
        unsigned long pfn = table_end++;
        void *adr;
@@ -262,7 +262,7 @@ static __meminit void *alloc_low_page(unsigned long *phys)
        return adr;
 }
 
-static __meminit void unmap_low_page(void *adr)
+static __ref void unmap_low_page(void *adr)
 {
        if (after_bootmem)
                return;
@@ -336,9 +336,12 @@ phys_pmd_init(pmd_t *pmd_page, unsigned long address, unsigned long end,
                }
 
                if (pmd_val(*pmd)) {
-                       if (!pmd_large(*pmd))
+                       if (!pmd_large(*pmd)) {
+                               spin_lock(&init_mm.page_table_lock);
                                last_map_addr = phys_pte_update(pmd, address,
-                                                                end);
+                                                               end);
+                               spin_unlock(&init_mm.page_table_lock);
+                       }
                        /* Count entries we're using from level2_ident_pgt */
                        if (start == 0)
                                pages++;
@@ -347,8 +350,10 @@ phys_pmd_init(pmd_t *pmd_page, unsigned long address, unsigned long end,
 
                if (page_size_mask & (1<<PG_LEVEL_2M)) {
                        pages++;
+                       spin_lock(&init_mm.page_table_lock);
                        set_pte((pte_t *)pmd,
                                pfn_pte(address >> PAGE_SHIFT, PAGE_KERNEL_LARGE));
+                       spin_unlock(&init_mm.page_table_lock);
                        last_map_addr = (address & PMD_MASK) + PMD_SIZE;
                        continue;
                }
@@ -357,7 +362,9 @@ phys_pmd_init(pmd_t *pmd_page, unsigned long address, unsigned long end,
                last_map_addr = phys_pte_init(pte, address, end);
                unmap_low_page(pte);
 
+               spin_lock(&init_mm.page_table_lock);
                pmd_populate_kernel(&init_mm, pmd, __va(pte_phys));
+               spin_unlock(&init_mm.page_table_lock);
        }
        update_page_count(PG_LEVEL_2M, pages);
        return last_map_addr;
@@ -370,9 +377,7 @@ phys_pmd_update(pud_t *pud, unsigned long address, unsigned long end,
        pmd_t *pmd = pmd_offset(pud, 0);
        unsigned long last_map_addr;
 
-       spin_lock(&init_mm.page_table_lock);
        last_map_addr = phys_pmd_init(pmd, address, end, page_size_mask);
-       spin_unlock(&init_mm.page_table_lock);
        __flush_tlb_all();
        return last_map_addr;
 }
@@ -408,20 +413,21 @@ phys_pud_init(pud_t *pud_page, unsigned long addr, unsigned long end,
 
                if (page_size_mask & (1<<PG_LEVEL_1G)) {
                        pages++;
+                       spin_lock(&init_mm.page_table_lock);
                        set_pte((pte_t *)pud,
                                pfn_pte(addr >> PAGE_SHIFT, PAGE_KERNEL_LARGE));
+                       spin_unlock(&init_mm.page_table_lock);
                        last_map_addr = (addr & PUD_MASK) + PUD_SIZE;
                        continue;
                }
 
                pmd = alloc_low_page(&pmd_phys);
-
-               spin_lock(&init_mm.page_table_lock);
                last_map_addr = phys_pmd_init(pmd, addr, end, page_size_mask);
                unmap_low_page(pmd);
+
+               spin_lock(&init_mm.page_table_lock);
                pud_populate(&init_mm, pud, __va(pmd_phys));
                spin_unlock(&init_mm.page_table_lock);
-
        }
        __flush_tlb_all();
        update_page_count(PG_LEVEL_1G, pages);
@@ -513,16 +519,14 @@ static unsigned long __init kernel_physical_mapping_init(unsigned long start,
                        continue;
                }
 
-               if (after_bootmem)
-                       pud = pud_offset(pgd, start & PGDIR_MASK);
-               else
-                       pud = alloc_low_page(&pud_phys);
-
+               pud = alloc_low_page(&pud_phys);
                last_map_addr = phys_pud_init(pud, __pa(start), __pa(next),
                                                 page_size_mask);
                unmap_low_page(pud);
-               pgd_populate(&init_mm, pgd_offset_k(start),
-                            __va(pud_phys));
+
+               spin_lock(&init_mm.page_table_lock);
+               pgd_populate(&init_mm, pgd, __va(pud_phys));
+               spin_unlock(&init_mm.page_table_lock);
        }
 
        return last_map_addr;
index 6ba6f889c79da6f7c0370df17ef529cf5dd16a93..d4b6e6a29ae3597c45071805f734a502a12d6ab2 100644 (file)
@@ -553,13 +553,11 @@ static int __init check_early_ioremap_leak(void)
 {
        if (!early_ioremap_nested)
                return 0;
-
-       printk(KERN_WARNING
+       WARN(1, KERN_WARNING
               "Debug warning: early ioremap leak of %d areas detected.\n",
-              early_ioremap_nested);
+               early_ioremap_nested);
        printk(KERN_WARNING
-              "please boot with early_ioremap_debug and report the dmesg.\n");
-       WARN_ON(1);
+               "please boot with early_ioremap_debug and report the dmesg.\n");
 
        return 1;
 }
index e7397e108beb2d55c192eee9413a28468ac66fb6..635b50e85581de29bc4a9d32ffbd82da6612838c 100644 (file)
@@ -430,7 +430,9 @@ static void enter_uniprocessor(void)
                                                "may miss events.\n");
 }
 
-static void leave_uniprocessor(void)
+/* __ref because leave_uniprocessor calls cpu_up which is __cpuinit,
+   but this whole function is ifdefed CONFIG_HOTPLUG_CPU */
+static void __ref leave_uniprocessor(void)
 {
        int cpu;
        int err;
index f5f5154ea11e4b788d98a9a12e4d23ddd28e4525..43e2f8483e4f59c33559263c0011e1e5bf041f9d 100644 (file)
@@ -849,7 +849,7 @@ int set_memory_uc(unsigned long addr, int numpages)
        /*
         * for now UC MINUS. see comments in ioremap_nocache()
         */
-       if (reserve_memtype(addr, addr + numpages * PAGE_SIZE,
+       if (reserve_memtype(__pa(addr), __pa(addr) + numpages * PAGE_SIZE,
                            _PAGE_CACHE_UC_MINUS, NULL))
                return -EINVAL;
 
@@ -868,7 +868,7 @@ int set_memory_wc(unsigned long addr, int numpages)
        if (!pat_enabled)
                return set_memory_uc(addr, numpages);
 
-       if (reserve_memtype(addr, addr + numpages * PAGE_SIZE,
+       if (reserve_memtype(__pa(addr), __pa(addr) + numpages * PAGE_SIZE,
                _PAGE_CACHE_WC, NULL))
                return -EINVAL;
 
@@ -884,7 +884,7 @@ int _set_memory_wb(unsigned long addr, int numpages)
 
 int set_memory_wb(unsigned long addr, int numpages)
 {
-       free_memtype(addr, addr + numpages * PAGE_SIZE);
+       free_memtype(__pa(addr), __pa(addr) + numpages * PAGE_SIZE);
 
        return _set_memory_wb(addr, numpages);
 }
index 2fe30916d4b66aba6ea1121a9d5bfadb60f1c82f..2a50e0fa64a53290726e9eb1d1b4252afcce1fc8 100644 (file)
@@ -207,6 +207,9 @@ static int chk_conflict(struct memtype *new, struct memtype *entry,
        return -EBUSY;
 }
 
+static struct memtype *cached_entry;
+static u64 cached_start;
+
 /*
  * req_type typically has one of the:
  * - _PAGE_CACHE_WB
@@ -280,11 +283,17 @@ int reserve_memtype(u64 start, u64 end, unsigned long req_type,
 
        spin_lock(&memtype_lock);
 
+       if (cached_entry && start >= cached_start)
+               entry = cached_entry;
+       else
+               entry = list_entry(&memtype_list, struct memtype, nd);
+
        /* Search for existing mapping that overlaps the current range */
        where = NULL;
-       list_for_each_entry(entry, &memtype_list, nd) {
+       list_for_each_entry_continue(entry, &memtype_list, nd) {
                if (end <= entry->start) {
                        where = entry->nd.prev;
+                       cached_entry = list_entry(where, struct memtype, nd);
                        break;
                } else if (start <= entry->start) { /* end > entry->start */
                        err = chk_conflict(new, entry, new_type);
@@ -292,6 +301,8 @@ int reserve_memtype(u64 start, u64 end, unsigned long req_type,
                                dprintk("Overlap at 0x%Lx-0x%Lx\n",
                                        entry->start, entry->end);
                                where = entry->nd.prev;
+                               cached_entry = list_entry(where,
+                                                       struct memtype, nd);
                        }
                        break;
                } else if (start < entry->end) { /* start > entry->start */
@@ -299,7 +310,20 @@ int reserve_memtype(u64 start, u64 end, unsigned long req_type,
                        if (!err) {
                                dprintk("Overlap at 0x%Lx-0x%Lx\n",
                                        entry->start, entry->end);
-                               where = &entry->nd;
+                               cached_entry = list_entry(entry->nd.prev,
+                                                       struct memtype, nd);
+
+                               /*
+                                * Move to right position in the linked
+                                * list to add this new entry
+                                */
+                               list_for_each_entry_continue(entry,
+                                                       &memtype_list, nd) {
+                                       if (start <= entry->start) {
+                                               where = entry->nd.prev;
+                                               break;
+                                       }
+                               }
                        }
                        break;
                }
@@ -314,6 +338,8 @@ int reserve_memtype(u64 start, u64 end, unsigned long req_type,
                return err;
        }
 
+       cached_start = start;
+
        if (where)
                list_add(&new->nd, where);
        else
@@ -343,6 +369,9 @@ int free_memtype(u64 start, u64 end)
        spin_lock(&memtype_lock);
        list_for_each_entry(entry, &memtype_list, nd) {
                if (entry->start == start && entry->end == end) {
+                       if (cached_entry == entry || cached_start == start)
+                               cached_entry = NULL;
+
                        list_del(&entry->nd);
                        kfree(entry);
                        err = 0;
@@ -361,14 +390,6 @@ int free_memtype(u64 start, u64 end)
 }
 
 
-/*
- * /dev/mem mmap interface. The memtype used for mapping varies:
- * - Use UC for mappings with O_SYNC flag
- * - Without O_SYNC flag, if there is any conflict in reserve_memtype,
- *   inherit the memtype from existing mapping.
- * - Else use UC_MINUS memtype (for backward compatibility with existing
- *   X drivers.
- */
 pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
                                unsigned long size, pgprot_t vma_prot)
 {
@@ -406,14 +427,14 @@ int phys_mem_access_prot_allowed(struct file *file, unsigned long pfn,
                                unsigned long size, pgprot_t *vma_prot)
 {
        u64 offset = ((u64) pfn) << PAGE_SHIFT;
-       unsigned long flags = _PAGE_CACHE_UC_MINUS;
+       unsigned long flags = -1;
        int retval;
 
        if (!range_is_allowed(pfn, size))
                return 0;
 
        if (file->f_flags & O_SYNC) {
-               flags = _PAGE_CACHE_UC;
+               flags = _PAGE_CACHE_UC_MINUS;
        }
 
 #ifdef CONFIG_X86_32
@@ -436,13 +457,14 @@ int phys_mem_access_prot_allowed(struct file *file, unsigned long pfn,
 #endif
 
        /*
-        * With O_SYNC, we can only take UC mapping. Fail if we cannot.
+        * With O_SYNC, we can only take UC_MINUS mapping. Fail if we cannot.
+        *
         * Without O_SYNC, we want to get
         * - WB for WB-able memory and no other conflicting mappings
         * - UC_MINUS for non-WB-able memory with no other conflicting mappings
         * - Inherit from confliting mappings otherwise
         */
-       if (flags != _PAGE_CACHE_UC_MINUS) {
+       if (flags != -1) {
                retval = reserve_memtype(offset, offset + size, flags, NULL);
        } else {
                retval = reserve_memtype(offset, offset + size, -1, &flags);
index 3f90289410e6fbfc81fa1b350f7d6fdce4ecd18c..0227694f7dab9b156350eaef0e90f79e8ec2ecc4 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/slab.h>
 #include <linux/moduleparam.h>
 #include <linux/kdebug.h>
+#include <linux/cpu.h>
 #include <asm/nmi.h>
 #include <asm/msr.h>
 #include <asm/apic.h>
@@ -28,23 +29,48 @@ static DEFINE_PER_CPU(unsigned long, saved_lvtpc);
 
 static int nmi_start(void);
 static void nmi_stop(void);
+static void nmi_cpu_start(void *dummy);
+static void nmi_cpu_stop(void *dummy);
 
 /* 0 == registered but off, 1 == registered and on */
 static int nmi_enabled = 0;
 
+#ifdef CONFIG_SMP
+static int oprofile_cpu_notifier(struct notifier_block *b, unsigned long action,
+                                void *data)
+{
+       int cpu = (unsigned long)data;
+       switch (action) {
+       case CPU_DOWN_FAILED:
+       case CPU_ONLINE:
+               smp_call_function_single(cpu, nmi_cpu_start, NULL, 0);
+               break;
+       case CPU_DOWN_PREPARE:
+               smp_call_function_single(cpu, nmi_cpu_stop, NULL, 1);
+               break;
+       }
+       return NOTIFY_DONE;
+}
+
+static struct notifier_block oprofile_cpu_nb = {
+       .notifier_call = oprofile_cpu_notifier
+};
+#endif
+
 #ifdef CONFIG_PM
 
 static int nmi_suspend(struct sys_device *dev, pm_message_t state)
 {
+       /* Only one CPU left, just stop that one */
        if (nmi_enabled == 1)
-               nmi_stop();
+               nmi_cpu_stop(NULL);
        return 0;
 }
 
 static int nmi_resume(struct sys_device *dev)
 {
        if (nmi_enabled == 1)
-               nmi_start();
+               nmi_cpu_start(NULL);
        return 0;
 }
 
@@ -463,6 +489,9 @@ int __init op_nmi_init(struct oprofile_operations *ops)
        }
 
        init_sysfs();
+#ifdef CONFIG_SMP
+       register_cpu_notifier(&oprofile_cpu_nb);
+#endif
        using_nmi = 1;
        ops->create_files = nmi_create_files;
        ops->setup = nmi_setup;
@@ -476,6 +505,10 @@ int __init op_nmi_init(struct oprofile_operations *ops)
 
 void op_nmi_exit(void)
 {
-       if (using_nmi)
+       if (using_nmi) {
                exit_sysfs();
+#ifdef CONFIG_SMP
+               unregister_cpu_notifier(&oprofile_cpu_nb);
+#endif
+       }
 }
index fec0123b33a9dde965e42caf9ae1e3ab23cb118c..8e077185e185cbc72e58be92fcbd29f05437ed23 100644 (file)
@@ -590,6 +590,8 @@ static __init int intel_router_probe(struct irq_router *r, struct pci_dev *route
        case PCI_DEVICE_ID_INTEL_ICH10_1:
        case PCI_DEVICE_ID_INTEL_ICH10_2:
        case PCI_DEVICE_ID_INTEL_ICH10_3:
+       case PCI_DEVICE_ID_INTEL_PCH_0:
+       case PCI_DEVICE_ID_INTEL_PCH_1:
                r->name = "PIIX/ICH";
                r->get = pirq_piix_get;
                r->set = pirq_piix_set;
index ec9ce35e44d6afe51b2c63bafbe9d5e3053d68c4..b722dd481b3975b2b9b171203a42f6406b9cafed 100644 (file)
@@ -14,7 +14,7 @@ static void __devinit pcibios_fixup_peer_bridges(void)
        int n, devfn;
        long node;
 
-       if (pcibios_last_bus <= 0 || pcibios_last_bus >= 0xff)
+       if (pcibios_last_bus <= 0 || pcibios_last_bus > 0xff)
                return;
        DBG("PCI: Peer bridge fixup\n");
 
index 2bd5c53f638603932f9e195a8e70d1b496588d72..d9635764ce3de8eff7163ef5e44ddc59a2000e18 100644 (file)
@@ -293,7 +293,7 @@ static acpi_status __init find_mboard_resource(acpi_handle handle, u32 lvl,
        return AE_OK;
 }
 
-static int __init is_acpi_reserved(unsigned long start, unsigned long end)
+static int __init is_acpi_reserved(u64 start, u64 end, unsigned not_used)
 {
        struct resource mcfg_res;
 
@@ -310,6 +310,41 @@ static int __init is_acpi_reserved(unsigned long start, unsigned long end)
        return mcfg_res.flags;
 }
 
+typedef int (*check_reserved_t)(u64 start, u64 end, unsigned type);
+
+static int __init is_mmconf_reserved(check_reserved_t is_reserved,
+               u64 addr, u64 size, int i,
+               typeof(pci_mmcfg_config[0]) *cfg, int with_e820)
+{
+       u64 old_size = size;
+       int valid = 0;
+
+       while (!is_reserved(addr, addr + size - 1, E820_RESERVED)) {
+               size >>= 1;
+               if (size < (16UL<<20))
+                       break;
+       }
+
+       if (size >= (16UL<<20) || size == old_size) {
+               printk(KERN_NOTICE
+                      "PCI: MCFG area at %Lx reserved in %s\n",
+                       addr, with_e820?"E820":"ACPI motherboard resources");
+               valid = 1;
+
+               if (old_size != size) {
+                       /* update end_bus_number */
+                       cfg->end_bus_number = cfg->start_bus_number + ((size>>20) - 1);
+                       printk(KERN_NOTICE "PCI: updated MCFG configuration %d: base %lx "
+                              "segment %hu buses %u - %u\n",
+                              i, (unsigned long)cfg->address, cfg->pci_segment,
+                              (unsigned int)cfg->start_bus_number,
+                              (unsigned int)cfg->end_bus_number);
+               }
+       }
+
+       return valid;
+}
+
 static void __init pci_mmcfg_reject_broken(int early)
 {
        typeof(pci_mmcfg_config[0]) *cfg;
@@ -324,21 +359,22 @@ static void __init pci_mmcfg_reject_broken(int early)
 
        for (i = 0; i < pci_mmcfg_config_num; i++) {
                int valid = 0;
-               u32 size = (cfg->end_bus_number + 1) << 20;
+               u64 addr, size;
+
                cfg = &pci_mmcfg_config[i];
+               addr = cfg->start_bus_number;
+               addr <<= 20;
+               addr += cfg->address;
+               size = cfg->end_bus_number + 1 - cfg->start_bus_number;
+               size <<= 20;
                printk(KERN_NOTICE "PCI: MCFG configuration %d: base %lx "
                       "segment %hu buses %u - %u\n",
                       i, (unsigned long)cfg->address, cfg->pci_segment,
                       (unsigned int)cfg->start_bus_number,
                       (unsigned int)cfg->end_bus_number);
 
-               if (!early &&
-                   is_acpi_reserved(cfg->address, cfg->address + size - 1)) {
-                       printk(KERN_NOTICE "PCI: MCFG area at %Lx reserved "
-                              "in ACPI motherboard resources\n",
-                              cfg->address);
-                       valid = 1;
-               }
+               if (!early)
+                       valid = is_mmconf_reserved(is_acpi_reserved, addr, size, i, cfg, 0);
 
                if (valid)
                        continue;
@@ -347,16 +383,11 @@ static void __init pci_mmcfg_reject_broken(int early)
                        printk(KERN_ERR "PCI: BIOS Bug: MCFG area at %Lx is not"
                               " reserved in ACPI motherboard resources\n",
                               cfg->address);
+
                /* Don't try to do this check unless configuration
                   type 1 is available. how about type 2 ?*/
-               if (raw_pci_ops && e820_all_mapped(cfg->address,
-                                                 cfg->address + size - 1,
-                                                 E820_RESERVED)) {
-                       printk(KERN_NOTICE
-                              "PCI: MCFG area at %Lx reserved in E820\n",
-                              cfg->address);
-                       valid = 1;
-               }
+               if (raw_pci_ops)
+                       valid = is_mmconf_reserved(e820_all_mapped, addr, size, i, cfg, 1);
 
                if (!valid)
                        goto reject;
index c13cc77291af7d1c26378051f7fa1b9770d0f81d..656c2c7abf999628e1232024b71c4af2f22a1ac9 100644 (file)
@@ -293,27 +293,30 @@ void __init printk_all_partitions(void)
 /* iterator */
 static int find_start(struct device *dev, void *data)
 {
-       loff_t k = *(loff_t *)data;
+       loff_t *k = data;
 
        if (dev->type != &disk_type)
                return 0;
-       if (!k--)
+       if (!*k)
                return 1;
+       (*k)--;
        return 0;
 }
 
 static void *part_start(struct seq_file *part, loff_t *pos)
 {
        struct device *dev;
-       loff_t n = *pos;
+       loff_t k = *pos;
 
-       if (!n)
+       if (!k)
                seq_puts(part, "major minor  #blocks  name\n\n");
 
        mutex_lock(&block_class_lock);
-       dev = class_find_device(&block_class, NULL, (void *)pos, find_start);
-       if (dev)
+       dev = class_find_device(&block_class, NULL, &k, find_start);
+       if (dev) {
+               put_device(dev);
                return dev_to_disk(dev);
+       }
        return NULL;
 }
 
@@ -330,8 +333,10 @@ static void *part_next(struct seq_file *part, void *v, loff_t *pos)
        struct device *dev;
        ++*pos;
        dev = class_find_device(&block_class, &gp->dev, NULL, find_next);
-       if (dev)
+       if (dev) {
+               put_device(dev);
                return dev_to_disk(dev);
+       }
        return NULL;
 }
 
@@ -568,11 +573,14 @@ static struct device_type disk_type = {
 static void *diskstats_start(struct seq_file *part, loff_t *pos)
 {
        struct device *dev;
+       loff_t k = *pos;
 
        mutex_lock(&block_class_lock);
-       dev = class_find_device(&block_class, NULL, (void *)pos, find_start);
-       if (dev)
+       dev = class_find_device(&block_class, NULL, &k, find_start);
+       if (dev) {
+               put_device(dev);
                return dev_to_disk(dev);
+       }
        return NULL;
 }
 
@@ -583,8 +591,10 @@ static void *diskstats_next(struct seq_file *part, void *v, loff_t *pos)
 
        ++*pos;
        dev = class_find_device(&block_class, &gp->dev, NULL, find_next);
-       if (dev)
+       if (dev) {
+               put_device(dev);
                return dev_to_disk(dev);
+       }
        return NULL;
 }
 
@@ -712,10 +722,12 @@ dev_t blk_lookup_devt(const char *name, int part)
        mutex_lock(&block_class_lock);
        find.name = name;
        find.part = part;
-       dev = class_find_device(&block_class, NULL, (void *)&find, match_id);
-       if (dev)
+       dev = class_find_device(&block_class, NULL, &find, match_id);
+       if (dev) {
+               put_device(dev);
                devt = MKDEV(MAJOR(dev->devt),
                             MINOR(dev->devt) + part);
+       }
        mutex_unlock(&block_class_lock);
 
        return devt;
index 4b226768752abed604033f708d093f0b04aee41b..fd9f06c63d76efc223a6f025dcab10b19ceba84c 100644 (file)
@@ -174,8 +174,9 @@ static int crypto_authenc_genicv(struct aead_request *req, u8 *iv,
 static void crypto_authenc_encrypt_done(struct crypto_async_request *req,
                                        int err)
 {
+       struct aead_request *areq = req->data;
+
        if (!err) {
-               struct aead_request *areq = req->data;
                struct crypto_aead *authenc = crypto_aead_reqtfm(areq);
                struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc);
                struct ablkcipher_request *abreq = aead_request_ctx(areq);
@@ -185,7 +186,7 @@ static void crypto_authenc_encrypt_done(struct crypto_async_request *req,
                err = crypto_authenc_genicv(areq, iv, 0);
        }
 
-       aead_request_complete(req->data, err);
+       aead_request_complete(areq, err);
 }
 
 static int crypto_authenc_encrypt(struct aead_request *req)
@@ -216,14 +217,15 @@ static int crypto_authenc_encrypt(struct aead_request *req)
 static void crypto_authenc_givencrypt_done(struct crypto_async_request *req,
                                           int err)
 {
+       struct aead_request *areq = req->data;
+
        if (!err) {
-               struct aead_request *areq = req->data;
                struct skcipher_givcrypt_request *greq = aead_request_ctx(areq);
 
                err = crypto_authenc_genicv(areq, greq->giv, 0);
        }
 
-       aead_request_complete(req->data, err);
+       aead_request_complete(areq, err);
 }
 
 static int crypto_authenc_givencrypt(struct aead_givcrypt_request *req)
index ef3e5522e1a4a41979ff5ec56b72ed860d004275..c729e6988bbb17db928de1cd903682cfc3dc2802 100644 (file)
@@ -486,6 +486,8 @@ static const struct pci_device_id ahci_pci_tbl[] = {
        { PCI_VDEVICE(INTEL, 0x502b), board_ahci }, /* Tolapai */
        { PCI_VDEVICE(INTEL, 0x3a05), board_ahci }, /* ICH10 */
        { PCI_VDEVICE(INTEL, 0x3a25), board_ahci }, /* ICH10 */
+       { PCI_VDEVICE(INTEL, 0x3b24), board_ahci }, /* PCH RAID */
+       { PCI_VDEVICE(INTEL, 0x3b2b), board_ahci }, /* PCH RAID */
 
        /* 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,
@@ -575,9 +577,9 @@ static const struct pci_device_id ahci_pci_tbl[] = {
        { PCI_VDEVICE(NVIDIA, 0x0bc7), board_ahci },            /* MCP7B */
 
        /* SiS */
-       { PCI_VDEVICE(SI, 0x1184), board_ahci_nopmp },          /* SiS 966 */
-       { PCI_VDEVICE(SI, 0x1185), board_ahci_nopmp },          /* SiS 968 */
-       { PCI_VDEVICE(SI, 0x0186), board_ahci_nopmp },          /* SiS 968 */
+       { PCI_VDEVICE(SI, 0x1184), board_ahci },                /* SiS 966 */
+       { PCI_VDEVICE(SI, 0x1185), board_ahci },                /* SiS 968 */
+       { PCI_VDEVICE(SI, 0x0186), board_ahci },                /* SiS 968 */
 
        /* Marvell */
        { PCI_VDEVICE(MARVELL, 0x6145), board_ahci_mv },        /* 6145 */
index c294121fd69e71e68e84a328c8d8ed63f6e7a65e..b1d08a8f50030da3bb5d6a74726b5a72fdffe24b 100644 (file)
@@ -275,6 +275,14 @@ static const struct pci_device_id piix_pci_tbl[] = {
        { 0x8086, 0x3a20, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata },
        /* SATA Controller IDE (ICH10) */
        { 0x8086, 0x3a26, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
+       /* SATA Controller IDE (PCH) */
+       { 0x8086, 0x3b20, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata },
+       /* SATA Controller IDE (PCH) */
+       { 0x8086, 0x3b26, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
+       /* SATA Controller IDE (PCH) */
+       { 0x8086, 0x3b2d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
+       /* SATA Controller IDE (PCH) */
+       { 0x8086, 0x3b2e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata },
 
        { }     /* terminate list */
 };
index 5ba96c5052c8c737bf8e07d8968affb334636ccd..79e3a8e7a84a36de25dea2bcb7161b7bcdcc6fd5 100644 (file)
@@ -104,6 +104,7 @@ struct ata_force_param {
        unsigned long   xfer_mask;
        unsigned int    horkage_on;
        unsigned int    horkage_off;
+       unsigned int    lflags;
 };
 
 struct ata_force_ent {
@@ -196,22 +197,23 @@ void ata_force_cbl(struct ata_port *ap)
 }
 
 /**
- *     ata_force_spd_limit - force SATA spd limit according to libata.force
+ *     ata_force_link_limits - force link limits according to libata.force
  *     @link: ATA link of interest
  *
- *     Force SATA spd limit according to libata.force and whine about
- *     it.  When only the port part is specified (e.g. 1:), the limit
- *     applies to all links connected to both the host link and all
- *     fan-out ports connected via PMP.  If the device part is
- *     specified as 0 (e.g. 1.00:), it specifies the first fan-out
- *     link not the host link.  Device number 15 always points to the
- *     host link whether PMP is attached or not.
+ *     Force link flags and SATA spd limit according to libata.force
+ *     and whine about it.  When only the port part is specified
+ *     (e.g. 1:), the limit applies to all links connected to both
+ *     the host link and all fan-out ports connected via PMP.  If the
+ *     device part is specified as 0 (e.g. 1.00:), it specifies the
+ *     first fan-out link not the host link.  Device number 15 always
+ *     points to the host link whether PMP is attached or not.
  *
  *     LOCKING:
  *     EH context.
  */
-static void ata_force_spd_limit(struct ata_link *link)
+static void ata_force_link_limits(struct ata_link *link)
 {
+       bool did_spd = false;
        int linkno, i;
 
        if (ata_is_host_link(link))
@@ -228,13 +230,22 @@ static void ata_force_spd_limit(struct ata_link *link)
                if (fe->device != -1 && fe->device != linkno)
                        continue;
 
-               if (!fe->param.spd_limit)
-                       continue;
+               /* only honor the first spd limit */
+               if (!did_spd && fe->param.spd_limit) {
+                       link->hw_sata_spd_limit = (1 << fe->param.spd_limit) - 1;
+                       ata_link_printk(link, KERN_NOTICE,
+                                       "FORCE: PHY spd limit set to %s\n",
+                                       fe->param.name);
+                       did_spd = true;
+               }
 
-               link->hw_sata_spd_limit = (1 << fe->param.spd_limit) - 1;
-               ata_link_printk(link, KERN_NOTICE,
-                       "FORCE: PHY spd limit set to %s\n", fe->param.name);
-               return;
+               /* let lflags stack */
+               if (fe->param.lflags) {
+                       link->flags |= fe->param.lflags;
+                       ata_link_printk(link, KERN_NOTICE,
+                                       "FORCE: link flag 0x%x forced -> 0x%x\n",
+                                       fe->param.lflags, link->flags);
+               }
        }
 }
 
@@ -3277,7 +3288,7 @@ int ata_do_set_mode(struct ata_link *link, struct ata_device **r_failed_dev)
                dev->dma_mode = ata_xfer_mask2mode(dma_mask);
 
                found = 1;
-               if (dev->dma_mode != 0xff)
+               if (ata_dma_enabled(dev))
                        used_dma = 1;
        }
        if (!found)
@@ -3302,7 +3313,7 @@ int ata_do_set_mode(struct ata_link *link, struct ata_device **r_failed_dev)
 
        /* step 3: set host DMA timings */
        ata_link_for_each_dev(dev, link) {
-               if (!ata_dev_enabled(dev) || dev->dma_mode == 0xff)
+               if (!ata_dev_enabled(dev) || !ata_dma_enabled(dev))
                        continue;
 
                dev->xfer_mode = dev->dma_mode;
@@ -5188,19 +5199,18 @@ void ata_link_init(struct ata_port *ap, struct ata_link *link, int pmp)
  */
 int sata_link_init_spd(struct ata_link *link)
 {
-       u32 scontrol;
        u8 spd;
        int rc;
 
-       rc = sata_scr_read(link, SCR_CONTROL, &scontrol);
+       rc = sata_scr_read(link, SCR_CONTROL, &link->saved_scontrol);
        if (rc)
                return rc;
 
-       spd = (scontrol >> 4) & 0xf;
+       spd = (link->saved_scontrol >> 4) & 0xf;
        if (spd)
                link->hw_sata_spd_limit &= (1 << spd) - 1;
 
-       ata_force_spd_limit(link);
+       ata_force_link_limits(link);
 
        link->sata_spd_limit = link->hw_sata_spd_limit;
 
@@ -5783,9 +5793,10 @@ static void ata_port_detach(struct ata_port *ap)
        ata_port_wait_eh(ap);
 
        /* EH is now guaranteed to see UNLOADING - EH context belongs
-        * to us.  Disable all existing devices.
+        * to us.  Restore SControl and disable all existing devices.
         */
-       ata_port_for_each_link(link, ap) {
+       __ata_port_for_each_link(link, ap) {
+               sata_scr_write(link, SCR_CONTROL, link->saved_scontrol);
                ata_link_for_each_dev(dev, link)
                        ata_dev_disable(dev);
        }
@@ -5991,6 +6002,9 @@ static int __init ata_parse_force_one(char **cur,
                { "udma133",    .xfer_mask      = 1 << (ATA_SHIFT_UDMA + 6) },
                { "udma/133",   .xfer_mask      = 1 << (ATA_SHIFT_UDMA + 6) },
                { "udma7",      .xfer_mask      = 1 << (ATA_SHIFT_UDMA + 7) },
+               { "nohrst",     .lflags         = ATA_LFLAG_NO_HRST },
+               { "nosrst",     .lflags         = ATA_LFLAG_NO_SRST },
+               { "norst",      .lflags         = ATA_LFLAG_NO_HRST | ATA_LFLAG_NO_SRST },
        };
        char *start = *cur, *p = *cur;
        char *id, *val, *endp;
index 58bdc538d229d400b78fd2c0a46317c1a84d943c..c1db2f234d2e409d21851c91c77a292cc631406e 100644 (file)
@@ -2040,7 +2040,7 @@ static void ata_eh_link_report(struct ata_link *link)
        }
 
        if (ehc->i.serror)
-               ata_port_printk(ap, KERN_ERR,
+               ata_link_printk(link, KERN_ERR,
                  "SError: { %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s}\n",
                  ehc->i.serror & SERR_DATA_RECOVERED ? "RecovData " : "",
                  ehc->i.serror & SERR_COMM_RECOVERED ? "RecovComm " : "",
@@ -2171,18 +2171,12 @@ static int ata_do_reset(struct ata_link *link, ata_reset_fn_t reset,
 }
 
 static int ata_eh_followup_srst_needed(struct ata_link *link,
-                                      int rc, int classify,
-                                      const unsigned int *classes)
+                                      int rc, const unsigned int *classes)
 {
        if ((link->flags & ATA_LFLAG_NO_SRST) || ata_link_offline(link))
                return 0;
-       if (rc == -EAGAIN) {
-               if (classify)
-                       return 1;
-               rc = 0;
-       }
-       if (rc != 0)
-               return 0;
+       if (rc == -EAGAIN)
+               return 1;
        if (sata_pmp_supported(link->ap) && ata_is_host_link(link))
                return 1;
        return 0;
@@ -2210,6 +2204,10 @@ int ata_eh_reset(struct ata_link *link, int classify,
         */
        while (ata_eh_reset_timeouts[max_tries] != ULONG_MAX)
                max_tries++;
+       if (link->flags & ATA_LFLAG_NO_HRST)
+               hardreset = NULL;
+       if (link->flags & ATA_LFLAG_NO_SRST)
+               softreset = NULL;
 
        now = jiffies;
        deadline = ata_deadline(ehc->last_reset, ATA_EH_RESET_COOL_DOWN);
@@ -2247,10 +2245,10 @@ int ata_eh_reset(struct ata_link *link, int classify,
        ehc->i.action &= ~ATA_EH_RESET;
        if (hardreset) {
                reset = hardreset;
-               ehc->i.action = ATA_EH_HARDRESET;
+               ehc->i.action |= ATA_EH_HARDRESET;
        } else if (softreset) {
                reset = softreset;
-               ehc->i.action = ATA_EH_SOFTRESET;
+               ehc->i.action |= ATA_EH_SOFTRESET;
        }
 
        if (prereset) {
@@ -2305,9 +2303,11 @@ int ata_eh_reset(struct ata_link *link, int classify,
                        ehc->i.flags |= ATA_EHI_DID_SOFTRESET;
 
                rc = ata_do_reset(link, reset, classes, deadline);
+               if (rc && rc != -EAGAIN)
+                       goto fail;
 
                if (reset == hardreset &&
-                   ata_eh_followup_srst_needed(link, rc, classify, classes)) {
+                   ata_eh_followup_srst_needed(link, rc, classes)) {
                        /* okay, let's do follow-up softreset */
                        reset = softreset;
 
@@ -2322,10 +2322,6 @@ int ata_eh_reset(struct ata_link *link, int classify,
                        ata_eh_about_to_do(link, NULL, ATA_EH_RESET);
                        rc = ata_do_reset(link, reset, classes, deadline);
                }
-
-               /* -EAGAIN can happen if we skipped followup SRST */
-               if (rc && rc != -EAGAIN)
-                       goto fail;
        } else {
                if (verbose)
                        ata_link_printk(link, KERN_INFO, "no reset method "
index fbe605711554a24dd1ae23be66d02128c8193b18..eb919c16a03e67f25042da2756f274821b549ee8 100644 (file)
@@ -181,7 +181,7 @@ static unsigned int pacpi_qc_issue(struct ata_queued_cmd *qc)
 
        if (adev != acpi->last) {
                pacpi_set_piomode(ap, adev);
-               if (adev->dma_mode)
+               if (ata_dma_enabled(adev))
                        pacpi_set_dmamode(ap, adev);
                acpi->last = adev;
        }
index d7de7baf58a8ccb8551a8685167410b60ddf031d..e8a0d99d7356baaf0afba8c9c348ff5adb45b828 100644 (file)
@@ -183,7 +183,7 @@ static void atiixp_bmdma_start(struct ata_queued_cmd *qc)
        u16 tmp16;
 
        pci_read_config_word(pdev, ATIIXP_IDE_UDMA_CONTROL, &tmp16);
-       if (adev->dma_mode >= XFER_UDMA_0)
+       if (ata_using_udma(adev))
                tmp16 |= (1 << dn);
        else
                tmp16 &= ~(1 << dn);
index 744beebaaf494f17603b3750036da58cc0242cdf..0c4b271a9d5a372c07a80ded36566b40e831bcb5 100644 (file)
@@ -149,10 +149,10 @@ static unsigned int cs5530_qc_issue(struct ata_queued_cmd *qc)
        struct ata_device *prev = ap->private_data;
 
        /* See if the DMA settings could be wrong */
-       if (adev->dma_mode != 0 && adev != prev && prev != NULL) {
+       if (ata_dma_enabled(adev) && adev != prev && prev != NULL) {
                /* Maybe, but do the channels match MWDMA/UDMA ? */
-               if ((adev->dma_mode >= XFER_UDMA_0 && prev->dma_mode < XFER_UDMA_0) ||
-                   (adev->dma_mode < XFER_UDMA_0 && prev->dma_mode >= XFER_UDMA_0))
+               if ((ata_using_udma(adev) && !ata_using_udma(prev)) ||
+                   (ata_using_udma(prev) && !ata_using_udma(adev)))
                        /* Switch the mode bits */
                        cs5530_set_dmamode(ap, adev);
        }
index 27843c70eb9dc64e8d6292e2dc7fe2ee425bae40..0221c9a46769ad5e826485691d2718f863795eeb 100644 (file)
@@ -606,7 +606,7 @@ static void it821x_display_disk(int n, u8 *buf)
 {
        unsigned char id[41];
        int mode = 0;
-       char *mtype;
+       char *mtype = "";
        char mbuf[8];
        char *cbl = "(40 wire cable)";
 
index e678af383d13283dc578c875580cead05c37623c..df64f24430018674f527bfe1bb26d49a73b3ea05 100644 (file)
@@ -198,7 +198,7 @@ static unsigned int oldpiix_qc_issue(struct ata_queued_cmd *qc)
 
        if (adev != ap->private_data) {
                oldpiix_set_piomode(ap, adev);
-               if (adev->dma_mode)
+               if (ata_dma_enabled(adev))
                        oldpiix_set_dmamode(ap, adev);
        }
        return ata_sff_qc_issue(qc);
index cbab397e3db7a1cc5893d40de3d99d524d563383..0278fd2b8fb1cc8c80ba05bc1e638027a22d3a95 100644 (file)
@@ -167,10 +167,10 @@ static unsigned int sc1200_qc_issue(struct ata_queued_cmd *qc)
        struct ata_device *prev = ap->private_data;
 
        /* See if the DMA settings could be wrong */
-       if (adev->dma_mode != 0 && adev != prev && prev != NULL) {
+       if (ata_dma_enabled(adev) && adev != prev && prev != NULL) {
                /* Maybe, but do the channels match MWDMA/UDMA ? */
-               if ((adev->dma_mode >= XFER_UDMA_0 && prev->dma_mode < XFER_UDMA_0) ||
-                   (adev->dma_mode < XFER_UDMA_0 && prev->dma_mode >= XFER_UDMA_0))
+               if ((ata_using_udma(adev) && !ata_using_udma(prev)) ||
+                   (ata_using_udma(prev) && !ata_using_udma(adev)))
                        /* Switch the mode bits */
                        sc1200_set_dmamode(ap, adev);
        }
index 57d951b11f2d840c18d92f7ed180ef7a240a386d..8fdb2ce73210b885393dc6ec066d5f3c69185646 100644 (file)
@@ -324,62 +324,26 @@ static void via_set_dmamode(struct ata_port *ap, struct ata_device *adev)
 }
 
 /**
- *     via_ata_sff_tf_load - send taskfile registers to host controller
+ *     via_tf_load - send taskfile registers to host controller
  *     @ap: Port to which output is sent
  *     @tf: ATA taskfile register set
  *
  *     Outputs ATA taskfile to standard ATA host controller.
  *
  *     Note: This is to fix the internal bug of via chipsets, which
- *  will reset the device register after changing the IEN bit on
- *  ctl register
+ *     will reset the device register after changing the IEN bit on
+ *     ctl register
  */
-static void via_ata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf)
+static void via_tf_load(struct ata_port *ap, const struct ata_taskfile *tf)
 {
-       struct ata_ioports *ioaddr = &ap->ioaddr;
-       unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR;
-
-       if (tf->ctl != ap->last_ctl) {
-               iowrite8(tf->ctl, ioaddr->ctl_addr);
-               iowrite8(tf->device, ioaddr->device_addr);
-               ap->last_ctl = tf->ctl;
-               ata_wait_idle(ap);
-       }
-
-       if (is_addr && (tf->flags & ATA_TFLAG_LBA48)) {
-               iowrite8(tf->hob_feature, ioaddr->feature_addr);
-               iowrite8(tf->hob_nsect, ioaddr->nsect_addr);
-               iowrite8(tf->hob_lbal, ioaddr->lbal_addr);
-               iowrite8(tf->hob_lbam, ioaddr->lbam_addr);
-               iowrite8(tf->hob_lbah, ioaddr->lbah_addr);
-               VPRINTK("hob: feat 0x%X nsect 0x%X, lba 0x%X 0x%X 0x%X\n",
-                       tf->hob_feature,
-                       tf->hob_nsect,
-                       tf->hob_lbal,
-                       tf->hob_lbam,
-                       tf->hob_lbah);
-       }
+       struct ata_taskfile tmp_tf;
 
-       if (is_addr) {
-               iowrite8(tf->feature, ioaddr->feature_addr);
-               iowrite8(tf->nsect, ioaddr->nsect_addr);
-               iowrite8(tf->lbal, ioaddr->lbal_addr);
-               iowrite8(tf->lbam, ioaddr->lbam_addr);
-               iowrite8(tf->lbah, ioaddr->lbah_addr);
-               VPRINTK("feat 0x%X nsect 0x%X lba 0x%X 0x%X 0x%X\n",
-                       tf->feature,
-                       tf->nsect,
-                       tf->lbal,
-                       tf->lbam,
-                       tf->lbah);
+       if (ap->ctl != ap->last_ctl && !(tf->flags & ATA_TFLAG_DEVICE)) {
+               tmp_tf = *tf;
+               tmp_tf.flags |= ATA_TFLAG_DEVICE;
+               tf = &tmp_tf;
        }
-
-       if (tf->flags & ATA_TFLAG_DEVICE) {
-               iowrite8(tf->device, ioaddr->device_addr);
-               VPRINTK("device 0x%X\n", tf->device);
-       }
-
-       ata_wait_idle(ap);
+       ata_sff_tf_load(ap, tf);
 }
 
 static struct scsi_host_template via_sht = {
@@ -392,13 +356,12 @@ static struct ata_port_operations via_port_ops = {
        .set_piomode    = via_set_piomode,
        .set_dmamode    = via_set_dmamode,
        .prereset       = via_pre_reset,
-       .sff_tf_load = via_ata_tf_load,
+       .sff_tf_load    = via_tf_load,
 };
 
 static struct ata_port_operations via_port_ops_noirq = {
        .inherits       = &via_port_ops,
        .sff_data_xfer  = ata_sff_data_xfer_noirq,
-       .sff_tf_load = via_ata_tf_load,
 };
 
 /**
index ad169ffbc4cb2a0ad8387c478b6a9540992f99b6..13c1d2af18ac3e0ff02ef35b926df40955ac3006 100644 (file)
@@ -1134,30 +1134,16 @@ static int mv_qc_defer(struct ata_queued_cmd *qc)
        if (ap->nr_active_links == 0)
                return 0;
 
-       if (pp->pp_flags & MV_PP_FLAG_EDMA_EN) {
-               /*
-                * The port is operating in host queuing mode (EDMA).
-                * It can accomodate a new qc if the qc protocol
-                * is compatible with the current host queue mode.
-                */
-               if (pp->pp_flags & MV_PP_FLAG_NCQ_EN) {
-                       /*
-                        * The host queue (EDMA) is in NCQ mode.
-                        * If the new qc is also an NCQ command,
-                        * then allow the new qc.
-                        */
-                       if (qc->tf.protocol == ATA_PROT_NCQ)
-                               return 0;
-               } else {
-                       /*
-                        * The host queue (EDMA) is in non-NCQ, DMA mode.
-                        * If the new qc is also a non-NCQ, DMA command,
-                        * then allow the new qc.
-                        */
-                       if (qc->tf.protocol == ATA_PROT_DMA)
-                               return 0;
-               }
-       }
+       /*
+        * The port is operating in host queuing mode (EDMA) with NCQ
+        * enabled, allow multiple NCQ commands.  EDMA also allows
+        * queueing multiple DMA commands but libata core currently
+        * doesn't allow it.
+        */
+       if ((pp->pp_flags & MV_PP_FLAG_EDMA_EN) &&
+           (pp->pp_flags & MV_PP_FLAG_NCQ_EN) && ata_is_ncq(qc->tf.protocol))
+               return 0;
+
        return ATA_DEFER_PORT;
 }
 
@@ -3036,7 +3022,8 @@ static int mv_chip_id(struct ata_host *host, unsigned int board_idx)
                break;
        case chip_soc:
                hpriv->ops = &mv_soc_ops;
-               hp_flags |= MV_HP_FLAG_SOC | MV_HP_ERRATA_60X1C0;
+               hp_flags |= MV_HP_FLAG_SOC | MV_HP_GEN_IIE |
+                       MV_HP_ERRATA_60X1C0;
                break;
 
        default:
index 2ebd07f2ef81d33f1d9d5824b3b68085944616f3..5effec6f545870a071f003923666b8b4cb310d53 100644 (file)
@@ -3,7 +3,6 @@
  */
 
 #include <linux/module.h>
-#include <linux/version.h>
 #include <linux/kernel.h>
 #include <linux/skbuff.h>
 #include <linux/errno.h>
index 5667c2f02c51b2249fdac0d69fc7fd0a8fe4dfd0..cc5e28c8885ce1b78d2b0453e9068c8abf0dde64 100644 (file)
@@ -295,6 +295,12 @@ int class_for_each_device(struct class *class, struct device *start,
 
        if (!class)
                return -EINVAL;
+       if (!class->p) {
+               WARN(1, "%s called for class '%s' before it was initialized",
+                    __func__, class->name);
+               return -EINVAL;
+       }
+
        mutex_lock(&class->p->class_mutex);
        list_for_each_entry(dev, &class->p->class_devices, node) {
                if (start) {
@@ -344,6 +350,11 @@ struct device *class_find_device(struct class *class, struct device *start,
 
        if (!class)
                return NULL;
+       if (!class->p) {
+               WARN(1, "%s called for class '%s' before it was initialized",
+                    __func__, class->name);
+               return NULL;
+       }
 
        mutex_lock(&class->p->class_mutex);
        list_for_each_entry(dev, &class->p->class_devices, node) {
index 068aa1c9538c99d54a47603e25f69544f084f537..d021c98605b3a1fe7e7dcd5f61e9e456b2a16aae 100644 (file)
@@ -53,7 +53,7 @@ static inline int device_is_not_partition(struct device *dev)
  * it is attached to.  If it is not attached to a bus either, an empty
  * string will be returned.
  */
-const char *dev_driver_string(struct device *dev)
+const char *dev_driver_string(const struct device *dev)
 {
        return dev->driver ? dev->driver->name :
                        (dev->bus ? dev->bus->name :
@@ -541,6 +541,7 @@ void device_initialize(struct device *dev)
        spin_lock_init(&dev->devres_lock);
        INIT_LIST_HEAD(&dev->devres_head);
        device_init_wakeup(dev, 0);
+       device_pm_init(dev);
        set_dev_node(dev, -1);
 }
 
@@ -843,13 +844,19 @@ int device_add(struct device *dev)
 {
        struct device *parent = NULL;
        struct class_interface *class_intf;
-       int error;
+       int error = -EINVAL;
 
        dev = get_device(dev);
-       if (!dev || !strlen(dev->bus_id)) {
-               error = -EINVAL;
-               goto Done;
-       }
+       if (!dev)
+               goto done;
+
+       /* Temporarily support init_name if it is set.
+        * It will override bus_id for now */
+       if (dev->init_name)
+               dev_set_name(dev, "%s", dev->init_name);
+
+       if (!strlen(dev->bus_id))
+               goto done;
 
        pr_debug("device: '%s': %s\n", dev->bus_id, __func__);
 
@@ -897,9 +904,10 @@ int device_add(struct device *dev)
        error = bus_add_device(dev);
        if (error)
                goto BusError;
-       error = device_pm_add(dev);
+       error = dpm_sysfs_add(dev);
        if (error)
-               goto PMError;
+               goto DPMError;
+       device_pm_add(dev);
        kobject_uevent(&dev->kobj, KOBJ_ADD);
        bus_attach_device(dev);
        if (parent)
@@ -917,10 +925,10 @@ int device_add(struct device *dev)
                                class_intf->add_dev(dev, class_intf);
                mutex_unlock(&dev->class->p->class_mutex);
        }
- Done:
+done:
        put_device(dev);
        return error;
- PMError:
DPMError:
        bus_remove_device(dev);
  BusError:
        if (dev->bus)
@@ -944,7 +952,7 @@ int device_add(struct device *dev)
        cleanup_device_parent(dev);
        if (parent)
                put_device(parent);
-       goto Done;
+       goto done;
 }
 
 /**
@@ -1007,6 +1015,7 @@ void device_del(struct device *dev)
        struct class_interface *class_intf;
 
        device_pm_remove(dev);
+       dpm_sysfs_remove(dev);
        if (parent)
                klist_del(&dev->knode_parent);
        if (MAJOR(dev->devt)) {
index 2ef5acf4368b9e8deef4440d865a87cef8d0b0a6..1e2bda780e48268eb38b834f7078644689b5dc7b 100644 (file)
@@ -16,9 +16,6 @@
 #include <linux/string.h>
 #include "base.h"
 
-#define to_dev(node) container_of(node, struct device, driver_list)
-
-
 static struct device *next_device(struct klist_iter *i)
 {
        struct klist_node *n = klist_next(i);
index 3250c5257b748286cfec992558a7590f0ab915e9..273a944d4040e861afa6a1ea6c601264eec6c4a7 100644 (file)
@@ -67,20 +67,16 @@ void device_pm_unlock(void)
  *     device_pm_add - add a device to the list of active devices
  *     @dev:   Device to be added to the list
  */
-int device_pm_add(struct device *dev)
+void device_pm_add(struct device *dev)
 {
-       int error;
-
        pr_debug("PM: Adding info for %s:%s\n",
                 dev->bus ? dev->bus->name : "No Bus",
                 kobject_name(&dev->kobj));
        mutex_lock(&dpm_list_mtx);
        if (dev->parent) {
-               if (dev->parent->power.status >= DPM_SUSPENDING) {
-                       dev_warn(dev, "parent %s is sleeping, will not add\n",
+               if (dev->parent->power.status >= DPM_SUSPENDING)
+                       dev_warn(dev, "parent %s should not be sleeping\n",
                                dev->parent->bus_id);
-                       WARN_ON(true);
-               }
        } else if (transition_started) {
                /*
                 * We refuse to register parentless devices while a PM
@@ -89,13 +85,9 @@ int device_pm_add(struct device *dev)
                 */
                WARN_ON(true);
        }
-       error = dpm_sysfs_add(dev);
-       if (!error) {
-               dev->power.status = DPM_ON;
-               list_add_tail(&dev->power.entry, &dpm_list);
-       }
+
+       list_add_tail(&dev->power.entry, &dpm_list);
        mutex_unlock(&dpm_list_mtx);
-       return error;
 }
 
 /**
@@ -110,7 +102,6 @@ void device_pm_remove(struct device *dev)
                 dev->bus ? dev->bus->name : "No Bus",
                 kobject_name(&dev->kobj));
        mutex_lock(&dpm_list_mtx);
-       dpm_sysfs_remove(dev);
        list_del_init(&dev->power.entry);
        mutex_unlock(&dpm_list_mtx);
 }
index a3252c0e28878fde258ebac8c10ad7c10cafbb86..41f51fae042f06f06d7548f4ad10463b7b399f4f 100644 (file)
@@ -1,3 +1,8 @@
+static inline void device_pm_init(struct device *dev)
+{
+       dev->power.status = DPM_ON;
+}
+
 #ifdef CONFIG_PM_SLEEP
 
 /*
@@ -11,12 +16,12 @@ static inline struct device *to_device(struct list_head *entry)
        return container_of(entry, struct device, power.entry);
 }
 
-extern int device_pm_add(struct device *);
+extern void device_pm_add(struct device *);
 extern void device_pm_remove(struct device *);
 
 #else /* CONFIG_PM_SLEEP */
 
-static inline int device_pm_add(struct device *dev) { return 0; }
+static inline void device_pm_add(struct device *dev) {}
 static inline void device_pm_remove(struct device *dev) {}
 
 #endif
index 24b97b0bef994411bda31e377c041da6471ed9a2..d070d492e385b26893e34d514cbda0fa6cb5e34f 100644 (file)
@@ -571,8 +571,8 @@ out_free:
                list_del(&brd->brd_list);
                brd_free(brd);
        }
+       unregister_blkdev(RAMDISK_MAJOR, "ramdisk");
 
-       unregister_blkdev(RAMDISK_MAJOR, "brd");
        return -ENOMEM;
 }
 
index ad98dda6037dd5193baa266bf2471c52ca1b6f79..1778e4a2c672be69ce18e6a8c64e2356ceca5b92 100644 (file)
@@ -707,15 +707,15 @@ static int __init nbd_init(void)
 
        BUILD_BUG_ON(sizeof(struct nbd_request) != 28);
 
-       nbd_dev = kcalloc(nbds_max, sizeof(*nbd_dev), GFP_KERNEL);
-       if (!nbd_dev)
-               return -ENOMEM;
-
        if (max_part < 0) {
                printk(KERN_CRIT "nbd: max_part must be >= 0\n");
                return -EINVAL;
        }
 
+       nbd_dev = kcalloc(nbds_max, sizeof(*nbd_dev), GFP_KERNEL);
+       if (!nbd_dev)
+               return -ENOMEM;
+
        part_shift = 0;
        if (max_part > 0)
                part_shift = fls(max_part);
@@ -779,6 +779,7 @@ out:
                blk_cleanup_queue(nbd_dev[i].disk->queue);
                put_disk(nbd_dev[i].disk);
        }
+       kfree(nbd_dev);
        return err;
 }
 
@@ -795,6 +796,7 @@ static void __exit nbd_cleanup(void)
                }
        }
        unregister_blkdev(NBD_MAJOR, "nbd");
+       kfree(nbd_dev);
        printk(KERN_INFO "nbd: unregistered device at major %d\n", NBD_MAJOR);
 }
 
index a235ca787465f5bb0d310fd4211635492f43dc26..7cb4029a5375a774ed9c0cc888284d37330b1b17 100644 (file)
@@ -3,8 +3,8 @@ menu "Bluetooth device drivers"
        depends on BT
 
 config BT_HCIUSB
-       tristate "HCI USB driver"
-       depends on USB
+       tristate "HCI USB driver (old version)"
+       depends on USB && BT_HCIBTUSB=n
        help
          Bluetooth HCI USB driver.
          This driver is required if you want to use Bluetooth devices with
@@ -23,15 +23,13 @@ config BT_HCIUSB_SCO
          Say Y here to compile support for SCO over HCI USB.
 
 config BT_HCIBTUSB
-       tristate "HCI USB driver (alternate version)"
-       depends on USB && EXPERIMENTAL && BT_HCIUSB=n
+       tristate "HCI USB driver"
+       depends on USB
        help
          Bluetooth HCI USB driver.
          This driver is required if you want to use Bluetooth devices with
          USB interface.
 
-          This driver is still experimental and has no SCO support.
-
          Say Y here to compile support for Bluetooth USB devices into the
          kernel or say M to compile it as module (btusb).
 
index 593b7c5950380bff58d8dac8d19ba95cf129220d..27058477cc8b7722bdc901ec7edb21e1d503be27 100644 (file)
@@ -60,7 +60,7 @@
 /* ======================== Module parameters ======================== */
 
 
-MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>, Jose Orlando Pereira <jop@di.uminho.pt>");
+MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
 MODULE_DESCRIPTION("Bluetooth driver for the 3Com Bluetooth PCMCIA card");
 MODULE_LICENSE("GPL");
 MODULE_FIRMWARE("BT3CPCC.bin");
index 95ae9ba5661e41d8f922ebc2d49836cfe8698f5e..6a010681ecf3d33f114bb78607e0d6f19d46b319 100644 (file)
@@ -2,7 +2,7 @@
  *
  *  Generic Bluetooth USB driver
  *
- *  Copyright (C) 2005-2007  Marcel Holtmann <marcel@holtmann.org>
+ *  Copyright (C) 2005-2008  Marcel Holtmann <marcel@holtmann.org>
  *
  *
  *  This program is free software; you can redistribute it and/or modify
@@ -41,7 +41,7 @@
 #define BT_DBG(D...)
 #endif
 
-#define VERSION "0.2"
+#define VERSION "0.3"
 
 static int ignore_dga;
 static int ignore_csr;
@@ -160,12 +160,16 @@ static struct usb_device_id blacklist_table[] = {
        { }     /* Terminating entry */
 };
 
+#define BTUSB_MAX_ISOC_FRAMES  10
+
 #define BTUSB_INTR_RUNNING     0
 #define BTUSB_BULK_RUNNING     1
+#define BTUSB_ISOC_RUNNING     2
 
 struct btusb_data {
        struct hci_dev       *hdev;
        struct usb_device    *udev;
+       struct usb_interface *isoc;
 
        spinlock_t lock;
 
@@ -176,10 +180,15 @@ struct btusb_data {
        struct usb_anchor tx_anchor;
        struct usb_anchor intr_anchor;
        struct usb_anchor bulk_anchor;
+       struct usb_anchor isoc_anchor;
 
        struct usb_endpoint_descriptor *intr_ep;
        struct usb_endpoint_descriptor *bulk_tx_ep;
        struct usb_endpoint_descriptor *bulk_rx_ep;
+       struct usb_endpoint_descriptor *isoc_tx_ep;
+       struct usb_endpoint_descriptor *isoc_rx_ep;
+
+       int isoc_altsetting;
 };
 
 static void btusb_intr_complete(struct urb *urb)
@@ -195,6 +204,8 @@ static void btusb_intr_complete(struct urb *urb)
                return;
 
        if (urb->status == 0) {
+               hdev->stat.byte_rx += urb->actual_length;
+
                if (hci_recv_fragment(hdev, HCI_EVENT_PKT,
                                                urb->transfer_buffer,
                                                urb->actual_length) < 0) {
@@ -216,7 +227,7 @@ static void btusb_intr_complete(struct urb *urb)
        }
 }
 
-static inline int btusb_submit_intr_urb(struct hci_dev *hdev)
+static int btusb_submit_intr_urb(struct hci_dev *hdev)
 {
        struct btusb_data *data = hdev->driver_data;
        struct urb *urb;
@@ -226,6 +237,9 @@ static inline int btusb_submit_intr_urb(struct hci_dev *hdev)
 
        BT_DBG("%s", hdev->name);
 
+       if (!data->intr_ep)
+               return -ENODEV;
+
        urb = usb_alloc_urb(0, GFP_ATOMIC);
        if (!urb)
                return -ENOMEM;
@@ -274,6 +288,8 @@ static void btusb_bulk_complete(struct urb *urb)
                return;
 
        if (urb->status == 0) {
+               hdev->stat.byte_rx += urb->actual_length;
+
                if (hci_recv_fragment(hdev, HCI_ACLDATA_PKT,
                                                urb->transfer_buffer,
                                                urb->actual_length) < 0) {
@@ -295,7 +311,7 @@ static void btusb_bulk_complete(struct urb *urb)
        }
 }
 
-static inline int btusb_submit_bulk_urb(struct hci_dev *hdev)
+static int btusb_submit_bulk_urb(struct hci_dev *hdev)
 {
        struct btusb_data *data = hdev->driver_data;
        struct urb *urb;
@@ -305,6 +321,9 @@ static inline int btusb_submit_bulk_urb(struct hci_dev *hdev)
 
        BT_DBG("%s", hdev->name);
 
+       if (!data->bulk_rx_ep)
+               return -ENODEV;
+
        urb = usb_alloc_urb(0, GFP_KERNEL);
        if (!urb)
                return -ENOMEM;
@@ -339,6 +358,127 @@ static inline int btusb_submit_bulk_urb(struct hci_dev *hdev)
        return err;
 }
 
+static void btusb_isoc_complete(struct urb *urb)
+{
+       struct hci_dev *hdev = urb->context;
+       struct btusb_data *data = hdev->driver_data;
+       int i, err;
+
+       BT_DBG("%s urb %p status %d count %d", hdev->name,
+                                       urb, urb->status, urb->actual_length);
+
+       if (!test_bit(HCI_RUNNING, &hdev->flags))
+               return;
+
+       if (urb->status == 0) {
+               for (i = 0; i < urb->number_of_packets; i++) {
+                       unsigned int offset = urb->iso_frame_desc[i].offset;
+                       unsigned int length = urb->iso_frame_desc[i].actual_length;
+
+                       if (urb->iso_frame_desc[i].status)
+                               continue;
+
+                       hdev->stat.byte_rx += length;
+
+                       if (hci_recv_fragment(hdev, HCI_SCODATA_PKT,
+                                               urb->transfer_buffer + offset,
+                                                               length) < 0) {
+                               BT_ERR("%s corrupted SCO packet", hdev->name);
+                               hdev->stat.err_rx++;
+                       }
+               }
+       }
+
+       if (!test_bit(BTUSB_ISOC_RUNNING, &data->flags))
+               return;
+
+       usb_anchor_urb(urb, &data->isoc_anchor);
+
+       err = usb_submit_urb(urb, GFP_ATOMIC);
+       if (err < 0) {
+               BT_ERR("%s urb %p failed to resubmit (%d)",
+                                               hdev->name, urb, -err);
+               usb_unanchor_urb(urb);
+       }
+}
+
+static void inline __fill_isoc_descriptor(struct urb *urb, int len, int mtu)
+{
+       int i, offset = 0;
+
+       BT_DBG("len %d mtu %d", len, mtu);
+
+       for (i = 0; i < BTUSB_MAX_ISOC_FRAMES && len >= mtu;
+                                       i++, offset += mtu, len -= mtu) {
+               urb->iso_frame_desc[i].offset = offset;
+               urb->iso_frame_desc[i].length = mtu;
+       }
+
+       if (len && i < BTUSB_MAX_ISOC_FRAMES) {
+               urb->iso_frame_desc[i].offset = offset;
+               urb->iso_frame_desc[i].length = len;
+               i++;
+       }
+
+       urb->number_of_packets = i;
+}
+
+static int btusb_submit_isoc_urb(struct hci_dev *hdev)
+{
+       struct btusb_data *data = hdev->driver_data;
+       struct urb *urb;
+       unsigned char *buf;
+       unsigned int pipe;
+       int err, size;
+
+       BT_DBG("%s", hdev->name);
+
+       if (!data->isoc_rx_ep)
+               return -ENODEV;
+
+       urb = usb_alloc_urb(BTUSB_MAX_ISOC_FRAMES, GFP_KERNEL);
+       if (!urb)
+               return -ENOMEM;
+
+       size = le16_to_cpu(data->isoc_rx_ep->wMaxPacketSize) *
+                                               BTUSB_MAX_ISOC_FRAMES;
+
+       buf = kmalloc(size, GFP_KERNEL);
+       if (!buf) {
+               usb_free_urb(urb);
+               return -ENOMEM;
+       }
+
+       pipe = usb_rcvisocpipe(data->udev, data->isoc_rx_ep->bEndpointAddress);
+
+       urb->dev      = data->udev;
+       urb->pipe     = pipe;
+       urb->context  = hdev;
+       urb->complete = btusb_isoc_complete;
+       urb->interval = data->isoc_rx_ep->bInterval;
+
+       urb->transfer_flags  = URB_FREE_BUFFER | URB_ISO_ASAP;
+       urb->transfer_buffer = buf;
+       urb->transfer_buffer_length = size;
+
+       __fill_isoc_descriptor(urb, size,
+                       le16_to_cpu(data->isoc_rx_ep->wMaxPacketSize));
+
+       usb_anchor_urb(urb, &data->isoc_anchor);
+
+       err = usb_submit_urb(urb, GFP_KERNEL);
+       if (err < 0) {
+               BT_ERR("%s urb %p submission failed (%d)",
+                                               hdev->name, urb, -err);
+               usb_unanchor_urb(urb);
+               kfree(buf);
+       }
+
+       usb_free_urb(urb);
+
+       return err;
+}
+
 static void btusb_tx_complete(struct urb *urb)
 {
        struct sk_buff *skb = urb->context;
@@ -392,6 +532,9 @@ static int btusb_close(struct hci_dev *hdev)
        if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
                return 0;
 
+       clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
+       usb_kill_anchored_urbs(&data->intr_anchor);
+
        clear_bit(BTUSB_BULK_RUNNING, &data->flags);
        usb_kill_anchored_urbs(&data->bulk_anchor);
 
@@ -453,6 +596,9 @@ static int btusb_send_frame(struct sk_buff *skb)
                break;
 
        case HCI_ACLDATA_PKT:
+               if (!data->bulk_tx_ep || hdev->conn_hash.acl_num < 1)
+                       return -ENODEV;
+
                urb = usb_alloc_urb(0, GFP_ATOMIC);
                if (!urb)
                        return -ENOMEM;
@@ -467,9 +613,31 @@ static int btusb_send_frame(struct sk_buff *skb)
                break;
 
        case HCI_SCODATA_PKT:
+               if (!data->isoc_tx_ep || hdev->conn_hash.sco_num < 1)
+                       return -ENODEV;
+
+               urb = usb_alloc_urb(BTUSB_MAX_ISOC_FRAMES, GFP_ATOMIC);
+               if (!urb)
+                       return -ENOMEM;
+
+               pipe = usb_sndisocpipe(data->udev,
+                                       data->isoc_tx_ep->bEndpointAddress);
+
+               urb->dev      = data->udev;
+               urb->pipe     = pipe;
+               urb->context  = skb;
+               urb->complete = btusb_tx_complete;
+               urb->interval = data->isoc_tx_ep->bInterval;
+
+               urb->transfer_flags  = URB_ISO_ASAP;
+               urb->transfer_buffer = skb->data;
+               urb->transfer_buffer_length = skb->len;
+
+               __fill_isoc_descriptor(urb, skb->len,
+                               le16_to_cpu(data->isoc_tx_ep->wMaxPacketSize));
+
                hdev->stat.sco_tx++;
-               kfree_skb(skb);
-               return 0;
+               break;
 
        default:
                return -EILSEQ;
@@ -508,22 +676,86 @@ static void btusb_notify(struct hci_dev *hdev, unsigned int evt)
                schedule_work(&data->work);
 }
 
+static int inline __set_isoc_interface(struct hci_dev *hdev, int altsetting)
+{
+       struct btusb_data *data = hdev->driver_data;
+       struct usb_interface *intf = data->isoc;
+       struct usb_endpoint_descriptor *ep_desc;
+       int i, err;
+
+       if (!data->isoc)
+               return -ENODEV;
+
+       err = usb_set_interface(data->udev, 1, altsetting);
+       if (err < 0) {
+               BT_ERR("%s setting interface failed (%d)", hdev->name, -err);
+               return err;
+       }
+
+       data->isoc_altsetting = altsetting;
+
+       data->isoc_tx_ep = NULL;
+       data->isoc_rx_ep = NULL;
+
+       for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++) {
+               ep_desc = &intf->cur_altsetting->endpoint[i].desc;
+
+               if (!data->isoc_tx_ep && usb_endpoint_is_isoc_out(ep_desc)) {
+                       data->isoc_tx_ep = ep_desc;
+                       continue;
+               }
+
+               if (!data->isoc_rx_ep && usb_endpoint_is_isoc_in(ep_desc)) {
+                       data->isoc_rx_ep = ep_desc;
+                       continue;
+               }
+       }
+
+       if (!data->isoc_tx_ep || !data->isoc_rx_ep) {
+               BT_ERR("%s invalid SCO descriptors", hdev->name);
+               return -ENODEV;
+       }
+
+       return 0;
+}
+
 static void btusb_work(struct work_struct *work)
 {
        struct btusb_data *data = container_of(work, struct btusb_data, work);
        struct hci_dev *hdev = data->hdev;
 
-       if (hdev->conn_hash.acl_num == 0) {
+       if (hdev->conn_hash.acl_num > 0) {
+               if (!test_and_set_bit(BTUSB_BULK_RUNNING, &data->flags)) {
+                       if (btusb_submit_bulk_urb(hdev) < 0)
+                               clear_bit(BTUSB_BULK_RUNNING, &data->flags);
+                       else
+                               btusb_submit_bulk_urb(hdev);
+               }
+       } else {
                clear_bit(BTUSB_BULK_RUNNING, &data->flags);
                usb_kill_anchored_urbs(&data->bulk_anchor);
-               return;
        }
 
-       if (!test_and_set_bit(BTUSB_BULK_RUNNING, &data->flags)) {
-               if (btusb_submit_bulk_urb(hdev) < 0)
-                       clear_bit(BTUSB_BULK_RUNNING, &data->flags);
-               else
-                       btusb_submit_bulk_urb(hdev);
+       if (hdev->conn_hash.sco_num > 0) {
+               if (data->isoc_altsetting != 2) {
+                       clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
+                       usb_kill_anchored_urbs(&data->isoc_anchor);
+
+                       if (__set_isoc_interface(hdev, 2) < 0)
+                               return;
+               }
+
+               if (!test_and_set_bit(BTUSB_ISOC_RUNNING, &data->flags)) {
+                       if (btusb_submit_isoc_urb(hdev) < 0)
+                               clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
+                       else
+                               btusb_submit_isoc_urb(hdev);
+               }
+       } else {
+               clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
+               usb_kill_anchored_urbs(&data->isoc_anchor);
+
+               __set_isoc_interface(hdev, 0);
        }
 }
 
@@ -597,6 +829,7 @@ static int btusb_probe(struct usb_interface *intf,
        init_usb_anchor(&data->tx_anchor);
        init_usb_anchor(&data->intr_anchor);
        init_usb_anchor(&data->bulk_anchor);
+       init_usb_anchor(&data->isoc_anchor);
 
        hdev = hci_alloc_dev();
        if (!hdev) {
@@ -620,6 +853,9 @@ static int btusb_probe(struct usb_interface *intf,
 
        hdev->owner = THIS_MODULE;
 
+       /* interface numbers are hardcoded in the spec */
+       data->isoc = usb_ifnum_to_if(data->udev, 1);
+
        if (reset || id->driver_info & BTUSB_RESET)
                set_bit(HCI_QUIRK_RESET_ON_INIT, &hdev->quirks);
 
@@ -628,11 +864,16 @@ static int btusb_probe(struct usb_interface *intf,
                        set_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks);
        }
 
+       if (id->driver_info & BTUSB_BROKEN_ISOC)
+               data->isoc = NULL;
+
        if (id->driver_info & BTUSB_SNIFFER) {
-               struct usb_device *udev = interface_to_usbdev(intf);
+               struct usb_device *udev = data->udev;
 
                if (le16_to_cpu(udev->descriptor.bcdDevice) > 0x997)
                        set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks);
+
+               data->isoc = NULL;
        }
 
        if (id->driver_info & BTUSB_BCM92035) {
@@ -646,6 +887,16 @@ static int btusb_probe(struct usb_interface *intf,
                }
        }
 
+       if (data->isoc) {
+               err = usb_driver_claim_interface(&btusb_driver,
+                                                       data->isoc, NULL);
+               if (err < 0) {
+                       hci_free_dev(hdev);
+                       kfree(data);
+                       return err;
+               }
+       }
+
        err = hci_register_dev(hdev);
        if (err < 0) {
                hci_free_dev(hdev);
@@ -670,6 +921,9 @@ static void btusb_disconnect(struct usb_interface *intf)
 
        hdev = data->hdev;
 
+       if (data->isoc)
+               usb_driver_release_interface(&btusb_driver, data->isoc);
+
        usb_set_intfdata(intf, NULL);
 
        hci_unregister_dev(hdev);
index 69df187d74ced8d2d262309c203e071669089f3d..8dfcf77cb71783c892437f5cb20eff417c1ee94e 100644 (file)
@@ -577,7 +577,7 @@ module_exit(hci_uart_exit);
 module_param(reset, bool, 0644);
 MODULE_PARM_DESC(reset, "Send HCI reset command on initialization");
 
-MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>, Marcel Holtmann <marcel@holtmann.org>");
+MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
 MODULE_DESCRIPTION("Bluetooth HCI UART driver ver " VERSION);
 MODULE_VERSION(VERSION);
 MODULE_LICENSE("GPL");
index e397572bf574cc95da87d14cb126a48b4ba9bef4..3c453924f8386c9b92050ae978967d188ec3b4da 100644 (file)
@@ -1130,7 +1130,7 @@ module_param(isoc, int, 0644);
 MODULE_PARM_DESC(isoc, "Set isochronous transfers for SCO over HCI support");
 #endif
 
-MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>, Marcel Holtmann <marcel@holtmann.org>");
+MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
 MODULE_DESCRIPTION("Bluetooth HCI USB driver ver " VERSION);
 MODULE_VERSION(VERSION);
 MODULE_LICENSE("GPL");
index d97700aa54a9b63edf66507e7592fdc9e6ca3937..7320a71b63685403c9972766c4eb716ba9b05791 100644 (file)
@@ -377,7 +377,7 @@ module_exit(vhci_exit);
 module_param(minor, int, 0444);
 MODULE_PARM_DESC(minor, "Miscellaneous minor device number");
 
-MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>, Marcel Holtmann <marcel@holtmann.org>");
+MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
 MODULE_DESCRIPTION("Bluetooth virtual HCI driver ver " VERSION);
 MODULE_VERSION(VERSION);
 MODULE_LICENSE("GPL");
index f52931e1c16eb08d0d353a92836a6fdfe0060268..8e8afb6141f99edc8f3a38bbcad1e1b9e802961f 100644 (file)
@@ -2695,15 +2695,13 @@ static __devinit void default_find_bmc(void)
        for (i = 0; ; i++) {
                if (!ipmi_defaults[i].port)
                        break;
-
-               info = kzalloc(sizeof(*info), GFP_KERNEL);
-               if (!info)
-                       return;
-
 #ifdef CONFIG_PPC_MERGE
                if (check_legacy_ioport(ipmi_defaults[i].port))
                        continue;
 #endif
+               info = kzalloc(sizeof(*info), GFP_KERNEL);
+               if (!info)
+                       return;
 
                info->addr_source = NULL;
 
index e0d0e371909cd2f1c00d4e2f63fe8c8ae2c81bcc..1838aa3d24feac6a09b9516acbb1ffd623e7f2db 100644 (file)
@@ -1571,6 +1571,7 @@ u32 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport)
 
        return half_md4_transform(hash, keyptr->secret);
 }
+EXPORT_SYMBOL_GPL(secure_ipv4_port_ephemeral);
 
 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
 u32 secure_ipv6_port_ephemeral(const __be32 *saddr, const __be32 *daddr,
index c5b1840906b2fdb968277fd6f02b594fb6d86683..8b0252bf06e221ea89a0b9b6b3f89f0eda301722 100644 (file)
@@ -38,7 +38,6 @@
 
 #include <linux/types.h>
 #include <linux/cdev.h>
-#include <linux/version.h>
 #include <linux/platform_device.h>
 
 #include <asm/io.h>
index ffabd3ba2bd82c25076751ddf24decf25f699268..62bda453c90b8a6101e91d11f00ec24406ab48b4 100644 (file)
@@ -38,7 +38,6 @@
 
 #include <linux/types.h>
 #include <linux/cdev.h>
-#include <linux/version.h>
 #include <linux/platform_device.h>
 
 #include <asm/io.h>
index 1f9c8b082dbe1643920a59f4cba44973957607de..24d0d9b938fb39e485c56d9e74d1d9ff6effa5e6 100644 (file)
@@ -38,7 +38,6 @@
 
 #include <linux/types.h>
 #include <linux/cdev.h>
-#include <linux/version.h>
 #include <linux/platform_device.h>
 
 #include <asm/io.h>
index b27b13c5eb5ad3871c88247887460a253d1a5276..4b55ec607a88f622bf6e81e24aad7812a401d76a 100644 (file)
@@ -34,7 +34,6 @@
 #include <linux/platform_device.h>
 #include <linux/sysdev.h>
 #include <linux/workqueue.h>
-#include <linux/version.h>
 
 #define EDAC_MC_LABEL_LEN      31
 #define EDAC_DEVICE_NAME_LEN   31
index fa6d6abefd4d14d9bdb8c372118a1ddbcea7b2fb..4509024382081cc17325ab72da5d7587675b1ef8 100644 (file)
@@ -12,8 +12,8 @@ config FIREWIRE
          This is the "Juju" FireWire stack, a new alternative implementation
          designed for robustness and simplicity.  You can build either this
          stack, or the old stack (the ieee1394 driver, ohci1394 etc.) or both.
-         Please read http://wiki.linux1394.org/JujuMigration before you
-         enable the new stack.
+         Please read http://ieee1394.wiki.kernel.org/index.php/Juju_Migration
+         before you enable the new stack.
 
          To compile this driver as a module, say M here: the module will be
          called firewire-core.
index c1adcdbf7979d5f958d9780a719c03c961171f84..9efb02137254b61391efa5f30a3b155b6c68998d 100644 (file)
@@ -14,7 +14,6 @@
 */
 
 #include <linux/module.h>
-#include <linux/version.h>
 #include <linux/kernel.h>
 #include <linux/err.h>
 #include <linux/slab.h>
index 994a21e5a0aa7e6d929e94b82f0f8f99efe5b72f..16240a7896509c024bacf59ff48bd8dd1c227d9d 100644 (file)
@@ -844,7 +844,7 @@ static struct node_entry *nodemgr_create_node(octlet_t guid, struct csr1212_csr
        ne->host = host;
        ne->nodeid = nodeid;
        ne->generation = generation;
-       ne->needs_probe = 1;
+       ne->needs_probe = true;
 
        ne->guid = guid;
        ne->guid_vendor_id = (guid >> 40) & 0xffffff;
@@ -1144,7 +1144,7 @@ static void nodemgr_process_root_directory(struct host_info *hi, struct node_ent
        struct csr1212_keyval *kv, *vendor_name_kv = NULL;
        u8 last_key_id = 0;
 
-       ne->needs_probe = 0;
+       ne->needs_probe = false;
 
        csr1212_for_each_dir_entry(ne->csr, kv, ne->csr->root_kv, dentry) {
                switch (kv->key.id) {
@@ -1295,7 +1295,7 @@ static void nodemgr_update_node(struct node_entry *ne, struct csr1212_csr *csr,
                nodemgr_update_bus_options(ne);
 
                /* Mark the node as new, so it gets re-probed */
-               ne->needs_probe = 1;
+               ne->needs_probe = true;
        } else {
                /* old cache is valid, so update its generation */
                struct nodemgr_csr_info *ci = ne->csr->private;
@@ -1566,57 +1566,60 @@ static void nodemgr_probe_ne(struct host_info *hi, struct node_entry *ne, int ge
 struct probe_param {
        struct host_info *hi;
        int generation;
+       bool probe_now;
 };
 
-static int __nodemgr_node_probe(struct device *dev, void *data)
+static int node_probe(struct device *dev, void *data)
 {
-       struct probe_param *param = (struct probe_param *)data;
+       struct probe_param *p = data;
        struct node_entry *ne;
 
+       if (p->generation != get_hpsb_generation(p->hi->host))
+               return -EAGAIN;
+
        ne = container_of(dev, struct node_entry, node_dev);
-       if (!ne->needs_probe)
-               nodemgr_probe_ne(param->hi, ne, param->generation);
-       if (ne->needs_probe)
-               nodemgr_probe_ne(param->hi, ne, param->generation);
+       if (ne->needs_probe == p->probe_now)
+               nodemgr_probe_ne(p->hi, ne, p->generation);
        return 0;
 }
 
 static void nodemgr_node_probe(struct host_info *hi, int generation)
 {
-       struct hpsb_host *host = hi->host;
-       struct probe_param param;
+       struct probe_param p;
 
-       param.hi = hi;
-       param.generation = generation;
-       /* Do some processing of the nodes we've probed. This pulls them
+       p.hi = hi;
+       p.generation = generation;
+       /*
+        * Do some processing of the nodes we've probed. This pulls them
         * into the sysfs layer if needed, and can result in processing of
         * unit-directories, or just updating the node and it's
         * unit-directories.
         *
         * Run updates before probes. Usually, updates are time-critical
-        * while probes are time-consuming. (Well, those probes need some
-        * improvement...) */
-
-       class_for_each_device(&nodemgr_ne_class, NULL, &param,
-                             __nodemgr_node_probe);
-
-       /* If we had a bus reset while we were scanning the bus, it is
-        * possible that we did not probe all nodes.  In that case, we
-        * skip the clean up for now, since we could remove nodes that
-        * were still on the bus.  Another bus scan is pending which will
-        * do the clean up eventually.
+        * while probes are time-consuming.
         *
+        * Meanwhile, another bus reset may have happened. In this case we
+        * skip everything here and let the next bus scan handle it.
+        * Otherwise we may prematurely remove nodes which are still there.
+        */
+       p.probe_now = false;
+       if (class_for_each_device(&nodemgr_ne_class, NULL, &p, node_probe) != 0)
+               return;
+
+       p.probe_now = true;
+       if (class_for_each_device(&nodemgr_ne_class, NULL, &p, node_probe) != 0)
+               return;
+       /*
         * Now let's tell the bus to rescan our devices. This may seem
         * like overhead, but the driver-model core will only scan a
         * device for a driver when either the device is added, or when a
         * new driver is added. A bus reset is a good reason to rescan
         * devices that were there before.  For example, an sbp2 device
         * may become available for login, if the host that held it was
-        * just removed.  */
-
-       if (generation == get_hpsb_generation(host))
-               if (bus_rescan_devices(&ieee1394_bus_type))
-                       HPSB_DEBUG("bus_rescan_devices had an error");
+        * just removed.
+        */
+       if (bus_rescan_devices(&ieee1394_bus_type) != 0)
+               HPSB_DEBUG("bus_rescan_devices had an error");
 }
 
 static int nodemgr_send_resume_packet(struct hpsb_host *host)
index 919e92e2a9556b12045fca7371f8faf6e955e679..6eb26465a84ca44029c4d43cc3ba17ba1eb1c378 100644 (file)
@@ -97,7 +97,7 @@ struct node_entry {
        struct hpsb_host *host;         /* Host this node is attached to */
        nodeid_t nodeid;                /* NodeID */
        struct bus_options busopt;      /* Bus Options */
-       int needs_probe;
+       bool needs_probe;
        unsigned int generation;        /* Synced with hpsb generation */
 
        /* The following is read from the config rom */
index 9cbf3154d2432ec748a03625450b35b92f9ade7f..1d6ad34355372f1c492d984e1c8b56f625d0acf6 100644 (file)
@@ -731,15 +731,26 @@ static int sbp2_update(struct unit_directory *ud)
 {
        struct sbp2_lu *lu = ud->device.driver_data;
 
-       if (sbp2_reconnect_device(lu)) {
-               /* Reconnect has failed. Perhaps we didn't reconnect fast
-                * enough. Try a regular login, but first log out just in
-                * case of any weirdness. */
+       if (sbp2_reconnect_device(lu) != 0) {
+               /*
+                * Reconnect failed.  If another bus reset happened,
+                * let nodemgr proceed and call sbp2_update again later
+                * (or sbp2_remove if this node went away).
+                */
+               if (!hpsb_node_entry_valid(lu->ne))
+                       return 0;
+               /*
+                * Or the target rejected the reconnect because we weren't
+                * fast enough.  Try a regular login, but first log out
+                * just in case of any weirdness.
+                */
                sbp2_logout_device(lu);
 
-               if (sbp2_login_device(lu)) {
-                       /* Login failed too, just fail, and the backend
-                        * will call our sbp2_remove for us */
+               if (sbp2_login_device(lu) != 0) {
+                       if (!hpsb_node_entry_valid(lu->ne))
+                               return 0;
+
+                       /* Maybe another initiator won the login. */
                        SBP2_ERR("Failed to reconnect to sbp2 device!");
                        return -EBUSY;
                }
index ec950bf8c479b220143c54289fb90a18bd176d64..21f7d06f14ad2f1ed9e5ede9f6323a9007a2106f 100644 (file)
@@ -54,7 +54,6 @@
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/vmalloc.h>
-#include <linux/version.h>
 #include <linux/notifier.h>
 #include <linux/cpu.h>
 #include <linux/device.h>
index 23faba9d21eb34aab1337782fecd24f7a3871ec8..8bb5170b4e416b1b660f333561ffa7c8bb4c7360 100644 (file)
@@ -31,7 +31,6 @@
  * SOFTWARE.
  */
 
-#include <linux/version.h>
 #include <linux/module.h>
 #include <linux/fs.h>
 #include <linux/mount.h>
index d90f5e9a54faf8b16c790eab5a7af4ade2a022af..9839e20119bcfc64f483f68cf2b18d24e1786f77 100644 (file)
@@ -1720,7 +1720,7 @@ static void ipath_7220_put_tid(struct ipath_devdata *dd, u64 __iomem *tidptr,
                                 "not 2KB aligned!\n", pa);
                        return;
                }
-               if (pa >= (1UL << IBA7220_TID_SZ_SHIFT)) {
+               if (chippa >= (1UL << IBA7220_TID_SZ_SHIFT)) {
                        ipath_dev_err(dd,
                                      "BUG: Physical page address 0x%lx "
                                      "larger than supported\n", pa);
index 36aa242c487c4d582d39d94b86e53377466455ef..729446f56aab580d2ffcd7200a124d22ea6e7c3e 100644 (file)
@@ -267,6 +267,7 @@ int ipath_make_ud_req(struct ipath_qp *qp)
        u16 lrh0;
        u16 lid;
        int ret = 0;
+       int next_cur;
 
        spin_lock_irqsave(&qp->s_lock, flags);
 
@@ -290,8 +291,9 @@ int ipath_make_ud_req(struct ipath_qp *qp)
                goto bail;
 
        wqe = get_swqe_ptr(qp, qp->s_cur);
-       if (++qp->s_cur >= qp->s_size)
-               qp->s_cur = 0;
+       next_cur = qp->s_cur + 1;
+       if (next_cur >= qp->s_size)
+               next_cur = 0;
 
        /* Construct the header. */
        ah_attr = &to_iah(wqe->wr.wr.ud.ah)->attr;
@@ -315,6 +317,7 @@ int ipath_make_ud_req(struct ipath_qp *qp)
                                qp->s_flags |= IPATH_S_WAIT_DMA;
                                goto bail;
                        }
+                       qp->s_cur = next_cur;
                        spin_unlock_irqrestore(&qp->s_lock, flags);
                        ipath_ud_loopback(qp, wqe);
                        spin_lock_irqsave(&qp->s_lock, flags);
@@ -323,6 +326,7 @@ int ipath_make_ud_req(struct ipath_qp *qp)
                }
        }
 
+       qp->s_cur = next_cur;
        extra_bytes = -wqe->length & 3;
        nwords = (wqe->length + extra_bytes) >> 2;
 
index 39bd897b40c6aa1cd4ded5a0179dafc6035af792..8eb7ae96974d0846fe52f28a04f579ce12edd28b 100644 (file)
@@ -43,7 +43,6 @@
 #include <linux/dma-mapping.h>
 #include <linux/workqueue.h>
 #include <linux/slab.h>
-#include <linux/version.h>
 #include <asm/io.h>
 #include <linux/crc32c.h>
 
index f51201b17bfd3048ddbd66fd4edadb41b310cdb0..7e9e218738fa0f4be74741266e690d7c4211e6e0 100644 (file)
@@ -156,14 +156,8 @@ static int ipoib_stop(struct net_device *dev)
 
        netif_stop_queue(dev);
 
-       /*
-        * Now flush workqueue to make sure a scheduled task doesn't
-        * bring our internal state back up.
-        */
-       flush_workqueue(ipoib_workqueue);
-
-       ipoib_ib_dev_down(dev, 1);
-       ipoib_ib_dev_stop(dev, 1);
+       ipoib_ib_dev_down(dev, 0);
+       ipoib_ib_dev_stop(dev, 0);
 
        if (!test_bit(IPOIB_FLAG_SUBINTERFACE, &priv->flags)) {
                struct ipoib_dev_priv *cpriv;
@@ -1314,7 +1308,7 @@ sysfs_failed:
 
 register_failed:
        ib_unregister_event_handler(&priv->event_handler);
-       flush_scheduled_work();
+       flush_workqueue(ipoib_workqueue);
 
 event_failed:
        ipoib_dev_cleanup(priv->dev);
@@ -1373,7 +1367,12 @@ static void ipoib_remove_one(struct ib_device *device)
 
        list_for_each_entry_safe(priv, tmp, dev_list, list) {
                ib_unregister_event_handler(&priv->event_handler);
-               flush_scheduled_work();
+
+               rtnl_lock();
+               dev_change_flags(priv->dev, priv->dev->flags & ~IFF_UP);
+               rtnl_unlock();
+
+               flush_workqueue(ipoib_workqueue);
 
                unregister_netdev(priv->dev);
                ipoib_dev_cleanup(priv->dev);
index 8950e9546f4eb64a33fe4dd2b7c7698382b63e37..ac33c8f3ea8580e5120dd98704cfbccb0ccd5c71 100644 (file)
@@ -392,8 +392,16 @@ static int ipoib_mcast_join_complete(int status,
                                           &priv->mcast_task, 0);
                mutex_unlock(&mcast_mutex);
 
-               if (mcast == priv->broadcast)
+               if (mcast == priv->broadcast) {
+                       /*
+                        * Take RTNL lock here to avoid racing with
+                        * ipoib_stop() and turning the carrier back
+                        * on while a device is being removed.
+                        */
+                       rtnl_lock();
                        netif_carrier_on(dev);
+                       rtnl_unlock();
+               }
 
                return 0;
        }
index 63462ecca147ccfa9e0b40e2070d49412592ba67..26ff6214a81f4b64ac2a0b406ece8febcbfbac59 100644 (file)
@@ -33,7 +33,6 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/delay.h>
-#include <linux/version.h>
 
 #include "iscsi_iser.h"
 
index a92d81567559ba9fb59508628fdba56a0b7405bb..3524bef62be654910ec23ca5c917787269a6b018 100644 (file)
@@ -677,8 +677,8 @@ static int handle_eviocgbit(struct input_dev *dev, unsigned int cmd, void __user
                len = OLD_KEY_MAX;
                if (printk_timed_ratelimit(&keymax_warn_time, 10 * 1000))
                        printk(KERN_WARNING
-                               "evdev.c(EVIOCGBIT): Suspicious buffer size %d, "
-                               "limiting output to %d bytes. See "
+                               "evdev.c(EVIOCGBIT): Suspicious buffer size %u, "
+                               "limiting output to %zu bytes. See "
                                "http://userweb.kernel.org/~dtor/eviocgbit-bug.html\n",
                                OLD_KEY_MAX,
                                BITS_TO_LONGS(OLD_KEY_MAX) * sizeof(long));
index 54ed8e2e1c021c540f2c06adaef5ae009f3d056b..6f227d3dbda19039356ae25519e6465b96463219 100644 (file)
@@ -29,7 +29,6 @@
  */
 
 #include <linux/module.h>
-#include <linux/version.h>
 
 #include <linux/init.h>
 #include <linux/fs.h>
index 3f48279f219502b70aaf80f267b8ae1b190b2ab7..ec96b369dd7ac02ed3bb49dec3bcfe8e9c649ae1 100644 (file)
@@ -9,7 +9,6 @@
  */
 
 #include <linux/module.h>
-#include <linux/version.h>
 
 #include <linux/init.h>
 #include <linux/fs.h>
index 6a1f48b76e3298649130c8d341123bcbf2e0f131..2adf9cb265da69fd67b6d1b8bec3fa3841e95ec2 100644 (file)
@@ -148,6 +148,9 @@ static int __devexit cobalt_buttons_remove(struct platform_device *pdev)
        return 0;
 }
 
+MODULE_AUTHOR("Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>");
+MODULE_DESCRIPTION("Cobalt button interface driver");
+MODULE_LICENSE("GPL");
 /* work with hotplug and coldplug */
 MODULE_ALIAS("platform:Cobalt buttons");
 
index 3392901848711f4f5053b4d042387ce5d69a2611..72cf5e33790ea6e0541b7e351e53e2cf03803bd4 100644 (file)
@@ -9,7 +9,6 @@
  */
 
 #include <linux/init.h>
-#include <linux/version.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/input-polldev.h>
index b9b7a98bc5a5b49a450d46b4a94fcc6f8037ee89..7df0228e836e1dff3c679f9009b66bece3fe1558 100644 (file)
@@ -64,7 +64,6 @@ Scott Hill shill@gtcocalcomp.com
 #include <asm/byteorder.h>
 
 
-#include <linux/version.h>
 #include <linux/usb/input.h>
 
 /* Version with a Major number of 2 is for kernel inclusion only. */
index 283f93a0cee29f873baa7f544b46363184f3529b..37a555f37306226ff0dae5495bfa45c733d297a2 100644 (file)
@@ -25,7 +25,6 @@
 
 #include <linux/module.h>
 #include <linux/moduleparam.h>
-#include <linux/version.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/delay.h>
index c1cd99d589810de0c03387a6af4f89fdf0f40c86..504ca11749a1896e35b489bfba4bdc6747c57e71 100644 (file)
@@ -173,7 +173,7 @@ static int migor_ts_probe(struct i2c_client *client,
        input_set_abs_params(input, ABS_X, 95, 955, 0, 0);
        input_set_abs_params(input, ABS_Y, 85, 935, 0, 0);
 
-       input->name = client->driver_name;
+       input->name = client->name;
        input->id.bustype = BUS_I2C;
        input->dev.parent = &client->dev;
 
@@ -192,7 +192,7 @@ static int migor_ts_probe(struct i2c_client *client,
                goto err1;
 
        error = request_irq(priv->irq, migor_ts_isr, IRQF_TRIGGER_LOW,
-                           client->driver_name, priv);
+                           client->name, priv);
        if (error) {
                dev_err(&client->dev, "Unable to request touchscreen IRQ.\n");
                goto err2;
@@ -224,12 +224,19 @@ static int migor_ts_remove(struct i2c_client *client)
        return 0;
 }
 
+static const struct i2c_device_id migor_ts_id[] = {
+       { "migor_ts", 0 },
+       { }
+};
+MODULE_DEVICE_TABLE(i2c, migor_ts);
+
 static struct i2c_driver migor_ts_driver = {
        .driver = {
                .name = "migor_ts",
        },
        .probe = migor_ts_probe,
        .remove = migor_ts_remove,
+       .id_table = migor_ts_id,
 };
 
 static int __init migor_ts_init(void)
index 978e1a13ffc7437c3dec7b0917227b1440dd07d2..372efbc694ffbf7ebe71e96decefd71060e6d7c8 100644 (file)
@@ -17,7 +17,6 @@
 
 #include <linux/module.h>
 #include <linux/moduleparam.h>
-#include <linux/version.h>
 #include <linux/kernel.h>
 #include <linux/input.h>
 #include <linux/delay.h>
index 4c5d85a249aeceb6edc7d59506618bbe5dc22807..c8bb1e7335fcf8f9450c0be194cafc9f014d03fb 100644 (file)
@@ -17,7 +17,6 @@
 
 #include <linux/module.h>
 #include <linux/moduleparam.h>
-#include <linux/version.h>
 #include <linux/kernel.h>
 #include <linux/input.h>
 #include <linux/delay.h>
index 838458792ea0dc6924676ac6448573d6270da871..781ee83547e68374eba1f253a016a26435135e27 100644 (file)
@@ -17,7 +17,6 @@
 
 #include <linux/module.h>
 #include <linux/moduleparam.h>
-#include <linux/version.h>
 #include <linux/kernel.h>
 #include <linux/input.h>
 #include <linux/delay.h>
index cdc24ad314e0b7478b0a6cdde46362e335974a3c..d589ab0e3adc41c0b75eb55c645937afdcdef843 100644 (file)
@@ -37,7 +37,6 @@
 
 #include <linux/module.h>
 #include <linux/moduleparam.h>
-#include <linux/version.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/delay.h>
index 37344aaee22f3ab44910a18576489466c0b8c30d..a661bbdae3d62f657fc801eceb80d9afefc3e4bf 100644 (file)
@@ -98,6 +98,10 @@ static u32 lg_get_features(struct virtio_device *vdev)
        return features;
 }
 
+/* The virtio core takes the features the Host offers, and copies the
+ * ones supported by the driver into the vdev->features array.  Once
+ * that's all sorted out, this routine is called so we can tell the
+ * Host which features we understand and accept. */
 static void lg_finalize_features(struct virtio_device *vdev)
 {
        unsigned int i, bits;
@@ -108,6 +112,10 @@ static void lg_finalize_features(struct virtio_device *vdev)
        /* Give virtio_ring a chance to accept features. */
        vring_transport_features(vdev);
 
+       /* The vdev->feature array is a Linux bitmask: this isn't the
+        * same as a the simple array of bits used by lguest devices
+        * for features.  So we do this slow, manual conversion which is
+        * completely general. */
        memset(out_features, 0, desc->feature_len);
        bits = min_t(unsigned, desc->feature_len, sizeof(vdev->features)) * 8;
        for (i = 0; i < bits; i++) {
index c6408a62d95e3ab791bb3a303ba717ec1563b591..bc2a807f210df1804129f0de665c8b2cacde9614 100644 (file)
@@ -16,7 +16,6 @@
  *
  */
 
-#include <linux/version.h>
 #include <linux/kernel.h>
 #include <linux/irq.h>
 #include <linux/gpio.h>
index b2d9878dc3f0ea606896c356ced7d942acef2106..c6c77a505ec1e621307ded371c224094b0222b13 100644 (file)
@@ -192,6 +192,9 @@ static struct quirk_entry *quirks;
 
 static void set_quirks(void)
 {
+       if (!interface)
+               return;
+
        if (quirks->mailled)
                interface->capability |= ACER_CAP_MAILLED;
 
@@ -1237,6 +1240,8 @@ static int __init acer_wmi_init(void)
                return -ENODEV;
        }
 
+       set_quirks();
+
        if (platform_driver_register(&acer_platform_driver)) {
                printk(ACER_ERR "Unable to register platform driver.\n");
                goto error_platform_register;
index 9e8d79e7e9f4cb4b105840ce71420e435820edd5..facdb9893c84c322dbb65f47e2a7bf8de3c69685 100644 (file)
@@ -553,9 +553,9 @@ static void eeepc_hwmon_exit(void)
        hwmon = eeepc_hwmon_device;
        if (!hwmon)
                return ;
-       hwmon_device_unregister(hwmon);
        sysfs_remove_group(&hwmon->kobj,
                           &hwmon_attribute_group);
+       hwmon_device_unregister(hwmon);
        eeepc_hwmon_device = NULL;
 }
 
index ea55654e5948255afdf82679e76bb1b5f3078047..15b1780025c84e75c24b83ca0ce6dbab6336dc0b 100644 (file)
@@ -26,7 +26,6 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/version.h>
 #include <linux/delay.h>
 #include <linux/eeprom_93cx6.h>
 
index 948b86f35ef4a2e2068f12878d21f6653f4e9868..d1eec7d3243f39ea0bb7e2e0b9c0f299e11ee1ce 100644 (file)
@@ -6,7 +6,6 @@
 
 #include <linux/module.h>
 #include <linux/types.h>
-#include <linux/version.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <asm/io.h>
index effaf7cdefabe4bb306a4e982cde16613721ac7b..1a6feb4474ded02f2fb4381c088efe3dd310a024 100644 (file)
@@ -9,7 +9,6 @@
 
 #include <linux/module.h>
 #include <linux/types.h>
-#include <linux/version.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <asm/io.h>
index aa64a475278134eb3eafea4bb5cb7db40459b8da..bbbcdd4c8d13d7f757c435538bc2f1ccc63953db 100644 (file)
@@ -12,7 +12,6 @@
 
 #include <linux/module.h>
 #include <linux/types.h>
-#include <linux/version.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <asm/io.h>
index 761946ea45b132da9dde13b1d3ea9b7935f53a8a..92c334ff450885a8d06179ac14a4276c3805b933 100644 (file)
@@ -16,7 +16,6 @@
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/nand.h>
 #include <linux/mtd/partitions.h>
-#include <linux/version.h>
 #include <asm/io.h>
 
 #include <asm/mach-au1x00/au1xxx.h>
index 4b4cb2bf4f11564fbd72f0e3996c966e4eff9b3a..a5c141cecd4edf0aca3a89900d6c5927d03cd92f 100644 (file)
@@ -1172,7 +1172,7 @@ config ETH16I
 
 config NE2000
        tristate "NE2000/NE1000 support"
-       depends on NET_ISA || (Q40 && m) || M32R || TOSHIBA_RBTX4927 || TOSHIBA_RBTX4938
+       depends on NET_ISA || (Q40 && m) || M32R || MACH_TX49XX
        select CRC32
        ---help---
          If you have a network (Ethernet) card of this type, say Y and read
index e4483de84e7f5558cf0e62e7ae40eef16dd68796..66de80b64b92a3f937edf821e49ec748c6478ed3 100644 (file)
@@ -52,7 +52,6 @@
 
 #include <linux/module.h>
 #include <linux/moduleparam.h>
-#include <linux/version.h>
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
index 020771bfb6039839becfdda79f4d1d085a2912f3..e2d702b8b2e4766321824c26941074b40c950fa5 100644 (file)
@@ -551,7 +551,7 @@ static int eth_poll(struct napi_struct *napi, int budget)
                if ((skb = netdev_alloc_skb(dev, RX_BUFF_SIZE))) {
                        phys = dma_map_single(&dev->dev, skb->data,
                                              RX_BUFF_SIZE, DMA_FROM_DEVICE);
-                       if (dma_mapping_error(phys)) {
+                       if (dma_mapping_error(&dev->dev, phys)) {
                                dev_kfree_skb(skb);
                                skb = NULL;
                        }
@@ -698,7 +698,7 @@ static int eth_xmit(struct sk_buff *skb, struct net_device *dev)
 #endif
 
        phys = dma_map_single(&dev->dev, mem, bytes, DMA_TO_DEVICE);
-       if (dma_mapping_error(phys)) {
+       if (dma_mapping_error(&dev->dev, phys)) {
 #ifdef __ARMEB__
                dev_kfree_skb(skb);
 #else
@@ -883,7 +883,7 @@ static int init_queues(struct port *port)
                desc->buf_len = MAX_MRU;
                desc->data = dma_map_single(&port->netdev->dev, data,
                                            RX_BUFF_SIZE, DMA_FROM_DEVICE);
-               if (dma_mapping_error(desc->data)) {
+               if (dma_mapping_error(&port->netdev->dev, desc->data)) {
                        free_buffer(buff);
                        return -EIO;
                }
index cdc3b85b10b9086fe6dfbbe198afef23e9f37019..619c6583e1aac7ca5e8dd1ff263fab6325b6193c 100644 (file)
@@ -355,7 +355,7 @@ static int atl1e_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
        struct atl1e_adapter *adapter = netdev_priv(netdev);
 
        if (wol->wolopts & (WAKE_ARP | WAKE_MAGICSECURE |
-                           WAKE_MCAST | WAKE_BCAST | WAKE_MCAST))
+                           WAKE_UCAST | WAKE_MCAST | WAKE_BCAST))
                return -EOPNOTSUPP;
        /* these settings will always override what we currently have */
        adapter->wol = 0;
index cb8be490e5aed1f9f7afd7f9a68522ee2d6192ba..5ee1b0557a028f1bf7c6e621c50a60d0a6c14e9f 100644 (file)
@@ -807,7 +807,7 @@ err_out:
 static int au1000_init(struct net_device *dev)
 {
        struct au1000_private *aup = (struct au1000_private *) dev->priv;
-       u32 flags;
+       unsigned long flags;
        int i;
        u32 control;
 
index 0b4adf4a0f7da9ab772ca84bc1d4738ca034c263..a886a4b9f7e5e24b97f7efe6f3e3aba559221cf9 100644 (file)
@@ -554,7 +554,7 @@ static int ax_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 
        spin_lock_irqsave(&ax->mii_lock, flags);
        mii_ethtool_gset(&ax->mii, cmd);
-       spin_lock_irqsave(&ax->mii_lock, flags);
+       spin_unlock_irqrestore(&ax->mii_lock, flags);
 
        return 0;
 }
@@ -567,7 +567,7 @@ static int ax_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 
        spin_lock_irqsave(&ax->mii_lock, flags);
        rc = mii_ethtool_sset(&ax->mii, cmd);
-       spin_lock_irqsave(&ax->mii_lock, flags);
+       spin_unlock_irqrestore(&ax->mii_lock, flags);
 
        return rc;
 }
index 5ebde67d4297451aa9019f97105f31c76f268f7f..2486a656f12d9f47ff27ead587e084a3c337a1a3 100644 (file)
@@ -35,8 +35,8 @@
 #include <linux/time.h>
 #include <linux/ethtool.h>
 #include <linux/mii.h>
-#ifdef NETIF_F_HW_VLAN_TX
 #include <linux/if_vlan.h>
+#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
 #define BCM_VLAN 1
 #endif
 #include <net/ip.h>
@@ -57,8 +57,8 @@
 
 #define DRV_MODULE_NAME                "bnx2"
 #define PFX DRV_MODULE_NAME    ": "
-#define DRV_MODULE_VERSION     "1.7.9"
-#define DRV_MODULE_RELDATE     "July 18, 2008"
+#define DRV_MODULE_VERSION     "1.8.0"
+#define DRV_MODULE_RELDATE     "Aug 14, 2008"
 
 #define RUN_AT(x) (jiffies + (x))
 
@@ -2876,6 +2876,8 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget)
                struct sw_bd *rx_buf;
                struct sk_buff *skb;
                dma_addr_t dma_addr;
+               u16 vtag = 0;
+               int hw_vlan __maybe_unused = 0;
 
                sw_ring_cons = RX_RING_IDX(sw_cons);
                sw_ring_prod = RX_RING_IDX(sw_prod);
@@ -2919,7 +2921,7 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget)
                if (len <= bp->rx_copy_thresh) {
                        struct sk_buff *new_skb;
 
-                       new_skb = netdev_alloc_skb(bp->dev, len + 2);
+                       new_skb = netdev_alloc_skb(bp->dev, len + 6);
                        if (new_skb == NULL) {
                                bnx2_reuse_rx_skb(bp, rxr, skb, sw_ring_cons,
                                                  sw_ring_prod);
@@ -2928,9 +2930,9 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget)
 
                        /* aligned copy */
                        skb_copy_from_linear_data_offset(skb,
-                                                        BNX2_RX_OFFSET - 2,
-                                     new_skb->data, len + 2);
-                       skb_reserve(new_skb, 2);
+                                                        BNX2_RX_OFFSET - 6,
+                                     new_skb->data, len + 6);
+                       skb_reserve(new_skb, 6);
                        skb_put(new_skb, len);
 
                        bnx2_reuse_rx_skb(bp, rxr, skb,
@@ -2941,6 +2943,25 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget)
                           dma_addr, (sw_ring_cons << 16) | sw_ring_prod)))
                        goto next_rx;
 
+               if ((status & L2_FHDR_STATUS_L2_VLAN_TAG) &&
+                   !(bp->rx_mode & BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG)) {
+                       vtag = rx_hdr->l2_fhdr_vlan_tag;
+#ifdef BCM_VLAN
+                       if (bp->vlgrp)
+                               hw_vlan = 1;
+                       else
+#endif
+                       {
+                               struct vlan_ethhdr *ve = (struct vlan_ethhdr *)
+                                       __skb_push(skb, 4);
+
+                               memmove(ve, skb->data + 4, ETH_ALEN * 2);
+                               ve->h_vlan_proto = htons(ETH_P_8021Q);
+                               ve->h_vlan_TCI = htons(vtag);
+                               len += 4;
+                       }
+               }
+
                skb->protocol = eth_type_trans(skb, bp->dev);
 
                if ((len > (bp->dev->mtu + ETH_HLEN)) &&
@@ -2962,10 +2983,8 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget)
                }
 
 #ifdef BCM_VLAN
-               if ((status & L2_FHDR_STATUS_L2_VLAN_TAG) && bp->vlgrp) {
-                       vlan_hwaccel_receive_skb(skb, bp->vlgrp,
-                               rx_hdr->l2_fhdr_vlan_tag);
-               }
+               if (hw_vlan)
+                       vlan_hwaccel_receive_skb(skb, bp->vlgrp, vtag);
                else
 #endif
                        netif_receive_skb(skb);
@@ -3237,10 +3256,10 @@ bnx2_set_rx_mode(struct net_device *dev)
                                  BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG);
        sort_mode = 1 | BNX2_RPM_SORT_USER0_BC_EN;
 #ifdef BCM_VLAN
-       if (!bp->vlgrp && !(bp->flags & BNX2_FLAG_ASF_ENABLE))
+       if (!bp->vlgrp && (bp->flags & BNX2_FLAG_CAN_KEEP_VLAN))
                rx_mode |= BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG;
 #else
-       if (!(bp->flags & BNX2_FLAG_ASF_ENABLE))
+       if (bp->flags & BNX2_FLAG_CAN_KEEP_VLAN)
                rx_mode |= BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG;
 #endif
        if (dev->flags & IFF_PROMISC) {
@@ -5963,10 +5982,12 @@ bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev)
                vlan_tag_flags |= TX_BD_FLAGS_TCP_UDP_CKSUM;
        }
 
+#ifdef BCM_VLAN
        if (bp->vlgrp && vlan_tx_tag_present(skb)) {
                vlan_tag_flags |=
                        (TX_BD_FLAGS_VLAN_TAG | (vlan_tx_tag_get(skb) << 16));
        }
+#endif
        if ((mss = skb_shinfo(skb)->gso_size)) {
                u32 tcp_opt_len, ip_tcp_len;
                struct iphdr *iph;
index 8b92c6ad0759107131e4d65211dad419c0b5e60f..4ce7fe9c5251143745985b70cb449df9f394edfd 100644 (file)
@@ -21,7 +21,6 @@
 #include <linux/delay.h>
 #include <linux/ethtool.h>
 #include <linux/mutex.h>
-#include <linux/version.h>
 
 #include "bnx2x_reg.h"
 #include "bnx2x_fw_defs.h"
index 3e7dc171cdf10858c94d87a4874cadcdfbb24246..971576b4368751846f95d85064cccf2c6d5255eb 100644 (file)
@@ -44,7 +44,6 @@
 #include <net/ip.h>
 #include <net/tcp.h>
 #include <net/checksum.h>
-#include <linux/version.h>
 #include <net/ip6_checksum.h>
 #include <linux/workqueue.h>
 #include <linux/crc32.h>
index a7800e55909099d07594c4e13c05c09c040d380d..ec6b0af3d46b4f5d715587173cb5c293fea965e1 100644 (file)
@@ -26,7 +26,6 @@
 #include <linux/errno.h>
 #include <linux/types.h>
 #include <linux/delay.h>
-#include <linux/version.h>
 
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
index f823b8ba5785060e939300397130e290be8543cd..14b0e6cd3b8d420b995b63b6989f6d9070d58d31 100644 (file)
 
 /* Interrupt Cause Set */
 #define E1000_ICS_LSC       E1000_ICR_LSC       /* Link Status Change */
-#define E1000_ICS_RXDMT0    E1000_ICR_RXDMT0    /* rx desc min. threshold */
+#define E1000_ICS_RXSEQ     E1000_ICR_RXSEQ     /* Rx sequence error */
 #define E1000_ICS_RXDMT0    E1000_ICR_RXDMT0    /* Rx desc min. threshold */
 
 /* Transmit Descriptor Control */
index cf57050d99d8fce223e17d2dcae7c1180a8d9673..ac4e506b4f88a495cd9d6e7616cc662ed60abf96 100644 (file)
@@ -326,6 +326,7 @@ struct e1000_info {
 #define FLAG_RX_CSUM_ENABLED              (1 << 28)
 #define FLAG_TSO_FORCE                    (1 << 29)
 #define FLAG_RX_RESTART_NOW               (1 << 30)
+#define FLAG_MSI_TEST_FAILED              (1 << 31)
 
 #define E1000_RX_DESC_PS(R, i)     \
        (&(((union e1000_rx_desc_packet_split *)((R).desc))[i]))
index cf9679f2b7c41fc94906f81872f452bdf9750b71..e21c9e0f3738441a159ad0a4068e9bb8fe2b82e5 100644 (file)
@@ -177,7 +177,7 @@ static u32 e1000_get_link(struct net_device *netdev)
        u32 status;
        
        status = er32(STATUS);
-       return (status & E1000_STATUS_LU);
+       return (status & E1000_STATUS_LU) ? 1 : 0;
 }
 
 static int e1000_set_spd_dplx(struct e1000_adapter *adapter, u16 spddplx)
index 05b0b2f9c54bc7ac2234e4ef5dedb3a8469a2103..d266510c8a94683ae4d21516cf6c18491dc3eb3a 100644 (file)
@@ -510,9 +510,12 @@ static bool e1000_clean_rx_irq(struct e1000_adapter *adapter,
                            netdev_alloc_skb(netdev, length + NET_IP_ALIGN);
                        if (new_skb) {
                                skb_reserve(new_skb, NET_IP_ALIGN);
-                               memcpy(new_skb->data - NET_IP_ALIGN,
-                                      skb->data - NET_IP_ALIGN,
-                                      length + NET_IP_ALIGN);
+                               skb_copy_to_linear_data_offset(new_skb,
+                                                              -NET_IP_ALIGN,
+                                                              (skb->data -
+                                                               NET_IP_ALIGN),
+                                                              (length +
+                                                               NET_IP_ALIGN));
                                /* save the skb in buffer_info as good */
                                buffer_info->skb = skb;
                                skb = new_skb;
@@ -1233,26 +1236,36 @@ static irqreturn_t e1000_intr(int irq, void *data)
        return IRQ_HANDLED;
 }
 
+/**
+ * e1000_request_irq - initialize interrupts
+ *
+ * Attempts to configure interrupts using the best available
+ * capabilities of the hardware and kernel.
+ **/
 static int e1000_request_irq(struct e1000_adapter *adapter)
 {
        struct net_device *netdev = adapter->netdev;
-       irq_handler_t handler = e1000_intr;
        int irq_flags = IRQF_SHARED;
        int err;
 
-       if (!pci_enable_msi(adapter->pdev)) {
-               adapter->flags |= FLAG_MSI_ENABLED;
-               handler = e1000_intr_msi;
-               irq_flags = 0;
+       if (!(adapter->flags & FLAG_MSI_TEST_FAILED)) {
+               err = pci_enable_msi(adapter->pdev);
+               if (!err) {
+                       adapter->flags |= FLAG_MSI_ENABLED;
+                       irq_flags = 0;
+               }
        }
 
-       err = request_irq(adapter->pdev->irq, handler, irq_flags, netdev->name,
-                         netdev);
+       err = request_irq(adapter->pdev->irq,
+                         ((adapter->flags & FLAG_MSI_ENABLED) ?
+                               &e1000_intr_msi : &e1000_intr),
+                         irq_flags, netdev->name, netdev);
        if (err) {
-               e_err("Unable to allocate %s interrupt (return: %d)\n",
-                     adapter->flags & FLAG_MSI_ENABLED ? "MSI":"INTx", err);
-               if (adapter->flags & FLAG_MSI_ENABLED)
+               if (adapter->flags & FLAG_MSI_ENABLED) {
                        pci_disable_msi(adapter->pdev);
+                       adapter->flags &= ~FLAG_MSI_ENABLED;
+               }
+               e_err("Unable to allocate interrupt, Error: %d\n", err);
        }
 
        return err;
@@ -2591,6 +2604,135 @@ err:
        return -ENOMEM;
 }
 
+/**
+ * e1000_intr_msi_test - Interrupt Handler
+ * @irq: interrupt number
+ * @data: pointer to a network interface device structure
+ **/
+static irqreturn_t e1000_intr_msi_test(int irq, void *data)
+{
+       struct net_device *netdev = data;
+       struct e1000_adapter *adapter = netdev_priv(netdev);
+       struct e1000_hw *hw = &adapter->hw;
+       u32 icr = er32(ICR);
+
+       e_dbg("%s: icr is %08X\n", netdev->name, icr);
+       if (icr & E1000_ICR_RXSEQ) {
+               adapter->flags &= ~FLAG_MSI_TEST_FAILED;
+               wmb();
+       }
+
+       return IRQ_HANDLED;
+}
+
+/**
+ * e1000_test_msi_interrupt - Returns 0 for successful test
+ * @adapter: board private struct
+ *
+ * code flow taken from tg3.c
+ **/
+static int e1000_test_msi_interrupt(struct e1000_adapter *adapter)
+{
+       struct net_device *netdev = adapter->netdev;
+       struct e1000_hw *hw = &adapter->hw;
+       int err;
+
+       /* poll_enable hasn't been called yet, so don't need disable */
+       /* clear any pending events */
+       er32(ICR);
+
+       /* free the real vector and request a test handler */
+       e1000_free_irq(adapter);
+
+       /* Assume that the test fails, if it succeeds then the test
+        * MSI irq handler will unset this flag */
+       adapter->flags |= FLAG_MSI_TEST_FAILED;
+
+       err = pci_enable_msi(adapter->pdev);
+       if (err)
+               goto msi_test_failed;
+
+       err = request_irq(adapter->pdev->irq, &e1000_intr_msi_test, 0,
+                         netdev->name, netdev);
+       if (err) {
+               pci_disable_msi(adapter->pdev);
+               goto msi_test_failed;
+       }
+
+       wmb();
+
+       e1000_irq_enable(adapter);
+
+       /* fire an unusual interrupt on the test handler */
+       ew32(ICS, E1000_ICS_RXSEQ);
+       e1e_flush();
+       msleep(50);
+
+       e1000_irq_disable(adapter);
+
+       rmb();
+
+       if (adapter->flags & FLAG_MSI_TEST_FAILED) {
+               err = -EIO;
+               e_info("MSI interrupt test failed!\n");
+       }
+
+       free_irq(adapter->pdev->irq, netdev);
+       pci_disable_msi(adapter->pdev);
+
+       if (err == -EIO)
+               goto msi_test_failed;
+
+       /* okay so the test worked, restore settings */
+       e_dbg("%s: MSI interrupt test succeeded!\n", netdev->name);
+msi_test_failed:
+       /* restore the original vector, even if it failed */
+       e1000_request_irq(adapter);
+       return err;
+}
+
+/**
+ * e1000_test_msi - Returns 0 if MSI test succeeds or INTx mode is restored
+ * @adapter: board private struct
+ *
+ * code flow taken from tg3.c, called with e1000 interrupts disabled.
+ **/
+static int e1000_test_msi(struct e1000_adapter *adapter)
+{
+       int err;
+       u16 pci_cmd;
+
+       if (!(adapter->flags & FLAG_MSI_ENABLED))
+               return 0;
+
+       /* disable SERR in case the MSI write causes a master abort */
+       pci_read_config_word(adapter->pdev, PCI_COMMAND, &pci_cmd);
+       pci_write_config_word(adapter->pdev, PCI_COMMAND,
+                             pci_cmd & ~PCI_COMMAND_SERR);
+
+       err = e1000_test_msi_interrupt(adapter);
+
+       /* restore previous setting of command word */
+       pci_write_config_word(adapter->pdev, PCI_COMMAND, pci_cmd);
+
+       /* success ! */
+       if (!err)
+               return 0;
+
+       /* EIO means MSI test failed */
+       if (err != -EIO)
+               return err;
+
+       /* back to INTx mode */
+       e_warn("MSI interrupt test failed, using legacy interrupt.\n");
+
+       e1000_free_irq(adapter);
+
+       err = e1000_request_irq(adapter);
+
+       return err;
+}
+
 /**
  * e1000_open - Called when a network interface is made active
  * @netdev: network interface device structure
@@ -2649,6 +2791,19 @@ static int e1000_open(struct net_device *netdev)
        if (err)
                goto err_req_irq;
 
+       /*
+        * Work around PCIe errata with MSI interrupts causing some chipsets to
+        * ignore e1000e MSI messages, which means we need to test our MSI
+        * interrupt now
+        */
+       {
+               err = e1000_test_msi(adapter);
+               if (err) {
+                       e_err("Interrupt allocation failed\n");
+                       goto err_req_irq;
+               }
+       }
+
        /* From here on the code is the same as e1000e_up() */
        clear_bit(__E1000_DOWN, &adapter->state);
 
@@ -3055,7 +3210,7 @@ static void e1000_watchdog_task(struct work_struct *work)
                        case SPEED_10:
                                txb2b = 0;
                                netdev->tx_queue_len = 10;
-                               adapter->tx_timeout_factor = 14;
+                               adapter->tx_timeout_factor = 16;
                                break;
                        case SPEED_100:
                                txb2b = 0;
@@ -3721,7 +3876,7 @@ static int e1000_change_mtu(struct net_device *netdev, int new_mtu)
        struct e1000_adapter *adapter = netdev_priv(netdev);
        int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN;
 
-       if ((max_frame < ETH_ZLEN + ETH_FCS_LEN) ||
+       if ((new_mtu < ETH_ZLEN + ETH_FCS_LEN + VLAN_HLEN) ||
            (max_frame > MAX_JUMBO_FRAME_SIZE)) {
                e_err("Invalid MTU setting\n");
                return -EINVAL;
index 8effc3107f9a914e3ae710d22dc97487d79ddc87..ed912e023a7266db32cf88dcb60e8bf406d5c421 100644 (file)
@@ -324,14 +324,27 @@ void __devinit e1000e_check_options(struct e1000_adapter *adapter)
                                adapter->itr = 20000;
                                break;
                        default:
-                               e1000_validate_option(&adapter->itr, &opt,
-                                       adapter);
                                /*
-                                * save the setting, because the dynamic bits
-                                * change itr. clear the lower two bits
-                                * because they are used as control
+                                * Save the setting, because the dynamic bits
+                                * change itr.
                                 */
-                               adapter->itr_setting = adapter->itr & ~3;
+                               if (e1000_validate_option(&adapter->itr, &opt,
+                                                         adapter) &&
+                                   (adapter->itr == 3)) {
+                                       /*
+                                        * In case of invalid user value,
+                                        * default to conservative mode.
+                                        */
+                                       adapter->itr_setting = adapter->itr;
+                                       adapter->itr = 20000;
+                               } else {
+                                       /*
+                                        * Clear the lower two bits because
+                                        * they are used as control.
+                                        */
+                                       adapter->itr_setting =
+                                               adapter->itr & ~3;
+                               }
                                break;
                        }
                } else {
index ca6cf6ecb37b17a2f5d605b5dc9e9413a733cdc4..999d69168277f7190bb2d4e0367ea56a5ba473d8 100644 (file)
@@ -134,9 +134,7 @@ static int gfar_process_frame(struct net_device *dev, struct sk_buff *skb, int l
 static void gfar_vlan_rx_register(struct net_device *netdev,
                                struct vlan_group *grp);
 void gfar_halt(struct net_device *dev);
-#ifdef CONFIG_PM
 static void gfar_halt_nodisable(struct net_device *dev);
-#endif
 void gfar_start(struct net_device *dev);
 static void gfar_clear_exact_match(struct net_device *dev);
 static void gfar_set_mac_for_addr(struct net_device *dev, int num, u8 *addr);
@@ -631,7 +629,6 @@ static void init_registers(struct net_device *dev)
 }
 
 
-#ifdef CONFIG_PM
 /* Halt the receive and transmit queues */
 static void gfar_halt_nodisable(struct net_device *dev)
 {
@@ -657,7 +654,6 @@ static void gfar_halt_nodisable(struct net_device *dev)
                        cpu_relax();
        }
 }
-#endif
 
 /* Halt the receive and transmit queues */
 void gfar_halt(struct net_device *dev)
@@ -666,6 +662,8 @@ void gfar_halt(struct net_device *dev)
        struct gfar __iomem *regs = priv->regs;
        u32 tempval;
 
+       gfar_halt_nodisable(dev);
+
        /* Disable Rx and Tx */
        tempval = gfar_read(&regs->maccfg1);
        tempval &= ~(MACCFG1_RX_EN | MACCFG1_TX_EN);
index 5116f68e01b9a4618423f47d555d68771da01d3e..782c201700820c45abb1cddfd1dba606ba6c38ae 100644 (file)
@@ -33,7 +33,6 @@
 
 #include <asm/uaccess.h>
 #include <linux/module.h>
-#include <linux/version.h>
 
 #include "gianfar.h"
 
index e0e718ab4c2ee3f69f1463dfe199a3446f48c7d5..dd9318f19497c82915722fe774f5fe48f40ed222 100644 (file)
@@ -7,7 +7,6 @@
 #ifndef __LINUX_IPG_H
 #define __LINUX_IPG_H
 
-#include <linux/version.h>
 #include <linux/module.h>
 
 #include <linux/kernel.h>
@@ -21,7 +20,6 @@
 #include <linux/etherdevice.h>
 #include <linux/init.h>
 #include <linux/skbuff.h>
-#include <linux/version.h>
 #include <asm/bitops.h>
 
 /*
index 2f38e847e2cd0401c7ef6eba738cb6cb2b465561..f96358b641af974334d2deaed65531ecefcc8323 100644 (file)
@@ -190,6 +190,7 @@ static enum ixgbe_media_type ixgbe_get_media_type_82598(struct ixgbe_hw *hw)
        case IXGBE_DEV_ID_82598AF_DUAL_PORT:
        case IXGBE_DEV_ID_82598AF_SINGLE_PORT:
        case IXGBE_DEV_ID_82598EB_CX4:
+       case IXGBE_DEV_ID_82598_CX4_DUAL_PORT:
                media_type = ixgbe_media_type_fiber;
                break;
        case IXGBE_DEV_ID_82598AT_DUAL_PORT:
index e5f3da8468cccd13c49d28125b730d49417dc27b..34bca16d48a6663c4a8bb919d8ee77bd591b4171 100644 (file)
@@ -48,7 +48,7 @@ char ixgbe_driver_name[] = "ixgbe";
 static const char ixgbe_driver_string[] =
        "Intel(R) 10 Gigabit PCI Express Network Driver";
 
-#define DRV_VERSION "1.3.18-k2"
+#define DRV_VERSION "1.3.18-k4"
 const char ixgbe_driver_version[] = DRV_VERSION;
 static const char ixgbe_copyright[] =
         "Copyright (c) 1999-2007 Intel Corporation.";
@@ -72,6 +72,8 @@ static struct pci_device_id ixgbe_pci_tbl[] = {
         board_82598 },
        {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598EB_CX4),
         board_82598 },
+       {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598_CX4_DUAL_PORT),
+        board_82598 },
 
        /* required last entry */
        {0, }
index 1ad7cb9c25a84a0e934e565fb084ffdf17ecb4cc..c0282a223df3938dd0dad446f925e88300535b4f 100644 (file)
@@ -39,6 +39,7 @@
 #define IXGBE_DEV_ID_82598AF_SINGLE_PORT 0x10C7
 #define IXGBE_DEV_ID_82598AT_DUAL_PORT   0x10C8
 #define IXGBE_DEV_ID_82598EB_CX4         0x10DD
+#define IXGBE_DEV_ID_82598_CX4_DUAL_PORT 0x10EC
 
 /* General Registers */
 #define IXGBE_CTRL      0x00000
index 49f6bc036a9275f21478f4d7f498300020358049..3b43bfd85a0f6dd3e1506d8a5a29e4ae85f3429e 100644 (file)
@@ -64,68 +64,6 @@ struct pcpu_lstats {
        unsigned long bytes;
 };
 
-/* KISS: just allocate small chunks and copy bits.
- *
- * So, in fact, this is documentation, explaining what we expect
- * of largesending device modulo TCP checksum, which is ignored for loopback.
- */
-
-#ifdef LOOPBACK_TSO
-static void emulate_large_send_offload(struct sk_buff *skb)
-{
-       struct iphdr *iph = ip_hdr(skb);
-       struct tcphdr *th = (struct tcphdr *)(skb_network_header(skb) +
-                                             (iph->ihl * 4));
-       unsigned int doffset = (iph->ihl + th->doff) * 4;
-       unsigned int mtu = skb_shinfo(skb)->gso_size + doffset;
-       unsigned int offset = 0;
-       u32 seq = ntohl(th->seq);
-       u16 id  = ntohs(iph->id);
-
-       while (offset + doffset < skb->len) {
-               unsigned int frag_size = min(mtu, skb->len - offset) - doffset;
-               struct sk_buff *nskb = alloc_skb(mtu + 32, GFP_ATOMIC);
-
-               if (!nskb)
-                       break;
-               skb_reserve(nskb, 32);
-               skb_set_mac_header(nskb, -ETH_HLEN);
-               skb_reset_network_header(nskb);
-               iph = ip_hdr(nskb);
-               skb_copy_to_linear_data(nskb, skb_network_header(skb),
-                                       doffset);
-               if (skb_copy_bits(skb,
-                                 doffset + offset,
-                                 nskb->data + doffset,
-                                 frag_size))
-                       BUG();
-               skb_put(nskb, doffset + frag_size);
-               nskb->ip_summed = CHECKSUM_UNNECESSARY;
-               nskb->dev = skb->dev;
-               nskb->priority = skb->priority;
-               nskb->protocol = skb->protocol;
-               nskb->dst = dst_clone(skb->dst);
-               memcpy(nskb->cb, skb->cb, sizeof(skb->cb));
-               nskb->pkt_type = skb->pkt_type;
-
-               th = (struct tcphdr *)(skb_network_header(nskb) + iph->ihl * 4);
-               iph->tot_len = htons(frag_size + doffset);
-               iph->id = htons(id);
-               iph->check = 0;
-               iph->check = ip_fast_csum((unsigned char *) iph, iph->ihl);
-               th->seq = htonl(seq);
-               if (offset + doffset + frag_size < skb->len)
-                       th->fin = th->psh = 0;
-               netif_rx(nskb);
-               offset += frag_size;
-               seq += frag_size;
-               id++;
-       }
-
-       dev_kfree_skb(skb);
-}
-#endif /* LOOPBACK_TSO */
-
 /*
  * The higher levels take care of making this non-reentrant (it's
  * called with bh's disabled).
@@ -137,9 +75,6 @@ static int loopback_xmit(struct sk_buff *skb, struct net_device *dev)
        skb_orphan(skb);
 
        skb->protocol = eth_type_trans(skb,dev);
-#ifndef LOOPBACK_MUST_CHECKSUM
-       skb->ip_summed = CHECKSUM_UNNECESSARY;
-#endif
 
 #ifdef LOOPBACK_TSO
        if (skb_is_gso(skb)) {
@@ -234,9 +169,7 @@ static void loopback_setup(struct net_device *dev)
        dev->type               = ARPHRD_LOOPBACK;      /* 0x0001*/
        dev->flags              = IFF_LOOPBACK;
        dev->features           = NETIF_F_SG | NETIF_F_FRAGLIST
-#ifdef LOOPBACK_TSO
                | NETIF_F_TSO
-#endif
                | NETIF_F_NO_CSUM
                | NETIF_F_HIGHDMA
                | NETIF_F_LLTX
index f1de38f8b7425d7bbf2c2bf81ba3d2dfd8899814..54cd89cb0838fd46ad379943e78763289d66630c 100644 (file)
@@ -56,7 +56,6 @@
 #include <linux/ethtool.h>
 #include <linux/firmware.h>
 #include <linux/delay.h>
-#include <linux/version.h>
 #include <linux/timer.h>
 #include <linux/vmalloc.h>
 #include <linux/crc32.h>
@@ -3548,7 +3547,11 @@ static void myri10ge_probe_slices(struct myri10ge_priv *mgp)
 
        /* try to load the slice aware rss firmware */
        old_fw = mgp->fw_name;
-       if (old_fw == myri10ge_fw_aligned)
+       if (myri10ge_fw_name != NULL) {
+               dev_info(&mgp->pdev->dev, "overriding rss firmware to %s\n",
+                        myri10ge_fw_name);
+               mgp->fw_name = myri10ge_fw_name;
+       } else if (old_fw == myri10ge_fw_aligned)
                mgp->fw_name = myri10ge_fw_rss_aligned;
        else
                mgp->fw_name = myri10ge_fw_rss_unaligned;
index 42443d697423d72fef98e52958d514a1ef3c4779..fa3ceca4e15c0c07f3d414b8fbeb05eb711129cb 100644 (file)
@@ -118,7 +118,7 @@ bad_clone_list[] __initdata = {
     {"E-LAN100", "E-LAN200", {0x00, 0x00, 0x5d}}, /* Broken ne1000 clones */
     {"PCM-4823", "PCM-4823", {0x00, 0xc0, 0x6c}}, /* Broken Advantech MoBo */
     {"REALTEK", "RTL8019", {0x00, 0x00, 0xe8}}, /* no-name with Realtek chip */
-#if defined(CONFIG_TOSHIBA_RBTX4927) || defined(CONFIG_TOSHIBA_RBTX4938)
+#ifdef CONFIG_MACH_TX49XX
     {"RBHMA4X00-RTL8019", "RBHMA4X00/RTL8019", {0x00, 0x60, 0x0a}},  /* Toshiba built-in */
 #endif
     {"LCS-8834", "LCS-8836", {0x04, 0x04, 0x37}}, /* ShinyNet (SET) */
@@ -142,7 +142,7 @@ bad_clone_list[] __initdata = {
 #if defined(CONFIG_PLAT_MAPPI)
 #  define DCR_VAL 0x4b
 #elif defined(CONFIG_PLAT_OAKS32R)  || \
-   defined(CONFIG_TOSHIBA_RBTX4927) || defined(CONFIG_TOSHIBA_RBTX4938)
+   defined(CONFIG_MACH_TX49XX)
 #  define DCR_VAL 0x48         /* 8-bit mode */
 #else
 #  define DCR_VAL 0x49
index 93a7b9b668d5a745ea873d686e26eb1976570647..244ab49c4337354e86dce1a4a97208abf54256ff 100644 (file)
@@ -45,7 +45,6 @@
 #include <linux/in.h>
 #include <linux/tcp.h>
 #include <linux/skbuff.h>
-#include <linux/version.h>
 
 #include <linux/ethtool.h>
 #include <linux/mii.h>
@@ -66,8 +65,8 @@
 
 #define _NETXEN_NIC_LINUX_MAJOR 4
 #define _NETXEN_NIC_LINUX_MINOR 0
-#define _NETXEN_NIC_LINUX_SUBVERSION 0
-#define NETXEN_NIC_LINUX_VERSIONID  "4.0.0"
+#define _NETXEN_NIC_LINUX_SUBVERSION 11
+#define NETXEN_NIC_LINUX_VERSIONID  "4.0.11"
 
 #define NETXEN_VERSION_CODE(a, b, c)   (((a) << 16) + ((b) << 8) + (c))
 
@@ -1615,7 +1614,8 @@ dma_watchdog_wakeup(struct netxen_adapter *adapter)
 
 
 int netxen_is_flash_supported(struct netxen_adapter *adapter);
-int netxen_get_flash_mac_addr(struct netxen_adapter *adapter, __le64 mac[]);
+int netxen_get_flash_mac_addr(struct netxen_adapter *adapter, __le64 *mac);
+int netxen_p3_get_mac_addr(struct netxen_adapter *adapter, __le64 *mac);
 extern void netxen_change_ringparam(struct netxen_adapter *adapter);
 extern int netxen_rom_fast_read(struct netxen_adapter *adapter, int addr,
                                int *valp);
index 4ad3e0844b9938de000c4bd966e02f8913976635..b974ca0fc530a45babd8962ec47a0f70c2820f9a 100644 (file)
@@ -38,7 +38,6 @@
 #include <asm/io.h>
 #include <linux/netdevice.h>
 #include <linux/ethtool.h>
-#include <linux/version.h>
 
 #include "netxen_nic.h"
 #include "netxen_nic_hw.h"
index e8e8d73f6ed76eeae52bd2e2b6b92800287c40a3..e80f9e3e59731fb08ccadefa1da9cb9d0a007768 100644 (file)
@@ -32,8 +32,6 @@
 
 #include <linux/module.h>
 #include <linux/kernel.h>
-#include <linux/version.h>
-
 #include <linux/spinlock.h>
 #include <asm/irq.h>
 #include <linux/init.h>
index 9aa20f961618aff39195cec203306e285db7bdad..84978f80f396e681eefa0e8cc76bac57e1ea232c 100644 (file)
@@ -733,31 +733,56 @@ static int netxen_get_flash_block(struct netxen_adapter *adapter, int base,
        return 0;
 }
 
-int netxen_get_flash_mac_addr(struct netxen_adapter *adapter, __le64 mac[])
+int netxen_get_flash_mac_addr(struct netxen_adapter *adapter, __le64 *mac)
 {
-       __le32 *pmac = (__le32 *) & mac[0];
+       __le32 *pmac = (__le32 *) mac;
+       u32 offset;
 
-       if (netxen_get_flash_block(adapter,
-                                  NETXEN_USER_START +
-                                  offsetof(struct netxen_new_user_info,
-                                           mac_addr),
-                                  FLASH_NUM_PORTS * sizeof(u64), pmac) == -1) {
+       offset = NETXEN_USER_START +
+               offsetof(struct netxen_new_user_info, mac_addr) +
+               adapter->portnum * sizeof(u64);
+
+       if (netxen_get_flash_block(adapter, offset, sizeof(u64), pmac) == -1)
                return -1;
-       }
+
        if (*mac == cpu_to_le64(~0ULL)) {
+
+               offset = NETXEN_USER_START_OLD +
+                       offsetof(struct netxen_user_old_info, mac_addr) +
+                       adapter->portnum * sizeof(u64);
+
                if (netxen_get_flash_block(adapter,
-                                          NETXEN_USER_START_OLD +
-                                          offsetof(struct netxen_user_old_info,
-                                                   mac_addr),
-                                          FLASH_NUM_PORTS * sizeof(u64),
-                                          pmac) == -1)
+                                       offset, sizeof(u64), pmac) == -1)
                        return -1;
+
                if (*mac == cpu_to_le64(~0ULL))
                        return -1;
        }
        return 0;
 }
 
+int netxen_p3_get_mac_addr(struct netxen_adapter *adapter, __le64 *mac)
+{
+       uint32_t crbaddr, mac_hi, mac_lo;
+       int pci_func = adapter->ahw.pci_func;
+
+       crbaddr = CRB_MAC_BLOCK_START +
+               (4 * ((pci_func/2) * 3)) + (4 * (pci_func & 1));
+
+       adapter->hw_read_wx(adapter, crbaddr, &mac_lo, 4);
+       adapter->hw_read_wx(adapter, crbaddr+4, &mac_hi, 4);
+
+       mac_hi = cpu_to_le32(mac_hi);
+       mac_lo = cpu_to_le32(mac_lo);
+
+       if (pci_func & 1)
+               *mac = ((mac_lo >> 16) | ((u64)mac_hi << 16));
+       else
+               *mac = ((mac_lo) | ((u64)mac_hi << 32));
+
+       return 0;
+}
+
 #define CRB_WIN_LOCK_TIMEOUT 100000000
 
 static int crb_win_lock(struct netxen_adapter *adapter)
@@ -2183,10 +2208,10 @@ void netxen_nic_flash_print(struct netxen_adapter *adapter)
        if (adapter->portnum == 0) {
                get_brd_name_by_type(board_info->board_type, brd_name);
 
-               printk("NetXen %s Board S/N %s  Chip id 0x%x\n",
-                               brd_name, serial_num, board_info->chip_id);
-               printk("NetXen Firmware version %d.%d.%d\n", fw_major,
-                               fw_minor, fw_build);
+               printk(KERN_INFO "NetXen %s Board S/N %s  Chip rev 0x%x\n",
+                               brd_name, serial_num, adapter->ahw.revision_id);
+               printk(KERN_INFO "NetXen Firmware version %d.%d.%d\n",
+                               fw_major, fw_minor, fw_build);
        }
 
        if (NETXEN_VERSION_CODE(fw_major, fw_minor, fw_build) <
index 519fc860e17e0ac9e1aa018acc40549a60eca178..5bba675d0504594fc340ab3223956d167d4ef0ea 100644 (file)
@@ -1079,10 +1079,12 @@ int netxen_initialize_adapter_offload(struct netxen_adapter *adapter)
 
 void netxen_free_adapter_offload(struct netxen_adapter *adapter)
 {
-       int i;
+       int i = 100;
+
+       if (!adapter->dummy_dma.addr)
+               return;
 
-       if (adapter->dummy_dma.addr) {
-               i = 100;
+       if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
                do {
                        if (dma_watchdog_shutdown_request(adapter) == 1)
                                break;
@@ -1090,17 +1092,17 @@ void netxen_free_adapter_offload(struct netxen_adapter *adapter)
                        if (dma_watchdog_shutdown_poll_result(adapter) == 1)
                                break;
                } while (--i);
+       }
 
-               if (i) {
-                       pci_free_consistent(adapter->pdev,
-                                   NETXEN_HOST_DUMMY_DMA_SIZE,
-                                   adapter->dummy_dma.addr,
-                                   adapter->dummy_dma.phys_addr);
-                       adapter->dummy_dma.addr = NULL;
-               } else {
-                       printk(KERN_ERR "%s: dma_watchdog_shutdown failed\n",
-                                       adapter->netdev->name);
-               }
+       if (i) {
+               pci_free_consistent(adapter->pdev,
+                           NETXEN_HOST_DUMMY_DMA_SIZE,
+                           adapter->dummy_dma.addr,
+                           adapter->dummy_dma.phys_addr);
+               adapter->dummy_dma.addr = NULL;
+       } else {
+               printk(KERN_ERR "%s: dma_watchdog_shutdown failed\n",
+                               adapter->netdev->name);
        }
 }
 
index 7615c715e66efd0b3cffb33d1c103f79c1c50916..32bb47adbe39b3db3b2c44b083c73ece4fbd3b9a 100644 (file)
@@ -149,76 +149,18 @@ static uint32_t msi_tgt_status[8] = {
 
 static struct netxen_legacy_intr_set legacy_intr[] = NX_LEGACY_INTR_CONFIG;
 
-static void netxen_nic_disable_int(struct netxen_adapter *adapter)
+static inline void netxen_nic_disable_int(struct netxen_adapter *adapter)
 {
-       u32 mask = 0x7ff;
-       int retries = 32;
-       int pci_fn = adapter->ahw.pci_func;
-
-       if (adapter->msi_mode != MSI_MODE_MULTIFUNC)
-               adapter->pci_write_normalize(adapter,
-                               adapter->crb_intr_mask, 0);
-
-       if (adapter->intr_scheme != -1 &&
-           adapter->intr_scheme != INTR_SCHEME_PERPORT)
-               adapter->pci_write_immediate(adapter, ISR_INT_MASK, mask);
-
-       if (!NETXEN_IS_MSI_FAMILY(adapter)) {
-               do {
-                       adapter->pci_write_immediate(adapter,
-                                       adapter->legacy_intr.tgt_status_reg,
-                                       0xffffffff);
-                       mask = adapter->pci_read_immediate(adapter,
-                                       ISR_INT_VECTOR);
-                       if (!(mask & 0x80))
-                               break;
-                       udelay(10);
-               } while (--retries);
-
-               if (!retries) {
-                       printk(KERN_NOTICE "%s: Failed to disable interrupt\n",
-                                       netxen_nic_driver_name);
-               }
-       } else {
-               if (adapter->msi_mode == MSI_MODE_MULTIFUNC) {
-                       adapter->pci_write_immediate(adapter,
-                                       msi_tgt_status[pci_fn], 0xffffffff);
-               }
-       }
+       adapter->pci_write_normalize(adapter, adapter->crb_intr_mask, 0);
 }
 
-static void netxen_nic_enable_int(struct netxen_adapter *adapter)
+static inline void netxen_nic_enable_int(struct netxen_adapter *adapter)
 {
-       u32 mask;
-
-       if (adapter->intr_scheme != -1 &&
-               adapter->intr_scheme != INTR_SCHEME_PERPORT) {
-               switch (adapter->ahw.board_type) {
-               case NETXEN_NIC_GBE:
-                       mask  =  0x77b;
-                       break;
-               case NETXEN_NIC_XGBE:
-                       mask  =  0x77f;
-                       break;
-               default:
-                       mask  =  0x7ff;
-                       break;
-               }
-
-               adapter->pci_write_immediate(adapter, ISR_INT_MASK, mask);
-       }
-
        adapter->pci_write_normalize(adapter, adapter->crb_intr_mask, 0x1);
 
-       if (!NETXEN_IS_MSI_FAMILY(adapter)) {
-               mask = 0xbff;
-               if (adapter->intr_scheme == INTR_SCHEME_PERPORT)
-                       adapter->pci_write_immediate(adapter,
-                               adapter->legacy_intr.tgt_mask_reg, mask);
-               else
-                       adapter->pci_write_normalize(adapter,
-                                       CRB_INT_VECTOR, 0);
-       }
+       if (!NETXEN_IS_MSI_FAMILY(adapter))
+               adapter->pci_write_immediate(adapter,
+                               adapter->legacy_intr.tgt_mask_reg, 0xfbff);
 }
 
 static int nx_set_dma_mask(struct netxen_adapter *adapter, uint8_t revision_id)
@@ -501,6 +443,44 @@ static void netxen_init_msix_entries(struct netxen_adapter *adapter)
                adapter->msix_entries[i].entry = i;
 }
 
+static int
+netxen_read_mac_addr(struct netxen_adapter *adapter)
+{
+       int i;
+       unsigned char *p;
+       __le64 mac_addr;
+       DECLARE_MAC_BUF(mac);
+       struct net_device *netdev = adapter->netdev;
+       struct pci_dev *pdev = adapter->pdev;
+
+       if (netxen_is_flash_supported(adapter) != 0)
+               return -EIO;
+
+       if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
+               if (netxen_p3_get_mac_addr(adapter, &mac_addr) != 0)
+                       return -EIO;
+       } else {
+               if (netxen_get_flash_mac_addr(adapter, &mac_addr) != 0)
+                       return -EIO;
+       }
+
+       p = (unsigned char *)&mac_addr;
+       for (i = 0; i < 6; i++)
+               netdev->dev_addr[i] = *(p + 5 - i);
+
+       memcpy(netdev->perm_addr, netdev->dev_addr, netdev->addr_len);
+
+       /* set station address */
+
+       if (!is_valid_ether_addr(netdev->perm_addr)) {
+               dev_warn(&pdev->dev, "Bad MAC address %s.\n",
+                               print_mac(mac, netdev->dev_addr));
+       } else
+               adapter->macaddr_set(adapter, netdev->dev_addr);
+
+       return 0;
+}
+
 /*
  * netxen_nic_probe()
  *
@@ -529,10 +509,8 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        unsigned long mem_base, mem_len, db_base, db_len, pci_len0 = 0;
        int i = 0, err;
        int first_driver, first_boot;
-       __le64 mac_addr[FLASH_NUM_PORTS + 1];
        u32 val;
        int pci_func_id = PCI_FUNC(pdev->devfn);
-       DECLARE_MAC_BUF(mac);
        struct netxen_legacy_intr_set *legacy_intrp;
        uint8_t revision_id;
 
@@ -545,6 +523,13 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
                return -ENODEV;
        }
 
+       if (pdev->revision >= NX_P3_A0 && pdev->revision < NX_P3_B1) {
+               printk(KERN_WARNING "NetXen chip revisions between 0x%x-0x%x"
+                               "will not be enabled.\n",
+                               NX_P3_A0, NX_P3_B1);
+               return -ENODEV;
+       }
+
        if ((err = pci_enable_device(pdev)))
                return err;
 
@@ -898,34 +883,14 @@ request_msi:
                goto err_out_disable_msi;
 
        init_timer(&adapter->watchdog_timer);
-       adapter->ahw.linkup = 0;
        adapter->watchdog_timer.function = &netxen_watchdog;
        adapter->watchdog_timer.data = (unsigned long)adapter;
        INIT_WORK(&adapter->watchdog_task, netxen_watchdog_task);
        INIT_WORK(&adapter->tx_timeout_task, netxen_tx_timeout_task);
 
-       if (netxen_is_flash_supported(adapter) == 0 &&
-                       netxen_get_flash_mac_addr(adapter, mac_addr) == 0) {
-               unsigned char *p;
-
-               p = (unsigned char *)&mac_addr[adapter->portnum];
-               netdev->dev_addr[0] = *(p + 5);
-               netdev->dev_addr[1] = *(p + 4);
-               netdev->dev_addr[2] = *(p + 3);
-               netdev->dev_addr[3] = *(p + 2);
-               netdev->dev_addr[4] = *(p + 1);
-               netdev->dev_addr[5] = *(p + 0);
-
-               memcpy(netdev->perm_addr, netdev->dev_addr,
-                       netdev->addr_len);
-               if (!is_valid_ether_addr(netdev->perm_addr)) {
-                       printk(KERN_ERR "%s: Bad MAC address %s.\n",
-                                       netxen_nic_driver_name,
-                                       print_mac(mac, netdev->dev_addr));
-               } else {
-                       adapter->macaddr_set(adapter, netdev->dev_addr);
-               }
-       }
+       err = netxen_read_mac_addr(adapter);
+       if (err)
+               dev_warn(&pdev->dev, "failed to read mac addr\n");
 
        netif_carrier_off(netdev);
        netif_stop_queue(netdev);
@@ -1000,6 +965,7 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev)
 
        if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC) {
                netxen_free_hw_resources(adapter);
+               netxen_release_rx_buffers(adapter);
                netxen_free_sw_resources(adapter);
        }
 
@@ -1069,6 +1035,15 @@ static int netxen_nic_open(struct net_device *netdev)
                        goto err_out_free_sw;
                }
 
+               if ((adapter->msi_mode != MSI_MODE_MULTIFUNC) ||
+                       (adapter->intr_scheme != INTR_SCHEME_PERPORT)) {
+                       printk(KERN_ERR "%s: Firmware interrupt scheme is "
+                                       "incompatible with driver\n",
+                                       netdev->name);
+                       adapter->driver_mismatch = 1;
+                       goto err_out_free_hw;
+               }
+
                if (adapter->fw_major < 4) {
                        adapter->crb_addr_cmd_producer =
                                crb_cmd_producer[adapter->portnum];
@@ -1094,7 +1069,7 @@ static int netxen_nic_open(struct net_device *netdev)
                                  flags, netdev->name, adapter);
                if (err) {
                        printk(KERN_ERR "request_irq failed with: %d\n", err);
-                       goto err_out_free_hw;
+                       goto err_out_free_rxbuf;
                }
 
                adapter->is_up = NETXEN_ADAPTER_UP_MAGIC;
@@ -1116,6 +1091,7 @@ static int netxen_nic_open(struct net_device *netdev)
        if (adapter->set_mtu)
                adapter->set_mtu(adapter, netdev->mtu);
 
+       adapter->ahw.linkup = 0;
        mod_timer(&adapter->watchdog_timer, jiffies);
 
        napi_enable(&adapter->napi);
@@ -1127,6 +1103,8 @@ static int netxen_nic_open(struct net_device *netdev)
 
 err_out_free_irq:
        free_irq(adapter->irq, adapter);
+err_out_free_rxbuf:
+       netxen_release_rx_buffers(adapter);
 err_out_free_hw:
        netxen_free_hw_resources(adapter);
 err_out_free_sw:
@@ -1152,10 +1130,8 @@ static int netxen_nic_close(struct net_device *netdev)
 
        netxen_release_tx_buffers(adapter);
 
-       if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC) {
-               FLUSH_SCHEDULED_WORK();
-               del_timer_sync(&adapter->watchdog_timer);
-       }
+       FLUSH_SCHEDULED_WORK();
+       del_timer_sync(&adapter->watchdog_timer);
 
        return 0;
 }
@@ -1458,7 +1434,8 @@ void netxen_watchdog_task(struct work_struct *work)
 
        netxen_nic_handle_phy_intr(adapter);
 
-       mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ);
+       if (netif_running(adapter->netdev))
+               mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ);
 }
 
 static void netxen_tx_timeout(struct net_device *netdev)
@@ -1518,18 +1495,9 @@ struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev)
        return stats;
 }
 
-static inline void
-netxen_handle_int(struct netxen_adapter *adapter)
-{
-       netxen_nic_disable_int(adapter);
-       napi_schedule(&adapter->napi);
-}
-
 static irqreturn_t netxen_intr(int irq, void *data)
 {
        struct netxen_adapter *adapter = data;
-       u32 our_int = 0;
-
        u32 status = 0;
 
        status = adapter->pci_read_immediate(adapter, ISR_INT_VECTOR);
@@ -1544,22 +1512,32 @@ static irqreturn_t netxen_intr(int irq, void *data)
                if (!ISR_LEGACY_INT_TRIGGERED(status))
                        return IRQ_NONE;
 
-       } else if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
+       } else {
+               unsigned long our_int = 0;
 
                our_int = adapter->pci_read_normalize(adapter, CRB_INT_VECTOR);
+
                /* not our interrupt */
-               if ((our_int & (0x80 << adapter->portnum)) == 0)
+               if (!test_and_clear_bit((7 + adapter->portnum), &our_int))
                        return IRQ_NONE;
 
-               if (adapter->intr_scheme == INTR_SCHEME_PERPORT) {
-                       /* claim interrupt */
-                       adapter->pci_write_normalize(adapter,
-                               CRB_INT_VECTOR,
-                               our_int & ~((u32)(0x80 << adapter->portnum)));
-               }
+               /* claim interrupt */
+               adapter->pci_write_normalize(adapter,
+                               CRB_INT_VECTOR, (our_int & 0xffffffff));
        }
 
-       netxen_handle_int(adapter);
+       /* clear interrupt */
+       if (adapter->fw_major < 4)
+               netxen_nic_disable_int(adapter);
+
+       adapter->pci_write_immediate(adapter,
+                       adapter->legacy_intr.tgt_status_reg,
+                       0xffffffff);
+       /* read twice to ensure write is flushed */
+       adapter->pci_read_immediate(adapter, ISR_INT_VECTOR);
+       adapter->pci_read_immediate(adapter, ISR_INT_VECTOR);
+
+       napi_schedule(&adapter->napi);
 
        return IRQ_HANDLED;
 }
@@ -1568,7 +1546,11 @@ static irqreturn_t netxen_msi_intr(int irq, void *data)
 {
        struct netxen_adapter *adapter = data;
 
-       netxen_handle_int(adapter);
+       /* clear interrupt */
+       adapter->pci_write_immediate(adapter,
+                       msi_tgt_status[adapter->ahw.pci_func], 0xffffffff);
+
+       napi_schedule(&adapter->napi);
        return IRQ_HANDLED;
 }
 
index 83e5ee57bfef9ae5298285b8a548590ec88a4141..b293adcc95ab192481e0ec731f98c8d32b5452f2 100644 (file)
 #define CRB_SW_INT_MASK_2         NETXEN_NIC_REG(0x1e4)
 #define CRB_SW_INT_MASK_3         NETXEN_NIC_REG(0x1e8)
 
+#define CRB_MAC_BLOCK_START        NETXEN_CAM_RAM(0x1c0)
+
 /*
  * capabilities register, can be used to selectively enable/disable features
  * for backward compability
index b35d79449500a50bafd8cbdb39f01130114e152a..88f03c9e9403a208e9d3a5af54738cdbeed862d3 100644 (file)
@@ -46,7 +46,6 @@
 #include <linux/err.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
-#include <linux/version.h>
 #include <linux/init.h>
 #include <linux/types.h>
 #include <linux/slab.h>
index f9298827a76caa07f8508d4179b9b312cf13fb72..ff175e8f36b274ad58902dc03eb2222cd9c43afa 100644 (file)
@@ -61,7 +61,6 @@
  */
 
 #include <linux/module.h>
-#include <linux/version.h>
 #include <linux/string.h>
 #include <linux/list.h>
 #include <asm/uaccess.h>
index 6531ff565c545bd02841fc2d15942f3e4896d65f..5d86281d9363df82406cdadd609dbb019cfd55d3 100644 (file)
@@ -24,7 +24,6 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/version.h>
 #include <linux/moduleparam.h>
 #include <linux/string.h>
 #include <linux/timer.h>
index 25e62cf58d3ac98e3cab012b1999f9b7a8711dfd..1c370e6aa641d571467c4b4727e009bd8a01fd1c 100644 (file)
@@ -20,7 +20,6 @@
  *  the file called "COPYING".
  */
 
-#include <linux/version.h>
 #include <linux/init.h>
 #include <linux/dma-mapping.h>
 #include <linux/etherdevice.h>
index 7d29edcd40b4f111af185b07bac9ffd2fc77fbe0..e24b25ca1c690e0d78df1feb29e2277f9347a3af 100644 (file)
@@ -24,7 +24,6 @@
 
 #include <linux/crc32.h>
 #include <linux/kernel.h>
-#include <linux/version.h>
 #include <linux/module.h>
 #include <linux/netdevice.h>
 #include <linux/dma-mapping.h>
@@ -666,11 +665,16 @@ static void sky2_phy_power_down(struct sky2_hw *hw, unsigned port)
 
        if (hw->chip_id != CHIP_ID_YUKON_EC) {
                if (hw->chip_id == CHIP_ID_YUKON_EC_U) {
-                       ctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL);
+                       /* select page 2 to access MAC control register */
+                       gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 2);
 
+                       ctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL);
                        /* enable Power Down */
                        ctrl |= PHY_M_PC_POW_D_ENA;
                        gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ctrl);
+
+                       /* set page register back to 0 */
+                       gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 0);
                }
 
                /* set IEEE compatible Power Down Mode (dev. #4.99) */
index c66dfc9ec1ec691cd32e9013b651dde7074ffef0..7db48f1cd9498873be69a70a0cd7fa3ac4aada10 100644 (file)
@@ -27,7 +27,6 @@
 #include <linux/sched.h>
 #include <linux/tty.h>
 #include <linux/if_vlan.h>
-#include <linux/version.h>
 #include <linux/interrupt.h>
 #include <linux/vmalloc.h>
 #include <asm/byteorder.h>
index d2439b85a79011d3582991a7fa5cf5902bc675e8..71d2c5cfdad9b9a2c2f98163446abecfdbb6e447 100644 (file)
@@ -66,8 +66,8 @@
 
 #define DRV_MODULE_NAME                "tg3"
 #define PFX DRV_MODULE_NAME    ": "
-#define DRV_MODULE_VERSION     "3.93"
-#define DRV_MODULE_RELDATE     "May 22, 2008"
+#define DRV_MODULE_VERSION     "3.94"
+#define DRV_MODULE_RELDATE     "August 14, 2008"
 
 #define TG3_DEF_MAC_MODE       0
 #define TG3_DEF_RX_MODE                0
@@ -536,6 +536,7 @@ static int tg3_ape_lock(struct tg3 *tp, int locknum)
                return 0;
 
        switch (locknum) {
+               case TG3_APE_LOCK_GRC:
                case TG3_APE_LOCK_MEM:
                        break;
                default:
@@ -573,6 +574,7 @@ static void tg3_ape_unlock(struct tg3 *tp, int locknum)
                return;
 
        switch (locknum) {
+               case TG3_APE_LOCK_GRC:
                case TG3_APE_LOCK_MEM:
                        break;
                default:
@@ -1017,16 +1019,44 @@ static void tg3_mdio_fini(struct tg3 *tp)
        }
 }
 
+/* tp->lock is held. */
+static inline void tg3_generate_fw_event(struct tg3 *tp)
+{
+       u32 val;
+
+       val = tr32(GRC_RX_CPU_EVENT);
+       val |= GRC_RX_CPU_DRIVER_EVENT;
+       tw32_f(GRC_RX_CPU_EVENT, val);
+
+       tp->last_event_jiffies = jiffies;
+}
+
+#define TG3_FW_EVENT_TIMEOUT_USEC 2500
+
 /* tp->lock is held. */
 static void tg3_wait_for_event_ack(struct tg3 *tp)
 {
        int i;
+       unsigned int delay_cnt;
+       long time_remain;
+
+       /* If enough time has passed, no wait is necessary. */
+       time_remain = (long)(tp->last_event_jiffies + 1 +
+                     usecs_to_jiffies(TG3_FW_EVENT_TIMEOUT_USEC)) -
+                     (long)jiffies;
+       if (time_remain < 0)
+               return;
 
-       /* Wait for up to 2.5 milliseconds */
-       for (i = 0; i < 250000; i++) {
+       /* Check if we can shorten the wait time. */
+       delay_cnt = jiffies_to_usecs(time_remain);
+       if (delay_cnt > TG3_FW_EVENT_TIMEOUT_USEC)
+               delay_cnt = TG3_FW_EVENT_TIMEOUT_USEC;
+       delay_cnt = (delay_cnt >> 3) + 1;
+
+       for (i = 0; i < delay_cnt; i++) {
                if (!(tr32(GRC_RX_CPU_EVENT) & GRC_RX_CPU_DRIVER_EVENT))
                        break;
-               udelay(10);
+               udelay(8);
        }
 }
 
@@ -1075,9 +1105,7 @@ static void tg3_ump_link_report(struct tg3 *tp)
                val = 0;
        tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX + 12, val);
 
-       val = tr32(GRC_RX_CPU_EVENT);
-       val |= GRC_RX_CPU_DRIVER_EVENT;
-       tw32_f(GRC_RX_CPU_EVENT, val);
+       tg3_generate_fw_event(tp);
 }
 
 static void tg3_link_report(struct tg3 *tp)
@@ -2124,6 +2152,13 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state)
                     (tp->tg3_flags & TG3_FLAG_WOL_ENABLE))
                        mac_mode |= MAC_MODE_MAGIC_PKT_ENABLE;
 
+               if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE) {
+                       mac_mode |= tp->mac_mode &
+                                   (MAC_MODE_APE_TX_EN | MAC_MODE_APE_RX_EN);
+                       if (mac_mode & MAC_MODE_APE_TX_EN)
+                               mac_mode |= MAC_MODE_TDE_ENABLE;
+               }
+
                tw32_f(MAC_MODE, mac_mode);
                udelay(100);
 
@@ -5493,7 +5528,7 @@ static void tg3_ape_send_event(struct tg3 *tp, u32 event)
                return;
 
        apedata = tg3_ape_read32(tp, TG3_APE_FW_STATUS);
-       if (apedata != APE_FW_STATUS_READY)
+       if (!(apedata & APE_FW_STATUS_READY))
                return;
 
        /* Wait for up to 1 millisecond for APE to service previous event. */
@@ -5760,6 +5795,8 @@ static int tg3_chip_reset(struct tg3 *tp)
 
        tg3_mdio_stop(tp);
 
+       tg3_ape_lock(tp, TG3_APE_LOCK_GRC);
+
        /* No matching tg3_nvram_unlock() after this because
         * chip reset below will undo the nvram lock.
         */
@@ -5908,12 +5945,19 @@ static int tg3_chip_reset(struct tg3 *tp)
        } else if (tp->tg3_flags2 & TG3_FLG2_MII_SERDES) {
                tp->mac_mode = MAC_MODE_PORT_MODE_GMII;
                tw32_f(MAC_MODE, tp->mac_mode);
+       } else if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE) {
+               tp->mac_mode &= (MAC_MODE_APE_TX_EN | MAC_MODE_APE_RX_EN);
+               if (tp->mac_mode & MAC_MODE_APE_TX_EN)
+                       tp->mac_mode |= MAC_MODE_TDE_ENABLE;
+               tw32_f(MAC_MODE, tp->mac_mode);
        } else
                tw32_f(MAC_MODE, 0);
        udelay(40);
 
        tg3_mdio_start(tp);
 
+       tg3_ape_unlock(tp, TG3_APE_LOCK_GRC);
+
        err = tg3_poll_fw(tp);
        if (err)
                return err;
@@ -5935,6 +5979,7 @@ static int tg3_chip_reset(struct tg3 *tp)
                tg3_read_mem(tp, NIC_SRAM_DATA_CFG, &nic_cfg);
                if (nic_cfg & NIC_SRAM_DATA_CFG_ASF_ENABLE) {
                        tp->tg3_flags |= TG3_FLAG_ENABLE_ASF;
+                       tp->last_event_jiffies = jiffies;
                        if (tp->tg3_flags2 & TG3_FLG2_5750_PLUS)
                                tp->tg3_flags2 |= TG3_FLG2_ASF_NEW_HANDSHAKE;
                }
@@ -5948,15 +5993,12 @@ static void tg3_stop_fw(struct tg3 *tp)
 {
        if ((tp->tg3_flags & TG3_FLAG_ENABLE_ASF) &&
           !(tp->tg3_flags3 & TG3_FLG3_ENABLE_APE)) {
-               u32 val;
-
                /* Wait for RX cpu to ACK the previous event. */
                tg3_wait_for_event_ack(tp);
 
                tg3_write_mem(tp, NIC_SRAM_FW_CMD_MBOX, FWCMD_NICDRV_PAUSE_FW);
-               val = tr32(GRC_RX_CPU_EVENT);
-               val |= GRC_RX_CPU_DRIVER_EVENT;
-               tw32(GRC_RX_CPU_EVENT, val);
+
+               tg3_generate_fw_event(tp);
 
                /* Wait for RX cpu to ACK this event. */
                tg3_wait_for_event_ack(tp);
@@ -7406,7 +7448,11 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
                udelay(10);
        }
 
-       tp->mac_mode = MAC_MODE_TXSTAT_ENABLE | MAC_MODE_RXSTAT_ENABLE |
+       if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE)
+               tp->mac_mode &= MAC_MODE_APE_TX_EN | MAC_MODE_APE_RX_EN;
+       else
+               tp->mac_mode = 0;
+       tp->mac_mode |= MAC_MODE_TXSTAT_ENABLE | MAC_MODE_RXSTAT_ENABLE |
                MAC_MODE_TDE_ENABLE | MAC_MODE_RDE_ENABLE | MAC_MODE_FHDE_ENABLE;
        if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS) &&
            !(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) &&
@@ -7840,9 +7886,8 @@ static void tg3_timer(unsigned long __opaque)
         * resets.
         */
        if (!--tp->asf_counter) {
-               if (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) {
-                       u32 val;
-
+               if ((tp->tg3_flags & TG3_FLAG_ENABLE_ASF) &&
+                   !(tp->tg3_flags3 & TG3_FLG3_ENABLE_APE)) {
                        tg3_wait_for_event_ack(tp);
 
                        tg3_write_mem(tp, NIC_SRAM_FW_CMD_MBOX,
@@ -7850,9 +7895,8 @@ static void tg3_timer(unsigned long __opaque)
                        tg3_write_mem(tp, NIC_SRAM_FW_CMD_LEN_MBOX, 4);
                        /* 5 seconds timeout */
                        tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX, 5);
-                       val = tr32(GRC_RX_CPU_EVENT);
-                       val |= GRC_RX_CPU_DRIVER_EVENT;
-                       tw32_f(GRC_RX_CPU_EVENT, val);
+
+                       tg3_generate_fw_event(tp);
                }
                tp->asf_counter = tp->asf_multiplier;
        }
@@ -8422,6 +8466,11 @@ static inline unsigned long get_stat64(tg3_stat64_t *val)
        return ret;
 }
 
+static inline u64 get_estat64(tg3_stat64_t *val)
+{
+       return ((u64)val->high << 32) | ((u64)val->low);
+}
+
 static unsigned long calc_crc_errors(struct tg3 *tp)
 {
        struct tg3_hw_stats *hw_stats = tp->hw_stats;
@@ -8450,7 +8499,7 @@ static unsigned long calc_crc_errors(struct tg3 *tp)
 
 #define ESTAT_ADD(member) \
        estats->member =        old_estats->member + \
-                               get_stat64(&hw_stats->member)
+                               get_estat64(&hw_stats->member)
 
 static struct tg3_ethtool_stats *tg3_get_estats(struct tg3 *tp)
 {
@@ -12416,6 +12465,13 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
                                       tp->misc_host_ctrl);
        }
 
+       /* Preserve the APE MAC_MODE bits */
+       if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE)
+               tp->mac_mode = tr32(MAC_MODE) |
+                              MAC_MODE_APE_TX_EN | MAC_MODE_APE_RX_EN;
+       else
+               tp->mac_mode = TG3_DEF_MAC_MODE;
+
        /* these are limited to 10/100 only */
        if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703 &&
             (grc_misc_cfg == 0x8000 || grc_misc_cfg == 0x4000)) ||
@@ -13275,7 +13331,6 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
        tp->pdev = pdev;
        tp->dev = dev;
        tp->pm_cap = pm_cap;
-       tp->mac_mode = TG3_DEF_MAC_MODE;
        tp->rx_mode = TG3_DEF_RX_MODE;
        tp->tx_mode = TG3_DEF_TX_MODE;
 
index df07842172b7dff8c479d9795bc39afb6c87f5a6..f5b8cab8d4b5c2d4f227be04c87ef60e2f7b70cb 100644 (file)
 #define  MAC_MODE_TDE_ENABLE            0x00200000
 #define  MAC_MODE_RDE_ENABLE            0x00400000
 #define  MAC_MODE_FHDE_ENABLE           0x00800000
+#define  MAC_MODE_APE_RX_EN             0x08000000
+#define  MAC_MODE_APE_TX_EN             0x10000000
 #define MAC_STATUS                     0x00000404
 #define  MAC_STATUS_PCS_SYNCED          0x00000001
 #define  MAC_STATUS_SIGNAL_DET          0x00000002
 #define  APE_EVENT_STATUS_EVENT_PENDING         0x80000000
 
 /* APE convenience enumerations. */
+#define TG3_APE_LOCK_GRC                1
 #define TG3_APE_LOCK_MEM                4
 
 #define TG3_EEPROM_SB_F1R2_MBA_OFF     0x10
@@ -2429,7 +2432,10 @@ struct tg3 {
        struct tg3_ethtool_stats        estats;
        struct tg3_ethtool_stats        estats_prev;
 
+       union {
        unsigned long                   phy_crc_errors;
+       unsigned long                   last_event_jiffies;
+       };
 
        u32                             rx_offset;
        u32                             tg3_flags;
index 85246ed7cb9c4059307ab5807a2178c0e031f515..ec871f646766dc7294101fe5ad7f789b66d3f0bb 100644 (file)
@@ -360,8 +360,8 @@ TLan_GetSKB( const struct tlan_list_tag *tag)
 {
        unsigned long addr;
 
-       addr = tag->buffer[8].address;
-       addr |= (tag->buffer[9].address << 16) << 16;
+       addr = tag->buffer[9].address;
+       addr |= (tag->buffer[8].address << 16) << 16;
        return (struct sk_buff *) addr;
 }
 
@@ -1984,7 +1984,6 @@ static void TLan_ResetLists( struct net_device *dev )
        TLanList        *list;
        dma_addr_t      list_phys;
        struct sk_buff  *skb;
-       void            *t = NULL;
 
        priv->txHead = 0;
        priv->txTail = 0;
@@ -2022,7 +2021,8 @@ static void TLan_ResetLists( struct net_device *dev )
                        }
 
                        skb_reserve( skb, NET_IP_ALIGN );
-                       list->buffer[0].address = pci_map_single(priv->pciDev, t,
+                       list->buffer[0].address = pci_map_single(priv->pciDev,
+                                                                skb->data,
                                                                 TLAN_MAX_FRAME_SIZE,
                                                                 PCI_DMA_FROMDEVICE);
                        TLan_StoreSKB(list, skb);
index 47d84cd2809770b3996a3a0fa65dd6f8eb39c3c0..59d1673f9387febe69304c48e1c6a17a6e19e538 100644 (file)
 #include <linux/pci.h>
 #include <linux/dma-mapping.h>
 #include <linux/spinlock.h>
-#include <linux/version.h>
 #include <linux/bitops.h>
 #include <linux/jiffies.h>
 
index e7bb3494afc74609e53413a97c517d4bd9d37f7d..13ccee6449c1314a08db9e1863f2f0619fadf9c8 100644 (file)
@@ -60,8 +60,6 @@
  *
  */
 
-#include <linux/version.h>
-
 /* MAX_INTR - the maximum number of times we can loop
  * inside the interrupt function before returning
  * control to the OS (maximum value is 256)
index e6bbc639c2d0c8428cc28e29692760f549bf50ce..6daea0c91862ecddc2110712c8e62381e1e9639c 100644 (file)
@@ -358,6 +358,66 @@ static unsigned int tun_chr_poll(struct file *file, poll_table * wait)
        return mask;
 }
 
+/* prepad is the amount to reserve at front.  len is length after that.
+ * linear is a hint as to how much to copy (usually headers). */
+static struct sk_buff *tun_alloc_skb(size_t prepad, size_t len, size_t linear,
+                                    gfp_t gfp)
+{
+       struct sk_buff *skb;
+       unsigned int i;
+
+       skb = alloc_skb(prepad + len, gfp|__GFP_NOWARN);
+       if (skb) {
+               skb_reserve(skb, prepad);
+               skb_put(skb, len);
+               return skb;
+       }
+
+       /* Under a page?  Don't bother with paged skb. */
+       if (prepad + len < PAGE_SIZE)
+               return NULL;
+
+       /* Start with a normal skb, and add pages. */
+       skb = alloc_skb(prepad + linear, gfp);
+       if (!skb)
+               return NULL;
+
+       skb_reserve(skb, prepad);
+       skb_put(skb, linear);
+
+       len -= linear;
+
+       for (i = 0; i < MAX_SKB_FRAGS; i++) {
+               skb_frag_t *f = &skb_shinfo(skb)->frags[i];
+
+               f->page = alloc_page(gfp|__GFP_ZERO);
+               if (!f->page)
+                       break;
+
+               f->page_offset = 0;
+               f->size = PAGE_SIZE;
+
+               skb->data_len += PAGE_SIZE;
+               skb->len += PAGE_SIZE;
+               skb->truesize += PAGE_SIZE;
+               skb_shinfo(skb)->nr_frags++;
+
+               if (len < PAGE_SIZE) {
+                       len = 0;
+                       break;
+               }
+               len -= PAGE_SIZE;
+       }
+
+       /* Too large, or alloc fail? */
+       if (unlikely(len)) {
+               kfree_skb(skb);
+               skb = NULL;
+       }
+
+       return skb;
+}
+
 /* Get packet from user space buffer */
 static __inline__ ssize_t tun_get_user(struct tun_struct *tun, struct iovec *iv, size_t count)
 {
@@ -391,14 +451,12 @@ static __inline__ ssize_t tun_get_user(struct tun_struct *tun, struct iovec *iv,
                        return -EINVAL;
        }
 
-       if (!(skb = alloc_skb(len + align, GFP_KERNEL))) {
+       if (!(skb = tun_alloc_skb(align, len, gso.hdr_len, GFP_KERNEL))) {
                tun->dev->stats.rx_dropped++;
                return -ENOMEM;
        }
 
-       if (align)
-               skb_reserve(skb, align);
-       if (memcpy_fromiovec(skb_put(skb, len), iv, len)) {
+       if (skb_copy_datagram_from_iovec(skb, 0, iv, len)) {
                tun->dev->stats.rx_dropped++;
                kfree_skb(skb);
                return -EFAULT;
@@ -748,6 +806,36 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
        return err;
 }
 
+static int tun_get_iff(struct net *net, struct file *file, struct ifreq *ifr)
+{
+       struct tun_struct *tun = file->private_data;
+
+       if (!tun)
+               return -EBADFD;
+
+       DBG(KERN_INFO "%s: tun_get_iff\n", tun->dev->name);
+
+       strcpy(ifr->ifr_name, tun->dev->name);
+
+       ifr->ifr_flags = 0;
+
+       if (ifr->ifr_flags & TUN_TUN_DEV)
+               ifr->ifr_flags |= IFF_TUN;
+       else
+               ifr->ifr_flags |= IFF_TAP;
+
+       if (tun->flags & TUN_NO_PI)
+               ifr->ifr_flags |= IFF_NO_PI;
+
+       if (tun->flags & TUN_ONE_QUEUE)
+               ifr->ifr_flags |= IFF_ONE_QUEUE;
+
+       if (tun->flags & TUN_VNET_HDR)
+               ifr->ifr_flags |= IFF_VNET_HDR;
+
+       return 0;
+}
+
 /* This is like a cut-down ethtool ops, except done via tun fd so no
  * privs required. */
 static int set_offload(struct net_device *dev, unsigned long arg)
@@ -833,6 +921,15 @@ static int tun_chr_ioctl(struct inode *inode, struct file *file,
        DBG(KERN_INFO "%s: tun_chr_ioctl cmd %d\n", tun->dev->name, cmd);
 
        switch (cmd) {
+       case TUNGETIFF:
+               ret = tun_get_iff(current->nsproxy->net_ns, file, &ifr);
+               if (ret)
+                       return ret;
+
+               if (copy_to_user(argp, &ifr, sizeof(ifr)))
+                       return -EFAULT;
+               break;
+
        case TUNSETNOCSUM:
                /* Disable/Enable checksum */
                if (arg)
index 8549f1159a30cd55db8e78239bbe757c91c1acf8..734ce0977f02891e1c6d7a0ac0ba666e3f36ec49 100644 (file)
@@ -128,7 +128,6 @@ static const int multicast_filter_limit = 32;
 #include <asm/io.h>
 #include <asm/uaccess.h>
 #include <linux/in6.h>
-#include <linux/version.h>
 #include <linux/dma-mapping.h>
 
 #include "typhoon.h"
index 68e198bd538bcc98d47091152eb2d518fdc2eba9..0973b6e37024af5b25d7e391050a103d5104cd0f 100644 (file)
@@ -154,17 +154,6 @@ config USB_NET_AX8817X
          This driver creates an interface named "ethX", where X depends on
          what other networking devices you have in use.
 
-config USB_HSO
-       tristate "Option USB High Speed Mobile Devices"
-       depends on USB && RFKILL
-       default n
-       help
-         Choose this option if you have an Option HSDPA/HSUPA card.
-         These cards support downlink speeds of 7.2Mbps or greater.
-
-         To compile this driver as a module, choose M here: the
-         module will be called hso.
-
 config USB_NET_CDCETHER
        tristate "CDC Ethernet support (smart devices such as cable modems)"
        depends on USB_USBNET
@@ -337,5 +326,15 @@ config USB_NET_ZAURUS
          really need this non-conformant variant of CDC Ethernet (or in
          some cases CDC MDLM) protocol, not "g_ether".
 
+config USB_HSO
+       tristate "Option USB High Speed Mobile Devices"
+       depends on USB && RFKILL
+       default n
+       help
+         Choose this option if you have an Option HSDPA/HSUPA card.
+         These cards support downlink speeds of 7.2Mbps or greater.
+
+         To compile this driver as a module, choose M here: the
+         module will be called hso.
 
 endmenu
index 031d07b105af1f3f9716d083d8edba60a971e1de..1b7cac77159ea62249c4fe49de32bc62148b3d98 100644 (file)
 
 #define MAX_RX_URBS                    2
 
-#define get_serial_by_tty(x)   \
-       (x ? (struct hso_serial *)x->driver_data : NULL)
+static inline struct hso_serial *get_serial_by_tty(struct tty_struct *tty)
+{
+       if (tty)
+               return tty->driver_data;
+       return NULL;
+}
 
 /*****************************************************************************/
 /* Debugging functions                                                       */
@@ -294,24 +298,25 @@ static int hso_get_activity(struct hso_device *hso_dev);
 
 /* #define DEBUG */
 
-#define dev2net(x) (x->port_data.dev_net)
-#define dev2ser(x) (x->port_data.dev_serial)
+static inline struct hso_net *dev2net(struct hso_device *hso_dev)
+{
+       return hso_dev->port_data.dev_net;
+}
+
+static inline struct hso_serial *dev2ser(struct hso_device *hso_dev)
+{
+       return hso_dev->port_data.dev_serial;
+}
 
 /* Debugging functions */
 #ifdef DEBUG
 static void dbg_dump(int line_count, const char *func_name, unsigned char *buf,
                     unsigned int len)
 {
-       u8 i = 0;
+       static char name[255];
 
-       printk(KERN_DEBUG "[%d:%s]: len %d", line_count, func_name, len);
-
-       for (i = 0; i < len; i++) {
-               if (!(i % 16))
-                       printk("\n    0x%03x:  ", i);
-               printk("%02x ", (unsigned char)buf[i]);
-       }
-       printk("\n");
+       sprintf(name, "hso[%d:%s]", line_count, func_name);
+       print_hex_dump_bytes(name, DUMP_PREFIX_NONE, buf, len);
 }
 
 #define DUMP(buf_, len_)       \
@@ -528,13 +533,12 @@ static struct hso_serial *get_serial_by_shared_int_and_type(
 
 static struct hso_serial *get_serial_by_index(unsigned index)
 {
-       struct hso_serial *serial;
+       struct hso_serial *serial = NULL;
        unsigned long flags;
 
-       if (!serial_table[index])
-               return NULL;
        spin_lock_irqsave(&serial_table_lock, flags);
-       serial = dev2ser(serial_table[index]);
+       if (serial_table[index])
+               serial = dev2ser(serial_table[index]);
        spin_unlock_irqrestore(&serial_table_lock, flags);
 
        return serial;
@@ -561,6 +565,7 @@ static int get_free_serial_index(void)
 static void set_serial_by_index(unsigned index, struct hso_serial *serial)
 {
        unsigned long flags;
+
        spin_lock_irqsave(&serial_table_lock, flags);
        if (serial)
                serial_table[index] = serial->parent;
@@ -569,7 +574,7 @@ static void set_serial_by_index(unsigned index, struct hso_serial *serial)
        spin_unlock_irqrestore(&serial_table_lock, flags);
 }
 
-/* log a meaningfull explanation of an USB status */
+/* log a meaningful explanation of an USB status */
 static void log_usb_status(int status, const char *function)
 {
        char *explanation;
@@ -1103,8 +1108,8 @@ static void hso_serial_close(struct tty_struct *tty, struct file *filp)
        /* reset the rts and dtr */
        /* do the actual close */
        serial->open_count--;
+       kref_put(&serial->parent->ref, hso_serial_ref_free);
        if (serial->open_count <= 0) {
-               kref_put(&serial->parent->ref, hso_serial_ref_free);
                serial->open_count = 0;
                if (serial->tty) {
                        serial->tty->driver_data = NULL;
@@ -1467,7 +1472,8 @@ static void hso_std_serial_write_bulk_callback(struct urb *urb)
                return;
        }
        hso_put_activity(serial->parent);
-       tty_wakeup(serial->tty);
+       if (serial->tty)
+               tty_wakeup(serial->tty);
        hso_kick_transmit(serial);
 
        D1(" ");
@@ -1538,7 +1544,8 @@ static void ctrl_callback(struct urb *urb)
                        clear_bit(HSO_SERIAL_FLAG_RX_SENT, &serial->flags);
        } else {
                hso_put_activity(serial->parent);
-               tty_wakeup(serial->tty);
+               if (serial->tty)
+                       tty_wakeup(serial->tty);
                /* response to a write command */
                hso_kick_transmit(serial);
        }
@@ -2652,7 +2659,7 @@ static void hso_free_interface(struct usb_interface *interface)
                        hso_stop_net_device(network_table[i]);
                        cancel_work_sync(&network_table[i]->async_put_intf);
                        cancel_work_sync(&network_table[i]->async_get_intf);
-                       if(rfk)
+                       if (rfk)
                                rfkill_unregister(rfk);
                        hso_free_net_device(network_table[i]);
                }
@@ -2723,7 +2730,7 @@ static int hso_mux_submit_intr_urb(struct hso_shared_int *shared_int,
 }
 
 /* operations setup of the serial interface */
-static struct tty_operations hso_serial_ops = {
+static const struct tty_operations hso_serial_ops = {
        .open = hso_serial_open,
        .close = hso_serial_close,
        .write = hso_serial_write,
index 2028866f59951068ebb799ee3209ef22d9ff13c6..b20a45aa8680ec1b0fb0501142fedb4ba3c7978c 100644 (file)
@@ -40,7 +40,6 @@
  *
  */
 
-#include <linux/version.h>
 #include <linux/module.h>
 #include <linux/delay.h>
 #include <linux/hardirq.h>
@@ -587,7 +586,6 @@ ath5k_pci_suspend(struct pci_dev *pdev, pm_message_t state)
        ath5k_stop_hw(sc);
 
        free_irq(pdev->irq, sc);
-       pci_disable_msi(pdev);
        pci_save_state(pdev);
        pci_disable_device(pdev);
        pci_set_power_state(pdev, PCI_D3hot);
@@ -616,12 +614,10 @@ ath5k_pci_resume(struct pci_dev *pdev)
         */
        pci_write_config_byte(pdev, 0x41, 0);
 
-       pci_enable_msi(pdev);
-
        err = request_irq(pdev->irq, ath5k_intr, IRQF_SHARED, "ath", sc);
        if (err) {
                ATH5K_ERR(sc, "request_irq failed\n");
-               goto err_msi;
+               goto err_no_irq;
        }
 
        err = ath5k_init(sc);
@@ -642,8 +638,7 @@ ath5k_pci_resume(struct pci_dev *pdev)
        return 0;
 err_irq:
        free_irq(pdev->irq, sc);
-err_msi:
-       pci_disable_msi(pdev);
+err_no_irq:
        pci_disable_device(pdev);
        return err;
 }
index bde162f128aba6c70100c1dbd8d1c979061e0411..a17eb130f57431e104a9141596037cfe9ef7e31e 100644 (file)
@@ -5017,7 +5017,11 @@ static void ath9k_hw_spur_mitigate(struct ath_hal *ah,
 
        for (i = 0; i < 123; i++) {
                if ((cur_vit_mask > lower) && (cur_vit_mask < upper)) {
-                       if ((abs(cur_vit_mask - bin)) < 75)
+
+                       /* workaround for gcc bug #37014 */
+                       volatile int tmp = abs(cur_vit_mask - bin);
+
+                       if (tmp < 75)
                                mask_amt = 1;
                        else
                                mask_amt = 0;
index 3bf3a869361f13fec7ff1b4a48bdd5ae9ddc363b..7205a936ec74708085576ef5b538528b0a747d15 100644 (file)
@@ -33,7 +33,6 @@
 #include <linux/moduleparam.h>
 #include <linux/if_arp.h>
 #include <linux/etherdevice.h>
-#include <linux/version.h>
 #include <linux/firmware.h>
 #include <linux/wireless.h>
 #include <linux/workqueue.h>
@@ -4615,7 +4614,9 @@ static void b43_sprom_fixup(struct ssb_bus *bus)
        if (bus->bustype == SSB_BUSTYPE_PCI) {
                pdev = bus->host_pci;
                if (IS_PDEV(pdev, BROADCOM, 0x4318, ASUSTEK, 0x100F) ||
+                   IS_PDEV(pdev, BROADCOM, 0x4320,    DELL, 0x0003) ||
                    IS_PDEV(pdev, BROADCOM, 0x4320, LINKSYS, 0x0015) ||
+                   IS_PDEV(pdev, BROADCOM, 0x4320, LINKSYS, 0x0014) ||
                    IS_PDEV(pdev, BROADCOM, 0x4320, LINKSYS, 0x0013))
                        bus->sprom.boardflags_lo &= ~B43_BFL_BTCOEXIST;
        }
index 2541c81932f058cd3eb960ddef99d0a53621f8c0..1cb77db5c29265d55d059b398f0c3dcb04c3b47a 100644 (file)
@@ -34,7 +34,6 @@
 #include <linux/moduleparam.h>
 #include <linux/if_arp.h>
 #include <linux/etherdevice.h>
-#include <linux/version.h>
 #include <linux/firmware.h>
 #include <linux/wireless.h>
 #include <linux/workqueue.h>
index c6f886ec08a395893772d50bf6d3e1c241109bb2..19a401c4a0dcd507f23d89db9100bcb2415385d4 100644 (file)
@@ -157,7 +157,6 @@ that only one external action is invoked at a time.
 #include <linux/stringify.h>
 #include <linux/tcp.h>
 #include <linux/types.h>
-#include <linux/version.h>
 #include <linux/time.h>
 #include <linux/firmware.h>
 #include <linux/acpi.h>
index 36e8d2f6e7b4d2b3ba712fb066685d4917446913..dcce3542d5a771d9eb24753d8d464854bb4e6639 100644 (file)
@@ -31,7 +31,6 @@
 ******************************************************************************/
 
 #include "ipw2200.h"
-#include <linux/version.h>
 
 
 #ifndef KBUILD_EXTMOD
index d3336966b6b5169cc776f729bc06b73459c8f4ff..705c65bed9fd7a719c22b355e8ad6fe7c8eee07c 100644 (file)
@@ -27,7 +27,6 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/version.h>
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/dma-mapping.h>
index b3931f6135a4002aed0cd3d0f1a9007540a7f696..3f51f36353449bdf0eaa8afa6c2fc1ec2bb39665 100644 (file)
@@ -26,7 +26,6 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/version.h>
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/dma-mapping.h>
index 22bb26985c2e6a7ef4545ea6e6206ccdce47f8e7..e2581229d8b2b6e6ac68a58f5ae20d001475b50e 100644 (file)
@@ -26,7 +26,6 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/version.h>
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/dma-mapping.h>
@@ -967,7 +966,7 @@ static int iwl4965_interpolate_chan(struct iwl_priv *priv, u32 channel,
 
        s = iwl4965_get_sub_band(priv, channel);
        if (s >= EEPROM_TX_POWER_BANDS) {
-               IWL_ERROR("Tx Power can not find channel %d ", channel);
+               IWL_ERROR("Tx Power can not find channel %d\n", channel);
                return -1;
        }
 
index f3d139b663e651bab5759b7d12b2f2dd8e923a1e..cbc01a00eaf4416e42ea3b2261df33506fe52d14 100644 (file)
@@ -25,7 +25,6 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/version.h>
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/dma-mapping.h>
index ed09e48b1b61ade5d9fb4dde1fe9410be2d37c91..061ffba9c884c017c00970bc2a148fd3d6dc0602 100644 (file)
@@ -29,7 +29,6 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/version.h>
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/dma-mapping.h>
index 9bd61809129f800bfa7ca5ef3ff35482675e0a65..c72f72579beaeb2f70e2760a695f7b9268a533ab 100644 (file)
@@ -28,7 +28,6 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/version.h>
 #include <net/mac80211.h>
 
 struct iwl_priv; /* FIXME: remove */
index bce53830b301f8f32749facf5b85c1ad72561666..37155755efc596bb51d3dc395374bf40a533b086 100644 (file)
@@ -63,7 +63,6 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/version.h>
 #include <linux/init.h>
 
 #include <net/mac80211.h>
@@ -146,7 +145,7 @@ int iwlcore_eeprom_verify_signature(struct iwl_priv *priv)
 {
        u32 gp = iwl_read32(priv, CSR_EEPROM_GP);
        if ((gp & CSR_EEPROM_GP_VALID_MSK) == CSR_EEPROM_GP_BAD_SIGNATURE) {
-               IWL_ERROR("EEPROM not found, EEPROM_GP=0x%08x", gp);
+               IWL_ERROR("EEPROM not found, EEPROM_GP=0x%08x\n", gp);
                return -ENOENT;
        }
        return 0;
@@ -227,7 +226,7 @@ int iwl_eeprom_init(struct iwl_priv *priv)
 
        ret = priv->cfg->ops->lib->eeprom_ops.verify_signature(priv);
        if (ret < 0) {
-               IWL_ERROR("EEPROM not found, EEPROM_GP=0x%08x", gp);
+               IWL_ERROR("EEPROM not found, EEPROM_GP=0x%08x\n", gp);
                ret = -ENOENT;
                goto err;
        }
@@ -254,7 +253,7 @@ int iwl_eeprom_init(struct iwl_priv *priv)
                }
 
                if (!(r & CSR_EEPROM_REG_READ_VALID_MSK)) {
-                       IWL_ERROR("Time out reading EEPROM[%d]", addr);
+                       IWL_ERROR("Time out reading EEPROM[%d]\n", addr);
                        ret = -ETIMEDOUT;
                        goto done;
                }
index 6512834bb9162bf220a105ddfa1654cc540a577d..2eb03eea1908f166c24a86aee7d1d5303e5443bc 100644 (file)
@@ -28,7 +28,6 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/version.h>
 #include <net/mac80211.h>
 
 #include "iwl-dev.h" /* FIXME: remove */
index cb11c4a4d69152a0dd0f021a4ab7ceb16c9bc02a..4eee1b163cd2c27115fa46ce95cc9cc0193011dc 100644 (file)
@@ -27,7 +27,6 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/version.h>
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/dma-mapping.h>
index 028e3053c0ca423698b2390608521520e0dfc404..a099c9e30e55dcdfe0d933a3e64c4947719bd593 100644 (file)
@@ -29,7 +29,6 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/version.h>
 #include <linux/init.h>
 
 #include <net/mac80211.h>
index e5e5846e9f252f63f7fdbe3e3fc7a6b3039d9047..5d642298f04c33014c896e5cec97d143a38f1b66 100644 (file)
@@ -27,7 +27,6 @@
  *****************************************************************************/
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/version.h>
 #include <linux/init.h>
 
 #include <net/mac80211.h>
index 60a6e010603608eeca8550b5b928f3c3dcaf75e8..6283a3a707f58dad2f5cb17bfcb82ed05a57a148 100644 (file)
@@ -207,7 +207,7 @@ static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index,
        case WLAN_HT_CAP_MIMO_PS_DISABLED:
                break;
        default:
-               IWL_WARNING("Invalid MIMO PS mode %d", mimo_ps_mode);
+               IWL_WARNING("Invalid MIMO PS mode %d\n", mimo_ps_mode);
                break;
        }
 
@@ -969,7 +969,7 @@ int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr)
                return priv->hw_params.bcast_sta_id;
 
        default:
-               IWL_WARNING("Unknown mode of operation: %d", priv->iw_mode);
+               IWL_WARNING("Unknown mode of operation: %d\n", priv->iw_mode);
                return priv->hw_params.bcast_sta_id;
        }
 }
index 4108c7c8f00f5331dcaa35679eee8d95e822a7ec..d82823b5c8abce08948fad392cd9e8c3368aabf5 100644 (file)
@@ -493,7 +493,7 @@ int iwl_txq_ctx_reset(struct iwl_priv *priv)
        /* Alloc keep-warm buffer */
        ret = iwl_kw_alloc(priv);
        if (ret) {
-               IWL_ERROR("Keep Warm allocation failed");
+               IWL_ERROR("Keep Warm allocation failed\n");
                goto error_kw;
        }
        spin_lock_irqsave(&priv->lock, flags);
@@ -1463,7 +1463,7 @@ void iwl_rx_reply_compressed_ba(struct iwl_priv *priv,
        u16 ba_resp_scd_ssn = le16_to_cpu(ba_resp->scd_ssn);
 
        if (scd_flow >= priv->hw_params.max_txq_num) {
-               IWL_ERROR("BUG_ON scd_flow is bigger than number of queues");
+               IWL_ERROR("BUG_ON scd_flow is bigger than number of queues\n");
                return;
        }
 
index 444847ab1b5a7ab0a86ecd8e1bd0fd31108e5736..b775d5bab66835c40ac87812305bf405951489f6 100644 (file)
@@ -29,7 +29,6 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/version.h>
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/dma-mapping.h>
@@ -1558,7 +1557,7 @@ int iwl3945_eeprom_init(struct iwl3945_priv *priv)
        BUILD_BUG_ON(sizeof(priv->eeprom) != IWL_EEPROM_IMAGE_SIZE);
 
        if ((gp & CSR_EEPROM_GP_VALID_MSK) == CSR_EEPROM_GP_BAD_SIGNATURE) {
-               IWL_ERROR("EEPROM not found, EEPROM_GP=0x%08x", gp);
+               IWL_ERROR("EEPROM not found, EEPROM_GP=0x%08x\n", gp);
                return -ENOENT;
        }
 
@@ -1583,7 +1582,7 @@ int iwl3945_eeprom_init(struct iwl3945_priv *priv)
                }
 
                if (!(r & CSR_EEPROM_REG_READ_VALID_MSK)) {
-                       IWL_ERROR("Time out reading EEPROM[%d]", addr);
+                       IWL_ERROR("Time out reading EEPROM[%d]\n", addr);
                        return -ETIMEDOUT;
                }
                e[addr / 2] = le16_to_cpu((__force __le16)(r >> 16));
@@ -2507,7 +2506,7 @@ static int iwl3945_get_sta_id(struct iwl3945_priv *priv, struct ieee80211_hdr *h
                return priv->hw_setting.bcast_sta_id;
 
        default:
-               IWL_WARNING("Unknown mode of operation: %d", priv->iw_mode);
+               IWL_WARNING("Unknown mode of operation: %d\n", priv->iw_mode);
                return priv->hw_setting.bcast_sta_id;
        }
 }
index 83cd85e1f8475e90e4d9a7e46ef11333af55c7ef..29be3dc8ee093fa4cd7dbcf89c4dcc11184058df 100644 (file)
@@ -413,12 +413,12 @@ static void p54_rx_frame_sent(struct ieee80211_hw *dev, struct sk_buff *skb)
                        last_addr = range->end_addr;
                        __skb_unlink(entry, &priv->tx_queue);
                        memset(&info->status, 0, sizeof(info->status));
-                       priv->tx_stats[skb_get_queue_mapping(skb)].len--;
                        entry_hdr = (struct p54_control_hdr *) entry->data;
                        entry_data = (struct p54_tx_control_allocdata *) entry_hdr->data;
                        if ((entry_hdr->magic1 & cpu_to_le16(0x4000)) != 0)
                                pad = entry_data->align[0];
 
+                       priv->tx_stats[entry_data->hw_queue - 4].len--;
                        if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) {
                                if (!(payload->status & 0x01))
                                        info->flags |= IEEE80211_TX_STAT_ACK;
@@ -557,6 +557,7 @@ static int p54_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
        struct p54_tx_control_allocdata *txhdr;
        size_t padding, len;
        u8 rate;
+       u8 cts_rate = 0x20;
 
        current_queue = &priv->tx_stats[skb_get_queue_mapping(skb)];
        if (unlikely(current_queue->len > current_queue->limit))
@@ -581,28 +582,28 @@ static int p54_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
        hdr->type = (info->flags & IEEE80211_TX_CTL_NO_ACK) ? 0 : cpu_to_le16(1);
        hdr->retry1 = hdr->retry2 = info->control.retry_limit;
 
-       memset(txhdr->wep_key, 0x0, 16);
-       txhdr->padding = 0;
-       txhdr->padding2 = 0;
-
        /* TODO: add support for alternate retry TX rates */
        rate = ieee80211_get_tx_rate(dev, info)->hw_value;
-       if (info->flags & IEEE80211_TX_CTL_SHORT_PREAMBLE)
+       if (info->flags & IEEE80211_TX_CTL_SHORT_PREAMBLE) {
                rate |= 0x10;
-       if (info->flags & IEEE80211_TX_CTL_USE_RTS_CTS)
+               cts_rate |= 0x10;
+       }
+       if (info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) {
                rate |= 0x40;
-       else if (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT)
+               cts_rate |= ieee80211_get_rts_cts_rate(dev, info)->hw_value;
+       } else if (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT) {
                rate |= 0x20;
+               cts_rate |= ieee80211_get_rts_cts_rate(dev, info)->hw_value;
+       }
        memset(txhdr->rateset, rate, 8);
-       txhdr->wep_key_present = 0;
-       txhdr->wep_key_len = 0;
-       txhdr->frame_type = cpu_to_le32(skb_get_queue_mapping(skb) + 4);
-       txhdr->magic4 = 0;
-       txhdr->antenna = (info->antenna_sel_tx == 0) ?
+       txhdr->key_type = 0;
+       txhdr->key_len = 0;
+       txhdr->hw_queue = skb_get_queue_mapping(skb) + 4;
+       txhdr->tx_antenna = (info->antenna_sel_tx == 0) ?
                2 : info->antenna_sel_tx - 1;
        txhdr->output_power = 0x7f; // HW Maximum
-       txhdr->magic5 = (info->flags & IEEE80211_TX_CTL_NO_ACK) ?
-               0 : ((rate > 0x3) ? cpu_to_le32(0x33) : cpu_to_le32(0x23));
+       txhdr->cts_rate = (info->flags & IEEE80211_TX_CTL_NO_ACK) ?
+                         0 : cts_rate;
        if (padding)
                txhdr->align[0] = padding;
 
@@ -836,10 +837,21 @@ static int p54_start(struct ieee80211_hw *dev)
        struct p54_common *priv = dev->priv;
        int err;
 
+       if (!priv->cached_vdcf) {
+               priv->cached_vdcf = kzalloc(sizeof(struct p54_tx_control_vdcf)+
+                       priv->tx_hdr_len + sizeof(struct p54_control_hdr),
+                       GFP_KERNEL);
+
+               if (!priv->cached_vdcf)
+                       return -ENOMEM;
+       }
+
        err = priv->open(dev);
        if (!err)
                priv->mode = IEEE80211_IF_TYPE_MNTR;
 
+       p54_init_vdcf(dev);
+
        return err;
 }
 
@@ -1019,15 +1031,6 @@ struct ieee80211_hw *p54_init_common(size_t priv_data_len)
        dev->extra_tx_headroom = sizeof(struct p54_control_hdr) + 4 +
                                 sizeof(struct p54_tx_control_allocdata);
 
-        priv->cached_vdcf = kzalloc(sizeof(struct p54_tx_control_vdcf) +
-              priv->tx_hdr_len + sizeof(struct p54_control_hdr), GFP_KERNEL);
-
-       if (!priv->cached_vdcf) {
-               ieee80211_free_hw(dev);
-               return NULL;
-       }
-
-       p54_init_vdcf(dev);
        mutex_init(&priv->conf_mutex);
 
        return dev;
index 2245fcce92dc917e4707bf37cef9f086c1ca2b7c..8db6c0e8e540a3dda566be866621a7b94d46d3d8 100644 (file)
@@ -183,16 +183,16 @@ struct p54_frame_sent_hdr {
 
 struct p54_tx_control_allocdata {
        u8 rateset[8];
-       u16 padding;
-       u8 wep_key_present;
-       u8 wep_key_len;
-       u8 wep_key[16];
-       __le32 frame_type;
-       u32 padding2;
-       __le16 magic4;
-       u8 antenna;
+       u8 unalloc0[2];
+       u8 key_type;
+       u8 key_len;
+       u8 key[16];
+       u8 hw_queue;
+       u8 unalloc1[9];
+       u8 tx_antenna;
        u8 output_power;
-       __le32 magic5;
+       u8 cts_rate;
+       u8 unalloc2[3];
        u8 align[0];
 } __attribute__ ((packed));
 
index 815c095ef7971361e59d3a95648aee811dea6d09..cbaca23a945353a30734a3ec5aa19e095a209a38 100644 (file)
@@ -109,7 +109,17 @@ static void p54u_rx_cb(struct urb *urb)
                urb->context = skb;
                skb_queue_tail(&priv->rx_queue, skb);
        } else {
+               if (!priv->hw_type)
+                       skb_push(skb, sizeof(struct net2280_tx_hdr));
+
+               skb_reset_tail_pointer(skb);
                skb_trim(skb, 0);
+               if (urb->transfer_buffer != skb_tail_pointer(skb)) {
+                       /* this should not happen */
+                       WARN_ON(1);
+                       urb->transfer_buffer = skb_tail_pointer(skb);
+               }
+
                skb_queue_tail(&priv->rx_queue, skb);
        }
 
index a4a8c57004db179d2df8777c45e421786f68a6af..ff78e52ce43c2340ba910741c2ece4be764a05e0 100644 (file)
@@ -173,10 +173,10 @@ struct rxdone_entry_desc {
  *     frame transmission failed due to excessive retries.
  */
 enum txdone_entry_desc_flags {
-       TXDONE_UNKNOWN = 1 << 0,
-       TXDONE_SUCCESS = 1 << 1,
-       TXDONE_FAILURE = 1 << 2,
-       TXDONE_EXCESSIVE_RETRY = 1 << 3,
+       TXDONE_UNKNOWN,
+       TXDONE_SUCCESS,
+       TXDONE_FAILURE,
+       TXDONE_EXCESSIVE_RETRY,
 };
 
 /**
index 8d76bb2e031289b027ec810a9bbbc6b75754dfbd..2050227ea5304acb1daa8ba8f601a17b14eb5c25 100644 (file)
@@ -181,6 +181,7 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb)
         * (Only indirectly by looking at the failed TX counters
         * in the register).
         */
+       txdesc.flags = 0;
        if (!urb->status)
                __set_bit(TXDONE_UNKNOWN, &txdesc.flags);
        else
index 57376fb993edecbd984876f2a24cfa22f863fafc..ca5deb6244e63c881ba3e48bdee13da2ca2f0716 100644 (file)
@@ -40,6 +40,7 @@ static struct usb_device_id rtl8187_table[] __devinitdata = {
        /* Netgear */
        {USB_DEVICE(0x0846, 0x6100), .driver_info = DEVICE_RTL8187},
        {USB_DEVICE(0x0846, 0x6a00), .driver_info = DEVICE_RTL8187},
+       {USB_DEVICE(0x0846, 0x4260), .driver_info = DEVICE_RTL8187B},
        /* HP */
        {USB_DEVICE(0x03f0, 0xca02), .driver_info = DEVICE_RTL8187},
        /* Sitecom */
index 8a1d93a2bb815c380bb18710369912834c2d2f06..51e5214071da9f32b370c48622d70f9a62f55e5b 100644 (file)
@@ -57,6 +57,15 @@ static ssize_t devspec_show(struct device *dev,
        return sprintf(buf, "%s\n", ofdev->node->full_name);
 }
 
+static ssize_t name_show(struct device *dev,
+                               struct device_attribute *attr, char *buf)
+{
+       struct of_device *ofdev;
+
+       ofdev = to_of_device(dev);
+       return sprintf(buf, "%s\n", ofdev->node->name);
+}
+
 static ssize_t modalias_show(struct device *dev,
                                struct device_attribute *attr, char *buf)
 {
@@ -71,6 +80,7 @@ static ssize_t modalias_show(struct device *dev,
 
 struct device_attribute of_platform_device_attrs[] = {
        __ATTR_RO(devspec),
+       __ATTR_RO(name),
        __ATTR_RO(modalias),
        __ATTR_NULL
 };
index 93e37f0666ab5e2786484a775f107bbffd9b3ecd..e17ef54f0efced2d0173a9f5af250c2f0fa93517 100644 (file)
@@ -382,7 +382,7 @@ EXPORT_SYMBOL_GPL(acpi_get_hp_params_from_firmware);
 int acpi_get_hp_hw_control_from_firmware(struct pci_dev *dev, u32 flags)
 {
        acpi_status status;
-       acpi_handle chandle, handle = DEVICE_ACPI_HANDLE(&(dev->dev));
+       acpi_handle chandle, handle;
        struct pci_dev *pdev = dev;
        struct pci_bus *parent;
        struct acpi_buffer string = { ACPI_ALLOCATE_BUFFER, NULL };
@@ -399,10 +399,25 @@ int acpi_get_hp_hw_control_from_firmware(struct pci_dev *dev, u32 flags)
         * Per PCI firmware specification, we should run the ACPI _OSC
         * method to get control of hotplug hardware before using it. If
         * an _OSC is missing, we look for an OSHP to do the same thing.
-        * To handle different BIOS behavior, we look for _OSC and OSHP
-        * within the scope of the hotplug controller and its parents,
+        * To handle different BIOS behavior, we look for _OSC on a root
+        * bridge preferentially (according to PCI fw spec). Later for
+        * OSHP within the scope of the hotplug controller and its parents,
         * upto the host bridge under which this controller exists.
         */
+       handle = acpi_find_root_bridge_handle(pdev);
+       if (handle) {
+               acpi_get_name(handle, ACPI_FULL_PATHNAME, &string);
+               dbg("Trying to get hotplug control for %s\n",
+                               (char *)string.pointer);
+               status = pci_osc_control_set(handle, flags);
+               if (ACPI_SUCCESS(status))
+                       goto got_one;
+               kfree(string.pointer);
+               string = (struct acpi_buffer){ ACPI_ALLOCATE_BUFFER, NULL };
+       }
+
+       pdev = dev;
+       handle = DEVICE_ACPI_HANDLE(&dev->dev);
        while (!handle) {
                /*
                 * This hotplug controller was not listed in the ACPI name
@@ -427,15 +442,9 @@ int acpi_get_hp_hw_control_from_firmware(struct pci_dev *dev, u32 flags)
                acpi_get_name(handle, ACPI_FULL_PATHNAME, &string);
                dbg("Trying to get hotplug control for %s \n",
                    (char *)string.pointer);
-               status = pci_osc_control_set(handle, flags);
-               if (status == AE_NOT_FOUND)
-                       status = acpi_run_oshp(handle);
-               if (ACPI_SUCCESS(status)) {
-                       dbg("Gained control for hotplug HW for pci %s (%s)\n",
-                           pci_name(dev), (char *)string.pointer);
-                       kfree(string.pointer);
-                       return 0;
-               }
+               status = acpi_run_oshp(handle);
+               if (ACPI_SUCCESS(status))
+                       goto got_one;
                if (acpi_root_bridge(handle))
                        break;
                chandle = handle;
@@ -449,6 +458,11 @@ int acpi_get_hp_hw_control_from_firmware(struct pci_dev *dev, u32 flags)
 
        kfree(string.pointer);
        return -ENODEV;
+got_one:
+       dbg("Gained control for hotplug HW for pci %s (%s)\n", pci_name(dev),
+                       (char *)string.pointer);
+       kfree(string.pointer);
+       return 0;
 }
 EXPORT_SYMBOL(acpi_get_hp_hw_control_from_firmware);
 
index e3a1e7e7dba246b6bc35a16dbd8a0a3f00ee885e..9e6cec67e1cc33d62690e8a3ebcf462c706956ca 100644 (file)
@@ -43,7 +43,6 @@ extern int pciehp_poll_mode;
 extern int pciehp_poll_time;
 extern int pciehp_debug;
 extern int pciehp_force;
-extern int pciehp_slot_with_bus;
 extern struct workqueue_struct *pciehp_wq;
 
 #define dbg(format, arg...)                                            \
index 3677495c4f91e2bf827c7d863d431be4272c3c5a..4fd5355bc3b55a6c957f2d0b031b2a5dd9d2d7d3 100644 (file)
@@ -41,7 +41,6 @@ int pciehp_debug;
 int pciehp_poll_mode;
 int pciehp_poll_time;
 int pciehp_force;
-int pciehp_slot_with_bus;
 struct workqueue_struct *pciehp_wq;
 
 #define DRIVER_VERSION "0.4"
@@ -56,12 +55,10 @@ module_param(pciehp_debug, bool, 0644);
 module_param(pciehp_poll_mode, bool, 0644);
 module_param(pciehp_poll_time, int, 0644);
 module_param(pciehp_force, bool, 0644);
-module_param(pciehp_slot_with_bus, bool, 0644);
 MODULE_PARM_DESC(pciehp_debug, "Debugging mode enabled or not");
 MODULE_PARM_DESC(pciehp_poll_mode, "Using polling mechanism for hot-plug events or not");
 MODULE_PARM_DESC(pciehp_poll_time, "Polling mechanism frequency, in seconds");
 MODULE_PARM_DESC(pciehp_force, "Force pciehp, even if _OSC and OSHP are missing");
-MODULE_PARM_DESC(pciehp_slot_with_bus, "Use bus number in the slot name");
 
 #define PCIE_MODULE_NAME "pciehp"
 
@@ -194,6 +191,7 @@ static int init_slots(struct controller *ctrl)
        struct slot *slot;
        struct hotplug_slot *hotplug_slot;
        struct hotplug_slot_info *info;
+       int len, dup = 1;
        int retval = -ENOMEM;
 
        list_for_each_entry(slot, &ctrl->slot_list, slot_list) {
@@ -220,15 +218,24 @@ static int init_slots(struct controller *ctrl)
                dbg("Registering bus=%x dev=%x hp_slot=%x sun=%x "
                    "slot_device_offset=%x\n", slot->bus, slot->device,
                    slot->hp_slot, slot->number, ctrl->slot_device_offset);
+duplicate_name:
                retval = pci_hp_register(hotplug_slot,
                                         ctrl->pci_dev->subordinate,
                                         slot->device);
                if (retval) {
+                       /*
+                        * If slot N already exists, we'll try to create
+                        * slot N-1, N-2 ... N-M, until we overflow.
+                        */
+                       if (retval == -EEXIST) {
+                               len = snprintf(slot->name, SLOT_NAME_SIZE,
+                                              "%d-%d", slot->number, dup++);
+                               if (len < SLOT_NAME_SIZE)
+                                       goto duplicate_name;
+                               else
+                                       err("duplicate slot name overflow\n");
+                       }
                        err("pci_hp_register failed with error %d\n", retval);
-                       if (retval == -EEXIST)
-                               err("Failed to register slot because of name "
-                                   "collision. Try \'pciehp_slot_with_bus\' "
-                                   "module option.\n");
                        goto error_info;
                }
                /* create additional sysfs entries */
index ad27e9e225a6f37b2ee7bb46dc601a0e73ad11db..ab31f5ba665d14c23ba3d3f19194eb154312e9c1 100644 (file)
@@ -1030,15 +1030,6 @@ static void pcie_shutdown_notification(struct controller *ctrl)
        pciehp_free_irq(ctrl);
 }
 
-static void make_slot_name(struct slot *slot)
-{
-       if (pciehp_slot_with_bus)
-               snprintf(slot->name, SLOT_NAME_SIZE, "%04d_%04d",
-                        slot->bus, slot->number);
-       else
-               snprintf(slot->name, SLOT_NAME_SIZE, "%d", slot->number);
-}
-
 static int pcie_init_slot(struct controller *ctrl)
 {
        struct slot *slot;
@@ -1053,7 +1044,7 @@ static int pcie_init_slot(struct controller *ctrl)
        slot->device = ctrl->slot_device_offset + slot->hp_slot;
        slot->hpc_ops = ctrl->hpc_ops;
        slot->number = ctrl->first_slot;
-       make_slot_name(slot);
+       snprintf(slot->name, SLOT_NAME_SIZE, "%d", slot->number);
        mutex_init(&slot->lock);
        INIT_DELAYED_WORK(&slot->work, pciehp_queue_pushbutton_work);
        list_add(&slot->slot_list, &ctrl->slot_list);
index a8cbd039b85bfde22a4f6e019d8de62cb5714f9e..cc38615395f1087f10a07764fe8d402524a9830b 100644 (file)
@@ -39,7 +39,6 @@
 int shpchp_debug;
 int shpchp_poll_mode;
 int shpchp_poll_time;
-static int shpchp_slot_with_bus;
 struct workqueue_struct *shpchp_wq;
 
 #define DRIVER_VERSION "0.4"
@@ -53,11 +52,9 @@ MODULE_LICENSE("GPL");
 module_param(shpchp_debug, bool, 0644);
 module_param(shpchp_poll_mode, bool, 0644);
 module_param(shpchp_poll_time, int, 0644);
-module_param(shpchp_slot_with_bus, bool, 0644);
 MODULE_PARM_DESC(shpchp_debug, "Debugging mode enabled or not");
 MODULE_PARM_DESC(shpchp_poll_mode, "Using polling mechanism for hot-plug events or not");
 MODULE_PARM_DESC(shpchp_poll_time, "Polling mechanism frequency, in seconds");
-MODULE_PARM_DESC(shpchp_slot_with_bus, "Use bus number in the slot name");
 
 #define SHPC_MODULE_NAME "shpchp"
 
@@ -99,23 +96,13 @@ static void release_slot(struct hotplug_slot *hotplug_slot)
        kfree(slot);
 }
 
-static void make_slot_name(struct slot *slot)
-{
-       if (shpchp_slot_with_bus)
-               snprintf(slot->hotplug_slot->name, SLOT_NAME_SIZE, "%04d_%04d",
-                        slot->bus, slot->number);
-       else
-               snprintf(slot->hotplug_slot->name, SLOT_NAME_SIZE, "%d",
-                        slot->number);
-}
-
 static int init_slots(struct controller *ctrl)
 {
        struct slot *slot;
        struct hotplug_slot *hotplug_slot;
        struct hotplug_slot_info *info;
        int retval = -ENOMEM;
-       int i;
+       int i, len, dup = 1;
 
        for (i = 0; i < ctrl->num_slots; i++) {
                slot = kzalloc(sizeof(*slot), GFP_KERNEL);
@@ -146,7 +133,7 @@ static int init_slots(struct controller *ctrl)
                /* register this slot with the hotplug pci core */
                hotplug_slot->private = slot;
                hotplug_slot->release = &release_slot;
-               make_slot_name(slot);
+               snprintf(slot->name, SLOT_NAME_SIZE, "%d", slot->number);
                hotplug_slot->ops = &shpchp_hotplug_slot_ops;
 
                get_power_status(hotplug_slot, &info->power_status);
@@ -157,14 +144,23 @@ static int init_slots(struct controller *ctrl)
                dbg("Registering bus=%x dev=%x hp_slot=%x sun=%x "
                    "slot_device_offset=%x\n", slot->bus, slot->device,
                    slot->hp_slot, slot->number, ctrl->slot_device_offset);
+duplicate_name:
                retval = pci_hp_register(slot->hotplug_slot,
                                ctrl->pci_dev->subordinate, slot->device);
                if (retval) {
+                       /*
+                        * If slot N already exists, we'll try to create
+                        * slot N-1, N-2 ... N-M, until we overflow.
+                        */
+                       if (retval == -EEXIST) {
+                               len = snprintf(slot->name, SLOT_NAME_SIZE,
+                                              "%d-%d", slot->number, dup++);
+                               if (len < SLOT_NAME_SIZE)
+                                       goto duplicate_name;
+                               else
+                                       err("duplicate slot name overflow\n");
+                       }
                        err("pci_hp_register failed with error %d\n", retval);
-                       if (retval == -EEXIST)
-                               err("Failed to register slot because of name "
-                                    "collision. Try \'shpchp_slot_with_bus\' "
-                                   "module option.\n");
                        goto error_info;
                }
 
index 30f581b8791f5f84c6ab72a1f76bf1de8a5a2c87..6dd7b13e9808072bab1bf605ab997d817592efb1 100644 (file)
@@ -36,12 +36,7 @@ int aer_osc_setup(struct pcie_device *pciedev)
        if (acpi_pci_disabled)
                return -1;
 
-       /* Find root host bridge */
-       while (pdev->bus->self)
-               pdev = pdev->bus->self;
-       handle = acpi_get_pci_rootbridge_handle(
-               pci_domain_nr(pdev->bus), pdev->bus->number);
-
+       handle = acpi_find_root_bridge_handle(pdev);
        if (handle) {
                pcie_osc_support_set(OSC_EXT_PCI_CONFIG_SUPPORT);
                status = pci_osc_control_set(handle,
index a04498d390c85fbac5c4ec940b06f501bb076d2d..cce2f4cb1fbf37985d7303ec2e34d9f507d92aee 100644 (file)
@@ -383,6 +383,7 @@ void __devinit pci_read_bridge_bases(struct pci_bus *child)
                        res->start = base;
                if (!res->end)
                        res->end = limit + 0xfff;
+               printk(KERN_INFO "PCI: bridge %s io port: [%llx, %llx]\n", pci_name(dev), res->start, res->end);
        }
 
        res = child->resource[1];
@@ -394,6 +395,7 @@ void __devinit pci_read_bridge_bases(struct pci_bus *child)
                res->flags = (mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | IORESOURCE_MEM;
                res->start = base;
                res->end = limit + 0xfffff;
+               printk(KERN_INFO "PCI: bridge %s 32bit mmio: [%llx, %llx]\n", pci_name(dev), res->start, res->end);
        }
 
        res = child->resource[2];
@@ -429,6 +431,7 @@ void __devinit pci_read_bridge_bases(struct pci_bus *child)
                res->flags = (mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | IORESOURCE_MEM | IORESOURCE_PREFETCH;
                res->start = base;
                res->end = limit + 0xfffff;
+               printk(KERN_INFO "PCI: bridge %s %sbit mmio pref: [%llx, %llx]\n", pci_name(dev), (res->flags & PCI_PREF_RANGE_TYPE_64)?"64":"32",res->start, res->end);
        }
 }
 
index 217814fef4ef4c7e5b3e4b54b96b1e70c7e2b7d4..3b3b5f1787973556f7dacecd01b1ab3bbe68b68f 100644 (file)
@@ -280,6 +280,8 @@ static struct pci_dev *pci_get_dev_by_id(const struct pci_device_id *id,
                              match_pci_dev_by_id);
        if (dev)
                pdev = to_pci_dev(dev);
+       if (from)
+               pci_dev_put(from);
        return pdev;
 }
 
index 827c0a520e2b3aec87bcc2a160720fbd48e836b2..82634a2f1b1d82da305e73ef1287330ea0cf01ed 100644 (file)
@@ -530,6 +530,36 @@ void __ref pci_bus_assign_resources(struct pci_bus *bus)
 }
 EXPORT_SYMBOL(pci_bus_assign_resources);
 
+static void pci_bus_dump_res(struct pci_bus *bus)
+{
+        int i;
+
+        for (i = 0; i < PCI_BUS_NUM_RESOURCES; i++) {
+                struct resource *res = bus->resource[i];
+                if (!res)
+                        continue;
+
+               printk(KERN_INFO "bus: %02x index %x %s: [%llx, %llx]\n", bus->number, i, (res->flags & IORESOURCE_IO)? "io port":"mmio", res->start, res->end);
+        }
+}
+
+static void pci_bus_dump_resources(struct pci_bus *bus)
+{
+       struct pci_bus *b;
+       struct pci_dev *dev;
+
+
+       pci_bus_dump_res(bus);
+
+       list_for_each_entry(dev, &bus->devices, bus_list) {
+               b = dev->subordinate;
+               if (!b)
+                       continue;
+
+               pci_bus_dump_resources(b);
+       }
+}
+
 void __init
 pci_assign_unassigned_resources(void)
 {
@@ -545,4 +575,9 @@ pci_assign_unassigned_resources(void)
                pci_bus_assign_resources(bus);
                pci_enable_bridges(bus);
        }
+
+       /* dump the resource on buses */
+       list_for_each_entry(bus, &pci_root_buses, node) {
+               pci_bus_dump_resources(bus);
+       }
 }
index 90ab73825401a0b5f4c0b7de15c5ff755a4edb7d..9a9755c92fada3268f03f69ee7270964bf322818 100644 (file)
@@ -561,7 +561,7 @@ config RTC_DRV_AT91SAM9_GPBR
 
 config RTC_DRV_BFIN
        tristate "Blackfin On-Chip RTC"
-       depends on BLACKFIN
+       depends on BLACKFIN && !BF561
        help
          If you say yes here you will get support for the
          Blackfin On-Chip Real Time Clock.
index a1af4c27939b446b0de1f43d8d61c7a51b610d21..34439ce3967e1844c552091fb72a0555b904644d 100644 (file)
@@ -218,26 +218,6 @@ static irqreturn_t bfin_rtc_interrupt(int irq, void *dev_id)
                return IRQ_NONE;
 }
 
-static int bfin_rtc_open(struct device *dev)
-{
-       int ret;
-
-       dev_dbg_stamp(dev);
-
-       ret = request_irq(IRQ_RTC, bfin_rtc_interrupt, IRQF_SHARED, to_platform_device(dev)->name, dev);
-       if (!ret)
-               bfin_rtc_reset(dev, RTC_ISTAT_WRITE_COMPLETE);
-
-       return ret;
-}
-
-static void bfin_rtc_release(struct device *dev)
-{
-       dev_dbg_stamp(dev);
-       bfin_rtc_reset(dev, 0);
-       free_irq(IRQ_RTC, dev);
-}
-
 static void bfin_rtc_int_set(u16 rtc_int)
 {
        bfin_write_RTC_ISTAT(rtc_int);
@@ -370,8 +350,6 @@ static int bfin_rtc_proc(struct device *dev, struct seq_file *seq)
 }
 
 static struct rtc_class_ops bfin_rtc_ops = {
-       .open          = bfin_rtc_open,
-       .release       = bfin_rtc_release,
        .ioctl         = bfin_rtc_ioctl,
        .read_time     = bfin_rtc_read_time,
        .set_time      = bfin_rtc_set_time,
@@ -383,29 +361,44 @@ static struct rtc_class_ops bfin_rtc_ops = {
 static int __devinit bfin_rtc_probe(struct platform_device *pdev)
 {
        struct bfin_rtc *rtc;
+       struct device *dev = &pdev->dev;
        int ret = 0;
+       unsigned long timeout;
 
-       dev_dbg_stamp(&pdev->dev);
+       dev_dbg_stamp(dev);
 
+       /* Allocate memory for our RTC struct */
        rtc = kzalloc(sizeof(*rtc), GFP_KERNEL);
        if (unlikely(!rtc))
                return -ENOMEM;
+       platform_set_drvdata(pdev, rtc);
+       device_init_wakeup(dev, 1);
 
-       rtc->rtc_dev = rtc_device_register(pdev->name, &pdev->dev, &bfin_rtc_ops, THIS_MODULE);
-       if (IS_ERR(rtc)) {
-               ret = PTR_ERR(rtc->rtc_dev);
+       /* Grab the IRQ and init the hardware */
+       ret = request_irq(IRQ_RTC, bfin_rtc_interrupt, IRQF_SHARED, pdev->name, dev);
+       if (unlikely(ret))
                goto err;
-       }
-
-       /* see comment at top of file about stopwatch/PIE */
+       /* sometimes the bootloader touched things, but the write complete was not
+        * enabled, so let's just do a quick timeout here since the IRQ will not fire ...
+        */
+       timeout = jiffies + HZ;
+       while (bfin_read_RTC_ISTAT() & RTC_ISTAT_WRITE_PENDING)
+               if (time_after(jiffies, timeout))
+                       break;
+       bfin_rtc_reset(dev, RTC_ISTAT_WRITE_COMPLETE);
        bfin_write_RTC_SWCNT(0);
 
-       platform_set_drvdata(pdev, rtc);
-
-       device_init_wakeup(&pdev->dev, 1);
+       /* Register our RTC with the RTC framework */
+       rtc->rtc_dev = rtc_device_register(pdev->name, dev, &bfin_rtc_ops, THIS_MODULE);
+       if (unlikely(IS_ERR(rtc))) {
+               ret = PTR_ERR(rtc->rtc_dev);
+               goto err_irq;
+       }
 
        return 0;
 
+ err_irq:
+       free_irq(IRQ_RTC, dev);
  err:
        kfree(rtc);
        return ret;
@@ -414,7 +407,10 @@ static int __devinit bfin_rtc_probe(struct platform_device *pdev)
 static int __devexit bfin_rtc_remove(struct platform_device *pdev)
 {
        struct bfin_rtc *rtc = platform_get_drvdata(pdev);
+       struct device *dev = &pdev->dev;
 
+       bfin_rtc_reset(dev, 0);
+       free_irq(IRQ_RTC, dev);
        rtc_device_unregister(rtc->rtc_dev);
        platform_set_drvdata(pdev, NULL);
        kfree(rtc);
index 35dcc06eb3e2dab77b16e27881f2b6bd6250c372..f118252f3a9f2b921cef3fff96fd1ef890d65b3c 100644 (file)
@@ -403,11 +403,14 @@ static long rtc_dev_ioctl(struct file *file,
 
 #ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL
        case RTC_UIE_OFF:
+               mutex_unlock(&rtc->ops_lock);
                clear_uie(rtc);
-               break;
+               return 0;
 
        case RTC_UIE_ON:
+               mutex_unlock(&rtc->ops_lock);
                err = set_uie(rtc);
+               return err;
 #endif
        default:
                err = -ENOTTY;
index 640acd20fdde43c2751f2be4d6d0a63198bf7b7d..a150418fba765d5db942db7bd2ffdb525716367e 100644 (file)
@@ -173,7 +173,7 @@ static int ds1374_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
        int cr, sr;
        int ret = 0;
 
-       if (client->irq < 0)
+       if (client->irq <= 0)
                return -EINVAL;
 
        mutex_lock(&ds1374->mutex);
@@ -212,7 +212,7 @@ static int ds1374_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
        int cr;
        int ret = 0;
 
-       if (client->irq < 0)
+       if (client->irq <= 0)
                return -EINVAL;
 
        ret = ds1374_read_time(dev, &now);
@@ -381,7 +381,7 @@ static int ds1374_probe(struct i2c_client *client,
        if (ret)
                goto out_free;
 
-       if (client->irq >= 0) {
+       if (client->irq > 0) {
                ret = request_irq(client->irq, ds1374_irq, 0,
                                  "ds1374", client);
                if (ret) {
@@ -401,7 +401,7 @@ static int ds1374_probe(struct i2c_client *client,
        return 0;
 
 out_irq:
-       if (client->irq >= 0)
+       if (client->irq > 0)
                free_irq(client->irq, client);
 
 out_free:
@@ -414,7 +414,7 @@ static int __devexit ds1374_remove(struct i2c_client *client)
 {
        struct ds1374 *ds1374 = i2c_get_clientdata(client);
 
-       if (client->irq >= 0) {
+       if (client->irq > 0) {
                mutex_lock(&ds1374->mutex);
                ds1374->exiting = 1;
                mutex_unlock(&ds1374->mutex);
index 12f0310ae89c661621c6d9db3c993db084adacd6..78b2551fb19def5e380aa73f70f424c6e500e91e 100644 (file)
@@ -20,8 +20,6 @@
  */
 
 #include <linux/module.h>
-#include <linux/version.h>
-
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
 #include <linux/init.h>
index b35f9bfa2af4db00df60d0ae74cec8bc0251dfd2..395985b339c933a2c0afa17bff1f38fc78e6bf17 100644 (file)
@@ -14,7 +14,6 @@
  */
 
 #include <linux/module.h>
-#include <linux/version.h>
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
 #include <linux/device.h>
index 1b6c52ef73391da1aff66cc1aa6bcda8c193ddd8..acb78017e7d0fd2e2988bfed85ec484e527bfcc6 100644 (file)
@@ -2333,13 +2333,11 @@ int dasd_generic_notify(struct ccw_device *cdev, int event)
 {
        struct dasd_device *device;
        struct dasd_ccw_req *cqr;
-       unsigned long flags;
        int ret;
 
-       device = dasd_device_from_cdev(cdev);
+       device = dasd_device_from_cdev_locked(cdev);
        if (IS_ERR(device))
                return 0;
-       spin_lock_irqsave(get_ccwdev_lock(cdev), flags);
        ret = 0;
        switch (event) {
        case CIO_GONE:
@@ -2369,7 +2367,6 @@ int dasd_generic_notify(struct ccw_device *cdev, int event)
                ret = 1;
                break;
        }
-       spin_unlock_irqrestore(get_ccwdev_lock(cdev), flags);
        dasd_put_device(device);
        return ret;
 }
index 4bf0aa5112c10c00cc2dfeff42409244539de503..2476f87d21d0027ae61dc08e546abb15b37ec979 100644 (file)
@@ -308,7 +308,7 @@ struct dasd_psf_prssd_data {
        unsigned char flags;
        unsigned char reserved[4];
        unsigned char suborder;
-       unsigned char varies[9];
+       unsigned char varies[5];
 } __attribute__ ((packed));
 
 /*
index 29da4413ad437b789dd78f104f894b396f99e386..bf512ac75b9e640f058cf1d1b8ddbd2d9490134a 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/poll.h>
 #include <linux/mutex.h>
 #include <linux/smp_lock.h>
+#include <linux/err.h>
 
 #include <asm/uaccess.h>
 #include <asm/atomic.h>
@@ -457,7 +458,7 @@ int dasd_eer_enable(struct dasd_device *device)
 
        cqr = dasd_kmalloc_request("ECKD", 1 /* SNSS */,
                                   SNSS_DATA_SIZE, device);
-       if (!cqr)
+       if (IS_ERR(cqr))
                return -ENOMEM;
 
        cqr->startdev = device;
index 01fcdd91b846533a920cc3076c67bf85ca3816c2..db85f1fb131e0494dfb3e7a4838b23c269d9d36b 100644 (file)
@@ -384,6 +384,10 @@ dcssblk_add_store(struct device *dev, struct device_attribute *attr, const char
         * get minor, add to list
         */
        down_write(&dcssblk_devices_sem);
+       if (dcssblk_get_segment_by_name(local_buf)) {
+               rc = -EEXIST;
+               goto release_gd;
+       }
        rc = dcssblk_assign_free_minor(dev_info);
        if (rc) {
                up_write(&dcssblk_devices_sem);
index 687720b552d1c460019c8aa40a758294538195dd..be0ce2215c8de2d1214dd75d0330b850edc84885 100644 (file)
@@ -109,7 +109,7 @@ tapechar_check_idalbuffer(struct tape_device *device, size_t block_size)
 
        /* The current idal buffer is not correct. Allocate a new one. */
        new = idal_buffer_alloc(block_size, 0);
-       if (new == NULL)
+       if (IS_ERR(new))
                return -ENOMEM;
 
        if (device->char_data.idal_buf != NULL)
index 2a1af4e60be0919226217471beec3b1ea8f2b7b7..cc8fd781ee227ce6e8f1ae38956b2fb002fe5ad6 100644 (file)
@@ -248,7 +248,7 @@ tape_std_mtsetblk(struct tape_device *device, int count)
 
        /* Allocate a new idal buffer. */
        new = idal_buffer_alloc(count, 0);
-       if (new == NULL)
+       if (IS_ERR(new))
                return -ENOMEM;
        if (device->char_data.idal_buf != NULL)
                idal_buffer_free(device->char_data.idal_buf);
index 26a930e832bdab58c7f649c866124200e1f3f8c8..e0ce65fca4e797ed2da7370093a56f1a86d04c81 100644 (file)
@@ -112,8 +112,10 @@ ccwgroup_release (struct device *dev)
        gdev = to_ccwgroupdev(dev);
 
        for (i = 0; i < gdev->count; i++) {
-               dev_set_drvdata(&gdev->cdev[i]->dev, NULL);
-               put_device(&gdev->cdev[i]->dev);
+               if (gdev->cdev[i]) {
+                       dev_set_drvdata(&gdev->cdev[i]->dev, NULL);
+                       put_device(&gdev->cdev[i]->dev);
+               }
        }
        kfree(gdev);
 }
@@ -221,6 +223,13 @@ int ccwgroup_create_from_string(struct device *root, unsigned int creator_id,
        atomic_set(&gdev->onoff, 0);
        mutex_init(&gdev->reg_mutex);
        mutex_lock(&gdev->reg_mutex);
+       gdev->creator_id = creator_id;
+       gdev->count = num_devices;
+       gdev->dev.bus = &ccwgroup_bus_type;
+       gdev->dev.parent = root;
+       gdev->dev.release = ccwgroup_release;
+       device_initialize(&gdev->dev);
+
        curr_buf = buf;
        for (i = 0; i < num_devices && curr_buf; i++) {
                rc = __get_next_bus_id(&curr_buf, tmp_bus_id);
@@ -258,16 +267,11 @@ int ccwgroup_create_from_string(struct device *root, unsigned int creator_id,
                rc = -EINVAL;
                goto error;
        }
-       gdev->creator_id = creator_id;
-       gdev->count = num_devices;
-       gdev->dev.bus = &ccwgroup_bus_type;
-       gdev->dev.parent = root;
-       gdev->dev.release = ccwgroup_release;
 
        snprintf (gdev->dev.bus_id, BUS_ID_SIZE, "%s",
                        gdev->cdev[0]->dev.bus_id);
 
-       rc = device_register(&gdev->dev);
+       rc = device_add(&gdev->dev);
        if (rc)
                goto error;
        get_device(&gdev->dev);
index 46c021d880dc5ee7441cd11f8e885bf54d79b7dd..51489eff6b0b4484ad234e6b7b7a0819a6d1ddd6 100644 (file)
@@ -477,7 +477,6 @@ void css_schedule_eval_all(void)
 
 void css_wait_for_slow_path(void)
 {
-       flush_workqueue(ccw_device_notify_work);
        flush_workqueue(slow_path_wq);
 }
 
index e818d0c54c0949f5a21ae134ccf426da5d079d9c..28221030b886cfa5ae8d794fdf176bdbfe401845 100644 (file)
@@ -150,7 +150,6 @@ static struct css_driver io_subchannel_driver = {
 };
 
 struct workqueue_struct *ccw_device_work;
-struct workqueue_struct *ccw_device_notify_work;
 wait_queue_head_t ccw_device_init_wq;
 atomic_t ccw_device_init_count;
 
@@ -168,11 +167,6 @@ init_ccw_bus_type (void)
        ccw_device_work = create_singlethread_workqueue("cio");
        if (!ccw_device_work)
                return -ENOMEM; /* FIXME: better errno ? */
-       ccw_device_notify_work = create_singlethread_workqueue("cio_notify");
-       if (!ccw_device_notify_work) {
-               ret = -ENOMEM; /* FIXME: better errno ? */
-               goto out_err;
-       }
        slow_path_wq = create_singlethread_workqueue("kslowcrw");
        if (!slow_path_wq) {
                ret = -ENOMEM; /* FIXME: better errno ? */
@@ -192,8 +186,6 @@ init_ccw_bus_type (void)
 out_err:
        if (ccw_device_work)
                destroy_workqueue(ccw_device_work);
-       if (ccw_device_notify_work)
-               destroy_workqueue(ccw_device_notify_work);
        if (slow_path_wq)
                destroy_workqueue(slow_path_wq);
        return ret;
@@ -204,7 +196,6 @@ cleanup_ccw_bus_type (void)
 {
        css_driver_unregister(&io_subchannel_driver);
        bus_unregister(&ccw_bus_type);
-       destroy_workqueue(ccw_device_notify_work);
        destroy_workqueue(ccw_device_work);
 }
 
@@ -1496,11 +1487,22 @@ static void device_set_disconnected(struct ccw_device *cdev)
                ccw_device_schedule_recovery();
 }
 
+void ccw_device_set_notoper(struct ccw_device *cdev)
+{
+       struct subchannel *sch = to_subchannel(cdev->dev.parent);
+
+       CIO_TRACE_EVENT(2, "notoper");
+       CIO_TRACE_EVENT(2, sch->dev.bus_id);
+       ccw_device_set_timeout(cdev, 0);
+       cio_disable_subchannel(sch);
+       cdev->private->state = DEV_STATE_NOT_OPER;
+}
+
 static int io_subchannel_sch_event(struct subchannel *sch, int slow)
 {
        int event, ret, disc;
        unsigned long flags;
-       enum { NONE, UNREGISTER, UNREGISTER_PROBE, REPROBE } action;
+       enum { NONE, UNREGISTER, UNREGISTER_PROBE, REPROBE, DISC } action;
        struct ccw_device *cdev;
 
        spin_lock_irqsave(sch->lock, flags);
@@ -1535,16 +1537,11 @@ static int io_subchannel_sch_event(struct subchannel *sch, int slow)
                }
                /* fall through */
        case CIO_GONE:
-               /* Prevent unwanted effects when opening lock. */
-               cio_disable_subchannel(sch);
-               device_set_disconnected(cdev);
                /* Ask driver what to do with device. */
-               action = UNREGISTER;
-               spin_unlock_irqrestore(sch->lock, flags);
-               ret = io_subchannel_notify(sch, event);
-               spin_lock_irqsave(sch->lock, flags);
-               if (ret)
-                       action = NONE;
+               if (io_subchannel_notify(sch, event))
+                       action = DISC;
+               else
+                       action = UNREGISTER;
                break;
        case CIO_REVALIDATE:
                /* Device will be removed, so no notify necessary. */
@@ -1565,6 +1562,7 @@ static int io_subchannel_sch_event(struct subchannel *sch, int slow)
        switch (action) {
        case UNREGISTER:
        case UNREGISTER_PROBE:
+               ccw_device_set_notoper(cdev);
                /* Unregister device (will use subchannel lock). */
                spin_unlock_irqrestore(sch->lock, flags);
                css_sch_device_unregister(sch);
@@ -1577,6 +1575,9 @@ static int io_subchannel_sch_event(struct subchannel *sch, int slow)
        case REPROBE:
                ccw_device_trigger_reprobe(cdev);
                break;
+       case DISC:
+               device_set_disconnected(cdev);
+               break;
        default:
                break;
        }
@@ -1828,5 +1829,4 @@ EXPORT_SYMBOL(ccw_driver_unregister);
 EXPORT_SYMBOL(get_ccwdev_by_busid);
 EXPORT_SYMBOL(ccw_bus_type);
 EXPORT_SYMBOL(ccw_device_work);
-EXPORT_SYMBOL(ccw_device_notify_work);
 EXPORT_SYMBOL_GPL(ccw_device_get_subchannel_id);
index 9800a8335a3fa81a195b9c5b3ae83380c21ae5ef..6f5c3f2b3587d8f72d98aa781f9f2cbd6dfd50d3 100644 (file)
@@ -72,7 +72,6 @@ dev_fsm_final_state(struct ccw_device *cdev)
 }
 
 extern struct workqueue_struct *ccw_device_work;
-extern struct workqueue_struct *ccw_device_notify_work;
 extern wait_queue_head_t ccw_device_init_wq;
 extern atomic_t ccw_device_init_count;
 
@@ -120,6 +119,7 @@ int ccw_device_stlck(struct ccw_device *);
 void ccw_device_trigger_reprobe(struct ccw_device *);
 void ccw_device_kill_io(struct ccw_device *);
 int ccw_device_notify(struct ccw_device *, int);
+void ccw_device_set_notoper(struct ccw_device *cdev);
 
 /* qdio needs this. */
 void ccw_device_set_timeout(struct ccw_device *, int);
index 8b5fe57fb2f31ef1684d586aca9f69c9c9e4fab3..550508df952b89693f5b13e4de5e5bec2a976ac3 100644 (file)
@@ -337,26 +337,34 @@ int ccw_device_notify(struct ccw_device *cdev, int event)
                return 0;
        if (!cdev->online)
                return 0;
+       CIO_MSG_EVENT(2, "notify called for 0.%x.%04x, event=%d\n",
+                     cdev->private->dev_id.ssid, cdev->private->dev_id.devno,
+                     event);
        return cdev->drv->notify ? cdev->drv->notify(cdev, event) : 0;
 }
 
-static void
-ccw_device_oper_notify(struct work_struct *work)
+static void cmf_reenable_delayed(struct work_struct *work)
 {
        struct ccw_device_private *priv;
        struct ccw_device *cdev;
-       int ret;
 
        priv = container_of(work, struct ccw_device_private, kick_work);
        cdev = priv->cdev;
-       ret = ccw_device_notify(cdev, CIO_OPER);
-       if (ret) {
+       cmf_reenable(cdev);
+}
+
+static void ccw_device_oper_notify(struct ccw_device *cdev)
+{
+       if (ccw_device_notify(cdev, CIO_OPER)) {
                /* Reenable channel measurements, if needed. */
-               cmf_reenable(cdev);
-               wake_up(&cdev->private->wait_q);
-       } else
-               /* Driver doesn't want device back. */
-               ccw_device_do_unreg_rereg(work);
+               PREPARE_WORK(&cdev->private->kick_work, cmf_reenable_delayed);
+               queue_work(ccw_device_work, &cdev->private->kick_work);
+               return;
+       }
+       /* Driver doesn't want device back. */
+       ccw_device_set_notoper(cdev);
+       PREPARE_WORK(&cdev->private->kick_work, ccw_device_do_unreg_rereg);
+       queue_work(ccw_device_work, &cdev->private->kick_work);
 }
 
 /*
@@ -386,8 +394,7 @@ ccw_device_done(struct ccw_device *cdev, int state)
 
        if (cdev->private->flags.donotify) {
                cdev->private->flags.donotify = 0;
-               PREPARE_WORK(&cdev->private->kick_work, ccw_device_oper_notify);
-               queue_work(ccw_device_notify_work, &cdev->private->kick_work);
+               ccw_device_oper_notify(cdev);
        }
        wake_up(&cdev->private->wait_q);
 
index 8484b83698e11cf32ca51bedff4088930caa66f6..5a4d85b829adf11884f92cac93f9317b7ad4c064 100644 (file)
 
 /* s390dbf views */
 #define QDIO_DBF_SETUP_LEN             8
-#define QDIO_DBF_SETUP_PAGES           4
+#define QDIO_DBF_SETUP_PAGES           8
 #define QDIO_DBF_SETUP_NR_AREAS                1
 
 #define QDIO_DBF_TRACE_LEN             8
 #define QDIO_DBF_TRACE_NR_AREAS                2
 
 #ifdef CONFIG_QDIO_DEBUG
-#define QDIO_DBF_TRACE_PAGES           16
+#define QDIO_DBF_TRACE_PAGES           32
 #define QDIO_DBF_SETUP_LEVEL           6
 #define QDIO_DBF_TRACE_LEVEL           4
 #else /* !CONFIG_QDIO_DEBUG */
-#define QDIO_DBF_TRACE_PAGES           4
+#define QDIO_DBF_TRACE_PAGES           8
 #define QDIO_DBF_SETUP_LEVEL           2
 #define QDIO_DBF_TRACE_LEVEL           2
 #endif /* CONFIG_QDIO_DEBUG */
index d15648514a0f6dd9ef8c9db44088f238f8f377c4..e6eabc853422cc9320c7925099471ec04e48f44b 100644 (file)
@@ -330,6 +330,7 @@ static int qdio_siga_output(struct qdio_q *q)
        int cc;
        u32 busy_bit;
        u64 start_time = 0;
+       char dbf_text[15];
 
        QDIO_DBF_TEXT5(0, trace, "sigaout");
        QDIO_DBF_HEX5(0, trace, &q, sizeof(void *));
@@ -338,6 +339,9 @@ static int qdio_siga_output(struct qdio_q *q)
 again:
        cc = qdio_do_siga_output(q, &busy_bit);
        if (queue_type(q) == QDIO_IQDIO_QFMT && cc == 2 && busy_bit) {
+               sprintf(dbf_text, "bb%4x%2x", q->irq_ptr->schid.sch_no, q->nr);
+               QDIO_DBF_TEXT3(0, trace, dbf_text);
+
                if (!start_time)
                        start_time = get_usecs();
                else if ((get_usecs() - start_time) < QDIO_BUSY_BIT_PATIENCE)
@@ -748,16 +752,18 @@ static void qdio_kick_outbound_q(struct qdio_q *q)
        rc = qdio_siga_output(q);
        switch (rc) {
        case 0:
-               /* went smooth this time, reset timestamp */
-               q->u.out.timestamp = 0;
-
                /* TODO: improve error handling for CC=0 case */
 #ifdef CONFIG_QDIO_DEBUG
-               QDIO_DBF_TEXT3(0, trace, "cc2reslv");
-               sprintf(dbf_text, "%4x%2x%2x", q->irq_ptr->schid.sch_no, q->nr,
-                       atomic_read(&q->u.out.busy_siga_counter));
-               QDIO_DBF_TEXT3(0, trace, dbf_text);
+               if (q->u.out.timestamp) {
+                       QDIO_DBF_TEXT3(0, trace, "cc2reslv");
+                       sprintf(dbf_text, "%4x%2x%2x", q->irq_ptr->schid.sch_no,
+                               q->nr,
+                               atomic_read(&q->u.out.busy_siga_counter));
+                       QDIO_DBF_TEXT3(0, trace, dbf_text);
+               }
 #endif /* CONFIG_QDIO_DEBUG */
+               /* went smooth this time, reset timestamp */
+               q->u.out.timestamp = 0;
                break;
        /* cc=2 and busy bit */
        case (2 | QDIO_ERROR_SIGA_BUSY):
@@ -1066,14 +1072,12 @@ void qdio_int_handler(struct ccw_device *cdev, unsigned long intparm,
        if (IS_ERR(irb)) {
                switch (PTR_ERR(irb)) {
                case -EIO:
-                       sprintf(dbf_text, "ierr%4x",
-                               cdev->private->schid.sch_no);
+                       sprintf(dbf_text, "ierr%4x", irq_ptr->schid.sch_no);
                        QDIO_DBF_TEXT2(1, setup, dbf_text);
                        qdio_int_error(cdev);
                        return;
                case -ETIMEDOUT:
-                       sprintf(dbf_text, "qtoh%4x",
-                               cdev->private->schid.sch_no);
+                       sprintf(dbf_text, "qtoh%4x", irq_ptr->schid.sch_no);
                        QDIO_DBF_TEXT2(1, setup, dbf_text);
                        qdio_int_error(cdev);
                        return;
@@ -1124,8 +1128,10 @@ void qdio_int_handler(struct ccw_device *cdev, unsigned long intparm,
 struct qdio_ssqd_desc *qdio_get_ssqd_desc(struct ccw_device *cdev)
 {
        struct qdio_irq *irq_ptr;
+       char dbf_text[15];
 
-       QDIO_DBF_TEXT0(0, setup, "getssqd");
+       sprintf(dbf_text, "qssq%4x", cdev->private->schid.sch_no);
+       QDIO_DBF_TEXT0(0, setup, dbf_text);
 
        irq_ptr = cdev->private->qdio_data;
        if (!irq_ptr)
@@ -1149,14 +1155,13 @@ int qdio_cleanup(struct ccw_device *cdev, int how)
        char dbf_text[15];
        int rc;
 
+       sprintf(dbf_text, "qcln%4x", cdev->private->schid.sch_no);
+       QDIO_DBF_TEXT0(0, setup, dbf_text);
+
        irq_ptr = cdev->private->qdio_data;
        if (!irq_ptr)
                return -ENODEV;
 
-       sprintf(dbf_text, "qcln%4x", irq_ptr->schid.sch_no);
-       QDIO_DBF_TEXT1(0, trace, dbf_text);
-       QDIO_DBF_TEXT0(0, setup, dbf_text);
-
        rc = qdio_shutdown(cdev, how);
        if (rc == 0)
                rc = qdio_free(cdev);
@@ -1191,6 +1196,9 @@ int qdio_shutdown(struct ccw_device *cdev, int how)
        unsigned long flags;
        char dbf_text[15];
 
+       sprintf(dbf_text, "qshu%4x", cdev->private->schid.sch_no);
+       QDIO_DBF_TEXT0(0, setup, dbf_text);
+
        irq_ptr = cdev->private->qdio_data;
        if (!irq_ptr)
                return -ENODEV;
@@ -1205,10 +1213,6 @@ int qdio_shutdown(struct ccw_device *cdev, int how)
                return 0;
        }
 
-       sprintf(dbf_text, "qsqs%4x", irq_ptr->schid.sch_no);
-       QDIO_DBF_TEXT1(0, trace, dbf_text);
-       QDIO_DBF_TEXT0(0, setup, dbf_text);
-
        tiqdio_remove_input_queues(irq_ptr);
        qdio_shutdown_queues(cdev);
        qdio_shutdown_debug_entries(irq_ptr, cdev);
@@ -1247,7 +1251,6 @@ no_cleanup:
 
        qdio_set_state(irq_ptr, QDIO_IRQ_STATE_INACTIVE);
        mutex_unlock(&irq_ptr->setup_mutex);
-       module_put(THIS_MODULE);
        if (rc)
                return rc;
        return 0;
@@ -1263,16 +1266,14 @@ int qdio_free(struct ccw_device *cdev)
        struct qdio_irq *irq_ptr;
        char dbf_text[15];
 
+       sprintf(dbf_text, "qfre%4x", cdev->private->schid.sch_no);
+       QDIO_DBF_TEXT0(0, setup, dbf_text);
+
        irq_ptr = cdev->private->qdio_data;
        if (!irq_ptr)
                return -ENODEV;
 
        mutex_lock(&irq_ptr->setup_mutex);
-
-       sprintf(dbf_text, "qfqs%4x", irq_ptr->schid.sch_no);
-       QDIO_DBF_TEXT1(0, trace, dbf_text);
-       QDIO_DBF_TEXT0(0, setup, dbf_text);
-
        cdev->private->qdio_data = NULL;
        mutex_unlock(&irq_ptr->setup_mutex);
 
@@ -1295,7 +1296,6 @@ int qdio_initialize(struct qdio_initialize *init_data)
 
        sprintf(dbf_text, "qini%4x", init_data->cdev->private->schid.sch_no);
        QDIO_DBF_TEXT0(0, setup, dbf_text);
-       QDIO_DBF_TEXT0(0, trace, dbf_text);
 
        rc = qdio_allocate(init_data);
        if (rc)
@@ -1319,7 +1319,6 @@ int qdio_allocate(struct qdio_initialize *init_data)
 
        sprintf(dbf_text, "qalc%4x", init_data->cdev->private->schid.sch_no);
        QDIO_DBF_TEXT0(0, setup, dbf_text);
-       QDIO_DBF_TEXT0(0, trace, dbf_text);
 
        if ((init_data->no_input_qs && !init_data->input_handler) ||
            (init_data->no_output_qs && !init_data->output_handler))
@@ -1389,6 +1388,9 @@ int qdio_establish(struct qdio_initialize *init_data)
        unsigned long saveflags;
        int rc;
 
+       sprintf(dbf_text, "qest%4x", cdev->private->schid.sch_no);
+       QDIO_DBF_TEXT0(0, setup, dbf_text);
+
        irq_ptr = cdev->private->qdio_data;
        if (!irq_ptr)
                return -ENODEV;
@@ -1396,13 +1398,6 @@ int qdio_establish(struct qdio_initialize *init_data)
        if (cdev->private->state != DEV_STATE_ONLINE)
                return -EINVAL;
 
-       if (!try_module_get(THIS_MODULE))
-               return -EINVAL;
-
-       sprintf(dbf_text, "qest%4x", cdev->private->schid.sch_no);
-       QDIO_DBF_TEXT0(0, setup, dbf_text);
-       QDIO_DBF_TEXT0(0, trace, dbf_text);
-
        mutex_lock(&irq_ptr->setup_mutex);
        qdio_setup_irq(init_data);
 
@@ -1472,6 +1467,9 @@ int qdio_activate(struct ccw_device *cdev)
        unsigned long saveflags;
        char dbf_text[20];
 
+       sprintf(dbf_text, "qact%4x", cdev->private->schid.sch_no);
+       QDIO_DBF_TEXT0(0, setup, dbf_text);
+
        irq_ptr = cdev->private->qdio_data;
        if (!irq_ptr)
                return -ENODEV;
@@ -1485,10 +1483,6 @@ int qdio_activate(struct ccw_device *cdev)
                goto out;
        }
 
-       sprintf(dbf_text, "qact%4x", irq_ptr->schid.sch_no);
-       QDIO_DBF_TEXT2(0, setup, dbf_text);
-       QDIO_DBF_TEXT2(0, trace, dbf_text);
-
        irq_ptr->ccw.cmd_code = irq_ptr->aqueue.cmd;
        irq_ptr->ccw.flags = CCW_FLAG_SLI;
        irq_ptr->ccw.count = irq_ptr->aqueue.count;
@@ -1663,7 +1657,7 @@ int do_QDIO(struct ccw_device *cdev, unsigned int callflags,
 #ifdef CONFIG_QDIO_DEBUG
        char dbf_text[20];
 
-       sprintf(dbf_text, "doQD%04x", cdev->private->schid.sch_no);
+       sprintf(dbf_text, "doQD%4x", cdev->private->schid.sch_no);
        QDIO_DBF_TEXT3(0, trace, dbf_text);
 #endif /* CONFIG_QDIO_DEBUG */
 
index 1bd2a208db28a3d5a649c3d9a9ea04eebb5390e8..1679e2f91c945eb0164b3d8a813207c9cfd5efbd 100644 (file)
@@ -165,7 +165,7 @@ static void setup_queues(struct qdio_irq *irq_ptr,
        void **output_sbal_array = qdio_init->output_sbal_addr_array;
        int i;
 
-       sprintf(dbf_text, "qfqs%4x", qdio_init->cdev->private->schid.sch_no);
+       sprintf(dbf_text, "qset%4x", qdio_init->cdev->private->schid.sch_no);
        QDIO_DBF_TEXT0(0, setup, dbf_text);
 
        for_each_input_queue(irq_ptr, q, i) {
@@ -285,7 +285,7 @@ void qdio_setup_ssqd_info(struct qdio_irq *irq_ptr)
        rc = __get_ssqd_info(irq_ptr);
        if (rc) {
                QDIO_DBF_TEXT2(0, setup, "ssqdasig");
-               sprintf(dbf_text, "schno%x", irq_ptr->schid.sch_no);
+               sprintf(dbf_text, "schn%4x", irq_ptr->schid.sch_no);
                QDIO_DBF_TEXT2(0, setup, dbf_text);
                sprintf(dbf_text, "rc:%d", rc);
                QDIO_DBF_TEXT2(0, setup, dbf_text);
@@ -447,7 +447,7 @@ void qdio_print_subchannel_info(struct qdio_irq *irq_ptr,
 {
        char s[80];
 
-       sprintf(s, "%s ", cdev->dev.bus_id);
+       sprintf(s, "%s sc:%x ", cdev->dev.bus_id, irq_ptr->schid.sch_no);
 
        switch (irq_ptr->qib.qfmt) {
        case QDIO_QETH_QFMT:
index 9291a771d8123c8cffbb40158322713a1bba33ca..ea7f614002670024f766d887062ff4824029556d 100644 (file)
@@ -113,7 +113,11 @@ void tiqdio_remove_input_queues(struct qdio_irq *irq_ptr)
        struct qdio_q *q;
        int i;
 
-       for_each_input_queue(irq_ptr, q, i) {
+       for (i = 0; i < irq_ptr->nr_input_qs; i++) {
+               q = irq_ptr->input_qs[i];
+               /* if establish triggered an error */
+               if (!q || !q->entry.prev || !q->entry.next)
+                       continue;
                list_del_rcu(&q->entry);
                synchronize_rcu();
        }
index 49ae1cd25caaede02cf3a782c99089ecc43a9061..2de1e2fccbf9f5d5f740143843caf38e0149a833 100644 (file)
@@ -19,7 +19,6 @@
 #undef DEBUGDATA
 #undef DEBUGCCW
 
-#include <linux/version.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
index e7c7b4ebc1fe3c3cebbcce6c1342a2e54145e7f2..2dee69da35cf67f412143dd2c5f190bffcc43cbc 100644 (file)
@@ -376,7 +376,7 @@ static int get_lun(struct scsi_device *sdev, struct rdac_dh_data *h)
                if (inqp->page_id[0] != 'e' || inqp->page_id[1] != 'd' ||
                    inqp->page_id[2] != 'i' || inqp->page_id[3] != 'd')
                        return SCSI_DH_NOSYS;
-               h->lun = scsilun_to_int((struct scsi_lun *)inqp->lun);
+               h->lun = inqp->lun[7]; /* Uses only the last byte */
        }
        return err;
 }
@@ -386,6 +386,7 @@ static int check_ownership(struct scsi_device *sdev, struct rdac_dh_data *h)
        int err;
        struct c9_inquiry *inqp;
 
+       h->lun_state = RDAC_LUN_UNOWNED;
        err = submit_inquiry(sdev, 0xC9, sizeof(struct c9_inquiry), h);
        if (err == SCSI_DH_OK) {
                inqp = &h->inq.c9;
index 19406cea6d6a3800356b5598df151d3c26af47fb..179ad77f6cc9d1039ba9adcea328292c7e72dc22 100644 (file)
@@ -21,7 +21,6 @@
 
 #include <linux/i2o-dev.h>
 
-#include <linux/version.h>
 #include <linux/notifier.h>
 #include <asm/atomic.h>
 
index ae560bc04f9d4df009ad8aef36abfa288dfca2f2..4e0b7c8eb32e731a535b9d2110af3b52f494d78b 100644 (file)
@@ -556,11 +556,12 @@ static void ibmvfc_link_down(struct ibmvfc_host *vhost,
 /**
  * ibmvfc_init_host - Start host initialization
  * @vhost:             ibmvfc host struct
+ * @relogin:   is this a re-login?
  *
  * Return value:
  *     nothing
  **/
-static void ibmvfc_init_host(struct ibmvfc_host *vhost)
+static void ibmvfc_init_host(struct ibmvfc_host *vhost, int relogin)
 {
        struct ibmvfc_target *tgt;
 
@@ -574,6 +575,11 @@ static void ibmvfc_init_host(struct ibmvfc_host *vhost)
        }
 
        if (!ibmvfc_set_host_state(vhost, IBMVFC_INITIALIZING)) {
+               if (!relogin) {
+                       memset(vhost->async_crq.msgs, 0, PAGE_SIZE);
+                       vhost->async_crq.cur = 0;
+               }
+
                list_for_each_entry(tgt, &vhost->targets, queue)
                        tgt->need_login = 1;
                scsi_block_requests(vhost->host);
@@ -1059,9 +1065,10 @@ static void ibmvfc_get_starget_port_id(struct scsi_target *starget)
 static int ibmvfc_wait_while_resetting(struct ibmvfc_host *vhost)
 {
        long timeout = wait_event_timeout(vhost->init_wait_q,
-                                         (vhost->state == IBMVFC_ACTIVE ||
-                                          vhost->state == IBMVFC_HOST_OFFLINE ||
-                                          vhost->state == IBMVFC_LINK_DEAD),
+                                         ((vhost->state == IBMVFC_ACTIVE ||
+                                           vhost->state == IBMVFC_HOST_OFFLINE ||
+                                           vhost->state == IBMVFC_LINK_DEAD) &&
+                                          vhost->action == IBMVFC_HOST_ACTION_NONE),
                                          (init_timeout * HZ));
 
        return timeout ? 0 : -EIO;
@@ -1450,8 +1457,8 @@ static void ibmvfc_scsi_done(struct ibmvfc_event *evt)
        struct ibmvfc_cmd *vfc_cmd = &evt->xfer_iu->cmd;
        struct ibmvfc_fcp_rsp *rsp = &vfc_cmd->rsp;
        struct scsi_cmnd *cmnd = evt->cmnd;
-       int rsp_len = 0;
-       int sense_len = rsp->fcp_sense_len;
+       u32 rsp_len = 0;
+       u32 sense_len = rsp->fcp_sense_len;
 
        if (cmnd) {
                if (vfc_cmd->response_flags & IBMVFC_ADAPTER_RESID_VALID)
@@ -1468,7 +1475,7 @@ static void ibmvfc_scsi_done(struct ibmvfc_event *evt)
                                rsp_len = rsp->fcp_rsp_len;
                        if ((sense_len + rsp_len) > SCSI_SENSE_BUFFERSIZE)
                                sense_len = SCSI_SENSE_BUFFERSIZE - rsp_len;
-                       if ((rsp->flags & FCP_SNS_LEN_VALID) && rsp->fcp_sense_len)
+                       if ((rsp->flags & FCP_SNS_LEN_VALID) && rsp->fcp_sense_len && rsp_len <= 8)
                                memcpy(cmnd->sense_buffer, rsp->data.sense + rsp_len, sense_len);
 
                        ibmvfc_log_error(evt);
@@ -2077,17 +2084,18 @@ static void ibmvfc_handle_async(struct ibmvfc_async_crq *crq,
 {
        const char *desc = ibmvfc_get_ae_desc(crq->event);
 
-       ibmvfc_log(vhost, 3, "%s event received\n", desc);
+       ibmvfc_log(vhost, 3, "%s event received. scsi_id: %lx, wwpn: %lx,"
+                  " node_name: %lx\n", desc, crq->scsi_id, crq->wwpn, crq->node_name);
 
        switch (crq->event) {
        case IBMVFC_AE_LINK_UP:
        case IBMVFC_AE_RESUME:
                vhost->events_to_log |= IBMVFC_AE_LINKUP;
-               ibmvfc_init_host(vhost);
+               ibmvfc_init_host(vhost, 1);
                break;
        case IBMVFC_AE_SCN_FABRIC:
                vhost->events_to_log |= IBMVFC_AE_RSCN;
-               ibmvfc_init_host(vhost);
+               ibmvfc_init_host(vhost, 1);
                break;
        case IBMVFC_AE_SCN_NPORT:
        case IBMVFC_AE_SCN_GROUP:
@@ -2133,13 +2141,13 @@ static void ibmvfc_handle_crq(struct ibmvfc_crq *crq, struct ibmvfc_host *vhost)
                        /* Send back a response */
                        rc = ibmvfc_send_crq_init_complete(vhost);
                        if (rc == 0)
-                               ibmvfc_init_host(vhost);
+                               ibmvfc_init_host(vhost, 0);
                        else
                                dev_err(vhost->dev, "Unable to send init rsp. rc=%ld\n", rc);
                        break;
                case IBMVFC_CRQ_INIT_COMPLETE:
                        dev_info(vhost->dev, "Partner initialization complete\n");
-                       ibmvfc_init_host(vhost);
+                       ibmvfc_init_host(vhost, 0);
                        break;
                default:
                        dev_err(vhost->dev, "Unknown crq message type: %d\n", crq->format);
@@ -3357,8 +3365,6 @@ static void ibmvfc_npiv_login(struct ibmvfc_host *vhost)
        mad->buffer.va = vhost->login_buf_dma;
        mad->buffer.len = sizeof(*vhost->login_buf);
 
-       memset(vhost->async_crq.msgs, 0, PAGE_SIZE);
-       vhost->async_crq.cur = 0;
        ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_INIT_WAIT);
 
        if (!ibmvfc_send_event(evt, vhost, default_timeout))
@@ -3601,8 +3607,9 @@ static void ibmvfc_do_work(struct ibmvfc_host *vhost)
                        }
                }
 
-               if (vhost->reinit) {
+               if (vhost->reinit && !ibmvfc_set_host_state(vhost, IBMVFC_INITIALIZING)) {
                        vhost->reinit = 0;
+                       scsi_block_requests(vhost->host);
                        ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_QUERY);
                } else {
                        ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_NONE);
index 4bf6e374f076b854babc1eae897bd3500cdbed8a..fb3177ab66918382c878fc0289c8bbf4cce9ff95 100644 (file)
@@ -29,8 +29,8 @@
 #include "viosrp.h"
 
 #define IBMVFC_NAME    "ibmvfc"
-#define IBMVFC_DRIVER_VERSION          "1.0.1"
-#define IBMVFC_DRIVER_DATE             "(July 11, 2008)"
+#define IBMVFC_DRIVER_VERSION          "1.0.2"
+#define IBMVFC_DRIVER_DATE             "(August 14, 2008)"
 
 #define IBMVFC_DEFAULT_TIMEOUT 15
 #define IBMVFC_INIT_TIMEOUT            30
index 6b24b9cdb04cda6666837684cd232d271dfc4b10..7b1502c0ab6e5e049a66058be068478ebc5886ec 100644 (file)
@@ -1636,7 +1636,7 @@ static unsigned long ibmvscsi_get_desired_dma(struct vio_dev *vdev)
        unsigned long desired_io = max_requests * sizeof(union viosrp_iu);
 
        /* add io space for sg data */
-       desired_io += (IBMVSCSI_MAX_SECTORS_DEFAULT *
+       desired_io += (IBMVSCSI_MAX_SECTORS_DEFAULT * 512 *
                             IBMVSCSI_CMDS_PER_LUN_DEFAULT);
 
        return desired_io;
index 7c615c70ec5c236f7416f9466f2cd5a920c5e865..bc9e6ddf41df237ec5dd030950d42619174b883e 100644 (file)
 #include <asm/byteorder.h>
 #include <asm/page.h>
 #include <linux/stddef.h>
-#include <linux/version.h>
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <linux/kernel.h>
index e0657b6f009c0b5488a969f43936cf719c9dcbc9..4e49fbcfe8affffe92d9b8830d5f6b6160f7f11d 100644 (file)
@@ -50,7 +50,6 @@
 #ifndef _IPS_H_
    #define _IPS_H_
 
-#include <linux/version.h>
 #include <linux/nmi.h>
    #include <asm/uaccess.h>
    #include <asm/io.h>
index 90272e65957a74569ba1fe7a0df9665668357d1f..094b47e94b299abf9976328eaf4b2b233fd151dd 100644 (file)
@@ -27,7 +27,6 @@
 #include <linux/pci.h>
 #include <linux/spinlock.h>
 #include <linux/ctype.h>
-#include <linux/version.h>
 
 #include <scsi/scsi.h>
 #include <scsi/scsi_device.h>
index fc7ac158476c5d4bc94ecf08a46f1c8604c032ae..97b763378e7dca9e8de4678eeb013f25ac2da185 100644 (file)
@@ -10,7 +10,7 @@
  *        2 of the License, or (at your option) any later version.
  *
  * FILE                : megaraid_sas.c
- * Version     : v00.00.03.20-rc1
+ * Version     : v00.00.04.01-rc1
  *
  * Authors:
  *     (email-id : megaraidlinux@lsi.com)
@@ -71,6 +71,10 @@ static struct pci_device_id megasas_pci_table[] = {
        /* ppc IOP */
        {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1078DE)},
        /* ppc IOP */
+       {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1078GEN2)},
+       /* gen2*/
+       {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS0079GEN2)},
+       /* gen2*/
        {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_VERDE_ZCR)},
        /* xscale IOP, vega */
        {PCI_DEVICE(PCI_VENDOR_ID_DELL, PCI_DEVICE_ID_DELL_PERC5)},
@@ -198,6 +202,9 @@ megasas_clear_intr_xscale(struct megasas_register_set __iomem * regs)
         */
        writel(status, &regs->outbound_intr_status);
 
+       /* Dummy readl to force pci flush */
+       readl(&regs->outbound_intr_status);
+
        return 0;
 }
 
@@ -293,6 +300,9 @@ megasas_clear_intr_ppc(struct megasas_register_set __iomem * regs)
         */
        writel(status, &regs->outbound_doorbell_clear);
 
+       /* Dummy readl to force pci flush */
+       readl(&regs->outbound_doorbell_clear);
+
        return 0;
 }
 /**
@@ -317,6 +327,99 @@ static struct megasas_instance_template megasas_instance_template_ppc = {
        .read_fw_status_reg = megasas_read_fw_status_reg_ppc,
 };
 
+/**
+*      The following functions are defined for gen2 (deviceid : 0x78 0x79)
+*      controllers
+*/
+
+/**
+ * megasas_enable_intr_gen2 -  Enables interrupts
+ * @regs:                      MFI register set
+ */
+static inline void
+megasas_enable_intr_gen2(struct megasas_register_set __iomem *regs)
+{
+       writel(0xFFFFFFFF, &(regs)->outbound_doorbell_clear);
+
+       /* write ~0x00000005 (4 & 1) to the intr mask*/
+       writel(~MFI_GEN2_ENABLE_INTERRUPT_MASK, &(regs)->outbound_intr_mask);
+
+       /* Dummy readl to force pci flush */
+       readl(&regs->outbound_intr_mask);
+}
+
+/**
+ * megasas_disable_intr_gen2 - Disables interrupt
+ * @regs:                      MFI register set
+ */
+static inline void
+megasas_disable_intr_gen2(struct megasas_register_set __iomem *regs)
+{
+       u32 mask = 0xFFFFFFFF;
+       writel(mask, &regs->outbound_intr_mask);
+       /* Dummy readl to force pci flush */
+       readl(&regs->outbound_intr_mask);
+}
+
+/**
+ * megasas_read_fw_status_reg_gen2 - returns the current FW status value
+ * @regs:                      MFI register set
+ */
+static u32
+megasas_read_fw_status_reg_gen2(struct megasas_register_set __iomem *regs)
+{
+       return readl(&(regs)->outbound_scratch_pad);
+}
+
+/**
+ * megasas_clear_interrupt_gen2 -      Check & clear interrupt
+ * @regs:                              MFI register set
+ */
+static int
+megasas_clear_intr_gen2(struct megasas_register_set __iomem *regs)
+{
+       u32 status;
+       /*
+        * Check if it is our interrupt
+        */
+       status = readl(&regs->outbound_intr_status);
+
+       if (!(status & MFI_GEN2_ENABLE_INTERRUPT_MASK))
+               return 1;
+
+       /*
+        * Clear the interrupt by writing back the same value
+        */
+       writel(status, &regs->outbound_doorbell_clear);
+
+       /* Dummy readl to force pci flush */
+       readl(&regs->outbound_intr_status);
+
+       return 0;
+}
+/**
+ * megasas_fire_cmd_gen2 -     Sends command to the FW
+ * @frame_phys_addr :          Physical address of cmd
+ * @frame_count :              Number of frames for the command
+ * @regs :                     MFI register set
+ */
+static inline void
+megasas_fire_cmd_gen2(dma_addr_t frame_phys_addr, u32 frame_count,
+                       struct megasas_register_set __iomem *regs)
+{
+       writel((frame_phys_addr | (frame_count<<1))|1,
+                       &(regs)->inbound_queue_port);
+}
+
+static struct megasas_instance_template megasas_instance_template_gen2 = {
+
+       .fire_cmd = megasas_fire_cmd_gen2,
+       .enable_intr = megasas_enable_intr_gen2,
+       .disable_intr = megasas_disable_intr_gen2,
+       .clear_intr = megasas_clear_intr_gen2,
+       .read_fw_status_reg = megasas_read_fw_status_reg_gen2,
+};
+
 /**
 *      This is the end of set of functions & definitions
 *      specific to ppc (deviceid : 0x60) controllers
@@ -1976,7 +2079,12 @@ static int megasas_init_mfi(struct megasas_instance *instance)
        /*
         * Map the message registers
         */
-       instance->base_addr = pci_resource_start(instance->pdev, 0);
+       if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS1078GEN2) ||
+               (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0079GEN2)) {
+               instance->base_addr = pci_resource_start(instance->pdev, 1);
+       } else {
+               instance->base_addr = pci_resource_start(instance->pdev, 0);
+       }
 
        if (pci_request_regions(instance->pdev, "megasas: LSI")) {
                printk(KERN_DEBUG "megasas: IO memory region busy!\n");
@@ -1998,6 +2106,10 @@ static int megasas_init_mfi(struct megasas_instance *instance)
                case PCI_DEVICE_ID_LSI_SAS1078DE:
                        instance->instancet = &megasas_instance_template_ppc;
                        break;
+               case PCI_DEVICE_ID_LSI_SAS1078GEN2:
+               case PCI_DEVICE_ID_LSI_SAS0079GEN2:
+                       instance->instancet = &megasas_instance_template_gen2;
+                       break;
                case PCI_DEVICE_ID_LSI_SAS1064R:
                case PCI_DEVICE_ID_DELL_PERC5:
                default:
@@ -2857,6 +2969,7 @@ static void megasas_shutdown(struct pci_dev *pdev)
 {
        struct megasas_instance *instance = pci_get_drvdata(pdev);
        megasas_flush_cache(instance);
+       megasas_shutdown_controller(instance, MR_DCMD_CTRL_SHUTDOWN);
 }
 
 /**
@@ -3292,7 +3405,7 @@ megasas_sysfs_set_dbg_lvl(struct device_driver *dd, const char *buf, size_t coun
        return retval;
 }
 
-static DRIVER_ATTR(dbg_lvl, S_IRUGO|S_IWUGO, megasas_sysfs_show_dbg_lvl,
+static DRIVER_ATTR(dbg_lvl, S_IRUGO|S_IWUSR, megasas_sysfs_show_dbg_lvl,
                megasas_sysfs_set_dbg_lvl);
 
 static ssize_t
index b0c41e67170281428b5725437524826a7a10fd6f..0d033248fdf1dffe5cefc162901aec3fcd487b59 100644 (file)
@@ -18,9 +18,9 @@
 /*
  * MegaRAID SAS Driver meta data
  */
-#define MEGASAS_VERSION                        "00.00.03.20-rc1"
-#define MEGASAS_RELDATE                        "March 10, 2008"
-#define MEGASAS_EXT_VERSION            "Mon. March 10 11:02:31 PDT 2008"
+#define MEGASAS_VERSION                                "00.00.04.01"
+#define MEGASAS_RELDATE                                "July 24, 2008"
+#define MEGASAS_EXT_VERSION                    "Thu July 24 11:41:51 PST 2008"
 
 /*
  * Device IDs
@@ -28,6 +28,8 @@
 #define        PCI_DEVICE_ID_LSI_SAS1078R              0x0060
 #define        PCI_DEVICE_ID_LSI_SAS1078DE             0x007C
 #define        PCI_DEVICE_ID_LSI_VERDE_ZCR             0x0413
+#define        PCI_DEVICE_ID_LSI_SAS1078GEN2           0x0078
+#define        PCI_DEVICE_ID_LSI_SAS0079GEN2           0x0079
 
 /*
  * =====================================
@@ -580,6 +582,8 @@ struct megasas_ctrl_info {
 #define MEGASAS_COMPLETION_TIMER_INTERVAL      (HZ/10)
 
 #define MFI_REPLY_1078_MESSAGE_INTERRUPT       0x80000000
+#define MFI_REPLY_GEN2_MESSAGE_INTERRUPT       0x00000001
+#define MFI_GEN2_ENABLE_INTERRUPT_MASK         (0x00000001 | 0x00000004)
 
 /*
 * register set for both 1068 and 1078 controllers
index edf9fdb3cb3c7dda1faa3059defdd66501eefe58..22052bb7becb4023b170f2c6abbf56dea609770d 100644 (file)
@@ -23,7 +23,6 @@
  *   1.2: PowerPC (big endian) support.
  */
 
-#include <linux/version.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
index 6715ecb3bfcaf2f1a3bce11c94b826ac72893979..9565acf1aa729d888d99f347eee5956436bd4960 100644 (file)
@@ -16,7 +16,6 @@
 #ifndef _NSP32_H
 #define _NSP32_H
 
-#include <linux/version.h>
 //#define NSP32_DEBUG 9
 
 /*
index a221b6ef9fa991dac4e685c4e8ac290a6cb50be8..24e6cb8396e35e9bcebe890e9352f1cddc613c80 100644 (file)
@@ -25,7 +25,6 @@
 
 ***********************************************************************/
 
-#include <linux/version.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
index a319a20ed440748da301b5a268941d5e57d00294..45e7dcb4b34d8b276edae17cf56a13c749317fa3 100644 (file)
@@ -993,6 +993,17 @@ qla2x00_terminate_rport_io(struct fc_rport *rport)
 {
        fc_port_t *fcport = *(fc_port_t **)rport->dd_data;
 
+       /*
+        * At this point all fcport's software-states are cleared.  Perform any
+        * final cleanup of firmware resources (PCBs and XCBs).
+        */
+       if (fcport->loop_id != FC_NO_LOOP_ID) {
+               fcport->ha->isp_ops->fabric_logout(fcport->ha, fcport->loop_id,
+                   fcport->d_id.b.domain, fcport->d_id.b.area,
+                   fcport->d_id.b.al_pa);
+               fcport->loop_id = FC_NO_LOOP_ID;
+       }
+
        qla2x00_abort_fcport_cmds(fcport);
        scsi_target_unblock(&rport->dev);
 }
index 6da31ba94404f7bf6b48f418a3ba18829569adb8..94a720eabfd83cc491601ba7b53d5bfef82f4ae2 100644 (file)
@@ -2237,6 +2237,7 @@ typedef struct scsi_qla_host {
 #define REGISTER_FDMI_NEEDED   26
 #define FCPORT_UPDATE_NEEDED   27
 #define VP_DPC_NEEDED          28      /* wake up for VP dpc handling */
+#define UNLOADING              29
 
        uint32_t        device_flags;
 #define DFLG_LOCAL_DEVICES             BIT_0
index 601a6b29750c5beec1d52cc1b5638b396073f7f2..ee89ddd64aae17d7098c3aae9614593f7e2c6e03 100644 (file)
@@ -976,8 +976,9 @@ qla2x00_setup_chip(scsi_qla_host_t *ha)
                                    &ha->fw_attributes, &ha->fw_memory_size);
                                qla2x00_resize_request_q(ha);
                                ha->flags.npiv_supported = 0;
-                               if ((IS_QLA24XX(ha) || IS_QLA25XX(ha)) &&
-                                   (ha->fw_attributes & BIT_2)) {
+                               if ((IS_QLA24XX(ha) || IS_QLA25XX(ha) ||
+                                    IS_QLA84XX(ha)) &&
+                                        (ha->fw_attributes & BIT_2)) {
                                        ha->flags.npiv_supported = 1;
                                        if ((!ha->max_npiv_vports) ||
                                            ((ha->max_npiv_vports + 1) %
@@ -3251,6 +3252,7 @@ qla2x00_abort_isp(scsi_qla_host_t *ha)
 {
        int rval;
        uint8_t        status = 0;
+       scsi_qla_host_t *vha;
 
        if (ha->flags.online) {
                ha->flags.online = 0;
@@ -3265,6 +3267,8 @@ qla2x00_abort_isp(scsi_qla_host_t *ha)
                if (atomic_read(&ha->loop_state) != LOOP_DOWN) {
                        atomic_set(&ha->loop_state, LOOP_DOWN);
                        qla2x00_mark_all_devices_lost(ha, 0);
+                       list_for_each_entry(vha, &ha->vp_list, vp_list)
+                              qla2x00_mark_all_devices_lost(vha, 0);
                } else {
                        if (!atomic_read(&ha->loop_down_timer))
                                atomic_set(&ha->loop_down_timer,
index 874d802edb7de482c79774bd760bdf61a7210ca4..45a3b93eed57aac2617617a79a449df231f51f8f 100644 (file)
@@ -879,11 +879,12 @@ qla2x00_handle_sense(srb_t *sp, uint8_t *sense_data, uint32_t sense_len)
        sp->request_sense_ptr += sense_len;
        sp->request_sense_length -= sense_len;
        if (sp->request_sense_length != 0)
-               sp->ha->status_srb = sp;
+               sp->fcport->ha->status_srb = sp;
 
        DEBUG5(printk("%s(): Check condition Sense data, scsi(%ld:%d:%d:%d) "
-           "cmd=%p pid=%ld\n", __func__, sp->ha->host_no, cp->device->channel,
-           cp->device->id, cp->device->lun, cp, cp->serial_number));
+           "cmd=%p pid=%ld\n", __func__, sp->fcport->ha->host_no,
+           cp->device->channel, cp->device->id, cp->device->lun, cp,
+           cp->serial_number));
        if (sense_len)
                DEBUG5(qla2x00_dump_buffer(cp->sense_buffer,
                    CMD_ACTUAL_SNSLEN(cp)));
@@ -1184,9 +1185,8 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt)
                    atomic_read(&fcport->state)));
 
                cp->result = DID_BUS_BUSY << 16;
-               if (atomic_read(&fcport->state) == FCS_ONLINE) {
-                       qla2x00_mark_device_lost(ha, fcport, 1, 1);
-               }
+               if (atomic_read(&fcport->state) == FCS_ONLINE)
+                       qla2x00_mark_device_lost(fcport->ha, fcport, 1, 1);
                break;
 
        case CS_RESET:
@@ -1229,7 +1229,7 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt)
 
                /* Check to see if logout occurred. */
                if ((le16_to_cpu(sts->status_flags) & SF_LOGOUT_SENT))
-                       qla2x00_mark_device_lost(ha, fcport, 1, 1);
+                       qla2x00_mark_device_lost(fcport->ha, fcport, 1, 1);
                break;
 
        default:
index bc90d6b8d0a0d940bf1114c79c818cebc7ee81c5..813bc7784c0aa8fc6542fbce86ec7e5d8e586662 100644 (file)
@@ -2686,7 +2686,7 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *ha,
                set_bit(VP_IDX_ACQUIRED, &vha->vp_flags);
                set_bit(VP_DPC_NEEDED, &ha->dpc_flags);
 
-               wake_up_process(ha->dpc_thread);
+               qla2xxx_wake_dpc(ha);
        }
 }
 
index 50baf6a1d67cbc732eac8ec5578d36ea20b59fba..93560cd727845d73db00bf635e0c75129697d63e 100644 (file)
@@ -6,7 +6,6 @@
  */
 #include "qla_def.h"
 
-#include <linux/version.h>
 #include <linux/moduleparam.h>
 #include <linux/vmalloc.h>
 #include <linux/smp_lock.h>
index 7c8af7ed2a5dc0d841fa797050d82fd5baefdfb1..26afe44265c794177380eea2b25433d2277761f5 100644 (file)
@@ -780,7 +780,8 @@ qla2x00_eh_wait_for_pending_commands(scsi_qla_host_t *ha, unsigned int t,
                sp = pha->outstanding_cmds[cnt];
                if (!sp)
                        continue;
-               if (ha->vp_idx != sp->ha->vp_idx)
+
+               if (ha->vp_idx != sp->fcport->ha->vp_idx)
                        continue;
                match = 0;
                switch (type) {
@@ -1080,9 +1081,7 @@ qla2x00_abort_all_cmds(scsi_qla_host_t *ha, int res)
                sp = ha->outstanding_cmds[cnt];
                if (sp) {
                        ha->outstanding_cmds[cnt] = NULL;
-                       sp->flags = 0;
                        sp->cmd->result = res;
-                       sp->cmd->host_scribble = (unsigned char *)NULL;
                        qla2x00_sp_compl(ha, sp);
                }
        }
@@ -1776,10 +1775,15 @@ probe_out:
 static void
 qla2x00_remove_one(struct pci_dev *pdev)
 {
-       scsi_qla_host_t *ha;
+       scsi_qla_host_t *ha, *vha, *temp;
 
        ha = pci_get_drvdata(pdev);
 
+       list_for_each_entry_safe(vha, temp, &ha->vp_list, vp_list)
+               fc_vport_terminate(vha->fc_vport);
+
+       set_bit(UNLOADING, &ha->dpc_flags);
+
        qla2x00_dfs_remove(ha);
 
        qla84xx_put_chip(ha);
@@ -2451,8 +2455,10 @@ qla2x00_do_dpc(void *data)
 void
 qla2xxx_wake_dpc(scsi_qla_host_t *ha)
 {
-       if (ha->dpc_thread)
-               wake_up_process(ha->dpc_thread);
+       struct task_struct *t = ha->dpc_thread;
+
+       if (!test_bit(UNLOADING, &ha->dpc_flags) && t)
+               wake_up_process(t);
 }
 
 /*
index 676c390db354c18c58d816154be7d41f3c8811c8..4160e4caa7b97af229f03b74bb472fb7a4dd53b3 100644 (file)
@@ -7,7 +7,7 @@
 /*
  * Driver version
  */
-#define QLA2XXX_VERSION      "8.02.01-k6"
+#define QLA2XXX_VERSION      "8.02.01-k7"
 
 #define QLA_DRIVER_MAJOR_VER   8
 #define QLA_DRIVER_MINOR_VER   2
index d831a2beff393079d9a20686494bf022be1f7651..87ab2443e66d405ec72d45a2da2f120d59e48f0c 100644 (file)
@@ -1165,15 +1165,19 @@ EXPORT_SYMBOL(ssb_dma_translation);
 
 int ssb_dma_set_mask(struct ssb_device *dev, u64 mask)
 {
+#ifdef CONFIG_SSB_PCIHOST
        int err;
+#endif
 
        switch (dev->bus->bustype) {
        case SSB_BUSTYPE_PCI:
+#ifdef CONFIG_SSB_PCIHOST
                err = pci_set_dma_mask(dev->bus->host_pci, mask);
                if (err)
                        return err;
                err = pci_set_consistent_dma_mask(dev->bus->host_pci, mask);
                return err;
+#endif
        case SSB_BUSTYPE_SSB:
                return dma_set_mask(dev->dev, mask);
        default:
@@ -1188,6 +1192,7 @@ void * ssb_dma_alloc_consistent(struct ssb_device *dev, size_t size,
 {
        switch (dev->bus->bustype) {
        case SSB_BUSTYPE_PCI:
+#ifdef CONFIG_SSB_PCIHOST
                if (gfp_flags & GFP_DMA) {
                        /* Workaround: The PCI API does not support passing
                         * a GFP flag. */
@@ -1195,6 +1200,7 @@ void * ssb_dma_alloc_consistent(struct ssb_device *dev, size_t size,
                                                  size, dma_handle, gfp_flags);
                }
                return pci_alloc_consistent(dev->bus->host_pci, size, dma_handle);
+#endif
        case SSB_BUSTYPE_SSB:
                return dma_alloc_coherent(dev->dev, size, dma_handle, gfp_flags);
        default:
@@ -1210,6 +1216,7 @@ void ssb_dma_free_consistent(struct ssb_device *dev, size_t size,
 {
        switch (dev->bus->bustype) {
        case SSB_BUSTYPE_PCI:
+#ifdef CONFIG_SSB_PCIHOST
                if (gfp_flags & GFP_DMA) {
                        /* Workaround: The PCI API does not support passing
                         * a GFP flag. */
@@ -1220,6 +1227,7 @@ void ssb_dma_free_consistent(struct ssb_device *dev, size_t size,
                pci_free_consistent(dev->bus->host_pci, size,
                                    vaddr, dma_handle);
                return;
+#endif
        case SSB_BUSTYPE_SSB:
                dma_free_coherent(dev->dev, size, vaddr, dma_handle);
                return;
index 2e9079df26b3a2ebd67e633295167389d380ae81..4190be64917f416be6f4809929bf0e23b78a755d 100644 (file)
@@ -33,6 +33,19 @@ config UIO_PDRV
 
          If you don't know what to do here, say N.
 
+config UIO_PDRV_GENIRQ
+       tristate "Userspace I/O platform driver with generic IRQ handling"
+       help
+         Platform driver for Userspace I/O devices, including generic
+         interrupt handling code. Shared interrupts are not supported.
+
+         This kernel driver requires that the matching userspace driver
+         handles interrupts in a special way. Userspace is responsible
+         for acknowledging the hardware device if needed, and re-enabling
+         interrupts in the interrupt controller using the write() syscall.
+
+         If you don't know what to do here, say N.
+
 config UIO_SMX
        tristate "SMX cryptengine UIO interface"
        default n
index e00ce0def1a02898d0b197c2c593f8344bb989b7..8667bbdef904fc3ddd2df2d1208938f5fdcc2a7e 100644 (file)
@@ -1,4 +1,5 @@
 obj-$(CONFIG_UIO)      += uio.o
 obj-$(CONFIG_UIO_CIF)  += uio_cif.o
 obj-$(CONFIG_UIO_PDRV) += uio_pdrv.o
+obj-$(CONFIG_UIO_PDRV_GENIRQ)  += uio_pdrv_genirq.o
 obj-$(CONFIG_UIO_SMX)  += uio_smx.o
index 5d0d2e85d9820ed70c48b900c262d7ff1c44f393..0b4ef39cd85d289d3aee60264dd6044bee1f0b8b 100644 (file)
@@ -88,6 +88,8 @@ static int uio_pdrv_remove(struct platform_device *pdev)
 
        uio_unregister_device(pdata->uioinfo);
 
+       kfree(pdata);
+
        return 0;
 }
 
@@ -114,5 +116,5 @@ module_exit(uio_pdrv_exit);
 
 MODULE_AUTHOR("Uwe Kleine-Koenig");
 MODULE_DESCRIPTION("Userspace I/O platform driver");
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
 MODULE_ALIAS("platform:" DRIVER_NAME);
diff --git a/drivers/uio/uio_pdrv_genirq.c b/drivers/uio/uio_pdrv_genirq.c
new file mode 100644 (file)
index 0000000..1f82c83
--- /dev/null
@@ -0,0 +1,188 @@
+/*
+ * drivers/uio/uio_pdrv_genirq.c
+ *
+ * Userspace I/O platform driver with generic IRQ handling code.
+ *
+ * Copyright (C) 2008 Magnus Damm
+ *
+ * Based on uio_pdrv.c by Uwe Kleine-Koenig,
+ * Copyright (C) 2008 by Digi International Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/uio_driver.h>
+#include <linux/spinlock.h>
+#include <linux/bitops.h>
+#include <linux/interrupt.h>
+#include <linux/stringify.h>
+
+#define DRIVER_NAME "uio_pdrv_genirq"
+
+struct uio_pdrv_genirq_platdata {
+       struct uio_info *uioinfo;
+       spinlock_t lock;
+       unsigned long flags;
+};
+
+static irqreturn_t uio_pdrv_genirq_handler(int irq, struct uio_info *dev_info)
+{
+       struct uio_pdrv_genirq_platdata *priv = dev_info->priv;
+
+       /* Just disable the interrupt in the interrupt controller, and
+        * remember the state so we can allow user space to enable it later.
+        */
+
+       if (!test_and_set_bit(0, &priv->flags))
+               disable_irq_nosync(irq);
+
+       return IRQ_HANDLED;
+}
+
+static int uio_pdrv_genirq_irqcontrol(struct uio_info *dev_info, s32 irq_on)
+{
+       struct uio_pdrv_genirq_platdata *priv = dev_info->priv;
+       unsigned long flags;
+
+       /* Allow user space to enable and disable the interrupt
+        * in the interrupt controller, but keep track of the
+        * state to prevent per-irq depth damage.
+        *
+        * Serialize this operation to support multiple tasks.
+        */
+
+       spin_lock_irqsave(&priv->lock, flags);
+       if (irq_on) {
+               if (test_and_clear_bit(0, &priv->flags))
+                       enable_irq(dev_info->irq);
+       } else {
+               if (!test_and_set_bit(0, &priv->flags))
+                       disable_irq(dev_info->irq);
+       }
+       spin_unlock_irqrestore(&priv->lock, flags);
+
+       return 0;
+}
+
+static int uio_pdrv_genirq_probe(struct platform_device *pdev)
+{
+       struct uio_info *uioinfo = pdev->dev.platform_data;
+       struct uio_pdrv_genirq_platdata *priv;
+       struct uio_mem *uiomem;
+       int ret = -EINVAL;
+       int i;
+
+       if (!uioinfo || !uioinfo->name || !uioinfo->version) {
+               dev_err(&pdev->dev, "missing platform_data\n");
+               goto bad0;
+       }
+
+       if (uioinfo->handler || uioinfo->irqcontrol || uioinfo->irq_flags) {
+               dev_err(&pdev->dev, "interrupt configuration error\n");
+               goto bad0;
+       }
+
+       priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+       if (!priv) {
+               ret = -ENOMEM;
+               dev_err(&pdev->dev, "unable to kmalloc\n");
+               goto bad0;
+       }
+
+       priv->uioinfo = uioinfo;
+       spin_lock_init(&priv->lock);
+       priv->flags = 0; /* interrupt is enabled to begin with */
+
+       uiomem = &uioinfo->mem[0];
+
+       for (i = 0; i < pdev->num_resources; ++i) {
+               struct resource *r = &pdev->resource[i];
+
+               if (r->flags != IORESOURCE_MEM)
+                       continue;
+
+               if (uiomem >= &uioinfo->mem[MAX_UIO_MAPS]) {
+                       dev_warn(&pdev->dev, "device has more than "
+                                       __stringify(MAX_UIO_MAPS)
+                                       " I/O memory resources.\n");
+                       break;
+               }
+
+               uiomem->memtype = UIO_MEM_PHYS;
+               uiomem->addr = r->start;
+               uiomem->size = r->end - r->start + 1;
+               ++uiomem;
+       }
+
+       while (uiomem < &uioinfo->mem[MAX_UIO_MAPS]) {
+               uiomem->size = 0;
+               ++uiomem;
+       }
+
+       /* This driver requires no hardware specific kernel code to handle
+        * interrupts. Instead, the interrupt handler simply disables the
+        * interrupt in the interrupt controller. User space is responsible
+        * for performing hardware specific acknowledge and re-enabling of
+        * the interrupt in the interrupt controller.
+        *
+        * Interrupt sharing is not supported.
+        */
+
+       uioinfo->irq_flags = IRQF_DISABLED;
+       uioinfo->handler = uio_pdrv_genirq_handler;
+       uioinfo->irqcontrol = uio_pdrv_genirq_irqcontrol;
+       uioinfo->priv = priv;
+
+       ret = uio_register_device(&pdev->dev, priv->uioinfo);
+       if (ret) {
+               dev_err(&pdev->dev, "unable to register uio device\n");
+               goto bad1;
+       }
+
+       platform_set_drvdata(pdev, priv);
+       return 0;
+ bad1:
+       kfree(priv);
+ bad0:
+       return ret;
+}
+
+static int uio_pdrv_genirq_remove(struct platform_device *pdev)
+{
+       struct uio_pdrv_genirq_platdata *priv = platform_get_drvdata(pdev);
+
+       uio_unregister_device(priv->uioinfo);
+       kfree(priv);
+       return 0;
+}
+
+static struct platform_driver uio_pdrv_genirq = {
+       .probe = uio_pdrv_genirq_probe,
+       .remove = uio_pdrv_genirq_remove,
+       .driver = {
+               .name = DRIVER_NAME,
+               .owner = THIS_MODULE,
+       },
+};
+
+static int __init uio_pdrv_genirq_init(void)
+{
+       return platform_driver_register(&uio_pdrv_genirq);
+}
+
+static void __exit uio_pdrv_genirq_exit(void)
+{
+       platform_driver_unregister(&uio_pdrv_genirq);
+}
+
+module_init(uio_pdrv_genirq_init);
+module_exit(uio_pdrv_genirq_exit);
+
+MODULE_AUTHOR("Magnus Damm");
+MODULE_DESCRIPTION("Userspace I/O platform driver with generic IRQ handling");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:" DRIVER_NAME);
index cb01b5106efd0b0b7c7e9f04d61488392adef34b..b6483dd98acc46e8e3f82648c6b40d54f45f41dd 100644 (file)
@@ -64,7 +64,6 @@
 #include <linux/ctype.h>
 #include <linux/sched.h>
 #include <linux/kthread.h>
-#include <linux/version.h>
 #include <linux/mutex.h>
 #include <linux/freezer.h>
 
index efc4373ededb4ea1f15a31f8c32716f1333be6a2..c257453fa9dec42ea864b6cbd89dbd6a3cab5781 100644 (file)
@@ -589,8 +589,8 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp)
        tasklet_schedule(&acm->urb_task);
 
 done:
-err_out:
        mutex_unlock(&acm->mutex);
+err_out:
        mutex_unlock(&open_mutex);
        return rv;
 
@@ -1362,6 +1362,9 @@ static struct usb_device_id acm_ids[] = {
        { USB_DEVICE(0x0803, 0x3095), /* Zoom Telephonics Model 3095F USB MODEM */
        .driver_info = NO_UNION_NORMAL, /* has no union descriptor */
        },
+       { USB_DEVICE(0x0572, 0x1321), /* Conexant USB MODEM CX93010 */
+       .driver_info = NO_UNION_NORMAL, /* has no union descriptor */
+       },
 
        /* control interfaces with various AT-command sets */
        { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM,
index 2be37fe466f2f56d5d2adfbd94ebd3ec5ba2cd6f..5a7fa6f099584206536c40b21dde9117b79cd5e1 100644 (file)
@@ -230,6 +230,13 @@ static int usb_probe_interface(struct device *dev)
                 */
                intf->pm_usage_cnt = !(driver->supports_autosuspend);
 
+               /* Carry out a deferred switch to altsetting 0 */
+               if (intf->needs_altsetting0) {
+                       usb_set_interface(udev, intf->altsetting[0].
+                                       desc.bInterfaceNumber, 0);
+                       intf->needs_altsetting0 = 0;
+               }
+
                error = driver->probe(intf, id);
                if (error) {
                        mark_quiesced(intf);
@@ -266,8 +273,17 @@ static int usb_unbind_interface(struct device *dev)
 
        driver->disconnect(intf);
 
-       /* reset other interface state */
-       usb_set_interface(udev, intf->altsetting[0].desc.bInterfaceNumber, 0);
+       /* Reset other interface state.
+        * We cannot do a Set-Interface if the device is suspended or
+        * if it is prepared for a system sleep (since installing a new
+        * altsetting means creating new endpoint device entries).
+        * When either of these happens, defer the Set-Interface.
+        */
+       if (!error && intf->dev.power.status == DPM_ON)
+               usb_set_interface(udev, intf->altsetting[0].
+                               desc.bInterfaceNumber, 0);
+       else
+               intf->needs_altsetting0 = 1;
        usb_set_intfdata(intf, NULL);
 
        intf->condition = USB_INTERFACE_UNBOUND;
@@ -798,7 +814,8 @@ void usb_forced_unbind_intf(struct usb_interface *intf)
  * The caller must hold @intf's device's lock, but not its pm_mutex
  * and not @intf->dev.sem.
  *
- * FIXME: The caller must block system sleep transitions.
+ * Note: Rebinds will be skipped if a system sleep transition is in
+ * progress and the PM "complete" callback hasn't occurred yet.
  */
 void usb_rebind_intf(struct usb_interface *intf)
 {
@@ -814,10 +831,12 @@ void usb_rebind_intf(struct usb_interface *intf)
        }
 
        /* Try to rebind the interface */
-       intf->needs_binding = 0;
-       rc = device_attach(&intf->dev);
-       if (rc < 0)
-               dev_warn(&intf->dev, "rebind failed: %d\n", rc);
+       if (intf->dev.power.status == DPM_ON) {
+               intf->needs_binding = 0;
+               rc = device_attach(&intf->dev);
+               if (rc < 0)
+                       dev_warn(&intf->dev, "rebind failed: %d\n", rc);
+       }
 }
 
 #ifdef CONFIG_PM
@@ -829,7 +848,6 @@ void usb_rebind_intf(struct usb_interface *intf)
  * or rebind interfaces that have been unbound, according to @action.
  *
  * The caller must hold @udev's device lock.
- * FIXME: For rebinds, the caller must block system sleep transitions.
  */
 static void do_unbind_rebind(struct usb_device *udev, int action)
 {
@@ -851,22 +869,8 @@ static void do_unbind_rebind(struct usb_device *udev, int action)
                                }
                                break;
                        case DO_REBIND:
-                               if (intf->needs_binding) {
-
-       /* FIXME: The next line is needed because we are going to probe
-        * the interface, but as far as the PM core is concerned the
-        * interface is still suspended.  The problem wouldn't exist
-        * if we could rebind the interface during the interface's own
-        * resume() call, but at the time the usb_device isn't locked!
-        *
-        * The real solution will be to carry this out during the device's
-        * complete() callback.  Until that is implemented, we have to
-        * use this hack.
-        */
-//                                     intf->dev.power.sleeping = 0;
-
+                               if (intf->needs_binding)
                                        usb_rebind_intf(intf);
-                               }
                                break;
                        }
                }
@@ -926,14 +930,14 @@ static int usb_resume_device(struct usb_device *udev)
 }
 
 /* Caller has locked intf's usb_device's pm mutex */
-static int usb_suspend_interface(struct usb_interface *intf, pm_message_t msg)
+static int usb_suspend_interface(struct usb_device *udev,
+               struct usb_interface *intf, pm_message_t msg)
 {
        struct usb_driver       *driver;
        int                     status = 0;
 
        /* with no hardware, USB interfaces only use FREEZE and ON states */
-       if (interface_to_usbdev(intf)->state == USB_STATE_NOTATTACHED ||
-                       !is_active(intf))
+       if (udev->state == USB_STATE_NOTATTACHED || !is_active(intf))
                goto done;
 
        if (intf->condition == USB_INTERFACE_UNBOUND)   /* This can't happen */
@@ -944,7 +948,7 @@ static int usb_suspend_interface(struct usb_interface *intf, pm_message_t msg)
                status = driver->suspend(intf, msg);
                if (status == 0)
                        mark_quiesced(intf);
-               else if (!interface_to_usbdev(intf)->auto_pm)
+               else if (!udev->auto_pm)
                        dev_err(&intf->dev, "%s error %d\n",
                                        "suspend", status);
        } else {
@@ -961,13 +965,13 @@ static int usb_suspend_interface(struct usb_interface *intf, pm_message_t msg)
 }
 
 /* Caller has locked intf's usb_device's pm_mutex */
-static int usb_resume_interface(struct usb_interface *intf, int reset_resume)
+static int usb_resume_interface(struct usb_device *udev,
+               struct usb_interface *intf, int reset_resume)
 {
        struct usb_driver       *driver;
        int                     status = 0;
 
-       if (interface_to_usbdev(intf)->state == USB_STATE_NOTATTACHED ||
-                       is_active(intf))
+       if (udev->state == USB_STATE_NOTATTACHED || is_active(intf))
                goto done;
 
        /* Don't let autoresume interfere with unbinding */
@@ -975,8 +979,17 @@ static int usb_resume_interface(struct usb_interface *intf, int reset_resume)
                goto done;
 
        /* Can't resume it if it doesn't have a driver. */
-       if (intf->condition == USB_INTERFACE_UNBOUND)
+       if (intf->condition == USB_INTERFACE_UNBOUND) {
+
+               /* Carry out a deferred switch to altsetting 0 */
+               if (intf->needs_altsetting0 &&
+                               intf->dev.power.status == DPM_ON) {
+                       usb_set_interface(udev, intf->altsetting[0].
+                                       desc.bInterfaceNumber, 0);
+                       intf->needs_altsetting0 = 0;
+               }
                goto done;
+       }
 
        /* Don't resume if the interface is marked for rebinding */
        if (intf->needs_binding)
@@ -1151,7 +1164,7 @@ static int usb_suspend_both(struct usb_device *udev, pm_message_t msg)
        if (udev->actconfig) {
                for (; i < udev->actconfig->desc.bNumInterfaces; i++) {
                        intf = udev->actconfig->interface[i];
-                       status = usb_suspend_interface(intf, msg);
+                       status = usb_suspend_interface(udev, intf, msg);
                        if (status != 0)
                                break;
                }
@@ -1163,7 +1176,7 @@ static int usb_suspend_both(struct usb_device *udev, pm_message_t msg)
        if (status != 0) {
                while (--i >= 0) {
                        intf = udev->actconfig->interface[i];
-                       usb_resume_interface(intf, 0);
+                       usb_resume_interface(udev, intf, 0);
                }
 
                /* Try another autosuspend when the interfaces aren't busy */
@@ -1276,7 +1289,7 @@ static int usb_resume_both(struct usb_device *udev)
        if (status == 0 && udev->actconfig) {
                for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) {
                        intf = udev->actconfig->interface[i];
-                       usb_resume_interface(intf, udev->reset_resume);
+                       usb_resume_interface(udev, intf, udev->reset_resume);
                }
        }
 
@@ -1605,12 +1618,10 @@ int usb_external_resume_device(struct usb_device *udev)
        return status;
 }
 
-static int usb_suspend(struct device *dev, pm_message_t message)
+int usb_suspend(struct device *dev, pm_message_t message)
 {
        struct usb_device       *udev;
 
-       if (!is_usb_device(dev))        /* Ignore PM for interfaces */
-               return 0;
        udev = to_usb_device(dev);
 
        /* If udev is already suspended, we can skip this suspend and
@@ -1629,12 +1640,10 @@ static int usb_suspend(struct device *dev, pm_message_t message)
        return usb_external_suspend_device(udev, message);
 }
 
-static int usb_resume(struct device *dev)
+int usb_resume(struct device *dev)
 {
        struct usb_device       *udev;
 
-       if (!is_usb_device(dev))        /* Ignore PM for interfaces */
-               return 0;
        udev = to_usb_device(dev);
 
        /* If udev->skip_sys_resume is set then udev was already suspended
@@ -1646,17 +1655,10 @@ static int usb_resume(struct device *dev)
        return usb_external_resume_device(udev);
 }
 
-#else
-
-#define usb_suspend    NULL
-#define usb_resume     NULL
-
 #endif /* CONFIG_PM */
 
 struct bus_type usb_bus_type = {
        .name =         "usb",
        .match =        usb_device_match,
        .uevent =       usb_uevent,
-       .suspend =      usb_suspend,
-       .resume =       usb_resume,
 };
index f7bfd72ef115bae2855e05c9b622ff41588477b1..8abd4e59bf4abac0bb2edcee5385894f42310e98 100644 (file)
@@ -924,15 +924,6 @@ static int register_root_hub(struct usb_hcd *hcd)
        return retval;
 }
 
-void usb_enable_root_hub_irq (struct usb_bus *bus)
-{
-       struct usb_hcd *hcd;
-
-       hcd = container_of (bus, struct usb_hcd, self);
-       if (hcd->driver->hub_irq_enable && hcd->state != HC_STATE_HALT)
-               hcd->driver->hub_irq_enable (hcd);
-}
-
 
 /*-------------------------------------------------------------------------*/
 
index 5b0b59b0d89b37709da23af08cf0271c193d9ebf..e710ce04e228f94647908d789500a4e2b8a646f9 100644 (file)
@@ -212,8 +212,6 @@ struct hc_driver {
        int     (*bus_suspend)(struct usb_hcd *);
        int     (*bus_resume)(struct usb_hcd *);
        int     (*start_port_reset)(struct usb_hcd *, unsigned port_num);
-       void    (*hub_irq_enable)(struct usb_hcd *);
-               /* Needed only if port-change IRQs are level-triggered */
 
                /* force handover of high-speed port to full-speed companion */
        void    (*relinquish_port)(struct usb_hcd *, int);
@@ -379,8 +377,6 @@ extern struct list_head usb_bus_list;
 extern struct mutex usb_bus_list_lock;
 extern wait_queue_head_t usb_kill_urb_queue;
 
-extern void usb_enable_root_hub_irq(struct usb_bus *bus);
-
 extern int usb_find_interface_driver(struct usb_device *dev,
        struct usb_interface *interface);
 
index 107e1d25ddec3fbe0a485191131dad985342c8ff..6a5cb018383d538a2b504429183be99e112c6a5b 100644 (file)
@@ -2102,8 +2102,6 @@ int usb_port_resume(struct usb_device *udev)
        }
 
        clear_bit(port1, hub->busy_bits);
-       if (!hub->hdev->parent && !hub->busy_bits[0])
-               usb_enable_root_hub_irq(hub->hdev->bus);
 
        status = check_port_resume_type(udev,
                        hub, port1, status, portchange, portstatus);
@@ -3081,11 +3079,6 @@ static void hub_events(void)
                        }
                }
 
-               /* If this is a root hub, tell the HCD it's okay to
-                * re-enable port-change interrupts now. */
-               if (!hdev->parent && !hub->busy_bits[0])
-                       usb_enable_root_hub_irq(hdev->bus);
-
 loop_autopm:
                /* Allow autosuspend if we're not going to run again */
                if (list_empty(&hub->event_list))
@@ -3311,8 +3304,6 @@ static int usb_reset_and_verify_device(struct usb_device *udev)
                        break;
        }
        clear_bit(port1, parent_hub->busy_bits);
-       if (!parent_hdev->parent && !parent_hub->busy_bits[0])
-               usb_enable_root_hub_irq(parent_hdev->bus);
 
        if (ret < 0)
                goto re_enumerate;
index c0b1ae25ae2a8923cf463bd670f3873acaf87102..47111e88f791ad748956d4cbae7317145cfd8927 100644 (file)
@@ -601,15 +601,20 @@ EXPORT_SYMBOL_GPL(usb_kill_anchored_urbs);
 void usb_unlink_anchored_urbs(struct usb_anchor *anchor)
 {
        struct urb *victim;
+       unsigned long flags;
 
-       spin_lock_irq(&anchor->lock);
+       spin_lock_irqsave(&anchor->lock, flags);
        while (!list_empty(&anchor->urb_list)) {
                victim = list_entry(anchor->urb_list.prev, struct urb,
                                    anchor_list);
+               usb_get_urb(victim);
+               spin_unlock_irqrestore(&anchor->lock, flags);
                /* this will unanchor the URB */
                usb_unlink_urb(victim);
+               usb_put_urb(victim);
+               spin_lock_irqsave(&anchor->lock, flags);
        }
-       spin_unlock_irq(&anchor->lock);
+       spin_unlock_irqrestore(&anchor->lock, flags);
 }
 EXPORT_SYMBOL_GPL(usb_unlink_anchored_urbs);
 
index 84fcaa6a21ec285e85ab309bfc0b4be728f62caa..be1fa0723f2c662a058040e8878e7ffb5c12c3df 100644 (file)
@@ -219,12 +219,6 @@ static int usb_dev_uevent(struct device *dev, struct kobj_uevent_env *env)
 }
 #endif /* CONFIG_HOTPLUG */
 
-struct device_type usb_device_type = {
-       .name =         "usb_device",
-       .release =      usb_release_dev,
-       .uevent =       usb_dev_uevent,
-};
-
 #ifdef CONFIG_PM
 
 static int ksuspend_usb_init(void)
@@ -244,13 +238,80 @@ static void ksuspend_usb_cleanup(void)
        destroy_workqueue(ksuspend_usb_wq);
 }
 
+/* USB device Power-Management thunks.
+ * There's no need to distinguish here between quiescing a USB device
+ * and powering it down; the generic_suspend() routine takes care of
+ * it by skipping the usb_port_suspend() call for a quiesce.  And for
+ * USB interfaces there's no difference at all.
+ */
+
+static int usb_dev_prepare(struct device *dev)
+{
+       return 0;               /* Implement eventually? */
+}
+
+static void usb_dev_complete(struct device *dev)
+{
+       /* Currently used only for rebinding interfaces */
+       usb_resume(dev);        /* Implement eventually? */
+}
+
+static int usb_dev_suspend(struct device *dev)
+{
+       return usb_suspend(dev, PMSG_SUSPEND);
+}
+
+static int usb_dev_resume(struct device *dev)
+{
+       return usb_resume(dev);
+}
+
+static int usb_dev_freeze(struct device *dev)
+{
+       return usb_suspend(dev, PMSG_FREEZE);
+}
+
+static int usb_dev_thaw(struct device *dev)
+{
+       return usb_resume(dev);
+}
+
+static int usb_dev_poweroff(struct device *dev)
+{
+       return usb_suspend(dev, PMSG_HIBERNATE);
+}
+
+static int usb_dev_restore(struct device *dev)
+{
+       return usb_resume(dev);
+}
+
+static struct pm_ops usb_device_pm_ops = {
+       .prepare =      usb_dev_prepare,
+       .complete =     usb_dev_complete,
+       .suspend =      usb_dev_suspend,
+       .resume =       usb_dev_resume,
+       .freeze =       usb_dev_freeze,
+       .thaw =         usb_dev_thaw,
+       .poweroff =     usb_dev_poweroff,
+       .restore =      usb_dev_restore,
+};
+
 #else
 
 #define ksuspend_usb_init()    0
 #define ksuspend_usb_cleanup() do {} while (0)
+#define usb_device_pm_ops      (*(struct pm_ops *)0)
 
 #endif /* CONFIG_PM */
 
+struct device_type usb_device_type = {
+       .name =         "usb_device",
+       .release =      usb_release_dev,
+       .uevent =       usb_dev_uevent,
+       .pm =           &usb_device_pm_ops,
+};
+
 
 /* Returns 1 if @usb_bus is WUSB, 0 otherwise */
 static unsigned usb_bus_is_wusb(struct usb_bus *bus)
index d9a6e16dbf842fbb645117eb57093b429ce9c6e0..9a1a45ac3add0ba9ab582d713a6341ee6df311c7 100644 (file)
@@ -41,6 +41,9 @@ extern void usb_host_cleanup(void);
 
 #ifdef CONFIG_PM
 
+extern int usb_suspend(struct device *dev, pm_message_t msg);
+extern int usb_resume(struct device *dev);
+
 extern void usb_autosuspend_work(struct work_struct *work);
 extern int usb_port_suspend(struct usb_device *dev);
 extern int usb_port_resume(struct usb_device *dev);
index 1500e1b3c30289af26bdc9400c59845129aaa9d1..abf8192f89e845696c6e1a32df16db86e926e387 100644 (file)
@@ -44,7 +44,6 @@
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/kernel.h>
-#include <linux/version.h>
 #include <linux/delay.h>
 #include <linux/ioport.h>
 #include <linux/sched.h>
index a28513ecbe5bd3de7c675a6a7c9afb99246f63ec..7cbc78a6853d846689b000842cf264466a67dedc 100644 (file)
@@ -1622,7 +1622,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
        struct pxa_udc *udc = the_controller;
        int retval;
 
-       if (!driver || driver->speed != USB_SPEED_FULL || !driver->bind
+       if (!driver || driver->speed < USB_SPEED_FULL || !driver->bind
                        || !driver->disconnect || !driver->setup)
                return -EINVAL;
        if (!udc)
index 538807384592cc76905e2f6134227a5a5e88c99e..29d13ebe7500bf482745c5cadf35972ca02ffea3 100644 (file)
@@ -35,7 +35,6 @@
 #include <linux/list.h>
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
-#include <linux/version.h>
 #include <linux/clk.h>
 
 #include <linux/debugfs.h>
index d22a84f86a33755a3749f275cd49e031ee14ac06..8017f1cf78e244b0f37c4a32d2833de3d2d2a586 100644 (file)
@@ -988,7 +988,7 @@ static void do_atl_int(struct usb_hcd *usb_hcd)
                /*
                 * write bank1 address twice to ensure the 90ns delay (time
                 * between BANK0 write and the priv_read_copy() call is at
-                * least 3*t_WHWL + 2*t_w11 = 3*25ns + 2*17ns = 92ns)
+                * least 3*t_WHWL + 2*t_w11 = 3*25ns + 2*17ns = 109ns)
                 */
                isp1760_writel(payload  + ISP_BANK(1), usb_hcd->regs +
                                HC_MEMORY_REG);
index 6db7a2889e6648f50344d4d42e3a2c04d332a91b..4ed228a899435a91bc1428daa37a9eb54f283b14 100644 (file)
@@ -260,7 +260,6 @@ static const struct hc_driver ohci_at91_hc_driver = {
         */
        .hub_status_data =      ohci_hub_status_data,
        .hub_control =          ohci_hub_control,
-       .hub_irq_enable =       ohci_rhsc_enable,
 #ifdef CONFIG_PM
        .bus_suspend =          ohci_bus_suspend,
        .bus_resume =           ohci_bus_resume,
index c0948008fe3d17c068c47d83b768b2e7fc365bff..2ac4e022a13f6fc68c6ea32702f1bab05713b88a 100644 (file)
@@ -163,7 +163,6 @@ static const struct hc_driver ohci_au1xxx_hc_driver = {
         */
        .hub_status_data =      ohci_hub_status_data,
        .hub_control =          ohci_hub_control,
-       .hub_irq_enable =       ohci_rhsc_enable,
 #ifdef CONFIG_PM
        .bus_suspend =          ohci_bus_suspend,
        .bus_resume =           ohci_bus_resume,
index cb0b506f8259b20237854bfaae4f9b290223b82a..fb3055f084b5f1a89aaf30efe19cd643b9ddef85 100644 (file)
@@ -134,7 +134,6 @@ static struct hc_driver ohci_ep93xx_hc_driver = {
        .get_frame_number       = ohci_get_frame,
        .hub_status_data        = ohci_hub_status_data,
        .hub_control            = ohci_hub_control,
-       .hub_irq_enable         = ohci_rhsc_enable,
 #ifdef CONFIG_PM
        .bus_suspend            = ohci_bus_suspend,
        .bus_resume             = ohci_bus_resume,
index 439beb784f3e1eb42495d4a323288a56d5eea02d..7ea9a7b311554199f4e5f97ba060cc853786f2f0 100644 (file)
 
 /*-------------------------------------------------------------------------*/
 
-/* hcd->hub_irq_enable() */
-static void ohci_rhsc_enable (struct usb_hcd *hcd)
-{
-       struct ohci_hcd         *ohci = hcd_to_ohci (hcd);
-
-       spin_lock_irq(&ohci->lock);
-       if (!ohci->autostop)
-               del_timer(&hcd->rh_timer);      /* Prevent next poll */
-       ohci_writel(ohci, OHCI_INTR_RHSC, &ohci->regs->intrenable);
-       spin_unlock_irq(&ohci->lock);
-}
-
 #define OHCI_SCHED_ENABLES \
        (OHCI_CTRL_CLE|OHCI_CTRL_BLE|OHCI_CTRL_PLE|OHCI_CTRL_IE)
 
@@ -374,18 +362,28 @@ static int ohci_root_hub_state_changes(struct ohci_hcd *ohci, int changed,
                int any_connected)
 {
        int     poll_rh = 1;
+       int     rhsc;
 
+       rhsc = ohci_readl(ohci, &ohci->regs->intrenable) & OHCI_INTR_RHSC;
        switch (ohci->hc_control & OHCI_CTRL_HCFS) {
 
        case OHCI_USB_OPER:
-               /* keep on polling until we know a device is connected
-                * and RHSC is enabled */
+               /* If no status changes are pending, enable status-change
+                * interrupts.
+                */
+               if (!rhsc && !changed) {
+                       rhsc = OHCI_INTR_RHSC;
+                       ohci_writel(ohci, rhsc, &ohci->regs->intrenable);
+               }
+
+               /* Keep on polling until we know a device is connected
+                * and RHSC is enabled, or until we autostop.
+                */
                if (!ohci->autostop) {
                        if (any_connected ||
                                        !device_may_wakeup(&ohci_to_hcd(ohci)
                                                ->self.root_hub->dev)) {
-                               if (ohci_readl(ohci, &ohci->regs->intrenable) &
-                                               OHCI_INTR_RHSC)
+                               if (rhsc)
                                        poll_rh = 0;
                        } else {
                                ohci->autostop = 1;
@@ -398,12 +396,13 @@ static int ohci_root_hub_state_changes(struct ohci_hcd *ohci, int changed,
                                ohci->autostop = 0;
                                ohci->next_statechange = jiffies +
                                                STATECHANGE_DELAY;
-                       } else if (time_after_eq(jiffies,
+                       } else if (rhsc && time_after_eq(jiffies,
                                                ohci->next_statechange)
                                        && !ohci->ed_rm_list
                                        && !(ohci->hc_control &
                                                OHCI_SCHED_ENABLES)) {
                                ohci_rh_suspend(ohci, 1);
+                               poll_rh = 0;
                        }
                }
                break;
@@ -417,6 +416,12 @@ static int ohci_root_hub_state_changes(struct ohci_hcd *ohci, int changed,
                        else
                                usb_hcd_resume_root_hub(ohci_to_hcd(ohci));
                } else {
+                       if (!rhsc && (ohci->autostop ||
+                                       ohci_to_hcd(ohci)->self.root_hub->
+                                               do_remote_wakeup))
+                               ohci_writel(ohci, OHCI_INTR_RHSC,
+                                               &ohci->regs->intrenable);
+
                        /* everything is idle, no need for polling */
                        poll_rh = 0;
                }
@@ -438,12 +443,16 @@ static inline int ohci_rh_resume(struct ohci_hcd *ohci)
 static int ohci_root_hub_state_changes(struct ohci_hcd *ohci, int changed,
                int any_connected)
 {
-       int     poll_rh = 1;
-
-       /* keep on polling until RHSC is enabled */
+       /* If RHSC is enabled, don't poll */
        if (ohci_readl(ohci, &ohci->regs->intrenable) & OHCI_INTR_RHSC)
-               poll_rh = 0;
-       return poll_rh;
+               return 0;
+
+       /* If no status changes are pending, enable status-change interrupts */
+       if (!changed) {
+               ohci_writel(ohci, OHCI_INTR_RHSC, &ohci->regs->intrenable);
+               return 0;
+       }
+       return 1;
 }
 
 #endif /* CONFIG_PM */
index 9e31d440d115e7e8260476bcd81e39fd80b026e1..de42283149c7154608c30c9b1ceeec29e14b07ba 100644 (file)
@@ -193,7 +193,6 @@ static const struct hc_driver ohci_lh7a404_hc_driver = {
         */
        .hub_status_data =      ohci_hub_status_data,
        .hub_control =          ohci_hub_control,
-       .hub_irq_enable =       ohci_rhsc_enable,
 #ifdef CONFIG_PM
        .bus_suspend =          ohci_bus_suspend,
        .bus_resume =           ohci_bus_resume,
index 3d532b709670c9386959f1a8c84a327875790d10..1eb64d08b60a9591bd994f757c0372602b7c7ef4 100644 (file)
@@ -470,7 +470,6 @@ static const struct hc_driver ohci_omap_hc_driver = {
         */
        .hub_status_data =      ohci_hub_status_data,
        .hub_control =          ohci_hub_control,
-       .hub_irq_enable =       ohci_rhsc_enable,
 #ifdef CONFIG_PM
        .bus_suspend =          ohci_bus_suspend,
        .bus_resume =           ohci_bus_resume,
index 083e8df0a817f83b925ac397f5e90cb43b8af1d2..a9c2ae36c7ad5ce6bf9585fc9b8e418ad10751ba 100644 (file)
@@ -459,7 +459,6 @@ static const struct hc_driver ohci_pci_hc_driver = {
         */
        .hub_status_data =      ohci_hub_status_data,
        .hub_control =          ohci_hub_control,
-       .hub_irq_enable =       ohci_rhsc_enable,
 #ifdef CONFIG_PM
        .bus_suspend =          ohci_bus_suspend,
        .bus_resume =           ohci_bus_resume,
index b02cd0761977aed3bf6c85eda07227a6bfe8d4c1..658a2a978c32139bcf98181e9cd5fa4466f214b0 100644 (file)
@@ -277,7 +277,6 @@ static const struct hc_driver ohci_pnx4008_hc_driver = {
         */
        .hub_status_data = ohci_hub_status_data,
        .hub_control = ohci_hub_control,
-       .hub_irq_enable = ohci_rhsc_enable,
 #ifdef CONFIG_PM
        .bus_suspend = ohci_bus_suspend,
        .bus_resume = ohci_bus_resume,
index 605d59cba28e79d46bbbb3215cfc9ccd1b6f6a5b..28467e288a93d54607c7cb244e1e904dc6136395 100644 (file)
@@ -201,7 +201,6 @@ static const struct hc_driver ohci_pnx8550_hc_driver = {
         */
        .hub_status_data =      ohci_hub_status_data,
        .hub_control =          ohci_hub_control,
-       .hub_irq_enable =       ohci_rhsc_enable,
 #ifdef CONFIG_PM
        .bus_suspend =          ohci_bus_suspend,
        .bus_resume =           ohci_bus_resume,
index 91e6e101a4cc987feae9591a4926f6a35aef95a0..7ac53264ead369b1beb9c140cd50e131a019ea40 100644 (file)
@@ -72,7 +72,6 @@ static const struct hc_driver ohci_ppc_of_hc_driver = {
         */
        .hub_status_data =      ohci_hub_status_data,
        .hub_control =          ohci_hub_control,
-       .hub_irq_enable =       ohci_rhsc_enable,
 #ifdef CONFIG_PM
        .bus_suspend =          ohci_bus_suspend,
        .bus_resume =           ohci_bus_resume,
index 523c30125577d39a8c24287ce30ae2b2532929e2..cd3398b675b2dea8c2402fd2178cee58c23a52e4 100644 (file)
@@ -172,7 +172,6 @@ static const struct hc_driver ohci_ppc_soc_hc_driver = {
         */
        .hub_status_data =      ohci_hub_status_data,
        .hub_control =          ohci_hub_control,
-       .hub_irq_enable =       ohci_rhsc_enable,
 #ifdef CONFIG_PM
        .bus_suspend =          ohci_bus_suspend,
        .bus_resume =           ohci_bus_resume,
index 55c95647f008d7eec7eb6991a6a5f19212f4fd59..2089d8a46c4bbedb0cd140dc5db4d0cee4cab908 100644 (file)
@@ -68,7 +68,6 @@ static const struct hc_driver ps3_ohci_hc_driver = {
        .get_frame_number       = ohci_get_frame,
        .hub_status_data        = ohci_hub_status_data,
        .hub_control            = ohci_hub_control,
-       .hub_irq_enable         = ohci_rhsc_enable,
        .start_port_reset       = ohci_start_port_reset,
 #if defined(CONFIG_PM)
        .bus_suspend            = ohci_bus_suspend,
index 8c9c4849db6efc5fedfec17201622f60a6df9174..7f0f35c781858628a995dc85df361c6cae56b264 100644 (file)
@@ -298,7 +298,6 @@ static const struct hc_driver ohci_pxa27x_hc_driver = {
         */
        .hub_status_data =      ohci_hub_status_data,
        .hub_control =          ohci_hub_control,
-       .hub_irq_enable =       ohci_rhsc_enable,
 #ifdef  CONFIG_PM
        .bus_suspend =          ohci_bus_suspend,
        .bus_resume =           ohci_bus_resume,
index 9e3dc4069e8bc9cb4dac244f1b8dfa5f276ff9ac..f46af7a718d416a548b565c142ccf8d229c1505f 100644 (file)
@@ -466,7 +466,6 @@ static const struct hc_driver ohci_s3c2410_hc_driver = {
         */
        .hub_status_data =      ohci_s3c2410_hub_status_data,
        .hub_control =          ohci_s3c2410_hub_control,
-       .hub_irq_enable =       ohci_rhsc_enable,
 #ifdef CONFIG_PM
        .bus_suspend =          ohci_bus_suspend,
        .bus_resume =           ohci_bus_resume,
index 4626b002e670f15a5a93a1f8cf1c80edf12480b9..e4bbe8e188e4653355426294e511e92588085b9a 100644 (file)
@@ -231,7 +231,6 @@ static const struct hc_driver ohci_sa1111_hc_driver = {
         */
        .hub_status_data =      ohci_hub_status_data,
        .hub_control =          ohci_hub_control,
-       .hub_irq_enable =       ohci_rhsc_enable,
 #ifdef CONFIG_PM
        .bus_suspend =          ohci_bus_suspend,
        .bus_resume =           ohci_bus_resume,
index e7ee607278fece8b92570beb5b839e74ca8aa2db..60f03cc7ec4f20a4f80d228b59faebe715ae1148 100644 (file)
@@ -68,7 +68,6 @@ static const struct hc_driver ohci_sh_hc_driver = {
         */
        .hub_status_data =      ohci_hub_status_data,
        .hub_control =          ohci_hub_control,
-       .hub_irq_enable =       ohci_rhsc_enable,
 #ifdef CONFIG_PM
        .bus_suspend =          ohci_bus_suspend,
        .bus_resume =           ohci_bus_resume,
index 21b164e4abebf8bc71d12611b4356bb97e038718..cff23637cfcc5e6cd5322d8faddd866f885b9e27 100644 (file)
@@ -75,7 +75,6 @@ static const struct hc_driver ohci_sm501_hc_driver = {
         */
        .hub_status_data =      ohci_hub_status_data,
        .hub_control =          ohci_hub_control,
-       .hub_irq_enable =       ohci_rhsc_enable,
 #ifdef CONFIG_PM
        .bus_suspend =          ohci_bus_suspend,
        .bus_resume =           ohci_bus_resume,
index 3660c83d80af44b269bfa9c32311846db1878105..23fd6a886bddb0f25d2279d3da8d11c66e5e61ad 100644 (file)
@@ -81,7 +81,6 @@ static const struct hc_driver ssb_ohci_hc_driver = {
 
        .hub_status_data        = ohci_hub_status_data,
        .hub_control            = ohci_hub_control,
-       .hub_irq_enable         = ohci_rhsc_enable,
 #ifdef CONFIG_PM
        .bus_suspend            = ohci_bus_suspend,
        .bus_resume             = ohci_bus_resume,
index 20ad3c48fcb2966fb20e2bc36fc49971b239110b..228f2b070f2b7d558e33271827cccb3588794ebd 100644 (file)
@@ -2934,16 +2934,6 @@ static int u132_start_port_reset(struct usb_hcd *hcd, unsigned port_num)
                return 0;
 }
 
-static void u132_hub_irq_enable(struct usb_hcd *hcd)
-{
-       struct u132 *u132 = hcd_to_u132(hcd);
-       if (u132->going > 1) {
-               dev_err(&u132->platform_dev->dev, "device has been removed %d\n"
-                       , u132->going);
-       } else if (u132->going > 0)
-               dev_err(&u132->platform_dev->dev, "device is being removed\n");
-}
-
 
 #ifdef CONFIG_PM
 static int u132_bus_suspend(struct usb_hcd *hcd)
@@ -2995,7 +2985,6 @@ static struct hc_driver u132_hc_driver = {
        .bus_suspend = u132_bus_suspend,
        .bus_resume = u132_bus_resume,
        .start_port_reset = u132_start_port_reset,
-       .hub_irq_enable = u132_hub_irq_enable,
 };
 
 /*
index e6ca9979e3ae5eece2a693207f2e7426ca8fc1dc..a4ef77ef917d9bc6be7f2b29bff6a58ba6d105e1 100644 (file)
@@ -19,7 +19,6 @@
 #include <linux/slab.h>
 #include <linux/sched.h>
 #include <linux/poll.h>
-#include <linux/version.h>
 #include <linux/usb/iowarrior.h>
 
 /* Version Information */
index fbace41a7cba4418dc8602f70eae8614b0db33c7..69c34a58e2054a7c49d225164a3f1a7ead20cf5a 100644 (file)
@@ -3270,6 +3270,7 @@ static struct usb_device_id sisusb_table [] = {
        { USB_DEVICE(0x0711, 0x0900) },
        { USB_DEVICE(0x0711, 0x0901) },
        { USB_DEVICE(0x0711, 0x0902) },
+       { USB_DEVICE(0x0711, 0x0918) },
        { USB_DEVICE(0x182d, 0x021c) },
        { USB_DEVICE(0x182d, 0x0269) },
        { }
index faca4333f27a8125a46fcbb7d32362ac56fc3524..a0017486ad4ea27f6220764ede93cb3562e59247 100644 (file)
@@ -165,12 +165,11 @@ config USB_TUSB_OMAP_DMA
        help
          Enable DMA transfers on TUSB 6010 when OMAP DMA is available.
 
-config USB_MUSB_LOGLEVEL
+config USB_MUSB_DEBUG
        depends on USB_MUSB_HDRC
-       int  'Logging Level (0 - none / 3 - annoying / ... )'
-       default 0
+       bool "Enable debugging messages"
+       default n
        help
-         Set the logging level. 0 disables the debugging altogether,
-         although when USB_DEBUG is set the value is at least 1.
-         Starting at level 3, per-transfer (urb, usb_request, packet,
-         or dma transfer) tracing may kick in.
+         This enables musb debugging. To set the logging level use the debug
+         module parameter. Starting at level 3, per-transfer (urb, usb_request,
+         packet, or dma transfer) tracing may kick in.
index 88eb67de08aeed097a0285026e1a08a30fec77aa..b6af0d687a73657b27fc87fd8c57153fc7f2021d 100644 (file)
@@ -64,23 +64,6 @@ endif
 
 # Debugging
 
-MUSB_DEBUG:=$(CONFIG_USB_MUSB_LOGLEVEL)
-
-ifeq ("$(strip $(MUSB_DEBUG))","")
-    ifdef CONFIG_USB_DEBUG
-       MUSB_DEBUG:=1
-    else
-       MUSB_DEBUG:=0
-    endif
+ifeq ($(CONFIG_USB_MUSB_DEBUG),y)
+       EXTRA_CFLAGS += -DDEBUG
 endif
-
-ifneq ($(MUSB_DEBUG),0)
-    EXTRA_CFLAGS += -DDEBUG
-
-    ifeq ($(CONFIG_PROC_FS),y)
-       musb_hdrc-objs          += musb_procfs.o
-    endif
-
-endif
-
-EXTRA_CFLAGS += -DMUSB_DEBUG=$(MUSB_DEBUG)
index d68ec6daf3350676cee67df8ed9426b724b0fa35..c5b8f0296fcf2f9f9a7ab40404d1f8324e325508 100644 (file)
 
 
 
-#if MUSB_DEBUG > 0
-unsigned debug = MUSB_DEBUG;
-module_param(debug, uint, 0);
-MODULE_PARM_DESC(debug, "initial debug message level");
-
-#define MUSB_VERSION_SUFFIX    "/dbg"
-#endif
+unsigned debug;
+module_param(debug, uint, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(debug, "Debug message level. Default = 0");
 
 #define DRIVER_AUTHOR "Mentor Graphics, Texas Instruments, Nokia"
 #define DRIVER_DESC "Inventra Dual-Role USB Controller Driver"
 
-#define MUSB_VERSION_BASE "6.0"
-
-#ifndef MUSB_VERSION_SUFFIX
-#define MUSB_VERSION_SUFFIX    ""
-#endif
-#define MUSB_VERSION   MUSB_VERSION_BASE MUSB_VERSION_SUFFIX
+#define MUSB_VERSION "6.0"
 
 #define DRIVER_INFO DRIVER_DESC ", v" MUSB_VERSION
 
@@ -2037,6 +2028,8 @@ bad_config:
                musb->xceiv.state = OTG_STATE_A_IDLE;
 
                status = usb_add_hcd(musb_to_hcd(musb), -1, 0);
+               if (status)
+                       goto fail;
 
                DBG(1, "%s mode, status %d, devctl %02x %c\n",
                        "HOST", status,
@@ -2051,6 +2044,8 @@ bad_config:
                musb->xceiv.state = OTG_STATE_B_IDLE;
 
                status = musb_gadget_setup(musb);
+               if (status)
+                       goto fail;
 
                DBG(1, "%s mode, status %d, dev%02x\n",
                        is_otg_enabled(musb) ? "OTG" : "PERIPHERAL",
@@ -2059,16 +2054,14 @@ bad_config:
 
        }
 
-       if (status == 0)
-               musb_debug_create("driver/musb_hdrc", musb);
-       else {
+       return 0;
+
 fail:
-               if (musb->clock)
-                       clk_put(musb->clock);
-               device_init_wakeup(dev, 0);
-               musb_free(musb);
-               return status;
-       }
+       if (musb->clock)
+               clk_put(musb->clock);
+       device_init_wakeup(dev, 0);
+       musb_free(musb);
+       return status;
 
 #ifdef CONFIG_SYSFS
        status = device_create_file(dev, &dev_attr_mode);
@@ -2131,7 +2124,6 @@ static int __devexit musb_remove(struct platform_device *pdev)
         *  - OTG mode: both roles are deactivated (or never-activated)
         */
        musb_shutdown(pdev);
-       musb_debug_delete("driver/musb_hdrc", musb);
 #ifdef CONFIG_USB_MUSB_HDRC_HCD
        if (musb->board_mode == MUSB_HOST)
                usb_remove_hcd(musb_to_hcd(musb));
index eade46d817084813616c13a3a60f6951b5bd9602..82227251931b4c8c512f5d66babe9fec3fbafff2 100644 (file)
@@ -485,23 +485,4 @@ extern int musb_platform_get_vbus_status(struct musb *musb);
 extern int __init musb_platform_init(struct musb *musb);
 extern int musb_platform_exit(struct musb *musb);
 
-/*-------------------------- ProcFS definitions ---------------------*/
-
-struct proc_dir_entry;
-
-#if (MUSB_DEBUG > 0) && defined(MUSB_CONFIG_PROC_FS)
-extern struct proc_dir_entry *musb_debug_create(char *name, struct musb *data);
-extern void musb_debug_delete(char *name, struct musb *data);
-
-#else
-static inline struct proc_dir_entry *
-musb_debug_create(char *name, struct musb *data)
-{
-       return NULL;
-}
-static inline void musb_debug_delete(char *name, struct musb *data)
-{
-}
-#endif
-
 #endif /* __MUSB_CORE_H__ */
index 3bdb311e820d454ee4e801a05247c5464ef1a839..4d2794441b153ac6c2f745b99f06c245cb56bbe5 100644 (file)
                                __func__, __LINE__ , ## args); \
        } } while (0)
 
-#if MUSB_DEBUG > 0
 extern unsigned debug;
-#else
-#define debug  0
-#endif
 
 static inline int _dbg_level(unsigned l)
 {
index 48d7d3ccb2438ecd4d70c2f317dc485ef960b72d..a57652fff39cac614b399e089fa76c8c32f38dd8 100644 (file)
@@ -476,6 +476,7 @@ static void ep0_rxstate(struct musb *musb)
                        return;
                musb->ackpend = 0;
        }
+       musb_ep_select(musb->mregs, 0);
        musb_writew(regs, MUSB_CSR0, tmp);
 }
 
@@ -528,6 +529,7 @@ static void ep0_txstate(struct musb *musb)
        }
 
        /* send it out, triggering a "txpktrdy cleared" irq */
+       musb_ep_select(musb->mregs, 0);
        musb_writew(regs, MUSB_CSR0, csr);
 }
 
diff --git a/drivers/usb/musb/musb_procfs.c b/drivers/usb/musb/musb_procfs.c
deleted file mode 100644 (file)
index 55e6b78..0000000
+++ /dev/null
@@ -1,830 +0,0 @@
-/*
- * MUSB OTG driver debug support
- *
- * Copyright 2005 Mentor Graphics Corporation
- * Copyright (C) 2005-2006 by Texas Instruments
- * Copyright (C) 2006-2007 Nokia Corporation
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * 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 St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- * NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
-#include <linux/uaccess.h>     /* FIXME remove procfs writes */
-#include <asm/arch/hardware.h>
-
-#include "musb_core.h"
-
-#include "davinci.h"
-
-#ifdef CONFIG_USB_MUSB_HDRC_HCD
-
-static int dump_qh(struct musb_qh *qh, char *buf, unsigned max)
-{
-       int                             count;
-       int                             tmp;
-       struct usb_host_endpoint        *hep = qh->hep;
-       struct urb                      *urb;
-
-       count = snprintf(buf, max, "    qh %p dev%d ep%d%s max%d\n",
-                       qh, qh->dev->devnum, qh->epnum,
-                       ({ char *s; switch (qh->type) {
-                       case USB_ENDPOINT_XFER_BULK:
-                               s = "-bulk"; break;
-                       case USB_ENDPOINT_XFER_INT:
-                               s = "-int"; break;
-                       case USB_ENDPOINT_XFER_CONTROL:
-                               s = ""; break;
-                       default:
-                               s = "iso"; break;
-                       }; s; }),
-                       qh->maxpacket);
-       if (count <= 0)
-               return 0;
-       buf += count;
-       max -= count;
-
-       list_for_each_entry(urb, &hep->urb_list, urb_list) {
-               tmp = snprintf(buf, max, "\t%s urb %p %d/%d\n",
-                               usb_pipein(urb->pipe) ? "in" : "out",
-                               urb, urb->actual_length,
-                               urb->transfer_buffer_length);
-               if (tmp <= 0)
-                       break;
-               tmp = min(tmp, (int)max);
-               count += tmp;
-               buf += tmp;
-               max -= tmp;
-       }
-       return count;
-}
-
-static int
-dump_queue(struct list_head *q, char *buf, unsigned max)
-{
-       int             count = 0;
-       struct musb_qh  *qh;
-
-       list_for_each_entry(qh, q, ring) {
-               int     tmp;
-
-               tmp = dump_qh(qh, buf, max);
-               if (tmp <= 0)
-                       break;
-               tmp = min(tmp, (int)max);
-               count += tmp;
-               buf += tmp;
-               max -= tmp;
-       }
-       return count;
-}
-
-#endif /* HCD */
-
-#ifdef CONFIG_USB_GADGET_MUSB_HDRC
-static int dump_ep(struct musb_ep *ep, char *buffer, unsigned max)
-{
-       char            *buf = buffer;
-       int             code = 0;
-       void __iomem    *regs = ep->hw_ep->regs;
-       char            *mode = "1buf";
-
-       if (ep->is_in) {
-               if (ep->hw_ep->tx_double_buffered)
-                       mode = "2buf";
-       } else {
-               if (ep->hw_ep->rx_double_buffered)
-                       mode = "2buf";
-       }
-
-       do {
-               struct usb_request      *req;
-
-               code = snprintf(buf, max,
-                               "\n%s (hw%d): %s%s, csr %04x maxp %04x\n",
-                               ep->name, ep->current_epnum,
-                               mode, ep->dma ? " dma" : "",
-                               musb_readw(regs,
-                                       (ep->is_in || !ep->current_epnum)
-                                               ? MUSB_TXCSR
-                                               : MUSB_RXCSR),
-                               musb_readw(regs, ep->is_in
-                                               ? MUSB_TXMAXP
-                                               : MUSB_RXMAXP)
-                               );
-               if (code <= 0)
-                       break;
-               code = min(code, (int) max);
-               buf += code;
-               max -= code;
-
-               if (is_cppi_enabled() && ep->current_epnum) {
-                       unsigned        cppi = ep->current_epnum - 1;
-                       void __iomem    *base = ep->musb->ctrl_base;
-                       unsigned        off1 = cppi << 2;
-                       void __iomem    *ram = base;
-                       char            tmp[16];
-
-                       if (ep->is_in) {
-                               ram += DAVINCI_TXCPPI_STATERAM_OFFSET(cppi);
-                               tmp[0] = 0;
-                       } else {
-                               ram += DAVINCI_RXCPPI_STATERAM_OFFSET(cppi);
-                               snprintf(tmp, sizeof tmp, "%d left, ",
-                                       musb_readl(base,
-                                       DAVINCI_RXCPPI_BUFCNT0_REG + off1));
-                       }
-
-                       code = snprintf(buf, max, "%cX DMA%d: %s"
-                                       "%08x %08x, %08x %08x; "
-                                       "%08x %08x %08x .. %08x\n",
-                               ep->is_in ? 'T' : 'R',
-                               ep->current_epnum - 1, tmp,
-                               musb_readl(ram, 0 * 4),
-                               musb_readl(ram, 1 * 4),
-                               musb_readl(ram, 2 * 4),
-                               musb_readl(ram, 3 * 4),
-                               musb_readl(ram, 4 * 4),
-                               musb_readl(ram, 5 * 4),
-                               musb_readl(ram, 6 * 4),
-                               musb_readl(ram, 7 * 4));
-                       if (code <= 0)
-                               break;
-                       code = min(code, (int) max);
-                       buf += code;
-                       max -= code;
-               }
-
-               if (list_empty(&ep->req_list)) {
-                       code = snprintf(buf, max, "\t(queue empty)\n");
-                       if (code <= 0)
-                               break;
-                       code = min(code, (int) max);
-                       buf += code;
-                       max -= code;
-                       break;
-               }
-               list_for_each_entry(req, &ep->req_list, list) {
-                       code = snprintf(buf, max, "\treq %p, %s%s%d/%d\n",
-                                       req,
-                                       req->zero ? "zero, " : "",
-                                       req->short_not_ok ? "!short, " : "",
-                                       req->actual, req->length);
-                       if (code <= 0)
-                               break;
-                       code = min(code, (int) max);
-                       buf += code;
-                       max -= code;
-               }
-       } while (0);
-       return buf - buffer;
-}
-#endif
-
-static int
-dump_end_info(struct musb *musb, u8 epnum, char *aBuffer, unsigned max)
-{
-       int                     code = 0;
-       char                    *buf = aBuffer;
-       struct musb_hw_ep       *hw_ep = &musb->endpoints[epnum];
-
-       do {
-               musb_ep_select(musb->mregs, epnum);
-#ifdef CONFIG_USB_MUSB_HDRC_HCD
-               if (is_host_active(musb)) {
-                       int             dump_rx, dump_tx;
-                       void __iomem    *regs = hw_ep->regs;
-
-                       /* TEMPORARY (!) until we have a real periodic
-                        * schedule tree ...
-                        */
-                       if (!epnum) {
-                               /* control is shared, uses RX queue
-                                * but (mostly) shadowed tx registers
-                                */
-                               dump_tx = !list_empty(&musb->control);
-                               dump_rx = 0;
-                       } else if (hw_ep == musb->bulk_ep) {
-                               dump_tx = !list_empty(&musb->out_bulk);
-                               dump_rx = !list_empty(&musb->in_bulk);
-                       } else if (musb->periodic[epnum]) {
-                               struct usb_host_endpoint        *hep;
-
-                               hep = musb->periodic[epnum]->hep;
-                               dump_rx = hep->desc.bEndpointAddress
-                                               & USB_ENDPOINT_DIR_MASK;
-                               dump_tx = !dump_rx;
-                       } else
-                               break;
-                       /* END TEMPORARY */
-
-
-                       if (dump_rx) {
-                               code = snprintf(buf, max,
-                                       "\nRX%d: %s rxcsr %04x interval %02x "
-                                       "max %04x type %02x; "
-                                       "dev %d hub %d port %d"
-                                       "\n",
-                                       epnum,
-                                       hw_ep->rx_double_buffered
-                                               ? "2buf" : "1buf",
-                                       musb_readw(regs, MUSB_RXCSR),
-                                       musb_readb(regs, MUSB_RXINTERVAL),
-                                       musb_readw(regs, MUSB_RXMAXP),
-                                       musb_readb(regs, MUSB_RXTYPE),
-                                       /* FIXME:  assumes multipoint */
-                                       musb_readb(musb->mregs,
-                                               MUSB_BUSCTL_OFFSET(epnum,
-                                               MUSB_RXFUNCADDR)),
-                                       musb_readb(musb->mregs,
-                                               MUSB_BUSCTL_OFFSET(epnum,
-                                               MUSB_RXHUBADDR)),
-                                       musb_readb(musb->mregs,
-                                               MUSB_BUSCTL_OFFSET(epnum,
-                                               MUSB_RXHUBPORT))
-                                       );
-                               if (code <= 0)
-                                       break;
-                               code = min(code, (int) max);
-                               buf += code;
-                               max -= code;
-
-                               if (is_cppi_enabled()
-                                               && epnum
-                                               && hw_ep->rx_channel) {
-                                       unsigned        cppi = epnum - 1;
-                                       unsigned        off1 = cppi << 2;
-                                       void __iomem    *base;
-                                       void __iomem    *ram;
-                                       char            tmp[16];
-
-                                       base = musb->ctrl_base;
-                                       ram = DAVINCI_RXCPPI_STATERAM_OFFSET(
-                                                       cppi) + base;
-                                       snprintf(tmp, sizeof tmp, "%d left, ",
-                                               musb_readl(base,
-                                               DAVINCI_RXCPPI_BUFCNT0_REG
-                                                               + off1));
-
-                                       code = snprintf(buf, max,
-                                               "    rx dma%d: %s"
-                                               "%08x %08x, %08x %08x; "
-                                               "%08x %08x %08x .. %08x\n",
-                                               cppi, tmp,
-                                               musb_readl(ram, 0 * 4),
-                                               musb_readl(ram, 1 * 4),
-                                               musb_readl(ram, 2 * 4),
-                                               musb_readl(ram, 3 * 4),
-                                               musb_readl(ram, 4 * 4),
-                                               musb_readl(ram, 5 * 4),
-                                               musb_readl(ram, 6 * 4),
-                                               musb_readl(ram, 7 * 4));
-                                       if (code <= 0)
-                                               break;
-                                       code = min(code, (int) max);
-                                       buf += code;
-                                       max -= code;
-                               }
-
-                               if (hw_ep == musb->bulk_ep
-                                               && !list_empty(
-                                                       &musb->in_bulk)) {
-                                       code = dump_queue(&musb->in_bulk,
-                                                       buf, max);
-                                       if (code <= 0)
-                                               break;
-                                       code = min(code, (int) max);
-                                       buf += code;
-                                       max -= code;
-                               } else if (musb->periodic[epnum]) {
-                                       code = dump_qh(musb->periodic[epnum],
-                                                       buf, max);
-                                       if (code <= 0)
-                                               break;
-                                       code = min(code, (int) max);
-                                       buf += code;
-                                       max -= code;
-                               }
-                       }
-
-                       if (dump_tx) {
-                               code = snprintf(buf, max,
-                                       "\nTX%d: %s txcsr %04x interval %02x "
-                                       "max %04x type %02x; "
-                                       "dev %d hub %d port %d"
-                                       "\n",
-                                       epnum,
-                                       hw_ep->tx_double_buffered
-                                               ? "2buf" : "1buf",
-                                       musb_readw(regs, MUSB_TXCSR),
-                                       musb_readb(regs, MUSB_TXINTERVAL),
-                                       musb_readw(regs, MUSB_TXMAXP),
-                                       musb_readb(regs, MUSB_TXTYPE),
-                                       /* FIXME:  assumes multipoint */
-                                       musb_readb(musb->mregs,
-                                               MUSB_BUSCTL_OFFSET(epnum,
-                                               MUSB_TXFUNCADDR)),
-                                       musb_readb(musb->mregs,
-                                               MUSB_BUSCTL_OFFSET(epnum,
-                                               MUSB_TXHUBADDR)),
-                                       musb_readb(musb->mregs,
-                                               MUSB_BUSCTL_OFFSET(epnum,
-                                               MUSB_TXHUBPORT))
-                                       );
-                               if (code <= 0)
-                                       break;
-                               code = min(code, (int) max);
-                               buf += code;
-                               max -= code;
-
-                               if (is_cppi_enabled()
-                                               && epnum
-                                               && hw_ep->tx_channel) {
-                                       unsigned        cppi = epnum - 1;
-                                       void __iomem    *base;
-                                       void __iomem    *ram;
-
-                                       base = musb->ctrl_base;
-                                       ram = DAVINCI_RXCPPI_STATERAM_OFFSET(
-                                                       cppi) + base;
-                                       code = snprintf(buf, max,
-                                               "    tx dma%d: "
-                                               "%08x %08x, %08x %08x; "
-                                               "%08x %08x %08x .. %08x\n",
-                                               cppi,
-                                               musb_readl(ram, 0 * 4),
-                                               musb_readl(ram, 1 * 4),
-                                               musb_readl(ram, 2 * 4),
-                                               musb_readl(ram, 3 * 4),
-                                               musb_readl(ram, 4 * 4),
-                                               musb_readl(ram, 5 * 4),
-                                               musb_readl(ram, 6 * 4),
-                                               musb_readl(ram, 7 * 4));
-                                       if (code <= 0)
-                                               break;
-                                       code = min(code, (int) max);
-                                       buf += code;
-                                       max -= code;
-                               }
-
-                               if (hw_ep == musb->control_ep
-                                               && !list_empty(
-                                                       &musb->control)) {
-                                       code = dump_queue(&musb->control,
-                                                       buf, max);
-                                       if (code <= 0)
-                                               break;
-                                       code = min(code, (int) max);
-                                       buf += code;
-                                       max -= code;
-                               } else if (hw_ep == musb->bulk_ep
-                                               && !list_empty(
-                                                       &musb->out_bulk)) {
-                                       code = dump_queue(&musb->out_bulk,
-                                                       buf, max);
-                                       if (code <= 0)
-                                               break;
-                                       code = min(code, (int) max);
-                                       buf += code;
-                                       max -= code;
-                               } else if (musb->periodic[epnum]) {
-                                       code = dump_qh(musb->periodic[epnum],
-                                                       buf, max);
-                                       if (code <= 0)
-                                               break;
-                                       code = min(code, (int) max);
-                                       buf += code;
-                                       max -= code;
-                               }
-                       }
-               }
-#endif
-#ifdef CONFIG_USB_GADGET_MUSB_HDRC
-               if (is_peripheral_active(musb)) {
-                       code = 0;
-
-                       if (hw_ep->ep_in.desc || !epnum) {
-                               code = dump_ep(&hw_ep->ep_in, buf, max);
-                               if (code <= 0)
-                                       break;
-                               code = min(code, (int) max);
-                               buf += code;
-                               max -= code;
-                       }
-                       if (hw_ep->ep_out.desc) {
-                               code = dump_ep(&hw_ep->ep_out, buf, max);
-                               if (code <= 0)
-                                       break;
-                               code = min(code, (int) max);
-                               buf += code;
-                               max -= code;
-                       }
-               }
-#endif
-       } while (0);
-
-       return buf - aBuffer;
-}
-
-/* Dump the current status and compile options.
- * @param musb the device driver instance
- * @param buffer where to dump the status; it must be big enough to hold the
- * result otherwise "BAD THINGS HAPPENS(TM)".
- */
-static int dump_header_stats(struct musb *musb, char *buffer)
-{
-       int code, count = 0;
-       const void __iomem *mbase = musb->mregs;
-
-       *buffer = 0;
-       count = sprintf(buffer, "Status: %sHDRC, Mode=%s "
-                               "(Power=%02x, DevCtl=%02x)\n",
-                       (musb->is_multipoint ? "M" : ""), MUSB_MODE(musb),
-                       musb_readb(mbase, MUSB_POWER),
-                       musb_readb(mbase, MUSB_DEVCTL));
-       if (count <= 0)
-               return 0;
-       buffer += count;
-
-       code = sprintf(buffer, "OTG state: %s; %sactive\n",
-                       otg_state_string(musb),
-                       musb->is_active ? "" : "in");
-       if (code <= 0)
-               goto done;
-       buffer += code;
-       count += code;
-
-       code = sprintf(buffer,
-                       "Options: "
-#ifdef CONFIG_MUSB_PIO_ONLY
-                       "pio"
-#elif defined(CONFIG_USB_TI_CPPI_DMA)
-                       "cppi-dma"
-#elif defined(CONFIG_USB_INVENTRA_DMA)
-                       "musb-dma"
-#elif defined(CONFIG_USB_TUSB_OMAP_DMA)
-                       "tusb-omap-dma"
-#else
-                       "?dma?"
-#endif
-                       ", "
-#ifdef CONFIG_USB_MUSB_OTG
-                       "otg (peripheral+host)"
-#elif defined(CONFIG_USB_GADGET_MUSB_HDRC)
-                       "peripheral"
-#elif defined(CONFIG_USB_MUSB_HDRC_HCD)
-                       "host"
-#endif
-                       ", debug=%d [eps=%d]\n",
-               debug,
-               musb->nr_endpoints);
-       if (code <= 0)
-               goto done;
-       count += code;
-       buffer += code;
-
-#ifdef CONFIG_USB_GADGET_MUSB_HDRC
-       code = sprintf(buffer, "Peripheral address: %02x\n",
-                       musb_readb(musb->ctrl_base, MUSB_FADDR));
-       if (code <= 0)
-               goto done;
-       buffer += code;
-       count += code;
-#endif
-
-#ifdef CONFIG_USB_MUSB_HDRC_HCD
-       code = sprintf(buffer, "Root port status: %08x\n",
-                       musb->port1_status);
-       if (code <= 0)
-               goto done;
-       buffer += code;
-       count += code;
-#endif
-
-#ifdef CONFIG_ARCH_DAVINCI
-       code = sprintf(buffer,
-                       "DaVinci: ctrl=%02x stat=%1x phy=%03x\n"
-                       "\trndis=%05x auto=%04x intsrc=%08x intmsk=%08x"
-                       "\n",
-                       musb_readl(musb->ctrl_base, DAVINCI_USB_CTRL_REG),
-                       musb_readl(musb->ctrl_base, DAVINCI_USB_STAT_REG),
-                       __raw_readl((void __force __iomem *)
-                                       IO_ADDRESS(USBPHY_CTL_PADDR)),
-                       musb_readl(musb->ctrl_base, DAVINCI_RNDIS_REG),
-                       musb_readl(musb->ctrl_base, DAVINCI_AUTOREQ_REG),
-                       musb_readl(musb->ctrl_base,
-                                       DAVINCI_USB_INT_SOURCE_REG),
-                       musb_readl(musb->ctrl_base,
-                                       DAVINCI_USB_INT_MASK_REG));
-       if (code <= 0)
-               goto done;
-       count += code;
-       buffer += code;
-#endif /* DAVINCI */
-
-#ifdef CONFIG_USB_TUSB6010
-       code = sprintf(buffer,
-                       "TUSB6010: devconf %08x, phy enable %08x drive %08x"
-                       "\n\totg %03x timer %08x"
-                       "\n\tprcm conf %08x mgmt %08x; int src %08x mask %08x"
-                       "\n",
-                       musb_readl(musb->ctrl_base, TUSB_DEV_CONF),
-                       musb_readl(musb->ctrl_base, TUSB_PHY_OTG_CTRL_ENABLE),
-                       musb_readl(musb->ctrl_base, TUSB_PHY_OTG_CTRL),
-                       musb_readl(musb->ctrl_base, TUSB_DEV_OTG_STAT),
-                       musb_readl(musb->ctrl_base, TUSB_DEV_OTG_TIMER),
-                       musb_readl(musb->ctrl_base, TUSB_PRCM_CONF),
-                       musb_readl(musb->ctrl_base, TUSB_PRCM_MNGMT),
-                       musb_readl(musb->ctrl_base, TUSB_INT_SRC),
-                       musb_readl(musb->ctrl_base, TUSB_INT_MASK));
-       if (code <= 0)
-               goto done;
-       count += code;
-       buffer += code;
-#endif /* DAVINCI */
-
-       if (is_cppi_enabled() && musb->dma_controller) {
-               code = sprintf(buffer,
-                               "CPPI: txcr=%d txsrc=%01x txena=%01x; "
-                               "rxcr=%d rxsrc=%01x rxena=%01x "
-                               "\n",
-                               musb_readl(musb->ctrl_base,
-                                               DAVINCI_TXCPPI_CTRL_REG),
-                               musb_readl(musb->ctrl_base,
-                                               DAVINCI_TXCPPI_RAW_REG),
-                               musb_readl(musb->ctrl_base,
-                                               DAVINCI_TXCPPI_INTENAB_REG),
-                               musb_readl(musb->ctrl_base,
-                                               DAVINCI_RXCPPI_CTRL_REG),
-                               musb_readl(musb->ctrl_base,
-                                               DAVINCI_RXCPPI_RAW_REG),
-                               musb_readl(musb->ctrl_base,
-                                               DAVINCI_RXCPPI_INTENAB_REG));
-               if (code <= 0)
-                       goto done;
-               count += code;
-               buffer += code;
-       }
-
-#ifdef CONFIG_USB_GADGET_MUSB_HDRC
-       if (is_peripheral_enabled(musb)) {
-               code = sprintf(buffer, "Gadget driver: %s\n",
-                               musb->gadget_driver
-                                       ? musb->gadget_driver->driver.name
-                                       : "(none)");
-               if (code <= 0)
-                       goto done;
-               count += code;
-               buffer += code;
-       }
-#endif
-
-done:
-       return count;
-}
-
-/* Write to ProcFS
- *
- * C soft-connect
- * c soft-disconnect
- * I enable HS
- * i disable HS
- * s stop session
- * F force session (OTG-unfriendly)
- * E rElinquish bus (OTG)
- * H request host mode
- * h cancel host request
- * T start sending TEST_PACKET
- * D<num> set/query the debug level
- */
-static int musb_proc_write(struct file *file, const char __user *buffer,
-                       unsigned long count, void *data)
-{
-       char cmd;
-       u8 reg;
-       struct musb *musb = (struct musb *)data;
-       void __iomem *mbase = musb->mregs;
-
-       /* MOD_INC_USE_COUNT; */
-
-       if (unlikely(copy_from_user(&cmd, buffer, 1)))
-               return -EFAULT;
-
-       switch (cmd) {
-       case 'C':
-               if (mbase) {
-                       reg = musb_readb(mbase, MUSB_POWER)
-                                       | MUSB_POWER_SOFTCONN;
-                       musb_writeb(mbase, MUSB_POWER, reg);
-               }
-               break;
-
-       case 'c':
-               if (mbase) {
-                       reg = musb_readb(mbase, MUSB_POWER)
-                                       & ~MUSB_POWER_SOFTCONN;
-                       musb_writeb(mbase, MUSB_POWER, reg);
-               }
-               break;
-
-       case 'I':
-               if (mbase) {
-                       reg = musb_readb(mbase, MUSB_POWER)
-                                       | MUSB_POWER_HSENAB;
-                       musb_writeb(mbase, MUSB_POWER, reg);
-               }
-               break;
-
-       case 'i':
-               if (mbase) {
-                       reg = musb_readb(mbase, MUSB_POWER)
-                                       & ~MUSB_POWER_HSENAB;
-                       musb_writeb(mbase, MUSB_POWER, reg);
-               }
-               break;
-
-       case 'F':
-               reg = musb_readb(mbase, MUSB_DEVCTL);
-               reg |= MUSB_DEVCTL_SESSION;
-               musb_writeb(mbase, MUSB_DEVCTL, reg);
-               break;
-
-       case 'H':
-               if (mbase) {
-                       reg = musb_readb(mbase, MUSB_DEVCTL);
-                       reg |= MUSB_DEVCTL_HR;
-                       musb_writeb(mbase, MUSB_DEVCTL, reg);
-                       /* MUSB_HST_MODE( ((struct musb*)data) ); */
-                       /* WARNING("Host Mode\n"); */
-               }
-               break;
-
-       case 'h':
-               if (mbase) {
-                       reg = musb_readb(mbase, MUSB_DEVCTL);
-                       reg &= ~MUSB_DEVCTL_HR;
-                       musb_writeb(mbase, MUSB_DEVCTL, reg);
-               }
-               break;
-
-       case 'T':
-               if (mbase) {
-                       musb_load_testpacket(musb);
-                       musb_writeb(mbase, MUSB_TESTMODE,
-                                       MUSB_TEST_PACKET);
-               }
-               break;
-
-#if (MUSB_DEBUG > 0)
-               /* set/read debug level */
-       case 'D':{
-                       if (count > 1) {
-                               char digits[8], *p = digits;
-                               int i = 0, level = 0, sign = 1;
-                               int len = min(count - 1, (unsigned long)8);
-
-                               if (copy_from_user(&digits, &buffer[1], len))
-                                       return -EFAULT;
-
-                               /* optional sign */
-                               if (*p == '-') {
-                                       len -= 1;
-                                       sign = -sign;
-                                       p++;
-                               }
-
-                               /* read it */
-                               while (i++ < len && *p > '0' && *p < '9') {
-                                       level = level * 10 + (*p - '0');
-                                       p++;
-                               }
-
-                               level *= sign;
-                               DBG(1, "debug level %d\n", level);
-                               debug = level;
-                       }
-               }
-               break;
-
-
-       case '?':
-               INFO("?: you are seeing it\n");
-               INFO("C/c: soft connect enable/disable\n");
-               INFO("I/i: hispeed enable/disable\n");
-               INFO("F: force session start\n");
-               INFO("H: host mode\n");
-               INFO("T: start sending TEST_PACKET\n");
-               INFO("D: set/read dbug level\n");
-               break;
-#endif
-
-       default:
-               ERR("Command %c not implemented\n", cmd);
-               break;
-       }
-
-       musb_platform_try_idle(musb, 0);
-
-       return count;
-}
-
-static int musb_proc_read(char *page, char **start,
-                       off_t off, int count, int *eof, void *data)
-{
-       char *buffer = page;
-       int code = 0;
-       unsigned long   flags;
-       struct musb     *musb = data;
-       unsigned        epnum;
-
-       count -= off;
-       count -= 1;             /* for NUL at end */
-       if (count <= 0)
-               return -EINVAL;
-
-       spin_lock_irqsave(&musb->lock, flags);
-
-       code = dump_header_stats(musb, buffer);
-       if (code > 0) {
-               buffer += code;
-               count -= code;
-       }
-
-       /* generate the report for the end points */
-       /* REVISIT ... not unless something's connected! */
-       for (epnum = 0; count >= 0 && epnum < musb->nr_endpoints;
-                       epnum++) {
-               code = dump_end_info(musb, epnum, buffer, count);
-               if (code > 0) {
-                       buffer += code;
-                       count -= code;
-               }
-       }
-
-       musb_platform_try_idle(musb, 0);
-
-       spin_unlock_irqrestore(&musb->lock, flags);
-       *eof = 1;
-
-       return buffer - page;
-}
-
-void __devexit musb_debug_delete(char *name, struct musb *musb)
-{
-       if (musb->proc_entry)
-               remove_proc_entry(name, NULL);
-}
-
-struct proc_dir_entry *__init
-musb_debug_create(char *name, struct musb *data)
-{
-       struct proc_dir_entry   *pde;
-
-       /* FIXME convert everything to seq_file; then later, debugfs */
-
-       if (!name)
-               return NULL;
-
-       pde = create_proc_entry(name, S_IFREG | S_IRUGO | S_IWUSR, NULL);
-       data->proc_entry = pde;
-       if (pde) {
-               pde->data = data;
-               /* pde->owner = THIS_MODULE; */
-
-               pde->read_proc = musb_proc_read;
-               pde->write_proc = musb_proc_write;
-
-               pde->size = 0;
-
-               pr_debug("Registered /proc/%s\n", name);
-       } else {
-               pr_debug("Cannot create a valid proc file entry");
-       }
-
-       return pde;
-}
index 2e663f1afd5e4ea85fa170f2d387f06d817bac5a..d95382088075923ab47ae4fc869784e03c0520d4 100644 (file)
@@ -38,8 +38,6 @@
 #include <linux/usb.h>
 #include <linux/usb/serial.h>
 
-#include <linux/version.h>
-
 /* the mode to be set when the port ist opened */
 static int initial_mode = 1;
 
index e143198aeb028e0bec63189cf8d4ace46e778a70..9f9cd36455f463423e4cbe22fd752e639415580b 100644 (file)
@@ -173,6 +173,7 @@ static int  option_send_setup(struct tty_struct *tty, struct usb_serial_port *po
 #define KYOCERA_PRODUCT_KPC680                 0x180a
 
 #define ANYDATA_VENDOR_ID                      0x16d5
+#define ANYDATA_PRODUCT_ADU_620UW              0x6202
 #define ANYDATA_PRODUCT_ADU_E100A              0x6501
 #define ANYDATA_PRODUCT_ADU_500A               0x6502
 
@@ -318,6 +319,7 @@ static struct usb_device_id option_ids[] = {
        { USB_DEVICE(DELL_VENDOR_ID, 0x8138) }, /* Dell Wireless 5520 Voda I Mobile Broadband (3G HSDPA) Minicard */
        { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_E100A) },
        { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_500A) },
+       { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_620UW) },
        { USB_DEVICE(AXESSTEL_VENDOR_ID, AXESSTEL_PRODUCT_MV110H) },
        { USB_DEVICE(ONDA_VENDOR_ID, ONDA_PRODUCT_MSA501HS) },
        { USB_DEVICE(ONDA_VENDOR_ID, ONDA_PRODUCT_ET502HS) },
index 4bd569e479a723c70d3f3532271a65e4d111dab7..314d18694b6a38c2d3fd6eeca883e1448bcd0fd2 100644 (file)
@@ -11,7 +11,6 @@
  *  Code is based on s3fb
  */
 
-#include <linux/version.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
index 940467aed13f27864849db15ba36b70e4ad2b846..6d5aa806777e0826b187e8786ee7633d425b83f4 100644 (file)
@@ -733,7 +733,6 @@ static int bfin_bf54x_remove(struct platform_device *pdev)
 static int bfin_bf54x_suspend(struct platform_device *pdev, pm_message_t state)
 {
        struct fb_info *fbinfo = platform_get_drvdata(pdev);
-       struct bfin_bf54xfb_info *info = fbinfo->par;
 
        bfin_write_EPPI0_CONTROL(bfin_read_EPPI0_CONTROL() & ~EPPI_EN);
        disable_dma(CH_EPPI0);
@@ -747,8 +746,18 @@ static int bfin_bf54x_resume(struct platform_device *pdev)
        struct fb_info *fbinfo = platform_get_drvdata(pdev);
        struct bfin_bf54xfb_info *info = fbinfo->par;
 
-       enable_dma(CH_EPPI0);
-       bfin_write_EPPI0_CONTROL(bfin_read_EPPI0_CONTROL() | EPPI_EN);
+       if (info->lq043_open_cnt) {
+
+               bfin_write_EPPI0_CONTROL(0);
+               SSYNC();
+
+               config_dma(info);
+               config_ppi(info);
+
+               /* start dma */
+               enable_dma(CH_EPPI0);
+               bfin_write_EPPI0_CONTROL(bfin_read_EPPI0_CONTROL() | EPPI_EN);
+       }
 
        return 0;
 }
index 59df132cc3756deda96bfcce5d453a309e803a15..4835bdc4e9f1819615ab2454549f9a637d01a0e1 100644 (file)
@@ -114,6 +114,17 @@ static struct vm_operations_struct fb_deferred_io_vm_ops = {
        .page_mkwrite   = fb_deferred_io_mkwrite,
 };
 
+static int fb_deferred_io_set_page_dirty(struct page *page)
+{
+       if (!PageDirty(page))
+               SetPageDirty(page);
+       return 0;
+}
+
+static const struct address_space_operations fb_deferred_io_aops = {
+       .set_page_dirty = fb_deferred_io_set_page_dirty,
+};
+
 static int fb_deferred_io_mmap(struct fb_info *info, struct vm_area_struct *vma)
 {
        vma->vm_ops = &fb_deferred_io_vm_ops;
@@ -163,6 +174,14 @@ void fb_deferred_io_init(struct fb_info *info)
 }
 EXPORT_SYMBOL_GPL(fb_deferred_io_init);
 
+void fb_deferred_io_open(struct fb_info *info,
+                        struct inode *inode,
+                        struct file *file)
+{
+       file->f_mapping->a_ops = &fb_deferred_io_aops;
+}
+EXPORT_SYMBOL_GPL(fb_deferred_io_open);
+
 void fb_deferred_io_cleanup(struct fb_info *info)
 {
        void *screen_base = (void __force *) info->screen_base;
index 6b487801eeaedc96e8b65a330363156e32452f6c..98843c2ecf733a17e0742109fa63009d47c9b405 100644 (file)
@@ -1344,6 +1344,10 @@ fb_open(struct inode *inode, struct file *file)
                if (res)
                        module_put(info->fbops->owner);
        }
+#ifdef CONFIG_FB_DEFERRED_IO
+       if (info->fbdefio)
+               fb_deferred_io_open(info, inode, file);
+#endif
 out:
        unlock_kernel();
        return res;
index 3f1ca2adda3d7353fe41529bb9fa59c1085affa3..c6dd924976a4f105457bd15c205a2938a07eeee3 100644 (file)
@@ -1746,6 +1746,7 @@ static void __devexit pm2fb_remove(struct pci_dev *pdev)
        release_mem_region(fix->mmio_start, fix->mmio_len);
 
        pci_set_drvdata(pdev, NULL);
+       fb_dealloc_cmap(&info->cmap);
        kfree(info->pixmap.addr);
        kfree(info);
 }
index 8361bd0e3df1dd55bdbf1f31b3d1eb08802df28a..4dcec48a1d78949e07a78663213e035ec248a5f5 100644 (file)
@@ -11,7 +11,6 @@
  * which is based on the code of neofb.
  */
 
-#include <linux/version.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
index f6ef6cca73cd5390fbde0f2c805893096a9aac08..4c32c06579a04c7826e56f5f5b4f87acf95eeab6 100644 (file)
@@ -595,6 +595,8 @@ static int __init sh_mobile_lcdc_probe(struct platform_device *pdev)
                info->fbops = &sh_mobile_lcdc_ops;
                info->var.xres = info->var.xres_virtual = cfg->lcd_cfg.xres;
                info->var.yres = info->var.yres_virtual = cfg->lcd_cfg.yres;
+               info->var.width = cfg->lcd_size_cfg.width;
+               info->var.height = cfg->lcd_size_cfg.height;
                info->var.activate = FB_ACTIVATE_NOW;
                error = sh_mobile_lcdc_set_bpp(&info->var, cfg->bpp);
                if (error)
index c4aba59d4809a7fce3eec1d0504e926fe67b16bb..7491abfcf1fc4c8f882332ffa83f143069fc4ec8 100644 (file)
@@ -30,7 +30,6 @@
 #define _VERMILION_H_
 
 #include <linux/kernel.h>
-#include <linux/version.h>
 #include <linux/pci.h>
 #include <asm/atomic.h>
 #include <linux/mutex.h>
index 34aae7a2a62b35a3dd2aa4436816f844f588f616..3df17dc8c3d786f5ff2e66f878a888bc35df71c1 100644 (file)
@@ -12,7 +12,6 @@
  * (http://davesdomain.org.uk/viafb/)
  */
 
-#include <linux/version.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
index 7b3a8423f485e340afffb81d6f0dbc4c933eec83..5da3d2423cc0f4cc22ebd2f530414d0ef891bb00 100644 (file)
@@ -24,7 +24,6 @@
 #include <linux/device.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
-#include <linux/version.h>
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/mm.h>
index bfef604160d16460062f46b84f16c9320579c0d4..62eab43152d21314826838080caed9ad3ee3eb1e 100644 (file)
@@ -158,7 +158,7 @@ static inline s64 towards_target(struct virtio_balloon *vb)
        vb->vdev->config->get(vb->vdev,
                              offsetof(struct virtio_balloon_config, num_pages),
                              &v, sizeof(v));
-       return v - vb->num_pages;
+       return (s64)v - vb->num_pages;
 }
 
 static void update_balloon_size(struct virtio_balloon *vb)
index a5bc91ae6ff69f5d5d4b2e9f49e308acd9126b20..d0e87cbe157ca5e4634151f8d997e9d66fb66ebc 100644 (file)
@@ -102,7 +102,7 @@ static void do_suspend(void)
        /* XXX use normal device tree? */
        xenbus_suspend();
 
-       err = stop_machine_run(xen_suspend, &cancelled, 0);
+       err = stop_machine(xen_suspend, &cancelled, &cpumask_of_cpu(0));
        if (err) {
                printk(KERN_ERR "failed to start xen_suspend: %d\n", err);
                goto out;
index 56372ecf16909d8dd7c2e37062c044d2aa147c23..dfc0197905ca1e9d50ce8ff613261b141d6f8439 100644 (file)
@@ -914,7 +914,9 @@ static int load_flat_binary(struct linux_binprm * bprm, struct pt_regs * regs)
        /* Stash our initial stack pointer into the mm structure */
        current->mm->start_stack = (unsigned long )sp;
 
-       
+#ifdef FLAT_PLAT_INIT
+       FLAT_PLAT_INIT(regs);
+#endif
        DBG_FLT("start_thread(regs=0x%x, entry=0x%x, start_stack=0x%x)\n",
                (int)regs, (int)start_addr, (int)current->mm->start_stack);
        
index 756205314c24401fc31ebbb6eb7c479aa4c92145..8d7e88e02e0f9cc13207d86ee090a2594f79497b 100644 (file)
@@ -120,8 +120,6 @@ static int load_misc_binary(struct linux_binprm *bprm, struct pt_regs *regs)
        if (bprm->misc_bang)
                goto _ret;
 
-       bprm->misc_bang = 1;
-
        /* to keep locking time low, we copy the interpreter string */
        read_lock(&entries_lock);
        fmt = check_file(bprm);
@@ -199,6 +197,8 @@ static int load_misc_binary(struct linux_binprm *bprm, struct pt_regs *regs)
        if (retval < 0)
                goto _error;
 
+       bprm->misc_bang = 1;
+
        retval = search_binary_handler (bprm, regs);
        if (retval < 0)
                goto _error;
index 0c3b618c15b3f05bd1adee50fada78b7561a36dc..f40423eb1a14e66b73693f5505a54f00b3bd6f4a 100644 (file)
@@ -43,58 +43,13 @@ static DEFINE_MUTEX(read_mutex);
 static int cramfs_iget5_test(struct inode *inode, void *opaque)
 {
        struct cramfs_inode *cramfs_inode = opaque;
-
-       if (inode->i_ino != CRAMINO(cramfs_inode))
-               return 0; /* does not match */
-
-       if (inode->i_ino != 1)
-               return 1;
-
-       /* all empty directories, char, block, pipe, and sock, share inode #1 */
-
-       if ((inode->i_mode != cramfs_inode->mode) ||
-           (inode->i_gid != cramfs_inode->gid) ||
-           (inode->i_uid != cramfs_inode->uid))
-               return 0; /* does not match */
-
-       if ((S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) &&
-           (inode->i_rdev != old_decode_dev(cramfs_inode->size)))
-               return 0; /* does not match */
-
-       return 1; /* matches */
+       return inode->i_ino == CRAMINO(cramfs_inode) && inode->i_ino != 1;
 }
 
 static int cramfs_iget5_set(struct inode *inode, void *opaque)
 {
-       static struct timespec zerotime;
        struct cramfs_inode *cramfs_inode = opaque;
-       inode->i_mode = cramfs_inode->mode;
-       inode->i_uid = cramfs_inode->uid;
-       inode->i_size = cramfs_inode->size;
-       inode->i_blocks = (cramfs_inode->size - 1) / 512 + 1;
-       inode->i_gid = cramfs_inode->gid;
-       /* Struct copy intentional */
-       inode->i_mtime = inode->i_atime = inode->i_ctime = zerotime;
        inode->i_ino = CRAMINO(cramfs_inode);
-       /* inode->i_nlink is left 1 - arguably wrong for directories,
-          but it's the best we can do without reading the directory
-           contents.  1 yields the right result in GNU find, even
-          without -noleaf option. */
-       if (S_ISREG(inode->i_mode)) {
-               inode->i_fop = &generic_ro_fops;
-               inode->i_data.a_ops = &cramfs_aops;
-       } else if (S_ISDIR(inode->i_mode)) {
-               inode->i_op = &cramfs_dir_inode_operations;
-               inode->i_fop = &cramfs_directory_operations;
-       } else if (S_ISLNK(inode->i_mode)) {
-               inode->i_op = &page_symlink_inode_operations;
-               inode->i_data.a_ops = &cramfs_aops;
-       } else {
-               inode->i_size = 0;
-               inode->i_blocks = 0;
-               init_special_inode(inode, inode->i_mode,
-                       old_decode_dev(cramfs_inode->size));
-       }
        return 0;
 }
 
@@ -104,12 +59,48 @@ static struct inode *get_cramfs_inode(struct super_block *sb,
        struct inode *inode = iget5_locked(sb, CRAMINO(cramfs_inode),
                                            cramfs_iget5_test, cramfs_iget5_set,
                                            cramfs_inode);
+       static struct timespec zerotime;
+
        if (inode && (inode->i_state & I_NEW)) {
+               inode->i_mode = cramfs_inode->mode;
+               inode->i_uid = cramfs_inode->uid;
+               inode->i_size = cramfs_inode->size;
+               inode->i_blocks = (cramfs_inode->size - 1) / 512 + 1;
+               inode->i_gid = cramfs_inode->gid;
+               /* Struct copy intentional */
+               inode->i_mtime = inode->i_atime = inode->i_ctime = zerotime;
+               /* inode->i_nlink is left 1 - arguably wrong for directories,
+                  but it's the best we can do without reading the directory
+                  contents.  1 yields the right result in GNU find, even
+                  without -noleaf option. */
+               if (S_ISREG(inode->i_mode)) {
+                       inode->i_fop = &generic_ro_fops;
+                       inode->i_data.a_ops = &cramfs_aops;
+               } else if (S_ISDIR(inode->i_mode)) {
+                       inode->i_op = &cramfs_dir_inode_operations;
+                       inode->i_fop = &cramfs_directory_operations;
+               } else if (S_ISLNK(inode->i_mode)) {
+                       inode->i_op = &page_symlink_inode_operations;
+                       inode->i_data.a_ops = &cramfs_aops;
+               } else {
+                       inode->i_size = 0;
+                       inode->i_blocks = 0;
+                       init_special_inode(inode, inode->i_mode,
+                               old_decode_dev(cramfs_inode->size));
+               }
                unlock_new_inode(inode);
        }
        return inode;
 }
 
+static void cramfs_drop_inode(struct inode *inode)
+{
+       if (inode->i_ino == 1)
+               generic_delete_inode(inode);
+       else
+               generic_drop_inode(inode);
+}
+
 /*
  * We have our own block cache: don't fill up the buffer cache
  * with the rom-image, because the way the filesystem is set
@@ -534,6 +525,7 @@ static const struct super_operations cramfs_ops = {
        .put_super      = cramfs_put_super,
        .remount_fs     = cramfs_remount,
        .statfs         = cramfs_statfs,
+       .drop_inode     = cramfs_drop_inode,
 };
 
 static int cramfs_get_sb(struct file_system_type *fs_type,
index 1ae5004e93fc20ffd99a652efa6be9897a0518c1..e9fa960ba6da9fa6cf573fc517d70808e519ab83 100644 (file)
@@ -1626,6 +1626,9 @@ ext4_fsblk_t ext4_has_free_blocks(struct ext4_sb_info *sbi,
                free_blocks =
                        percpu_counter_sum_and_set(&sbi->s_freeblocks_counter);
 #endif
+       if (free_blocks <= root_blocks)
+               /* we don't have free space */
+               return 0;
        if (free_blocks - root_blocks < nblocks)
                return free_blocks - root_blocks;
        return nblocks;
index d3d23d73c08b5e5e1584f16f88be892e4903ecfa..ec8e33b452198ba9ab7818884a57e27ff8a20509 100644 (file)
@@ -411,7 +411,7 @@ static int call_filldir(struct file * filp, void * dirent,
                                get_dtype(sb, fname->file_type));
                if (error) {
                        filp->f_pos = curr_pos;
-                       info->extra_fname = fname->next;
+                       info->extra_fname = fname;
                        return error;
                }
                fname = fname->next;
@@ -450,11 +450,21 @@ static int ext4_dx_readdir(struct file * filp,
         * If there are any leftover names on the hash collision
         * chain, return them first.
         */
-       if (info->extra_fname &&
-           call_filldir(filp, dirent, filldir, info->extra_fname))
-               goto finished;
+       if (info->extra_fname) {
+               if (call_filldir(filp, dirent, filldir, info->extra_fname))
+                       goto finished;
 
-       if (!info->curr_node)
+               info->extra_fname = NULL;
+               info->curr_node = rb_next(info->curr_node);
+               if (!info->curr_node) {
+                       if (info->next_hash == ~0) {
+                               filp->f_pos = EXT4_HTREE_EOF;
+                               goto finished;
+                       }
+                       info->curr_hash = info->next_hash;
+                       info->curr_minor_hash = 0;
+               }
+       } else if (!info->curr_node)
                info->curr_node = rb_first(&info->root);
 
        while (1) {
index 6c7924d9e358caf3c0803dc43d0d26b76dd9b620..295003241d3d7dbb3b4127dcbb7357c2327d0146 100644 (file)
@@ -1072,6 +1072,8 @@ extern void ext4_set_inode_flags(struct inode *);
 extern void ext4_get_inode_flags(struct ext4_inode_info *);
 extern void ext4_set_aops(struct inode *inode);
 extern int ext4_writepage_trans_blocks(struct inode *);
+extern int ext4_meta_trans_blocks(struct inode *, int nrblocks, int idxblocks);
+extern int ext4_chunk_trans_blocks(struct inode *, int nrblocks);
 extern int ext4_block_truncate_page(handle_t *handle,
                struct address_space *mapping, loff_t from);
 extern int ext4_page_mkwrite(struct vm_area_struct *vma, struct page *page);
@@ -1227,6 +1229,8 @@ extern const struct inode_operations ext4_fast_symlink_inode_operations;
 /* extents.c */
 extern int ext4_ext_tree_init(handle_t *handle, struct inode *);
 extern int ext4_ext_writepage_trans_blocks(struct inode *, int);
+extern int ext4_ext_index_trans_blocks(struct inode *inode, int nrblocks,
+                                      int chunk);
 extern int ext4_ext_get_blocks(handle_t *handle, struct inode *inode,
                        ext4_lblk_t iblock,
                        unsigned long max_blocks, struct buffer_head *bh_result,
index 6c166c0a54b7ea24a49a90681e0284dee3d364d6..d33dc56d6986e785ea6e75f9a256cf2191fc6b74 100644 (file)
@@ -216,7 +216,9 @@ extern int ext4_ext_calc_metadata_amount(struct inode *inode, int blocks);
 extern ext4_fsblk_t idx_pblock(struct ext4_extent_idx *);
 extern void ext4_ext_store_pblock(struct ext4_extent *, ext4_fsblk_t);
 extern int ext4_extent_tree_init(handle_t *, struct inode *);
-extern int ext4_ext_calc_credits_for_insert(struct inode *, struct ext4_ext_path *);
+extern int ext4_ext_calc_credits_for_single_extent(struct inode *inode,
+                                                  int num,
+                                                  struct ext4_ext_path *path);
 extern int ext4_ext_try_to_merge(struct inode *inode,
                                 struct ext4_ext_path *path,
                                 struct ext4_extent *);
index eb8bc3afe6e9f590f491bf9098980f39f27bf245..b455c685a98b5cb779654fa22826622899ca6133 100644 (file)
                                         EXT4_XATTR_TRANS_BLOCKS - 2 + \
                                         2*EXT4_QUOTA_TRANS_BLOCKS(sb))
 
+/*
+ * Define the number of metadata blocks we need to account to modify data.
+ *
+ * This include super block, inode block, quota blocks and xattr blocks
+ */
+#define EXT4_META_TRANS_BLOCKS(sb)     (EXT4_XATTR_TRANS_BLOCKS + \
+                                       2*EXT4_QUOTA_TRANS_BLOCKS(sb))
+
 /* Delete operations potentially hit one directory's namespace plus an
  * entire inode, plus arbitrary amounts of bitmap/indirection data.  Be
  * generous.  We can grow the delete transaction later if necessary. */
index 612c3d2c38240ff59a643bcbf405c2229443a848..b24d3c53f20cd20407d5d5373c79b725d308cc45 100644 (file)
@@ -1747,54 +1747,61 @@ static int ext4_ext_rm_idx(handle_t *handle, struct inode *inode,
 }
 
 /*
- * ext4_ext_calc_credits_for_insert:
- * This routine returns max. credits that the extent tree can consume.
- * It should be OK for low-performance paths like ->writepage()
- * To allow many writing processes to fit into a single transaction,
- * the caller should calculate credits under i_data_sem and
- * pass the actual path.
+ * ext4_ext_calc_credits_for_single_extent:
+ * This routine returns max. credits that needed to insert an extent
+ * to the extent tree.
+ * When pass the actual path, the caller should calculate credits
+ * under i_data_sem.
  */
-int ext4_ext_calc_credits_for_insert(struct inode *inode,
+int ext4_ext_calc_credits_for_single_extent(struct inode *inode, int nrblocks,
                                                struct ext4_ext_path *path)
 {
-       int depth, needed;
-
        if (path) {
+               int depth = ext_depth(inode);
+               int ret = 0;
+
                /* probably there is space in leaf? */
-               depth = ext_depth(inode);
                if (le16_to_cpu(path[depth].p_hdr->eh_entries)
-                               < le16_to_cpu(path[depth].p_hdr->eh_max))
-                       return 1;
-       }
+                               < le16_to_cpu(path[depth].p_hdr->eh_max)) {
 
-       /*
-        * given 32-bit logical block (4294967296 blocks), max. tree
-        * can be 4 levels in depth -- 4 * 340^4 == 53453440000.
-        * Let's also add one more level for imbalance.
-        */
-       depth = 5;
-
-       /* allocation of new data block(s) */
-       needed = 2;
+                       /*
+                        *  There are some space in the leaf tree, no
+                        *  need to account for leaf block credit
+                        *
+                        *  bitmaps and block group descriptor blocks
+                        *  and other metadat blocks still need to be
+                        *  accounted.
+                        */
+                       /* 1 bitmap, 1 block group descriptor */
+                       ret = 2 + EXT4_META_TRANS_BLOCKS(inode->i_sb);
+               }
+       }
 
-       /*
-        * tree can be full, so it would need to grow in depth:
-        * we need one credit to modify old root, credits for
-        * new root will be added in split accounting
-        */
-       needed += 1;
+       return ext4_chunk_trans_blocks(inode, nrblocks);
+}
 
-       /*
-        * Index split can happen, we would need:
-        *    allocate intermediate indexes (bitmap + group)
-        *  + change two blocks at each level, but root (already included)
-        */
-       needed += (depth * 2) + (depth * 2);
+/*
+ * How many index/leaf blocks need to change/allocate to modify nrblocks?
+ *
+ * if nrblocks are fit in a single extent (chunk flag is 1), then
+ * in the worse case, each tree level index/leaf need to be changed
+ * if the tree split due to insert a new extent, then the old tree
+ * index/leaf need to be updated too
+ *
+ * If the nrblocks are discontiguous, they could cause
+ * the whole tree split more than once, but this is really rare.
+ */
+int ext4_ext_index_trans_blocks(struct inode *inode, int nrblocks, int chunk)
+{
+       int index;
+       int depth = ext_depth(inode);
 
-       /* any allocation modifies superblock */
-       needed += 1;
+       if (chunk)
+               index = depth * 2;
+       else
+               index = depth * 3;
 
-       return needed;
+       return index;
 }
 
 static int ext4_remove_blocks(handle_t *handle, struct inode *inode,
@@ -1921,9 +1928,7 @@ ext4_ext_rm_leaf(handle_t *handle, struct inode *inode,
                        correct_index = 1;
                        credits += (ext_depth(inode)) + 1;
                }
-#ifdef CONFIG_QUOTA
                credits += 2 * EXT4_QUOTA_TRANS_BLOCKS(inode->i_sb);
-#endif
 
                err = ext4_ext_journal_restart(handle, credits);
                if (err)
@@ -2805,7 +2810,7 @@ void ext4_ext_truncate(struct inode *inode)
        /*
         * probably first extent we're gonna free will be last in block
         */
-       err = ext4_writepage_trans_blocks(inode) + 3;
+       err = ext4_writepage_trans_blocks(inode);
        handle = ext4_journal_start(inode, err);
        if (IS_ERR(handle))
                return;
@@ -2819,7 +2824,7 @@ void ext4_ext_truncate(struct inode *inode)
        down_write(&EXT4_I(inode)->i_data_sem);
        ext4_ext_invalidate_cache(inode);
 
-       ext4_mb_discard_inode_preallocations(inode);
+       ext4_discard_reservation(inode);
 
        /*
         * TODO: optimization is possible here.
@@ -2858,27 +2863,6 @@ out_stop:
        ext4_journal_stop(handle);
 }
 
-/*
- * ext4_ext_writepage_trans_blocks:
- * calculate max number of blocks we could modify
- * in order to allocate new block for an inode
- */
-int ext4_ext_writepage_trans_blocks(struct inode *inode, int num)
-{
-       int needed;
-
-       needed = ext4_ext_calc_credits_for_insert(inode, NULL);
-
-       /* caller wants to allocate num blocks, but note it includes sb */
-       needed = needed * num - (num - 1);
-
-#ifdef CONFIG_QUOTA
-       needed += 2 * EXT4_QUOTA_TRANS_BLOCKS(inode->i_sb);
-#endif
-
-       return needed;
-}
-
 static void ext4_falloc_update_inode(struct inode *inode,
                                int mode, loff_t new_size, int update_ctime)
 {
@@ -2939,10 +2923,9 @@ long ext4_fallocate(struct inode *inode, int mode, loff_t offset, loff_t len)
        max_blocks = (EXT4_BLOCK_ALIGN(len + offset, blkbits) >> blkbits)
                                                        - block;
        /*
-        * credits to insert 1 extent into extent tree + buffers to be able to
-        * modify 1 super block, 1 block bitmap and 1 group descriptor.
+        * credits to insert 1 extent into extent tree
         */
-       credits = EXT4_DATA_TRANS_BLOCKS(inode->i_sb) + 3;
+       credits = ext4_chunk_trans_blocks(inode, max_blocks);
        mutex_lock(&inode->i_mutex);
 retry:
        while (ret >= 0 && ret < max_blocks) {
index 655e760212b871655c2fa55a0e0f1b889476ae77..f344834bbf58a4f0228b5ab85243d8bba1b1d648 100644 (file)
@@ -351,7 +351,7 @@ find_close_to_parent:
                        goto found_flexbg;
                }
 
-               if (best_flex < 0 ||
+               if (flex_group[best_flex].free_inodes == 0 ||
                    (flex_group[i].free_blocks >
                     flex_group[best_flex].free_blocks &&
                     flex_group[i].free_inodes))
index 59fbbe899acc24a5817befbc67fda67ba427b3d1..7e91913e325bb511086c5a2ddb0ddeda0bc28e01 100644 (file)
@@ -41,6 +41,8 @@
 #include "acl.h"
 #include "ext4_extents.h"
 
+#define MPAGE_DA_EXTENT_TAIL 0x01
+
 static inline int ext4_begin_ordered_truncate(struct inode *inode,
                                              loff_t new_size)
 {
@@ -1005,6 +1007,9 @@ static int ext4_indirect_calc_metadata_amount(struct inode *inode, int blocks)
  */
 static int ext4_calc_metadata_amount(struct inode *inode, int blocks)
 {
+       if (!blocks)
+               return 0;
+
        if (EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL)
                return ext4_ext_calc_metadata_amount(inode, blocks);
 
@@ -1041,18 +1046,6 @@ static void ext4_da_update_reserve_space(struct inode *inode, int used)
        spin_unlock(&EXT4_I(inode)->i_block_reservation_lock);
 }
 
-/* Maximum number of blocks we map for direct IO at once. */
-#define DIO_MAX_BLOCKS 4096
-/*
- * Number of credits we need for writing DIO_MAX_BLOCKS:
- * We need sb + group descriptor + bitmap + inode -> 4
- * For B blocks with A block pointers per block we need:
- * 1 (triple ind.) + (B/A/A + 2) (doubly ind.) + (B/A + 2) (indirect).
- * If we plug in 4096 for B and 256 for A (for 1KB block size), we get 25.
- */
-#define DIO_CREDITS 25
-
-
 /*
  * The ext4_get_blocks_wrap() function try to look up the requested blocks,
  * and returns if the blocks are already mapped.
@@ -1164,19 +1157,23 @@ int ext4_get_blocks_wrap(handle_t *handle, struct inode *inode, sector_t block,
        return retval;
 }
 
+/* Maximum number of blocks we map for direct IO at once. */
+#define DIO_MAX_BLOCKS 4096
+
 static int ext4_get_block(struct inode *inode, sector_t iblock,
                        struct buffer_head *bh_result, int create)
 {
        handle_t *handle = ext4_journal_current_handle();
        int ret = 0, started = 0;
        unsigned max_blocks = bh_result->b_size >> inode->i_blkbits;
+       int dio_credits;
 
        if (create && !handle) {
                /* Direct IO write... */
                if (max_blocks > DIO_MAX_BLOCKS)
                        max_blocks = DIO_MAX_BLOCKS;
-               handle = ext4_journal_start(inode, DIO_CREDITS +
-                             2 * EXT4_QUOTA_TRANS_BLOCKS(inode->i_sb));
+               dio_credits = ext4_chunk_trans_blocks(inode, max_blocks);
+               handle = ext4_journal_start(inode, dio_credits);
                if (IS_ERR(handle)) {
                        ret = PTR_ERR(handle);
                        goto out;
@@ -1559,7 +1556,25 @@ static void ext4_da_release_space(struct inode *inode, int to_free)
        struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
        int total, mdb, mdb_free, release;
 
+       if (!to_free)
+               return;         /* Nothing to release, exit */
+
        spin_lock(&EXT4_I(inode)->i_block_reservation_lock);
+
+       if (!EXT4_I(inode)->i_reserved_data_blocks) {
+               /*
+                * if there is no reserved blocks, but we try to free some
+                * then the counter is messed up somewhere.
+                * but since this function is called from invalidate
+                * page, it's harmless to return without any action
+                */
+               printk(KERN_INFO "ext4 delalloc try to release %d reserved "
+                           "blocks for inode %lu, but there is no reserved "
+                           "data blocks\n", to_free, inode->i_ino);
+               spin_unlock(&EXT4_I(inode)->i_block_reservation_lock);
+               return;
+       }
+
        /* recalculate the number of metablocks still need to be reserved */
        total = EXT4_I(inode)->i_reserved_data_blocks - to_free;
        mdb = ext4_calc_metadata_amount(inode, total);
@@ -1613,11 +1628,13 @@ struct mpage_da_data {
        unsigned long first_page, next_page;    /* extent of pages */
        get_block_t *get_block;
        struct writeback_control *wbc;
+       int io_done;
+       long pages_written;
 };
 
 /*
  * mpage_da_submit_io - walks through extent of pages and try to write
- * them with __mpage_writepage()
+ * them with writepage() call back
  *
  * @mpd->inode: inode
  * @mpd->first_page: first page of the extent
@@ -1632,18 +1649,11 @@ struct mpage_da_data {
 static int mpage_da_submit_io(struct mpage_da_data *mpd)
 {
        struct address_space *mapping = mpd->inode->i_mapping;
-       struct mpage_data mpd_pp = {
-               .bio = NULL,
-               .last_block_in_bio = 0,
-               .get_block = mpd->get_block,
-               .use_writepage = 1,
-       };
        int ret = 0, err, nr_pages, i;
        unsigned long index, end;
        struct pagevec pvec;
 
        BUG_ON(mpd->next_page <= mpd->first_page);
-
        pagevec_init(&pvec, 0);
        index = mpd->first_page;
        end = mpd->next_page - 1;
@@ -1661,8 +1671,9 @@ static int mpage_da_submit_io(struct mpage_da_data *mpd)
                                break;
                        index++;
 
-                       err = __mpage_writepage(page, mpd->wbc, &mpd_pp);
-
+                       err = mapping->a_ops->writepage(page, mpd->wbc);
+                       if (!err)
+                               mpd->pages_written++;
                        /*
                         * In error case, we have to continue because
                         * remaining pages are still locked
@@ -1673,9 +1684,6 @@ static int mpage_da_submit_io(struct mpage_da_data *mpd)
                }
                pagevec_release(&pvec);
        }
-       if (mpd_pp.bio)
-               mpage_bio_submit(WRITE, mpd_pp.bio);
-
        return ret;
 }
 
@@ -1698,7 +1706,7 @@ static void mpage_put_bnr_to_bhs(struct mpage_da_data *mpd, sector_t logical,
        int blocks = exbh->b_size >> inode->i_blkbits;
        sector_t pblock = exbh->b_blocknr, cur_logical;
        struct buffer_head *head, *bh;
-       unsigned long index, end;
+       pgoff_t index, end;
        struct pagevec pvec;
        int nr_pages, i;
 
@@ -1741,6 +1749,13 @@ static void mpage_put_bnr_to_bhs(struct mpage_da_data *mpd, sector_t logical,
                                if (buffer_delay(bh)) {
                                        bh->b_blocknr = pblock;
                                        clear_buffer_delay(bh);
+                                       bh->b_bdev = inode->i_sb->s_bdev;
+                               } else if (buffer_unwritten(bh)) {
+                                       bh->b_blocknr = pblock;
+                                       clear_buffer_unwritten(bh);
+                                       set_buffer_mapped(bh);
+                                       set_buffer_new(bh);
+                                       bh->b_bdev = inode->i_sb->s_bdev;
                                } else if (buffer_mapped(bh))
                                        BUG_ON(bh->b_blocknr != pblock);
 
@@ -1776,13 +1791,11 @@ static inline void __unmap_underlying_blocks(struct inode *inode,
  *
  * The function skips space we know is already mapped to disk blocks.
  *
- * The function ignores errors ->get_block() returns, thus real
- * error handling is postponed to __mpage_writepage()
  */
 static void mpage_da_map_blocks(struct mpage_da_data *mpd)
 {
+       int err = 0;
        struct buffer_head *lbh = &mpd->lbh;
-       int err = 0, remain = lbh->b_size;
        sector_t next = lbh->b_blocknr;
        struct buffer_head new;
 
@@ -1792,38 +1805,36 @@ static void mpage_da_map_blocks(struct mpage_da_data *mpd)
        if (buffer_mapped(lbh) && !buffer_delay(lbh))
                return;
 
-       while (remain) {
-               new.b_state = lbh->b_state;
-               new.b_blocknr = 0;
-               new.b_size = remain;
-               err = mpd->get_block(mpd->inode, next, &new, 1);
-               if (err) {
-                       /*
-                        * Rather than implement own error handling
-                        * here, we just leave remaining blocks
-                        * unallocated and try again with ->writepage()
-                        */
-                       break;
-               }
-               BUG_ON(new.b_size == 0);
+       new.b_state = lbh->b_state;
+       new.b_blocknr = 0;
+       new.b_size = lbh->b_size;
 
-               if (buffer_new(&new))
-                       __unmap_underlying_blocks(mpd->inode, &new);
+       /*
+        * If we didn't accumulate anything
+        * to write simply return
+        */
+       if (!new.b_size)
+               return;
+       err = mpd->get_block(mpd->inode, next, &new, 1);
+       if (err)
+               return;
+       BUG_ON(new.b_size == 0);
 
-               /*
-                * If blocks are delayed marked, we need to
-                * put actual blocknr and drop delayed bit
-                */
-               if (buffer_delay(lbh))
-                       mpage_put_bnr_to_bhs(mpd, next, &new);
+       if (buffer_new(&new))
+               __unmap_underlying_blocks(mpd->inode, &new);
 
-               /* go for the remaining blocks */
-               next += new.b_size >> mpd->inode->i_blkbits;
-               remain -= new.b_size;
-       }
+       /*
+        * If blocks are delayed marked, we need to
+        * put actual blocknr and drop delayed bit
+        */
+       if (buffer_delay(lbh) || buffer_unwritten(lbh))
+               mpage_put_bnr_to_bhs(mpd, next, &new);
+
+       return;
 }
 
-#define BH_FLAGS ((1 << BH_Uptodate) | (1 << BH_Mapped) | (1 << BH_Delay))
+#define BH_FLAGS ((1 << BH_Uptodate) | (1 << BH_Mapped) | \
+               (1 << BH_Delay) | (1 << BH_Unwritten))
 
 /*
  * mpage_add_bh_to_extent - try to add one more block to extent of blocks
@@ -1837,41 +1848,61 @@ static void mpage_da_map_blocks(struct mpage_da_data *mpd)
 static void mpage_add_bh_to_extent(struct mpage_da_data *mpd,
                                   sector_t logical, struct buffer_head *bh)
 {
-       struct buffer_head *lbh = &mpd->lbh;
        sector_t next;
+       size_t b_size = bh->b_size;
+       struct buffer_head *lbh = &mpd->lbh;
+       int nrblocks = lbh->b_size >> mpd->inode->i_blkbits;
 
-       next = lbh->b_blocknr + (lbh->b_size >> mpd->inode->i_blkbits);
-
+       /* check if thereserved journal credits might overflow */
+       if (!(EXT4_I(mpd->inode)->i_flags & EXT4_EXTENTS_FL)) {
+               if (nrblocks >= EXT4_MAX_TRANS_DATA) {
+                       /*
+                        * With non-extent format we are limited by the journal
+                        * credit available.  Total credit needed to insert
+                        * nrblocks contiguous blocks is dependent on the
+                        * nrblocks.  So limit nrblocks.
+                        */
+                       goto flush_it;
+               } else if ((nrblocks + (b_size >> mpd->inode->i_blkbits)) >
+                               EXT4_MAX_TRANS_DATA) {
+                       /*
+                        * Adding the new buffer_head would make it cross the
+                        * allowed limit for which we have journal credit
+                        * reserved. So limit the new bh->b_size
+                        */
+                       b_size = (EXT4_MAX_TRANS_DATA - nrblocks) <<
+                                               mpd->inode->i_blkbits;
+                       /* we will do mpage_da_submit_io in the next loop */
+               }
+       }
        /*
         * First block in the extent
         */
        if (lbh->b_size == 0) {
                lbh->b_blocknr = logical;
-               lbh->b_size = bh->b_size;
+               lbh->b_size = b_size;
                lbh->b_state = bh->b_state & BH_FLAGS;
                return;
        }
 
+       next = lbh->b_blocknr + nrblocks;
        /*
         * Can we merge the block to our big extent?
         */
        if (logical == next && (bh->b_state & BH_FLAGS) == lbh->b_state) {
-               lbh->b_size += bh->b_size;
+               lbh->b_size += b_size;
                return;
        }
 
+flush_it:
        /*
         * We couldn't merge the block to our extent, so we
         * need to flush current  extent and start new one
         */
        mpage_da_map_blocks(mpd);
-
-       /*
-        * Now start a new extent
-        */
-       lbh->b_size = bh->b_size;
-       lbh->b_state = bh->b_state & BH_FLAGS;
-       lbh->b_blocknr = logical;
+       mpage_da_submit_io(mpd);
+       mpd->io_done = 1;
+       return;
 }
 
 /*
@@ -1891,17 +1922,35 @@ static int __mpage_da_writepage(struct page *page,
        struct buffer_head *bh, *head, fake;
        sector_t logical;
 
+       if (mpd->io_done) {
+               /*
+                * Rest of the page in the page_vec
+                * redirty then and skip then. We will
+                * try to to write them again after
+                * starting a new transaction
+                */
+               redirty_page_for_writepage(wbc, page);
+               unlock_page(page);
+               return MPAGE_DA_EXTENT_TAIL;
+       }
        /*
         * Can we merge this page to current extent?
         */
        if (mpd->next_page != page->index) {
                /*
                 * Nope, we can't. So, we map non-allocated blocks
-                * and start IO on them using __mpage_writepage()
+                * and start IO on them using writepage()
                 */
                if (mpd->next_page != mpd->first_page) {
                        mpage_da_map_blocks(mpd);
                        mpage_da_submit_io(mpd);
+                       /*
+                        * skip rest of the page in the page_vec
+                        */
+                       mpd->io_done = 1;
+                       redirty_page_for_writepage(wbc, page);
+                       unlock_page(page);
+                       return MPAGE_DA_EXTENT_TAIL;
                }
 
                /*
@@ -1932,6 +1981,8 @@ static int __mpage_da_writepage(struct page *page,
                set_buffer_dirty(bh);
                set_buffer_uptodate(bh);
                mpage_add_bh_to_extent(mpd, logical, bh);
+               if (mpd->io_done)
+                       return MPAGE_DA_EXTENT_TAIL;
        } else {
                /*
                 * Page with regular buffer heads, just add all dirty ones
@@ -1940,8 +1991,12 @@ static int __mpage_da_writepage(struct page *page,
                bh = head;
                do {
                        BUG_ON(buffer_locked(bh));
-                       if (buffer_dirty(bh))
+                       if (buffer_dirty(bh) &&
+                               (!buffer_mapped(bh) || buffer_delay(bh))) {
                                mpage_add_bh_to_extent(mpd, logical, bh);
+                               if (mpd->io_done)
+                                       return MPAGE_DA_EXTENT_TAIL;
+                       }
                        logical++;
                } while ((bh = bh->b_this_page) != head);
        }
@@ -1960,22 +2015,13 @@ static int __mpage_da_writepage(struct page *page,
  *
  * This is a library function, which implements the writepages()
  * address_space_operation.
- *
- * In order to avoid duplication of logic that deals with partial pages,
- * multiple bio per page, etc, we find non-allocated blocks, allocate
- * them with minimal calls to ->get_block() and re-use __mpage_writepage()
- *
- * It's important that we call __mpage_writepage() only once for each
- * involved page, otherwise we'd have to implement more complicated logic
- * to deal with pages w/o PG_lock or w/ PG_writeback and so on.
- *
- * See comments to mpage_writepages()
  */
 static int mpage_da_writepages(struct address_space *mapping,
                               struct writeback_control *wbc,
                               get_block_t get_block)
 {
        struct mpage_da_data mpd;
+       long to_write;
        int ret;
 
        if (!get_block)
@@ -1989,17 +2035,22 @@ static int mpage_da_writepages(struct address_space *mapping,
        mpd.first_page = 0;
        mpd.next_page = 0;
        mpd.get_block = get_block;
+       mpd.io_done = 0;
+       mpd.pages_written = 0;
+
+       to_write = wbc->nr_to_write;
 
        ret = write_cache_pages(mapping, wbc, __mpage_da_writepage, &mpd);
 
        /*
         * Handle last extent of pages
         */
-       if (mpd.next_page != mpd.first_page) {
+       if (!mpd.io_done && mpd.next_page != mpd.first_page) {
                mpage_da_map_blocks(&mpd);
                mpage_da_submit_io(&mpd);
        }
 
+       wbc->nr_to_write = to_write - mpd.pages_written;
        return ret;
 }
 
@@ -2204,63 +2255,95 @@ static int ext4_da_writepage(struct page *page,
 }
 
 /*
- * For now just follow the DIO way to estimate the max credits
- * needed to write out EXT4_MAX_WRITEBACK_PAGES.
- * todo: need to calculate the max credits need for
- * extent based files, currently the DIO credits is based on
- * indirect-blocks mapping way.
- *
- * Probably should have a generic way to calculate credits
- * for DIO, writepages, and truncate
+ * This is called via ext4_da_writepages() to
+ * calulate the total number of credits to reserve to fit
+ * a single extent allocation into a single transaction,
+ * ext4_da_writpeages() will loop calling this before
+ * the block allocation.
  */
-#define EXT4_MAX_WRITEBACK_PAGES      DIO_MAX_BLOCKS
-#define EXT4_MAX_WRITEBACK_CREDITS    DIO_CREDITS
+
+static int ext4_da_writepages_trans_blocks(struct inode *inode)
+{
+       int max_blocks = EXT4_I(inode)->i_reserved_data_blocks;
+
+       /*
+        * With non-extent format the journal credit needed to
+        * insert nrblocks contiguous block is dependent on
+        * number of contiguous block. So we will limit
+        * number of contiguous block to a sane value
+        */
+       if (!(inode->i_flags & EXT4_EXTENTS_FL) &&
+           (max_blocks > EXT4_MAX_TRANS_DATA))
+               max_blocks = EXT4_MAX_TRANS_DATA;
+
+       return ext4_chunk_trans_blocks(inode, max_blocks);
+}
 
 static int ext4_da_writepages(struct address_space *mapping,
-                               struct writeback_control *wbc)
+                             struct writeback_control *wbc)
 {
-       struct inode *inode = mapping->host;
        handle_t *handle = NULL;
-       int needed_blocks;
-       int ret = 0;
-       long to_write;
        loff_t range_start = 0;
+       struct inode *inode = mapping->host;
+       int needed_blocks, ret = 0, nr_to_writebump = 0;
+       long to_write, pages_skipped = 0;
+       struct ext4_sb_info *sbi = EXT4_SB(mapping->host->i_sb);
 
        /*
         * No pages to write? This is mainly a kludge to avoid starting
         * a transaction for special inodes like journal inode on last iput()
         * because that could violate lock ordering on umount
         */
-       if (!mapping->nrpages)
+       if (!mapping->nrpages || !mapping_tagged(mapping, PAGECACHE_TAG_DIRTY))
                return 0;
-
        /*
-        * Estimate the worse case needed credits to write out
-        * EXT4_MAX_BUF_BLOCKS pages
+        * Make sure nr_to_write is >= sbi->s_mb_stream_request
+        * This make sure small files blocks are allocated in
+        * single attempt. This ensure that small files
+        * get less fragmented.
         */
-       needed_blocks = EXT4_MAX_WRITEBACK_CREDITS;
+       if (wbc->nr_to_write < sbi->s_mb_stream_request) {
+               nr_to_writebump = sbi->s_mb_stream_request - wbc->nr_to_write;
+               wbc->nr_to_write = sbi->s_mb_stream_request;
+       }
 
-       to_write = wbc->nr_to_write;
-       if (!wbc->range_cyclic) {
+       if (!wbc->range_cyclic)
                /*
                 * If range_cyclic is not set force range_cont
                 * and save the old writeback_index
                 */
                wbc->range_cont = 1;
-               range_start =  wbc->range_start;
-       }
 
-       while (!ret && to_write) {
+       range_start =  wbc->range_start;
+       pages_skipped = wbc->pages_skipped;
+
+restart_loop:
+       to_write = wbc->nr_to_write;
+       while (!ret && to_write > 0) {
+
+               /*
+                * we  insert one extent at a time. So we need
+                * credit needed for single extent allocation.
+                * journalled mode is currently not supported
+                * by delalloc
+                */
+               BUG_ON(ext4_should_journal_data(inode));
+               needed_blocks = ext4_da_writepages_trans_blocks(inode);
+
                /* start a new transaction*/
                handle = ext4_journal_start(inode, needed_blocks);
                if (IS_ERR(handle)) {
                        ret = PTR_ERR(handle);
+                       printk(KERN_EMERG "%s: jbd2_start: "
+                              "%ld pages, ino %lu; err %d\n", __func__,
+                               wbc->nr_to_write, inode->i_ino, ret);
+                       dump_stack();
                        goto out_writepages;
                }
                if (ext4_should_order_data(inode)) {
                        /*
                         * With ordered mode we need to add
-                        * the inode to the journal handle
+                        * the inode to the journal handl
                         * when we do block allocation.
                         */
                        ret = ext4_jbd2_file_inode(handle, inode);
@@ -2268,20 +2351,20 @@ static int ext4_da_writepages(struct address_space *mapping,
                                ext4_journal_stop(handle);
                                goto out_writepages;
                        }
-
                }
-               /*
-                * set the max dirty pages could be write at a time
-                * to fit into the reserved transaction credits
-                */
-               if (wbc->nr_to_write > EXT4_MAX_WRITEBACK_PAGES)
-                       wbc->nr_to_write = EXT4_MAX_WRITEBACK_PAGES;
 
                to_write -= wbc->nr_to_write;
                ret = mpage_da_writepages(mapping, wbc,
-                                               ext4_da_get_block_write);
+                                         ext4_da_get_block_write);
                ext4_journal_stop(handle);
-               if (wbc->nr_to_write) {
+               if (ret == MPAGE_DA_EXTENT_TAIL) {
+                       /*
+                        * got one extent now try with
+                        * rest of the pages
+                        */
+                       to_write += wbc->nr_to_write;
+                       ret = 0;
+               } else if (wbc->nr_to_write) {
                        /*
                         * There is no more writeout needed
                         * or we requested for a noblocking writeout
@@ -2293,10 +2376,18 @@ static int ext4_da_writepages(struct address_space *mapping,
                wbc->nr_to_write = to_write;
        }
 
-out_writepages:
-       wbc->nr_to_write = to_write;
-       if (range_start)
+       if (wbc->range_cont && (pages_skipped != wbc->pages_skipped)) {
+               /* We skipped pages in this loop */
                wbc->range_start = range_start;
+               wbc->nr_to_write = to_write +
+                               wbc->pages_skipped - pages_skipped;
+               wbc->pages_skipped = pages_skipped;
+               goto restart_loop;
+       }
+
+out_writepages:
+       wbc->nr_to_write = to_write - nr_to_writebump;
+       wbc->range_start = range_start;
        return ret;
 }
 
@@ -3486,6 +3577,9 @@ void ext4_truncate(struct inode *inode)
         * modify the block allocation tree.
         */
        down_write(&ei->i_data_sem);
+
+       ext4_discard_reservation(inode);
+
        /*
         * The orphan list entry will now protect us from any crash which
         * occurs before the truncate completes, so it is now safe to propagate
@@ -3555,8 +3649,6 @@ do_indirects:
                ;
        }
 
-       ext4_discard_reservation(inode);
-
        up_write(&ei->i_data_sem);
        inode->i_mtime = inode->i_ctime = ext4_current_time(inode);
        ext4_mark_inode_dirty(handle, inode);
@@ -4324,56 +4416,128 @@ int ext4_getattr(struct vfsmount *mnt, struct dentry *dentry,
        return 0;
 }
 
+static int ext4_indirect_trans_blocks(struct inode *inode, int nrblocks,
+                                     int chunk)
+{
+       int indirects;
+
+       /* if nrblocks are contiguous */
+       if (chunk) {
+               /*
+                * With N contiguous data blocks, it need at most
+                * N/EXT4_ADDR_PER_BLOCK(inode->i_sb) indirect blocks
+                * 2 dindirect blocks
+                * 1 tindirect block
+                */
+               indirects = nrblocks / EXT4_ADDR_PER_BLOCK(inode->i_sb);
+               return indirects + 3;
+       }
+       /*
+        * if nrblocks are not contiguous, worse case, each block touch
+        * a indirect block, and each indirect block touch a double indirect
+        * block, plus a triple indirect block
+        */
+       indirects = nrblocks * 2 + 1;
+       return indirects;
+}
+
+static int ext4_index_trans_blocks(struct inode *inode, int nrblocks, int chunk)
+{
+       if (!(EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL))
+               return ext4_indirect_trans_blocks(inode, nrblocks, 0);
+       return ext4_ext_index_trans_blocks(inode, nrblocks, 0);
+}
 /*
- * How many blocks doth make a writepage()?
- *
- * With N blocks per page, it may be:
- * N data blocks
- * 2 indirect block
- * 2 dindirect
- * 1 tindirect
- * N+5 bitmap blocks (from the above)
- * N+5 group descriptor summary blocks
- * 1 inode block
- * 1 superblock.
- * 2 * EXT4_SINGLEDATA_TRANS_BLOCKS for the quote files
+ * Account for index blocks, block groups bitmaps and block group
+ * descriptor blocks if modify datablocks and index blocks
+ * worse case, the indexs blocks spread over different block groups
  *
- * 3 * (N + 5) + 2 + 2 * EXT4_SINGLEDATA_TRANS_BLOCKS
+ * If datablocks are discontiguous, they are possible to spread over
+ * different block groups too. If they are contiugous, with flexbg,
+ * they could still across block group boundary.
  *
- * With ordered or writeback data it's the same, less the N data blocks.
+ * Also account for superblock, inode, quota and xattr blocks
+ */
+int ext4_meta_trans_blocks(struct inode *inode, int nrblocks, int chunk)
+{
+       int groups, gdpblocks;
+       int idxblocks;
+       int ret = 0;
+
+       /*
+        * How many index blocks need to touch to modify nrblocks?
+        * The "Chunk" flag indicating whether the nrblocks is
+        * physically contiguous on disk
+        *
+        * For Direct IO and fallocate, they calls get_block to allocate
+        * one single extent at a time, so they could set the "Chunk" flag
+        */
+       idxblocks = ext4_index_trans_blocks(inode, nrblocks, chunk);
+
+       ret = idxblocks;
+
+       /*
+        * Now let's see how many group bitmaps and group descriptors need
+        * to account
+        */
+       groups = idxblocks;
+       if (chunk)
+               groups += 1;
+       else
+               groups += nrblocks;
+
+       gdpblocks = groups;
+       if (groups > EXT4_SB(inode->i_sb)->s_groups_count)
+               groups = EXT4_SB(inode->i_sb)->s_groups_count;
+       if (groups > EXT4_SB(inode->i_sb)->s_gdb_count)
+               gdpblocks = EXT4_SB(inode->i_sb)->s_gdb_count;
+
+       /* bitmaps and block group descriptor blocks */
+       ret += groups + gdpblocks;
+
+       /* Blocks for super block, inode, quota and xattr blocks */
+       ret += EXT4_META_TRANS_BLOCKS(inode->i_sb);
+
+       return ret;
+}
+
+/*
+ * Calulate the total number of credits to reserve to fit
+ * the modification of a single pages into a single transaction,
+ * which may include multiple chunks of block allocations.
  *
- * If the inode's direct blocks can hold an integral number of pages then a
- * page cannot straddle two indirect blocks, and we can only touch one indirect
- * and dindirect block, and the "5" above becomes "3".
+ * This could be called via ext4_write_begin()
  *
- * This still overestimates under most circumstances.  If we were to pass the
- * start and end offsets in here as well we could do block_to_path() on each
- * block and work out the exact number of indirects which are touched.  Pah.
+ * We need to consider the worse case, when
+ * one new block per extent.
  */
-
 int ext4_writepage_trans_blocks(struct inode *inode)
 {
        int bpp = ext4_journal_blocks_per_page(inode);
-       int indirects = (EXT4_NDIR_BLOCKS % bpp) ? 5 : 3;
        int ret;
 
-       if (EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL)
-               return ext4_ext_writepage_trans_blocks(inode, bpp);
+       ret = ext4_meta_trans_blocks(inode, bpp, 0);
 
+       /* Account for data blocks for journalled mode */
        if (ext4_should_journal_data(inode))
-               ret = 3 * (bpp + indirects) + 2;
-       else
-               ret = 2 * (bpp + indirects) + 2;
-
-#ifdef CONFIG_QUOTA
-       /* We know that structure was already allocated during DQUOT_INIT so
-        * we will be updating only the data blocks + inodes */
-       ret += 2*EXT4_QUOTA_TRANS_BLOCKS(inode->i_sb);
-#endif
-
+               ret += bpp;
        return ret;
 }
 
+/*
+ * Calculate the journal credits for a chunk of data modification.
+ *
+ * This is called from DIO, fallocate or whoever calling
+ * ext4_get_blocks_wrap() to map/allocate a chunk of contigous disk blocks.
+ *
+ * journal buffers for data blocks are not included here, as DIO
+ * and fallocate do no need to journal data buffers.
+ */
+int ext4_chunk_trans_blocks(struct inode *inode, int nrblocks)
+{
+       return ext4_meta_trans_blocks(inode, nrblocks, 1);
+}
+
 /*
  * The caller must have previously called ext4_reserve_inode_write().
  * Give this, we know that the caller already has write access to iloc->bh.
index 865e9ddb44d406d298da48b0137a4f426f8d45dd..e0e3a5eb1ddba0575798cd5d561b23c25409cdb6 100644 (file)
@@ -3281,6 +3281,35 @@ static void ext4_mb_use_group_pa(struct ext4_allocation_context *ac,
        mb_debug("use %u/%u from group pa %p\n", pa->pa_lstart-len, len, pa);
 }
 
+/*
+ * Return the prealloc space that have minimal distance
+ * from the goal block. @cpa is the prealloc
+ * space that is having currently known minimal distance
+ * from the goal block.
+ */
+static struct ext4_prealloc_space *
+ext4_mb_check_group_pa(ext4_fsblk_t goal_block,
+                       struct ext4_prealloc_space *pa,
+                       struct ext4_prealloc_space *cpa)
+{
+       ext4_fsblk_t cur_distance, new_distance;
+
+       if (cpa == NULL) {
+               atomic_inc(&pa->pa_count);
+               return pa;
+       }
+       cur_distance = abs(goal_block - cpa->pa_pstart);
+       new_distance = abs(goal_block - pa->pa_pstart);
+
+       if (cur_distance < new_distance)
+               return cpa;
+
+       /* drop the previous reference */
+       atomic_dec(&cpa->pa_count);
+       atomic_inc(&pa->pa_count);
+       return pa;
+}
+
 /*
  * search goal blocks in preallocated space
  */
@@ -3290,7 +3319,8 @@ ext4_mb_use_preallocated(struct ext4_allocation_context *ac)
        int order, i;
        struct ext4_inode_info *ei = EXT4_I(ac->ac_inode);
        struct ext4_locality_group *lg;
-       struct ext4_prealloc_space *pa;
+       struct ext4_prealloc_space *pa, *cpa = NULL;
+       ext4_fsblk_t goal_block;
 
        /* only data can be preallocated */
        if (!(ac->ac_flags & EXT4_MB_HINT_DATA))
@@ -3333,6 +3363,13 @@ ext4_mb_use_preallocated(struct ext4_allocation_context *ac)
                /* The max size of hash table is PREALLOC_TB_SIZE */
                order = PREALLOC_TB_SIZE - 1;
 
+       goal_block = ac->ac_g_ex.fe_group * EXT4_BLOCKS_PER_GROUP(ac->ac_sb) +
+                    ac->ac_g_ex.fe_start +
+                    le32_to_cpu(EXT4_SB(ac->ac_sb)->s_es->s_first_data_block);
+       /*
+        * search for the prealloc space that is having
+        * minimal distance from the goal block.
+        */
        for (i = order; i < PREALLOC_TB_SIZE; i++) {
                rcu_read_lock();
                list_for_each_entry_rcu(pa, &lg->lg_prealloc_list[i],
@@ -3340,17 +3377,19 @@ ext4_mb_use_preallocated(struct ext4_allocation_context *ac)
                        spin_lock(&pa->pa_lock);
                        if (pa->pa_deleted == 0 &&
                                        pa->pa_free >= ac->ac_o_ex.fe_len) {
-                               atomic_inc(&pa->pa_count);
-                               ext4_mb_use_group_pa(ac, pa);
-                               spin_unlock(&pa->pa_lock);
-                               ac->ac_criteria = 20;
-                               rcu_read_unlock();
-                               return 1;
+
+                               cpa = ext4_mb_check_group_pa(goal_block,
+                                                               pa, cpa);
                        }
                        spin_unlock(&pa->pa_lock);
                }
                rcu_read_unlock();
        }
+       if (cpa) {
+               ext4_mb_use_group_pa(ac, cpa);
+               ac->ac_criteria = 20;
+               return 1;
+       }
        return 0;
 }
 
index b9e077ba07e94b0c979ebea4530e1fc9471e6eee..46fc0b5b12bab540cf00bb1ffb7fcec1b51854fa 100644 (file)
@@ -53,7 +53,8 @@ static int finish_range(handle_t *handle, struct inode *inode,
         * credit. But below we try to not accumalate too much
         * of them by restarting the journal.
         */
-       needed = ext4_ext_calc_credits_for_insert(inode, path);
+       needed = ext4_ext_calc_credits_for_single_extent(inode,
+                   lb->last_block - lb->first_block + 1, path);
 
        /*
         * Make sure the credit we accumalated is not really high
index 0a9265164265fda4be2aa94c1db1941c3bb0b247..b3d35604ea1890f3b33567658ba9827f4d2c3a98 100644 (file)
@@ -773,7 +773,8 @@ int ext4_group_add(struct super_block *sb, struct ext4_new_group_data *input)
 
        if (reserved_gdb || gdb_off == 0) {
                if (!EXT4_HAS_COMPAT_FEATURE(sb,
-                                            EXT4_FEATURE_COMPAT_RESIZE_INODE)){
+                                            EXT4_FEATURE_COMPAT_RESIZE_INODE)
+                   || !le16_to_cpu(es->s_reserved_gdt_blocks)) {
                        ext4_warning(sb, __func__,
                                     "No reserved GDT blocks, can't resize");
                        return -EPERM;
index d5d77958b861b9fc29114965a566a7e2dfdd4a84..566344b926b772bb668ea62e15b3ddc641389a96 100644 (file)
@@ -568,6 +568,7 @@ static struct inode *ext4_alloc_inode(struct super_block *sb)
 #endif
        ei->i_block_alloc_info = NULL;
        ei->vfs_inode.i_version = 1;
+       ei->vfs_inode.i_data.writeback_index = 0;
        memset(&ei->i_cached_extent, 0, sizeof(struct ext4_ext_cache));
        INIT_LIST_HEAD(&ei->i_prealloc_list);
        spin_lock_init(&ei->i_prealloc_lock);
index 6d266d793e2caba12ef6b65501ab1db116c50574..80ff3381fa218950b7753db8ac907144f7579e4f 100644 (file)
@@ -562,26 +562,23 @@ static int fat_write_inode(struct inode *inode, int wait)
        struct buffer_head *bh;
        struct msdos_dir_entry *raw_entry;
        loff_t i_pos;
-       int err = 0;
+       int err;
 
 retry:
        i_pos = MSDOS_I(inode)->i_pos;
        if (inode->i_ino == MSDOS_ROOT_INO || !i_pos)
                return 0;
 
-       lock_super(sb);
        bh = sb_bread(sb, i_pos >> sbi->dir_per_block_bits);
        if (!bh) {
                printk(KERN_ERR "FAT: unable to read inode block "
                       "for updating (i_pos %lld)\n", i_pos);
-               err = -EIO;
-               goto out;
+               return -EIO;
        }
        spin_lock(&sbi->inode_hash_lock);
        if (i_pos != MSDOS_I(inode)->i_pos) {
                spin_unlock(&sbi->inode_hash_lock);
                brelse(bh);
-               unlock_super(sb);
                goto retry;
        }
 
@@ -607,11 +604,10 @@ retry:
        }
        spin_unlock(&sbi->inode_hash_lock);
        mark_buffer_dirty(bh);
+       err = 0;
        if (wait)
                err = sync_dirty_buffer(bh);
        brelse(bh);
-out:
-       unlock_super(sb);
        return err;
 }
 
index c4a1c3c65aac35ba999a4739fb3ed6549b5e1b75..da3cc460d4df4d16f3afb81fea786589948a2c18 100644 (file)
@@ -115,11 +115,11 @@ asmlinkage long sys_ioprio_set(int which, int who, int ioprio)
                                pgrp = task_pgrp(current);
                        else
                                pgrp = find_vpid(who);
-                       do_each_pid_task(pgrp, PIDTYPE_PGID, p) {
+                       do_each_pid_thread(pgrp, PIDTYPE_PGID, p) {
                                ret = set_task_ioprio(p, ioprio);
                                if (ret)
                                        break;
-                       } while_each_pid_task(pgrp, PIDTYPE_PGID, p);
+                       } while_each_pid_thread(pgrp, PIDTYPE_PGID, p);
                        break;
                case IOPRIO_WHO_USER:
                        if (!who)
@@ -204,7 +204,7 @@ asmlinkage long sys_ioprio_get(int which, int who)
                                pgrp = task_pgrp(current);
                        else
                                pgrp = find_vpid(who);
-                       do_each_pid_task(pgrp, PIDTYPE_PGID, p) {
+                       do_each_pid_thread(pgrp, PIDTYPE_PGID, p) {
                                tmpio = get_task_ioprio(p);
                                if (tmpio < 0)
                                        continue;
@@ -212,7 +212,7 @@ asmlinkage long sys_ioprio_get(int which, int who)
                                        ret = tmpio;
                                else
                                        ret = ioprio_best(ret, tmpio);
-                       } while_each_pid_task(pgrp, PIDTYPE_PGID, p);
+                       } while_each_pid_thread(pgrp, PIDTYPE_PGID, p);
                        break;
                case IOPRIO_WHO_USER:
                        if (!who)
index 31559f45fdde31eb511fc89bc564aa180fc1099b..4c41db91eaa45bffb0566d401d4a915abea4e32b 100644 (file)
@@ -12,7 +12,6 @@
 #ifndef _JFFS2_FS_I
 #define _JFFS2_FS_I
 
-#include <linux/version.h>
 #include <linux/rbtree.h>
 #include <linux/posix_acl.h>
 #include <linux/mutex.h>
index 79ecd281d2cbf1e1db1484ffe4b24413bc6f9e63..3f87d2632947371b47df580c32d041fb39bb91ba 100644 (file)
@@ -52,14 +52,14 @@ int nommu_vma_show(struct seq_file *m, struct vm_area_struct *vma)
        }
 
        seq_printf(m,
-                  "%08lx-%08lx %c%c%c%c %08lx %02x:%02x %lu %n",
+                  "%08lx-%08lx %c%c%c%c %08llx %02x:%02x %lu %n",
                   vma->vm_start,
                   vma->vm_end,
                   flags & VM_READ ? 'r' : '-',
                   flags & VM_WRITE ? 'w' : '-',
                   flags & VM_EXEC ? 'x' : '-',
                   flags & VM_MAYSHARE ? flags & VM_SHARED ? 'S' : 's' : 'p',
-                  vma->vm_pgoff << PAGE_SHIFT,
+                  ((loff_t)vma->vm_pgoff) << PAGE_SHIFT,
                   MAJOR(dev), MINOR(dev), ino, &len);
 
        if (file) {
index 7546a918f7907612b078c411d8eeb288b099ffc2..73d1891ee6259e41f5be2f1d8d2a16948887097d 100644 (file)
@@ -219,14 +219,14 @@ static int show_map(struct seq_file *m, void *v)
                ino = inode->i_ino;
        }
 
-       seq_printf(m, "%08lx-%08lx %c%c%c%c %08lx %02x:%02x %lu %n",
+       seq_printf(m, "%08lx-%08lx %c%c%c%c %08llx %02x:%02x %lu %n",
                        vma->vm_start,
                        vma->vm_end,
                        flags & VM_READ ? 'r' : '-',
                        flags & VM_WRITE ? 'w' : '-',
                        flags & VM_EXEC ? 'x' : '-',
                        flags & VM_MAYSHARE ? 's' : 'p',
-                       vma->vm_pgoff << PAGE_SHIFT,
+                       ((loff_t)vma->vm_pgoff) << PAGE_SHIFT,
                        MAJOR(dev), MINOR(dev), ino, &len);
 
        /*
index cdc2d3464a1af7ddc84efac8bcdca346cb773926..2813cdd723751aa2cde0bc931a79f913e97aca50 100644 (file)
@@ -18,7 +18,6 @@
 #ifndef __XFS_DMAPI_H__
 #define __XFS_DMAPI_H__
 
-#include <linux/version.h>
 /*     Values used to define the on-disk version of dm_attrname_t. All
  *     on-disk attribute names start with the 8-byte string "SGI_DMI_".
  *
index b7037d80d461b793304035dff1a329409732cd4b..d5b631935ec8edc9d00166498d46a4746defd086 100644 (file)
@@ -1,6 +1,5 @@
 include include/asm-generic/Kbuild.asm
 
-header-y += arch/
 header-y += arch-v10/
 header-y += arch-v32/
 
index 20e44fe00abf66f6b74b0daf482bea26d1dcebc7..ca7475e73b5ee7f2673334011f86e5cb77ac62b1 100644 (file)
@@ -271,6 +271,8 @@ static inline void __iomem *ioremap_fullcache(unsigned long physaddr, unsigned l
        return __ioremap(physaddr, size, IOMAP_FULL_CACHING);
 }
 
+#define ioremap_wc ioremap_nocache
+
 extern void iounmap(void volatile __iomem *addr);
 
 static inline void __iomem *ioport_map(unsigned long port, unsigned int nr)
index b8b6dc878250b37ae888f111e286c188c7678db6..c1a4119e6497ee2b23a4460d3c2ef05294cec128 100644 (file)
@@ -259,6 +259,8 @@ static inline void *ioremap_nocache(unsigned long offset, unsigned long size)
        return (void *) (offset | 0x20000000);
 }
 
+#define ioremap_wc ioremap_nocache
+
 static inline void iounmap(void *addr)
 {
 }
index b02ea6e17de8b6a097c722f28d2c726f5e39514d..754d635f90ffc9514a1daae0ed560eed9d629cd9 100644 (file)
@@ -118,6 +118,7 @@ enum uv_system_type {UV_NONE, UV_LEGACY_APIC, UV_X2APIC, UV_NON_UNIQUE_APIC};
 #define get_uv_system_type()           UV_NONE
 #define is_uv_system()                 0
 #define uv_wakeup_secondary(a, b)      1
+#define uv_system_init()               do {} while (0)
 
 
 #endif
index 0f8504627c41ce8c6d9f168e8ff038a8d15c3d12..a47d6312913596fbd0a8a77c54ed8b45937a5a90 100644 (file)
@@ -42,6 +42,7 @@ extern int is_uv_system(void);
 extern struct genapic apic_x2apic_uv_x;
 DECLARE_PER_CPU(int, x2apic_extra_bits);
 extern void uv_cpu_init(void);
+extern void uv_system_init(void);
 extern int uv_wakeup_secondary(int phys_apicid, unsigned int start_rip);
 
 extern void setup_apic_routing(void);
index b95d167b7fb26d8697a1d1a56b2000648b042e8b..a48c7f2dbdc04b32f010fbc6267b7a479f37e578 100644 (file)
@@ -76,6 +76,7 @@
 #define CALL_FUNCTION_SINGLE_VECTOR    0xfb
 #define THERMAL_APIC_VECTOR            0xfa
 #define THRESHOLD_APIC_VECTOR          0xf9
+#define UV_BAU_MESSAGE                 0xf8
 #define INVALIDATE_TLB_VECTOR_END      0xf7
 #define INVALIDATE_TLB_VECTOR_START    0xf0    /* f0-f7 used for TLB flush */
 
index 0f3c531146142df89075e4623c36377510c7489e..c2e34c27590066e4cf3359b78c1805d6c02805fc 100644 (file)
@@ -722,7 +722,7 @@ asmlinkage void kvm_handle_fault_on_reboot(void);
 
 #define __kvm_handle_fault_on_reboot(insn) \
        "666: " insn "\n\t" \
-       ".pushsection .text.fixup, \"ax\" \n" \
+       ".pushsection .fixup, \"ax\" \n" \
        "667: \n\t" \
        KVM_EX_PUSH " $666b \n\t" \
        "jmp kvm_handle_fault_on_reboot \n\t" \
index 91ac0dfb758805b052bba15f63796243fc4b9fab..610b6b308e93a005ff98753ea3d8586b131202ab 100644 (file)
 #define UV_ACTIVATION_DESCRIPTOR_SIZE  32
 #define UV_DISTRIBUTION_SIZE           256
 #define UV_SW_ACK_NPENDING             8
-#define UV_BAU_MESSAGE                 200
-/*
- * Messaging irq; see irq_64.h and include/asm-x86/hw_irq_64.h
- * To be dynamically allocated in the future
- */
 #define UV_NET_ENDPOINT_INTD           0x38
 #define UV_DESC_BASE_PNODE_SHIFT       49
 #define UV_PAYLOADQ_PNODE_SHIFT                49
index 8e15dd28c91fc18d116f34e0f69b030d444f3305..04ee0610014ab69e14b602487a197e5536fa9813 100644 (file)
@@ -35,7 +35,6 @@
 
 #include <linux/types.h>
 #include <linux/kernel.h>
-#include <linux/version.h>
 
 #include <xen/interface/xen.h>
 #include <xen/interface/version.h>
index d24a47f80f9c67587df13a5a8b57282f7dd2e8dd..4d8372d135df8df6d4f648b009faaa5d4d315538 100644 (file)
@@ -358,6 +358,7 @@ struct device {
 
        struct kobject kobj;
        char    bus_id[BUS_ID_SIZE];    /* position on parent bus */
+       const char              *init_name; /* initial name of the device */
        struct device_type      *type;
        unsigned                uevent_suppress:1;
 
@@ -406,7 +407,7 @@ struct device {
 /* Get the wakeup routines, which depend on struct device */
 #include <linux/pm_wakeup.h>
 
-static inline const char *dev_name(struct device *dev)
+static inline const char *dev_name(const struct device *dev)
 {
        /* will be changed into kobject_name(&dev->kobj) in the near future */
        return dev->bus_id;
@@ -518,7 +519,7 @@ extern void device_shutdown(void);
 extern void sysdev_shutdown(void);
 
 /* debugging and troubleshooting/diagnostic helpers. */
-extern const char *dev_driver_string(struct device *dev);
+extern const char *dev_driver_string(const struct device *dev);
 #define dev_printk(level, dev, format, arg...) \
        printk(level "%s %s: " format , dev_driver_string(dev) , \
               dev_name(dev) , ## arg)
index f5abd1306638379ecd609512cc742b8af53169e3..27e772cefb6a5b88e7f8605b3fb817c341d12e4a 100644 (file)
@@ -34,6 +34,27 @@ enum fid_type {
         */
        FILEID_INO32_GEN_PARENT = 2,
 
+       /*
+        * 64 bit object ID, 64 bit root object ID,
+        * 32 bit generation number.
+        */
+       FILEID_BTRFS_WITHOUT_PARENT = 0x4d,
+
+       /*
+        * 64 bit object ID, 64 bit root object ID,
+        * 32 bit generation number,
+        * 64 bit parent object ID, 32 bit parent generation.
+        */
+       FILEID_BTRFS_WITH_PARENT = 0x4e,
+
+       /*
+        * 64 bit object ID, 64 bit root object ID,
+        * 32 bit generation number,
+        * 64 bit parent object ID, 32 bit parent generation,
+        * 64 bit parent root object ID.
+        */
+       FILEID_BTRFS_WITH_PARENT_ROOT = 0x4f,
+
        /*
         * 32 bit block number, 16 bit partition reference,
         * 16 bit unused, 32 bit generation number.
index 3b8870e32afdd14b8166dd876762c0986cafd4ab..531ccd5f5960b0fe5818fdb768d3beb6bd3f3ea7 100644 (file)
@@ -976,6 +976,9 @@ static inline void __fb_pad_aligned_buffer(u8 *dst, u32 d_pitch,
 
 /* drivers/video/fb_defio.c */
 extern void fb_deferred_io_init(struct fb_info *info);
+extern void fb_deferred_io_open(struct fb_info *info,
+                               struct inode *inode,
+                               struct file *file);
 extern void fb_deferred_io_cleanup(struct fb_info *info);
 extern int fb_deferred_io_fsync(struct file *file, struct dentry *dentry,
                                int datasync);
index 809bb9ffc78846fbc2f8b5747ef42b225d8c4940..36b61ff392779750a84d2176e27fbbafb0078a27 100644 (file)
@@ -12,7 +12,6 @@
 #ifndef FS_UART_PD_H
 #define FS_UART_PD_H
 
-#include <linux/version.h>
 #include <asm/types.h>
 
 enum fs_uart_id {
index 4c6307ad9fdb525ebfd6cf2e95b5540d45bb2122..8529f57ba263a2ccabebdbacc3f668b47fd2d392 100644 (file)
@@ -45,6 +45,7 @@
 #define TUNGETFEATURES _IOR('T', 207, unsigned int)
 #define TUNSETOFFLOAD  _IOW('T', 208, unsigned int)
 #define TUNSETTXFILTER _IOW('T', 209, unsigned int)
+#define TUNGETIFF      _IOR('T', 210, unsigned int)
 
 /* TUNSETIFF ifr flags */
 #define IFF_TUN                0x0001
index 69511f74f912682e69e4d49a9abf5198c0a4bfa3..70a30651cd128cd3dbaf91a366886764abdede33 100644 (file)
@@ -320,12 +320,12 @@ struct kvm_trace_rec {
                struct {
                        __u64 cycle_u64;
                        __u32 extra_u32[KVM_TRC_EXTRA_MAX];
-               } cycle;
+               } __attribute__((packed)) cycle;
                struct {
                        __u32 extra_u32[KVM_TRC_EXTRA_MAX];
                } nocycle;
        } u;
-} __attribute__((packed));
+};
 
 #define KVMIO 0xAE
 
index 06b80337303b805bffcc2920b0d8796004f902ef..225bfc5bd9ec1eb43b143d059f926918a30c2656 100644 (file)
@@ -163,6 +163,7 @@ enum {
        ATA_DEV_NONE            = 9,    /* no device */
 
        /* struct ata_link flags */
+       ATA_LFLAG_NO_HRST       = (1 << 1), /* avoid hardreset */
        ATA_LFLAG_NO_SRST       = (1 << 2), /* avoid softreset */
        ATA_LFLAG_ASSUME_ATA    = (1 << 3), /* assume ATA class */
        ATA_LFLAG_ASSUME_SEMB   = (1 << 4), /* assume SEMB class */
@@ -646,6 +647,7 @@ struct ata_link {
 
        unsigned int            flags;          /* ATA_LFLAG_xxx */
 
+       u32                     saved_scontrol; /* SControl on probe */
        unsigned int            hw_sata_spd_limit;
        unsigned int            sata_spd_limit;
        unsigned int            sata_spd;       /* current SATA PHY speed */
@@ -1427,6 +1429,28 @@ static inline unsigned long ata_deadline(unsigned long from_jiffies,
        return from_jiffies + msecs_to_jiffies(timeout_msecs);
 }
 
+/* Don't open code these in drivers as there are traps. Firstly the range may
+   change in future hardware and specs, secondly 0xFF means 'no DMA' but is
+   > UDMA_0. Dyma ddreigiau */
+
+static inline int ata_using_mwdma(struct ata_device *adev)
+{
+       if (adev->dma_mode >= XFER_MW_DMA_0 && adev->dma_mode <= XFER_MW_DMA_4)
+               return 1;
+       return 0;
+}
+
+static inline int ata_using_udma(struct ata_device *adev)
+{
+       if (adev->dma_mode >= XFER_UDMA_0 && adev->dma_mode <= XFER_UDMA_7)
+               return 1;
+       return 0;
+}
+
+static inline int ata_dma_enabled(struct ata_device *adev)
+{
+       return (adev->dma_mode == 0xFF ? 0 : 1);
+}
 
 /**************************************************************************
  * PMP - drivers/ata/libata-pmp.c
index 3ba25065fa96b0f3907447f20fda02a8ea7e840c..8837928fbf33744249765eaedab779494a452d92 100644 (file)
@@ -57,6 +57,15 @@ static inline acpi_status pcie_osc_support_set(u32 flags)
 {
        return __pci_osc_support_set(flags, PCI_EXPRESS_ROOT_HID_STRING);
 }
+static inline acpi_handle acpi_find_root_bridge_handle(struct pci_dev *pdev)
+{
+       /* Find root host bridge */
+       while (pdev->bus->self)
+               pdev = pdev->bus->self;
+
+       return acpi_get_pci_rootbridge_handle(pci_domain_nr(pdev->bus),
+                       pdev->bus->number);
+}
 #else
 #if !defined(AE_ERROR)
 typedef u32            acpi_status;
@@ -66,6 +75,8 @@ static inline acpi_status pci_osc_control_set(acpi_handle handle, u32 flags)
 {return AE_ERROR;}
 static inline acpi_status pci_osc_support_set(u32 flags) {return AE_ERROR;} 
 static inline acpi_status pcie_osc_support_set(u32 flags) {return AE_ERROR;}
+static inline acpi_handle acpi_find_root_bridge_handle(struct pci_dev *pdev)
+{ return NULL; }
 #endif
 
 #endif /* _PCI_ACPI_H_ */
index 9ec2bcce8e8385d3e192f8b7c835a2062c592314..f1624b3967548fc116211aee27114e65e91f5d36 100644 (file)
 #define PCI_DEVICE_ID_INTEL_ICH10_3    0x3a1a
 #define PCI_DEVICE_ID_INTEL_ICH10_4    0x3a30
 #define PCI_DEVICE_ID_INTEL_ICH10_5    0x3a60
+#define PCI_DEVICE_ID_INTEL_PCH_0      0x3b10
+#define PCI_DEVICE_ID_INTEL_PCH_1      0x3b11
+#define PCI_DEVICE_ID_INTEL_PCH_2      0x3b30
 #define PCI_DEVICE_ID_INTEL_IOAT_SNB   0x402f
 #define PCI_DEVICE_ID_INTEL_5100_16    0x65f0
 #define PCI_DEVICE_ID_INTEL_5100_21    0x65f5
index 22921ac4cfd948b88e10a06c0725b33363b38caf..d7e98ff8021eb3bfc38e4c851b425c7eac5c097f 100644 (file)
@@ -161,4 +161,13 @@ pid_t pid_vnr(struct pid *pid);
                        }                                               \
        } while (0)
 
+#define do_each_pid_thread(pid, type, task)                            \
+       do_each_pid_task(pid, type, task) {                             \
+               struct task_struct *tg___ = task;                       \
+               do {
+
+#define while_each_pid_thread(pid, type, task)                         \
+               } while_each_thread(tg___, task);                       \
+               task = tg___;                                           \
+       } while_each_pid_task(pid, type, task)
 #endif /* _LINUX_PID_H */
index 69407f85e10b32daa4bd8ac82f88d43e36b82f78..fed6f5e0b41139070dd9c99b84ee324e7254f63f 100644 (file)
@@ -102,7 +102,7 @@ int try_to_unmap(struct page *, int ignore_refs);
  * Called from mm/filemap_xip.c to unmap empty zero page
  */
 pte_t *page_check_address(struct page *, struct mm_struct *,
-                               unsigned long, spinlock_t **);
+                               unsigned long, spinlock_t **, int);
 
 /*
  * Used by swapoff to help locate where page is expected in vma.
index 358661c9990e85a0b3c523a72606ee86411c1b57..909923717830f3a16d88cdd6d44ed53314e81f54 100644 (file)
@@ -1452,6 +1452,10 @@ extern int              skb_copy_datagram_iovec(const struct sk_buff *from,
 extern int            skb_copy_and_csum_datagram_iovec(struct sk_buff *skb,
                                                        int hlen,
                                                        struct iovec *iov);
+extern int            skb_copy_datagram_from_iovec(struct sk_buff *skb,
+                                                   int offset,
+                                                   struct iovec *from,
+                                                   int len);
 extern void           skb_free_datagram(struct sock *sk, struct sk_buff *skb);
 extern int            skb_kill_datagram(struct sock *sk, struct sk_buff *skb,
                                         unsigned int flags);
index f1cb0ba6d71586a5cd2f5b41172ee5b32b55631d..faf1519b5adc5235aab952baeb6876083e21c5ab 100644 (file)
@@ -3,16 +3,13 @@
 /* "Bogolock": stop the entire machine, disable interrupts.  This is a
    very heavy lock, which is equivalent to grabbing every spinlock
    (and more).  So the "read" side to such a lock is anything which
-   diables preeempt. */
+   disables preeempt. */
 #include <linux/cpu.h>
 #include <linux/cpumask.h>
 #include <asm/system.h>
 
 #if defined(CONFIG_STOP_MACHINE) && defined(CONFIG_SMP)
 
-/* Deprecated, but useful for transition. */
-#define ALL_CPUS ~0U
-
 /**
  * stop_machine: freeze the machine on all CPUs and run this function
  * @fn: the function to run
@@ -50,18 +47,4 @@ static inline int stop_machine(int (*fn)(void *), void *data,
        return ret;
 }
 #endif /* CONFIG_SMP */
-
-static inline int __deprecated stop_machine_run(int (*fn)(void *), void *data,
-                                               unsigned int cpu)
-{
-       /* If they don't care which cpu fn runs on, just pick one. */
-       if (cpu == NR_CPUS)
-               return stop_machine(fn, data, NULL);
-       else if (cpu == ~0U)
-               return stop_machine(fn, data, &cpu_possible_map);
-       else {
-               cpumask_t cpus = cpumask_of_cpu(cpu);
-               return stop_machine(fn, data, &cpus);
-       }
-}
 #endif /* _LINUX_STOP_MACHINE */
index d3c02695dc5d7e0826a7fa6ac4eb27bfbd937374..8cf8cfe2cc9712a176d7d4904107f4d30e74293f 100644 (file)
@@ -74,10 +74,13 @@ extern struct tick_device *tick_get_device(int cpu);
 extern int tick_init_highres(void);
 extern int tick_program_event(ktime_t expires, int force);
 extern void tick_setup_sched_timer(void);
+# endif
+
+# if defined CONFIG_NO_HZ || defined CONFIG_HIGH_RES_TIMERS
 extern void tick_cancel_sched_timer(int cpu);
 # else
 static inline void tick_cancel_sched_timer(int cpu) { }
-# endif /* HIGHRES */
+# endif
 
 # ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
 extern struct tick_device *tick_get_broadcast_device(void);
index 0924cd9c30f66feae597186d2b08d67155f008ad..94ac74aba6b6644dcd70f5015082facd90824195 100644 (file)
@@ -110,6 +110,8 @@ enum usb_interface_condition {
  * @sysfs_files_created: sysfs attributes exist
  * @needs_remote_wakeup: flag set when the driver requires remote-wakeup
  *     capability during autosuspend.
+ * @needs_altsetting0: flag set when a set-interface request for altsetting 0
+ *     has been deferred.
  * @needs_binding: flag set when the driver should be re-probed or unbound
  *     following a reset or suspend operation it doesn't support.
  * @dev: driver model's view of this device
@@ -162,6 +164,7 @@ struct usb_interface {
        unsigned is_active:1;           /* the interface is not suspended */
        unsigned sysfs_files_created:1; /* the sysfs attributes exist */
        unsigned needs_remote_wakeup:1; /* driver requires remote wakeup */
+       unsigned needs_altsetting0:1;   /* switch to altsetting 0 is pending */
        unsigned needs_binding:1;       /* needs delayed unbind/rebind */
 
        struct device dev;              /* interface specific device info */
index 06b28142b3abac573487512f2e21a4d3d1ca52be..c216de528b08ee97705adf052f29b0738e2230b3 100644 (file)
@@ -80,7 +80,8 @@ extern struct inet6_ifaddr      *ipv6_get_ifaddr(struct net *net,
                                                 struct net_device *dev,
                                                 int strict);
 
-extern int                     ipv6_dev_get_saddr(struct net_device *dev, 
+extern int                     ipv6_dev_get_saddr(struct net *net,
+                                              struct net_device *dev,
                                               const struct in6_addr *daddr,
                                               unsigned int srcprefs,
                                               struct in6_addr *saddr);
index bc391ba101e9aa96996236c55584ebc67fbd86b9..5f53db7e4e576f61450f83db2e2c5f14a871ce64 100644 (file)
@@ -107,6 +107,7 @@ struct rt6_rtnl_dump_arg
 {
        struct sk_buff *skb;
        struct netlink_callback *cb;
+       struct net *net;
 };
 
 extern int rt6_dump_route(struct rt6_info *rt, void *p_arg);
index b397e4d984c7a0a870f6969741a01b3daba2fea0..ff137fd7714f2909aca78a352990366cb02005b9 100644 (file)
@@ -708,10 +708,7 @@ enum ieee80211_tkip_key_type {
  *     rely on the host system for such buffering. This option is used
  *     to configure the IEEE 802.11 upper layer to buffer broadcast and
  *     multicast frames when there are power saving stations so that
- *     the driver can fetch them with ieee80211_get_buffered_bc(). Note
- *     that not setting this flag works properly only when the
- *     %IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE is also not set because
- *     otherwise the stack will not know when the DTIM beacon was sent.
+ *     the driver can fetch them with ieee80211_get_buffered_bc().
  *
  * @IEEE80211_HW_2GHZ_SHORT_SLOT_INCAPABLE:
  *     Hardware is not capable of short slot operation on the 2.4 GHz band.
@@ -1099,10 +1096,8 @@ enum ieee80211_ampdu_mlme_action {
  *     See the section "Frame filtering" for more information.
  *     This callback must be implemented and atomic.
  *
- * @set_tim: Set TIM bit. If the hardware/firmware takes care of beacon
- *     generation (that is, %IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE is set)
- *     mac80211 calls this function when a TIM bit must be set or cleared
- *     for a given AID. Must be atomic.
+ * @set_tim: Set TIM bit. mac80211 calls this function when a TIM bit
+ *     must be set or cleared for a given AID. Must be atomic.
  *
  * @set_key: See the section "Hardware crypto acceleration"
  *     This callback can sleep, and is only called between add_interface
index 853fe83d9f3700b9179e8a82c794970411ac5c20..b786a5b09253c0687739033f3eb51471a16d29a6 100644 (file)
@@ -78,6 +78,7 @@ extern struct Qdisc *fifo_create_dflt(struct Qdisc *sch, struct Qdisc_ops *ops,
 
 extern int register_qdisc(struct Qdisc_ops *qops);
 extern int unregister_qdisc(struct Qdisc_ops *qops);
+extern void qdisc_list_del(struct Qdisc *q);
 extern struct Qdisc *qdisc_lookup(struct net_device *dev, u32 handle);
 extern struct Qdisc *qdisc_lookup_class(struct net_device *dev, u32 handle);
 extern struct qdisc_rate_table *qdisc_get_rtab(struct tc_ratespec *r,
index a7abfda3e447896a0be5b06ed1809aa6e0b185fb..b1d2cfea89c5221b568a709c34ccb7031dfeff69 100644 (file)
@@ -27,6 +27,7 @@ enum qdisc_state_t
 {
        __QDISC_STATE_RUNNING,
        __QDISC_STATE_SCHED,
+       __QDISC_STATE_DEACTIVATED,
 };
 
 struct qdisc_size_table {
@@ -60,7 +61,6 @@ struct Qdisc
        struct gnet_stats_basic bstats;
        struct gnet_stats_queue qstats;
        struct gnet_stats_rate_est      rate_est;
-       struct rcu_head         q_rcu;
        int                     (*reshape_fail)(struct sk_buff *skb,
                                        struct Qdisc *q);
 
@@ -193,6 +193,11 @@ static inline struct Qdisc *qdisc_root(struct Qdisc *qdisc)
        return qdisc->dev_queue->qdisc;
 }
 
+static inline struct Qdisc *qdisc_root_sleeping(struct Qdisc *qdisc)
+{
+       return qdisc->dev_queue->qdisc_sleeping;
+}
+
 /* The qdisc root lock is a mechanism by which to top level
  * of a qdisc tree can be locked from any qdisc node in the
  * forest.  This allows changing the configuration of some
index 291d56a19167db9b8688dbbba446d051daae3b17..80b2e93c29360887eb55f65afd543c76e5b225cf 100644 (file)
@@ -6,6 +6,7 @@
 #include <linux/spinlock.h>
 #include <linux/workqueue.h>
 #include <linux/blkdev.h>
+#include <scsi/scsi.h>
 #include <asm/atomic.h>
 
 struct request_queue;
@@ -426,7 +427,7 @@ static inline int scsi_device_enclosure(struct scsi_device *sdev)
 
 static inline int scsi_device_protection(struct scsi_device *sdev)
 {
-       return sdev->inquiry[5] & (1<<0);
+       return sdev->scsi_level > SCSI_2 && sdev->inquiry[5] & (1<<0);
 }
 
 #define MODULE_ALIAS_SCSI_DEVICE(type) \
index 08864d257eb0ece2239cd86008973826bc49abd0..9db11911e04b7b55df05fd9f928f5629fe46430d 100644 (file)
@@ -1799,7 +1799,7 @@ static void *module_alloc_update_bounds(unsigned long size)
 
 /* Allocate and load the module: note that size of section 0 is always
    zero, and we rely on this for optional sections. */
-static struct module *load_module(void __user *umod,
+static noinline struct module *load_module(void __user *umod,
                                  unsigned long len,
                                  const char __user *uargs)
 {
index 21575fc46d0597914d4b92b5749c53f59f9be4e1..1d3ef29a2583e8cec49d46913b448fee86d3a549 100644 (file)
@@ -14,7 +14,6 @@
  */
 
 #include <linux/module.h>
-#include <linux/version.h>
 #include <linux/nsproxy.h>
 #include <linux/init_task.h>
 #include <linux/mnt_namespace.h>
index a0abf9a463f95bc9948f3ccd10fecddf75401eb8..80ccac849e4639f0b6224dead782aef918fdeec9 100644 (file)
@@ -14,7 +14,6 @@
 #include <linux/module.h>
 #include <linux/file.h>
 #include <linux/utsname.h>
-#include <linux/version.h>
 #include <linux/delay.h>
 #include <linux/bitops.h>
 #include <linux/genhd.h>
index f14f372cf6f5e0706e1ba94490c6c57a1aaf6d41..467d5940f62406c35ab64fb7c4c88b1556154fa0 100644 (file)
@@ -77,6 +77,7 @@ void wakeme_after_rcu(struct rcu_head  *head)
  * sections are delimited by rcu_read_lock() and rcu_read_unlock(),
  * and may be nested.
  */
+void synchronize_rcu(void);    /* Makes kernel-doc tools happy */
 synchronize_rcu_xxx(synchronize_rcu, call_rcu)
 EXPORT_SYMBOL_GPL(synchronize_rcu);
 
index c539f60c6f41bc2b9e170b93bf66a8bca5e93ce3..e661b01d340f06a17afb6cfef13a712ae0338ff9 100644 (file)
@@ -1338,6 +1338,7 @@ int do_notify_parent(struct task_struct *tsk, int sig)
        struct siginfo info;
        unsigned long flags;
        struct sighand_struct *psig;
+       int ret = sig;
 
        BUG_ON(sig == -1);
 
@@ -1402,7 +1403,7 @@ int do_notify_parent(struct task_struct *tsk, int sig)
                 * is implementation-defined: we do (if you don't want
                 * it, just use SIG_IGN instead).
                 */
-               tsk->exit_signal = -1;
+               ret = tsk->exit_signal = -1;
                if (psig->action[SIGCHLD-1].sa.sa_handler == SIG_IGN)
                        sig = -1;
        }
@@ -1411,7 +1412,7 @@ int do_notify_parent(struct task_struct *tsk, int sig)
        __wake_up_parent(tsk, tsk->parent);
        spin_unlock_irqrestore(&psig->siglock, flags);
 
-       return sig;
+       return ret;
 }
 
 static void do_notify_parent_cldstop(struct task_struct *tsk, int why)
index 3dacb00a7f765977c92d896ca4556f93ff87616b..038a7bc0901d20f90f841c5e4326fc1f2f2b963f 100644 (file)
@@ -169,9 +169,9 @@ asmlinkage long sys_setpriority(int which, int who, int niceval)
                                pgrp = find_vpid(who);
                        else
                                pgrp = task_pgrp(current);
-                       do_each_pid_task(pgrp, PIDTYPE_PGID, p) {
+                       do_each_pid_thread(pgrp, PIDTYPE_PGID, p) {
                                error = set_one_prio(p, niceval, error);
-                       } while_each_pid_task(pgrp, PIDTYPE_PGID, p);
+                       } while_each_pid_thread(pgrp, PIDTYPE_PGID, p);
                        break;
                case PRIO_USER:
                        user = current->user;
@@ -229,11 +229,11 @@ asmlinkage long sys_getpriority(int which, int who)
                                pgrp = find_vpid(who);
                        else
                                pgrp = task_pgrp(current);
-                       do_each_pid_task(pgrp, PIDTYPE_PGID, p) {
+                       do_each_pid_thread(pgrp, PIDTYPE_PGID, p) {
                                niceval = 20 - task_nice(p);
                                if (niceval > retval)
                                        retval = niceval;
-                       } while_each_pid_task(pgrp, PIDTYPE_PGID, p);
+                       } while_each_pid_thread(pgrp, PIDTYPE_PGID, p);
                        break;
                case PRIO_USER:
                        user = current->user;
index f5da526424a9b7c5dcaf965cbf00a49f09642eb0..7a46bde78c66f77e15ba75f8e570e4c46de274de 100644 (file)
@@ -643,17 +643,21 @@ void tick_setup_sched_timer(void)
                ts->nohz_mode = NOHZ_MODE_HIGHRES;
 #endif
 }
+#endif /* HIGH_RES_TIMERS */
 
+#if defined CONFIG_NO_HZ || defined CONFIG_HIGH_RES_TIMERS
 void tick_cancel_sched_timer(int cpu)
 {
        struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu);
 
+# ifdef CONFIG_HIGH_RES_TIMERS
        if (ts->sched_timer.base)
                hrtimer_cancel(&ts->sched_timer);
+# endif
 
        ts->nohz_mode = NOHZ_MODE_INACTIVE;
 }
-#endif /* HIGH_RES_TIMERS */
+#endif
 
 /**
  * Async notification about clocksource changes
index a9ab0596de44afe2bf3daa75c2c4ddca064c7f97..532858fa5b882eb8c3848b4c9ce430440297d2c0 100644 (file)
@@ -6,7 +6,6 @@
  */
 
 #include <linux/module.h>
-#include <linux/version.h>
 #include <linux/nsproxy.h>
 #include <linux/slab.h>
 #include <linux/user_namespace.h>
index 64d398f1244436cbdc4ede981dd927e39ee708b5..815237a55af8f277b43aea2c81471b9c05a4d00d 100644 (file)
@@ -12,7 +12,6 @@
 #include <linux/module.h>
 #include <linux/uts.h>
 #include <linux/utsname.h>
-#include <linux/version.h>
 #include <linux/err.h>
 #include <linux/slab.h>
 
index fe3a56c2256d7ee44e46813aeee597559ba29131..4ab9659d269e23bc315729f840b8742b5876e1ff 100644 (file)
@@ -12,7 +12,6 @@
 #include <linux/module.h>
 #include <linux/uts.h>
 #include <linux/utsname.h>
-#include <linux/version.h>
 #include <linux/sysctl.h>
 
 static void *get_uts(ctl_table *table, int write)
index bd732ffebc85f36cfc30e70fa124f0566701ecba..fbf0ae28237672a6fafdbbf29e481d76c45ddd11 100644 (file)
@@ -223,8 +223,7 @@ static int kobject_set_name_vargs(struct kobject *kobj, const char *fmt,
                return -ENOMEM;
 
        /* ewww... some of these buggers have '/' in the name ... */
-       s = strchr(kobj->name, '/');
-       if (s)
+       while ((s = strchr(kobj->name, '/')))
                s[0] = '!';
 
        kfree(old_name);
index e023c68b025555b6110e8d6352f9ad19e5c7f7f7..ad8eec6e44a85a9593c781ce252b127cb96992cd 100644 (file)
@@ -405,6 +405,29 @@ int __init reserve_bootmem(unsigned long addr, unsigned long size,
 }
 #endif /* !CONFIG_HAVE_ARCH_BOOTMEM_NODE */
 
+static unsigned long align_idx(struct bootmem_data *bdata, unsigned long idx,
+                       unsigned long step)
+{
+       unsigned long base = bdata->node_min_pfn;
+
+       /*
+        * Align the index with respect to the node start so that the
+        * combination of both satisfies the requested alignment.
+        */
+
+       return ALIGN(base + idx, step) - base;
+}
+
+static unsigned long align_off(struct bootmem_data *bdata, unsigned long off,
+                       unsigned long align)
+{
+       unsigned long base = PFN_PHYS(bdata->node_min_pfn);
+
+       /* Same as align_idx for byte offsets */
+
+       return ALIGN(base + off, align) - base;
+}
+
 static void * __init alloc_bootmem_core(struct bootmem_data *bdata,
                                unsigned long size, unsigned long align,
                                unsigned long goal, unsigned long limit)
@@ -441,7 +464,7 @@ static void * __init alloc_bootmem_core(struct bootmem_data *bdata,
        else
                start = ALIGN(min, step);
 
-       sidx = start - bdata->node_min_pfn;;
+       sidx = start - bdata->node_min_pfn;
        midx = max - bdata->node_min_pfn;
 
        if (bdata->hint_idx > sidx) {
@@ -450,7 +473,7 @@ static void * __init alloc_bootmem_core(struct bootmem_data *bdata,
                 * catch the fallback below.
                 */
                fallback = sidx + 1;
-               sidx = ALIGN(bdata->hint_idx, step);
+               sidx = align_idx(bdata, bdata->hint_idx, step);
        }
 
        while (1) {
@@ -459,7 +482,7 @@ static void * __init alloc_bootmem_core(struct bootmem_data *bdata,
                unsigned long eidx, i, start_off, end_off;
 find_block:
                sidx = find_next_zero_bit(bdata->node_bootmem_map, midx, sidx);
-               sidx = ALIGN(sidx, step);
+               sidx = align_idx(bdata, sidx, step);
                eidx = sidx + PFN_UP(size);
 
                if (sidx >= midx || eidx > midx)
@@ -467,7 +490,7 @@ find_block:
 
                for (i = sidx; i < eidx; i++)
                        if (test_bit(i, bdata->node_bootmem_map)) {
-                               sidx = ALIGN(i, step);
+                               sidx = align_idx(bdata, i, step);
                                if (sidx == i)
                                        sidx += step;
                                goto find_block;
@@ -475,7 +498,7 @@ find_block:
 
                if (bdata->last_end_off & (PAGE_SIZE - 1) &&
                                PFN_DOWN(bdata->last_end_off) + 1 == sidx)
-                       start_off = ALIGN(bdata->last_end_off, align);
+                       start_off = align_off(bdata, bdata->last_end_off, align);
                else
                        start_off = PFN_PHYS(sidx);
 
@@ -499,7 +522,7 @@ find_block:
        }
 
        if (fallback) {
-               sidx = ALIGN(fallback - 1, step);
+               sidx = align_idx(bdata, fallback - 1, step);
                fallback = 0;
                goto find_block;
        }
index 380ab402d71160a05d82a00598e5e35efeb5f116..b5167dfb2f2d65366004963558dfa765643423b8 100644 (file)
@@ -15,6 +15,8 @@
 #include <linux/rmap.h>
 #include <linux/mmu_notifier.h>
 #include <linux/sched.h>
+#include <linux/seqlock.h>
+#include <linux/mutex.h>
 #include <asm/tlbflush.h>
 #include <asm/io.h>
 
  * We do use our own empty page to avoid interference with other users
  * of ZERO_PAGE(), such as /dev/zero
  */
+static DEFINE_MUTEX(xip_sparse_mutex);
+static seqcount_t xip_sparse_seq = SEQCNT_ZERO;
 static struct page *__xip_sparse_page;
 
+/* called under xip_sparse_mutex */
 static struct page *xip_sparse_page(void)
 {
        if (!__xip_sparse_page) {
                struct page *page = alloc_page(GFP_HIGHUSER | __GFP_ZERO);
 
-               if (page) {
-                       static DEFINE_SPINLOCK(xip_alloc_lock);
-                       spin_lock(&xip_alloc_lock);
-                       if (!__xip_sparse_page)
-                               __xip_sparse_page = page;
-                       else
-                               __free_page(page);
-                       spin_unlock(&xip_alloc_lock);
-               }
+               if (page)
+                       __xip_sparse_page = page;
        }
        return __xip_sparse_page;
 }
@@ -174,18 +172,23 @@ __xip_unmap (struct address_space * mapping,
        pte_t pteval;
        spinlock_t *ptl;
        struct page *page;
+       unsigned count;
+       int locked = 0;
+
+       count = read_seqcount_begin(&xip_sparse_seq);
 
        page = __xip_sparse_page;
        if (!page)
                return;
 
+retry:
        spin_lock(&mapping->i_mmap_lock);
        vma_prio_tree_foreach(vma, &iter, &mapping->i_mmap, pgoff, pgoff) {
                mm = vma->vm_mm;
                address = vma->vm_start +
                        ((pgoff - vma->vm_pgoff) << PAGE_SHIFT);
                BUG_ON(address < vma->vm_start || address >= vma->vm_end);
-               pte = page_check_address(page, mm, address, &ptl);
+               pte = page_check_address(page, mm, address, &ptl, 1);
                if (pte) {
                        /* Nuke the page table entry. */
                        flush_cache_page(vma, address, pte_pfn(*pte));
@@ -198,6 +201,14 @@ __xip_unmap (struct address_space * mapping,
                }
        }
        spin_unlock(&mapping->i_mmap_lock);
+
+       if (locked) {
+               mutex_unlock(&xip_sparse_mutex);
+       } else if (read_seqcount_retry(&xip_sparse_seq, count)) {
+               mutex_lock(&xip_sparse_mutex);
+               locked = 1;
+               goto retry;
+       }
 }
 
 /*
@@ -218,7 +229,7 @@ static int xip_file_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
        int error;
 
        /* XXX: are VM_FAULT_ codes OK? */
-
+again:
        size = (i_size_read(inode) + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
        if (vmf->pgoff >= size)
                return VM_FAULT_SIGBUS;
@@ -237,8 +248,10 @@ static int xip_file_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
                int err;
 
                /* maybe shared writable, allocate new block */
+               mutex_lock(&xip_sparse_mutex);
                error = mapping->a_ops->get_xip_mem(mapping, vmf->pgoff, 1,
                                                        &xip_mem, &xip_pfn);
+               mutex_unlock(&xip_sparse_mutex);
                if (error)
                        return VM_FAULT_SIGBUS;
                /* unmap sparse mappings at pgoff from all other vmas */
@@ -252,14 +265,34 @@ found:
                BUG_ON(err);
                return VM_FAULT_NOPAGE;
        } else {
+               int err, ret = VM_FAULT_OOM;
+
+               mutex_lock(&xip_sparse_mutex);
+               write_seqcount_begin(&xip_sparse_seq);
+               error = mapping->a_ops->get_xip_mem(mapping, vmf->pgoff, 0,
+                                                       &xip_mem, &xip_pfn);
+               if (unlikely(!error)) {
+                       write_seqcount_end(&xip_sparse_seq);
+                       mutex_unlock(&xip_sparse_mutex);
+                       goto again;
+               }
+               if (error != -ENODATA)
+                       goto out;
                /* not shared and writable, use xip_sparse_page() */
                page = xip_sparse_page();
                if (!page)
-                       return VM_FAULT_OOM;
+                       goto out;
+               err = vm_insert_page(vma, (unsigned long)vmf->virtual_address,
+                                                       page);
+               if (err == -ENOMEM)
+                       goto out;
 
-               page_cache_get(page);
-               vmf->page = page;
-               return 0;
+               ret = VM_FAULT_NOPAGE;
+out:
+               write_seqcount_end(&xip_sparse_seq);
+               mutex_unlock(&xip_sparse_mutex);
+
+               return ret;
        }
 }
 
@@ -308,8 +341,10 @@ __xip_file_write(struct file *filp, const char __user *buf,
                                                &xip_mem, &xip_pfn);
                if (status == -ENODATA) {
                        /* we allocate a new page unmap it */
+                       mutex_lock(&xip_sparse_mutex);
                        status = a_ops->get_xip_mem(mapping, index, 1,
                                                        &xip_mem, &xip_pfn);
+                       mutex_unlock(&xip_sparse_mutex);
                        if (!status)
                                /* unmap page at pgoff from all other vmas */
                                __xip_unmap(mapping, index);
index 936ef2efd892029b1abf1c08c860fd40991d213d..4e0e26591dfaa6f242c4514fd83bdb54f7194b43 100644 (file)
@@ -12,7 +12,7 @@
 #include "internal.h"
 
 #ifdef CONFIG_DEBUG_MEMORY_INIT
-int __meminitdata mminit_loglevel;
+int mminit_loglevel;
 
 #ifndef SECTIONS_SHIFT
 #define SECTIONS_SHIFT 0
index 1ea4e6fcee77986f673d578a42bece82a92fb81e..0383acfcb0681a877f15f59d4d712980c37e1811 100644 (file)
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -224,10 +224,14 @@ unsigned long page_address_in_vma(struct page *page, struct vm_area_struct *vma)
 /*
  * Check that @page is mapped at @address into @mm.
  *
+ * If @sync is false, page_check_address may perform a racy check to avoid
+ * the page table lock when the pte is not present (helpful when reclaiming
+ * highly shared pages).
+ *
  * On success returns with pte mapped and locked.
  */
 pte_t *page_check_address(struct page *page, struct mm_struct *mm,
-                         unsigned long address, spinlock_t **ptlp)
+                         unsigned long address, spinlock_t **ptlp, int sync)
 {
        pgd_t *pgd;
        pud_t *pud;
@@ -249,7 +253,7 @@ pte_t *page_check_address(struct page *page, struct mm_struct *mm,
 
        pte = pte_offset_map(pmd, address);
        /* Make a quick check before getting the lock */
-       if (!pte_present(*pte)) {
+       if (!sync && !pte_present(*pte)) {
                pte_unmap(pte);
                return NULL;
        }
@@ -281,7 +285,7 @@ static int page_referenced_one(struct page *page,
        if (address == -EFAULT)
                goto out;
 
-       pte = page_check_address(page, mm, address, &ptl);
+       pte = page_check_address(page, mm, address, &ptl, 0);
        if (!pte)
                goto out;
 
@@ -450,7 +454,7 @@ static int page_mkclean_one(struct page *page, struct vm_area_struct *vma)
        if (address == -EFAULT)
                goto out;
 
-       pte = page_check_address(page, mm, address, &ptl);
+       pte = page_check_address(page, mm, address, &ptl, 1);
        if (!pte)
                goto out;
 
@@ -659,23 +663,30 @@ void page_remove_rmap(struct page *page, struct vm_area_struct *vma)
                }
 
                /*
-                * It would be tidy to reset the PageAnon mapping here,
-                * but that might overwrite a racing page_add_anon_rmap
-                * which increments mapcount after us but sets mapping
-                * before us: so leave the reset to free_hot_cold_page,
-                * and remember that it's only reliable while mapped.
-                * Leaving it set also helps swapoff to reinstate ptes
-                * faster for those pages still in swapcache.
+                * Now that the last pte has gone, s390 must transfer dirty
+                * flag from storage key to struct page.  We can usually skip
+                * this if the page is anon, so about to be freed; but perhaps
+                * not if it's in swapcache - there might be another pte slot
+                * containing the swap entry, but page not yet written to swap.
                 */
                if ((!PageAnon(page) || PageSwapCache(page)) &&
                    page_test_dirty(page)) {
                        page_clear_dirty(page);
                        set_page_dirty(page);
                }
-               mem_cgroup_uncharge_page(page);
 
+               mem_cgroup_uncharge_page(page);
                __dec_zone_page_state(page,
-                               PageAnon(page) ? NR_ANON_PAGES : NR_FILE_MAPPED);
+                       PageAnon(page) ? NR_ANON_PAGES : NR_FILE_MAPPED);
+               /*
+                * It would be tidy to reset the PageAnon mapping here,
+                * but that might overwrite a racing page_add_anon_rmap
+                * which increments mapcount after us but sets mapping
+                * before us: so leave the reset to free_hot_cold_page,
+                * and remember that it's only reliable while mapped.
+                * Leaving it set also helps swapoff to reinstate ptes
+                * faster for those pages still in swapcache.
+                */
        }
 }
 
@@ -697,7 +708,7 @@ static int try_to_unmap_one(struct page *page, struct vm_area_struct *vma,
        if (address == -EFAULT)
                goto out;
 
-       pte = page_check_address(page, mm, address, &ptl);
+       pte = page_check_address(page, mm, address, &ptl, 0);
        if (!pte)
                goto out;
 
index 167cf2dc8a03c16d3022c60a303b102f09732bdd..797c3831cbec7401ccfecd3ecdc98c7667c8d6bb 100644 (file)
@@ -60,7 +60,7 @@ void show_swap_cache_info(void)
        printk("Swap cache stats: add %lu, delete %lu, find %lu/%lu\n",
                swap_cache_info.add_total, swap_cache_info.del_total,
                swap_cache_info.find_success, swap_cache_info.find_total);
-       printk("Free swap  = %lukB\n", nr_swap_pages << (PAGE_SHIFT - 10));
+       printk("Free swap  = %ldkB\n", nr_swap_pages << (PAGE_SHIFT - 10));
        printk("Total swap = %lukB\n", total_swap_pages << (PAGE_SHIFT - 10));
 }
 
index 4e59df5f8e05a613d9990671162db5e7b8beb169..1edfdf4c095ba085ebe134eb6a3ee00d23128f1d 100644 (file)
@@ -456,7 +456,7 @@ static void __exit bt_exit(void)
 subsys_initcall(bt_init);
 module_exit(bt_exit);
 
-MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>, Marcel Holtmann <marcel@holtmann.org>");
+MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
 MODULE_DESCRIPTION("Bluetooth Core ver " VERSION);
 MODULE_VERSION(VERSION);
 MODULE_LICENSE("GPL");
index 12bba6207a8dca2719391bf1966072c9d3a107e3..80ba30cf4b682556252587e2ed57468f6663efa0 100644 (file)
@@ -736,7 +736,7 @@ MODULE_PARM_DESC(compress_src, "Compress sources headers");
 module_param(compress_dst, bool, 0644);
 MODULE_PARM_DESC(compress_dst, "Compress destination headers");
 
-MODULE_AUTHOR("David Libault <david.libault@inventel.fr>, Maxim Krasnyansky <maxk@qualcomm.com>");
+MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
 MODULE_DESCRIPTION("Bluetooth BNEP ver " VERSION);
 MODULE_VERSION(VERSION);
 MODULE_LICENSE("GPL");
index c85bf8f678dc5f1456788d3ebce5212627211912..f4f6615cad9f910c55f1cc70db8e633e010ce6eb 100644 (file)
@@ -3,8 +3,6 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 
-#include <linux/platform_device.h>
-
 #include <net/bluetooth/bluetooth.h>
 #include <net/bluetooth/hci_core.h>
 
 #undef  BT_DBG
 #define BT_DBG(D...)
 #endif
+
+struct class *bt_class = NULL;
+EXPORT_SYMBOL_GPL(bt_class);
+
 static struct workqueue_struct *btaddconn;
 static struct workqueue_struct *btdelconn;
 
-static inline char *typetostr(int type)
+static inline char *link_typetostr(int type)
+{
+       switch (type) {
+       case ACL_LINK:
+               return "ACL";
+       case SCO_LINK:
+               return "SCO";
+       case ESCO_LINK:
+               return "eSCO";
+       default:
+               return "UNKNOWN";
+       }
+}
+
+static ssize_t show_link_type(struct device *dev, struct device_attribute *attr, char *buf)
+{
+       struct hci_conn *conn = dev_get_drvdata(dev);
+       return sprintf(buf, "%s\n", link_typetostr(conn->type));
+}
+
+static ssize_t show_link_address(struct device *dev, struct device_attribute *attr, char *buf)
+{
+       struct hci_conn *conn = dev_get_drvdata(dev);
+       bdaddr_t bdaddr;
+       baswap(&bdaddr, &conn->dst);
+       return sprintf(buf, "%s\n", batostr(&bdaddr));
+}
+
+static ssize_t show_link_features(struct device *dev, struct device_attribute *attr, char *buf)
+{
+       struct hci_conn *conn = dev_get_drvdata(dev);
+
+       return sprintf(buf, "0x%02x%02x%02x%02x%02x%02x%02x%02x\n",
+                               conn->features[0], conn->features[1],
+                               conn->features[2], conn->features[3],
+                               conn->features[4], conn->features[5],
+                               conn->features[6], conn->features[7]);
+}
+
+#define LINK_ATTR(_name,_mode,_show,_store) \
+struct device_attribute link_attr_##_name = __ATTR(_name,_mode,_show,_store)
+
+static LINK_ATTR(type, S_IRUGO, show_link_type, NULL);
+static LINK_ATTR(address, S_IRUGO, show_link_address, NULL);
+static LINK_ATTR(features, S_IRUGO, show_link_features, NULL);
+
+static struct attribute *bt_link_attrs[] = {
+       &link_attr_type.attr,
+       &link_attr_address.attr,
+       &link_attr_features.attr,
+       NULL
+};
+
+static struct attribute_group bt_link_group = {
+       .attrs = bt_link_attrs,
+};
+
+static struct attribute_group *bt_link_groups[] = {
+       &bt_link_group,
+       NULL
+};
+
+static void bt_link_release(struct device *dev)
+{
+       void *data = dev_get_drvdata(dev);
+       kfree(data);
+}
+
+static struct device_type bt_link = {
+       .name    = "link",
+       .groups  = bt_link_groups,
+       .release = bt_link_release,
+};
+
+static void add_conn(struct work_struct *work)
+{
+       struct hci_conn *conn = container_of(work, struct hci_conn, work);
+
+       flush_workqueue(btdelconn);
+
+       if (device_add(&conn->dev) < 0) {
+               BT_ERR("Failed to register connection device");
+               return;
+       }
+}
+
+void hci_conn_add_sysfs(struct hci_conn *conn)
+{
+       struct hci_dev *hdev = conn->hdev;
+
+       BT_DBG("conn %p", conn);
+
+       conn->dev.type = &bt_link;
+       conn->dev.class = bt_class;
+       conn->dev.parent = &hdev->dev;
+
+       snprintf(conn->dev.bus_id, BUS_ID_SIZE, "%s:%d",
+                                       hdev->name, conn->handle);
+
+       dev_set_drvdata(&conn->dev, conn);
+
+       device_initialize(&conn->dev);
+
+       INIT_WORK(&conn->work, add_conn);
+
+       queue_work(btaddconn, &conn->work);
+}
+
+/*
+ * The rfcomm tty device will possibly retain even when conn
+ * is down, and sysfs doesn't support move zombie device,
+ * so we should move the device before conn device is destroyed.
+ */
+static int __match_tty(struct device *dev, void *data)
+{
+       return !strncmp(dev->bus_id, "rfcomm", 6);
+}
+
+static void del_conn(struct work_struct *work)
+{
+       struct hci_conn *conn = container_of(work, struct hci_conn, work);
+       struct hci_dev *hdev = conn->hdev;
+
+       while (1) {
+               struct device *dev;
+
+               dev = device_find_child(&conn->dev, NULL, __match_tty);
+               if (!dev)
+                       break;
+               device_move(dev, NULL);
+               put_device(dev);
+       }
+
+       device_del(&conn->dev);
+       put_device(&conn->dev);
+       hci_dev_put(hdev);
+}
+
+void hci_conn_del_sysfs(struct hci_conn *conn)
+{
+       BT_DBG("conn %p", conn);
+
+       if (!device_is_registered(&conn->dev))
+               return;
+
+       INIT_WORK(&conn->work, del_conn);
+
+       queue_work(btdelconn, &conn->work);
+}
+
+static inline char *host_typetostr(int type)
 {
        switch (type) {
        case HCI_VIRTUAL:
@@ -40,7 +192,7 @@ static inline char *typetostr(int type)
 static ssize_t show_type(struct device *dev, struct device_attribute *attr, char *buf)
 {
        struct hci_dev *hdev = dev_get_drvdata(dev);
-       return sprintf(buf, "%s\n", typetostr(hdev->type));
+       return sprintf(buf, "%s\n", host_typetostr(hdev->type));
 }
 
 static ssize_t show_name(struct device *dev, struct device_attribute *attr, char *buf)
@@ -221,183 +373,62 @@ static DEVICE_ATTR(sniff_max_interval, S_IRUGO | S_IWUSR,
 static DEVICE_ATTR(sniff_min_interval, S_IRUGO | S_IWUSR,
                                show_sniff_min_interval, store_sniff_min_interval);
 
-static struct device_attribute *bt_attrs[] = {
-       &dev_attr_type,
-       &dev_attr_name,
-       &dev_attr_class,
-       &dev_attr_address,
-       &dev_attr_features,
-       &dev_attr_manufacturer,
-       &dev_attr_hci_version,
-       &dev_attr_hci_revision,
-       &dev_attr_inquiry_cache,
-       &dev_attr_idle_timeout,
-       &dev_attr_sniff_max_interval,
-       &dev_attr_sniff_min_interval,
+static struct attribute *bt_host_attrs[] = {
+       &dev_attr_type.attr,
+       &dev_attr_name.attr,
+       &dev_attr_class.attr,
+       &dev_attr_address.attr,
+       &dev_attr_features.attr,
+       &dev_attr_manufacturer.attr,
+       &dev_attr_hci_version.attr,
+       &dev_attr_hci_revision.attr,
+       &dev_attr_inquiry_cache.attr,
+       &dev_attr_idle_timeout.attr,
+       &dev_attr_sniff_max_interval.attr,
+       &dev_attr_sniff_min_interval.attr,
        NULL
 };
 
-static ssize_t show_conn_type(struct device *dev, struct device_attribute *attr, char *buf)
-{
-       struct hci_conn *conn = dev_get_drvdata(dev);
-       return sprintf(buf, "%s\n", conn->type == ACL_LINK ? "ACL" : "SCO");
-}
-
-static ssize_t show_conn_address(struct device *dev, struct device_attribute *attr, char *buf)
-{
-       struct hci_conn *conn = dev_get_drvdata(dev);
-       bdaddr_t bdaddr;
-       baswap(&bdaddr, &conn->dst);
-       return sprintf(buf, "%s\n", batostr(&bdaddr));
-}
-
-static ssize_t show_conn_features(struct device *dev, struct device_attribute *attr, char *buf)
-{
-       struct hci_conn *conn = dev_get_drvdata(dev);
-
-       return sprintf(buf, "0x%02x%02x%02x%02x%02x%02x%02x%02x\n",
-                               conn->features[0], conn->features[1],
-                               conn->features[2], conn->features[3],
-                               conn->features[4], conn->features[5],
-                               conn->features[6], conn->features[7]);
-}
-
-#define CONN_ATTR(_name,_mode,_show,_store) \
-struct device_attribute conn_attr_##_name = __ATTR(_name,_mode,_show,_store)
-
-static CONN_ATTR(type, S_IRUGO, show_conn_type, NULL);
-static CONN_ATTR(address, S_IRUGO, show_conn_address, NULL);
-static CONN_ATTR(features, S_IRUGO, show_conn_features, NULL);
-
-static struct device_attribute *conn_attrs[] = {
-       &conn_attr_type,
-       &conn_attr_address,
-       &conn_attr_features,
-       NULL
+static struct attribute_group bt_host_group = {
+       .attrs = bt_host_attrs,
 };
 
-struct class *bt_class = NULL;
-EXPORT_SYMBOL_GPL(bt_class);
-
-static struct bus_type bt_bus = {
-       .name   = "bluetooth",
+static struct attribute_group *bt_host_groups[] = {
+       &bt_host_group,
+       NULL
 };
 
-static struct platform_device *bt_platform;
-
-static void bt_release(struct device *dev)
+static void bt_host_release(struct device *dev)
 {
        void *data = dev_get_drvdata(dev);
        kfree(data);
 }
 
-static void add_conn(struct work_struct *work)
-{
-       struct hci_conn *conn = container_of(work, struct hci_conn, work);
-       int i;
-
-       flush_workqueue(btdelconn);
-
-       if (device_add(&conn->dev) < 0) {
-               BT_ERR("Failed to register connection device");
-               return;
-       }
-
-       for (i = 0; conn_attrs[i]; i++)
-               if (device_create_file(&conn->dev, conn_attrs[i]) < 0)
-                       BT_ERR("Failed to create connection attribute");
-}
-
-void hci_conn_add_sysfs(struct hci_conn *conn)
-{
-       struct hci_dev *hdev = conn->hdev;
-
-       BT_DBG("conn %p", conn);
-
-       conn->dev.bus = &bt_bus;
-       conn->dev.parent = &hdev->dev;
-
-       conn->dev.release = bt_release;
-
-       snprintf(conn->dev.bus_id, BUS_ID_SIZE, "%s:%d",
-                                       hdev->name, conn->handle);
-
-       dev_set_drvdata(&conn->dev, conn);
-
-       device_initialize(&conn->dev);
-
-       INIT_WORK(&conn->work, add_conn);
-
-       queue_work(btaddconn, &conn->work);
-}
-
-/*
- * The rfcomm tty device will possibly retain even when conn
- * is down, and sysfs doesn't support move zombie device,
- * so we should move the device before conn device is destroyed.
- */
-static int __match_tty(struct device *dev, void *data)
-{
-       return !strncmp(dev->bus_id, "rfcomm", 6);
-}
-
-static void del_conn(struct work_struct *work)
-{
-       struct hci_conn *conn = container_of(work, struct hci_conn, work);
-       struct hci_dev *hdev = conn->hdev;
-
-       while (1) {
-               struct device *dev;
-
-               dev = device_find_child(&conn->dev, NULL, __match_tty);
-               if (!dev)
-                       break;
-               device_move(dev, NULL);
-               put_device(dev);
-       }
-
-       device_del(&conn->dev);
-       put_device(&conn->dev);
-       hci_dev_put(hdev);
-}
-
-void hci_conn_del_sysfs(struct hci_conn *conn)
-{
-       BT_DBG("conn %p", conn);
-
-       if (!device_is_registered(&conn->dev))
-               return;
-
-       INIT_WORK(&conn->work, del_conn);
-
-       queue_work(btdelconn, &conn->work);
-}
+static struct device_type bt_host = {
+       .name    = "host",
+       .groups  = bt_host_groups,
+       .release = bt_host_release,
+};
 
 int hci_register_sysfs(struct hci_dev *hdev)
 {
        struct device *dev = &hdev->dev;
-       unsigned int i;
        int err;
 
        BT_DBG("%p name %s type %d", hdev, hdev->name, hdev->type);
 
-       dev->bus = &bt_bus;
+       dev->type = &bt_host;
+       dev->class = bt_class;
        dev->parent = hdev->parent;
 
        strlcpy(dev->bus_id, hdev->name, BUS_ID_SIZE);
 
-       dev->release = bt_release;
-
        dev_set_drvdata(dev, hdev);
 
        err = device_register(dev);
        if (err < 0)
                return err;
 
-       for (i = 0; bt_attrs[i]; i++)
-               if (device_create_file(dev, bt_attrs[i]) < 0)
-                       BT_ERR("Failed to create device attribute");
-
        return 0;
 }
 
@@ -410,59 +441,30 @@ void hci_unregister_sysfs(struct hci_dev *hdev)
 
 int __init bt_sysfs_init(void)
 {
-       int err;
-
        btaddconn = create_singlethread_workqueue("btaddconn");
-       if (!btaddconn) {
-               err = -ENOMEM;
-               goto out;
-       }
+       if (!btaddconn)
+               return -ENOMEM;
 
        btdelconn = create_singlethread_workqueue("btdelconn");
        if (!btdelconn) {
-               err = -ENOMEM;
-               goto out_del;
-       }
-
-       bt_platform = platform_device_register_simple("bluetooth", -1, NULL, 0);
-       if (IS_ERR(bt_platform)) {
-               err = PTR_ERR(bt_platform);
-               goto out_platform;
+               destroy_workqueue(btaddconn);
+               return -ENOMEM;
        }
 
-       err = bus_register(&bt_bus);
-       if (err < 0)
-               goto out_bus;
-
        bt_class = class_create(THIS_MODULE, "bluetooth");
        if (IS_ERR(bt_class)) {
-               err = PTR_ERR(bt_class);
-               goto out_class;
+               destroy_workqueue(btdelconn);
+               destroy_workqueue(btaddconn);
+               return PTR_ERR(bt_class);
        }
 
        return 0;
-
-out_class:
-       bus_unregister(&bt_bus);
-out_bus:
-       platform_device_unregister(bt_platform);
-out_platform:
-       destroy_workqueue(btdelconn);
-out_del:
-       destroy_workqueue(btaddconn);
-out:
-       return err;
 }
 
 void bt_sysfs_cleanup(void)
 {
        destroy_workqueue(btaddconn);
-
        destroy_workqueue(btdelconn);
 
        class_destroy(bt_class);
-
-       bus_unregister(&bt_bus);
-
-       platform_device_unregister(bt_platform);
 }
index c1239852834aa78361939eba75ca596c5dba7d62..3396d5bdef1c3f8e0f24af0a64dd7b1eca7a333f 100644 (file)
@@ -2516,7 +2516,7 @@ EXPORT_SYMBOL(l2cap_load);
 module_init(l2cap_init);
 module_exit(l2cap_exit);
 
-MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>, Marcel Holtmann <marcel@holtmann.org>");
+MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
 MODULE_DESCRIPTION("Bluetooth L2CAP ver " VERSION);
 MODULE_VERSION(VERSION);
 MODULE_LICENSE("GPL");
index 6cfc7ba611b36bfd5af56816bc7bfef409cb81b7..ba537fae0a4ca653b4a7eedb7b941deb8aef613b 100644 (file)
@@ -2115,7 +2115,7 @@ MODULE_PARM_DESC(channel_mtu, "Default MTU for the RFCOMM channel");
 module_param(l2cap_mtu, uint, 0644);
 MODULE_PARM_DESC(l2cap_mtu, "Default MTU for the L2CAP connection");
 
-MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>, Marcel Holtmann <marcel@holtmann.org>");
+MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
 MODULE_DESCRIPTION("Bluetooth RFCOMM ver " VERSION);
 MODULE_VERSION(VERSION);
 MODULE_LICENSE("GPL");
index 8cda498748689d510e3452c187ce464b89987a5b..a16011fedc1d73d3adc24e66ff5e7ff24a37373c 100644 (file)
@@ -1002,7 +1002,7 @@ module_exit(sco_exit);
 module_param(disable_esco, bool, 0644);
 MODULE_PARM_DESC(disable_esco, "Disable eSCO connection creation");
 
-MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>, Marcel Holtmann <marcel@holtmann.org>");
+MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
 MODULE_DESCRIPTION("Bluetooth SCO ver " VERSION);
 MODULE_VERSION(VERSION);
 MODULE_LICENSE("GPL");
index 9b58d70b0e7d2a4a79129a2a7c769a7b70c3c5bc..4f52c3d50ebe029ed6250d055c64980e3b2a23c1 100644 (file)
@@ -148,11 +148,16 @@ static int br_set_tx_csum(struct net_device *dev, u32 data)
 }
 
 static struct ethtool_ops br_ethtool_ops = {
-       .get_drvinfo = br_getinfo,
-       .get_link = ethtool_op_get_link,
-       .set_sg = br_set_sg,
-       .set_tx_csum = br_set_tx_csum,
-       .set_tso = br_set_tso,
+       .get_drvinfo    = br_getinfo,
+       .get_link       = ethtool_op_get_link,
+       .get_tx_csum    = ethtool_op_get_tx_csum,
+       .set_tx_csum    = br_set_tx_csum,
+       .get_sg         = ethtool_op_get_sg,
+       .set_sg         = br_set_sg,
+       .get_tso        = ethtool_op_get_tso,
+       .set_tso        = br_set_tso,
+       .get_ufo        = ethtool_op_get_ufo,
+       .get_flags      = ethtool_op_get_flags,
 };
 
 void br_dev_setup(struct net_device *dev)
index dd61dcad60199a9ae29242f0c240e4bf4160df77..52f577a0f5440c32b17488c630cfc619ede5c49a 100644 (file)
@@ -339,6 +339,93 @@ fault:
        return -EFAULT;
 }
 
+/**
+ *     skb_copy_datagram_from_iovec - Copy a datagram from an iovec.
+ *     @skb: buffer to copy
+ *     @offset: offset in the buffer to start copying to
+ *     @from: io vector to copy to
+ *     @len: amount of data to copy to buffer from iovec
+ *
+ *     Returns 0 or -EFAULT.
+ *     Note: the iovec is modified during the copy.
+ */
+int skb_copy_datagram_from_iovec(struct sk_buff *skb, int offset,
+                                struct iovec *from, int len)
+{
+       int start = skb_headlen(skb);
+       int i, copy = start - offset;
+
+       /* Copy header. */
+       if (copy > 0) {
+               if (copy > len)
+                       copy = len;
+               if (memcpy_fromiovec(skb->data + offset, from, copy))
+                       goto fault;
+               if ((len -= copy) == 0)
+                       return 0;
+               offset += copy;
+       }
+
+       /* Copy paged appendix. Hmm... why does this look so complicated? */
+       for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
+               int end;
+
+               WARN_ON(start > offset + len);
+
+               end = start + skb_shinfo(skb)->frags[i].size;
+               if ((copy = end - offset) > 0) {
+                       int err;
+                       u8  *vaddr;
+                       skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
+                       struct page *page = frag->page;
+
+                       if (copy > len)
+                               copy = len;
+                       vaddr = kmap(page);
+                       err = memcpy_fromiovec(vaddr + frag->page_offset +
+                                              offset - start, from, copy);
+                       kunmap(page);
+                       if (err)
+                               goto fault;
+
+                       if (!(len -= copy))
+                               return 0;
+                       offset += copy;
+               }
+               start = end;
+       }
+
+       if (skb_shinfo(skb)->frag_list) {
+               struct sk_buff *list = skb_shinfo(skb)->frag_list;
+
+               for (; list; list = list->next) {
+                       int end;
+
+                       WARN_ON(start > offset + len);
+
+                       end = start + list->len;
+                       if ((copy = end - offset) > 0) {
+                               if (copy > len)
+                                       copy = len;
+                               if (skb_copy_datagram_from_iovec(list,
+                                                                offset - start,
+                                                                from, copy))
+                                       goto fault;
+                               if ((len -= copy) == 0)
+                                       return 0;
+                               offset += copy;
+                       }
+                       start = end;
+               }
+       }
+       if (!len)
+               return 0;
+
+fault:
+       return -EFAULT;
+}
+EXPORT_SYMBOL(skb_copy_datagram_from_iovec);
+
 static int skb_copy_and_csum_datagram(const struct sk_buff *skb, int offset,
                                      u8 __user *to, int len,
                                      __wsum *csump)
index 600bb23c4c2e3743239dc571c459fe3a5e8b19d5..60c51f7658870257571ee9455f95bb48888b4398 100644 (file)
@@ -1339,19 +1339,23 @@ static void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev)
 }
 
 
-void __netif_schedule(struct Qdisc *q)
+static inline void __netif_reschedule(struct Qdisc *q)
 {
-       if (!test_and_set_bit(__QDISC_STATE_SCHED, &q->state)) {
-               struct softnet_data *sd;
-               unsigned long flags;
+       struct softnet_data *sd;
+       unsigned long flags;
 
-               local_irq_save(flags);
-               sd = &__get_cpu_var(softnet_data);
-               q->next_sched = sd->output_queue;
-               sd->output_queue = q;
-               raise_softirq_irqoff(NET_TX_SOFTIRQ);
-               local_irq_restore(flags);
-       }
+       local_irq_save(flags);
+       sd = &__get_cpu_var(softnet_data);
+       q->next_sched = sd->output_queue;
+       sd->output_queue = q;
+       raise_softirq_irqoff(NET_TX_SOFTIRQ);
+       local_irq_restore(flags);
+}
+
+void __netif_schedule(struct Qdisc *q)
+{
+       if (!test_and_set_bit(__QDISC_STATE_SCHED, &q->state))
+               __netif_reschedule(q);
 }
 EXPORT_SYMBOL(__netif_schedule);
 
@@ -1800,9 +1804,13 @@ gso:
 
                spin_lock(root_lock);
 
-               rc = qdisc_enqueue_root(skb, q);
-               qdisc_run(q);
-
+               if (unlikely(test_bit(__QDISC_STATE_DEACTIVATED, &q->state))) {
+                       kfree_skb(skb);
+                       rc = NET_XMIT_DROP;
+               } else {
+                       rc = qdisc_enqueue_root(skb, q);
+                       qdisc_run(q);
+               }
                spin_unlock(root_lock);
 
                goto out;
@@ -1974,15 +1982,17 @@ static void net_tx_action(struct softirq_action *h)
 
                        head = head->next_sched;
 
-                       smp_mb__before_clear_bit();
-                       clear_bit(__QDISC_STATE_SCHED, &q->state);
-
                        root_lock = qdisc_lock(q);
                        if (spin_trylock(root_lock)) {
+                               smp_mb__before_clear_bit();
+                               clear_bit(__QDISC_STATE_SCHED,
+                                         &q->state);
                                qdisc_run(q);
                                spin_unlock(root_lock);
                        } else {
-                               __netif_schedule(q);
+                               if (!test_bit(__QDISC_STATE_DEACTIVATED,
+                                             &q->state))
+                                       __netif_reschedule(q);
                        }
                }
        }
@@ -2084,7 +2094,8 @@ static int ing_filter(struct sk_buff *skb)
        q = rxq->qdisc;
        if (q != &noop_qdisc) {
                spin_lock(qdisc_lock(q));
-               result = qdisc_enqueue_root(skb, q);
+               if (likely(!test_bit(__QDISC_STATE_DEACTIVATED, &q->state)))
+                       result = qdisc_enqueue_root(skb, q);
                spin_unlock(qdisc_lock(q));
        }
 
index a89f32fa94f6b0f9631a7353f3cbfd2e68bdcb70..57abe8266be198dd483c71ce07cf3ce0757ced0e 100644 (file)
@@ -99,7 +99,7 @@ struct gen_estimator_head
 
 static struct gen_estimator_head elist[EST_MAX_INTERVAL+1];
 
-/* Protects against NULL dereference and RCU write-side */
+/* Protects against NULL dereference */
 static DEFINE_RWLOCK(est_lock);
 
 static void est_timer(unsigned long arg)
@@ -185,7 +185,6 @@ int gen_new_estimator(struct gnet_stats_basic *bstats,
        est->last_packets = bstats->packets;
        est->avpps = rate_est->pps<<10;
 
-       write_lock_bh(&est_lock);
        if (!elist[idx].timer.function) {
                INIT_LIST_HEAD(&elist[idx].list);
                setup_timer(&elist[idx].timer, est_timer, idx);
@@ -195,7 +194,6 @@ int gen_new_estimator(struct gnet_stats_basic *bstats,
                mod_timer(&elist[idx].timer, jiffies + ((HZ/4) << idx));
 
        list_add_rcu(&est->list, &elist[idx].list);
-       write_unlock_bh(&est_lock);
        return 0;
 }
 
@@ -214,6 +212,7 @@ static void __gen_kill_estimator(struct rcu_head *head)
  * Removes the rate estimator specified by &bstats and &rate_est
  * and deletes the timer.
  *
+ * NOTE: Called under rtnl_mutex
  */
 void gen_kill_estimator(struct gnet_stats_basic *bstats,
        struct gnet_stats_rate_est *rate_est)
@@ -227,17 +226,17 @@ void gen_kill_estimator(struct gnet_stats_basic *bstats,
                if (!elist[idx].timer.function)
                        continue;
 
-               write_lock_bh(&est_lock);
                list_for_each_entry_safe(e, n, &elist[idx].list, list) {
                        if (e->rate_est != rate_est || e->bstats != bstats)
                                continue;
 
+                       write_lock_bh(&est_lock);
                        e->bstats = NULL;
+                       write_unlock_bh(&est_lock);
 
                        list_del_rcu(&e->list);
                        call_rcu(&e->e_rcu, __gen_kill_estimator);
                }
-               write_unlock_bh(&est_lock);
        }
 }
 
index 84640172d65d7901387925d49654de4b0ddb41e7..ca1ccdf1ef7612b87d16f53f803b2460de612360 100644 (file)
@@ -2256,14 +2256,7 @@ struct sk_buff *skb_segment(struct sk_buff *skb, int features)
                        segs = nskb;
                tail = nskb;
 
-               nskb->dev = skb->dev;
-               skb_copy_queue_mapping(nskb, skb);
-               nskb->priority = skb->priority;
-               nskb->protocol = skb->protocol;
-               nskb->vlan_tci = skb->vlan_tci;
-               nskb->dst = dst_clone(skb->dst);
-               memcpy(nskb->cb, skb->cb, sizeof(skb->cb));
-               nskb->pkt_type = skb->pkt_type;
+               __copy_skb_header(nskb, skb);
                nskb->mac_len = skb->mac_len;
 
                skb_reserve(nskb, headroom);
@@ -2274,6 +2267,7 @@ struct sk_buff *skb_segment(struct sk_buff *skb, int features)
                skb_copy_from_linear_data(skb, skb_put(nskb, doffset),
                                          doffset);
                if (!sg) {
+                       nskb->ip_summed = CHECKSUM_NONE;
                        nskb->csum = skb_copy_and_csum_bits(skb, offset,
                                                            skb_put(nskb, len),
                                                            len, 0);
@@ -2283,8 +2277,6 @@ struct sk_buff *skb_segment(struct sk_buff *skb, int features)
                frag = skb_shinfo(nskb)->frags;
                k = 0;
 
-               nskb->ip_summed = CHECKSUM_PARTIAL;
-               nskb->csum = skb->csum;
                skb_copy_from_linear_data_offset(skb, offset,
                                                 skb_put(nskb, hsize), hsize);
 
index df2f110df94a4bf2ccc1dcecb1d588fea65ff778..803933ab396d41af9e50d8d0e5e0d903708b9c05 100644 (file)
@@ -411,12 +411,6 @@ static int dccp_rcv_request_sent_state_process(struct sock *sk,
                struct dccp_sock *dp = dccp_sk(sk);
                long tstamp = dccp_timestamp();
 
-               /* Stop the REQUEST timer */
-               inet_csk_clear_xmit_timer(sk, ICSK_TIME_RETRANS);
-               WARN_ON(sk->sk_send_head == NULL);
-               __kfree_skb(sk->sk_send_head);
-               sk->sk_send_head = NULL;
-
                if (!between48(DCCP_SKB_CB(skb)->dccpd_ack_seq,
                               dp->dccps_awl, dp->dccps_awh)) {
                        dccp_pr_debug("invalid ackno: S.AWL=%llu, "
@@ -441,6 +435,12 @@ static int dccp_rcv_request_sent_state_process(struct sock *sk,
                                    DCCP_ACKVEC_STATE_RECEIVED))
                        goto out_invalid_packet; /* FIXME: change error code */
 
+               /* Stop the REQUEST timer */
+               inet_csk_clear_xmit_timer(sk, ICSK_TIME_RETRANS);
+               WARN_ON(sk->sk_send_head == NULL);
+               kfree_skb(sk->sk_send_head);
+               sk->sk_send_head = NULL;
+
                dp->dccps_isr = DCCP_SKB_CB(skb)->dccpd_seq;
                dccp_update_gsr(sk, dp->dccps_isr);
                /*
index 860558633b2c28b0ae9e8f658846d0b0bbe2b49b..55c355e632345c9d3b07b263beea4332e2d36904 100644 (file)
@@ -204,18 +204,22 @@ static struct sock *icmp_sk(struct net *net)
        return net->ipv4.icmp_sk[smp_processor_id()];
 }
 
-static inline int icmp_xmit_lock(struct sock *sk)
+static inline struct sock *icmp_xmit_lock(struct net *net)
 {
+       struct sock *sk;
+
        local_bh_disable();
 
+       sk = icmp_sk(net);
+
        if (unlikely(!spin_trylock(&sk->sk_lock.slock))) {
                /* This can happen if the output path signals a
                 * dst_link_failure() for an outgoing ICMP packet.
                 */
                local_bh_enable();
-               return 1;
+               return NULL;
        }
-       return 0;
+       return sk;
 }
 
 static inline void icmp_xmit_unlock(struct sock *sk)
@@ -354,15 +358,17 @@ static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb)
        struct ipcm_cookie ipc;
        struct rtable *rt = skb->rtable;
        struct net *net = dev_net(rt->u.dst.dev);
-       struct sock *sk = icmp_sk(net);
-       struct inet_sock *inet = inet_sk(sk);
+       struct sock *sk;
+       struct inet_sock *inet;
        __be32 daddr;
 
        if (ip_options_echo(&icmp_param->replyopts, skb))
                return;
 
-       if (icmp_xmit_lock(sk))
+       sk = icmp_xmit_lock(net);
+       if (sk == NULL)
                return;
+       inet = inet_sk(sk);
 
        icmp_param->data.icmph.checksum = 0;
 
@@ -419,7 +425,6 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info)
        if (!rt)
                goto out;
        net = dev_net(rt->u.dst.dev);
-       sk = icmp_sk(net);
 
        /*
         *      Find the original header. It is expected to be valid, of course.
@@ -483,7 +488,8 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info)
                }
        }
 
-       if (icmp_xmit_lock(sk))
+       sk = icmp_xmit_lock(net);
+       if (sk == NULL)
                return;
 
        /*
index 49587a497229e68aa9e1d49e7dcd6f2e78e8afea..462a22c9787779d71d812ffe0f7121b91b666995 100644 (file)
@@ -70,7 +70,7 @@ addrtype_mt_v1(const struct sk_buff *skb, const struct net_device *in,
                       (info->flags & IPT_ADDRTYPE_INVERT_SOURCE);
        if (ret && info->dest)
                ret &= match_type(dev, iph->daddr, info->dest) ^
-                      (info->flags & IPT_ADDRTYPE_INVERT_DEST);
+                      !!(info->flags & IPT_ADDRTYPE_INVERT_DEST);
        return ret;
 }
 
index 91537f11273f42b1298c88b990c8a2446da99d39..6c4f11f514461a5a244ba1d70180f42ad82940b4 100644 (file)
@@ -73,9 +73,13 @@ bool nf_nat_proto_unique_tuple(struct nf_conntrack_tuple *tuple,
                range_size = ntohs(range->max.all) - min + 1;
        }
 
-       off = *rover;
        if (range->flags & IP_NAT_RANGE_PROTO_RANDOM)
-               off = net_random();
+               off = secure_ipv4_port_ephemeral(tuple->src.u3.ip, tuple->dst.u3.ip,
+                                                maniptype == IP_NAT_MANIP_SRC
+                                                ? tuple->dst.u.all
+                                                : tuple->src.u.all);
+       else
+               off = *rover;
 
        for (i = 0; i < range_size; i++, off++) {
                *portptr = htons(min + off % range_size);
index 16fc6f454a3188426807fb30a4cc1e25618b6d2b..cca921ea855004f726906a9ed9f24249c7c0592b 100644 (file)
@@ -2914,6 +2914,68 @@ static int ipv4_sysctl_rtcache_flush_strategy(ctl_table *table,
        return 0;
 }
 
+static void rt_secret_reschedule(int old)
+{
+       struct net *net;
+       int new = ip_rt_secret_interval;
+       int diff = new - old;
+
+       if (!diff)
+               return;
+
+       rtnl_lock();
+       for_each_net(net) {
+               int deleted = del_timer_sync(&net->ipv4.rt_secret_timer);
+
+               if (!new)
+                       continue;
+
+               if (deleted) {
+                       long time = net->ipv4.rt_secret_timer.expires - jiffies;
+
+                       if (time <= 0 || (time += diff) <= 0)
+                               time = 0;
+
+                       net->ipv4.rt_secret_timer.expires = time;
+               } else
+                       net->ipv4.rt_secret_timer.expires = new;
+
+               net->ipv4.rt_secret_timer.expires += jiffies;
+               add_timer(&net->ipv4.rt_secret_timer);
+       }
+       rtnl_unlock();
+}
+
+static int ipv4_sysctl_rt_secret_interval(ctl_table *ctl, int write,
+                                         struct file *filp,
+                                         void __user *buffer, size_t *lenp,
+                                         loff_t *ppos)
+{
+       int old = ip_rt_secret_interval;
+       int ret = proc_dointvec_jiffies(ctl, write, filp, buffer, lenp, ppos);
+
+       rt_secret_reschedule(old);
+
+       return ret;
+}
+
+static int ipv4_sysctl_rt_secret_interval_strategy(ctl_table *table,
+                                                  int __user *name,
+                                                  int nlen,
+                                                  void __user *oldval,
+                                                  size_t __user *oldlenp,
+                                                  void __user *newval,
+                                                  size_t newlen)
+{
+       int old = ip_rt_secret_interval;
+       int ret = sysctl_jiffies(table, name, nlen, oldval, oldlenp, newval,
+                                newlen);
+
+       rt_secret_reschedule(old);
+
+       return ret;
+}
+
 static ctl_table ipv4_route_table[] = {
        {
                .ctl_name       = NET_IPV4_ROUTE_GC_THRESH,
@@ -3048,8 +3110,8 @@ static ctl_table ipv4_route_table[] = {
                .data           = &ip_rt_secret_interval,
                .maxlen         = sizeof(int),
                .mode           = 0644,
-               .proc_handler   = &proc_dointvec_jiffies,
-               .strategy       = &sysctl_jiffies,
+               .proc_handler   = &ipv4_sysctl_rt_secret_interval,
+               .strategy       = &ipv4_sysctl_rt_secret_interval_strategy,
        },
        { .ctl_name = 0 }
 };
@@ -3126,10 +3188,12 @@ static __net_init int rt_secret_timer_init(struct net *net)
        net->ipv4.rt_secret_timer.data = (unsigned long)net;
        init_timer_deferrable(&net->ipv4.rt_secret_timer);
 
-       net->ipv4.rt_secret_timer.expires =
-               jiffies + net_random() % ip_rt_secret_interval +
-               ip_rt_secret_interval;
-       add_timer(&net->ipv4.rt_secret_timer);
+       if (ip_rt_secret_interval) {
+               net->ipv4.rt_secret_timer.expires =
+                       jiffies + net_random() % ip_rt_secret_interval +
+                       ip_rt_secret_interval;
+               add_timer(&net->ipv4.rt_secret_timer);
+       }
        return 0;
 }
 
index a7842c54f58a0905201751a9d32a7e270875aaf4..7b6a584b62ddbcbac75ba193fe04cfebc26357da 100644 (file)
@@ -1106,13 +1106,12 @@ out:
        return ret;
 }
 
-int ipv6_dev_get_saddr(struct net_device *dst_dev,
+int ipv6_dev_get_saddr(struct net *net, struct net_device *dst_dev,
                       const struct in6_addr *daddr, unsigned int prefs,
                       struct in6_addr *saddr)
 {
        struct ipv6_saddr_score scores[2],
                                *score = &scores[0], *hiscore = &scores[1];
-       struct net *net = dev_net(dst_dev);
        struct ipv6_saddr_dst dst;
        struct net_device *dev;
        int dst_type;
@@ -1689,6 +1688,7 @@ addrconf_prefix_route(struct in6_addr *pfx, int plen, struct net_device *dev,
                .fc_dst_len = plen,
                .fc_flags = RTF_UP | flags,
                .fc_nlinfo.nl_net = dev_net(dev),
+               .fc_protocol = RTPROT_KERNEL,
        };
 
        ipv6_addr_copy(&cfg.fc_dst, pfx);
index 8d05527524e39063eb941494ec80e0678702a30b..f5de3f9dc692164edaf36f7bc0e0dcb0387dbb6f 100644 (file)
@@ -93,7 +93,8 @@ static int fib6_rule_action(struct fib_rule *rule, struct flowi *flp,
                        if (flags & RT6_LOOKUP_F_SRCPREF_COA)
                                srcprefs |= IPV6_PREFER_SRC_COA;
 
-                       if (ipv6_dev_get_saddr(ip6_dst_idev(&rt->u.dst)->dev,
+                       if (ipv6_dev_get_saddr(net,
+                                              ip6_dst_idev(&rt->u.dst)->dev,
                                               &flp->fl6_dst, srcprefs,
                                               &saddr))
                                goto again;
index abedf95fdf2dd0ca5f8cfa25cdfe0f6504395592..b3157a0cc15dc70814924be1f12b5e2ff4cad4f8 100644 (file)
@@ -91,19 +91,22 @@ static struct inet6_protocol icmpv6_protocol = {
        .flags          =       INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL,
 };
 
-static __inline__ int icmpv6_xmit_lock(struct sock *sk)
+static __inline__ struct sock *icmpv6_xmit_lock(struct net *net)
 {
+       struct sock *sk;
+
        local_bh_disable();
 
+       sk = icmpv6_sk(net);
        if (unlikely(!spin_trylock(&sk->sk_lock.slock))) {
                /* This can happen if the output path (f.e. SIT or
                 * ip6ip6 tunnel) signals dst_link_failure() for an
                 * outgoing ICMP6 packet.
                 */
                local_bh_enable();
-               return 1;
+               return NULL;
        }
-       return 0;
+       return sk;
 }
 
 static __inline__ void icmpv6_xmit_unlock(struct sock *sk)
@@ -392,11 +395,10 @@ void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info,
        fl.fl_icmp_code = code;
        security_skb_classify_flow(skb, &fl);
 
-       sk = icmpv6_sk(net);
-       np = inet6_sk(sk);
-
-       if (icmpv6_xmit_lock(sk))
+       sk = icmpv6_xmit_lock(net);
+       if (sk == NULL)
                return;
+       np = inet6_sk(sk);
 
        if (!icmpv6_xrlim_allow(sk, type, &fl))
                goto out;
@@ -539,11 +541,10 @@ static void icmpv6_echo_reply(struct sk_buff *skb)
        fl.fl_icmp_type = ICMPV6_ECHO_REPLY;
        security_skb_classify_flow(skb, &fl);
 
-       sk = icmpv6_sk(net);
-       np = inet6_sk(sk);
-
-       if (icmpv6_xmit_lock(sk))
+       sk = icmpv6_xmit_lock(net);
+       if (sk == NULL)
                return;
+       np = inet6_sk(sk);
 
        if (!fl.oif && ipv6_addr_is_multicast(&fl.fl6_dst))
                fl.oif = np->mcast_oif;
index 52dddc25d3e6e6c96a83fd7ccd6ade53b9160fa0..29c7c99e69f7611034354319b9e6452f26972635 100644 (file)
@@ -378,6 +378,7 @@ static int inet6_dump_fib(struct sk_buff *skb, struct netlink_callback *cb)
 
        arg.skb = skb;
        arg.cb = cb;
+       arg.net = net;
        w->args = &arg;
 
        for (h = s_h; h < FIB_TABLE_HASHSZ; h++, s_e = 0) {
index a4402de425d9ecb0b1f56dad298dc6cc92c8fb47..0e844c2736a77b0dad9aa87095298be92d01bf7c 100644 (file)
@@ -934,7 +934,7 @@ static int ip6_dst_lookup_tail(struct sock *sk,
                goto out_err_release;
 
        if (ipv6_addr_any(&fl->fl6_src)) {
-               err = ipv6_dev_get_saddr(ip6_dst_idev(*dst)->dev,
+               err = ipv6_dev_get_saddr(net, ip6_dst_idev(*dst)->dev,
                                         &fl->fl6_dst,
                                         sk ? inet6_sk(sk)->srcprefs : 0,
                                         &fl->fl6_src);
index 741cfcd96f88fe7a3694eb670e4fa91e4503175c..4e5eac301f91835a9bebb5b77a1c5a48c8cd9023 100644 (file)
@@ -911,7 +911,7 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname,
                } else {
                        if (np->rxopt.bits.rxinfo) {
                                struct in6_pktinfo src_info;
-                               src_info.ipi6_ifindex = np->mcast_oif;
+                               src_info.ipi6_ifindex = np->mcast_oif ? np->mcast_oif : sk->sk_bound_dev_if;
                                ipv6_addr_copy(&src_info.ipi6_addr, &np->daddr);
                                put_cmsg(&msg, SOL_IPV6, IPV6_PKTINFO, sizeof(src_info), &src_info);
                        }
@@ -921,7 +921,7 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname,
                        }
                        if (np->rxopt.bits.rxoinfo) {
                                struct in6_pktinfo src_info;
-                               src_info.ipi6_ifindex = np->mcast_oif;
+                               src_info.ipi6_ifindex = np->mcast_oif ? np->mcast_oif : sk->sk_bound_dev_if;
                                ipv6_addr_copy(&src_info.ipi6_addr, &np->daddr);
                                put_cmsg(&msg, SOL_IPV6, IPV6_2292PKTINFO, sizeof(src_info), &src_info);
                        }
index beb48e3f038afbfa6199b333ddc0b2e61e4683ba..f1c62ba0f56b90ded89f3d0d1787f881d9499ea5 100644 (file)
@@ -549,7 +549,7 @@ static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh,
                        override = 0;
                in6_ifa_put(ifp);
        } else {
-               if (ipv6_dev_get_saddr(dev, daddr,
+               if (ipv6_dev_get_saddr(dev_net(dev), dev, daddr,
                                       inet6_sk(dev_net(dev)->ipv6.ndisc_sk)->srcprefs,
                                       &tmpaddr))
                        return;
index 41b165ffb369fec9d101c59af630860cac018d04..9af6115f0f500822c94ff6cb751ab24cd34de911 100644 (file)
@@ -2106,7 +2106,8 @@ static inline size_t rt6_nlmsg_size(void)
               + nla_total_size(sizeof(struct rta_cacheinfo));
 }
 
-static int rt6_fill_node(struct sk_buff *skb, struct rt6_info *rt,
+static int rt6_fill_node(struct net *net,
+                        struct sk_buff *skb, struct rt6_info *rt,
                         struct in6_addr *dst, struct in6_addr *src,
                         int iif, int type, u32 pid, u32 seq,
                         int prefix, int nowait, unsigned int flags)
@@ -2189,7 +2190,7 @@ static int rt6_fill_node(struct sk_buff *skb, struct rt6_info *rt,
        } else if (dst) {
                struct inet6_dev *idev = ip6_dst_idev(&rt->u.dst);
                struct in6_addr saddr_buf;
-               if (ipv6_dev_get_saddr(idev ? idev->dev : NULL,
+               if (ipv6_dev_get_saddr(net, idev ? idev->dev : NULL,
                                       dst, 0, &saddr_buf) == 0)
                        NLA_PUT(skb, RTA_PREFSRC, 16, &saddr_buf);
        }
@@ -2234,7 +2235,8 @@ int rt6_dump_route(struct rt6_info *rt, void *p_arg)
        } else
                prefix = 0;
 
-       return rt6_fill_node(arg->skb, rt, NULL, NULL, 0, RTM_NEWROUTE,
+       return rt6_fill_node(arg->net,
+                    arg->skb, rt, NULL, NULL, 0, RTM_NEWROUTE,
                     NETLINK_CB(arg->cb->skb).pid, arg->cb->nlh->nlmsg_seq,
                     prefix, 0, NLM_F_MULTI);
 }
@@ -2300,7 +2302,7 @@ static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void
        rt = (struct rt6_info*) ip6_route_output(net, NULL, &fl);
        skb->dst = &rt->u.dst;
 
-       err = rt6_fill_node(skb, rt, &fl.fl6_dst, &fl.fl6_src, iif,
+       err = rt6_fill_node(net, skb, rt, &fl.fl6_dst, &fl.fl6_src, iif,
                            RTM_NEWROUTE, NETLINK_CB(in_skb).pid,
                            nlh->nlmsg_seq, 0, 0, 0);
        if (err < 0) {
@@ -2327,7 +2329,7 @@ void inet6_rt_notify(int event, struct rt6_info *rt, struct nl_info *info)
        if (skb == NULL)
                goto errout;
 
-       err = rt6_fill_node(skb, rt, NULL, NULL, 0,
+       err = rt6_fill_node(net, skb, rt, NULL, NULL, 0,
                                event, info->pid, seq, 0, 0, 0);
        if (err < 0) {
                /* -EMSGSIZE implies BUG in rt6_nlmsg_size() */
index 8f1e0543b3c4f114539e288d12ac273c5fbe127d..08e4cbbe3f04e5f64e6d91f8b7864c8108d5e0ef 100644 (file)
@@ -52,12 +52,14 @@ static struct dst_entry *xfrm6_dst_lookup(int tos, xfrm_address_t *saddr,
 static int xfrm6_get_saddr(xfrm_address_t *saddr, xfrm_address_t *daddr)
 {
        struct dst_entry *dst;
+       struct net_device *dev;
 
        dst = xfrm6_dst_lookup(0, NULL, daddr);
        if (IS_ERR(dst))
                return -EHOSTUNREACH;
 
-       ipv6_dev_get_saddr(ip6_dst_idev(dst)->dev,
+       dev = ip6_dst_idev(dst)->dev;
+       ipv6_dev_get_saddr(dev_net(dev), dev,
                           (struct in6_addr *)&daddr->a6, 0,
                           (struct in6_addr *)&saddr->a6);
        dst_release(dst);
index e1d11c9b6729e0145866ab9df120ada75601fda1..1e97fb9fb34bde3f88988e42cd546b43d95a5b6e 100644 (file)
@@ -2103,6 +2103,8 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
                        rcu_read_unlock();
                        return;
                }
+               /* update new sta with its last rx activity */
+               sta->last_rx = jiffies;
        }
 
        /*
index 105a616c5c7805a2333dd3133f7580845bc556a3..a8752031adcb6e4af93e0531bdec0ab26c75c619 100644 (file)
@@ -968,7 +968,7 @@ ctnetlink_change_helper(struct nf_conn *ct, struct nlattr *cda[])
                /* need to zero data of old helper */
                memset(&help->help, 0, sizeof(help->help));
        } else {
-               help = nf_ct_helper_ext_add(ct, GFP_KERNEL);
+               help = nf_ct_helper_ext_add(ct, GFP_ATOMIC);
                if (help == NULL)
                        return -ENOMEM;
        }
@@ -1136,16 +1136,33 @@ ctnetlink_create_conntrack(struct nlattr *cda[],
        ct->timeout.expires = jiffies + ct->timeout.expires * HZ;
        ct->status |= IPS_CONFIRMED;
 
+       rcu_read_lock();
+       helper = __nf_ct_helper_find(rtuple);
+       if (helper) {
+               help = nf_ct_helper_ext_add(ct, GFP_ATOMIC);
+               if (help == NULL) {
+                       rcu_read_unlock();
+                       err = -ENOMEM;
+                       goto err;
+               }
+               /* not in hash table yet so not strictly necessary */
+               rcu_assign_pointer(help->helper, helper);
+       }
+
        if (cda[CTA_STATUS]) {
                err = ctnetlink_change_status(ct, cda);
-               if (err < 0)
+               if (err < 0) {
+                       rcu_read_unlock();
                        goto err;
+               }
        }
 
        if (cda[CTA_PROTOINFO]) {
                err = ctnetlink_change_protoinfo(ct, cda);
-               if (err < 0)
+               if (err < 0) {
+                       rcu_read_unlock();
                        goto err;
+               }
        }
 
        nf_ct_acct_ext_add(ct, GFP_KERNEL);
@@ -1155,19 +1172,6 @@ ctnetlink_create_conntrack(struct nlattr *cda[],
                ct->mark = ntohl(nla_get_be32(cda[CTA_MARK]));
 #endif
 
-       rcu_read_lock();
-       helper = __nf_ct_helper_find(rtuple);
-       if (helper) {
-               help = nf_ct_helper_ext_add(ct, GFP_KERNEL);
-               if (help == NULL) {
-                       rcu_read_unlock();
-                       err = -ENOMEM;
-                       goto err;
-               }
-               /* not in hash table yet so not strictly necessary */
-               rcu_assign_pointer(help->helper, helper);
-       }
-
        /* setup master conntrack: this is a confirmed expectation */
        if (master_ct) {
                __set_bit(IPS_EXPECTED_BIT, &ct->status);
index d2d45655cd1a69582a8fdc2948c69c652ed0fd19..35a9994e23397e70b7f099b1bd573ed28c361512 100644 (file)
@@ -150,6 +150,8 @@ static void update_rfkill_state(struct rfkill *rfkill)
  * calls and handling all the red tape such as issuing notifications
  * if the call is successful.
  *
+ * Suspended devices are not touched at all, and -EAGAIN is returned.
+ *
  * Note that the @force parameter cannot override a (possibly cached)
  * state of RFKILL_STATE_HARD_BLOCKED.  Any device making use of
  * RFKILL_STATE_HARD_BLOCKED implements either get_state() or
@@ -168,6 +170,9 @@ static int rfkill_toggle_radio(struct rfkill *rfkill,
        int retval = 0;
        enum rfkill_state oldstate, newstate;
 
+       if (unlikely(rfkill->dev.power.power_state.event & PM_EVENT_SLEEP))
+               return -EBUSY;
+
        oldstate = rfkill->state;
 
        if (rfkill->get_state && !force &&
@@ -214,7 +219,7 @@ static int rfkill_toggle_radio(struct rfkill *rfkill,
  *
  * This function toggles the state of all switches of given type,
  * unless a specific switch is claimed by userspace (in which case,
- * that switch is left alone).
+ * that switch is left alone) or suspended.
  */
 void rfkill_switch_all(enum rfkill_type type, enum rfkill_state state)
 {
@@ -239,8 +244,8 @@ EXPORT_SYMBOL(rfkill_switch_all);
 /**
  * rfkill_epo - emergency power off all transmitters
  *
- * This kicks all rfkill devices to RFKILL_STATE_SOFT_BLOCKED, ignoring
- * everything in its path but rfkill_mutex and rfkill->mutex.
+ * This kicks all non-suspended rfkill devices to RFKILL_STATE_SOFT_BLOCKED,
+ * ignoring everything in its path but rfkill_mutex and rfkill->mutex.
  */
 void rfkill_epo(void)
 {
@@ -458,13 +463,14 @@ static int rfkill_resume(struct device *dev)
        if (dev->power.power_state.event != PM_EVENT_ON) {
                mutex_lock(&rfkill->mutex);
 
+               dev->power.power_state.event = PM_EVENT_ON;
+
                /* restore radio state AND notify everybody */
                rfkill_toggle_radio(rfkill, rfkill->state, 1);
 
                mutex_unlock(&rfkill->mutex);
        }
 
-       dev->power.power_state = PMSG_ON;
        return 0;
 }
 #else
index d2b6f54a626191b33fa782bd262b279a02cd57ef..5cafdd4c801848f00e3d55daca0d81875d709c7d 100644 (file)
@@ -280,7 +280,7 @@ replay:
                if (n->nlmsg_type == RTM_DELTFILTER && t->tcm_handle == 0) {
                        spin_lock_bh(root_lock);
                        *back = tp->next;
-                       spin_lock_bh(root_lock);
+                       spin_unlock_bh(root_lock);
 
                        tfilter_notify(skb, n, tp, fh, RTM_DELTFILTER);
                        tcf_destroy(tp);
index c25465e5607aeb32cf39fb8c784514a64ebedcbf..e7fb9e0d21b48a2949d846c61b9c775a535bcd24 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/kmod.h>
 #include <linux/list.h>
 #include <linux/hrtimer.h>
+#include <linux/lockdep.h>
 
 #include <net/net_namespace.h>
 #include <net/sock.h>
@@ -198,19 +199,53 @@ struct Qdisc *qdisc_match_from_root(struct Qdisc *root, u32 handle)
        return NULL;
 }
 
+/*
+ * This lock is needed until some qdiscs stop calling qdisc_tree_decrease_qlen()
+ * without rtnl_lock(); currently hfsc_dequeue(), netem_dequeue(), tbf_dequeue()
+ */
+static DEFINE_SPINLOCK(qdisc_list_lock);
+
+static void qdisc_list_add(struct Qdisc *q)
+{
+       if ((q->parent != TC_H_ROOT) && !(q->flags & TCQ_F_INGRESS)) {
+               spin_lock_bh(&qdisc_list_lock);
+               list_add_tail(&q->list, &qdisc_root_sleeping(q)->list);
+               spin_unlock_bh(&qdisc_list_lock);
+       }
+}
+
+void qdisc_list_del(struct Qdisc *q)
+{
+       if ((q->parent != TC_H_ROOT) && !(q->flags & TCQ_F_INGRESS)) {
+               spin_lock_bh(&qdisc_list_lock);
+               list_del(&q->list);
+               spin_unlock_bh(&qdisc_list_lock);
+       }
+}
+EXPORT_SYMBOL(qdisc_list_del);
+
 struct Qdisc *qdisc_lookup(struct net_device *dev, u32 handle)
 {
        unsigned int i;
+       struct Qdisc *q;
+
+       spin_lock_bh(&qdisc_list_lock);
 
        for (i = 0; i < dev->num_tx_queues; i++) {
                struct netdev_queue *txq = netdev_get_tx_queue(dev, i);
-               struct Qdisc *q, *txq_root = txq->qdisc_sleeping;
+               struct Qdisc *txq_root = txq->qdisc_sleeping;
 
                q = qdisc_match_from_root(txq_root, handle);
                if (q)
-                       return q;
+                       goto unlock;
        }
-       return qdisc_match_from_root(dev->rx_queue.qdisc_sleeping, handle);
+
+       q = qdisc_match_from_root(dev->rx_queue.qdisc_sleeping, handle);
+
+unlock:
+       spin_unlock_bh(&qdisc_list_lock);
+
+       return q;
 }
 
 static struct Qdisc *qdisc_leaf(struct Qdisc *p, u32 classid)
@@ -331,7 +366,7 @@ static struct qdisc_size_table *qdisc_get_stab(struct nlattr *opt)
        if (!s || tsize != s->tsize || (!tab && tsize > 0))
                return ERR_PTR(-EINVAL);
 
-       spin_lock_bh(&qdisc_stab_lock);
+       spin_lock(&qdisc_stab_lock);
 
        list_for_each_entry(stab, &qdisc_stab_list, list) {
                if (memcmp(&stab->szopts, s, sizeof(*s)))
@@ -339,11 +374,11 @@ static struct qdisc_size_table *qdisc_get_stab(struct nlattr *opt)
                if (tsize > 0 && memcmp(stab->data, tab, tsize * sizeof(u16)))
                        continue;
                stab->refcnt++;
-               spin_unlock_bh(&qdisc_stab_lock);
+               spin_unlock(&qdisc_stab_lock);
                return stab;
        }
 
-       spin_unlock_bh(&qdisc_stab_lock);
+       spin_unlock(&qdisc_stab_lock);
 
        stab = kmalloc(sizeof(*stab) + tsize * sizeof(u16), GFP_KERNEL);
        if (!stab)
@@ -354,9 +389,9 @@ static struct qdisc_size_table *qdisc_get_stab(struct nlattr *opt)
        if (tsize > 0)
                memcpy(stab->data, tab, tsize * sizeof(u16));
 
-       spin_lock_bh(&qdisc_stab_lock);
+       spin_lock(&qdisc_stab_lock);
        list_add_tail(&stab->list, &qdisc_stab_list);
-       spin_unlock_bh(&qdisc_stab_lock);
+       spin_unlock(&qdisc_stab_lock);
 
        return stab;
 }
@@ -366,14 +401,14 @@ void qdisc_put_stab(struct qdisc_size_table *tab)
        if (!tab)
                return;
 
-       spin_lock_bh(&qdisc_stab_lock);
+       spin_lock(&qdisc_stab_lock);
 
        if (--tab->refcnt == 0) {
                list_del(&tab->list);
                kfree(tab);
        }
 
-       spin_unlock_bh(&qdisc_stab_lock);
+       spin_unlock(&qdisc_stab_lock);
 }
 EXPORT_SYMBOL(qdisc_put_stab);
 
@@ -426,7 +461,7 @@ static enum hrtimer_restart qdisc_watchdog(struct hrtimer *timer)
 
        wd->qdisc->flags &= ~TCQ_F_THROTTLED;
        smp_wmb();
-       __netif_schedule(wd->qdisc);
+       __netif_schedule(qdisc_root(wd->qdisc));
 
        return HRTIMER_NORESTART;
 }
@@ -443,6 +478,10 @@ void qdisc_watchdog_schedule(struct qdisc_watchdog *wd, psched_time_t expires)
 {
        ktime_t time;
 
+       if (test_bit(__QDISC_STATE_DEACTIVATED,
+                    &qdisc_root_sleeping(wd->qdisc)->state))
+               return;
+
        wd->qdisc->flags |= TCQ_F_THROTTLED;
        time = ktime_set(0, 0);
        time = ktime_add_ns(time, PSCHED_US2NS(expires));
@@ -637,11 +676,8 @@ static void notify_and_destroy(struct sk_buff *skb, struct nlmsghdr *n, u32 clid
        if (new || old)
                qdisc_notify(skb, n, clid, old, new);
 
-       if (old) {
-               spin_lock_bh(&old->q.lock);
+       if (old)
                qdisc_destroy(old);
-               spin_unlock_bh(&old->q.lock);
-       }
 }
 
 /* Graft qdisc "new" to class "classid" of qdisc "parent" or
@@ -707,6 +743,10 @@ static int qdisc_graft(struct net_device *dev, struct Qdisc *parent,
        return err;
 }
 
+/* lockdep annotation is needed for ingress; egress gets it only for name */
+static struct lock_class_key qdisc_tx_lock;
+static struct lock_class_key qdisc_rx_lock;
+
 /*
    Allocate and initialize new qdisc.
 
@@ -767,6 +807,7 @@ qdisc_create(struct net_device *dev, struct netdev_queue *dev_queue,
        if (handle == TC_H_INGRESS) {
                sch->flags |= TCQ_F_INGRESS;
                handle = TC_H_MAKE(TC_H_INGRESS, 0);
+               lockdep_set_class(qdisc_lock(sch), &qdisc_rx_lock);
        } else {
                if (handle == 0) {
                        handle = qdisc_alloc_handle(dev);
@@ -774,6 +815,7 @@ qdisc_create(struct net_device *dev, struct netdev_queue *dev_queue,
                        if (handle == 0)
                                goto err_out3;
                }
+               lockdep_set_class(qdisc_lock(sch), &qdisc_tx_lock);
        }
 
        sch->handle = handle;
@@ -802,8 +844,8 @@ qdisc_create(struct net_device *dev, struct netdev_queue *dev_queue,
                                goto err_out3;
                        }
                }
-               if ((parent != TC_H_ROOT) && !(sch->flags & TCQ_F_INGRESS))
-                       list_add_tail(&sch->list, &dev_queue->qdisc_sleeping->list);
+
+               qdisc_list_add(sch);
 
                return sch;
        }
@@ -1084,20 +1126,13 @@ create_n_graft:
        }
 
 graft:
-       if (1) {
-               spinlock_t *root_lock;
-
-               err = qdisc_graft(dev, p, skb, n, clid, q, NULL);
-               if (err) {
-                       if (q) {
-                               root_lock = qdisc_root_lock(q);
-                               spin_lock_bh(root_lock);
-                               qdisc_destroy(q);
-                               spin_unlock_bh(root_lock);
-                       }
-                       return err;
-               }
+       err = qdisc_graft(dev, p, skb, n, clid, q, NULL);
+       if (err) {
+               if (q)
+                       qdisc_destroy(q);
+               return err;
        }
+
        return 0;
 }
 
index 4e261ce62f48071dc3a0569cbfd0d5915a9577dc..8fa90d68ec6d8ab2f7ac47efcd511e31553bece6 100644 (file)
@@ -521,6 +521,10 @@ static void cbq_ovl_delay(struct cbq_class *cl)
        struct cbq_sched_data *q = qdisc_priv(cl->qdisc);
        psched_tdiff_t delay = cl->undertime - q->now;
 
+       if (test_bit(__QDISC_STATE_DEACTIVATED,
+                    &qdisc_root_sleeping(cl->qdisc)->state))
+               return;
+
        if (!cl->delayed) {
                psched_time_t sched = q->now;
                ktime_t expires;
@@ -654,7 +658,7 @@ static enum hrtimer_restart cbq_undelay(struct hrtimer *timer)
        }
 
        sch->flags &= ~TCQ_F_THROTTLED;
-       __netif_schedule(sch);
+       __netif_schedule(qdisc_root(sch));
        return HRTIMER_NORESTART;
 }
 
index 468574682caab154eba2d8f35b09de3f8272522e..5f0ade7806a733e732ebcc6756695c0065fd844d 100644 (file)
@@ -518,15 +518,17 @@ void qdisc_reset(struct Qdisc *qdisc)
 }
 EXPORT_SYMBOL(qdisc_reset);
 
-/* this is the rcu callback function to clean up a qdisc when there
- * are no further references to it */
-
-static void __qdisc_destroy(struct rcu_head *head)
+void qdisc_destroy(struct Qdisc *qdisc)
 {
-       struct Qdisc *qdisc = container_of(head, struct Qdisc, q_rcu);
        const struct Qdisc_ops  *ops = qdisc->ops;
 
+       if (qdisc->flags & TCQ_F_BUILTIN ||
+           !atomic_dec_and_test(&qdisc->refcnt))
+               return;
+
 #ifdef CONFIG_NET_SCHED
+       qdisc_list_del(qdisc);
+
        qdisc_put_stab(qdisc->stab);
 #endif
        gen_kill_estimator(&qdisc->bstats, &qdisc->rate_est);
@@ -542,20 +544,6 @@ static void __qdisc_destroy(struct rcu_head *head)
 
        kfree((char *) qdisc - qdisc->padded);
 }
-
-/* Under qdisc_lock(qdisc) and BH! */
-
-void qdisc_destroy(struct Qdisc *qdisc)
-{
-       if (qdisc->flags & TCQ_F_BUILTIN ||
-           !atomic_dec_and_test(&qdisc->refcnt))
-               return;
-
-       if (qdisc->parent)
-               list_del(&qdisc->list);
-
-       call_rcu(&qdisc->q_rcu, __qdisc_destroy);
-}
 EXPORT_SYMBOL(qdisc_destroy);
 
 static bool dev_all_qdisc_sleeping_noop(struct net_device *dev)
@@ -597,6 +585,9 @@ static void transition_one_qdisc(struct net_device *dev,
        struct Qdisc *new_qdisc = dev_queue->qdisc_sleeping;
        int *need_watchdog_p = _need_watchdog;
 
+       if (!(new_qdisc->flags & TCQ_F_BUILTIN))
+               clear_bit(__QDISC_STATE_DEACTIVATED, &new_qdisc->state);
+
        rcu_assign_pointer(dev_queue->qdisc, new_qdisc);
        if (need_watchdog_p && new_qdisc != &noqueue_qdisc)
                *need_watchdog_p = 1;
@@ -640,6 +631,9 @@ static void dev_deactivate_queue(struct net_device *dev,
        if (qdisc) {
                spin_lock_bh(qdisc_lock(qdisc));
 
+               if (!(qdisc->flags & TCQ_F_BUILTIN))
+                       set_bit(__QDISC_STATE_DEACTIVATED, &qdisc->state);
+
                dev_queue->qdisc = qdisc_default;
                qdisc_reset(qdisc);
 
@@ -647,7 +641,7 @@ static void dev_deactivate_queue(struct net_device *dev,
        }
 }
 
-static bool some_qdisc_is_busy(struct net_device *dev, int lock)
+static bool some_qdisc_is_busy(struct net_device *dev)
 {
        unsigned int i;
 
@@ -661,14 +655,12 @@ static bool some_qdisc_is_busy(struct net_device *dev, int lock)
                q = dev_queue->qdisc_sleeping;
                root_lock = qdisc_lock(q);
 
-               if (lock)
-                       spin_lock_bh(root_lock);
+               spin_lock_bh(root_lock);
 
                val = (test_bit(__QDISC_STATE_RUNNING, &q->state) ||
                       test_bit(__QDISC_STATE_SCHED, &q->state));
 
-               if (lock)
-                       spin_unlock_bh(root_lock);
+               spin_unlock_bh(root_lock);
 
                if (val)
                        return true;
@@ -678,8 +670,6 @@ static bool some_qdisc_is_busy(struct net_device *dev, int lock)
 
 void dev_deactivate(struct net_device *dev)
 {
-       bool running;
-
        netdev_for_each_tx_queue(dev, dev_deactivate_queue, &noop_qdisc);
        dev_deactivate_queue(dev, &dev->rx_queue, &noop_qdisc);
 
@@ -689,25 +679,8 @@ void dev_deactivate(struct net_device *dev)
        synchronize_rcu();
 
        /* Wait for outstanding qdisc_run calls. */
-       do {
-               while (some_qdisc_is_busy(dev, 0))
-                       yield();
-
-               /*
-                * Double-check inside queue lock to ensure that all effects
-                * of the queue run are visible when we return.
-                */
-               running = some_qdisc_is_busy(dev, 1);
-
-               /*
-                * The running flag should never be set at this point because
-                * we've already set dev->qdisc to noop_qdisc *inside* the same
-                * pair of spin locks.  That is, if any qdisc_run starts after
-                * our initial test it should see the noop_qdisc and then
-                * clear the RUNNING bit before dropping the queue lock.  So
-                * if it is set here then we've found a bug.
-                */
-       } while (WARN_ON_ONCE(running));
+       while (some_qdisc_is_busy(dev))
+               yield();
 }
 
 static void dev_init_scheduler_queue(struct net_device *dev,
@@ -736,14 +709,10 @@ static void shutdown_scheduler_queue(struct net_device *dev,
        struct Qdisc *qdisc_default = _qdisc_default;
 
        if (qdisc) {
-               spinlock_t *root_lock = qdisc_lock(qdisc);
-
                dev_queue->qdisc = qdisc_default;
                dev_queue->qdisc_sleeping = qdisc_default;
 
-               spin_lock_bh(root_lock);
                qdisc_destroy(qdisc);
-               spin_unlock_bh(root_lock);
        }
 }
 
index 6febd245e62b349b061674986a13b826cff8e02a..0df0df202ed064770699569a6749563ec2d34706 100644 (file)
@@ -577,7 +577,7 @@ static int htb_enqueue(struct sk_buff *skb, struct Qdisc *sch)
                        sch->qstats.drops++;
                        cl->qstats.drops++;
                }
-               return NET_XMIT_DROP;
+               return ret;
        } else {
                cl->bstats.packets +=
                        skb_is_gso(skb)?skb_shinfo(skb)->gso_segs:1;
@@ -623,7 +623,7 @@ static int htb_requeue(struct sk_buff *skb, struct Qdisc *sch)
                        sch->qstats.drops++;
                        cl->qstats.drops++;
                }
-               return NET_XMIT_DROP;
+               return ret;
        } else
                htb_activate(q, cl);
 
index eac197610edf28b6b7bb019769c260d9f723fbe9..a6697c686c7fe18d3fdec32ab58e2e4671d3278a 100644 (file)
@@ -113,11 +113,11 @@ prio_requeue(struct sk_buff *skb, struct Qdisc* sch)
        if ((ret = qdisc->ops->requeue(skb, qdisc)) == NET_XMIT_SUCCESS) {
                sch->q.qlen++;
                sch->qstats.requeues++;
-               return 0;
+               return NET_XMIT_SUCCESS;
        }
        if (net_xmit_drop_count(ret))
                sch->qstats.drops++;
-       return NET_XMIT_DROP;
+       return ret;
 }
 
 
index 7d3b7ff3bf07fbb1af0de7cab8a5056a37254937..94c61598b86ae1c0f52a23817f797a216b77492f 100644 (file)
@@ -123,15 +123,8 @@ static int tbf_enqueue(struct sk_buff *skb, struct Qdisc* sch)
        struct tbf_sched_data *q = qdisc_priv(sch);
        int ret;
 
-       if (qdisc_pkt_len(skb) > q->max_size) {
-               sch->qstats.drops++;
-#ifdef CONFIG_NET_CLS_ACT
-               if (sch->reshape_fail == NULL || sch->reshape_fail(skb, sch))
-#endif
-                       kfree_skb(skb);
-
-               return NET_XMIT_DROP;
-       }
+       if (qdisc_pkt_len(skb) > q->max_size)
+               return qdisc_reshape_fail(skb, sch);
 
        ret = qdisc_enqueue(skb, q->qdisc);
        if (ret != 0) {
index e39a0cdef1841748d2957f581e7a90d76cd49359..4c8d9f45ce0999b5141f7fb92a7ee4ab1b03ef99 100644 (file)
@@ -103,6 +103,7 @@ static struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep,
 
                /* Initialize the CHUNKS parameter */
                auth_chunks->param_hdr.type = SCTP_PARAM_CHUNKS;
+               auth_chunks->param_hdr.length = htons(sizeof(sctp_paramhdr_t));
 
                /* If the Add-IP functionality is enabled, we must
                 * authenticate, ASCONF and ASCONF-ACK chunks
@@ -110,8 +111,7 @@ static struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep,
                if (sctp_addip_enable) {
                        auth_chunks->chunks[0] = SCTP_CID_ASCONF;
                        auth_chunks->chunks[1] = SCTP_CID_ASCONF_ACK;
-                       auth_chunks->param_hdr.length =
-                                       htons(sizeof(sctp_paramhdr_t) + 2);
+                       auth_chunks->param_hdr.length += htons(2);
                }
        }
 
index 483a01d0740a888efb4325358ee33d441f5fe80b..47f91afa02114229997f0f06810e156fcf9580fc 100644 (file)
@@ -319,7 +319,8 @@ static void sctp_v6_get_saddr(struct sctp_sock *sk,
                          __func__, asoc, dst, NIP6(daddr->v6.sin6_addr));
 
        if (!asoc) {
-               ipv6_dev_get_saddr(dst ? ip6_dst_idev(dst)->dev : NULL,
+               ipv6_dev_get_saddr(sock_net(sctp_opt2sk(sk)),
+                                  dst ? ip6_dst_idev(dst)->dev : NULL,
                                   &daddr->v6.sin6_addr,
                                   inet6_sk(&sk->inet.sk)->srcprefs,
                                   &saddr->v6.sin6_addr);
index dbb79adf8f3c0bab606f7141e96ae96dd29b3e4c..bb5c9ef130467320f0687eca3fc5702f6f17a59c 100644 (file)
@@ -3055,6 +3055,9 @@ static int sctp_setsockopt_auth_chunk(struct sock *sk,
 {
        struct sctp_authchunk val;
 
+       if (!sctp_auth_enable)
+               return -EACCES;
+
        if (optlen != sizeof(struct sctp_authchunk))
                return -EINVAL;
        if (copy_from_user(&val, optval, optlen))
@@ -3085,6 +3088,9 @@ static int sctp_setsockopt_hmac_ident(struct sock *sk,
        struct sctp_hmacalgo *hmacs;
        int err;
 
+       if (!sctp_auth_enable)
+               return -EACCES;
+
        if (optlen < sizeof(struct sctp_hmacalgo))
                return -EINVAL;
 
@@ -3123,6 +3129,9 @@ static int sctp_setsockopt_auth_key(struct sock *sk,
        struct sctp_association *asoc;
        int ret;
 
+       if (!sctp_auth_enable)
+               return -EACCES;
+
        if (optlen <= sizeof(struct sctp_authkey))
                return -EINVAL;
 
@@ -3160,6 +3169,9 @@ static int sctp_setsockopt_active_key(struct sock *sk,
        struct sctp_authkeyid val;
        struct sctp_association *asoc;
 
+       if (!sctp_auth_enable)
+               return -EACCES;
+
        if (optlen != sizeof(struct sctp_authkeyid))
                return -EINVAL;
        if (copy_from_user(&val, optval, optlen))
@@ -3185,6 +3197,9 @@ static int sctp_setsockopt_del_key(struct sock *sk,
        struct sctp_authkeyid val;
        struct sctp_association *asoc;
 
+       if (!sctp_auth_enable)
+               return -EACCES;
+
        if (optlen != sizeof(struct sctp_authkeyid))
                return -EINVAL;
        if (copy_from_user(&val, optval, optlen))
@@ -5197,19 +5212,29 @@ static int sctp_getsockopt_maxburst(struct sock *sk, int len,
 static int sctp_getsockopt_hmac_ident(struct sock *sk, int len,
                                    char __user *optval, int __user *optlen)
 {
+       struct sctp_hmacalgo  __user *p = (void __user *)optval;
        struct sctp_hmac_algo_param *hmacs;
-       __u16 param_len;
+       __u16 data_len = 0;
+       u32 num_idents;
+
+       if (!sctp_auth_enable)
+               return -EACCES;
 
        hmacs = sctp_sk(sk)->ep->auth_hmacs_list;
-       param_len = ntohs(hmacs->param_hdr.length);
+       data_len = ntohs(hmacs->param_hdr.length) - sizeof(sctp_paramhdr_t);
 
-       if (len < param_len)
+       if (len < sizeof(struct sctp_hmacalgo) + data_len)
                return -EINVAL;
+
+       len = sizeof(struct sctp_hmacalgo) + data_len;
+       num_idents = data_len / sizeof(u16);
+
        if (put_user(len, optlen))
                return -EFAULT;
-       if (copy_to_user(optval, hmacs->hmac_ids, len))
+       if (put_user(num_idents, &p->shmac_num_idents))
+               return -EFAULT;
+       if (copy_to_user(p->shmac_idents, hmacs->hmac_ids, data_len))
                return -EFAULT;
-
        return 0;
 }
 
@@ -5219,6 +5244,9 @@ static int sctp_getsockopt_active_key(struct sock *sk, int len,
        struct sctp_authkeyid val;
        struct sctp_association *asoc;
 
+       if (!sctp_auth_enable)
+               return -EACCES;
+
        if (len < sizeof(struct sctp_authkeyid))
                return -EINVAL;
        if (copy_from_user(&val, optval, sizeof(struct sctp_authkeyid)))
@@ -5233,6 +5261,12 @@ static int sctp_getsockopt_active_key(struct sock *sk, int len,
        else
                val.scact_keynumber = sctp_sk(sk)->ep->active_key_id;
 
+       len = sizeof(struct sctp_authkeyid);
+       if (put_user(len, optlen))
+               return -EFAULT;
+       if (copy_to_user(optval, &val, len))
+               return -EFAULT;
+
        return 0;
 }
 
@@ -5243,13 +5277,16 @@ static int sctp_getsockopt_peer_auth_chunks(struct sock *sk, int len,
        struct sctp_authchunks val;
        struct sctp_association *asoc;
        struct sctp_chunks_param *ch;
-       u32    num_chunks;
+       u32    num_chunks = 0;
        char __user *to;
 
-       if (len <= sizeof(struct sctp_authchunks))
+       if (!sctp_auth_enable)
+               return -EACCES;
+
+       if (len < sizeof(struct sctp_authchunks))
                return -EINVAL;
 
-       if (copy_from_user(&val, p, sizeof(struct sctp_authchunks)))
+       if (copy_from_user(&val, optval, sizeof(struct sctp_authchunks)))
                return -EFAULT;
 
        to = p->gauth_chunks;
@@ -5258,20 +5295,21 @@ static int sctp_getsockopt_peer_auth_chunks(struct sock *sk, int len,
                return -EINVAL;
 
        ch = asoc->peer.peer_chunks;
+       if (!ch)
+               goto num;
 
        /* See if the user provided enough room for all the data */
        num_chunks = ntohs(ch->param_hdr.length) - sizeof(sctp_paramhdr_t);
        if (len < num_chunks)
                return -EINVAL;
 
-       len = num_chunks;
-       if (put_user(len, optlen))
+       if (copy_to_user(to, ch->chunks, num_chunks))
                return -EFAULT;
+num:
+       len = sizeof(struct sctp_authchunks) + num_chunks;
+       if (put_user(len, optlen)) return -EFAULT;
        if (put_user(num_chunks, &p->gauth_number_of_chunks))
                return -EFAULT;
-       if (copy_to_user(to, ch->chunks, len))
-               return -EFAULT;
-
        return 0;
 }
 
@@ -5282,13 +5320,16 @@ static int sctp_getsockopt_local_auth_chunks(struct sock *sk, int len,
        struct sctp_authchunks val;
        struct sctp_association *asoc;
        struct sctp_chunks_param *ch;
-       u32    num_chunks;
+       u32    num_chunks = 0;
        char __user *to;
 
-       if (len <= sizeof(struct sctp_authchunks))
+       if (!sctp_auth_enable)
+               return -EACCES;
+
+       if (len < sizeof(struct sctp_authchunks))
                return -EINVAL;
 
-       if (copy_from_user(&val, p, sizeof(struct sctp_authchunks)))
+       if (copy_from_user(&val, optval, sizeof(struct sctp_authchunks)))
                return -EFAULT;
 
        to = p->gauth_chunks;
@@ -5301,17 +5342,21 @@ static int sctp_getsockopt_local_auth_chunks(struct sock *sk, int len,
        else
                ch = sctp_sk(sk)->ep->auth_chunk_list;
 
+       if (!ch)
+               goto num;
+
        num_chunks = ntohs(ch->param_hdr.length) - sizeof(sctp_paramhdr_t);
-       if (len < num_chunks)
+       if (len < sizeof(struct sctp_authchunks) + num_chunks)
                return -EINVAL;
 
-       len = num_chunks;
+       if (copy_to_user(to, ch->chunks, num_chunks))
+               return -EFAULT;
+num:
+       len = sizeof(struct sctp_authchunks) + num_chunks;
        if (put_user(len, optlen))
                return -EFAULT;
        if (put_user(num_chunks, &p->gauth_number_of_chunks))
                return -EFAULT;
-       if (copy_to_user(to, ch->chunks, len))
-               return -EFAULT;
 
        return 0;
 }
index 4fa1f3ad251340833a3b5d4b094dbc0c05557068..4c9890ec252875500c6c35d388fdd44af9545f34 100644 (file)
@@ -344,14 +344,20 @@ static void do_pnp_device_entry(void *symval, unsigned long size,
                                struct module *mod)
 {
        const unsigned long id_size = sizeof(struct pnp_device_id);
-       const struct pnp_device_id *id = symval;
+       const unsigned int count = (size / id_size)-1;
+       const struct pnp_device_id *devs = symval;
+       unsigned int i;
 
        device_id_check(mod->name, "pnp", size, id_size, symval);
 
-       buf_printf(&mod->dev_table_buf,
-                  "MODULE_ALIAS(\"pnp:d%s*\");\n", id->id);
-       buf_printf(&mod->dev_table_buf,
-                  "MODULE_ALIAS(\"acpi*:%s:*\");\n", id->id);
+       for (i = 0; i < count; i++) {
+               const char *id = (char *)devs[i].id;
+
+               buf_printf(&mod->dev_table_buf,
+                          "MODULE_ALIAS(\"pnp:d%s*\");\n", id);
+               buf_printf(&mod->dev_table_buf,
+                          "MODULE_ALIAS(\"acpi*:%s:*\");\n", id);
+       }
 }
 
 /* looks like: "pnp:dD" for every device of the card */
index ee0741f9eb5322c26f782a9fe59460db1568b1cf..fbef38a9604ae31e775cfdaaeac3a5efef922dc9 100644 (file)
@@ -38,7 +38,6 @@
 #include <linux/interrupt.h>
 #include <linux/init.h>
 #include <linux/slab.h>
-#include <linux/version.h>
 #include <sound/core.h>
 #include <sound/initval.h>
 #include <sound/pcm.h>
index 2f8b28add27687cfb63815836a72a06e1050eb92..03a274becae0ba9599a777819ed16a72ce453828 100644 (file)
@@ -249,11 +249,12 @@ static struct snd_ca0106_details ca0106_chip_details[] = {
           .name   = "MSI K8N Diamond MB [SB0438]",
           .gpio_type = 2,
           .i2c_adc = 1 } ,
-        /* Another MSI K8N Diamond MB, which has apprently a different SSID */
+        /* MSI K8N Diamond PLUS MB */
         { .serial = 0x10091102,
           .name   = "MSI K8N Diamond MB",
           .gpio_type = 2,
-          .i2c_adc = 1 } ,
+          .i2c_adc = 1,
+          .spi_dac = 2 }
         /* Shuttle XPC SD31P which has an onboard Creative Labs
          * Sound Blaster Live! 24-bit EAX
          * high-definition 7.1 audio processor".
index a73d6ca0a90655104c48b7ea50b4089815de5b70..1c53e337ecb2dce93b833dcce526f64288cc9136 100644 (file)
@@ -278,6 +278,9 @@ enum {
 /* Defines for Nvidia HDA support */
 #define NVIDIA_HDA_TRANSREG_ADDR      0x4e
 #define NVIDIA_HDA_ENABLE_COHBITS     0x0f
+#define NVIDIA_HDA_ISTRM_COH          0x4d
+#define NVIDIA_HDA_OSTRM_COH          0x4c
+#define NVIDIA_HDA_ENABLE_COHBIT      0x01
 
 /* Defines for Intel SCH HDA snoop control */
 #define INTEL_SCH_HDA_DEVC      0x78
@@ -900,6 +903,12 @@ static void azx_init_pci(struct azx *chip)
                update_pci_byte(chip->pci,
                                NVIDIA_HDA_TRANSREG_ADDR,
                                0x0f, NVIDIA_HDA_ENABLE_COHBITS);
+               update_pci_byte(chip->pci,
+                               NVIDIA_HDA_ISTRM_COH,
+                               0x01, NVIDIA_HDA_ENABLE_COHBIT);
+               update_pci_byte(chip->pci,
+                               NVIDIA_HDA_OSTRM_COH,
+                               0x01, NVIDIA_HDA_ENABLE_COHBIT);
                break;
        case AZX_DRIVER_SCH:
                pci_read_config_word(chip->pci, INTEL_SCH_HDA_DEVC, &snoop);
index b80e725432f047aaa9ab7b3016b27454bdc2daae..909f1c101c95af5e0a1c2db614a946de1cd570be 100644 (file)
@@ -952,7 +952,7 @@ do_sku:
                                            tmp | 0x2010);
                        break;
                case 0x10ec0888:
-                       alc888_coef_init(codec);
+                       /*alc888_coef_init(codec);*/ /* called in alc_init() */
                        break;
                case 0x10ec0267:
                case 0x10ec0268:
@@ -2439,6 +2439,8 @@ static int alc_init(struct hda_codec *codec)
        unsigned int i;
 
        alc_fix_pll(codec);
+       if (codec->vendor_id == 0x10ec0888)
+               alc888_coef_init(codec);
 
        for (i = 0; i < spec->num_init_verbs; i++)
                snd_hda_sequence_write(codec, spec->init_verbs[i]);
@@ -8426,8 +8428,6 @@ static int patch_alc883(struct hda_codec *codec)
        codec->patch_ops = alc_patch_ops;
        if (board_config == ALC883_AUTO)
                spec->init_hook = alc883_auto_init;
-       else if (codec->vendor_id == 0x10ec0888)
-               spec->init_hook = alc888_coef_init;
 
 #ifdef CONFIG_SND_HDA_POWER_SAVE
        if (!spec->loopback.amplist)
index b081e83766b7bcf321faaaf17cfc25297089c0b6..b81d6b2cfa1d73ca2f393ab97ee803066a67a262 100644 (file)
@@ -22,7 +22,6 @@
 
 #include <linux/module.h>
 #include <linux/moduleparam.h>
-#include <linux/version.h>
 #include <linux/kernel.h>
 #include <linux/clk.h>
 #include <linux/timer.h>
index b26003c4f3e850ba1559a9e158b1dca609fbda67..7da9f467b7b83f06d4fdf02a44e05ba4ff530b97 100644 (file)
@@ -562,10 +562,9 @@ static int ak4535_codec_probe(struct i2c_adapter *adap, int addr, int kind)
        client_template.addr = addr;
 
        i2c = kmemdup(&client_template, sizeof(client_template), GFP_KERNEL);
-       if (i2c == NULL) {
-               kfree(codec);
+       if (i2c == NULL)
                return -ENOMEM;
-       }
+
        i2c_set_clientdata(i2c, codec);
        codec->control_data = i2c;
 
@@ -583,7 +582,6 @@ static int ak4535_codec_probe(struct i2c_adapter *adap, int addr, int kind)
        return ret;
 
 err:
-       kfree(codec);
        kfree(i2c);
        return ret;
 }
@@ -660,6 +658,11 @@ static int ak4535_probe(struct platform_device *pdev)
 #else
        /* Add other interfaces here */
 #endif
+
+       if (ret != 0) {
+               kfree(codec->private_data);
+               kfree(codec);
+       }
        return ret;
 }
 
index b1dce5f459db6d40663112ecb2e3f8eb13bb30a9..5f9abb199435b35e82d99d7603e11f2338556080 100644 (file)
@@ -1199,10 +1199,9 @@ static int aic3x_codec_probe(struct i2c_adapter *adap, int addr, int kind)
        client_template.addr = addr;
 
        i2c = kmemdup(&client_template, sizeof(client_template), GFP_KERNEL);
-       if (i2c == NULL) {
-               kfree(codec);
+       if (i2c == NULL)
                return -ENOMEM;
-       }
+
        i2c_set_clientdata(i2c, codec);
        codec->control_data = i2c;
 
@@ -1221,7 +1220,6 @@ static int aic3x_codec_probe(struct i2c_adapter *adap, int addr, int kind)
        return ret;
 
 err:
-       kfree(codec);
        kfree(i2c);
        return ret;
 }
@@ -1302,6 +1300,11 @@ static int aic3x_probe(struct platform_device *pdev)
 #else
        /* Add other interfaces here */
 #endif
+
+       if (ret != 0) {
+               kfree(codec->private_data);
+               kfree(codec);
+       }
        return ret;
 }
 
index a52d6d9e007adf718fd25ac951c9eb55e1251cec..807318fbdc8f182a96df656f3918770887a65e31 100644 (file)
@@ -729,10 +729,9 @@ static int uda1380_codec_probe(struct i2c_adapter *adap, int addr, int kind)
        client_template.addr = addr;
 
        i2c = kmemdup(&client_template, sizeof(client_template), GFP_KERNEL);
-       if (i2c == NULL) {
-               kfree(codec);
+       if (i2c == NULL)
                return -ENOMEM;
-       }
+
        i2c_set_clientdata(i2c, codec);
        codec->control_data = i2c;
 
@@ -750,7 +749,6 @@ static int uda1380_codec_probe(struct i2c_adapter *adap, int addr, int kind)
        return ret;
 
 err:
-       kfree(codec);
        kfree(i2c);
        return ret;
 }
@@ -817,6 +815,9 @@ static int uda1380_probe(struct platform_device *pdev)
 #else
        /* Add other interfaces here */
 #endif
+
+       if (ret != 0)
+               kfree(codec);
        return ret;
 }
 
index 67325fd954472f51563b5803b799b69a119eca37..3d998e6a997e5270838a4532c425e154fb8f2bd6 100644 (file)
@@ -693,10 +693,9 @@ static int wm8510_codec_probe(struct i2c_adapter *adap, int addr, int kind)
        client_template.addr = addr;
 
        i2c = kmemdup(&client_template, sizeof(client_template), GFP_KERNEL);
-       if (i2c == NULL) {
-               kfree(codec);
+       if (i2c == NULL)
                return -ENOMEM;
-       }
+
        i2c_set_clientdata(i2c, codec);
        codec->control_data = i2c;
 
@@ -714,7 +713,6 @@ static int wm8510_codec_probe(struct i2c_adapter *adap, int addr, int kind)
        return ret;
 
 err:
-       kfree(codec);
        kfree(i2c);
        return ret;
 }
@@ -782,6 +780,9 @@ static int wm8510_probe(struct platform_device *pdev)
 #else
        /* Add other interfaces here */
 #endif
+
+       if (ret != 0)
+               kfree(codec);
        return ret;
 }
 
index 369d39c3f745d9d441ff23d253afaa51dc36aefb..9402fcaf04fa50b0c1c71bf2f3026e3aa0985ec8 100644 (file)
@@ -596,10 +596,9 @@ static int wm8731_codec_probe(struct i2c_adapter *adap, int addr, int kind)
        client_template.addr = addr;
 
        i2c = kmemdup(&client_template, sizeof(client_template), GFP_KERNEL);
-       if (i2c == NULL) {
-               kfree(codec);
+       if (i2c == NULL)
                return -ENOMEM;
-       }
+
        i2c_set_clientdata(i2c, codec);
        codec->control_data = i2c;
 
@@ -617,7 +616,6 @@ static int wm8731_codec_probe(struct i2c_adapter *adap, int addr, int kind)
        return ret;
 
 err:
-       kfree(codec);
        kfree(i2c);
        return ret;
 }
@@ -693,6 +691,11 @@ static int wm8731_probe(struct platform_device *pdev)
 #else
        /* Add other interfaces here */
 #endif
+
+       if (ret != 0) {
+               kfree(codec->private_data);
+               kfree(codec);
+       }
        return ret;
 }
 
index c6a8edf302ad58d44a4e9a9dd8bebb8b1b1ba777..dd1f55404b29d073a2eb5a74beb3a468882a8bd8 100644 (file)
@@ -869,10 +869,9 @@ static int wm8750_codec_probe(struct i2c_adapter *adap, int addr, int kind)
        client_template.addr = addr;
 
        i2c = kmemdup(&client_template, sizeof(client_template), GFP_KERNEL);
-       if (i2c == NULL) {
-               kfree(codec);
+       if (i2c == NULL)
                return -ENOMEM;
-       }
+
        i2c_set_clientdata(i2c, codec);
        codec->control_data = i2c;
 
@@ -890,7 +889,6 @@ static int wm8750_codec_probe(struct i2c_adapter *adap, int addr, int kind)
        return ret;
 
 err:
-       kfree(codec);
        kfree(i2c);
        return ret;
 }
@@ -966,6 +964,10 @@ static int wm8750_probe(struct platform_device *pdev)
                /* Add other interfaces here */
 #endif
 
+       if (ret != 0) {
+               kfree(codec->private_data);
+               kfree(codec);
+       }
        return ret;
 }
 
index 8604809f0c362b75ee150ae0292663683baebf6f..5761164fe16dea17481b538f4734d66fafdbebe9 100644 (file)
@@ -34,7 +34,6 @@
 
 #include <linux/module.h>
 #include <linux/moduleparam.h>
-#include <linux/version.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/delay.h>
@@ -1661,10 +1660,9 @@ static int wm8753_codec_probe(struct i2c_adapter *adap, int addr, int kind)
        client_template.addr = addr;
 
        i2c =  kmemdup(&client_template, sizeof(client_template), GFP_KERNEL);
-       if (!i2c) {
-               kfree(codec);
+       if (!i2c)
                return -ENOMEM;
-       }
+
        i2c_set_clientdata(i2c, codec);
        codec->control_data = i2c;
 
@@ -1683,7 +1681,6 @@ static int wm8753_codec_probe(struct i2c_adapter *adap, int addr, int kind)
        return ret;
 
 err:
-       kfree(codec);
        kfree(i2c);
        return ret;
 }
@@ -1760,6 +1757,11 @@ static int wm8753_probe(struct platform_device *pdev)
 #else
                /* Add other interfaces here */
 #endif
+
+       if (ret != 0) {
+               kfree(codec->private_data);
+               kfree(codec);
+       }
        return ret;
 }
 
index e44153fa38de2543ea0b912f2bdc6564ab0593af..dd995ef448b44452dcab76cdb2f3aa0f48a1b55c 100644 (file)
@@ -1500,10 +1500,9 @@ static int wm8990_codec_probe(struct i2c_adapter *adap, int addr, int kind)
        client_template.addr = addr;
 
        i2c =  kmemdup(&client_template, sizeof(client_template), GFP_KERNEL);
-       if (i2c == NULL) {
-               kfree(codec);
+       if (i2c == NULL)
                return -ENOMEM;
-       }
+
        i2c_set_clientdata(i2c, codec);
        codec->control_data = i2c;
 
@@ -1521,7 +1520,6 @@ static int wm8990_codec_probe(struct i2c_adapter *adap, int addr, int kind)
        return ret;
 
 err:
-       kfree(codec);
        kfree(i2c);
        return ret;
 }
@@ -1595,6 +1593,11 @@ static int wm8990_probe(struct platform_device *pdev)
 #else
                /* Add other interfaces here */
 #endif
+
+       if (ret != 0) {
+               kfree(codec->private_data);
+               kfree(codec);
+       }
        return ret;
 }
 
index 1fb7f9a7aecd63dfa6ae6c71414e3702047a5c5a..2f1c91b1d5567feb6fc3aea44eece7a3f00dd158 100644 (file)
@@ -13,7 +13,6 @@
 
 #include <linux/init.h>
 #include <linux/module.h>
-#include <linux/version.h>
 #include <linux/kernel.h>
 #include <linux/device.h>
 #include <sound/core.h>