Merge branch 'x86-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 15 Jul 2009 01:35:11 +0000 (18:35 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 15 Jul 2009 01:35:11 +0000 (18:35 -0700)
* 'x86-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
  x86: Fix warning in pvclock.c
  x86, apic: Fix false positive section mismatch in numaq_32.c
  x86: Fix false positive section mismatch in es7000_32.c
  x86: Remove spurious printk level from segfault message

310 files changed:
Documentation/driver-model/driver.txt
MAINTAINERS
Makefile
arch/alpha/kernel/ptrace.c
arch/blackfin/kernel/ptrace.c
arch/blackfin/kernel/sys_bfin.c
arch/cris/kernel/sys_cris.c
arch/ia64/kernel/ptrace.c
arch/m32r/kernel/ptrace.c
arch/microblaze/kernel/ptrace.c
arch/microblaze/kernel/signal.c
arch/microblaze/kernel/sys_microblaze.c
arch/mips/kernel/ptrace32.c
arch/mips/mm/hugetlbpage.c
arch/mn10300/kernel/ptrace.c
arch/mn10300/kernel/signal.c
arch/mn10300/kernel/sys_mn10300.c
arch/mn10300/kernel/traps.c
arch/mn10300/mm/fault.c
arch/mn10300/mm/misalignment.c
arch/powerpc/kernel/ptrace32.c
arch/s390/kernel/dis.c
arch/s390/kernel/ptrace.c
arch/s390/mm/fault.c
arch/sh/mm/tlb-sh3.c
arch/sparc/kernel/ptrace_32.c
arch/sparc/kernel/ptrace_64.c
arch/sparc/kernel/time_64.c
arch/sparc/kernel/traps_32.c
arch/sparc/kernel/vio.c
drivers/base/devres.c
drivers/base/firmware_class.c
drivers/block/DAC960.c
drivers/block/cciss.c
drivers/block/loop.c
drivers/bluetooth/hci_vhci.c
drivers/char/amiserial.c
drivers/char/cyclades.c
drivers/char/epca.c
drivers/char/isicom.c
drivers/char/istallion.c
drivers/char/moxa.c
drivers/char/mxser.c
drivers/char/n_hdlc.c
drivers/char/n_r3964.c
drivers/char/pty.c
drivers/char/rio/rio_linux.c
drivers/char/riscom8.c
drivers/char/rocket.c
drivers/char/serial167.c
drivers/char/specialix.c
drivers/char/sx.c
drivers/char/synclink.c
drivers/char/synclink_gt.c
drivers/char/synclinkmp.c
drivers/char/tpm/tpm.c
drivers/char/tty_ioctl.c
drivers/char/tty_ldisc.c
drivers/char/vt.c
drivers/char/vt_ioctl.c
drivers/gpio/vr41xx_giu.c
drivers/hid/usbhid/hid-core.c
drivers/hwmon/abituguru3.c
drivers/hwmon/max6650.c
drivers/hwmon/sht15.c
drivers/isdn/hisax/hfc_usb.c
drivers/isdn/i4l/isdn_tty.c
drivers/isdn/mISDN/stack.c
drivers/media/dvb/bt8xx/dst_ca.c
drivers/media/dvb/dvb-core/dvbdev.h
drivers/media/dvb/ttpci/av7110.c
drivers/media/radio/radio-mr800.c
drivers/media/radio/radio-si470x.c
drivers/media/video/bt8xx/bttv-driver.c
drivers/media/video/cx23885/cx23885-417.c
drivers/media/video/cx23885/cx23885-video.c
drivers/media/video/cx88/cx88-blackbird.c
drivers/media/video/cx88/cx88-video.c
drivers/media/video/dabusb.c
drivers/media/video/pwc/pwc-if.c
drivers/media/video/pwc/pwc.h
drivers/media/video/s2255drv.c
drivers/media/video/saa5246a.c
drivers/media/video/saa5249.c
drivers/media/video/saa7134/saa7134-empress.c
drivers/media/video/se401.c
drivers/media/video/stk-webcam.c
drivers/media/video/stradis.c
drivers/media/video/stv680.c
drivers/media/video/usbvideo/vicam.c
drivers/media/video/usbvision/usbvision-video.c
drivers/media/video/v4l2-dev.c
drivers/media/video/zoran/zoran_driver.c
drivers/misc/sgi-gru/grufile.c
drivers/misc/sgi-gru/grukservices.c
drivers/net/8139too.c
drivers/net/arm/ixp4xx_eth.c
drivers/net/atlx/atl2.c
drivers/net/cs89x0.c
drivers/net/ehea/ehea_main.c
drivers/net/fec.c
drivers/net/gianfar.c
drivers/net/igb/igb_main.c
drivers/net/irda/irtty-sir.c
drivers/net/isa-skeleton.c
drivers/net/phy/phy_device.c
drivers/net/plip.c
drivers/net/ps3_gelic_net.c
drivers/net/ps3_gelic_wireless.c
drivers/net/smc91x.c
drivers/net/smsc911x.c
drivers/net/sunvnet.c
drivers/net/usb/kaweth.c
drivers/net/usb/pegasus.c
drivers/net/via-rhine.c
drivers/net/wireless/orinoco/main.c
drivers/pci/hotplug/cpci_hotplug_core.c
drivers/pci/hotplug/cpqphp_ctrl.c
drivers/pci/hotplug/cpqphp_sysfs.c
drivers/pci/hotplug/pciehp_ctrl.c
drivers/pci/syscall.c
drivers/power/wm97xx_battery.c
drivers/s390/block/dasd_ioctl.c
drivers/scsi/qla2xxx/qla_mid.c
drivers/staging/comedi/drivers/jr3_pci.c
drivers/staging/comedi/drivers/s626.c
drivers/staging/go7007/s2250-loader.c
drivers/staging/meilhaus/TODO
drivers/staging/rspiusb/rspiusb.c
drivers/staging/rt2870/rt2870.h
drivers/staging/rtl8187se/ieee80211/ieee80211_softmac_wx.c
drivers/staging/rtl8192su/Kconfig
drivers/staging/rtl8192su/ieee80211/ieee80211_module.c
drivers/staging/rtl8192su/ieee80211/ieee80211_softmac_wx.c
drivers/staging/rtl8192su/r8192U_core.c
drivers/staging/rtl8192su/r8192U_pm.c
drivers/staging/serqt_usb2/serqt_usb2.c
drivers/staging/stlc45xx/stlc45xx.c
drivers/staging/usbip/usbip_common.c
drivers/staging/vt6655/device_main.c
drivers/telephony/ixj.c
drivers/telephony/phonedev.c
drivers/usb/class/cdc-acm.c
drivers/usb/class/cdc-wdm.c
drivers/usb/class/usbtmc.c
drivers/usb/core/Kconfig
drivers/usb/core/devices.c
drivers/usb/core/devio.c
drivers/usb/core/hcd.h
drivers/usb/core/hub.c
drivers/usb/core/hub.h
drivers/usb/core/message.c
drivers/usb/gadget/Kconfig
drivers/usb/gadget/amd5536udc.c
drivers/usb/gadget/audio.c
drivers/usb/gadget/ether.c
drivers/usb/gadget/langwell_udc.c
drivers/usb/gadget/pxa25x_udc.c
drivers/usb/gadget/rndis.c
drivers/usb/gadget/s3c2410_udc.c
drivers/usb/host/Kconfig
drivers/usb/host/ehci-au1xxx.c
drivers/usb/host/ehci-fsl.c
drivers/usb/host/ehci-hcd.c
drivers/usb/host/ehci-ixp4xx.c
drivers/usb/host/ehci-orion.c
drivers/usb/host/ehci-pci.c
drivers/usb/host/ehci-ppc-of.c
drivers/usb/host/ehci-ps3.c
drivers/usb/host/ehci-q.c
drivers/usb/host/ehci-sched.c
drivers/usb/host/ehci.h
drivers/usb/host/fhci-sched.c
drivers/usb/host/isp1760-if.c
drivers/usb/host/r8a66597-hcd.c
drivers/usb/misc/iowarrior.c
drivers/usb/misc/rio500.c
drivers/usb/misc/usblcd.c
drivers/usb/musb/cppi_dma.h
drivers/usb/musb/davinci.c
drivers/usb/musb/musb_core.h
drivers/usb/musb/musb_host.c
drivers/usb/otg/Kconfig
drivers/usb/otg/Makefile
drivers/usb/otg/langwell_otg.c [deleted file]
drivers/usb/otg/nop-usb-xceiv.c
drivers/usb/serial/console.c
drivers/usb/serial/cp210x.c
drivers/usb/serial/cypress_m8.c
drivers/usb/serial/ftdi_sio.c
drivers/usb/serial/ftdi_sio.h
drivers/usb/serial/mos7840.c
drivers/usb/serial/option.c
drivers/usb/serial/pl2303.c
drivers/usb/serial/pl2303.h
drivers/usb/serial/sierra.c
drivers/usb/serial/ti_usb_3410_5052.c
drivers/usb/serial/usb-serial.c
drivers/usb/storage/option_ms.c
drivers/video/fbmem.c
drivers/video/omap/omapfb_main.c
fs/adfs/super.c
fs/afs/dir.c
fs/afs/super.c
fs/autofs4/dev-ioctl.c
fs/bfs/dir.c
fs/bfs/file.c
fs/btrfs/compression.c
fs/btrfs/file.c
fs/btrfs/inode.c
fs/btrfs/ioctl.c
fs/btrfs/super.c
fs/char_dev.c
fs/compat.c
fs/compat_ioctl.c
fs/exofs/super.c
fs/ext2/ioctl.c
fs/ext4/ext4.h
fs/ext4/ext4_jbd2.c
fs/ext4/ext4_jbd2.h
fs/ext4/extents.c
fs/ext4/ialloc.c
fs/ext4/inode.c
fs/ext4/ioctl.c
fs/ext4/mballoc.c
fs/fat/dir.c
fs/fat/namei_msdos.c
fs/fat/namei_vfat.c
fs/fcntl.c
fs/freevxfs/vxfs_super.c
fs/fuse/dev.c
fs/gfs2/trace_gfs2.h
fs/hfs/super.c
fs/hfsplus/super.c
fs/hpfs/dir.c
fs/hpfs/file.c
fs/hpfs/hpfs_fn.h
fs/hpfs/inode.c
fs/hpfs/namei.c
fs/jbd2/journal.c
fs/jbd2/transaction.c
fs/jffs2/super.c
fs/lockd/clntproc.c
fs/lockd/svc4proc.c
fs/lockd/svcproc.c
fs/nfs/delegation.c
fs/nfs/dir.c
fs/nfs/file.c
fs/nfs/inode.c
fs/nfs/nfs4proc.c
fs/nfs/read.c
fs/nfs/write.c
fs/nfsd/nfsctl.c
fs/nfsd/nfssvc.c
fs/nilfs2/dir.c
fs/ocfs2/ioctl.c
fs/partitions/check.c
fs/reiserfs/xattr.c
fs/squashfs/super.c
fs/ubifs/ioctl.c
fs/xfs/linux-2.6/xfs_file.c
include/linux/backing-dev.h
include/linux/blkdev.h
include/linux/crash_dump.h
include/linux/device.h
include/linux/hardirq.h
include/linux/kmemleak.h
include/linux/personality.h
include/linux/quotaops.h
include/linux/skbuff.h
include/linux/slub_def.h
include/linux/sunrpc/xdr.h
include/linux/usb.h
include/linux/usb/langwell_otg.h [deleted file]
include/trace/events/block.h
include/trace/events/ext4.h
include/trace/events/irq.h
include/trace/events/jbd2.h
include/trace/events/kmem.h
include/trace/events/lockdep.h
include/trace/events/sched.h
include/trace/events/skb.h
include/trace/events/workqueue.h
kernel/futex.c
kernel/pid.c
kernel/power/user.c
kernel/trace/blktrace.c
kernel/trace/ftrace.c
kernel/trace/trace.c
mm/bootmem.c
mm/kmemleak.c
mm/page_alloc.c
mm/slub.c
net/appletalk/ddp.c
net/core/sock.c
net/ipv4/ip_gre.c
net/ipv4/ip_output.c
net/ipv6/ip6_output.c
net/ipv6/sit.c
net/ipx/af_ipx.c
net/irda/af_irda.c
net/irda/irnet/irnet.h
net/irda/irnet/irnet_ppp.c
net/sunrpc/clnt.c
net/sunrpc/sched.c
net/sunrpc/svc_xprt.c
net/wanrouter/wanmain.c
net/x25/af_x25.c
samples/trace_events/trace-events-sample.h
sound/soc/codecs/wm8988.c

index 8213216..60120fb 100644 (file)
@@ -207,8 +207,8 @@ Attributes
 ~~~~~~~~~~
 struct driver_attribute {
         struct attribute        attr;
-        ssize_t (*show)(struct device_driver *, char * buf, size_t count, loff_t off);
-        ssize_t (*store)(struct device_driver *, const char * buf, size_t count, loff_t off);
+        ssize_t (*show)(struct device_driver *driver, char *buf);
+        ssize_t (*store)(struct device_driver *, const char * buf, size_t count);
 };
 
 Device drivers can export attributes via their sysfs directories. 
index 9d1601e..18c3f0c 100644 (file)
@@ -3287,11 +3287,11 @@ F:      include/linux/ivtv*
 
 JFS FILESYSTEM
 P:     Dave Kleikamp
-M:     shaggy@austin.ibm.com
+M:     shaggy@linux.vnet.ibm.com
 L:     jfs-discussion@lists.sourceforge.net
 W:     http://jfs.sourceforge.net/
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/shaggy/jfs-2.6.git
-S:     Supported
+S:     Maintained
 F:     Documentation/filesystems/jfs.txt
 F:     fs/jfs/
 
index 0aeec59..be0abac 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 6
 SUBLEVEL = 31
-EXTRAVERSION = -rc2
+EXTRAVERSION = -rc3
 NAME = Man-Eating Seals of Antiquity
 
 # *DOCUMENTATION*
@@ -565,7 +565,7 @@ KBUILD_CFLAGS += $(call cc-option,-Wdeclaration-after-statement,)
 KBUILD_CFLAGS += $(call cc-option,-Wno-pointer-sign,)
 
 # disable invalid "can't wrap" optimizations for signed / pointers
-KBUILD_CFLAGS  += $(call cc-option,-fwrapv)
+KBUILD_CFLAGS  += $(call cc-option,-fno-strict-overflow)
 
 # revert to pre-gcc-4.4 behaviour of .eh_frame
 KBUILD_CFLAGS  += $(call cc-option,-fno-dwarf2-cfi-asm)
index 1e9ad52..e072041 100644 (file)
@@ -8,7 +8,6 @@
 #include <linux/sched.h>
 #include <linux/mm.h>
 #include <linux/smp.h>
-#include <linux/smp_lock.h>
 #include <linux/errno.h>
 #include <linux/ptrace.h>
 #include <linux/user.h>
index d76618d..6a387ee 100644 (file)
@@ -31,7 +31,6 @@
 #include <linux/sched.h>
 #include <linux/mm.h>
 #include <linux/smp.h>
-#include <linux/smp_lock.h>
 #include <linux/errno.h>
 #include <linux/ptrace.h>
 #include <linux/user.h>
index a8f1329..3da60fb 100644 (file)
@@ -29,7 +29,6 @@
  * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
-#include <linux/smp_lock.h>
 #include <linux/spinlock.h>
 #include <linux/sem.h>
 #include <linux/msg.h>
index a79fbd8..2ad962c 100644 (file)
@@ -15,7 +15,6 @@
 #include <linux/mm.h>
 #include <linux/fs.h>
 #include <linux/smp.h>
-#include <linux/smp_lock.h>
 #include <linux/sem.h>
 #include <linux/msg.h>
 #include <linux/shm.h>
index 92c9689..9daa87f 100644 (file)
@@ -15,7 +15,6 @@
 #include <linux/mm.h>
 #include <linux/errno.h>
 #include <linux/ptrace.h>
-#include <linux/smp_lock.h>
 #include <linux/user.h>
 #include <linux/security.h>
 #include <linux/audit.h>
index bf0abe9..98b8feb 100644 (file)
@@ -19,7 +19,6 @@
 #include <linux/mm.h>
 #include <linux/err.h>
 #include <linux/smp.h>
-#include <linux/smp_lock.h>
 #include <linux/errno.h>
 #include <linux/ptrace.h>
 #include <linux/user.h>
index b86aa62..53ff39a 100644 (file)
@@ -27,7 +27,6 @@
 #include <linux/kernel.h>
 #include <linux/mm.h>
 #include <linux/sched.h>
-#include <linux/smp_lock.h>
 #include <linux/ptrace.h>
 #include <linux/signal.h>
 
index 493819c..1c80e4f 100644 (file)
@@ -21,7 +21,6 @@
 #include <linux/sched.h>
 #include <linux/mm.h>
 #include <linux/smp.h>
-#include <linux/smp_lock.h>
 #include <linux/kernel.h>
 #include <linux/signal.h>
 #include <linux/errno.h>
index 8c9ebac..e000bce 100644 (file)
@@ -15,7 +15,6 @@
 #include <linux/errno.h>
 #include <linux/mm.h>
 #include <linux/smp.h>
-#include <linux/smp_lock.h>
 #include <linux/syscalls.h>
 #include <linux/sem.h>
 #include <linux/msg.h>
index c4f9ac1..32644b4 100644 (file)
@@ -22,7 +22,6 @@
 #include <linux/errno.h>
 #include <linux/ptrace.h>
 #include <linux/smp.h>
-#include <linux/smp_lock.h>
 #include <linux/user.h>
 #include <linux/security.h>
 
index 471c09a..8c2834f 100644 (file)
@@ -16,7 +16,6 @@
 #include <linux/mm.h>
 #include <linux/hugetlb.h>
 #include <linux/pagemap.h>
-#include <linux/smp_lock.h>
 #include <linux/slab.h>
 #include <linux/err.h>
 #include <linux/sysctl.h>
index e143339..cf847da 100644 (file)
@@ -13,7 +13,6 @@
 #include <linux/sched.h>
 #include <linux/mm.h>
 #include <linux/smp.h>
-#include <linux/smp_lock.h>
 #include <linux/errno.h>
 #include <linux/ptrace.h>
 #include <linux/user.h>
index 9f7572a..feb2f2e 100644 (file)
@@ -12,7 +12,6 @@
 #include <linux/sched.h>
 #include <linux/mm.h>
 #include <linux/smp.h>
-#include <linux/smp_lock.h>
 #include <linux/kernel.h>
 #include <linux/signal.h>
 #include <linux/errno.h>
index bca5a84..3e52a10 100644 (file)
@@ -13,7 +13,6 @@
 #include <linux/syscalls.h>
 #include <linux/mm.h>
 #include <linux/smp.h>
-#include <linux/smp_lock.h>
 #include <linux/sem.h>
 #include <linux/msg.h>
 #include <linux/shm.h>
@@ -21,7 +20,6 @@
 #include <linux/mman.h>
 #include <linux/file.h>
 #include <linux/utsname.h>
-#include <linux/syscalls.h>
 #include <linux/tty.h>
 
 #include <asm/uaccess.h>
index 0dfdc50..91365ad 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/timer.h>
 #include <linux/mm.h>
 #include <linux/smp.h>
-#include <linux/smp_lock.h>
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/spinlock.h>
index a62e1e1..53bb17d 100644 (file)
@@ -20,7 +20,6 @@
 #include <linux/mman.h>
 #include <linux/mm.h>
 #include <linux/smp.h>
-#include <linux/smp_lock.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
 #include <linux/vt_kern.h>             /* For unblank_screen() */
index 94c4a43..3001625 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/timer.h>
 #include <linux/mm.h>
 #include <linux/smp.h>
-#include <linux/smp_lock.h>
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/spinlock.h>
index 297632c..8a6daf4 100644 (file)
@@ -21,7 +21,6 @@
 #include <linux/sched.h>
 #include <linux/mm.h>
 #include <linux/smp.h>
-#include <linux/smp_lock.h>
 #include <linux/errno.h>
 #include <linux/ptrace.h>
 #include <linux/regset.h>
index d2f270c..db943a7 100644 (file)
@@ -15,7 +15,6 @@
 #include <linux/timer.h>
 #include <linux/mm.h>
 #include <linux/smp.h>
-#include <linux/smp_lock.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/delay.h>
index 490b399..43acd73 100644 (file)
@@ -26,7 +26,6 @@
 #include <linux/sched.h>
 #include <linux/mm.h>
 #include <linux/smp.h>
-#include <linux/smp_lock.h>
 #include <linux/errno.h>
 #include <linux/ptrace.h>
 #include <linux/user.h>
index 74eb26b..e5e119f 100644 (file)
@@ -22,7 +22,6 @@
 #include <linux/compat.h>
 #include <linux/smp.h>
 #include <linux/kdebug.h>
-#include <linux/smp_lock.h>
 #include <linux/init.h>
 #include <linux/console.h>
 #include <linux/module.h>
index 7fbfd5a..17cb7c3 100644 (file)
@@ -18,7 +18,6 @@
 #include <linux/mman.h>
 #include <linux/mm.h>
 #include <linux/smp.h>
-#include <linux/smp_lock.h>
 #include <linux/interrupt.h>
 
 #include <asm/system.h>
index 8ce6285..7e3dfd9 100644 (file)
@@ -16,7 +16,6 @@
 #include <linux/ptrace.h>
 #include <linux/user.h>
 #include <linux/smp.h>
-#include <linux/smp_lock.h>
 #include <linux/security.h>
 #include <linux/signal.h>
 #include <linux/regset.h>
index a941c61..4ae91dc 100644 (file)
@@ -17,7 +17,6 @@
 #include <linux/ptrace.h>
 #include <linux/user.h>
 #include <linux/smp.h>
-#include <linux/smp_lock.h>
 #include <linux/security.h>
 #include <linux/seccomp.h>
 #include <linux/audit.h>
index 5c12e79..da1218e 100644 (file)
@@ -11,7 +11,6 @@
 #include <linux/errno.h>
 #include <linux/module.h>
 #include <linux/sched.h>
-#include <linux/smp_lock.h>
 #include <linux/kernel.h>
 #include <linux/param.h>
 #include <linux/string.h>
index 3582833..c0490c7 100644 (file)
@@ -13,7 +13,6 @@
 #include <linux/kernel.h>
 #include <linux/signal.h>
 #include <linux/smp.h>
-#include <linux/smp_lock.h>
 #include <linux/kdebug.h>
 
 #include <asm/delay.h>
index 753d128..c28c714 100644 (file)
@@ -224,7 +224,12 @@ static struct vio_dev *vio_create_one(struct mdesc_handle *hp, u64 mp,
        if (!strcmp(type, "domain-services-port"))
                bus_id_name = "ds";
 
-       if (strlen(bus_id_name) >= BUS_ID_SIZE - 4) {
+       /*
+        * 20 char is the old driver-core name size limit, which is no more.
+        * This check can probably be removed after review and possible
+        * adaption of the vio users name length handling.
+        */
+       if (strlen(bus_id_name) >= 20 - 4) {
                printk(KERN_ERR "VIO: bus_id_name [%s] is too long.\n",
                       bus_id_name);
                return NULL;
index e8beb8e..05dd307 100644 (file)
@@ -428,6 +428,9 @@ int devres_release_all(struct device *dev)
 {
        unsigned long flags;
 
+       /* Looks like an uninitialized device structure */
+       if (WARN_ON(dev->devres_head.next == NULL))
+               return -ENODEV;
        spin_lock_irqsave(&dev->devres_lock, flags);
        return release_nodes(dev, dev->devres_head.next, &dev->devres_head,
                             flags);
index fc46653..f285f44 100644 (file)
@@ -217,8 +217,10 @@ firmware_data_read(struct kobject *kobj, struct bin_attribute *bin_attr,
                ret_count = -ENODEV;
                goto out;
        }
-       if (offset > fw->size)
-               return 0;
+       if (offset > fw->size) {
+               ret_count = 0;
+               goto out;
+       }
        if (count > fw->size - offset)
                count = fw->size - offset;
 
index 668dc23..1e6b7c1 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/ioport.h>
 #include <linux/mm.h>
 #include <linux/slab.h>
+#include <linux/smp_lock.h>
 #include <linux/proc_fs.h>
 #include <linux/reboot.h>
 #include <linux/spinlock.h>
index 65a0655..a52cc7f 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/pci.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
+#include <linux/smp_lock.h>
 #include <linux/delay.h>
 #include <linux/major.h>
 #include <linux/fs.h>
index 801f4ab..5757188 100644 (file)
@@ -61,7 +61,6 @@
 #include <linux/blkdev.h>
 #include <linux/blkpg.h>
 #include <linux/init.h>
-#include <linux/smp_lock.h>
 #include <linux/swap.h>
 #include <linux/slab.h>
 #include <linux/loop.h>
index 1df9dda..d5cde6d 100644 (file)
@@ -28,7 +28,6 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/slab.h>
-#include <linux/smp_lock.h>
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <linux/sched.h>
index 72429b6..6c32fbf 100644 (file)
@@ -81,6 +81,7 @@ static char *serial_version = "4.30";
 #include <linux/mm.h>
 #include <linux/seq_file.h>
 #include <linux/slab.h>
+#include <linux/smp_lock.h>
 #include <linux/init.h>
 #include <linux/bitops.h>
 
index f3366d3..2dafc2d 100644 (file)
 #include <linux/tty.h>
 #include <linux/tty_flip.h>
 #include <linux/serial.h>
+#include <linux/smp_lock.h>
 #include <linux/major.h>
 #include <linux/string.h>
 #include <linux/fcntl.h>
index abef1f7..ff647ca 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/tty.h>
 #include <linux/tty_flip.h>
 #include <linux/slab.h>
+#include <linux/smp_lock.h>
 #include <linux/ioport.h>
 #include <linux/interrupt.h>
 #include <linux/uaccess.h>
index 621d118..4f1f4cd 100644 (file)
 #include <linux/fs.h>
 #include <linux/sched.h>
 #include <linux/serial.h>
+#include <linux/smp_lock.h>
 #include <linux/mm.h>
 #include <linux/interrupt.h>
 #include <linux/timer.h>
index 0c999f5..ab2f334 100644 (file)
@@ -20,6 +20,7 @@
 
 #include <linux/module.h>
 #include <linux/slab.h>
+#include <linux/smp_lock.h>
 #include <linux/interrupt.h>
 #include <linux/tty.h>
 #include <linux/tty_flip.h>
index 65b6ff2..dd0083b 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/tty.h>
 #include <linux/tty_flip.h>
 #include <linux/major.h>
+#include <linux/smp_lock.h>
 #include <linux/string.h>
 #include <linux/fcntl.h>
 #include <linux/ptrace.h>
index 52d953e..dbf8d52 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/errno.h>
 #include <linux/signal.h>
 #include <linux/sched.h>
+#include <linux/smp_lock.h>
 #include <linux/timer.h>
 #include <linux/interrupt.h>
 #include <linux/tty.h>
index 1c43c8c..c68118e 100644 (file)
@@ -97,6 +97,7 @@
 #include <linux/slab.h>
 #include <linux/tty.h>
 #include <linux/errno.h>
+#include <linux/smp_lock.h>
 #include <linux/string.h>      /* used in new tty drivers */
 #include <linux/signal.h>      /* used in new tty drivers */
 #include <linux/if.h>
index 2e99158..6934025 100644 (file)
@@ -58,6 +58,7 @@
 #include <linux/ioport.h>
 #include <linux/in.h>
 #include <linux/slab.h>
+#include <linux/smp_lock.h>
 #include <linux/tty.h>
 #include <linux/errno.h>
 #include <linux/string.h>      /* used in new tty drivers */
index 9d1b4f5..6e6942c 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/major.h>
 #include <linux/mm.h>
 #include <linux/init.h>
+#include <linux/smp_lock.h>
 #include <linux/sysctl.h>
 #include <linux/device.h>
 #include <linux/uaccess.h>
index ce81da5..d58c2eb 100644 (file)
@@ -44,6 +44,7 @@
 #include <linux/delay.h>
 #include <linux/pci.h>
 #include <linux/slab.h>
+#include <linux/smp_lock.h>
 #include <linux/miscdevice.h>
 #include <linux/init.h>
 
index 2176604..171711a 100644 (file)
@@ -47,6 +47,7 @@
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/tty_flip.h>
+#include <linux/smp_lock.h>
 #include <linux/spinlock.h>
 #include <linux/device.h>
 
index 63d5b62..0e29a23 100644 (file)
@@ -73,6 +73,7 @@
 #include <linux/tty_driver.h>
 #include <linux/tty_flip.h>
 #include <linux/serial.h>
+#include <linux/smp_lock.h>
 #include <linux/string.h>
 #include <linux/fcntl.h>
 #include <linux/ptrace.h>
index f1f24f0..51e7a46 100644 (file)
@@ -52,6 +52,7 @@
 #include <linux/interrupt.h>
 #include <linux/serial.h>
 #include <linux/serialP.h>
+#include <linux/smp_lock.h>
 #include <linux/string.h>
 #include <linux/fcntl.h>
 #include <linux/ptrace.h>
index e72be41..bfe4cdb 100644 (file)
@@ -87,6 +87,7 @@
 #include <linux/tty_flip.h>
 #include <linux/mm.h>
 #include <linux/serial.h>
+#include <linux/smp_lock.h>
 #include <linux/fcntl.h>
 #include <linux/major.h>
 #include <linux/delay.h>
index 518f2a2..a81ec4f 100644 (file)
 #include <linux/eisa.h>
 #include <linux/pci.h>
 #include <linux/slab.h>
+#include <linux/smp_lock.h>
 #include <linux/init.h>
 #include <linux/miscdevice.h>
 #include <linux/bitops.h>
index afded3a..813552f 100644 (file)
@@ -81,6 +81,7 @@
 #include <linux/mm.h>
 #include <linux/seq_file.h>
 #include <linux/slab.h>
+#include <linux/smp_lock.h>
 #include <linux/delay.h>
 #include <linux/netdevice.h>
 #include <linux/vmalloc.h>
index a2e67e6..91f20a9 100644 (file)
@@ -62,6 +62,7 @@
 #include <linux/mm.h>
 #include <linux/seq_file.h>
 #include <linux/slab.h>
+#include <linux/smp_lock.h>
 #include <linux/netdevice.h>
 #include <linux/vmalloc.h>
 #include <linux/init.h>
index 6f727e3..8d4a2a8 100644 (file)
@@ -52,6 +52,7 @@
 #include <linux/mm.h>
 #include <linux/seq_file.h>
 #include <linux/slab.h>
+#include <linux/smp_lock.h>
 #include <linux/netdevice.h>
 #include <linux/vmalloc.h>
 #include <linux/init.h>
index ccdd828..b0603b2 100644 (file)
@@ -26,7 +26,6 @@
 #include <linux/poll.h>
 #include <linux/mutex.h>
 #include <linux/spinlock.h>
-#include <linux/smp_lock.h>
 
 #include "tpm.h"
 
index b24f6c6..ad6ba4e 100644 (file)
@@ -21,7 +21,6 @@
 #include <linux/module.h>
 #include <linux/bitops.h>
 #include <linux/mutex.h>
-#include <linux/smp_lock.h>
 
 #include <asm/io.h>
 #include <asm/uaccess.h>
index 913aa8d..0ef0dc9 100644 (file)
@@ -21,7 +21,6 @@
 #include <linux/proc_fs.h>
 #include <linux/init.h>
 #include <linux/module.h>
-#include <linux/smp_lock.h>
 #include <linux/device.h>
 #include <linux/wait.h>
 #include <linux/bitops.h>
index d9113b4..7947bd1 100644 (file)
@@ -89,6 +89,7 @@
 #include <linux/mutex.h>
 #include <linux/vt_kern.h>
 #include <linux/selection.h>
+#include <linux/smp_lock.h>
 #include <linux/tiocl.h>
 #include <linux/kbd_kern.h>
 #include <linux/consolemap.h>
index 7539bed..95189f2 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/console.h>
 #include <linux/consolemap.h>
 #include <linux/signal.h>
+#include <linux/smp_lock.h>
 #include <linux/timex.h>
 
 #include <asm/io.h>
index b70e061..b16c9a8 100644 (file)
@@ -29,7 +29,6 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
-#include <linux/smp_lock.h>
 #include <linux/spinlock.h>
 #include <linux/types.h>
 
index 76c4bbe..3c1fcb7 100644 (file)
@@ -22,7 +22,6 @@
 #include <linux/list.h>
 #include <linux/mm.h>
 #include <linux/mutex.h>
-#include <linux/smp_lock.h>
 #include <linux/spinlock.h>
 #include <asm/unaligned.h>
 #include <asm/byteorder.h>
index ad2b343..7d3f15d 100644 (file)
@@ -357,7 +357,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = {
                { "AUX5 Fan",           39, 2, 60, 1, 0 },
                { NULL, 0, 0, 0, 0, 0 } }
        },
-       { 0x0014, NULL /* Abit AB9 Pro, need DMI string */, {
+       { 0x0014, "AB9", /* + AB9 Pro */ {
                { "CPU Core",            0, 0, 10, 1, 0 },
                { "DDR",                 1, 0, 10, 1, 0 },
                { "DDR VTT",             2, 0, 10, 1, 0 },
@@ -455,7 +455,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = {
                { "AUX3 FAN",           37, 2, 60, 1, 0 },
                { NULL, 0, 0, 0, 0, 0 } }
        },
-       { 0x0018, NULL /* Unknown, need DMI string */, {
+       { 0x0018, "AB9 QuadGT", {
                { "CPU Core",            0, 0, 10, 1, 0 },
                { "DDR2",                1, 0, 20, 1, 0 },
                { "DDR2 VTT",            2, 0, 10, 1, 0 },
@@ -564,7 +564,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = {
                { "AUX3 Fan",           36, 2, 60, 1, 0 },
                { NULL, 0, 0, 0, 0, 0 } }
        },
-       { 0x001C, NULL /* Unknown, need DMI string */, {
+       { 0x001C, "IX38 QuadGT", {
                { "CPU Core",            0, 0, 10, 1, 0 },
                { "DDR2",                1, 0, 20, 1, 0 },
                { "DDR2 VTT",            2, 0, 10, 1, 0 },
index 86142a8..58f66be 100644 (file)
@@ -418,6 +418,7 @@ static ssize_t set_div(struct device *dev, struct device_attribute *devattr,
                data->count = 3;
                break;
        default:
+               mutex_unlock(&data->update_lock);
                dev_err(&client->dev,
                        "illegal value for fan divider (%d)\n", div);
                return -EINVAL;
index 56cd600..6290a25 100644 (file)
@@ -257,7 +257,7 @@ static inline int sht15_update_single_val(struct sht15_data *data,
                                 (data->flag == SHT15_READING_NOTHING),
                                 msecs_to_jiffies(timeout_msecs));
        if (ret == 0) {/* timeout occurred */
-               disable_irq_nosync(gpio_to_irq(data->pdata->gpio_data));;
+               disable_irq_nosync(gpio_to_irq(data->pdata->gpio_data));
                sht15_connection_reset(data);
                return -ETIME;
        }
index 8df889b..9de5420 100644 (file)
@@ -37,7 +37,6 @@
 #include <linux/kernel_stat.h>
 #include <linux/usb.h>
 #include <linux/kernel.h>
-#include <linux/smp_lock.h>
 #include <linux/sched.h>
 #include <linux/moduleparam.h>
 #include "hisax.h"
index b4d4522..2881a66 100644 (file)
@@ -13,6 +13,7 @@
 
 #include <linux/isdn.h>
 #include <linux/delay.h>
+#include <linux/smp_lock.h>
 #include "isdn_common.h"
 #include "isdn_tty.h"
 #ifdef CONFIG_ISDN_AUDIO
index e2f4501..3e1532a 100644 (file)
@@ -17,6 +17,7 @@
 
 #include <linux/mISDNif.h>
 #include <linux/kthread.h>
+#include <linux/smp_lock.h>
 #include "core.h"
 
 static u_int   *debug;
index 4601b05..0e246ea 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/smp_lock.h>
 #include <linux/string.h>
 #include <linux/dvb/ca.h>
 #include "dvbdev.h"
index 7992730..487919b 100644 (file)
@@ -27,7 +27,6 @@
 #include <linux/poll.h>
 #include <linux/fs.h>
 #include <linux/list.h>
-#include <linux/smp_lock.h>
 
 #define DVB_MAJOR 212
 
index d1d959e..8d65c65 100644 (file)
@@ -36,7 +36,6 @@
 #include <linux/fs.h>
 #include <linux/timer.h>
 #include <linux/poll.h>
-#include <linux/smp_lock.h>
 
 #include <linux/kernel.h>
 #include <linux/sched.h>
index 837467f..575bf9d 100644 (file)
@@ -58,6 +58,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/slab.h>
+#include <linux/smp_lock.h>
 #include <linux/input.h>
 #include <linux/videodev2.h>
 #include <media/v4l2-device.h>
index 46d2163..e85f318 100644 (file)
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/slab.h>
+#include <linux/smp_lock.h>
 #include <linux/input.h>
 #include <linux/usb.h>
 #include <linux/hid.h>
index 5eb1464..d147d29 100644 (file)
@@ -41,6 +41,7 @@
 #include <linux/fs.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
+#include <linux/smp_lock.h>
 #include <linux/interrupt.h>
 #include <linux/kdev_t.h>
 #include "bttvp.h"
index 2943bfd..428f0c4 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/delay.h>
 #include <linux/device.h>
 #include <linux/firmware.h>
+#include <linux/smp_lock.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-ioctl.h>
 #include <media/cx2341x.h>
index 70836af..5d60933 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/kmod.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
+#include <linux/smp_lock.h>
 #include <linux/interrupt.h>
 #include <linux/delay.h>
 #include <linux/kthread.h>
index 44eacfb..356d689 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/delay.h>
 #include <linux/device.h>
 #include <linux/firmware.h>
+#include <linux/smp_lock.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-ioctl.h>
 #include <media/cx2341x.h>
index b127708..2bb54c3 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/kmod.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
+#include <linux/smp_lock.h>
 #include <linux/interrupt.h>
 #include <linux/dma-mapping.h>
 #include <linux/delay.h>
index ec2f45d..0664d11 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/list.h>
 #include <linux/vmalloc.h>
 #include <linux/slab.h>
+#include <linux/smp_lock.h>
 #include <linux/init.h>
 #include <asm/uaccess.h>
 #include <asm/atomic.h>
index db25c30..8d17cf6 100644 (file)
@@ -62,6 +62,7 @@
 #include <linux/module.h>
 #include <linux/poll.h>
 #include <linux/slab.h>
+#include <linux/smp_lock.h>
 #ifdef CONFIG_USB_PWC_INPUT_EVDEV
 #include <linux/usb/input.h>
 #endif
index 0be6f81..0b658de 100644 (file)
@@ -29,7 +29,6 @@
 #include <linux/usb.h>
 #include <linux/spinlock.h>
 #include <linux/wait.h>
-#include <linux/smp_lock.h>
 #include <linux/version.h>
 #include <linux/mutex.h>
 #include <linux/mm.h>
index 6be845c..9e3262c 100644 (file)
@@ -48,6 +48,7 @@
 #include <linux/videodev2.h>
 #include <linux/version.h>
 #include <linux/mm.h>
+#include <linux/smp_lock.h>
 #include <media/videobuf-vmalloc.h>
 #include <media/v4l2-common.h>
 #include <media/v4l2-ioctl.h>
index 155804b..b624a4c 100644 (file)
@@ -43,7 +43,6 @@
 #include <linux/mm.h>
 #include <linux/init.h>
 #include <linux/i2c.h>
-#include <linux/smp_lock.h>
 #include <linux/mutex.h>
 #include <linux/videotext.h>
 #include <linux/videodev2.h>
index 271d6e9..12835fb 100644 (file)
@@ -46,7 +46,6 @@
 #include <linux/mm.h>
 #include <linux/init.h>
 #include <linux/i2c.h>
-#include <linux/smp_lock.h>
 #include <linux/mutex.h>
 #include <linux/delay.h>
 #include <linux/videotext.h>
index add1757..296788c 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
+#include <linux/smp_lock.h>
 #include <linux/delay.h>
 
 #include "saa7134-reg.h"
index c8f0529..85ffc2c 100644 (file)
@@ -31,6 +31,7 @@ static const char version[] = "0.24";
 #include <linux/init.h>
 #include <linux/vmalloc.h>
 #include <linux/slab.h>
+#include <linux/smp_lock.h>
 #include <linux/pagemap.h>
 #include <linux/usb.h>
 #include "se401.h"
index 2e59370..4d6785e 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/slab.h>
+#include <linux/smp_lock.h>
 
 #include <linux/usb.h>
 #include <linux/mm.h>
index 0eb3130..eaada39 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/kernel.h>
 #include <linux/major.h>
 #include <linux/slab.h>
+#include <linux/smp_lock.h>
 #include <linux/mm.h>
 #include <linux/init.h>
 #include <linux/poll.h>
index 75f286f..8b4e7da 100644 (file)
@@ -62,6 +62,7 @@
 #include <linux/init.h>
 #include <linux/vmalloc.h>
 #include <linux/slab.h>
+#include <linux/smp_lock.h>
 #include <linux/pagemap.h>
 #include <linux/errno.h>
 #include <linux/videodev.h>
index 8d73979..45fce39 100644 (file)
@@ -43,6 +43,7 @@
 #include <linux/vmalloc.h>
 #include <linux/mm.h>
 #include <linux/slab.h>
+#include <linux/smp_lock.h>
 #include <linux/mutex.h>
 #include <linux/firmware.h>
 #include <linux/ihex.h>
index 90b5891..90d9b5c 100644 (file)
@@ -50,6 +50,7 @@
 #include <linux/list.h>
 #include <linux/timer.h>
 #include <linux/slab.h>
+#include <linux/smp_lock.h>
 #include <linux/mm.h>
 #include <linux/utsname.h>
 #include <linux/highmem.h>
index 31eac66..a7f1b69 100644 (file)
@@ -25,7 +25,6 @@
 #include <linux/init.h>
 #include <linux/kmod.h>
 #include <linux/slab.h>
-#include <linux/smp_lock.h>
 #include <asm/uaccess.h>
 #include <asm/system.h>
 
index 3d7df32..bcdefb1 100644 (file)
@@ -49,6 +49,7 @@
 #include <linux/module.h>
 #include <linux/delay.h>
 #include <linux/slab.h>
+#include <linux/smp_lock.h>
 #include <linux/pci.h>
 #include <linux/vmalloc.h>
 #include <linux/wait.h>
index fa2d93a..aed6098 100644 (file)
@@ -29,7 +29,6 @@
 #include <linux/slab.h>
 #include <linux/mm.h>
 #include <linux/io.h>
-#include <linux/smp_lock.h>
 #include <linux/spinlock.h>
 #include <linux/device.h>
 #include <linux/miscdevice.h>
index eedbf9c..79689b1 100644 (file)
@@ -24,7 +24,6 @@
 #include <linux/errno.h>
 #include <linux/slab.h>
 #include <linux/mm.h>
-#include <linux/smp_lock.h>
 #include <linux/spinlock.h>
 #include <linux/device.h>
 #include <linux/miscdevice.h>
index 8ae72ec..0e2ba21 100644 (file)
@@ -908,6 +908,7 @@ static const struct net_device_ops rtl8139_netdev_ops = {
        .ndo_open               = rtl8139_open,
        .ndo_stop               = rtl8139_close,
        .ndo_get_stats          = rtl8139_get_stats,
+       .ndo_change_mtu         = eth_change_mtu,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_set_mac_address    = rtl8139_set_mac_address,
        .ndo_start_xmit         = rtl8139_start_xmit,
index 6f42ad7..3fe0987 100644 (file)
@@ -1142,7 +1142,9 @@ static const struct net_device_ops ixp4xx_netdev_ops = {
        .ndo_start_xmit = eth_xmit,
        .ndo_set_multicast_list = eth_set_mcast_list,
        .ndo_do_ioctl = eth_ioctl,
-
+       .ndo_change_mtu = eth_change_mtu,
+       .ndo_set_mac_address = eth_mac_addr,
+       .ndo_validate_addr = eth_validate_addr,
 };
 
 static int __devinit eth_init_one(struct platform_device *pdev)
index c734b19..204db96 100644 (file)
@@ -2071,7 +2071,7 @@ static int atl2_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
        if (wol->wolopts & (WAKE_ARP | WAKE_MAGICSECURE))
                return -EOPNOTSUPP;
 
-       if (wol->wolopts & (WAKE_MCAST|WAKE_BCAST|WAKE_MCAST))
+       if (wol->wolopts & (WAKE_UCAST | WAKE_BCAST | WAKE_MCAST))
                return -EOPNOTSUPP;
 
        /* these settings will always override what we currently have */
index 3eee666..55445f9 100644 (file)
@@ -1524,6 +1524,7 @@ static void net_timeout(struct net_device *dev)
 static int net_send_packet(struct sk_buff *skb, struct net_device *dev)
 {
        struct net_local *lp = netdev_priv(dev);
+       unsigned long flags;
 
        if (net_debug > 3) {
                printk("%s: sent %d byte packet of type %x\n",
@@ -1535,7 +1536,7 @@ static int net_send_packet(struct sk_buff *skb, struct net_device *dev)
                   ask the chip to start transmitting before the
                   whole packet has been completely uploaded. */
 
-       spin_lock_irq(&lp->lock);
+       spin_lock_irqsave(&lp->lock, flags);
        netif_stop_queue(dev);
 
        /* initiate a transmit sequence */
@@ -1549,13 +1550,13 @@ static int net_send_packet(struct sk_buff *skb, struct net_device *dev)
                 * we're waiting for TxOk, so return 1 and requeue this packet.
                 */
 
-               spin_unlock_irq(&lp->lock);
+               spin_unlock_irqrestore(&lp->lock, flags);
                if (net_debug) printk("cs89x0: Tx buffer not free!\n");
                return NETDEV_TX_BUSY;
        }
        /* Write the contents of the packet */
        writewords(dev->base_addr, TX_FRAME_PORT,skb->data,(skb->len+1) >>1);
-       spin_unlock_irq(&lp->lock);
+       spin_unlock_irqrestore(&lp->lock, flags);
        lp->stats.tx_bytes += skb->len;
        dev->trans_start = jiffies;
        dev_kfree_skb (skb);
index 147c4b0..e8d46cc 100644 (file)
@@ -3080,7 +3080,9 @@ static const struct net_device_ops ehea_netdev_ops = {
        .ndo_poll_controller    = ehea_netpoll,
 #endif
        .ndo_get_stats          = ehea_get_stats,
+       .ndo_change_mtu         = eth_change_mtu,
        .ndo_set_mac_address    = ehea_set_mac_addr,
+       .ndo_validate_addr      = eth_validate_addr,
        .ndo_set_multicast_list = ehea_set_multicast_list,
        .ndo_change_mtu         = ehea_change_mtu,
        .ndo_vlan_rx_register   = ehea_vlan_rx_register,
index 0f19b74..d4b9807 100644 (file)
@@ -1642,6 +1642,7 @@ static const struct net_device_ops fec_netdev_ops = {
        .ndo_stop               = fec_enet_close,
        .ndo_start_xmit         = fec_enet_start_xmit,
        .ndo_set_multicast_list = set_multicast_list,
+       .ndo_change_mtu         = eth_change_mtu,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_tx_timeout         = fec_timeout,
        .ndo_set_mac_address    = fec_set_mac_address,
index 4ae1d25..43d813e 100644 (file)
@@ -156,6 +156,8 @@ static const struct net_device_ops gfar_netdev_ops = {
        .ndo_tx_timeout = gfar_timeout,
        .ndo_do_ioctl = gfar_ioctl,
        .ndo_vlan_rx_register = gfar_vlan_rx_register,
+       .ndo_set_mac_address = eth_mac_addr,
+       .ndo_validate_addr = eth_validate_addr,
 #ifdef CONFIG_NET_POLL_CONTROLLER
        .ndo_poll_controller = gfar_netpoll,
 #endif
index be48029..adb09d3 100644 (file)
@@ -127,14 +127,48 @@ static void igb_restore_vlan(struct igb_adapter *);
 static void igb_ping_all_vfs(struct igb_adapter *);
 static void igb_msg_task(struct igb_adapter *);
 static int igb_rcv_msg_from_vf(struct igb_adapter *, u32);
-static inline void igb_set_rah_pool(struct e1000_hw *, int , int);
 static void igb_set_mc_list_pools(struct igb_adapter *, int, u16);
 static void igb_vmm_control(struct igb_adapter *);
-static inline void igb_set_vmolr(struct e1000_hw *, int);
-static inline int igb_set_vf_rlpml(struct igb_adapter *, int, int);
 static int igb_set_vf_mac(struct igb_adapter *adapter, int, unsigned char *);
 static void igb_restore_vf_multicasts(struct igb_adapter *adapter);
 
+static inline void igb_set_vmolr(struct e1000_hw *hw, int vfn)
+{
+       u32 reg_data;
+
+       reg_data = rd32(E1000_VMOLR(vfn));
+       reg_data |= E1000_VMOLR_BAM |    /* Accept broadcast */
+                   E1000_VMOLR_ROPE |   /* Accept packets matched in UTA */
+                   E1000_VMOLR_ROMPE |  /* Accept packets matched in MTA */
+                   E1000_VMOLR_AUPE |   /* Accept untagged packets */
+                   E1000_VMOLR_STRVLAN; /* Strip vlan tags */
+       wr32(E1000_VMOLR(vfn), reg_data);
+}
+
+static inline int igb_set_vf_rlpml(struct igb_adapter *adapter, int size,
+                                 int vfn)
+{
+       struct e1000_hw *hw = &adapter->hw;
+       u32 vmolr;
+
+       vmolr = rd32(E1000_VMOLR(vfn));
+       vmolr &= ~E1000_VMOLR_RLPML_MASK;
+       vmolr |= size | E1000_VMOLR_LPE;
+       wr32(E1000_VMOLR(vfn), vmolr);
+
+       return 0;
+}
+
+static inline void igb_set_rah_pool(struct e1000_hw *hw, int pool, int entry)
+{
+       u32 reg_data;
+
+       reg_data = rd32(E1000_RAH(entry));
+       reg_data &= ~E1000_RAH_POOL_MASK;
+       reg_data |= E1000_RAH_POOL_1 << pool;;
+       wr32(E1000_RAH(entry), reg_data);
+}
+
 #ifdef CONFIG_PM
 static int igb_suspend(struct pci_dev *, pm_message_t);
 static int igb_resume(struct pci_dev *);
@@ -5418,43 +5452,6 @@ static void igb_io_resume(struct pci_dev *pdev)
        igb_get_hw_control(adapter);
 }
 
-static inline void igb_set_vmolr(struct e1000_hw *hw, int vfn)
-{
-       u32 reg_data;
-
-       reg_data = rd32(E1000_VMOLR(vfn));
-       reg_data |= E1000_VMOLR_BAM |    /* Accept broadcast */
-                   E1000_VMOLR_ROPE |   /* Accept packets matched in UTA */
-                   E1000_VMOLR_ROMPE |  /* Accept packets matched in MTA */
-                   E1000_VMOLR_AUPE |   /* Accept untagged packets */
-                   E1000_VMOLR_STRVLAN; /* Strip vlan tags */
-       wr32(E1000_VMOLR(vfn), reg_data);
-}
-
-static inline int igb_set_vf_rlpml(struct igb_adapter *adapter, int size,
-                                 int vfn)
-{
-       struct e1000_hw *hw = &adapter->hw;
-       u32 vmolr;
-
-       vmolr = rd32(E1000_VMOLR(vfn));
-       vmolr &= ~E1000_VMOLR_RLPML_MASK;
-       vmolr |= size | E1000_VMOLR_LPE;
-       wr32(E1000_VMOLR(vfn), vmolr);
-
-       return 0;
-}
-
-static inline void igb_set_rah_pool(struct e1000_hw *hw, int pool, int entry)
-{
-       u32 reg_data;
-
-       reg_data = rd32(E1000_RAH(entry));
-       reg_data &= ~E1000_RAH_POOL_MASK;
-       reg_data |= E1000_RAH_POOL_1 << pool;;
-       wr32(E1000_RAH(entry), reg_data);
-}
-
 static void igb_set_mc_list_pools(struct igb_adapter *adapter,
                                  int entry_count, u16 total_rar_filters)
 {
index d53aa95..20f9bc6 100644 (file)
@@ -31,7 +31,6 @@
 #include <linux/tty.h>
 #include <linux/init.h>
 #include <asm/uaccess.h>
-#include <linux/smp_lock.h>
 #include <linux/delay.h>
 #include <linux/mutex.h>
 
index 73585fd..d12377b 100644 (file)
@@ -430,7 +430,8 @@ static int net_send_packet(struct sk_buff *skb, struct net_device *dev)
         * hardware interrupt handler.  Queue flow control is
         * thus managed under this lock as well.
         */
-       spin_lock_irq(&np->lock);
+       unsigned long flags;
+       spin_lock_irqsave(&np->lock, flags);
 
        add_to_tx_ring(np, skb, length);
        dev->trans_start = jiffies;
@@ -446,7 +447,7 @@ static int net_send_packet(struct sk_buff *skb, struct net_device *dev)
         * is when the transmit statistics are updated.
         */
 
-       spin_unlock_irq(&np->lock);
+       spin_unlock_irqrestore(&np->lock, flags);
 #else
        /* This is the case for older hardware which takes
         * a single transmit buffer at a time, and it is
index eba937c..b10fedd 100644 (file)
@@ -134,8 +134,10 @@ int phy_scan_fixups(struct phy_device *phydev)
 
                        err = fixup->run(phydev);
 
-                       if (err < 0)
+                       if (err < 0) {
+                               mutex_unlock(&phy_fixup_lock);
                                return err;
+                       }
                }
        }
        mutex_unlock(&phy_fixup_lock);
index 7a62f78..2ca8b0d 100644 (file)
@@ -270,6 +270,9 @@ static const struct net_device_ops plip_netdev_ops = {
        .ndo_stop                = plip_close,
        .ndo_start_xmit          = plip_tx_packet,
        .ndo_do_ioctl            = plip_ioctl,
+       .ndo_change_mtu          = eth_change_mtu,
+       .ndo_set_mac_address     = eth_mac_addr,
+       .ndo_validate_addr       = eth_validate_addr,
 };
 
 /* Entry point of PLIP driver.
index d1a5fb4..a3932c9 100644 (file)
@@ -1411,6 +1411,7 @@ static const struct net_device_ops gelic_netdevice_ops = {
        .ndo_set_multicast_list = gelic_net_set_multi,
        .ndo_change_mtu = gelic_net_change_mtu,
        .ndo_tx_timeout = gelic_net_tx_timeout,
+       .ndo_set_mac_address = eth_mac_addr,
        .ndo_validate_addr = eth_validate_addr,
 #ifdef CONFIG_NET_POLL_CONTROLLER
        .ndo_poll_controller = gelic_net_poll_controller,
index b6b3ca9..6932b08 100644 (file)
@@ -2707,6 +2707,7 @@ static const struct net_device_ops gelic_wl_netdevice_ops = {
        .ndo_set_multicast_list = gelic_net_set_multi,
        .ndo_change_mtu = gelic_net_change_mtu,
        .ndo_tx_timeout = gelic_net_tx_timeout,
+       .ndo_set_mac_address = eth_mac_addr,
        .ndo_validate_addr = eth_validate_addr,
 #ifdef CONFIG_NET_POLL_CONTROLLER
        .ndo_poll_controller = gelic_net_poll_controller,
index fdcbaf8..1c70e99 100644 (file)
@@ -1774,6 +1774,7 @@ static const struct net_device_ops smc_netdev_ops = {
        .ndo_start_xmit         = smc_hard_start_xmit,
        .ndo_tx_timeout         = smc_timeout,
        .ndo_set_multicast_list = smc_set_multicast_list,
+       .ndo_change_mtu         = eth_change_mtu,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_set_mac_address    = eth_mac_addr,
 #ifdef CONFIG_NET_POLL_CONTROLLER
index 66067f9..94b6d26 100644 (file)
@@ -1779,6 +1779,7 @@ static const struct net_device_ops smsc911x_netdev_ops = {
        .ndo_get_stats          = smsc911x_get_stats,
        .ndo_set_multicast_list = smsc911x_set_multicast_list,
        .ndo_do_ioctl           = smsc911x_do_ioctl,
+       .ndo_change_mtu         = eth_change_mtu,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_set_mac_address    = smsc911x_set_mac_address,
 #ifdef CONFIG_NET_POLL_CONTROLLER
index a82fb2a..f1e5e45 100644 (file)
@@ -1016,7 +1016,9 @@ static const struct net_device_ops vnet_ops = {
        .ndo_open               = vnet_open,
        .ndo_stop               = vnet_close,
        .ndo_set_multicast_list = vnet_set_rx_mode,
+       .ndo_change_mtu         = eth_change_mtu,
        .ndo_set_mac_address    = vnet_set_mac_addr,
+       .ndo_validate_addr      = eth_validate_addr,
        .ndo_tx_timeout         = vnet_tx_timeout,
        .ndo_change_mtu         = vnet_change_mtu,
        .ndo_start_xmit         = vnet_start_xmit,
index e013147..1f9ec29 100644 (file)
@@ -999,6 +999,9 @@ static const struct net_device_ops kaweth_netdev_ops = {
        .ndo_tx_timeout =               kaweth_tx_timeout,
        .ndo_set_multicast_list =       kaweth_set_rx_mode,
        .ndo_get_stats =                kaweth_netdev_stats,
+       .ndo_change_mtu =               eth_change_mtu,
+       .ndo_set_mac_address =          eth_mac_addr,
+       .ndo_validate_addr =            eth_validate_addr,
 };
 
 static int kaweth_probe(
index 73acbd2..631d269 100644 (file)
@@ -1493,6 +1493,9 @@ static const struct net_device_ops pegasus_netdev_ops = {
        .ndo_set_multicast_list =       pegasus_set_multicast,
        .ndo_get_stats =                pegasus_netdev_stats,
        .ndo_tx_timeout =               pegasus_tx_timeout,
+       .ndo_change_mtu =               eth_change_mtu,
+       .ndo_set_mac_address =          eth_mac_addr,
+       .ndo_validate_addr =            eth_validate_addr,
 };
 
 static struct usb_driver pegasus_driver = {
index d3489a3..88c30a5 100644 (file)
@@ -621,6 +621,7 @@ static const struct net_device_ops rhine_netdev_ops = {
        .ndo_start_xmit          = rhine_start_tx,
        .ndo_get_stats           = rhine_get_stats,
        .ndo_set_multicast_list  = rhine_set_rx_mode,
+       .ndo_change_mtu          = eth_change_mtu,
        .ndo_validate_addr       = eth_validate_addr,
        .ndo_set_mac_address     = eth_mac_addr,
        .ndo_do_ioctl            = netdev_ioctl,
index 345593c..a370e51 100644 (file)
@@ -2521,6 +2521,8 @@ static const struct net_device_ops orinoco_netdev_ops = {
        .ndo_start_xmit         = orinoco_xmit,
        .ndo_set_multicast_list = orinoco_set_multicast_list,
        .ndo_change_mtu         = orinoco_change_mtu,
+       .ndo_set_mac_address    = eth_mac_addr,
+       .ndo_validate_addr      = eth_validate_addr,
        .ndo_tx_timeout         = orinoco_tx_timeout,
        .ndo_get_stats          = orinoco_get_stats,
 };
@@ -2555,7 +2557,6 @@ struct net_device
        priv->wireless_data.spy_data = &priv->spy_data;
        dev->wireless_data = &priv->wireless_data;
 #endif
-       /* we use the default eth_mac_addr for setting the MAC addr */
 
        /* Reserve space in skb for the SNAP header */
        dev->hard_header_len += ENCAPS_OVERHEAD;
index a5b9f6a..d703e73 100644 (file)
@@ -32,7 +32,6 @@
 #include <linux/pci_hotplug.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
-#include <linux/smp_lock.h>
 #include <asm/atomic.h>
 #include <linux/delay.h>
 #include <linux/kthread.h>
index 2fa47af..0ff689a 100644 (file)
@@ -34,7 +34,6 @@
 #include <linux/interrupt.h>
 #include <linux/delay.h>
 #include <linux/wait.h>
-#include <linux/smp_lock.h>
 #include <linux/pci.h>
 #include <linux/pci_hotplug.h>
 #include <linux/kthread.h>
index 8450f4a..e6089bd 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/workqueue.h>
 #include <linux/pci.h>
 #include <linux/pci_hotplug.h>
+#include <linux/smp_lock.h>
 #include <linux/debugfs.h>
 #include "cpqphp.h"
 
index ff40345..8aab8ed 100644 (file)
@@ -30,7 +30,6 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
-#include <linux/smp_lock.h>
 #include <linux/pci.h>
 #include <linux/workqueue.h>
 #include "../pci.h"
index ec22284..e1c1ec5 100644 (file)
@@ -9,7 +9,6 @@
 
 #include <linux/errno.h>
 #include <linux/pci.h>
-#include <linux/smp_lock.h>
 #include <linux/syscalls.h>
 #include <asm/uaccess.h>
 #include "pci.h"
index 8bde921..b787335 100644 (file)
@@ -33,14 +33,14 @@ static enum power_supply_property *prop;
 
 static unsigned long wm97xx_read_bat(struct power_supply *bat_ps)
 {
-       return wm97xx_read_aux_adc(bat_ps->dev->parent->driver_data,
+       return wm97xx_read_aux_adc(dev_get_drvdata(bat_ps->dev->parent),
                                        pdata->batt_aux) * pdata->batt_mult /
                                        pdata->batt_div;
 }
 
 static unsigned long wm97xx_read_temp(struct power_supply *bat_ps)
 {
-       return wm97xx_read_aux_adc(bat_ps->dev->parent->driver_data,
+       return wm97xx_read_aux_adc(dev_get_drvdata(bat_ps->dev->parent),
                                        pdata->temp_aux) * pdata->temp_mult /
                                        pdata->temp_div;
 }
index 4ce3f72..df918ef 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/major.h>
 #include <linux/fs.h>
 #include <linux/blkpg.h>
+#include <linux/smp_lock.h>
 
 #include <asm/ccwdev.h>
 #include <asm/cmb.h>
index 650bcef..cd78c50 100644 (file)
@@ -9,7 +9,6 @@
 
 #include <linux/moduleparam.h>
 #include <linux/vmalloc.h>
-#include <linux/smp_lock.h>
 #include <linux/list.h>
 
 #include <scsi/scsi_tcq.h>
index baf83c6..e3c3adc 100644 (file)
@@ -45,6 +45,8 @@ Devices: [JR3] PCI force sensor board (jr3_pci)
 #include <linux/delay.h>
 #include <linux/ctype.h>
 #include <linux/firmware.h>
+#include <linux/jiffies.h>
+#include <linux/timer.h>
 #include "comedi_pci.h"
 #include "jr3_pci.h"
 
index 92121cf..5d9bab3 100644 (file)
@@ -111,9 +111,13 @@ static const struct s626_board s626_boards[] = {
 #define PCI_VENDOR_ID_S626 0x1131
 #define PCI_DEVICE_ID_S626 0x7146
 
+/*
+ * For devices with vendor:device id == 0x1131:0x7146 you must specify
+ * also subvendor:subdevice ids, because otherwise it will conflict with
+ * Philips SAA7146 media/dvb based cards.
+ */
 static DEFINE_PCI_DEVICE_TABLE(s626_pci_table) = {
-       {PCI_VENDOR_ID_S626, PCI_DEVICE_ID_S626, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-               0},
+       {PCI_VENDOR_ID_S626, PCI_DEVICE_ID_S626, 0x6000, 0x0272, 0, 0, 0},
        {0}
 };
 
@@ -499,25 +503,26 @@ static int s626_attach(struct comedi_device *dev, struct comedi_devconfig *it)
        resource_size_t resourceStart;
        dma_addr_t appdma;
        struct comedi_subdevice *s;
-       struct pci_dev *pdev;
+       const struct pci_device_id *ids;
+       struct pci_dev *pdev = NULL;
 
        if (alloc_private(dev, sizeof(struct s626_private)) < 0)
                return -ENOMEM;
 
-       for (pdev = pci_get_device(PCI_VENDOR_ID_S626, PCI_DEVICE_ID_S626,
-                       NULL); pdev != NULL;
-               pdev = pci_get_device(PCI_VENDOR_ID_S626,
-                       PCI_DEVICE_ID_S626, pdev)) {
-               if (it->options[0] || it->options[1]) {
-                       if (pdev->bus->number == it->options[0] &&
-                               PCI_SLOT(pdev->devfn) == it->options[1]) {
+       for (i = 0; i < (ARRAY_SIZE(s626_pci_table) - 1) && !pdev; i++) {
+               ids = &s626_pci_table[i];
+               do {
+                       pdev = pci_get_subsys(ids->vendor, ids->device, ids->subvendor,
+                                             ids->subdevice, pdev);
+
+                       if ((it->options[0] || it->options[1]) && pdev) {
                                /* matches requested bus/slot */
+                               if (pdev->bus->number == it->options[0] &&
+                                   PCI_SLOT(pdev->devfn) == it->options[1])
+                                       break;
+                       } else
                                break;
-                       }
-               } else {
-                       /* no bus/slot specified */
-                       break;
-               }
+               } while (1);
        }
        devpriv->pdev = pdev;
 
index a5e4aca..bb22347 100644 (file)
@@ -17,6 +17,7 @@
 
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/smp_lock.h>
 #include <linux/usb.h>
 #include <dvb-usb.h>
 
index 6ec2520..d6ce398 100644 (file)
@@ -7,4 +7,4 @@ TODO:
        - possible comedi merge
 
 Please send cleanup patches to Greg Kroah-Hartman <greg@kroah.com>
-and CC: David Kiliani <mail@davidkiliani.de>
+and CC: David Kiliani <mail@davidkiliani.de> and Meilhaus Support <support@meilhaus.de>
index 1cdfe69..2f8155c 100644 (file)
@@ -444,8 +444,7 @@ static void piusb_write_bulk_callback(struct urb *urb)
                        __func__, status);
 
        pdx->pendingWrite = 0;
-       usb_buffer_free(urb->dev, urb->transfer_buffer_length,
-                       urb->transfer_buffer, urb->transfer_dma);
+       kfree(urb->transfer_buffer);
 }
 
 int piusb_output(struct ioctl_struct *io, unsigned char *uBuf, int len,
@@ -457,9 +456,7 @@ int piusb_output(struct ioctl_struct *io, unsigned char *uBuf, int len,
 
        urb = usb_alloc_urb(0, GFP_KERNEL);
        if (urb != NULL) {
-               kbuf =
-                   usb_buffer_alloc(pdx->udev, len, GFP_KERNEL,
-                                    &urb->transfer_dma);
+               kbuf = kmalloc(len, GFP_KERNEL);
                if (!kbuf) {
                        dev_err(&pdx->udev->dev, "buffer_alloc failed\n");
                        return -ENOMEM;
@@ -470,7 +467,6 @@ int piusb_output(struct ioctl_struct *io, unsigned char *uBuf, int len,
                }
                usb_fill_bulk_urb(urb, pdx->udev, pdx->hEP[io->endpoint], kbuf,
                                  len, piusb_write_bulk_callback, pdx);
-               urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
                err = usb_submit_urb(urb, GFP_KERNEL);
                if (err) {
                        dev_err(&pdx->udev->dev,
@@ -641,7 +637,7 @@ static int MapUserBuffer(struct ioctl_struct *io, struct device_extension *pdx)
        numPagesRequired =
            ((uaddr & ~PAGE_MASK) + count + ~PAGE_MASK) >> PAGE_SHIFT;
        dbg("Number of pages needed = %d", numPagesRequired);
-       maplist_p = vmalloc(numPagesRequired * sizeof(struct page));
+       maplist_p = vmalloc(numPagesRequired * sizeof(struct page *));
        if (!maplist_p) {
                dbg("Can't Allocate Memory for maplist_p");
                return -ENOMEM;
@@ -712,9 +708,7 @@ static int MapUserBuffer(struct ioctl_struct *io, struct device_extension *pdx)
                usb_fill_bulk_urb(pdx->PixelUrb[frameInfo][i],
                                  pdx->udev,
                                  epAddr,
-                                 (dma_addr_t *) sg_dma_address(&pdx->
-                                                               sgl[frameInfo]
-                                                               [i]),
+                                 NULL, // non-DMA HC? buy a better hardware
                                  sg_dma_len(&pdx->sgl[frameInfo][i]),
                                  piusb_readPIXEL_callback, (void *)pdx);
                pdx->PixelUrb[frameInfo][i]->transfer_dma =
index 5e5b3f2..29e3b53 100644 (file)
@@ -89,6 +89,7 @@
        {USB_DEVICE(0x0DF6,0x002C)}, /* Sitecom */              \
        {USB_DEVICE(0x0DF6,0x002D)}, /* Sitecom */              \
        {USB_DEVICE(0x0DF6,0x0039)}, /* Sitecom */              \
+       {USB_DEVICE(0x0DF6,0x003F)}, /* Sitecom WL-608 */       \
        {USB_DEVICE(0x14B2,0x3C06)}, /* Conceptronic */         \
        {USB_DEVICE(0x14B2,0x3C28)}, /* Conceptronic */         \
        {USB_DEVICE(0x2019,0xED06)}, /* Planex Communications, Inc. */          \
index 93af37e..54b4b71 100644 (file)
@@ -461,19 +461,19 @@ int ieee80211_wx_get_name(struct ieee80211_device *ieee,
                             struct iw_request_info *info,
                             union iwreq_data *wrqu, char *extra)
 {
-       strcpy(wrqu->name, "802.11");
+       strlcpy(wrqu->name, "802.11", IFNAMSIZ);
        if(ieee->modulation & IEEE80211_CCK_MODULATION){
-               strcat(wrqu->name, "b");
+               strlcat(wrqu->name, "b", IFNAMSIZ);
                if(ieee->modulation & IEEE80211_OFDM_MODULATION)
-                       strcat(wrqu->name, "/g");
+                       strlcat(wrqu->name, "/g", IFNAMSIZ);
        }else if(ieee->modulation & IEEE80211_OFDM_MODULATION)
-               strcat(wrqu->name, "g");
+               strlcat(wrqu->name, "g", IFNAMSIZ);
 
        if((ieee->state == IEEE80211_LINKED) ||
                (ieee->state == IEEE80211_LINKED_SCANNING))
-               strcat(wrqu->name," linked");
+               strlcat(wrqu->name,"  link", IFNAMSIZ);
        else if(ieee->state != IEEE80211_NOLINK)
-               strcat(wrqu->name," link..");
+               strlcat(wrqu->name," .....", IFNAMSIZ);
 
 
        return 0;
index 4b5552c..770f412 100644 (file)
@@ -1,6 +1,6 @@
 config RTL8192SU
        tristate "RealTek RTL8192SU Wireless LAN NIC driver"
        depends on PCI
-       depends on WIRELESS_EXT && COMPAT_NET_DEV_OPS
+       depends on WIRELESS_EXT
        default N
        ---help---
index f408b45..759032d 100644 (file)
@@ -118,7 +118,6 @@ struct net_device *alloc_ieee80211(int sizeof_priv)
 #else
        ieee = (struct ieee80211_device *)dev->priv;
 #endif
-       dev->hard_start_xmit = ieee80211_xmit;
 
        memset(ieee, 0, sizeof(struct ieee80211_device)+sizeof_priv);
        ieee->dev = dev;
index 1f50c46..191dc3f 100644 (file)
@@ -548,21 +548,21 @@ int ieee80211_wx_get_name(struct ieee80211_device *ieee,
                             struct iw_request_info *info,
                             union iwreq_data *wrqu, char *extra)
 {
-       strcpy(wrqu->name, "802.11");
+       strlcpy(wrqu->name, "802.11", IFNAMSIZ);
        if(ieee->modulation & IEEE80211_CCK_MODULATION){
-               strcat(wrqu->name, "b");
+               strlcat(wrqu->name, "b", IFNAMSIZ);
                if(ieee->modulation & IEEE80211_OFDM_MODULATION)
-                       strcat(wrqu->name, "/g");
+                       strlcat(wrqu->name, "/g", IFNAMSIZ);
        }else if(ieee->modulation & IEEE80211_OFDM_MODULATION)
-               strcat(wrqu->name, "g");
+               strlcat(wrqu->name, "g", IFNAMSIZ);
        if (ieee->mode & (IEEE_N_24G | IEEE_N_5G))
-               strcat(wrqu->name, "/n");
+               strlcat(wrqu->name, "/n", IFNAMSIZ);
 
        if((ieee->state == IEEE80211_LINKED) ||
                (ieee->state == IEEE80211_LINKED_SCANNING))
-               strcat(wrqu->name," linked");
+               strlcat(wrqu->name, "  link", IFNAMSIZ);
        else if(ieee->state != IEEE80211_NOLINK)
-               strcat(wrqu->name," link..");
+               strlcat(wrqu->name, " .....", IFNAMSIZ);
 
 
        return 0;
index f1423d7..4ab2507 100644 (file)
@@ -12132,6 +12132,19 @@ static void HalUsbSetQueuePipeMapping8192SUsb(struct usb_interface *intf, struct
 }
 #endif
 
+static const struct net_device_ops rtl8192_netdev_ops = {
+       .ndo_open               = rtl8192_open,
+       .ndo_stop               = rtl8192_close,
+       .ndo_get_stats          = rtl8192_stats,
+       .ndo_tx_timeout         = tx_timeout,
+       .ndo_do_ioctl           = rtl8192_ioctl,
+       .ndo_set_multicast_list = r8192_set_multicast,
+       .ndo_set_mac_address    = r8192_set_mac_adr,
+       .ndo_validate_addr      = eth_validate_addr,
+       .ndo_change_mtu         = eth_change_mtu,
+       .ndo_start_xmit         = ieee80211_xmit,
+};
+
 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
 static int __devinit rtl8192_usb_probe(struct usb_interface *intf,
                         const struct usb_device_id *id)
@@ -12186,15 +12199,7 @@ static void * __devinit rtl8192_usb_probe(struct usb_device *udev,
        priv->ops = &rtl8192u_ops;
 #endif
 
-       dev->open = rtl8192_open;
-       dev->stop = rtl8192_close;
-       //dev->hard_start_xmit = rtl8192_8023_hard_start_xmit;
-       dev->tx_timeout = tx_timeout;
-       //dev->wireless_handlers = &r8192_wx_handlers_def;
-       dev->do_ioctl = rtl8192_ioctl;
-       dev->set_multicast_list = r8192_set_multicast;
-       dev->set_mac_address = r8192_set_mac_adr;
-       dev->get_stats = rtl8192_stats;
+       dev->netdev_ops = &rtl8192_netdev_ops;
 
          //DMESG("Oops: i'm coming\n");
 #if WIRELESS_EXT >= 12
index 92c95aa..b1531a8 100644 (file)
@@ -35,7 +35,9 @@ int rtl8192U_suspend(struct usb_interface *intf, pm_message_t state)
                      return 0;
                 }
 
-               dev->stop(dev);
+               if (dev->netdev_ops->ndo_stop)
+                       dev->netdev_ops->ndo_stop(dev);
+
                mdelay(10);
 
                netif_device_detach(dev);
@@ -61,7 +63,9 @@ int rtl8192U_resume (struct usb_interface *intf)
                }
 
                netif_device_attach(dev);
-               dev->open(dev);
+
+               if (dev->netdev_ops->ndo_open)
+                       dev->netdev_ops->ndo_open(dev);
        }
 
         return 0;
index 90b29b5..a9bd410 100644 (file)
@@ -866,7 +866,7 @@ static void qt_release(struct usb_serial *serial)
 
 }
 
-int qt_open(struct tty_struct *tty,
+static int qt_open(struct tty_struct *tty,
            struct usb_serial_port *port, struct file *filp)
 {
        struct usb_serial *serial;
@@ -1041,17 +1041,19 @@ static void qt_block_until_empty(struct tty_struct *tty,
        }
 }
 
-static void qt_close(struct tty_struct *tty, struct usb_serial_port *port,
-                    struct file *filp)
+static void qt_close( struct usb_serial_port *port)
 {
        struct usb_serial *serial = port->serial;
        struct quatech_port *qt_port;
        struct quatech_port *port0;
+       struct tty_struct *tty;
        int status;
        unsigned int index;
        status = 0;
 
        dbg("%s - port %d\n", __func__, port->number);
+
+       tty = tty_port_tty_get(&port->port);
        index = tty->index - serial->minor;
 
        qt_port = qt_get_port_private(port);
index cfdaac9..a137c78 100644 (file)
@@ -2235,24 +2235,6 @@ static void stlc45xx_op_remove_interface(struct ieee80211_hw *hw,
        stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
 }
 
-static int stlc45xx_op_config_interface(struct ieee80211_hw *hw,
-                                       struct ieee80211_vif *vif,
-                                       struct ieee80211_if_conf *conf)
-{
-       struct stlc45xx *stlc = hw->priv;
-
-       stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
-
-       mutex_lock(&stlc->mutex);
-
-       memcpy(stlc->bssid, conf->bssid, ETH_ALEN);
-       stlc45xx_tx_setup(stlc);
-
-       mutex_unlock(&stlc->mutex);
-
-       return 0;
-}
-
 static int stlc45xx_op_config(struct ieee80211_hw *hw, u32 changed)
 {
        struct stlc45xx *stlc = hw->priv;
@@ -2295,6 +2277,14 @@ static void stlc45xx_op_bss_info_changed(struct ieee80211_hw *hw,
 {
        struct stlc45xx *stlc = hw->priv;
 
+       stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
+       mutex_lock(&stlc->mutex);
+
+       memcpy(stlc->bssid, info->bssid, ETH_ALEN);
+       stlc45xx_tx_setup(stlc);
+
+       mutex_unlock(&stlc->mutex);
+
        if (changed & BSS_CHANGED_ASSOC) {
                stlc->associated = info->assoc;
                if (info->assoc)
@@ -2357,7 +2347,6 @@ static const struct ieee80211_ops stlc45xx_ops = {
        .add_interface = stlc45xx_op_add_interface,
        .remove_interface = stlc45xx_op_remove_interface,
        .config = stlc45xx_op_config,
-       .config_interface = stlc45xx_op_config_interface,
        .configure_filter = stlc45xx_op_configure_filter,
        .tx = stlc45xx_op_tx,
        .bss_info_changed = stlc45xx_op_bss_info_changed,
index 22f93dd..251220d 100644 (file)
@@ -18,6 +18,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/smp_lock.h>
 #include <linux/file.h>
 #include <linux/tcp.h>
 #include <linux/in.h>
index a10ed27..f43ca41 100644 (file)
@@ -344,7 +344,7 @@ static CHIP_INFO chip_info_table[]= {
 };
 
 static struct pci_device_id device_id_table[] __devinitdata = {
-{ 0x1106, 0x3253, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (int)&chip_info_table[0]},
+{ 0x1106, 0x3253, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long)&chip_info_table[0]},
 { 0, }
 };
 #endif
@@ -369,7 +369,7 @@ static int  device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
 
 #ifdef CONFIG_PM
 static int device_notify_reboot(struct notifier_block *, unsigned long event, void *ptr);
-static int viawget_suspend(struct pci_dev *pcid, u32 state);
+static int viawget_suspend(struct pci_dev *pcid, pm_message_t state);
 static int viawget_resume(struct pci_dev *pcid);
 struct notifier_block device_notifier = {
         notifier_call:  device_notify_reboot,
@@ -3941,7 +3941,7 @@ device_notify_reboot(struct notifier_block *nb, unsigned long event, void *p)
         while ((pdev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pdev)) != NULL) {
             if(pci_dev_driver(pdev) == &device_driver) {
                 if (pci_get_drvdata(pdev))
-                    viawget_suspend(pdev, 3);
+                    viawget_suspend(pdev, PMSG_HIBERNATE);
             }
         }
     }
@@ -3949,7 +3949,7 @@ device_notify_reboot(struct notifier_block *nb, unsigned long event, void *p)
 }
 
 static int
-viawget_suspend(struct pci_dev *pcid, u32 state)
+viawget_suspend(struct pci_dev *pcid, pm_message_t state)
 {
     int power_status;   // to silence the compiler
 
@@ -3971,7 +3971,7 @@ viawget_suspend(struct pci_dev *pcid, u32 state)
     memset(pMgmt->abyCurrBSSID, 0, 6);
     pMgmt->eCurrState = WMAC_STATE_IDLE;
     pci_disable_device(pcid);
-    power_status = pci_set_power_state(pcid, state);
+    power_status = pci_set_power_state(pcid, pci_choose_state(pcid, state));
     spin_unlock_irq(&pDevice->lock);
     return 0;
 }
index a913efc..40de151 100644 (file)
 #include <linux/fs.h>          /* everything... */
 #include <linux/errno.h>       /* error codes */
 #include <linux/slab.h>
+#include <linux/smp_lock.h>
 #include <linux/mm.h>
 #include <linux/ioport.h>
 #include <linux/interrupt.h>
index b52cc83..f3873f6 100644 (file)
@@ -23,7 +23,6 @@
 #include <linux/errno.h>
 #include <linux/phonedev.h>
 #include <linux/init.h>
-#include <linux/smp_lock.h>
 #include <asm/uaccess.h>
 #include <asm/system.h>
 
index 3f10459..5b15d9d 100644 (file)
@@ -387,6 +387,7 @@ static void acm_rx_tasklet(unsigned long _acm)
        struct acm_ru *rcv;
        unsigned long flags;
        unsigned char throttled;
+       struct usb_host_endpoint *ep;
 
        dbg("Entering acm_rx_tasklet");
 
@@ -462,11 +463,20 @@ urbs:
 
                rcv->buffer = buf;
 
-               usb_fill_bulk_urb(rcv->urb, acm->dev,
-                                 acm->rx_endpoint,
-                                 buf->base,
-                                 acm->readsize,
-                                 acm_read_bulk, rcv);
+               ep = (usb_pipein(acm->rx_endpoint) ? acm->dev->ep_in : acm->dev->ep_out)
+                               [usb_pipeendpoint(acm->rx_endpoint)];
+               if (usb_endpoint_xfer_int(&ep->desc))
+                       usb_fill_int_urb(rcv->urb, acm->dev,
+                                        acm->rx_endpoint,
+                                        buf->base,
+                                        acm->readsize,
+                                        acm_read_bulk, rcv, ep->desc.bInterval);
+               else
+                       usb_fill_bulk_urb(rcv->urb, acm->dev,
+                                         acm->rx_endpoint,
+                                         buf->base,
+                                         acm->readsize,
+                                         acm_read_bulk, rcv);
                rcv->urb->transfer_dma = buf->dma;
                rcv->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
 
@@ -1227,9 +1237,14 @@ made_compressed_probe:
                        goto alloc_fail7;
                }
 
-               usb_fill_bulk_urb(snd->urb, usb_dev,
-                       usb_sndbulkpipe(usb_dev, epwrite->bEndpointAddress),
-                       NULL, acm->writesize, acm_write_bulk, snd);
+               if (usb_endpoint_xfer_int(epwrite))
+                       usb_fill_int_urb(snd->urb, usb_dev,
+                               usb_sndbulkpipe(usb_dev, epwrite->bEndpointAddress),
+                               NULL, acm->writesize, acm_write_bulk, snd, epwrite->bInterval);
+               else
+                       usb_fill_bulk_urb(snd->urb, usb_dev,
+                               usb_sndbulkpipe(usb_dev, epwrite->bEndpointAddress),
+                               NULL, acm->writesize, acm_write_bulk, snd);
                snd->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
                snd->instance = acm;
        }
index 0fe4345..ba589d4 100644 (file)
@@ -15,7 +15,6 @@
 #include <linux/errno.h>
 #include <linux/slab.h>
 #include <linux/module.h>
-#include <linux/smp_lock.h>
 #include <linux/mutex.h>
 #include <linux/uaccess.h>
 #include <linux/bitops.h>
index 3703789..b09a527 100644 (file)
@@ -751,7 +751,7 @@ static int get_capabilities(struct usbtmc_device_data *data)
 {
        struct device *dev = &data->usb_dev->dev;
        char *buffer;
-       int rv;
+       int rv = 0;
 
        buffer = kmalloc(0x18, GFP_KERNEL);
        if (!buffer)
@@ -763,7 +763,7 @@ static int get_capabilities(struct usbtmc_device_data *data)
                             0, 0, buffer, 0x18, USBTMC_TIMEOUT);
        if (rv < 0) {
                dev_err(dev, "usb_control_msg returned %d\n", rv);
-               return rv;
+               goto err_out;
        }
 
        dev_dbg(dev, "GET_CAPABILITIES returned %x\n", buffer[0]);
@@ -773,7 +773,8 @@ static int get_capabilities(struct usbtmc_device_data *data)
        dev_dbg(dev, "USB488 device capabilities are %x\n", buffer[15]);
        if (buffer[0] != USBTMC_STATUS_SUCCESS) {
                dev_err(dev, "GET_CAPABILITIES returned %x\n", buffer[0]);
-               return -EPERM;
+               rv = -EPERM;
+               goto err_out;
        }
 
        data->capabilities.interface_capabilities = buffer[4];
@@ -781,8 +782,9 @@ static int get_capabilities(struct usbtmc_device_data *data)
        data->capabilities.usb488_interface_capabilities = buffer[14];
        data->capabilities.usb488_device_capabilities = buffer[15];
 
+err_out:
        kfree(buffer);
-       return 0;
+       return rv;
 }
 
 #define capability_attribute(name)                                     \
index 69280c3..ad92594 100644 (file)
@@ -28,7 +28,7 @@ comment "Miscellaneous USB options"
        depends on USB
 
 config USB_DEVICEFS
-       bool "USB device filesystem (DEPRECATED)" if EMBEDDED
+       bool "USB device filesystem (DEPRECATED)"
        depends on USB
        ---help---
          If you say Y here (and to "/proc file system support" in the "File
index 73c108d..96f1171 100644 (file)
@@ -136,17 +136,19 @@ static const struct class_info clas_info[] =
        {USB_CLASS_AUDIO,               "audio"},
        {USB_CLASS_COMM,                "comm."},
        {USB_CLASS_HID,                 "HID"},
-       {USB_CLASS_HUB,                 "hub"},
        {USB_CLASS_PHYSICAL,            "PID"},
+       {USB_CLASS_STILL_IMAGE,         "still"},
        {USB_CLASS_PRINTER,             "print"},
        {USB_CLASS_MASS_STORAGE,        "stor."},
+       {USB_CLASS_HUB,                 "hub"},
        {USB_CLASS_CDC_DATA,            "data"},
-       {USB_CLASS_APP_SPEC,            "app."},
-       {USB_CLASS_VENDOR_SPEC,         "vend."},
-       {USB_CLASS_STILL_IMAGE,         "still"},
        {USB_CLASS_CSCID,               "scard"},
        {USB_CLASS_CONTENT_SEC,         "c-sec"},
        {USB_CLASS_VIDEO,               "video"},
+       {USB_CLASS_WIRELESS_CONTROLLER, "wlcon"},
+       {USB_CLASS_MISC,                "misc"},
+       {USB_CLASS_APP_SPEC,            "app."},
+       {USB_CLASS_VENDOR_SPEC,         "vend."},
        {-1,                            "unk."}         /* leave as last */
 };
 
index 3086090..38b8bce 100644 (file)
@@ -325,21 +325,34 @@ static void async_completed(struct urb *urb)
        struct async *as = urb->context;
        struct dev_state *ps = as->ps;
        struct siginfo sinfo;
+       struct pid *pid = NULL;
+       uid_t uid = 0;
+       uid_t euid = 0;
+       u32 secid = 0;
+       int signr;
 
        spin_lock(&ps->lock);
        list_move_tail(&as->asynclist, &ps->async_completed);
-       spin_unlock(&ps->lock);
        as->status = urb->status;
-       if (as->signr) {
+       signr = as->signr;
+       if (signr) {
                sinfo.si_signo = as->signr;
                sinfo.si_errno = as->status;
                sinfo.si_code = SI_ASYNCIO;
                sinfo.si_addr = as->userurb;
-               kill_pid_info_as_uid(as->signr, &sinfo, as->pid, as->uid,
-                                     as->euid, as->secid);
+               pid = as->pid;
+               uid = as->uid;
+               euid = as->euid;
+               secid = as->secid;
        }
        snoop(&urb->dev->dev, "urb complete\n");
        snoop_urb(urb, as->userurb);
+       spin_unlock(&ps->lock);
+
+       if (signr)
+               kill_pid_info_as_uid(sinfo.si_signo, &sinfo, pid, uid,
+                                     euid, secid);
+
        wake_up(&ps->wait);
 }
 
@@ -982,7 +995,7 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
                                USBDEVFS_URB_ZERO_PACKET |
                                USBDEVFS_URB_NO_INTERRUPT))
                return -EINVAL;
-       if (!uurb->buffer)
+       if (uurb->buffer_length > 0 && !uurb->buffer)
                return -EINVAL;
        if (!(uurb->type == USBDEVFS_URB_TYPE_CONTROL &&
            (uurb->endpoint & ~USB_ENDPOINT_DIR_MASK) == 0)) {
@@ -1038,11 +1051,6 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
                        is_in = 0;
                        uurb->endpoint &= ~USB_DIR_IN;
                }
-               if (!access_ok(is_in ? VERIFY_WRITE : VERIFY_READ,
-                               uurb->buffer, uurb->buffer_length)) {
-                       kfree(dr);
-                       return -EFAULT;
-               }
                snoop(&ps->dev->dev, "control urb: bRequest=%02x "
                        "bRrequestType=%02x wValue=%04x "
                        "wIndex=%04x wLength=%04x\n",
@@ -1062,9 +1070,6 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
                uurb->number_of_packets = 0;
                if (uurb->buffer_length > MAX_USBFS_BUFFER_SIZE)
                        return -EINVAL;
-               if (!access_ok(is_in ? VERIFY_WRITE : VERIFY_READ,
-                               uurb->buffer, uurb->buffer_length))
-                       return -EFAULT;
                snoop(&ps->dev->dev, "bulk urb\n");
                break;
 
@@ -1106,28 +1111,35 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
                        return -EINVAL;
                if (uurb->buffer_length > MAX_USBFS_BUFFER_SIZE)
                        return -EINVAL;
-               if (!access_ok(is_in ? VERIFY_WRITE : VERIFY_READ,
-                               uurb->buffer, uurb->buffer_length))
-                       return -EFAULT;
                snoop(&ps->dev->dev, "interrupt urb\n");
                break;
 
        default:
                return -EINVAL;
        }
-       as = alloc_async(uurb->number_of_packets);
-       if (!as) {
+       if (uurb->buffer_length > 0 &&
+                       !access_ok(is_in ? VERIFY_WRITE : VERIFY_READ,
+                               uurb->buffer, uurb->buffer_length)) {
                kfree(isopkt);
                kfree(dr);
-               return -ENOMEM;
+               return -EFAULT;
        }
-       as->urb->transfer_buffer = kmalloc(uurb->buffer_length, GFP_KERNEL);
-       if (!as->urb->transfer_buffer) {
+       as = alloc_async(uurb->number_of_packets);
+       if (!as) {
                kfree(isopkt);
                kfree(dr);
-               free_async(as);
                return -ENOMEM;
        }
+       if (uurb->buffer_length > 0) {
+               as->urb->transfer_buffer = kmalloc(uurb->buffer_length,
+                               GFP_KERNEL);
+               if (!as->urb->transfer_buffer) {
+                       kfree(isopkt);
+                       kfree(dr);
+                       free_async(as);
+                       return -ENOMEM;
+               }
+       }
        as->urb->dev = ps->dev;
        as->urb->pipe = (uurb->type << 30) |
                        __create_pipe(ps->dev, uurb->endpoint & 0xf) |
@@ -1169,7 +1181,7 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
        kfree(isopkt);
        as->ps = ps;
        as->userurb = arg;
-       if (uurb->endpoint & USB_DIR_IN)
+       if (is_in && uurb->buffer_length > 0)
                as->userbuffer = uurb->buffer;
        else
                as->userbuffer = NULL;
@@ -1179,9 +1191,9 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
        as->uid = cred->uid;
        as->euid = cred->euid;
        security_task_getsecid(current, &as->secid);
-       if (!is_in) {
+       if (!is_in && uurb->buffer_length > 0) {
                if (copy_from_user(as->urb->transfer_buffer, uurb->buffer,
-                               as->urb->transfer_buffer_length)) {
+                               uurb->buffer_length)) {
                        free_async(as);
                        return -EFAULT;
                }
@@ -1231,22 +1243,22 @@ static int processcompl(struct async *as, void __user * __user *arg)
        if (as->userbuffer)
                if (copy_to_user(as->userbuffer, urb->transfer_buffer,
                                 urb->transfer_buffer_length))
-                       return -EFAULT;
+                       goto err_out;
        if (put_user(as->status, &userurb->status))
-               return -EFAULT;
+               goto err_out;
        if (put_user(urb->actual_length, &userurb->actual_length))
-               return -EFAULT;
+               goto err_out;
        if (put_user(urb->error_count, &userurb->error_count))
-               return -EFAULT;
+               goto err_out;
 
        if (usb_endpoint_xfer_isoc(&urb->ep->desc)) {
                for (i = 0; i < urb->number_of_packets; i++) {
                        if (put_user(urb->iso_frame_desc[i].actual_length,
                                     &userurb->iso_frame_desc[i].actual_length))
-                               return -EFAULT;
+                               goto err_out;
                        if (put_user(urb->iso_frame_desc[i].status,
                                     &userurb->iso_frame_desc[i].status))
-                               return -EFAULT;
+                               goto err_out;
                }
        }
 
@@ -1255,6 +1267,10 @@ static int processcompl(struct async *as, void __user * __user *arg)
        if (put_user(addr, (void __user * __user *)arg))
                return -EFAULT;
        return 0;
+
+err_out:
+       free_async(as);
+       return -EFAULT;
 }
 
 static struct async *reap_as(struct dev_state *ps)
index d397ecf..ec5c67e 100644 (file)
@@ -227,6 +227,10 @@ struct hc_driver {
                /* has a port been handed over to a companion? */
        int     (*port_handed_over)(struct usb_hcd *, int);
 
+               /* CLEAR_TT_BUFFER completion callback */
+       void    (*clear_tt_buffer_complete)(struct usb_hcd *,
+                               struct usb_host_endpoint *);
+
        /* xHCI specific functions */
                /* Called by usb_alloc_dev to alloc HC device structures */
        int     (*alloc_dev)(struct usb_hcd *, struct usb_device *);
index 2af3b4f..71f86c6 100644 (file)
@@ -450,10 +450,10 @@ hub_clear_tt_buffer (struct usb_device *hdev, u16 devinfo, u16 tt)
  * talking to TTs must queue control transfers (not just bulk and iso), so
  * both can talk to the same hub concurrently.
  */
-static void hub_tt_kevent (struct work_struct *work)
+static void hub_tt_work(struct work_struct *work)
 {
        struct usb_hub          *hub =
-               container_of(work, struct usb_hub, tt.kevent);
+               container_of(work, struct usb_hub, tt.clear_work);
        unsigned long           flags;
        int                     limit = 100;
 
@@ -462,6 +462,7 @@ static void hub_tt_kevent (struct work_struct *work)
                struct list_head        *next;
                struct usb_tt_clear     *clear;
                struct usb_device       *hdev = hub->hdev;
+               const struct hc_driver  *drv;
                int                     status;
 
                next = hub->tt.clear_list.next;
@@ -471,21 +472,25 @@ static void hub_tt_kevent (struct work_struct *work)
                /* drop lock so HCD can concurrently report other TT errors */
                spin_unlock_irqrestore (&hub->tt.lock, flags);
                status = hub_clear_tt_buffer (hdev, clear->devinfo, clear->tt);
-               spin_lock_irqsave (&hub->tt.lock, flags);
-
                if (status)
                        dev_err (&hdev->dev,
                                "clear tt %d (%04x) error %d\n",
                                clear->tt, clear->devinfo, status);
+
+               /* Tell the HCD, even if the operation failed */
+               drv = clear->hcd->driver;
+               if (drv->clear_tt_buffer_complete)
+                       (drv->clear_tt_buffer_complete)(clear->hcd, clear->ep);
+
                kfree(clear);
+               spin_lock_irqsave(&hub->tt.lock, flags);
        }
        spin_unlock_irqrestore (&hub->tt.lock, flags);
 }
 
 /**
- * usb_hub_tt_clear_buffer - clear control/bulk TT state in high speed hub
- * @udev: the device whose split transaction failed
- * @pipe: identifies the endpoint of the failed transaction
+ * usb_hub_clear_tt_buffer - clear control/bulk TT state in high speed hub
+ * @urb: an URB associated with the failed or incomplete split transaction
  *
  * High speed HCDs use this to tell the hub driver that some split control or
  * bulk transaction failed in a way that requires clearing internal state of
@@ -495,8 +500,10 @@ static void hub_tt_kevent (struct work_struct *work)
  * It may not be possible for that hub to handle additional full (or low)
  * speed transactions until that state is fully cleared out.
  */
-void usb_hub_tt_clear_buffer (struct usb_device *udev, int pipe)
+int usb_hub_clear_tt_buffer(struct urb *urb)
 {
+       struct usb_device       *udev = urb->dev;
+       int                     pipe = urb->pipe;
        struct usb_tt           *tt = udev->tt;
        unsigned long           flags;
        struct usb_tt_clear     *clear;
@@ -508,7 +515,7 @@ void usb_hub_tt_clear_buffer (struct usb_device *udev, int pipe)
        if ((clear = kmalloc (sizeof *clear, GFP_ATOMIC)) == NULL) {
                dev_err (&udev->dev, "can't save CLEAR_TT_BUFFER state\n");
                /* FIXME recover somehow ... RESET_TT? */
-               return;
+               return -ENOMEM;
        }
 
        /* info that CLEAR_TT_BUFFER needs */
@@ -520,14 +527,19 @@ void usb_hub_tt_clear_buffer (struct usb_device *udev, int pipe)
                        : (USB_ENDPOINT_XFER_BULK << 11);
        if (usb_pipein (pipe))
                clear->devinfo |= 1 << 15;
-       
+
+       /* info for completion callback */
+       clear->hcd = bus_to_hcd(udev->bus);
+       clear->ep = urb->ep;
+
        /* tell keventd to clear state for this TT */
        spin_lock_irqsave (&tt->lock, flags);
        list_add_tail (&clear->clear_list, &tt->clear_list);
-       schedule_work (&tt->kevent);
+       schedule_work(&tt->clear_work);
        spin_unlock_irqrestore (&tt->lock, flags);
+       return 0;
 }
-EXPORT_SYMBOL_GPL(usb_hub_tt_clear_buffer);
+EXPORT_SYMBOL_GPL(usb_hub_clear_tt_buffer);
 
 /* If do_delay is false, return the number of milliseconds the caller
  * needs to delay.
@@ -818,7 +830,7 @@ static void hub_quiesce(struct usb_hub *hub, enum hub_quiescing_type type)
        if (hub->has_indicators)
                cancel_delayed_work_sync(&hub->leds);
        if (hub->tt.hub)
-               cancel_work_sync(&hub->tt.kevent);
+               cancel_work_sync(&hub->tt.clear_work);
 }
 
 /* caller has locked the hub device */
@@ -935,7 +947,7 @@ static int hub_configure(struct usb_hub *hub,
 
        spin_lock_init (&hub->tt.lock);
        INIT_LIST_HEAD (&hub->tt.clear_list);
-       INIT_WORK (&hub->tt.kevent, hub_tt_kevent);
+       INIT_WORK(&hub->tt.clear_work, hub_tt_work);
        switch (hdev->descriptor.bDeviceProtocol) {
                case 0:
                        break;
index 889c0f3..de8081f 100644 (file)
@@ -188,16 +188,18 @@ struct usb_tt {
        /* for control/bulk error recovery (CLEAR_TT_BUFFER) */
        spinlock_t              lock;
        struct list_head        clear_list;     /* of usb_tt_clear */
-       struct work_struct                      kevent;
+       struct work_struct      clear_work;
 };
 
 struct usb_tt_clear {
        struct list_head        clear_list;
        unsigned                tt;
        u16                     devinfo;
+       struct usb_hcd          *hcd;
+       struct usb_host_endpoint        *ep;
 };
 
-extern void usb_hub_tt_clear_buffer(struct usb_device *dev, int pipe);
+extern int usb_hub_clear_tt_buffer(struct urb *urb);
 extern void usb_ep0_reinit(struct usb_device *);
 
 #endif /* __LINUX_HUB_H */
index 2bed83c..9720e69 100644 (file)
@@ -806,6 +806,48 @@ static int usb_string_sub(struct usb_device *dev, unsigned int langid,
        return rc;
 }
 
+static int usb_get_langid(struct usb_device *dev, unsigned char *tbuf)
+{
+       int err;
+
+       if (dev->have_langid)
+               return 0;
+
+       if (dev->string_langid < 0)
+               return -EPIPE;
+
+       err = usb_string_sub(dev, 0, 0, tbuf);
+
+       /* If the string was reported but is malformed, default to english
+        * (0x0409) */
+       if (err == -ENODATA || (err > 0 && err < 4)) {
+               dev->string_langid = 0x0409;
+               dev->have_langid = 1;
+               dev_err(&dev->dev,
+                       "string descriptor 0 malformed (err = %d), "
+                       "defaulting to 0x%04x\n",
+                               err, dev->string_langid);
+               return 0;
+       }
+
+       /* In case of all other errors, we assume the device is not able to
+        * deal with strings at all. Set string_langid to -1 in order to
+        * prevent any string to be retrieved from the device */
+       if (err < 0) {
+               dev_err(&dev->dev, "string descriptor 0 read error: %d\n",
+                                       err);
+               dev->string_langid = -1;
+               return -EPIPE;
+       }
+
+       /* always use the first langid listed */
+       dev->string_langid = tbuf[2] | (tbuf[3] << 8);
+       dev->have_langid = 1;
+       dev_dbg(&dev->dev, "default language 0x%04x\n",
+                               dev->string_langid);
+       return 0;
+}
+
 /**
  * usb_string - returns UTF-8 version of a string descriptor
  * @dev: the device whose string descriptor is being retrieved
@@ -837,24 +879,9 @@ int usb_string(struct usb_device *dev, int index, char *buf, size_t size)
        if (!tbuf)
                return -ENOMEM;
 
-       /* get langid for strings if it's not yet known */
-       if (!dev->have_langid) {
-               err = usb_string_sub(dev, 0, 0, tbuf);
-               if (err < 0) {
-                       dev_err(&dev->dev,
-                               "string descriptor 0 read error: %d\n",
-                               err);
-               } else if (err < 4) {
-                       dev_err(&dev->dev, "string descriptor 0 too short\n");
-               } else {
-                       dev->string_langid = tbuf[2] | (tbuf[3] << 8);
-                       /* always use the first langid listed */
-                       dev_dbg(&dev->dev, "default language 0x%04x\n",
-                               dev->string_langid);
-               }
-
-               dev->have_langid = 1;
-       }
+       err = usb_get_langid(dev, tbuf);
+       if (err < 0)
+               goto errout;
 
        err = usb_string_sub(dev, dev->string_langid, index, tbuf);
        if (err < 0)
index 5d1ddf4..7f8e83a 100644 (file)
@@ -286,6 +286,27 @@ config USB_S3C_HSOTG
        default USB_GADGET
        select USB_GADGET_SELECTED
 
+config USB_GADGET_IMX
+       boolean "Freescale IMX USB Peripheral Controller"
+       depends on ARCH_MX1
+       help
+          Freescale's IMX series include an integrated full speed
+          USB 1.1 device controller.  The controller in the IMX series
+          is register-compatible.
+
+          It has Six fixed-function endpoints, as well as endpoint
+          zero (for control transfers).
+
+          Say "y" to link the driver statically, or "m" to build a
+          dynamically linked module called "imx_udc" and force all
+          gadget drivers to also be dynamically linked.
+
+config USB_IMX
+       tristate
+       depends on USB_GADGET_IMX
+       default USB_GADGET
+       select USB_GADGET_SELECTED
+
 config USB_GADGET_S3C2410
        boolean "S3C2410 USB Device Controller"
        depends on ARCH_S3C2410
@@ -321,27 +342,6 @@ config USB_GADGET_MUSB_HDRC
          This OTG-capable silicon IP is used in dual designs including
          the TI DaVinci, OMAP 243x, OMAP 343x, TUSB 6010, and ADI Blackfin
 
-config USB_GADGET_IMX
-       boolean "Freescale IMX USB Peripheral Controller"
-       depends on ARCH_MX1
-       help
-          Freescale's IMX series include an integrated full speed
-          USB 1.1 device controller.  The controller in the IMX series
-          is register-compatible.
-
-          It has Six fixed-function endpoints, as well as endpoint
-          zero (for control transfers).
-
-          Say "y" to link the driver statically, or "m" to build a
-          dynamically linked module called "imx_udc" and force all
-          gadget drivers to also be dynamically linked.
-
-config USB_IMX
-       tristate
-       depends on USB_GADGET_IMX
-       default USB_GADGET
-       select USB_GADGET_SELECTED
-
 config USB_GADGET_M66592
        boolean "Renesas M66592 USB Peripheral Controller"
        select USB_GADGET_DUALSPEED
@@ -604,6 +604,7 @@ config USB_ZERO_HNPTEST
 config USB_AUDIO
        tristate "Audio Gadget (EXPERIMENTAL)"
        depends on SND
+       select SND_PCM
        help
          Gadget Audio is compatible with USB Audio Class specification 1.0.
          It will include at least one AudioControl interface, zero or more
index 826f3ad..77352cc 100644 (file)
@@ -48,7 +48,6 @@
 #include <linux/ioport.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
-#include <linux/smp_lock.h>
 #include <linux/errno.h>
 #include <linux/init.h>
 #include <linux/timer.h>
index 94de7e8..9f80f4e 100644 (file)
@@ -42,9 +42,9 @@
  * Instead:  allocate your own, using normal USB-IF procedures.
  */
 
-/* Thanks to NetChip Technologies for donating this product ID. */
-#define AUDIO_VENDOR_NUM               0x0525  /* NetChip */
-#define AUDIO_PRODUCT_NUM              0xa4a1  /* Linux-USB Audio Gadget */
+/* Thanks to Linux Foundation for donating this product ID. */
+#define AUDIO_VENDOR_NUM               0x1d6b  /* Linux Foundation */
+#define AUDIO_PRODUCT_NUM              0x0101  /* Linux-USB Audio Gadget */
 
 /*-------------------------------------------------------------------------*/
 
index d006dc6..bd102f5 100644 (file)
@@ -293,15 +293,16 @@ static int __init eth_bind(struct usb_composite_dev *cdev)
                /* CDC Subset */
                eth_config_driver.label = "CDC Subset/SAFE";
 
-               device_desc.idVendor = cpu_to_le16(SIMPLE_VENDOR_NUM),
-               device_desc.idProduct = cpu_to_le16(SIMPLE_PRODUCT_NUM),
-               device_desc.bDeviceClass = USB_CLASS_VENDOR_SPEC;
+               device_desc.idVendor = cpu_to_le16(SIMPLE_VENDOR_NUM);
+               device_desc.idProduct = cpu_to_le16(SIMPLE_PRODUCT_NUM);
+               if (!has_rndis())
+                       device_desc.bDeviceClass = USB_CLASS_VENDOR_SPEC;
        }
 
        if (has_rndis()) {
                /* RNDIS plus ECM-or-Subset */
-               device_desc.idVendor = cpu_to_le16(RNDIS_VENDOR_NUM),
-               device_desc.idProduct = cpu_to_le16(RNDIS_PRODUCT_NUM),
+               device_desc.idVendor = cpu_to_le16(RNDIS_VENDOR_NUM);
+               device_desc.idProduct = cpu_to_le16(RNDIS_PRODUCT_NUM);
                device_desc.bNumConfigurations = 2;
        }
 
index 6829d59..a391351 100644 (file)
@@ -34,7 +34,6 @@
 #include <linux/ioport.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
-#include <linux/smp_lock.h>
 #include <linux/errno.h>
 #include <linux/init.h>
 #include <linux/timer.h>
index 0ce4e28..ed21e26 100644 (file)
@@ -139,7 +139,7 @@ static int is_vbus_present(void)
 {
        struct pxa2xx_udc_mach_info             *mach = the_controller->mach;
 
-       if (mach->gpio_vbus) {
+       if (gpio_is_valid(mach->gpio_vbus)) {
                int value = gpio_get_value(mach->gpio_vbus);
 
                if (mach->gpio_vbus_inverted)
@@ -158,7 +158,7 @@ static void pullup_off(void)
        struct pxa2xx_udc_mach_info             *mach = the_controller->mach;
        int off_level = mach->gpio_pullup_inverted;
 
-       if (mach->gpio_pullup)
+       if (gpio_is_valid(mach->gpio_pullup))
                gpio_set_value(mach->gpio_pullup, off_level);
        else if (mach->udc_command)
                mach->udc_command(PXA2XX_UDC_CMD_DISCONNECT);
@@ -169,7 +169,7 @@ static void pullup_on(void)
        struct pxa2xx_udc_mach_info             *mach = the_controller->mach;
        int on_level = !mach->gpio_pullup_inverted;
 
-       if (mach->gpio_pullup)
+       if (gpio_is_valid(mach->gpio_pullup))
                gpio_set_value(mach->gpio_pullup, on_level);
        else if (mach->udc_command)
                mach->udc_command(PXA2XX_UDC_CMD_CONNECT);
@@ -1000,7 +1000,7 @@ static int pxa25x_udc_pullup(struct usb_gadget *_gadget, int is_active)
        udc = container_of(_gadget, struct pxa25x_udc, gadget);
 
        /* not all boards support pullup control */
-       if (!udc->mach->gpio_pullup && !udc->mach->udc_command)
+       if (!gpio_is_valid(udc->mach->gpio_pullup) && !udc->mach->udc_command)
                return -EOPNOTSUPP;
 
        udc->pullup = (is_active != 0);
@@ -1802,11 +1802,13 @@ pxa25x_udc_irq(int irq, void *_dev)
                                        USIR0 |= tmp;
                                        handled = 1;
                                }
+#ifndef        CONFIG_USB_PXA25X_SMALL
                                if (usir1 & tmp) {
                                        handle_ep(&dev->ep[i+8]);
                                        USIR1 |= tmp;
                                        handled = 1;
                                }
+#endif
                        }
                }
 
@@ -2160,7 +2162,7 @@ static int __init pxa25x_udc_probe(struct platform_device *pdev)
        dev->dev = &pdev->dev;
        dev->mach = pdev->dev.platform_data;
 
-       if (dev->mach->gpio_vbus) {
+       if (gpio_is_valid(dev->mach->gpio_vbus)) {
                if ((retval = gpio_request(dev->mach->gpio_vbus,
                                "pxa25x_udc GPIO VBUS"))) {
                        dev_dbg(&pdev->dev,
@@ -2173,7 +2175,7 @@ static int __init pxa25x_udc_probe(struct platform_device *pdev)
        } else
                vbus_irq = 0;
 
-       if (dev->mach->gpio_pullup) {
+       if (gpio_is_valid(dev->mach->gpio_pullup)) {
                if ((retval = gpio_request(dev->mach->gpio_pullup,
                                "pca25x_udc GPIO PULLUP"))) {
                        dev_dbg(&pdev->dev,
@@ -2256,10 +2258,10 @@ lubbock_fail0:
 #endif
        free_irq(irq, dev);
  err_irq1:
-       if (dev->mach->gpio_pullup)
+       if (gpio_is_valid(dev->mach->gpio_pullup))
                gpio_free(dev->mach->gpio_pullup);
  err_gpio_pullup:
-       if (dev->mach->gpio_vbus)
+       if (gpio_is_valid(dev->mach->gpio_vbus))
                gpio_free(dev->mach->gpio_vbus);
  err_gpio_vbus:
        clk_put(dev->clk);
@@ -2294,11 +2296,11 @@ static int __exit pxa25x_udc_remove(struct platform_device *pdev)
                free_irq(LUBBOCK_USB_IRQ, dev);
        }
 #endif
-       if (dev->mach->gpio_vbus) {
+       if (gpio_is_valid(dev->mach->gpio_vbus)) {
                free_irq(gpio_to_irq(dev->mach->gpio_vbus), dev);
                gpio_free(dev->mach->gpio_vbus);
        }
-       if (dev->mach->gpio_pullup)
+       if (gpio_is_valid(dev->mach->gpio_pullup))
                gpio_free(dev->mach->gpio_pullup);
 
        clk_put(dev->clk);
@@ -2329,7 +2331,7 @@ static int pxa25x_udc_suspend(struct platform_device *dev, pm_message_t state)
        struct pxa25x_udc       *udc = platform_get_drvdata(dev);
        unsigned long flags;
 
-       if (!udc->mach->gpio_pullup && !udc->mach->udc_command)
+       if (!gpio_is_valid(udc->mach->gpio_pullup) && !udc->mach->udc_command)
                WARNING("USB host won't detect disconnect!\n");
        udc->suspended = 1;
 
index 2b4660e..ca41b0b 100644 (file)
@@ -442,6 +442,8 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
 
        case OID_802_3_MAC_OPTIONS:
                pr_debug("%s: OID_802_3_MAC_OPTIONS\n", __func__);
+               *outbuf = cpu_to_le32(0);
+               retval = 0;
                break;
 
        /* ieee802.3 statistics OIDs (table 4-4) */
index 9a2b892..a9b452f 100644 (file)
@@ -28,7 +28,6 @@
 #include <linux/ioport.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
-#include <linux/smp_lock.h>
 #include <linux/errno.h>
 #include <linux/init.h>
 #include <linux/timer.h>
index 0c03471..1a920c7 100644 (file)
@@ -181,26 +181,27 @@ config USB_OHCI_HCD_PPC_SOC
          Enables support for the USB controller on the MPC52xx or
          STB03xxx processor chip.  If unsure, say Y.
 
-config USB_OHCI_HCD_PPC_OF
-       bool "OHCI support for PPC USB controller on OF platform bus"
-       depends on USB_OHCI_HCD && PPC_OF
-       default y
-       ---help---
-         Enables support for the USB controller PowerPC present on the
-         OpenFirmware platform bus.
-
 config USB_OHCI_HCD_PPC_OF_BE
-       bool "Support big endian HC"
-       depends on USB_OHCI_HCD_PPC_OF
-       default y
+       bool "OHCI support for OF platform bus (big endian)"
+       depends on USB_OHCI_HCD && PPC_OF
        select USB_OHCI_BIG_ENDIAN_DESC
        select USB_OHCI_BIG_ENDIAN_MMIO
+       ---help---
+         Enables support for big-endian USB controllers present on the
+         OpenFirmware platform bus.
 
 config USB_OHCI_HCD_PPC_OF_LE
-       bool "Support little endian HC"
-       depends on USB_OHCI_HCD_PPC_OF
-       default n
+       bool "OHCI support for OF platform bus (little endian)"
+       depends on USB_OHCI_HCD && PPC_OF
        select USB_OHCI_LITTLE_ENDIAN
+       ---help---
+         Enables support for little-endian USB controllers present on the
+         OpenFirmware platform bus.
+
+config USB_OHCI_HCD_PPC_OF
+       bool
+       depends on USB_OHCI_HCD && PPC_OF
+       default USB_OHCI_HCD_PPC_OF_BE || USB_OHCI_HCD_PPC_OF_LE
 
 config USB_OHCI_HCD_PCI
        bool "OHCI support for PCI-bus USB controllers"
index c3a778b..59d208d 100644 (file)
@@ -113,6 +113,8 @@ static const struct hc_driver ehci_au1xxx_hc_driver = {
        .bus_resume             = ehci_bus_resume,
        .relinquish_port        = ehci_relinquish_port,
        .port_handed_over       = ehci_port_handed_over,
+
+       .clear_tt_buffer_complete       = ehci_clear_tt_buffer_complete,
 };
 
 static int ehci_hcd_au1xxx_drv_probe(struct platform_device *pdev)
index bf86809..9911749 100644 (file)
@@ -325,6 +325,8 @@ static const struct hc_driver ehci_fsl_hc_driver = {
        .bus_resume = ehci_bus_resume,
        .relinquish_port = ehci_relinquish_port,
        .port_handed_over = ehci_port_handed_over,
+
+       .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
 };
 
 static int ehci_fsl_drv_probe(struct platform_device *pdev)
index 2b72473..7d03549 100644 (file)
@@ -1003,6 +1003,8 @@ idle_timeout:
                schedule_timeout_uninterruptible(1);
                goto rescan;
        case QH_STATE_IDLE:             /* fully unlinked */
+               if (qh->clearing_tt)
+                       goto idle_timeout;
                if (list_empty (&qh->qtd_list)) {
                        qh_put (qh);
                        break;
@@ -1030,12 +1032,14 @@ ehci_endpoint_reset(struct usb_hcd *hcd, struct usb_host_endpoint *ep)
        struct ehci_hcd         *ehci = hcd_to_ehci(hcd);
        struct ehci_qh          *qh;
        int                     eptype = usb_endpoint_type(&ep->desc);
+       int                     epnum = usb_endpoint_num(&ep->desc);
+       int                     is_out = usb_endpoint_dir_out(&ep->desc);
+       unsigned long           flags;
 
        if (eptype != USB_ENDPOINT_XFER_BULK && eptype != USB_ENDPOINT_XFER_INT)
                return;
 
- rescan:
-       spin_lock_irq(&ehci->lock);
+       spin_lock_irqsave(&ehci->lock, flags);
        qh = ep->hcpriv;
 
        /* For Bulk and Interrupt endpoints we maintain the toggle state
@@ -1044,29 +1048,24 @@ ehci_endpoint_reset(struct usb_hcd *hcd, struct usb_host_endpoint *ep)
         * the toggle bit in the QH.
         */
        if (qh) {
+               usb_settoggle(qh->dev, epnum, is_out, 0);
                if (!list_empty(&qh->qtd_list)) {
                        WARN_ONCE(1, "clear_halt for a busy endpoint\n");
-               } else if (qh->qh_state == QH_STATE_IDLE) {
-                       qh->hw_token &= ~cpu_to_hc32(ehci, QTD_TOGGLE);
-               } else {
-                       /* It's not safe to write into the overlay area
-                        * while the QH is active.  Unlink it first and
-                        * wait for the unlink to complete.
+               } else if (qh->qh_state == QH_STATE_LINKED) {
+
+                       /* The toggle value in the QH can't be updated
+                        * while the QH is active.  Unlink it now;
+                        * re-linking will call qh_refresh().
                         */
-                       if (qh->qh_state == QH_STATE_LINKED) {
-                               if (eptype == USB_ENDPOINT_XFER_BULK) {
-                                       unlink_async(ehci, qh);
-                               } else {
-                                       intr_deschedule(ehci, qh);
-                                       (void) qh_schedule(ehci, qh);
-                               }
+                       if (eptype == USB_ENDPOINT_XFER_BULK) {
+                               unlink_async(ehci, qh);
+                       } else {
+                               intr_deschedule(ehci, qh);
+                               (void) qh_schedule(ehci, qh);
                        }
-                       spin_unlock_irq(&ehci->lock);
-                       schedule_timeout_uninterruptible(1);
-                       goto rescan;
                }
        }
-       spin_unlock_irq(&ehci->lock);
+       spin_unlock_irqrestore(&ehci->lock, flags);
 }
 
 static int ehci_get_frame (struct usb_hcd *hcd)
index a44bb4a..89b7c70 100644 (file)
@@ -61,6 +61,8 @@ static const struct hc_driver ixp4xx_ehci_hc_driver = {
 #endif
        .relinquish_port        = ehci_relinquish_port,
        .port_handed_over       = ehci_port_handed_over,
+
+       .clear_tt_buffer_complete       = ehci_clear_tt_buffer_complete,
 };
 
 static int ixp4xx_ehci_probe(struct platform_device *pdev)
index 770dd9a..dc2ac61 100644 (file)
@@ -165,6 +165,8 @@ static const struct hc_driver ehci_orion_hc_driver = {
        .bus_resume = ehci_bus_resume,
        .relinquish_port = ehci_relinquish_port,
        .port_handed_over = ehci_port_handed_over,
+
+       .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
 };
 
 static void __init
index f3683e1..c2f1b7d 100644 (file)
@@ -404,6 +404,8 @@ static const struct hc_driver ehci_pci_hc_driver = {
        .bus_resume =           ehci_bus_resume,
        .relinquish_port =      ehci_relinquish_port,
        .port_handed_over =     ehci_port_handed_over,
+
+       .clear_tt_buffer_complete       = ehci_clear_tt_buffer_complete,
 };
 
 /*-------------------------------------------------------------------------*/
index fbd2722..36f96da 100644 (file)
@@ -79,6 +79,8 @@ static const struct hc_driver ehci_ppc_of_hc_driver = {
 #endif
        .relinquish_port        = ehci_relinquish_port,
        .port_handed_over       = ehci_port_handed_over,
+
+       .clear_tt_buffer_complete       = ehci_clear_tt_buffer_complete,
 };
 
 
index 93f7035..1dee33b 100644 (file)
@@ -75,6 +75,8 @@ static const struct hc_driver ps3_ehci_hc_driver = {
 #endif
        .relinquish_port        = ehci_relinquish_port,
        .port_handed_over       = ehci_port_handed_over,
+
+       .clear_tt_buffer_complete       = ehci_clear_tt_buffer_complete,
 };
 
 static int __devinit ps3_ehci_probe(struct ps3_system_bus_device *dev)
index 3192f68..9a13847 100644 (file)
@@ -93,6 +93,22 @@ qh_update (struct ehci_hcd *ehci, struct ehci_qh *qh, struct ehci_qtd *qtd)
        qh->hw_qtd_next = QTD_NEXT(ehci, qtd->qtd_dma);
        qh->hw_alt_next = EHCI_LIST_END(ehci);
 
+       /* Except for control endpoints, we make hardware maintain data
+        * toggle (like OHCI) ... here (re)initialize the toggle in the QH,
+        * and set the pseudo-toggle in udev. Only usb_clear_halt() will
+        * ever clear it.
+        */
+       if (!(qh->hw_info1 & cpu_to_hc32(ehci, 1 << 14))) {
+               unsigned        is_out, epnum;
+
+               is_out = !(qtd->hw_token & cpu_to_hc32(ehci, 1 << 8));
+               epnum = (hc32_to_cpup(ehci, &qh->hw_info1) >> 8) & 0x0f;
+               if (unlikely (!usb_gettoggle (qh->dev, epnum, is_out))) {
+                       qh->hw_token &= ~cpu_to_hc32(ehci, QTD_TOGGLE);
+                       usb_settoggle (qh->dev, epnum, is_out, 1);
+               }
+       }
+
        /* HC must see latest qtd and qh data before we clear ACTIVE+HALT */
        wmb ();
        qh->hw_token &= cpu_to_hc32(ehci, QTD_TOGGLE | QTD_STS_PING);
@@ -123,6 +139,55 @@ qh_refresh (struct ehci_hcd *ehci, struct ehci_qh *qh)
 
 /*-------------------------------------------------------------------------*/
 
+static void qh_link_async(struct ehci_hcd *ehci, struct ehci_qh *qh);
+
+static void ehci_clear_tt_buffer_complete(struct usb_hcd *hcd,
+               struct usb_host_endpoint *ep)
+{
+       struct ehci_hcd         *ehci = hcd_to_ehci(hcd);
+       struct ehci_qh          *qh = ep->hcpriv;
+       unsigned long           flags;
+
+       spin_lock_irqsave(&ehci->lock, flags);
+       qh->clearing_tt = 0;
+       if (qh->qh_state == QH_STATE_IDLE && !list_empty(&qh->qtd_list)
+                       && HC_IS_RUNNING(hcd->state))
+               qh_link_async(ehci, qh);
+       spin_unlock_irqrestore(&ehci->lock, flags);
+}
+
+static void ehci_clear_tt_buffer(struct ehci_hcd *ehci, struct ehci_qh *qh,
+               struct urb *urb, u32 token)
+{
+
+       /* If an async split transaction gets an error or is unlinked,
+        * the TT buffer may be left in an indeterminate state.  We
+        * have to clear the TT buffer.
+        *
+        * Note: this routine is never called for Isochronous transfers.
+        */
+       if (urb->dev->tt && !usb_pipeint(urb->pipe) && !qh->clearing_tt) {
+#ifdef DEBUG
+               struct usb_device *tt = urb->dev->tt->hub;
+               dev_dbg(&tt->dev,
+                       "clear tt buffer port %d, a%d ep%d t%08x\n",
+                       urb->dev->ttport, urb->dev->devnum,
+                       usb_pipeendpoint(urb->pipe), token);
+#endif /* DEBUG */
+               if (!ehci_is_TDI(ehci)
+                               || urb->dev->tt->hub !=
+                                  ehci_to_hcd(ehci)->self.root_hub) {
+                       if (usb_hub_clear_tt_buffer(urb) == 0)
+                               qh->clearing_tt = 1;
+               } else {
+
+                       /* REVISIT ARC-derived cores don't clear the root
+                        * hub TT buffer in this way...
+                        */
+               }
+       }
+}
+
 static int qtd_copy_status (
        struct ehci_hcd *ehci,
        struct urb *urb,
@@ -149,6 +214,14 @@ static int qtd_copy_status (
                if (token & QTD_STS_BABBLE) {
                        /* FIXME "must" disable babbling device's port too */
                        status = -EOVERFLOW;
+               /* CERR nonzero + halt --> stall */
+               } else if (QTD_CERR(token)) {
+                       status = -EPIPE;
+
+               /* In theory, more than one of the following bits can be set
+                * since they are sticky and the transaction is retried.
+                * Which to test first is rather arbitrary.
+                */
                } else if (token & QTD_STS_MMF) {
                        /* fs/ls interrupt xfer missed the complete-split */
                        status = -EPROTO;
@@ -157,21 +230,15 @@ static int qtd_copy_status (
                                ? -ENOSR  /* hc couldn't read data */
                                : -ECOMM; /* hc couldn't write data */
                } else if (token & QTD_STS_XACT) {
-                       /* timeout, bad crc, wrong PID, etc; retried */
-                       if (QTD_CERR (token))
-                               status = -EPIPE;
-                       else {
-                               ehci_dbg (ehci, "devpath %s ep%d%s 3strikes\n",
-                                       urb->dev->devpath,
-                                       usb_pipeendpoint (urb->pipe),
-                                       usb_pipein (urb->pipe) ? "in" : "out");
-                               status = -EPROTO;
-                       }
-               /* CERR nonzero + no errors + halt --> stall */
-               } else if (QTD_CERR (token))
-                       status = -EPIPE;
-               else    /* unknown */
+                       /* timeout, bad CRC, wrong PID, etc */
+                       ehci_dbg(ehci, "devpath %s ep%d%s 3strikes\n",
+                               urb->dev->devpath,
+                               usb_pipeendpoint(urb->pipe),
+                               usb_pipein(urb->pipe) ? "in" : "out");
+                       status = -EPROTO;
+               } else {        /* unknown */
                        status = -EPROTO;
+               }
 
                ehci_vdbg (ehci,
                        "dev%d ep%d%s qtd token %08x --> status %d\n",
@@ -179,28 +246,6 @@ static int qtd_copy_status (
                        usb_pipeendpoint (urb->pipe),
                        usb_pipein (urb->pipe) ? "in" : "out",
                        token, status);
-
-               /* if async CSPLIT failed, try cleaning out the TT buffer */
-               if (status != -EPIPE
-                               && urb->dev->tt
-                               && !usb_pipeint(urb->pipe)
-                               && ((token & QTD_STS_MMF) != 0
-                                       || QTD_CERR(token) == 0)
-                               && (!ehci_is_TDI(ehci)
-                                       || urb->dev->tt->hub !=
-                                          ehci_to_hcd(ehci)->self.root_hub)) {
-#ifdef DEBUG
-                       struct usb_device *tt = urb->dev->tt->hub;
-                       dev_dbg (&tt->dev,
-                               "clear tt buffer port %d, a%d ep%d t%08x\n",
-                               urb->dev->ttport, urb->dev->devnum,
-                               usb_pipeendpoint (urb->pipe), token);
-#endif /* DEBUG */
-                       /* REVISIT ARC-derived cores don't clear the root
-                        * hub TT buffer in this way...
-                        */
-                       usb_hub_tt_clear_buffer (urb->dev, urb->pipe);
-               }
        }
 
        return status;
@@ -391,9 +436,16 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh)
                        /* qh unlinked; token in overlay may be most current */
                        if (state == QH_STATE_IDLE
                                        && cpu_to_hc32(ehci, qtd->qtd_dma)
-                                               == qh->hw_current)
+                                               == qh->hw_current) {
                                token = hc32_to_cpu(ehci, qh->hw_token);
 
+                               /* An unlink may leave an incomplete
+                                * async transaction in the TT buffer.
+                                * We have to clear it.
+                                */
+                               ehci_clear_tt_buffer(ehci, qh, urb, token);
+                       }
+
                        /* force halt for unlinked or blocked qh, so we'll
                         * patch the qh later and so that completions can't
                         * activate it while we "know" it's stopped.
@@ -419,6 +471,13 @@ halt:
                                        && (qtd->hw_alt_next
                                                & EHCI_LIST_END(ehci)))
                                last_status = -EINPROGRESS;
+
+                       /* As part of low/full-speed endpoint-halt processing
+                        * we must clear the TT buffer (11.17.5).
+                        */
+                       if (unlikely(last_status != -EINPROGRESS &&
+                                       last_status != -EREMOTEIO))
+                               ehci_clear_tt_buffer(ehci, qh, urb, token);
                }
 
                /* if we're removing something not at the queue head,
@@ -834,6 +893,7 @@ done:
        qh->qh_state = QH_STATE_IDLE;
        qh->hw_info1 = cpu_to_hc32(ehci, info1);
        qh->hw_info2 = cpu_to_hc32(ehci, info2);
+       usb_settoggle (urb->dev, usb_pipeendpoint (urb->pipe), !is_input, 1);
        qh_refresh (ehci, qh);
        return qh;
 }
@@ -847,6 +907,10 @@ static void qh_link_async (struct ehci_hcd *ehci, struct ehci_qh *qh)
        __hc32          dma = QH_NEXT(ehci, qh->qh_dma);
        struct ehci_qh  *head;
 
+       /* Don't link a QH if there's a Clear-TT-Buffer pending */
+       if (unlikely(qh->clearing_tt))
+               return;
+
        /* (re)start the async schedule? */
        head = ehci->async;
        timer_action_done (ehci, TIMER_ASYNC_OFF);
@@ -864,7 +928,7 @@ static void qh_link_async (struct ehci_hcd *ehci, struct ehci_qh *qh)
                }
        }
 
-       /* clear halt and maybe recover from silicon quirk */
+       /* clear halt and/or toggle; and maybe recover from silicon quirk */
        if (qh->qh_state == QH_STATE_IDLE)
                qh_refresh (ehci, qh);
 
index 9d1babc..74f7f83 100644 (file)
@@ -1619,11 +1619,14 @@ itd_complete (
                                desc->status = -EPROTO;
 
                        /* HC need not update length with this error */
-                       if (!(t & EHCI_ISOC_BABBLE))
-                               desc->actual_length = EHCI_ITD_LENGTH (t);
+                       if (!(t & EHCI_ISOC_BABBLE)) {
+                               desc->actual_length = EHCI_ITD_LENGTH(t);
+                               urb->actual_length += desc->actual_length;
+                       }
                } else if (likely ((t & EHCI_ISOC_ACTIVE) == 0)) {
                        desc->status = 0;
-                       desc->actual_length = EHCI_ITD_LENGTH (t);
+                       desc->actual_length = EHCI_ITD_LENGTH(t);
+                       urb->actual_length += desc->actual_length;
                } else {
                        /* URB was too late */
                        desc->status = -EXDEV;
@@ -2014,7 +2017,8 @@ sitd_complete (
                        desc->status = -EPROTO;
        } else {
                desc->status = 0;
-               desc->actual_length = desc->length - SITD_LENGTH (t);
+               desc->actual_length = desc->length - SITD_LENGTH(t);
+               urb->actual_length += desc->actual_length;
        }
        stream->depth -= stream->interval << 3;
 
index 90ad339..2bfff30 100644 (file)
@@ -354,7 +354,9 @@ struct ehci_qh {
        unsigned short          period;         /* polling interval */
        unsigned short          start;          /* where polling starts */
 #define NO_FRAME ((unsigned short)~0)                  /* pick new start */
+
        struct usb_device       *dev;           /* access to TT */
+       unsigned                clearing_tt:1;  /* Clear-TT-Buf in progress */
 } __attribute__ ((aligned (32)));
 
 /*-------------------------------------------------------------------------*/
index bb63b68..62a226b 100644 (file)
@@ -576,9 +576,7 @@ irqreturn_t fhci_irq(struct usb_hcd *hcd)
                        out_be16(&usb->fhci->regs->usb_event,
                                 usb->saved_msk);
                } else if (usb->port_status == FHCI_PORT_DISABLED) {
-                       if (fhci_ioports_check_bus_state(fhci) == 1 &&
-                                       usb->port_status != FHCI_PORT_LOW &&
-                                       usb->port_status != FHCI_PORT_FULL)
+                       if (fhci_ioports_check_bus_state(fhci) == 1)
                                fhci_device_connected_interrupt(fhci);
                }
                usb_er &= ~USB_E_RESET_MASK;
@@ -605,9 +603,7 @@ irqreturn_t fhci_irq(struct usb_hcd *hcd)
        }
 
        if (usb_er & USB_E_IDLE_MASK) {
-               if (usb->port_status == FHCI_PORT_DISABLED &&
-                               usb->port_status != FHCI_PORT_LOW &&
-                               usb->port_status != FHCI_PORT_FULL) {
+               if (usb->port_status == FHCI_PORT_DISABLED) {
                        usb_er &= ~USB_E_RESET_MASK;
                        fhci_device_connected_interrupt(fhci);
                } else if (usb->port_status ==
index 3fa3a17..d4feebf 100644 (file)
@@ -361,7 +361,7 @@ static int __devexit isp1760_plat_remove(struct platform_device *pdev)
 
 static struct platform_driver isp1760_plat_driver = {
        .probe  = isp1760_plat_probe,
-       .remove = isp1760_plat_remove,
+       .remove = __devexit_p(isp1760_plat_remove),
        .driver = {
                .name   = "isp1760",
        },
index 56976cc..e18f749 100644 (file)
@@ -26,7 +26,6 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
-#include <linux/smp_lock.h>
 #include <linux/errno.h>
 #include <linux/init.h>
 #include <linux/timer.h>
index 3c5fe5c..90e1a8d 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/sched.h>
+#include <linux/smp_lock.h>
 #include <linux/poll.h>
 #include <linux/usb/iowarrior.h>
 
index deb95bb..d645f38 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/kernel.h>
 #include <linux/signal.h>
 #include <linux/sched.h>
+#include <linux/smp_lock.h>
 #include <linux/errno.h>
 #include <linux/random.h>
 #include <linux/poll.h>
index e0ff9cc..29092b8 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/slab.h>
+#include <linux/smp_lock.h>
 #include <linux/errno.h>
 #include <linux/mutex.h>
 #include <asm/uaccess.h>
index 8a39de3..59bf949 100644 (file)
@@ -5,7 +5,6 @@
 
 #include <linux/slab.h>
 #include <linux/list.h>
-#include <linux/smp_lock.h>
 #include <linux/errno.h>
 #include <linux/dmapool.h>
 
index 180d7da..e16ff60 100644 (file)
 #include <mach/hardware.h>
 #include <mach/memory.h>
 #include <mach/gpio.h>
+#include <mach/cputype.h>
 
 #include <asm/mach-types.h>
 
 #include "musb_core.h"
 
 #ifdef CONFIG_MACH_DAVINCI_EVM
-#define GPIO_nVBUS_DRV         87
+#define GPIO_nVBUS_DRV         144
 #endif
 
 #include "davinci.h"
@@ -329,7 +330,6 @@ static irqreturn_t davinci_interrupt(int irq, void *__hci)
                        mod_timer(&otg_workaround, jiffies + POLL_SECONDS * HZ);
                        WARNING("VBUS error workaround (delay coming)\n");
                } else if (is_host_enabled(musb) && drvvbus) {
-                       musb->is_active = 1;
                        MUSB_HST_MODE(musb);
                        musb->xceiv->default_a = 1;
                        musb->xceiv->state = OTG_STATE_A_WAIT_VRISE;
@@ -343,7 +343,9 @@ static irqreturn_t davinci_interrupt(int irq, void *__hci)
                        portstate(musb->port1_status &= ~USB_PORT_STAT_POWER);
                }
 
-               /* NOTE:  this must complete poweron within 100 msec */
+               /* NOTE:  this must complete poweron within 100 msec
+                * (OTG_TIME_A_WAIT_VRISE) but we don't check for that.
+                */
                davinci_source_power(musb, drvvbus, 0);
                DBG(2, "VBUS %s (%s)%s, devctl %02x\n",
                                drvvbus ? "on" : "off",
@@ -411,6 +413,21 @@ int __init musb_platform_init(struct musb *musb)
                __raw_writel(phy_ctrl, USB_PHY_CTRL);
        }
 
+       /* On dm355, the default-A state machine needs DRVVBUS control.
+        * If we won't be a host, there's no need to turn it on.
+        */
+       if (cpu_is_davinci_dm355()) {
+               u32     deepsleep = __raw_readl(DM355_DEEPSLEEP);
+
+               if (is_host_enabled(musb)) {
+                       deepsleep &= ~DRVVBUS_OVERRIDE;
+               } else {
+                       deepsleep &= ~DRVVBUS_FORCE;
+                       deepsleep |= DRVVBUS_OVERRIDE;
+               }
+               __raw_writel(deepsleep, DM355_DEEPSLEEP);
+       }
+
        /* reset the controller */
        musb_writel(tibase, DAVINCI_USB_CTRL_REG, 0x1);
 
@@ -437,6 +454,15 @@ int musb_platform_exit(struct musb *musb)
        if (is_host_enabled(musb))
                del_timer_sync(&otg_workaround);
 
+       /* force VBUS off */
+       if (cpu_is_davinci_dm355()) {
+               u32     deepsleep = __raw_readl(DM355_DEEPSLEEP);
+
+               deepsleep &= ~DRVVBUS_FORCE;
+               deepsleep |= DRVVBUS_OVERRIDE;
+               __raw_writel(deepsleep, DM355_DEEPSLEEP);
+       }
+
        davinci_source_power(musb, 0 /*off*/, 1);
 
        /* delay, to avoid problems with module reload */
index f3772ca..381d648 100644 (file)
@@ -38,7 +38,6 @@
 #include <linux/slab.h>
 #include <linux/list.h>
 #include <linux/interrupt.h>
-#include <linux/smp_lock.h>
 #include <linux/errno.h>
 #include <linux/timer.h>
 #include <linux/clk.h>
index 94a2a35..cf94511 100644 (file)
@@ -373,7 +373,7 @@ static void musb_advance_schedule(struct musb *musb, struct urb *urb,
                musb_save_toggle(qh, is_in, urb);
                break;
        case USB_ENDPOINT_XFER_ISOC:
-               if (urb->error_count)
+               if (status == 0 && urb->error_count)
                        status = -EXDEV;
                break;
        }
@@ -2235,13 +2235,30 @@ static void musb_h_stop(struct usb_hcd *hcd)
 static int musb_bus_suspend(struct usb_hcd *hcd)
 {
        struct musb     *musb = hcd_to_musb(hcd);
+       u8              devctl;
 
-       if (musb->xceiv->state == OTG_STATE_A_SUSPEND)
+       if (!is_host_active(musb))
                return 0;
 
-       if (is_host_active(musb) && musb->is_active) {
-               WARNING("trying to suspend as %s is_active=%i\n",
-                       otg_state_string(musb), musb->is_active);
+       switch (musb->xceiv->state) {
+       case OTG_STATE_A_SUSPEND:
+               return 0;
+       case OTG_STATE_A_WAIT_VRISE:
+               /* ID could be grounded even if there's no device
+                * on the other end of the cable.  NOTE that the
+                * A_WAIT_VRISE timers are messy with MUSB...
+                */
+               devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
+               if ((devctl & MUSB_DEVCTL_VBUS) == MUSB_DEVCTL_VBUS)
+                       musb->xceiv->state = OTG_STATE_A_WAIT_BCON;
+               break;
+       default:
+               break;
+       }
+
+       if (musb->is_active) {
+               WARNING("trying to suspend as %s while active\n",
+                               otg_state_string(musb));
                return -EBUSY;
        } else
                return 0;
index 69feeec..aa884d0 100644 (file)
@@ -59,18 +59,4 @@ config NOP_USB_XCEIV
         built-in with usb ip or which are autonomous and doesn't require any
         phy programming such as ISP1x04 etc.
 
-config USB_LANGWELL_OTG
-       tristate "Intel Langwell USB OTG dual-role support"
-       depends on USB && MRST
-       select USB_OTG
-       select USB_OTG_UTILS
-       help
-         Say Y here if you want to build Intel Langwell USB OTG
-         transciever driver in kernel. This driver implements role
-         switch between EHCI host driver and Langwell USB OTG
-         client driver.
-
-         To compile this driver as a module, choose M here: the
-         module will be called langwell_otg.
-
 endif # USB || OTG
index 6d1abdd..2081678 100644 (file)
@@ -9,7 +9,6 @@ obj-$(CONFIG_USB_OTG_UTILS)     += otg.o
 obj-$(CONFIG_USB_GPIO_VBUS)    += gpio_vbus.o
 obj-$(CONFIG_ISP1301_OMAP)     += isp1301_omap.o
 obj-$(CONFIG_TWL4030_USB)      += twl4030-usb.o
-obj-$(CONFIG_USB_LANGWELL_OTG) += langwell_otg.o
 obj-$(CONFIG_NOP_USB_XCEIV)    += nop-usb-xceiv.o
 
 ccflags-$(CONFIG_USB_DEBUG)    += -DDEBUG
diff --git a/drivers/usb/otg/langwell_otg.c b/drivers/usb/otg/langwell_otg.c
deleted file mode 100644 (file)
index 6f628d0..0000000
+++ /dev/null
@@ -1,1915 +0,0 @@
-/*
- * Intel Langwell USB OTG transceiver driver
- * Copyright (C) 2008 - 2009, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope 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 driver helps to switch Langwell OTG controller function between host
- * and peripheral. It works with EHCI driver and Langwell client controller
- * driver together.
- */
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/kernel.h>
-#include <linux/device.h>
-#include <linux/moduleparam.h>
-#include <linux/usb/ch9.h>
-#include <linux/usb/gadget.h>
-#include <linux/usb.h>
-#include <linux/usb/otg.h>
-#include <linux/notifier.h>
-#include <asm/ipc_defs.h>
-#include <linux/delay.h>
-#include "../core/hcd.h"
-
-#include <linux/usb/langwell_otg.h>
-
-#define        DRIVER_DESC             "Intel Langwell USB OTG transceiver driver"
-#define        DRIVER_VERSION          "3.0.0.32L.0002"
-
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_AUTHOR("Henry Yuan <hang.yuan@intel.com>, Hao Wu <hao.wu@intel.com>");
-MODULE_VERSION(DRIVER_VERSION);
-MODULE_LICENSE("GPL");
-
-static const char driver_name[] = "langwell_otg";
-
-static int langwell_otg_probe(struct pci_dev *pdev,
-                       const struct pci_device_id *id);
-static void langwell_otg_remove(struct pci_dev *pdev);
-static int langwell_otg_suspend(struct pci_dev *pdev, pm_message_t message);
-static int langwell_otg_resume(struct pci_dev *pdev);
-
-static int langwell_otg_set_host(struct otg_transceiver *otg,
-                               struct usb_bus *host);
-static int langwell_otg_set_peripheral(struct otg_transceiver *otg,
-                               struct usb_gadget *gadget);
-static int langwell_otg_start_srp(struct otg_transceiver *otg);
-
-static const struct pci_device_id pci_ids[] = {{
-       .class =        ((PCI_CLASS_SERIAL_USB << 8) | 0xfe),
-       .class_mask =   ~0,
-       .vendor =       0x8086,
-       .device =       0x0811,
-       .subvendor =    PCI_ANY_ID,
-       .subdevice =    PCI_ANY_ID,
-}, { /* end: all zeroes */ }
-};
-
-static struct pci_driver otg_pci_driver = {
-       .name =         (char *) driver_name,
-       .id_table =     pci_ids,
-
-       .probe =        langwell_otg_probe,
-       .remove =       langwell_otg_remove,
-
-       .suspend =      langwell_otg_suspend,
-       .resume =       langwell_otg_resume,
-};
-
-static const char *state_string(enum usb_otg_state state)
-{
-       switch (state) {
-       case OTG_STATE_A_IDLE:
-               return "a_idle";
-       case OTG_STATE_A_WAIT_VRISE:
-               return "a_wait_vrise";
-       case OTG_STATE_A_WAIT_BCON:
-               return "a_wait_bcon";
-       case OTG_STATE_A_HOST:
-               return "a_host";
-       case OTG_STATE_A_SUSPEND:
-               return "a_suspend";
-       case OTG_STATE_A_PERIPHERAL:
-               return "a_peripheral";
-       case OTG_STATE_A_WAIT_VFALL:
-               return "a_wait_vfall";
-       case OTG_STATE_A_VBUS_ERR:
-               return "a_vbus_err";
-       case OTG_STATE_B_IDLE:
-               return "b_idle";
-       case OTG_STATE_B_SRP_INIT:
-               return "b_srp_init";
-       case OTG_STATE_B_PERIPHERAL:
-               return "b_peripheral";
-       case OTG_STATE_B_WAIT_ACON:
-               return "b_wait_acon";
-       case OTG_STATE_B_HOST:
-               return "b_host";
-       default:
-               return "UNDEFINED";
-       }
-}
-
-/* HSM timers */
-static inline struct langwell_otg_timer *otg_timer_initializer
-(void (*function)(unsigned long), unsigned long expires, unsigned long data)
-{
-       struct langwell_otg_timer *timer;
-       timer = kmalloc(sizeof(struct langwell_otg_timer), GFP_KERNEL);
-       timer->function = function;
-       timer->expires = expires;
-       timer->data = data;
-       return timer;
-}
-
-static struct langwell_otg_timer *a_wait_vrise_tmr, *a_wait_bcon_tmr,
-       *a_aidl_bdis_tmr, *b_ase0_brst_tmr, *b_se0_srp_tmr, *b_srp_res_tmr,
-       *b_bus_suspend_tmr;
-
-static struct list_head active_timers;
-
-static struct langwell_otg *the_transceiver;
-
-/* host/client notify transceiver when event affects HNP state */
-void langwell_update_transceiver()
-{
-       otg_dbg("transceiver driver is notified\n");
-       queue_work(the_transceiver->qwork, &the_transceiver->work);
-}
-EXPORT_SYMBOL(langwell_update_transceiver);
-
-static int langwell_otg_set_host(struct otg_transceiver *otg,
-                                       struct usb_bus *host)
-{
-       otg->host = host;
-
-       return 0;
-}
-
-static int langwell_otg_set_peripheral(struct otg_transceiver *otg,
-                                       struct usb_gadget *gadget)
-{
-       otg->gadget = gadget;
-
-       return 0;
-}
-
-static int langwell_otg_set_power(struct otg_transceiver *otg,
-                               unsigned mA)
-{
-       return 0;
-}
-
-/* A-device drives vbus, controlled through PMIC CHRGCNTL register*/
-static void langwell_otg_drv_vbus(int on)
-{
-       struct ipc_pmic_reg_data        pmic_data = {0};
-       struct ipc_pmic_reg_data        battery_data;
-
-       /* Check if battery is attached or not */
-       battery_data.pmic_reg_data[0].register_address = 0xd2;
-       battery_data.ioc = 0;
-       battery_data.num_entries = 1;
-       if (ipc_pmic_register_read(&battery_data)) {
-               otg_dbg("Failed to read PMIC register 0xd2.\n");
-               return;
-       }
-
-       if ((battery_data.pmic_reg_data[0].value & 0x20) == 0) {
-               otg_dbg("no battery attached\n");
-               return;
-       }
-
-       /* Workaround for battery attachment issue */
-       if (battery_data.pmic_reg_data[0].value == 0x34) {
-               otg_dbg("battery \n");
-               return;
-       }
-
-       otg_dbg("battery attached\n");
-
-       pmic_data.ioc = 0;
-       pmic_data.pmic_reg_data[0].register_address = 0xD4;
-       pmic_data.num_entries = 1;
-       if (on)
-               pmic_data.pmic_reg_data[0].value = 0x20;
-       else
-               pmic_data.pmic_reg_data[0].value = 0xc0;
-
-       if (ipc_pmic_register_write(&pmic_data, TRUE))
-               otg_dbg("Failed to write PMIC.\n");
-
-}
-
-/* charge vbus or discharge vbus through a resistor to ground */
-static void langwell_otg_chrg_vbus(int on)
-{
-
-       u32     val;
-
-       val = readl(the_transceiver->regs + CI_OTGSC);
-
-       if (on)
-               writel((val & ~OTGSC_INTSTS_MASK) | OTGSC_VC,
-                               the_transceiver->regs + CI_OTGSC);
-       else
-               writel((val & ~OTGSC_INTSTS_MASK) | OTGSC_VD,
-                               the_transceiver->regs + CI_OTGSC);
-
-}
-
-/* Start SRP */
-static int langwell_otg_start_srp(struct otg_transceiver *otg)
-{
-       u32     val;
-
-       otg_dbg("Start SRP ->\n");
-
-       val = readl(the_transceiver->regs + CI_OTGSC);
-
-       writel((val & ~OTGSC_INTSTS_MASK) | OTGSC_HADP,
-               the_transceiver->regs + CI_OTGSC);
-
-       /* Check if the data plus is finished or not */
-       msleep(8);
-       val = readl(the_transceiver->regs + CI_OTGSC);
-       if (val & (OTGSC_HADP | OTGSC_DP))
-               otg_dbg("DataLine SRP Error\n");
-
-       /* FIXME: VBus SRP */
-
-       return 0;
-}
-
-
-/* stop SOF via bus_suspend */
-static void langwell_otg_loc_sof(int on)
-{
-       struct usb_hcd  *hcd;
-       int             err;
-
-       otg_dbg("loc_sof -> %d\n", on);
-
-       hcd = bus_to_hcd(the_transceiver->otg.host);
-       if (on)
-               err = hcd->driver->bus_resume(hcd);
-       else
-               err = hcd->driver->bus_suspend(hcd);
-
-       if (err)
-               otg_dbg("Failed to resume/suspend bus - %d\n", err);
-}
-
-static void langwell_otg_phy_low_power(int on)
-{
-       u32     val;
-
-       otg_dbg("phy low power mode-> %d\n", on);
-
-       val = readl(the_transceiver->regs + CI_HOSTPC1);
-       if (on)
-               writel(val | HOSTPC1_PHCD, the_transceiver->regs + CI_HOSTPC1);
-       else
-               writel(val & ~HOSTPC1_PHCD, the_transceiver->regs + CI_HOSTPC1);
-}
-
-/* Enable/Disable OTG interrupt */
-static void langwell_otg_intr(int on)
-{
-       u32 val;
-
-       otg_dbg("interrupt -> %d\n", on);
-
-       val = readl(the_transceiver->regs + CI_OTGSC);
-       if (on) {
-               val = val | (OTGSC_INTEN_MASK | OTGSC_IDPU);
-               writel(val, the_transceiver->regs + CI_OTGSC);
-       } else {
-               val = val & ~(OTGSC_INTEN_MASK | OTGSC_IDPU);
-               writel(val, the_transceiver->regs + CI_OTGSC);
-       }
-}
-
-/* set HAAR: Hardware Assist Auto-Reset */
-static void langwell_otg_HAAR(int on)
-{
-       u32     val;
-
-       otg_dbg("HAAR -> %d\n", on);
-
-       val = readl(the_transceiver->regs + CI_OTGSC);
-       if (on)
-               writel((val & ~OTGSC_INTSTS_MASK) | OTGSC_HAAR,
-                               the_transceiver->regs + CI_OTGSC);
-       else
-               writel((val & ~OTGSC_INTSTS_MASK) & ~OTGSC_HAAR,
-                               the_transceiver->regs + CI_OTGSC);
-}
-
-/* set HABA: Hardware Assist B-Disconnect to A-Connect */
-static void langwell_otg_HABA(int on)
-{
-       u32     val;
-
-       otg_dbg("HABA -> %d\n", on);
-
-       val = readl(the_transceiver->regs + CI_OTGSC);
-       if (on)
-               writel((val & ~OTGSC_INTSTS_MASK) | OTGSC_HABA,
-                               the_transceiver->regs + CI_OTGSC);
-       else
-               writel((val & ~OTGSC_INTSTS_MASK) & ~OTGSC_HABA,
-                               the_transceiver->regs + CI_OTGSC);
-}
-
-static int langwell_otg_check_se0_srp(int on)
-{
-       u32 val;
-
-       int delay_time = TB_SE0_SRP * 10; /* step is 100us */
-
-       otg_dbg("check_se0_srp -> \n");
-
-       do {
-               udelay(100);
-               if (!delay_time--)
-                       break;
-               val = readl(the_transceiver->regs + CI_PORTSC1);
-               val &= PORTSC_LS;
-       } while (!val);
-
-       otg_dbg("check_se0_srp <- \n");
-       return val;
-}
-
-/* The timeout callback function to set time out bit */
-static void set_tmout(unsigned long indicator)
-{
-       *(int *)indicator = 1;
-}
-
-void langwell_otg_nsf_msg(unsigned long indicator)
-{
-       switch (indicator) {
-       case 2:
-       case 4:
-       case 6:
-       case 7:
-               printk(KERN_ERR "OTG:NSF-%lu - deivce not responding\n",
-                               indicator);
-               break;
-       case 3:
-               printk(KERN_ERR "OTG:NSF-%lu - deivce not supported\n",
-                               indicator);
-               break;
-       default:
-               printk(KERN_ERR "Do not have this kind of NSF\n");
-               break;
-       }
-}
-
-/* Initialize timers */
-static void langwell_otg_init_timers(struct otg_hsm *hsm)
-{
-       /* HSM used timers */
-       a_wait_vrise_tmr = otg_timer_initializer(&set_tmout, TA_WAIT_VRISE,
-                               (unsigned long)&hsm->a_wait_vrise_tmout);
-       a_wait_bcon_tmr = otg_timer_initializer(&set_tmout, TA_WAIT_BCON,
-                               (unsigned long)&hsm->a_wait_bcon_tmout);
-       a_aidl_bdis_tmr = otg_timer_initializer(&set_tmout, TA_AIDL_BDIS,
-                               (unsigned long)&hsm->a_aidl_bdis_tmout);
-       b_ase0_brst_tmr = otg_timer_initializer(&set_tmout, TB_ASE0_BRST,
-                               (unsigned long)&hsm->b_ase0_brst_tmout);
-       b_se0_srp_tmr = otg_timer_initializer(&set_tmout, TB_SE0_SRP,
-                               (unsigned long)&hsm->b_se0_srp);
-       b_srp_res_tmr = otg_timer_initializer(&set_tmout, TB_SRP_RES,
-                               (unsigned long)&hsm->b_srp_res_tmout);
-       b_bus_suspend_tmr = otg_timer_initializer(&set_tmout, TB_BUS_SUSPEND,
-                               (unsigned long)&hsm->b_bus_suspend_tmout);
-}
-
-/* Free timers */
-static void langwell_otg_free_timers(void)
-{
-       kfree(a_wait_vrise_tmr);
-       kfree(a_wait_bcon_tmr);
-       kfree(a_aidl_bdis_tmr);
-       kfree(b_ase0_brst_tmr);
-       kfree(b_se0_srp_tmr);
-       kfree(b_srp_res_tmr);
-       kfree(b_bus_suspend_tmr);
-}
-
-/* Add timer to timer list */
-static void langwell_otg_add_timer(void *gtimer)
-{
-       struct langwell_otg_timer *timer = (struct langwell_otg_timer *)gtimer;
-       struct langwell_otg_timer *tmp_timer;
-       u32     val32;
-
-       /* Check if the timer is already in the active list,
-        * if so update timer count
-        */
-       list_for_each_entry(tmp_timer, &active_timers, list)
-               if (tmp_timer == timer) {
-                       timer->count = timer->expires;
-                       return;
-               }
-       timer->count = timer->expires;
-
-       if (list_empty(&active_timers)) {
-               val32 = readl(the_transceiver->regs + CI_OTGSC);
-               writel(val32 | OTGSC_1MSE, the_transceiver->regs + CI_OTGSC);
-       }
-
-       list_add_tail(&timer->list, &active_timers);
-}
-
-/* Remove timer from the timer list; clear timeout status */
-static void langwell_otg_del_timer(void *gtimer)
-{
-       struct langwell_otg_timer *timer = (struct langwell_otg_timer *)gtimer;
-       struct langwell_otg_timer *tmp_timer, *del_tmp;
-       u32 val32;
-
-       list_for_each_entry_safe(tmp_timer, del_tmp, &active_timers, list)
-               if (tmp_timer == timer)
-                       list_del(&timer->list);
-
-       if (list_empty(&active_timers)) {
-               val32 = readl(the_transceiver->regs + CI_OTGSC);
-               writel(val32 & ~OTGSC_1MSE, the_transceiver->regs + CI_OTGSC);
-       }
-}
-
-/* Reduce timer count by 1, and find timeout conditions.*/
-static int langwell_otg_tick_timer(u32 *int_sts)
-{
-       struct langwell_otg_timer *tmp_timer, *del_tmp;
-       int expired = 0;
-
-       list_for_each_entry_safe(tmp_timer, del_tmp, &active_timers, list) {
-               tmp_timer->count--;
-               /* check if timer expires */
-               if (!tmp_timer->count) {
-                       list_del(&tmp_timer->list);
-                       tmp_timer->function(tmp_timer->data);
-                       expired = 1;
-               }
-       }
-
-       if (list_empty(&active_timers)) {
-               otg_dbg("tick timer: disable 1ms int\n");
-               *int_sts = *int_sts & ~OTGSC_1MSE;
-       }
-       return expired;
-}
-
-static void reset_otg(void)
-{
-       u32     val;
-       int     delay_time = 1000;
-
-       otg_dbg("reseting OTG controller ...\n");
-       val = readl(the_transceiver->regs + CI_USBCMD);
-       writel(val | USBCMD_RST, the_transceiver->regs + CI_USBCMD);
-       do {
-               udelay(100);
-               if (!delay_time--)
-                       otg_dbg("reset timeout\n");
-               val = readl(the_transceiver->regs + CI_USBCMD);
-               val &= USBCMD_RST;
-       } while (val != 0);
-       otg_dbg("reset done.\n");
-}
-
-static void set_host_mode(void)
-{
-       u32     val;
-
-       reset_otg();
-       val = readl(the_transceiver->regs + CI_USBMODE);
-       val = (val & (~USBMODE_CM)) | USBMODE_HOST;
-       writel(val, the_transceiver->regs + CI_USBMODE);
-}
-
-static void set_client_mode(void)
-{
-       u32     val;
-
-       reset_otg();
-       val = readl(the_transceiver->regs + CI_USBMODE);
-       val = (val & (~USBMODE_CM)) | USBMODE_DEVICE;
-       writel(val, the_transceiver->regs + CI_USBMODE);
-}
-
-static void init_hsm(void)
-{
-       struct langwell_otg     *langwell = the_transceiver;
-       u32                     val32;
-
-       /* read OTGSC after reset */
-       val32 = readl(langwell->regs + CI_OTGSC);
-       otg_dbg("%s: OTGSC init value = 0x%x\n", __func__, val32);
-
-       /* set init state */
-       if (val32 & OTGSC_ID) {
-               langwell->hsm.id = 1;
-               langwell->otg.default_a = 0;
-               set_client_mode();
-               langwell->otg.state = OTG_STATE_B_IDLE;
-               langwell_otg_drv_vbus(0);
-       } else {
-               langwell->hsm.id = 0;
-               langwell->otg.default_a = 1;
-               set_host_mode();
-               langwell->otg.state = OTG_STATE_A_IDLE;
-       }
-
-       /* set session indicator */
-       if (val32 & OTGSC_BSE)
-               langwell->hsm.b_sess_end = 1;
-       if (val32 & OTGSC_BSV)
-               langwell->hsm.b_sess_vld = 1;
-       if (val32 & OTGSC_ASV)
-               langwell->hsm.a_sess_vld = 1;
-       if (val32 & OTGSC_AVV)
-               langwell->hsm.a_vbus_vld = 1;
-
-       /* defautly power the bus */
-       langwell->hsm.a_bus_req = 1;
-       langwell->hsm.a_bus_drop = 0;
-       /* defautly don't request bus as B device */
-       langwell->hsm.b_bus_req = 0;
-       /* no system error */
-       langwell->hsm.a_clr_err = 0;
-}
-
-static irqreturn_t otg_dummy_irq(int irq, void *_dev)
-{
-       void __iomem    *reg_base = _dev;
-       u32     val;
-       u32     int_mask = 0;
-
-       val = readl(reg_base + CI_USBMODE);
-       if ((val & USBMODE_CM) != USBMODE_DEVICE)
-               return IRQ_NONE;
-
-       val = readl(reg_base + CI_USBSTS);
-       int_mask = val & INTR_DUMMY_MASK;
-
-       if (int_mask == 0)
-               return IRQ_NONE;
-
-       /* clear hsm.b_conn here since host driver can't detect it
-       *  otg_dummy_irq called means B-disconnect happened.
-       */
-       if (the_transceiver->hsm.b_conn) {
-               the_transceiver->hsm.b_conn = 0;
-               if (spin_trylock(&the_transceiver->wq_lock)) {
-                       queue_work(the_transceiver->qwork,
-                               &the_transceiver->work);
-                       spin_unlock(&the_transceiver->wq_lock);
-               }
-       }
-       /* Clear interrupts */
-       writel(int_mask, reg_base + CI_USBSTS);
-       return IRQ_HANDLED;
-}
-
-static irqreturn_t otg_irq(int irq, void *_dev)
-{
-       struct  langwell_otg *langwell = _dev;
-       u32     int_sts, int_en;
-       u32     int_mask = 0;
-       int     flag = 0;
-
-       int_sts = readl(langwell->regs + CI_OTGSC);
-       int_en = (int_sts & OTGSC_INTEN_MASK) >> 8;
-       int_mask = int_sts & int_en;
-       if (int_mask == 0)
-               return IRQ_NONE;
-
-       if (int_mask & OTGSC_IDIS) {
-               otg_dbg("%s: id change int\n", __func__);
-               langwell->hsm.id = (int_sts & OTGSC_ID) ? 1 : 0;
-               flag = 1;
-       }
-       if (int_mask & OTGSC_DPIS) {
-               otg_dbg("%s: data pulse int\n", __func__);
-               langwell->hsm.a_srp_det = (int_sts & OTGSC_DPS) ? 1 : 0;
-               flag = 1;
-       }
-       if (int_mask & OTGSC_BSEIS) {
-               otg_dbg("%s: b session end int\n", __func__);
-               langwell->hsm.b_sess_end = (int_sts & OTGSC_BSE) ? 1 : 0;
-               flag = 1;
-       }
-       if (int_mask & OTGSC_BSVIS) {
-               otg_dbg("%s: b session valid int\n", __func__);
-               langwell->hsm.b_sess_vld = (int_sts & OTGSC_BSV) ? 1 : 0;
-               flag = 1;
-       }
-       if (int_mask & OTGSC_ASVIS) {
-               otg_dbg("%s: a session valid int\n", __func__);
-               langwell->hsm.a_sess_vld = (int_sts & OTGSC_ASV) ? 1 : 0;
-               flag = 1;
-       }
-       if (int_mask & OTGSC_AVVIS) {
-               otg_dbg("%s: a vbus valid int\n", __func__);
-               langwell->hsm.a_vbus_vld = (int_sts & OTGSC_AVV) ? 1 : 0;
-               flag = 1;
-       }
-
-       if (int_mask & OTGSC_1MSS) {
-               /* need to schedule otg_work if any timer is expired */
-               if (langwell_otg_tick_timer(&int_sts))
-                       flag = 1;
-       }
-
-       writel((int_sts & ~OTGSC_INTSTS_MASK) | int_mask,
-                       langwell->regs + CI_OTGSC);
-       if (flag)
-               queue_work(langwell->qwork, &langwell->work);
-
-       return IRQ_HANDLED;
-}
-
-static void langwell_otg_work(struct work_struct *work)
-{
-       struct langwell_otg *langwell = container_of(work,
-                                       struct langwell_otg, work);
-       int     retval;
-
-       otg_dbg("%s: old state = %s\n", __func__,
-                       state_string(langwell->otg.state));
-
-       switch (langwell->otg.state) {
-       case OTG_STATE_UNDEFINED:
-       case OTG_STATE_B_IDLE:
-               if (!langwell->hsm.id) {
-                       langwell_otg_del_timer(b_srp_res_tmr);
-                       langwell->otg.default_a = 1;
-                       langwell->hsm.a_srp_det = 0;
-
-                       langwell_otg_chrg_vbus(0);
-                       langwell_otg_drv_vbus(0);
-
-                       set_host_mode();
-                       langwell->otg.state = OTG_STATE_A_IDLE;
-                       queue_work(langwell->qwork, &langwell->work);
-               } else if (langwell->hsm.b_srp_res_tmout) {
-                       langwell->hsm.b_srp_res_tmout = 0;
-                       langwell->hsm.b_bus_req = 0;
-                       langwell_otg_nsf_msg(6);
-               } else if (langwell->hsm.b_sess_vld) {
-                       langwell_otg_del_timer(b_srp_res_tmr);
-                       langwell->hsm.b_sess_end = 0;
-                       langwell->hsm.a_bus_suspend = 0;
-
-                       langwell_otg_chrg_vbus(0);
-                       if (langwell->client_ops) {
-                               langwell->client_ops->resume(langwell->pdev);
-                               langwell->otg.state = OTG_STATE_B_PERIPHERAL;
-                       } else
-                               otg_dbg("client driver not loaded.\n");
-
-               } else if (langwell->hsm.b_bus_req &&
-                               (langwell->hsm.b_sess_end)) {
-                       /* workaround for b_se0_srp detection */
-                       retval = langwell_otg_check_se0_srp(0);
-                       if (retval) {
-                               langwell->hsm.b_bus_req = 0;
-                               otg_dbg("LS is not SE0, try again later\n");
-                       } else {
-                               /* Start SRP */
-                               langwell_otg_start_srp(&langwell->otg);
-                               langwell_otg_add_timer(b_srp_res_tmr);
-                       }
-               }
-               break;
-       case OTG_STATE_B_SRP_INIT:
-               if (!langwell->hsm.id) {
-                       langwell->otg.default_a = 1;
-                       langwell->hsm.a_srp_det = 0;
-
-                       langwell_otg_drv_vbus(0);
-                       langwell_otg_chrg_vbus(0);
-
-                       langwell->otg.state = OTG_STATE_A_IDLE;
-                       queue_work(langwell->qwork, &langwell->work);
-               } else if (langwell->hsm.b_sess_vld) {
-                       langwell_otg_chrg_vbus(0);
-                       if (langwell->client_ops) {
-                               langwell->client_ops->resume(langwell->pdev);
-                               langwell->otg.state = OTG_STATE_B_PERIPHERAL;
-                       } else
-                               otg_dbg("client driver not loaded.\n");
-               }
-               break;
-       case OTG_STATE_B_PERIPHERAL:
-               if (!langwell->hsm.id) {
-                       langwell->otg.default_a = 1;
-                       langwell->hsm.a_srp_det = 0;
-
-                       langwell_otg_drv_vbus(0);
-                       langwell_otg_chrg_vbus(0);
-                       set_host_mode();
-
-                       if (langwell->client_ops) {
-                               langwell->client_ops->suspend(langwell->pdev,
-                                       PMSG_FREEZE);
-                       } else
-                               otg_dbg("client driver has been removed.\n");
-
-                       langwell->otg.state = OTG_STATE_A_IDLE;
-                       queue_work(langwell->qwork, &langwell->work);
-               } else if (!langwell->hsm.b_sess_vld) {
-                       langwell->hsm.b_hnp_enable = 0;
-
-                       if (langwell->client_ops) {
-                               langwell->client_ops->suspend(langwell->pdev,
-                                       PMSG_FREEZE);
-                       } else
-                               otg_dbg("client driver has been removed.\n");
-
-                       langwell->otg.state = OTG_STATE_B_IDLE;
-               } else if (langwell->hsm.b_bus_req && langwell->hsm.b_hnp_enable
-                       && langwell->hsm.a_bus_suspend) {
-
-                       if (langwell->client_ops) {
-                               langwell->client_ops->suspend(langwell->pdev,
-                                       PMSG_FREEZE);
-                       } else
-                               otg_dbg("client driver has been removed.\n");
-
-                       langwell_otg_HAAR(1);
-                       langwell->hsm.a_conn = 0;
-
-                       if (langwell->host_ops) {
-                               langwell->host_ops->probe(langwell->pdev,
-                                       langwell->host_ops->id_table);
-                               langwell->otg.state = OTG_STATE_B_WAIT_ACON;
-                       } else
-                               otg_dbg("host driver not loaded.\n");
-
-                       langwell->hsm.a_bus_resume = 0;
-                       langwell->hsm.b_ase0_brst_tmout = 0;
-                       langwell_otg_add_timer(b_ase0_brst_tmr);
-               }
-               break;
-
-       case OTG_STATE_B_WAIT_ACON:
-               if (!langwell->hsm.id) {
-                       langwell_otg_del_timer(b_ase0_brst_tmr);
-                       langwell->otg.default_a = 1;
-                       langwell->hsm.a_srp_det = 0;
-
-                       langwell_otg_drv_vbus(0);
-                       langwell_otg_chrg_vbus(0);
-                       set_host_mode();
-
-                       langwell_otg_HAAR(0);
-                       if (langwell->host_ops)
-                               langwell->host_ops->remove(langwell->pdev);
-                       else
-                               otg_dbg("host driver has been removed.\n");
-                       langwell->otg.state = OTG_STATE_A_IDLE;
-                       queue_work(langwell->qwork, &langwell->work);
-               } else if (!langwell->hsm.b_sess_vld) {
-                       langwell_otg_del_timer(b_ase0_brst_tmr);
-                       langwell->hsm.b_hnp_enable = 0;
-                       langwell->hsm.b_bus_req = 0;
-                       langwell_otg_chrg_vbus(0);
-                       langwell_otg_HAAR(0);
-
-                       if (langwell->host_ops)
-                               langwell->host_ops->remove(langwell->pdev);
-                       else
-                               otg_dbg("host driver has been removed.\n");
-                       langwell->otg.state = OTG_STATE_B_IDLE;
-               } else if (langwell->hsm.a_conn) {
-                       langwell_otg_del_timer(b_ase0_brst_tmr);
-                       langwell_otg_HAAR(0);
-                       langwell->otg.state = OTG_STATE_B_HOST;
-                       queue_work(langwell->qwork, &langwell->work);
-               } else if (langwell->hsm.a_bus_resume ||
-                               langwell->hsm.b_ase0_brst_tmout) {
-                       langwell_otg_del_timer(b_ase0_brst_tmr);
-                       langwell_otg_HAAR(0);
-                       langwell_otg_nsf_msg(7);
-
-                       if (langwell->host_ops)
-                               langwell->host_ops->remove(langwell->pdev);
-                       else
-                               otg_dbg("host driver has been removed.\n");
-
-                       langwell->hsm.a_bus_suspend = 0;
-                       langwell->hsm.b_bus_req = 0;
-
-                       if (langwell->client_ops)
-                               langwell->client_ops->resume(langwell->pdev);
-                       else
-                               otg_dbg("client driver not loaded.\n");
-
-                       langwell->otg.state = OTG_STATE_B_PERIPHERAL;
-               }
-               break;
-
-       case OTG_STATE_B_HOST:
-               if (!langwell->hsm.id) {
-                       langwell->otg.default_a = 1;
-                       langwell->hsm.a_srp_det = 0;
-
-                       langwell_otg_drv_vbus(0);
-                       langwell_otg_chrg_vbus(0);
-                       set_host_mode();
-                       if (langwell->host_ops)
-                               langwell->host_ops->remove(langwell->pdev);
-                       else
-                               otg_dbg("host driver has been removed.\n");
-                       langwell->otg.state = OTG_STATE_A_IDLE;
-                       queue_work(langwell->qwork, &langwell->work);
-               } else if (!langwell->hsm.b_sess_vld) {
-                       langwell->hsm.b_hnp_enable = 0;
-                       langwell->hsm.b_bus_req = 0;
-                       langwell_otg_chrg_vbus(0);
-                       if (langwell->host_ops)
-                               langwell->host_ops->remove(langwell->pdev);
-                       else
-                               otg_dbg("host driver has been removed.\n");
-                       langwell->otg.state = OTG_STATE_B_IDLE;
-               } else if ((!langwell->hsm.b_bus_req) ||
-                               (!langwell->hsm.a_conn)) {
-                       langwell->hsm.b_bus_req = 0;
-                       langwell_otg_loc_sof(0);
-                       if (langwell->host_ops)
-                               langwell->host_ops->remove(langwell->pdev);
-                       else
-                               otg_dbg("host driver has been removed.\n");
-
-                       langwell->hsm.a_bus_suspend = 0;
-
-                       if (langwell->client_ops)
-                               langwell->client_ops->resume(langwell->pdev);
-                       else
-                               otg_dbg("client driver not loaded.\n");
-
-                       langwell->otg.state = OTG_STATE_B_PERIPHERAL;
-               }
-               break;
-
-       case OTG_STATE_A_IDLE:
-               langwell->otg.default_a = 1;
-               if (langwell->hsm.id) {
-                       langwell->otg.default_a = 0;
-                       langwell->hsm.b_bus_req = 0;
-                       langwell_otg_drv_vbus(0);
-                       langwell_otg_chrg_vbus(0);
-
-                       langwell->otg.state = OTG_STATE_B_IDLE;
-                       queue_work(langwell->qwork, &langwell->work);
-               } else if (langwell->hsm.a_sess_vld) {
-                       langwell_otg_drv_vbus(1);
-                       langwell->hsm.a_srp_det = 1;
-                       langwell->hsm.a_wait_vrise_tmout = 0;
-                       langwell_otg_add_timer(a_wait_vrise_tmr);
-                       langwell->otg.state = OTG_STATE_A_WAIT_VRISE;
-                       queue_work(langwell->qwork, &langwell->work);
-               } else if (!langwell->hsm.a_bus_drop &&
-                       (langwell->hsm.a_srp_det || langwell->hsm.a_bus_req)) {
-                       langwell_otg_drv_vbus(1);
-                       langwell->hsm.a_wait_vrise_tmout = 0;
-                       langwell_otg_add_timer(a_wait_vrise_tmr);
-                       langwell->otg.state = OTG_STATE_A_WAIT_VRISE;
-                       queue_work(langwell->qwork, &langwell->work);
-               }
-               break;
-       case OTG_STATE_A_WAIT_VRISE:
-               if (langwell->hsm.id) {
-                       langwell_otg_del_timer(a_wait_vrise_tmr);
-                       langwell->hsm.b_bus_req = 0;
-                       langwell->otg.default_a = 0;
-                       langwell_otg_drv_vbus(0);
-                       langwell->otg.state = OTG_STATE_B_IDLE;
-               } else if (langwell->hsm.a_vbus_vld) {
-                       langwell_otg_del_timer(a_wait_vrise_tmr);
-                       if (langwell->host_ops)
-                               langwell->host_ops->probe(langwell->pdev,
-                                               langwell->host_ops->id_table);
-                       else
-                               otg_dbg("host driver not loaded.\n");
-                       langwell->hsm.b_conn = 0;
-                       langwell->hsm.a_set_b_hnp_en = 0;
-                       langwell->hsm.a_wait_bcon_tmout = 0;
-                       langwell_otg_add_timer(a_wait_bcon_tmr);
-                       langwell->otg.state = OTG_STATE_A_WAIT_BCON;
-               } else if (langwell->hsm.a_wait_vrise_tmout) {
-                       if (langwell->hsm.a_vbus_vld) {
-                               if (langwell->host_ops)
-                                       langwell->host_ops->probe(
-                                               langwell->pdev,
-                                               langwell->host_ops->id_table);
-                               else
-                                       otg_dbg("host driver not loaded.\n");
-                               langwell->hsm.b_conn = 0;
-                               langwell->hsm.a_set_b_hnp_en = 0;
-                               langwell->hsm.a_wait_bcon_tmout = 0;
-                               langwell_otg_add_timer(a_wait_bcon_tmr);
-                               langwell->otg.state = OTG_STATE_A_WAIT_BCON;
-                       } else {
-                               langwell_otg_drv_vbus(0);
-                               langwell->otg.state = OTG_STATE_A_VBUS_ERR;
-                       }
-               }
-               break;
-       case OTG_STATE_A_WAIT_BCON:
-               if (langwell->hsm.id) {
-                       langwell_otg_del_timer(a_wait_bcon_tmr);
-
-                       langwell->otg.default_a = 0;
-                       langwell->hsm.b_bus_req = 0;
-                       if (langwell->host_ops)
-                               langwell->host_ops->remove(langwell->pdev);
-                       else
-                               otg_dbg("host driver has been removed.\n");
-                       langwell_otg_drv_vbus(0);
-                       langwell->otg.state = OTG_STATE_B_IDLE;
-                       queue_work(langwell->qwork, &langwell->work);
-               } else if (!langwell->hsm.a_vbus_vld) {
-                       langwell_otg_del_timer(a_wait_bcon_tmr);
-
-                       if (langwell->host_ops)
-                               langwell->host_ops->remove(langwell->pdev);
-                       else
-                               otg_dbg("host driver has been removed.\n");
-                       langwell_otg_drv_vbus(0);
-                       langwell->otg.state = OTG_STATE_A_VBUS_ERR;
-               } else if (langwell->hsm.a_bus_drop ||
-                               (langwell->hsm.a_wait_bcon_tmout &&
-                               !langwell->hsm.a_bus_req)) {
-                       langwell_otg_del_timer(a_wait_bcon_tmr);
-
-                       if (langwell->host_ops)
-                               langwell->host_ops->remove(langwell->pdev);
-                       else
-                               otg_dbg("host driver has been removed.\n");
-                       langwell_otg_drv_vbus(0);
-                       langwell->otg.state = OTG_STATE_A_WAIT_VFALL;
-               } else if (langwell->hsm.b_conn) {
-                       langwell_otg_del_timer(a_wait_bcon_tmr);
-
-                       langwell->hsm.a_suspend_req = 0;
-                       langwell->otg.state = OTG_STATE_A_HOST;
-                       if (!langwell->hsm.a_bus_req &&
-                               langwell->hsm.a_set_b_hnp_en) {
-                               /* It is not safe enough to do a fast
-                                * transistion from A_WAIT_BCON to
-                                * A_SUSPEND */
-                               msleep(10000);
-                               if (langwell->hsm.a_bus_req)
-                                       break;
-
-                               if (request_irq(langwell->pdev->irq,
-                                       otg_dummy_irq, IRQF_SHARED,
-                                       driver_name, langwell->regs) != 0) {
-                                       otg_dbg("request interrupt %d fail\n",
-                                       langwell->pdev->irq);
-                               }
-
-                               langwell_otg_HABA(1);
-                               langwell->hsm.b_bus_resume = 0;
-                               langwell->hsm.a_aidl_bdis_tmout = 0;
-                               langwell_otg_add_timer(a_aidl_bdis_tmr);
-
-                               langwell_otg_loc_sof(0);
-                               langwell->otg.state = OTG_STATE_A_SUSPEND;
-                       } else if (!langwell->hsm.a_bus_req &&
-                               !langwell->hsm.a_set_b_hnp_en) {
-                               struct pci_dev *pdev = langwell->pdev;
-                               if (langwell->host_ops)
-                                       langwell->host_ops->remove(pdev);
-                               else
-                                       otg_dbg("host driver removed.\n");
-                               langwell_otg_drv_vbus(0);
-                               langwell->otg.state = OTG_STATE_A_WAIT_VFALL;
-                       }
-               }
-               break;
-       case OTG_STATE_A_HOST:
-               if (langwell->hsm.id) {
-                       langwell->otg.default_a = 0;
-                       langwell->hsm.b_bus_req = 0;
-                       if (langwell->host_ops)
-                               langwell->host_ops->remove(langwell->pdev);
-                       else
-                               otg_dbg("host driver has been removed.\n");
-                       langwell_otg_drv_vbus(0);
-                       langwell->otg.state = OTG_STATE_B_IDLE;
-                       queue_work(langwell->qwork, &langwell->work);
-               } else if (langwell->hsm.a_bus_drop ||
-               (!langwell->hsm.a_set_b_hnp_en && !langwell->hsm.a_bus_req)) {
-                       if (langwell->host_ops)
-                               langwell->host_ops->remove(langwell->pdev);
-                       else
-                               otg_dbg("host driver has been removed.\n");
-                       langwell_otg_drv_vbus(0);
-                       langwell->otg.state = OTG_STATE_A_WAIT_VFALL;
-               } else if (!langwell->hsm.a_vbus_vld) {
-                       if (langwell->host_ops)
-                               langwell->host_ops->remove(langwell->pdev);
-                       else
-                               otg_dbg("host driver has been removed.\n");
-                       langwell_otg_drv_vbus(0);
-                       langwell->otg.state = OTG_STATE_A_VBUS_ERR;
-               } else if (langwell->hsm.a_set_b_hnp_en
-                               && !langwell->hsm.a_bus_req) {
-                       /* Set HABA to enable hardware assistance to signal
-                        *  A-connect after receiver B-disconnect. Hardware
-                        *  will then set client mode and enable URE, SLE and
-                        *  PCE after the assistance. otg_dummy_irq is used to
-                        *  clean these ints when client driver is not resumed.
-                        */
-                       if (request_irq(langwell->pdev->irq,
-                               otg_dummy_irq, IRQF_SHARED, driver_name,
-                               langwell->regs) != 0) {
-                               otg_dbg("request interrupt %d failed\n",
-                                               langwell->pdev->irq);
-                       }
-
-                       /* set HABA */
-                       langwell_otg_HABA(1);
-                       langwell->hsm.b_bus_resume = 0;
-                       langwell->hsm.a_aidl_bdis_tmout = 0;
-                       langwell_otg_add_timer(a_aidl_bdis_tmr);
-                       langwell_otg_loc_sof(0);
-                       langwell->otg.state = OTG_STATE_A_SUSPEND;
-               } else if (!langwell->hsm.b_conn || !langwell->hsm.a_bus_req) {
-                       langwell->hsm.a_wait_bcon_tmout = 0;
-                       langwell->hsm.a_set_b_hnp_en = 0;
-                       langwell_otg_add_timer(a_wait_bcon_tmr);
-                       langwell->otg.state = OTG_STATE_A_WAIT_BCON;
-               }
-               break;
-       case OTG_STATE_A_SUSPEND:
-               if (langwell->hsm.id) {
-                       langwell_otg_del_timer(a_aidl_bdis_tmr);
-                       langwell_otg_HABA(0);
-                       free_irq(langwell->pdev->irq, langwell->regs);
-                       langwell->otg.default_a = 0;
-                       langwell->hsm.b_bus_req = 0;
-                       if (langwell->host_ops)
-                               langwell->host_ops->remove(langwell->pdev);
-                       else
-                               otg_dbg("host driver has been removed.\n");
-                       langwell_otg_drv_vbus(0);
-                       langwell->otg.state = OTG_STATE_B_IDLE;
-                       queue_work(langwell->qwork, &langwell->work);
-               } else if (langwell->hsm.a_bus_req ||
-                               langwell->hsm.b_bus_resume) {
-                       langwell_otg_del_timer(a_aidl_bdis_tmr);
-                       langwell_otg_HABA(0);
-                       free_irq(langwell->pdev->irq, langwell->regs);
-                       langwell->hsm.a_suspend_req = 0;
-                       langwell_otg_loc_sof(1);
-                       langwell->otg.state = OTG_STATE_A_HOST;
-               } else if (langwell->hsm.a_aidl_bdis_tmout ||
-                               langwell->hsm.a_bus_drop) {
-                       langwell_otg_del_timer(a_aidl_bdis_tmr);
-                       langwell_otg_HABA(0);
-                       free_irq(langwell->pdev->irq, langwell->regs);
-                       if (langwell->host_ops)
-                               langwell->host_ops->remove(langwell->pdev);
-                       else
-                               otg_dbg("host driver has been removed.\n");
-                       langwell_otg_drv_vbus(0);
-                       langwell->otg.state = OTG_STATE_A_WAIT_VFALL;
-               } else if (!langwell->hsm.b_conn &&
-                               langwell->hsm.a_set_b_hnp_en) {
-                       langwell_otg_del_timer(a_aidl_bdis_tmr);
-                       langwell_otg_HABA(0);
-                       free_irq(langwell->pdev->irq, langwell->regs);
-
-                       if (langwell->host_ops)
-                               langwell->host_ops->remove(langwell->pdev);
-                       else
-                               otg_dbg("host driver has been removed.\n");
-
-                       langwell->hsm.b_bus_suspend = 0;
-                       langwell->hsm.b_bus_suspend_vld = 0;
-                       langwell->hsm.b_bus_suspend_tmout = 0;
-
-                       /* msleep(200); */
-                       if (langwell->client_ops)
-                               langwell->client_ops->resume(langwell->pdev);
-                       else
-                               otg_dbg("client driver not loaded.\n");
-
-                       langwell_otg_add_timer(b_bus_suspend_tmr);
-                       langwell->otg.state = OTG_STATE_A_PERIPHERAL;
-                       break;
-               } else if (!langwell->hsm.a_vbus_vld) {
-                       langwell_otg_del_timer(a_aidl_bdis_tmr);
-                       langwell_otg_HABA(0);
-                       free_irq(langwell->pdev->irq, langwell->regs);
-                       if (langwell->host_ops)
-                               langwell->host_ops->remove(langwell->pdev);
-                       else
-                               otg_dbg("host driver has been removed.\n");
-                       langwell_otg_drv_vbus(0);
-                       langwell->otg.state = OTG_STATE_A_VBUS_ERR;
-               }
-               break;
-       case OTG_STATE_A_PERIPHERAL:
-               if (langwell->hsm.id) {
-                       langwell_otg_del_timer(b_bus_suspend_tmr);
-                       langwell->otg.default_a = 0;
-                       langwell->hsm.b_bus_req = 0;
-                       if (langwell->client_ops)
-                               langwell->client_ops->suspend(langwell->pdev,
-                                       PMSG_FREEZE);
-                       else
-                               otg_dbg("client driver has been removed.\n");
-                       langwell_otg_drv_vbus(0);
-                       langwell->otg.state = OTG_STATE_B_IDLE;
-                       queue_work(langwell->qwork, &langwell->work);
-               } else if (!langwell->hsm.a_vbus_vld) {
-                       langwell_otg_del_timer(b_bus_suspend_tmr);
-                       if (langwell->client_ops)
-                               langwell->client_ops->suspend(langwell->pdev,
-                                       PMSG_FREEZE);
-                       else
-                               otg_dbg("client driver has been removed.\n");
-                       langwell_otg_drv_vbus(0);
-                       langwell->otg.state = OTG_STATE_A_VBUS_ERR;
-               } else if (langwell->hsm.a_bus_drop) {
-                       langwell_otg_del_timer(b_bus_suspend_tmr);
-                       if (langwell->client_ops)
-                               langwell->client_ops->suspend(langwell->pdev,
-                                       PMSG_FREEZE);
-                       else
-                               otg_dbg("client driver has been removed.\n");
-                       langwell_otg_drv_vbus(0);
-                       langwell->otg.state = OTG_STATE_A_WAIT_VFALL;
-               } else if (langwell->hsm.b_bus_suspend) {
-                       langwell_otg_del_timer(b_bus_suspend_tmr);
-                       if (langwell->client_ops)
-                               langwell->client_ops->suspend(langwell->pdev,
-                                       PMSG_FREEZE);
-                       else
-                               otg_dbg("client driver has been removed.\n");
-
-                       if (langwell->host_ops)
-                               langwell->host_ops->probe(langwell->pdev,
-                                               langwell->host_ops->id_table);
-                       else
-                               otg_dbg("host driver not loaded.\n");
-                       langwell->hsm.a_set_b_hnp_en = 0;
-                       langwell->hsm.a_wait_bcon_tmout = 0;
-                       langwell_otg_add_timer(a_wait_bcon_tmr);
-                       langwell->otg.state = OTG_STATE_A_WAIT_BCON;
-               } else if (langwell->hsm.b_bus_suspend_tmout) {
-                       u32     val;
-                       val = readl(langwell->regs + CI_PORTSC1);
-                       if (!(val & PORTSC_SUSP))
-                               break;
-                       if (langwell->client_ops)
-                               langwell->client_ops->suspend(langwell->pdev,
-                                               PMSG_FREEZE);
-                       else
-                               otg_dbg("client driver has been removed.\n");
-                       if (langwell->host_ops)
-                               langwell->host_ops->probe(langwell->pdev,
-                                               langwell->host_ops->id_table);
-                       else
-                               otg_dbg("host driver not loaded.\n");
-                       langwell->hsm.a_set_b_hnp_en = 0;
-                       langwell->hsm.a_wait_bcon_tmout = 0;
-                       langwell_otg_add_timer(a_wait_bcon_tmr);
-                       langwell->otg.state = OTG_STATE_A_WAIT_BCON;
-               }
-               break;
-       case OTG_STATE_A_VBUS_ERR:
-               if (langwell->hsm.id) {
-                       langwell->otg.default_a = 0;
-                       langwell->hsm.a_clr_err = 0;
-                       langwell->hsm.a_srp_det = 0;
-                       langwell->otg.state = OTG_STATE_B_IDLE;
-                       queue_work(langwell->qwork, &langwell->work);
-               } else if (langwell->hsm.a_clr_err) {
-                       langwell->hsm.a_clr_err = 0;
-                       langwell->hsm.a_srp_det = 0;
-                       reset_otg();
-                       init_hsm();
-                       if (langwell->otg.state == OTG_STATE_A_IDLE)
-                               queue_work(langwell->qwork, &langwell->work);
-               }
-               break;
-       case OTG_STATE_A_WAIT_VFALL:
-               if (langwell->hsm.id) {
-                       langwell->otg.default_a = 0;
-                       langwell->otg.state = OTG_STATE_B_IDLE;
-                       queue_work(langwell->qwork, &langwell->work);
-               } else if (langwell->hsm.a_bus_req) {
-                       langwell_otg_drv_vbus(1);
-                       langwell->hsm.a_wait_vrise_tmout = 0;
-                       langwell_otg_add_timer(a_wait_vrise_tmr);
-                       langwell->otg.state = OTG_STATE_A_WAIT_VRISE;
-               } else if (!langwell->hsm.a_sess_vld) {
-                       langwell->hsm.a_srp_det = 0;
-                       langwell_otg_drv_vbus(0);
-                       set_host_mode();
-                       langwell->otg.state = OTG_STATE_A_IDLE;
-               }
-               break;
-       default:
-               ;
-       }
-
-       otg_dbg("%s: new state = %s\n", __func__,
-                       state_string(langwell->otg.state));
-}
-
-       static ssize_t
-show_registers(struct device *_dev, struct device_attribute *attr, char *buf)
-{
-       struct langwell_otg *langwell;
-       char *next;
-       unsigned size;
-       unsigned t;
-
-       langwell = the_transceiver;
-       next = buf;
-       size = PAGE_SIZE;
-
-       t = scnprintf(next, size,
-               "\n"
-               "USBCMD = 0x%08x \n"
-               "USBSTS = 0x%08x \n"
-               "USBINTR = 0x%08x \n"
-               "ASYNCLISTADDR = 0x%08x \n"
-               "PORTSC1 = 0x%08x \n"
-               "HOSTPC1 = 0x%08x \n"
-               "OTGSC = 0x%08x \n"
-               "USBMODE = 0x%08x \n",
-               readl(langwell->regs + 0x30),
-               readl(langwell->regs + 0x34),
-               readl(langwell->regs + 0x38),
-               readl(langwell->regs + 0x48),
-               readl(langwell->regs + 0x74),
-               readl(langwell->regs + 0xb4),
-               readl(langwell->regs + 0xf4),
-               readl(langwell->regs + 0xf8)
-               );
-       size -= t;
-       next += t;
-
-       return PAGE_SIZE - size;
-}
-static DEVICE_ATTR(registers, S_IRUGO, show_registers, NULL);
-
-static ssize_t
-show_hsm(struct device *_dev, struct device_attribute *attr, char *buf)
-{
-       struct langwell_otg *langwell;
-       char *next;
-       unsigned size;
-       unsigned t;
-
-       langwell = the_transceiver;
-       next = buf;
-       size = PAGE_SIZE;
-
-       t = scnprintf(next, size,
-               "\n"
-               "current state = %s\n"
-               "a_bus_resume = \t%d\n"
-               "a_bus_suspend = \t%d\n"
-               "a_conn = \t%d\n"
-               "a_sess_vld = \t%d\n"
-               "a_srp_det = \t%d\n"
-               "a_vbus_vld = \t%d\n"
-               "b_bus_resume = \t%d\n"
-               "b_bus_suspend = \t%d\n"
-               "b_conn = \t%d\n"
-               "b_se0_srp = \t%d\n"
-               "b_sess_end = \t%d\n"
-               "b_sess_vld = \t%d\n"
-               "id = \t%d\n"
-               "a_set_b_hnp_en = \t%d\n"
-               "b_srp_done = \t%d\n"
-               "b_hnp_enable = \t%d\n"
-               "a_wait_vrise_tmout = \t%d\n"
-               "a_wait_bcon_tmout = \t%d\n"
-               "a_aidl_bdis_tmout = \t%d\n"
-               "b_ase0_brst_tmout = \t%d\n"
-               "a_bus_drop = \t%d\n"
-               "a_bus_req = \t%d\n"
-               "a_clr_err = \t%d\n"
-               "a_suspend_req = \t%d\n"
-               "b_bus_req = \t%d\n"
-               "b_bus_suspend_tmout = \t%d\n"
-               "b_bus_suspend_vld = \t%d\n",
-               state_string(langwell->otg.state),
-               langwell->hsm.a_bus_resume,
-               langwell->hsm.a_bus_suspend,
-               langwell->hsm.a_conn,
-               langwell->hsm.a_sess_vld,
-               langwell->hsm.a_srp_det,
-               langwell->hsm.a_vbus_vld,
-               langwell->hsm.b_bus_resume,
-               langwell->hsm.b_bus_suspend,
-               langwell->hsm.b_conn,
-               langwell->hsm.b_se0_srp,
-               langwell->hsm.b_sess_end,
-               langwell->hsm.b_sess_vld,
-               langwell->hsm.id,
-               langwell->hsm.a_set_b_hnp_en,
-               langwell->hsm.b_srp_done,
-               langwell->hsm.b_hnp_enable,
-               langwell->hsm.a_wait_vrise_tmout,
-               langwell->hsm.a_wait_bcon_tmout,
-               langwell->hsm.a_aidl_bdis_tmout,
-               langwell->hsm.b_ase0_brst_tmout,
-               langwell->hsm.a_bus_drop,
-               langwell->hsm.a_bus_req,
-               langwell->hsm.a_clr_err,
-               langwell->hsm.a_suspend_req,
-               langwell->hsm.b_bus_req,
-               langwell->hsm.b_bus_suspend_tmout,
-               langwell->hsm.b_bus_suspend_vld
-               );
-       size -= t;
-       next += t;
-
-       return PAGE_SIZE - size;
-}
-static DEVICE_ATTR(hsm, S_IRUGO, show_hsm, NULL);
-
-static ssize_t
-get_a_bus_req(struct device *dev, struct device_attribute *attr, char *buf)
-{
-       struct langwell_otg *langwell;
-       char *next;
-       unsigned size;
-       unsigned t;
-
-       langwell =  the_transceiver;
-       next = buf;
-       size = PAGE_SIZE;
-
-       t = scnprintf(next, size, "%d", langwell->hsm.a_bus_req);
-       size -= t;
-       next += t;
-
-       return PAGE_SIZE - size;
-}
-
-static ssize_t
-set_a_bus_req(struct device *dev, struct device_attribute *attr,
-               const char *buf, size_t count)
-{
-       struct langwell_otg *langwell;
-       langwell = the_transceiver;
-       if (!langwell->otg.default_a)
-               return -1;
-       if (count > 2)
-               return -1;
-
-       if (buf[0] == '0') {
-               langwell->hsm.a_bus_req = 0;
-               otg_dbg("a_bus_req = 0\n");
-       } else if (buf[0] == '1') {
-               /* If a_bus_drop is TRUE, a_bus_req can't be set */
-               if (langwell->hsm.a_bus_drop)
-                       return -1;
-               langwell->hsm.a_bus_req = 1;
-               otg_dbg("a_bus_req = 1\n");
-       }
-       if (spin_trylock(&langwell->wq_lock)) {
-               queue_work(langwell->qwork, &langwell->work);
-               spin_unlock(&langwell->wq_lock);
-       }
-       return count;
-}
-static DEVICE_ATTR(a_bus_req, S_IRUGO | S_IWUGO, get_a_bus_req, set_a_bus_req);
-
-static ssize_t
-get_a_bus_drop(struct device *dev, struct device_attribute *attr, char *buf)
-{
-       struct langwell_otg *langwell;
-       char *next;
-       unsigned size;
-       unsigned t;
-
-       langwell =  the_transceiver;
-       next = buf;
-       size = PAGE_SIZE;
-
-       t = scnprintf(next, size, "%d", langwell->hsm.a_bus_drop);
-       size -= t;
-       next += t;
-
-       return PAGE_SIZE - size;
-}
-
-static ssize_t
-set_a_bus_drop(struct device *dev, struct device_attribute *attr,
-               const char *buf, size_t count)
-{
-       struct langwell_otg *langwell;
-       langwell = the_transceiver;
-       if (!langwell->otg.default_a)
-               return -1;
-       if (count > 2)
-               return -1;
-
-       if (buf[0] == '0') {
-               langwell->hsm.a_bus_drop = 0;
-               otg_dbg("a_bus_drop = 0\n");
-       } else if (buf[0] == '1') {
-               langwell->hsm.a_bus_drop = 1;
-               langwell->hsm.a_bus_req = 0;
-               otg_dbg("a_bus_drop = 1, then a_bus_req = 0\n");
-       }
-       if (spin_trylock(&langwell->wq_lock)) {
-               queue_work(langwell->qwork, &langwell->work);
-               spin_unlock(&langwell->wq_lock);
-       }
-       return count;
-}
-static DEVICE_ATTR(a_bus_drop, S_IRUGO | S_IWUGO,
-       get_a_bus_drop, set_a_bus_drop);
-
-static ssize_t
-get_b_bus_req(struct device *dev, struct device_attribute *attr, char *buf)
-{
-       struct langwell_otg *langwell;
-       char *next;
-       unsigned size;
-       unsigned t;
-
-       langwell =  the_transceiver;
-       next = buf;
-       size = PAGE_SIZE;
-
-       t = scnprintf(next, size, "%d", langwell->hsm.b_bus_req);
-       size -= t;
-       next += t;
-
-       return PAGE_SIZE - size;
-}
-
-static ssize_t
-set_b_bus_req(struct device *dev, struct device_attribute *attr,
-               const char *buf, size_t count)
-{
-       struct langwell_otg *langwell;
-       langwell = the_transceiver;
-
-       if (langwell->otg.default_a)
-               return -1;
-
-       if (count > 2)
-               return -1;
-
-       if (buf[0] == '0') {
-               langwell->hsm.b_bus_req = 0;
-               otg_dbg("b_bus_req = 0\n");
-       } else if (buf[0] == '1') {
-               langwell->hsm.b_bus_req = 1;
-               otg_dbg("b_bus_req = 1\n");
-       }
-       if (spin_trylock(&langwell->wq_lock)) {
-               queue_work(langwell->qwork, &langwell->work);
-               spin_unlock(&langwell->wq_lock);
-       }
-       return count;
-}
-static DEVICE_ATTR(b_bus_req, S_IRUGO | S_IWUGO, get_b_bus_req, set_b_bus_req);
-
-static ssize_t
-set_a_clr_err(struct device *dev, struct device_attribute *attr,
-               const char *buf, size_t count)
-{
-       struct langwell_otg *langwell;
-       langwell = the_transceiver;
-
-       if (!langwell->otg.default_a)
-               return -1;
-       if (count > 2)
-               return -1;
-
-       if (buf[0] == '1') {
-               langwell->hsm.a_clr_err = 1;
-               otg_dbg("a_clr_err = 1\n");
-       }
-       if (spin_trylock(&langwell->wq_lock)) {
-               queue_work(langwell->qwork, &langwell->work);
-               spin_unlock(&langwell->wq_lock);
-       }
-       return count;
-}
-static DEVICE_ATTR(a_clr_err, S_IWUGO, NULL, set_a_clr_err);
-
-static struct attribute *inputs_attrs[] = {
-       &dev_attr_a_bus_req.attr,
-       &dev_attr_a_bus_drop.attr,
-       &dev_attr_b_bus_req.attr,
-       &dev_attr_a_clr_err.attr,
-       NULL,
-};
-
-static struct attribute_group debug_dev_attr_group = {
-       .name = "inputs",
-       .attrs = inputs_attrs,
-};
-
-int langwell_register_host(struct pci_driver *host_driver)
-{
-       int     ret = 0;
-
-       the_transceiver->host_ops = host_driver;
-       queue_work(the_transceiver->qwork, &the_transceiver->work);
-       otg_dbg("host controller driver is registered\n");
-
-       return ret;
-}
-EXPORT_SYMBOL(langwell_register_host);
-
-void langwell_unregister_host(struct pci_driver *host_driver)
-{
-       if (the_transceiver->host_ops)
-               the_transceiver->host_ops->remove(the_transceiver->pdev);
-       the_transceiver->host_ops = NULL;
-       the_transceiver->hsm.a_bus_drop = 1;
-       queue_work(the_transceiver->qwork, &the_transceiver->work);
-       otg_dbg("host controller driver is unregistered\n");
-}
-EXPORT_SYMBOL(langwell_unregister_host);
-
-int langwell_register_peripheral(struct pci_driver *client_driver)
-{
-       int     ret = 0;
-
-       if (client_driver)
-               ret = client_driver->probe(the_transceiver->pdev,
-                               client_driver->id_table);
-       if (!ret) {
-               the_transceiver->client_ops = client_driver;
-               queue_work(the_transceiver->qwork, &the_transceiver->work);
-               otg_dbg("client controller driver is registered\n");
-       }
-
-       return ret;
-}
-EXPORT_SYMBOL(langwell_register_peripheral);
-
-void langwell_unregister_peripheral(struct pci_driver *client_driver)
-{
-       if (the_transceiver->client_ops)
-               the_transceiver->client_ops->remove(the_transceiver->pdev);
-       the_transceiver->client_ops = NULL;
-       the_transceiver->hsm.b_bus_req = 0;
-       queue_work(the_transceiver->qwork, &the_transceiver->work);
-       otg_dbg("client controller driver is unregistered\n");
-}
-EXPORT_SYMBOL(langwell_unregister_peripheral);
-
-static int langwell_otg_probe(struct pci_dev *pdev,
-               const struct pci_device_id *id)
-{
-       unsigned long           resource, len;
-       void __iomem            *base = NULL;
-       int                     retval;
-       u32                     val32;
-       struct langwell_otg     *langwell;
-       char                    qname[] = "langwell_otg_queue";
-
-       retval = 0;
-       otg_dbg("\notg controller is detected.\n");
-       if (pci_enable_device(pdev) < 0) {
-               retval = -ENODEV;
-               goto done;
-       }
-
-       langwell = kzalloc(sizeof *langwell, GFP_KERNEL);
-       if (langwell == NULL) {
-               retval = -ENOMEM;
-               goto done;
-       }
-       the_transceiver = langwell;
-
-       /* control register: BAR 0 */
-       resource = pci_resource_start(pdev, 0);
-       len = pci_resource_len(pdev, 0);
-       if (!request_mem_region(resource, len, driver_name)) {
-               retval = -EBUSY;
-               goto err;
-       }
-       langwell->region = 1;
-
-       base = ioremap_nocache(resource, len);
-       if (base == NULL) {
-               retval = -EFAULT;
-               goto err;
-       }
-       langwell->regs = base;
-
-       if (!pdev->irq) {
-               otg_dbg("No IRQ.\n");
-               retval = -ENODEV;
-               goto err;
-       }
-
-       langwell->qwork = create_workqueue(qname);
-       if (!langwell->qwork) {
-               otg_dbg("cannot create workqueue %s\n", qname);
-               retval = -ENOMEM;
-               goto err;
-       }
-       INIT_WORK(&langwell->work, langwell_otg_work);
-
-       /* OTG common part */
-       langwell->pdev = pdev;
-       langwell->otg.dev = &pdev->dev;
-       langwell->otg.label = driver_name;
-       langwell->otg.set_host = langwell_otg_set_host;
-       langwell->otg.set_peripheral = langwell_otg_set_peripheral;
-       langwell->otg.set_power = langwell_otg_set_power;
-       langwell->otg.start_srp = langwell_otg_start_srp;
-       langwell->otg.state = OTG_STATE_UNDEFINED;
-       if (otg_set_transceiver(&langwell->otg)) {
-               otg_dbg("can't set transceiver\n");
-               retval = -EBUSY;
-               goto err;
-       }
-
-       reset_otg();
-       init_hsm();
-
-       spin_lock_init(&langwell->lock);
-       spin_lock_init(&langwell->wq_lock);
-       INIT_LIST_HEAD(&active_timers);
-       langwell_otg_init_timers(&langwell->hsm);
-
-       if (request_irq(pdev->irq, otg_irq, IRQF_SHARED,
-                               driver_name, langwell) != 0) {
-               otg_dbg("request interrupt %d failed\n", pdev->irq);
-               retval = -EBUSY;
-               goto err;
-       }
-
-       /* enable OTGSC int */
-       val32 = OTGSC_DPIE | OTGSC_BSEIE | OTGSC_BSVIE |
-               OTGSC_ASVIE | OTGSC_AVVIE | OTGSC_IDIE | OTGSC_IDPU;
-       writel(val32, langwell->regs + CI_OTGSC);
-
-       retval = device_create_file(&pdev->dev, &dev_attr_registers);
-       if (retval < 0) {
-               otg_dbg("Can't register sysfs attribute: %d\n", retval);
-               goto err;
-       }
-
-       retval = device_create_file(&pdev->dev, &dev_attr_hsm);
-       if (retval < 0) {
-               otg_dbg("Can't hsm sysfs attribute: %d\n", retval);
-               goto err;
-       }
-
-       retval = sysfs_create_group(&pdev->dev.kobj, &debug_dev_attr_group);
-       if (retval < 0) {
-               otg_dbg("Can't register sysfs attr group: %d\n", retval);
-               goto err;
-       }
-
-       if (langwell->otg.state == OTG_STATE_A_IDLE)
-               queue_work(langwell->qwork, &langwell->work);
-
-       return 0;
-
-err:
-       if (the_transceiver)
-               langwell_otg_remove(pdev);
-done:
-       return retval;
-}
-
-static void langwell_otg_remove(struct pci_dev *pdev)
-{
-       struct langwell_otg *langwell;
-
-       langwell = the_transceiver;
-
-       if (langwell->qwork) {
-               flush_workqueue(langwell->qwork);
-               destroy_workqueue(langwell->qwork);
-       }
-       langwell_otg_free_timers();
-
-       /* disable OTGSC interrupt as OTGSC doesn't change in reset */
-       writel(0, langwell->regs + CI_OTGSC);
-
-       if (pdev->irq)
-               free_irq(pdev->irq, langwell);
-       if (langwell->regs)
-               iounmap(langwell->regs);
-       if (langwell->region)
-               release_mem_region(pci_resource_start(pdev, 0),
-                               pci_resource_len(pdev, 0));
-
-       otg_set_transceiver(NULL);
-       pci_disable_device(pdev);
-       sysfs_remove_group(&pdev->dev.kobj, &debug_dev_attr_group);
-       device_remove_file(&pdev->dev, &dev_attr_hsm);
-       device_remove_file(&pdev->dev, &dev_attr_registers);
-       kfree(langwell);
-       langwell = NULL;
-}
-
-static void transceiver_suspend(struct pci_dev *pdev)
-{
-       pci_save_state(pdev);
-       pci_set_power_state(pdev, PCI_D3hot);
-       langwell_otg_phy_low_power(1);
-}
-
-static int langwell_otg_suspend(struct pci_dev *pdev, pm_message_t message)
-{
-       int     ret = 0;
-       struct langwell_otg *langwell;
-
-       langwell = the_transceiver;
-
-       /* Disbale OTG interrupts */
-       langwell_otg_intr(0);
-
-       if (pdev->irq)
-               free_irq(pdev->irq, langwell);
-
-       /* Prevent more otg_work */
-       flush_workqueue(langwell->qwork);
-       spin_lock(&langwell->wq_lock);
-
-       /* start actions */
-       switch (langwell->otg.state) {
-       case OTG_STATE_A_IDLE:
-       case OTG_STATE_B_IDLE:
-       case OTG_STATE_A_WAIT_VFALL:
-       case OTG_STATE_A_VBUS_ERR:
-               transceiver_suspend(pdev);
-               break;
-       case OTG_STATE_A_WAIT_VRISE:
-               langwell_otg_del_timer(a_wait_vrise_tmr);
-               langwell->hsm.a_srp_det = 0;
-               langwell_otg_drv_vbus(0);
-               langwell->otg.state = OTG_STATE_A_IDLE;
-               transceiver_suspend(pdev);
-               break;
-       case OTG_STATE_A_WAIT_BCON:
-               langwell_otg_del_timer(a_wait_bcon_tmr);
-               if (langwell->host_ops)
-                       ret = langwell->host_ops->suspend(pdev, message);
-               langwell_otg_drv_vbus(0);
-               break;
-       case OTG_STATE_A_HOST:
-               if (langwell->host_ops)
-                       ret = langwell->host_ops->suspend(pdev, message);
-               langwell_otg_drv_vbus(0);
-               langwell_otg_phy_low_power(1);
-               break;
-       case OTG_STATE_A_SUSPEND:
-               langwell_otg_del_timer(a_aidl_bdis_tmr);
-               langwell_otg_HABA(0);
-               if (langwell->host_ops)
-                       langwell->host_ops->remove(pdev);
-               else
-                       otg_dbg("host driver has been removed.\n");
-               langwell_otg_drv_vbus(0);
-               transceiver_suspend(pdev);
-               langwell->otg.state = OTG_STATE_A_WAIT_VFALL;
-               break;
-       case OTG_STATE_A_PERIPHERAL:
-               if (langwell->client_ops)
-                       ret = langwell->client_ops->suspend(pdev, message);
-               else
-                       otg_dbg("client driver has been removed.\n");
-               langwell_otg_drv_vbus(0);
-               transceiver_suspend(pdev);
-               langwell->otg.state = OTG_STATE_A_WAIT_VFALL;
-               break;
-       case OTG_STATE_B_HOST:
-               if (langwell->host_ops)
-                       langwell->host_ops->remove(pdev);
-               else
-                       otg_dbg("host driver has been removed.\n");
-               langwell->hsm.b_bus_req = 0;
-               transceiver_suspend(pdev);
-               langwell->otg.state = OTG_STATE_B_IDLE;
-               break;
-       case OTG_STATE_B_PERIPHERAL:
-               if (langwell->client_ops)
-                       ret = langwell->client_ops->suspend(pdev, message);
-               else
-                       otg_dbg("client driver has been removed.\n");
-               break;
-       case OTG_STATE_B_WAIT_ACON:
-               langwell_otg_del_timer(b_ase0_brst_tmr);
-               langwell_otg_HAAR(0);
-               if (langwell->host_ops)
-                       langwell->host_ops->remove(pdev);
-               else
-                       otg_dbg("host driver has been removed.\n");
-               langwell->hsm.b_bus_req = 0;
-               langwell->otg.state = OTG_STATE_B_IDLE;
-               transceiver_suspend(pdev);
-               break;
-       default:
-               otg_dbg("error state before suspend\n ");
-               break;
-       }
-       spin_unlock(&langwell->wq_lock);
-
-       return ret;
-}
-
-static void transceiver_resume(struct pci_dev *pdev)
-{
-       pci_restore_state(pdev);
-       pci_set_power_state(pdev, PCI_D0);
-       langwell_otg_phy_low_power(0);
-}
-
-static int langwell_otg_resume(struct pci_dev *pdev)
-{
-       int     ret = 0;
-       struct langwell_otg *langwell;
-
-       langwell = the_transceiver;
-
-       spin_lock(&langwell->wq_lock);
-
-       switch (langwell->otg.state) {
-       case OTG_STATE_A_IDLE:
-       case OTG_STATE_B_IDLE:
-       case OTG_STATE_A_WAIT_VFALL:
-       case OTG_STATE_A_VBUS_ERR:
-               transceiver_resume(pdev);
-               break;
-       case OTG_STATE_A_WAIT_BCON:
-               langwell_otg_add_timer(a_wait_bcon_tmr);
-               langwell_otg_drv_vbus(1);
-               if (langwell->host_ops)
-                       ret = langwell->host_ops->resume(pdev);
-               break;
-       case OTG_STATE_A_HOST:
-               langwell_otg_drv_vbus(1);
-               langwell_otg_phy_low_power(0);
-               if (langwell->host_ops)
-                       ret = langwell->host_ops->resume(pdev);
-               break;
-       case OTG_STATE_B_PERIPHERAL:
-               if (langwell->client_ops)
-                       ret = langwell->client_ops->resume(pdev);
-               else
-                       otg_dbg("client driver not loaded.\n");
-               break;
-       default:
-               otg_dbg("error state before suspend\n ");
-               break;
-       }
-
-       if (request_irq(pdev->irq, otg_irq, IRQF_SHARED,
-                               driver_name, the_transceiver) != 0) {
-               otg_dbg("request interrupt %d failed\n", pdev->irq);
-               ret = -EBUSY;
-       }
-
-       /* enable OTG interrupts */
-       langwell_otg_intr(1);
-
-       spin_unlock(&langwell->wq_lock);
-
-       queue_work(langwell->qwork, &langwell->work);
-
-
-       return ret;
-}
-
-static int __init langwell_otg_init(void)
-{
-       return pci_register_driver(&otg_pci_driver);
-}
-module_init(langwell_otg_init);
-
-static void __exit langwell_otg_cleanup(void)
-{
-       pci_unregister_driver(&otg_pci_driver);
-}
-module_exit(langwell_otg_cleanup);
index 9ed5ea5..af456b4 100644 (file)
@@ -53,6 +53,7 @@ EXPORT_SYMBOL(usb_nop_xceiv_register);
 void usb_nop_xceiv_unregister(void)
 {
        platform_device_unregister(pd);
+       pd = NULL;
 }
 EXPORT_SYMBOL(usb_nop_xceiv_unregister);
 
index 247b61b..0e4f2e4 100644 (file)
@@ -169,9 +169,11 @@ static int usb_console_setup(struct console *co, char *options)
                        kfree(tty);
                }
        }
-       /* So we know not to kill the hardware on a hangup on this
-          port. We have also bumped the use count by one so it won't go
-          idle */
+       /* Now that any required fake tty operations are completed restore
+        * the tty port count */
+       --port->port.count;
+       /* The console is special in terms of closing the device so
+        * indicate this port is now acting as a system console. */
        port->console = 1;
        retval = 0;
 
@@ -204,7 +206,7 @@ static void usb_console_write(struct console *co,
 
        dbg("%s - port %d, %d byte(s)", __func__, port->number, count);
 
-       if (!port->port.count) {
+       if (!port->console) {
                dbg("%s - port not opened", __func__);
                return;
        }
@@ -300,8 +302,7 @@ void usb_serial_console_exit(void)
 {
        if (usbcons_info.port) {
                unregister_console(&usbcons);
-               if (usbcons_info.port->port.count)
-                       usbcons_info.port->port.count--;
+               usbcons_info.port->console = 0;
                usbcons_info.port = NULL;
        }
 }
index 2b9eeda..e9a40b8 100644 (file)
@@ -67,6 +67,8 @@ static struct usb_device_id id_table [] = {
        { USB_DEVICE(0x10AB, 0x10C5) }, /* Siemens MC60 Cable */
        { USB_DEVICE(0x10B5, 0xAC70) }, /* Nokia CA-42 USB */
        { USB_DEVICE(0x10C4, 0x0F91) }, /* Vstabi */
+       { USB_DEVICE(0x10C4, 0x1101) }, /* Arkham Technology DS101 Bus Monitor */
+       { USB_DEVICE(0x10C4, 0x1601) }, /* Arkham Technology DS101 Adapter */
        { USB_DEVICE(0x10C4, 0x800A) }, /* SPORTident BSM7-D-USB main station */
        { USB_DEVICE(0x10C4, 0x803B) }, /* Pololu USB-serial converter */
        { USB_DEVICE(0x10C4, 0x8053) }, /* Enfora EDG1228 */
index 9734085..59adfe1 100644 (file)
@@ -1228,8 +1228,8 @@ static void cypress_read_int_callback(struct urb *urb)
                /* precursor to disconnect so just go away */
                return;
        case -EPIPE:
-               usb_clear_halt(port->serial->dev, 0x81);
-               break;
+               /* Can't call usb_clear_halt while in_interrupt */
+               /* FALLS THROUGH */
        default:
                /* something ugly is going on... */
                dev_err(&urb->dev->dev,
index 5f08702..60c64cc 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/errno.h>
 #include <linux/init.h>
 #include <linux/slab.h>
+#include <linux/smp_lock.h>
 #include <linux/tty.h>
 #include <linux/tty_driver.h>
 #include <linux/tty_flip.h>
@@ -107,6 +108,7 @@ struct ftdi_sio_quirk {
 
 static int   ftdi_jtag_probe(struct usb_serial *serial);
 static int   ftdi_mtxorb_hack_setup(struct usb_serial *serial);
+static int   ftdi_NDI_device_setup(struct usb_serial *serial);
 static void  ftdi_USB_UIRT_setup(struct ftdi_private *priv);
 static void  ftdi_HE_TIRA1_setup(struct ftdi_private *priv);
 
@@ -118,6 +120,10 @@ static struct ftdi_sio_quirk ftdi_mtxorb_hack_quirk = {
        .probe  = ftdi_mtxorb_hack_setup,
 };
 
+static struct ftdi_sio_quirk ftdi_NDI_device_quirk = {
+       .probe  = ftdi_NDI_device_setup,
+};
+
 static struct ftdi_sio_quirk ftdi_USB_UIRT_quirk = {
        .port_probe = ftdi_USB_UIRT_setup,
 };
@@ -191,6 +197,7 @@ static struct usb_device_id id_table_combined [] = {
        { USB_DEVICE(FTDI_VID, FTDI_MTXORB_4_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_MTXORB_5_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_MTXORB_6_PID) },
+       { USB_DEVICE(FTDI_VID, FTDI_R2000KU_TRUE_RNG) },
        { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0100_PID) },
        { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0101_PID) },
        { USB_DEVICE(MTXORB_VID, MTXORB_FTDI_RANGE_0102_PID) },
@@ -579,6 +586,9 @@ static struct usb_device_id id_table_combined [] = {
        { USB_DEVICE(FTDI_VID, FTDI_CCSICDU20_0_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_CCSICDU40_1_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_CCSMACHX_2_PID) },
+       { USB_DEVICE(FTDI_VID, FTDI_CCSLOAD_N_GO_3_PID) },
+       { USB_DEVICE(FTDI_VID, FTDI_CCSICDU64_4_PID) },
+       { USB_DEVICE(FTDI_VID, FTDI_CCSPRIME8_5_PID) },
        { USB_DEVICE(FTDI_VID, INSIDE_ACCESSO) },
        { USB_DEVICE(INTREPID_VID, INTREPID_VALUECAN_PID) },
        { USB_DEVICE(INTREPID_VID, INTREPID_NEOVI_PID) },
@@ -644,6 +654,16 @@ static struct usb_device_id id_table_combined [] = {
        { USB_DEVICE(FTDI_VID, FTDI_TACTRIX_OPENPORT_13S_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_TACTRIX_OPENPORT_13U_PID) },
        { USB_DEVICE(ELEKTOR_VID, ELEKTOR_FT323R_PID) },
+       { USB_DEVICE(FTDI_VID, FTDI_NDI_HUC_PID),
+               .driver_info = (kernel_ulong_t)&ftdi_NDI_device_quirk },
+       { USB_DEVICE(FTDI_VID, FTDI_NDI_SPECTRA_SCU_PID),
+               .driver_info = (kernel_ulong_t)&ftdi_NDI_device_quirk },
+       { USB_DEVICE(FTDI_VID, FTDI_NDI_FUTURE_2_PID),
+               .driver_info = (kernel_ulong_t)&ftdi_NDI_device_quirk },
+       { USB_DEVICE(FTDI_VID, FTDI_NDI_FUTURE_3_PID),
+               .driver_info = (kernel_ulong_t)&ftdi_NDI_device_quirk },
+       { USB_DEVICE(FTDI_VID, FTDI_NDI_AURORA_SCU_PID),
+               .driver_info = (kernel_ulong_t)&ftdi_NDI_device_quirk },
        { USB_DEVICE(TELLDUS_VID, TELLDUS_TELLSTICK_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_MAXSTREAM_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_PHI_FISCO_PID) },
@@ -660,6 +680,8 @@ static struct usb_device_id id_table_combined [] = {
                .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
        { USB_DEVICE(FTDI_VID, LMI_LM3S_EVAL_BOARD_PID),
                .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
+       { USB_DEVICE(FTDI_VID, FTDI_TURTELIZER_PID),
+               .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
        { USB_DEVICE(RATOC_VENDOR_ID, RATOC_PRODUCT_ID_USB60F) },
        { USB_DEVICE(FTDI_VID, FTDI_REU_TINY_PID) },
        { USB_DEVICE(PAPOUCH_VID, PAPOUCH_QUIDO4x4_PID) },
@@ -667,7 +689,6 @@ static struct usb_device_id id_table_combined [] = {
        { USB_DEVICE(FTDI_VID, FTDI_DOMINTELL_DUSB_PID) },
        { USB_DEVICE(ALTI2_VID, ALTI2_N3_PID) },
        { USB_DEVICE(FTDI_VID, DIEBOLD_BCS_SE923_PID) },
-       { USB_DEVICE(FTDI_VID, FTDI_NDI_HUC_PID) },
        { USB_DEVICE(ATMEL_VID, STK541_PID) },
        { USB_DEVICE(DE_VID, STB_PID) },
        { USB_DEVICE(DE_VID, WHT_PID) },
@@ -1023,6 +1044,16 @@ static __u32 get_ftdi_divisor(struct tty_struct *tty,
        case FT2232C: /* FT2232C chip */
        case FT232RL:
                if (baud <= 3000000) {
+                       __u16 product_id = le16_to_cpu(
+                               port->serial->dev->descriptor.idProduct);
+                       if (((FTDI_NDI_HUC_PID == product_id) ||
+                            (FTDI_NDI_SPECTRA_SCU_PID == product_id) ||
+                            (FTDI_NDI_FUTURE_2_PID == product_id) ||
+                            (FTDI_NDI_FUTURE_3_PID == product_id) ||
+                            (FTDI_NDI_AURORA_SCU_PID == product_id)) &&
+                           (baud == 19200)) {
+                               baud = 1200000;
+                       }
                        div_value = ftdi_232bm_baud_to_divisor(baud);
                } else {
                        dbg("%s - Baud rate too high!", __func__);
@@ -1553,6 +1584,39 @@ static void ftdi_HE_TIRA1_setup(struct ftdi_private *priv)
        priv->force_rtscts = 1;
 } /* ftdi_HE_TIRA1_setup */
 
+/*
+ * Module parameter to control latency timer for NDI FTDI-based USB devices.
+ * If this value is not set in modprobe.conf.local its value will be set to 1ms.
+ */
+static int ndi_latency_timer = 1;
+
+/* Setup for the NDI FTDI-based USB devices, which requires hardwired
+ * baudrate (19200 gets mapped to 1200000).
+ *
+ * Called from usbserial:serial_probe.
+ */
+static int ftdi_NDI_device_setup(struct usb_serial *serial)
+{
+       struct usb_device *udev = serial->dev;
+       int latency = ndi_latency_timer;
+       int rv = 0;
+       char buf[1];
+
+       if (latency == 0)
+               latency = 1;
+       if (latency > 99)
+               latency = 99;
+
+       dbg("%s setting NDI device latency to %d", __func__, latency);
+       dev_info(&udev->dev, "NDI device with a latency value of %d", latency);
+
+       rv = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
+                               FTDI_SIO_SET_LATENCY_TIMER_REQUEST,
+                               FTDI_SIO_SET_LATENCY_TIMER_REQUEST_TYPE,
+                               latency, 0, buf, 0, WDR_TIMEOUT);
+       return 0;
+}
+
 /*
  * First port on JTAG adaptors such as Olimex arm-usb-ocd or the FIC/OpenMoko
  * Neo1973 Debug Board is reserved for JTAG interface and can be accessed from
@@ -2622,3 +2686,5 @@ MODULE_PARM_DESC(vendor, "User specified vendor ID (default="
 module_param(product, ushort, 0);
 MODULE_PARM_DESC(product, "User specified product ID");
 
+module_param(ndi_latency_timer, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(ndi_latency_timer, "NDI device latency timer override");
index f1d440a..c9fbd74 100644 (file)
  *
  * Armin Laeuger originally sent the PID for the UM 100 module.
  */
+#define FTDI_R2000KU_TRUE_RNG  0xFB80  /* R2000KU TRUE RNG */
 #define FTDI_ELV_UR100_PID     0xFB58  /* USB-RS232-Umsetzer (UR 100) */
 #define FTDI_ELV_UM100_PID     0xFB5A  /* USB-Modul UM 100 */
 #define FTDI_ELV_UO100_PID     0xFB5B  /* USB-Modul UO 100 */
 #define FTDI_CCSICDU20_0_PID    0xF9D0
 #define FTDI_CCSICDU40_1_PID    0xF9D1
 #define FTDI_CCSMACHX_2_PID     0xF9D2
+#define FTDI_CCSLOAD_N_GO_3_PID 0xF9D3
+#define FTDI_CCSICDU64_4_PID    0xF9D4
+#define FTDI_CCSPRIME8_5_PID    0xF9D5
 
 /* Inside Accesso contactless reader (http://www.insidefr.com) */
 #define INSIDE_ACCESSO         0xFAD0
 /* Pyramid Computer GmbH */
 #define FTDI_PYRAMID_PID       0xE6C8  /* Pyramid Appliance Display */
 
+/*
+ * NDI (www.ndigital.com) product ids
+ */
+#define FTDI_NDI_HUC_PID               0xDA70  /* NDI Host USB Converter */
+#define FTDI_NDI_SPECTRA_SCU_PID       0xDA71  /* NDI Spectra SCU */
+#define FTDI_NDI_FUTURE_2_PID          0xDA72  /* NDI future device #2 */
+#define FTDI_NDI_FUTURE_3_PID          0xDA73  /* NDI future device #3 */
+#define FTDI_NDI_AURORA_SCU_PID                0xDA74  /* NDI Aurora SCU */
+
 /*
  * Posiflex inc retail equipment (http://www.posiflex.com.tw)
  */
 #define TML_VID                        0x1B91  /* Vendor ID */
 #define TML_USB_SERIAL_PID     0x0064  /* USB - Serial Converter */
 
-/* NDI Polaris System */
-#define FTDI_NDI_HUC_PID        0xDA70
-
 /* Propox devices */
 #define FTDI_PROPOX_JTAGCABLEII_PID    0xD738
 
 #define MARVELL_VID            0x9e88
 #define MARVELL_SHEEVAPLUG_PID 0x9e8f
 
+#define FTDI_TURTELIZER_PID    0xBDC8 /* JTAG/RS-232 adapter by egnite GmBH */
+
 /*
  *   BmRequestType:  1100 0000b
  *   bRequest:       FTDI_E2_READ
index c40f95c..c31940a 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/errno.h>
 #include <linux/init.h>
 #include <linux/slab.h>
+#include <linux/smp_lock.h>
 #include <linux/tty.h>
 #include <linux/tty_driver.h>
 #include <linux/tty_flip.h>
index 575816e..98262dd 100644 (file)
@@ -206,6 +206,7 @@ static int  option_resume(struct usb_serial *serial);
 #define NOVATELWIRELESS_PRODUCT_MC950D         0x4400
 #define NOVATELWIRELESS_PRODUCT_U727           0x5010
 #define NOVATELWIRELESS_PRODUCT_MC760          0x6000
+#define NOVATELWIRELESS_PRODUCT_OVMC760                0x6002
 
 /* FUTURE NOVATEL PRODUCTS */
 #define NOVATELWIRELESS_PRODUCT_EVDO_HIGHSPEED 0X6001
@@ -307,11 +308,20 @@ static int  option_resume(struct usb_serial *serial);
 #define DLINK_VENDOR_ID                                0x1186
 #define DLINK_PRODUCT_DWM_652                  0x3e04
 
+#define QISDA_VENDOR_ID                                0x1da5
+#define QISDA_PRODUCT_H21_4512                 0x4512
+#define QISDA_PRODUCT_H21_4523                 0x4523
+#define QISDA_PRODUCT_H20_4515                 0x4515
+#define QISDA_PRODUCT_H20_4519                 0x4519
+
 
 /* TOSHIBA PRODUCTS */
 #define TOSHIBA_VENDOR_ID                      0x0930
 #define TOSHIBA_PRODUCT_HSDPA_MINICARD         0x1302
 
+#define ALINK_VENDOR_ID                                0x1e0e
+#define ALINK_PRODUCT_3GU                      0x9200
+
 static struct usb_device_id option_ids[] = {
        { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) },
        { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) },
@@ -430,6 +440,7 @@ static struct usb_device_id option_ids[] = {
        { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC727) }, /* Novatel MC727/U727/USB727 */
        { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_U727) }, /* Novatel MC727/U727/USB727 */
        { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC760) }, /* Novatel MC760/U760/USB760 */
+       { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_OVMC760) }, /* Novatel Ovation MC760 */
        { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_FULLSPEED) }, /* Novatel HSPA product */
        { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_FULLSPEED) }, /* Novatel EVDO Embedded product */
        { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_FULLSPEED) }, /* Novatel HSPA Embedded product */
@@ -529,8 +540,13 @@ static struct usb_device_id option_ids[] = {
        { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_CDMA_TECH) },
        { USB_DEVICE(BENQ_VENDOR_ID, BENQ_PRODUCT_H10) },
        { USB_DEVICE(DLINK_VENDOR_ID, DLINK_PRODUCT_DWM_652) },
-       { USB_DEVICE(0x1da5, 0x4515) }, /* BenQ H20 */
+       { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H21_4512) },
+       { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H21_4523) },
+       { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H20_4515) },
+       { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H20_4519) },
        { USB_DEVICE(TOSHIBA_VENDOR_ID, TOSHIBA_PRODUCT_HSDPA_MINICARD ) }, /* Toshiba 3G HSDPA == Novatel Expedite EU870D MiniCard */
+       { USB_DEVICE(ALINK_VENDOR_ID, 0x9000) },
+       { USB_DEVICE_AND_INTERFACE_INFO(ALINK_VENDOR_ID, ALINK_PRODUCT_3GU, 0xff, 0xff, 0xff) },
        { } /* Terminating entry */
 };
 MODULE_DEVICE_TABLE(usb, option_ids);
@@ -732,7 +748,6 @@ static int option_write(struct tty_struct *tty, struct usb_serial_port *port,
                memcpy(this_urb->transfer_buffer, buf, todo);
                this_urb->transfer_buffer_length = todo;
 
-               this_urb->dev = port->serial->dev;
                err = usb_submit_urb(this_urb, GFP_ATOMIC);
                if (err) {
                        dbg("usb_submit_urb %p (write bulk) failed "
@@ -860,7 +875,6 @@ static void option_instat_callback(struct urb *urb)
 
        /* Resubmit urb so we continue receiving IRQ data */
        if (status != -ESHUTDOWN && status != -ENOENT) {
-               urb->dev = serial->dev;
                err = usb_submit_urb(urb, GFP_ATOMIC);
                if (err)
                        dbg("%s: resubmit intr urb failed. (%d)",
@@ -921,23 +935,11 @@ static int option_open(struct tty_struct *tty,
 
        dbg("%s", __func__);
 
-       /* Reset low level data toggle and start reading from endpoints */
+       /* Start reading from the IN endpoint */
        for (i = 0; i < N_IN_URB; i++) {
                urb = portdata->in_urbs[i];
                if (!urb)
                        continue;
-               if (urb->dev != serial->dev) {
-                       dbg("%s: dev %p != %p", __func__,
-                               urb->dev, serial->dev);
-                       continue;
-               }
-
-               /*
-                * make sure endpoint data toggle is synchronized with the
-                * device
-                */
-               usb_clear_halt(urb->dev, urb->pipe);
-
                err = usb_submit_urb(urb, GFP_KERNEL);
                if (err) {
                        dbg("%s: submit urb %d failed (%d) %d",
@@ -946,16 +948,6 @@ static int option_open(struct tty_struct *tty,
                }
        }
 
-       /* Reset low level data toggle on out endpoints */
-       for (i = 0; i < N_OUT_URB; i++) {
-               urb = portdata->out_urbs[i];
-               if (!urb)
-                       continue;
-               urb->dev = serial->dev;
-               /* usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe),
-                               usb_pipeout(urb->pipe), 0); */
-       }
-
        option_send_setup(port);
 
        return 0;
@@ -1218,7 +1210,6 @@ static int option_resume(struct usb_serial *serial)
                        dbg("%s: No interrupt URB for port %d\n", __func__, i);
                        continue;
                }
-               port->interrupt_in_urb->dev = serial->dev;
                err = usb_submit_urb(port->interrupt_in_urb, GFP_NOIO);
                dbg("Submitted interrupt URB for port %d (result %d)", i, err);
                if (err < 0) {
index efaf59c..7d15bfa 100644 (file)
@@ -94,6 +94,7 @@ static struct usb_device_id id_table [] = {
        { USB_DEVICE(YCCABLE_VENDOR_ID, YCCABLE_PRODUCT_ID) },
        { USB_DEVICE(SUPERIAL_VENDOR_ID, SUPERIAL_PRODUCT_ID) },
        { USB_DEVICE(HP_VENDOR_ID, HP_LD220_PRODUCT_ID) },
+       { USB_DEVICE(CRESSI_VENDOR_ID, CRESSI_EDY_PRODUCT_ID) },
        { }                                     /* Terminating entry */
 };
 
index 1d7a22e..12aac7d 100644 (file)
 /* Hewlett-Packard LD220-HP POS Pole Display */
 #define HP_VENDOR_ID           0x03f0
 #define HP_LD220_PRODUCT_ID    0x3524
+
+/* Cressi Edy (diving computer) PC interface */
+#define CRESSI_VENDOR_ID       0x04b8
+#define CRESSI_EDY_PRODUCT_ID  0x0521
index 032f7ae..f48d05e 100644 (file)
@@ -181,35 +181,50 @@ static const struct sierra_iface_info direct_ip_interface_blacklist = {
 };
 
 static struct usb_device_id id_table [] = {
+       { USB_DEVICE(0x0F3D, 0x0112) }, /* Airprime/Sierra PC 5220 */
+       { USB_DEVICE(0x03F0, 0x1B1D) }, /* HP ev2200 a.k.a MC5720 */
+       { USB_DEVICE(0x03F0, 0x1E1D) }, /* HP hs2300 a.k.a MC8775 */
+
        { USB_DEVICE(0x1199, 0x0017) }, /* Sierra Wireless EM5625 */
        { USB_DEVICE(0x1199, 0x0018) }, /* Sierra Wireless MC5720 */
        { USB_DEVICE(0x1199, 0x0218) }, /* Sierra Wireless MC5720 */
-       { USB_DEVICE(0x03f0, 0x1b1d) }, /* HP ev2200 a.k.a MC5720 */
        { USB_DEVICE(0x1199, 0x0020) }, /* Sierra Wireless MC5725 */
-       { USB_DEVICE(0x1199, 0x0024) }, /* Sierra Wireless MC5727 */
        { USB_DEVICE(0x1199, 0x0220) }, /* Sierra Wireless MC5725 */
+       { USB_DEVICE(0x1199, 0x0022) }, /* Sierra Wireless EM5725 */
+       { USB_DEVICE(0x1199, 0x0024) }, /* Sierra Wireless MC5727 */
+       { USB_DEVICE(0x1199, 0x0224) }, /* Sierra Wireless MC5727 */
        { USB_DEVICE(0x1199, 0x0019) }, /* Sierra Wireless AirCard 595 */
        { USB_DEVICE(0x1199, 0x0021) }, /* Sierra Wireless AirCard 597E */
+       { USB_DEVICE(0x1199, 0x0112) }, /* Sierra Wireless AirCard 580 */
        { USB_DEVICE(0x1199, 0x0120) }, /* Sierra Wireless USB Dongle 595U */
-        /* Sierra Wireless C597 */
+       /* Sierra Wireless C597 */
        { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x0023, 0xFF, 0xFF, 0xFF) },
-        /* Sierra Wireless Device */
+       /* Sierra Wireless T598 */
        { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x0025, 0xFF, 0xFF, 0xFF) },
-       { USB_DEVICE(0x1199, 0x0026) }, /* Sierra Wireless Device */
-       { USB_DEVICE(0x1199, 0x0027) }, /* Sierra Wireless Device */
-       { USB_DEVICE(0x1199, 0x0028) }, /* Sierra Wireless Device */
+       { USB_DEVICE(0x1199, 0x0026) }, /* Sierra Wireless T11 */
+       { USB_DEVICE(0x1199, 0x0027) }, /* Sierra Wireless AC402 */
+       { USB_DEVICE(0x1199, 0x0028) }, /* Sierra Wireless MC5728 */
+       { USB_DEVICE(0x1199, 0x0029) }, /* Sierra Wireless Device */
 
        { USB_DEVICE(0x1199, 0x6802) }, /* Sierra Wireless MC8755 */
-       { USB_DEVICE(0x1199, 0x6804) }, /* Sierra Wireless MC8755 */
        { USB_DEVICE(0x1199, 0x6803) }, /* Sierra Wireless MC8765 */
+       { USB_DEVICE(0x1199, 0x6804) }, /* Sierra Wireless MC8755 */
+       { USB_DEVICE(0x1199, 0x6805) }, /* Sierra Wireless MC8765 */
+       { USB_DEVICE(0x1199, 0x6808) }, /* Sierra Wireless MC8755 */
+       { USB_DEVICE(0x1199, 0x6809) }, /* Sierra Wireless MC8765 */
        { USB_DEVICE(0x1199, 0x6812) }, /* Sierra Wireless MC8775 & AC 875U */
-       { USB_DEVICE(0x1199, 0x6813) }, /* Sierra Wireless MC8775 (Lenovo) */
+       { USB_DEVICE(0x1199, 0x6813) }, /* Sierra Wireless MC8775 */
        { USB_DEVICE(0x1199, 0x6815) }, /* Sierra Wireless MC8775 */
-       { USB_DEVICE(0x03f0, 0x1e1d) }, /* HP hs2300 a.k.a MC8775 */
+       { USB_DEVICE(0x1199, 0x6816) }, /* Sierra Wireless MC8775 */
        { USB_DEVICE(0x1199, 0x6820) }, /* Sierra Wireless AirCard 875 */
        { USB_DEVICE(0x1199, 0x6821) }, /* Sierra Wireless AirCard 875U */
+       { USB_DEVICE(0x1199, 0x6822) }, /* Sierra Wireless AirCard 875E */
        { USB_DEVICE(0x1199, 0x6832) }, /* Sierra Wireless MC8780 */
        { USB_DEVICE(0x1199, 0x6833) }, /* Sierra Wireless MC8781 */
+       { USB_DEVICE(0x1199, 0x6834) }, /* Sierra Wireless MC8780 */
+       { USB_DEVICE(0x1199, 0x6835) }, /* Sierra Wireless MC8781 */
+       { USB_DEVICE(0x1199, 0x6838) }, /* Sierra Wireless MC8780 */
+       { USB_DEVICE(0x1199, 0x6839) }, /* Sierra Wireless MC8781 */
        { USB_DEVICE(0x1199, 0x683A) }, /* Sierra Wireless MC8785 */
        { USB_DEVICE(0x1199, 0x683B) }, /* Sierra Wireless MC8785 Composite */
        /* Sierra Wireless MC8790, MC8791, MC8792 Composite */
@@ -227,16 +242,13 @@ static struct usb_device_id id_table [] = {
        { USB_DEVICE(0x1199, 0x685A) }, /* Sierra Wireless AirCard 885 E */
        /* Sierra Wireless C885 */
        { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6880, 0xFF, 0xFF, 0xFF)},
-       /* Sierra Wireless Device */
+       /* Sierra Wireless C888, Air Card 501, USB 303, USB 304 */
        { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6890, 0xFF, 0xFF, 0xFF)},
-       /* Sierra Wireless Device */
+       /* Sierra Wireless C22/C33 */
        { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6891, 0xFF, 0xFF, 0xFF)},
-       /* Sierra Wireless Device */
+       /* Sierra Wireless HSPA Non-Composite Device */
        { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6892, 0xFF, 0xFF, 0xFF)},
-
-       { USB_DEVICE(0x1199, 0x0112) }, /* Sierra Wireless AirCard 580 */
-       { USB_DEVICE(0x0F3D, 0x0112) }, /* Airprime/Sierra PC 5220 */
-
+       { USB_DEVICE(0x1199, 0x6893) }, /* Sierra Wireless Device */
        { USB_DEVICE(0x1199, 0x68A3),   /* Sierra Wireless Direct IP modems */
          .driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist
        },
@@ -814,7 +826,7 @@ static int sierra_startup(struct usb_serial *serial)
        return 0;
 }
 
-static void sierra_disconnect(struct usb_serial *serial)
+static void sierra_release(struct usb_serial *serial)
 {
        int i;
        struct usb_serial_port *port;
@@ -830,7 +842,6 @@ static void sierra_disconnect(struct usb_serial *serial)
                if (!portdata)
                        continue;
                kfree(portdata);
-               usb_set_serial_port_data(port, NULL);
        }
 }
 
@@ -853,7 +864,7 @@ static struct usb_serial_driver sierra_device = {
        .tiocmget          = sierra_tiocmget,
        .tiocmset          = sierra_tiocmset,
        .attach            = sierra_startup,
-       .disconnect        = sierra_disconnect,
+       .release           = sierra_release,
        .read_int_callback = sierra_instat_callback,
 };
 
index 991d823..14971a9 100644 (file)
@@ -191,7 +191,6 @@ static struct usb_device_id ti_id_table_5052[5+TI_EXTRA_VID_PID_COUNT+1] = {
        { USB_DEVICE(TI_VENDOR_ID, TI_5152_BOOT_PRODUCT_ID) },
        { USB_DEVICE(TI_VENDOR_ID, TI_5052_EEPROM_PRODUCT_ID) },
        { USB_DEVICE(TI_VENDOR_ID, TI_5052_FIRMWARE_PRODUCT_ID) },
-       { USB_DEVICE(IBM_VENDOR_ID, IBM_4543_PRODUCT_ID) },
 };
 
 static struct usb_device_id ti_id_table_combined[14+2*TI_EXTRA_VID_PID_COUNT+1] = {
@@ -1658,7 +1657,7 @@ static int ti_do_download(struct usb_device *dev, int pipe,
        u8 cs = 0;
        int done;
        struct ti_firmware_header *header;
-       int status;
+       int status = 0;
        int len;
 
        for (pos = sizeof(struct ti_firmware_header); pos < size; pos++)
index a842164..bd7581b 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/errno.h>
 #include <linux/init.h>
 #include <linux/slab.h>
+#include <linux/smp_lock.h>
 #include <linux/tty.h>
 #include <linux/tty_driver.h>
 #include <linux/tty_flip.h>
@@ -220,7 +221,8 @@ static int serial_open (struct tty_struct *tty, struct file *filp)
        tty->driver_data = port;
        tty_port_tty_set(&port->port, tty);
 
-       if (port->port.count == 1) {
+       /* If the console is attached, the device is already open */
+       if (port->port.count == 1 && !port->console) {
 
                /* lock this module before we call it
                 * this may fail, which means we must bail out,
index d41cc0a..773a5cd 100644 (file)
@@ -118,6 +118,9 @@ static int option_inquiry(struct us_data *us)
 
        result = memcmp(buffer+8, "Option", 6);
 
+       if (result != 0)
+               result = memcmp(buffer+8, "ZCOPTION", 8);
+
        /* Read the CSW */
        usb_stor_bulk_transfer_buf(us,
                        us->recv_bulk_pipe,
index 53ea056..a85c818 100644 (file)
@@ -16,7 +16,6 @@
 #include <linux/compat.h>
 #include <linux/types.h>
 #include <linux/errno.h>
-#include <linux/smp_lock.h>
 #include <linux/kernel.h>
 #include <linux/major.h>
 #include <linux/slab.h>
index 4ea99bf..8862233 100644 (file)
@@ -1254,7 +1254,7 @@ static struct fb_ops omapfb_ops = {
 static ssize_t omapfb_show_caps_num(struct device *dev,
                                    struct device_attribute *attr, char *buf)
 {
-       struct omapfb_device *fbdev = (struct omapfb_device *)dev->driver_data;
+       struct omapfb_device *fbdev = dev_get_drvdata(dev);
        int plane;
        size_t size;
        struct omapfb_caps caps;
@@ -1274,7 +1274,7 @@ static ssize_t omapfb_show_caps_num(struct device *dev,
 static ssize_t omapfb_show_caps_text(struct device *dev,
                                     struct device_attribute *attr, char *buf)
 {
-       struct omapfb_device *fbdev = (struct omapfb_device *)dev->driver_data;
+       struct omapfb_device *fbdev = dev_get_drvdata(dev);
        int i;
        struct omapfb_caps caps;
        int plane;
@@ -1321,7 +1321,7 @@ static DEVICE_ATTR(caps_text, 0444, omapfb_show_caps_text, NULL);
 static ssize_t omapfb_show_panel_name(struct device *dev,
                                      struct device_attribute *attr, char *buf)
 {
-       struct omapfb_device *fbdev = (struct omapfb_device *)dev->driver_data;
+       struct omapfb_device *fbdev = dev_get_drvdata(dev);
 
        return snprintf(buf, PAGE_SIZE, "%s\n", fbdev->panel->name);
 }
@@ -1330,7 +1330,7 @@ static ssize_t omapfb_show_bklight_level(struct device *dev,
                                         struct device_attribute *attr,
                                         char *buf)
 {
-       struct omapfb_device *fbdev = (struct omapfb_device *)dev->driver_data;
+       struct omapfb_device *fbdev = dev_get_drvdata(dev);
        int r;
 
        if (fbdev->panel->get_bklight_level) {
@@ -1345,7 +1345,7 @@ static ssize_t omapfb_store_bklight_level(struct device *dev,
                                          struct device_attribute *attr,
                                          const char *buf, size_t size)
 {
-       struct omapfb_device *fbdev = (struct omapfb_device *)dev->driver_data;
+       struct omapfb_device *fbdev = dev_get_drvdata(dev);
        int r;
 
        if (fbdev->panel->set_bklight_level) {
@@ -1364,7 +1364,7 @@ static ssize_t omapfb_store_bklight_level(struct device *dev,
 static ssize_t omapfb_show_bklight_max(struct device *dev,
                                       struct device_attribute *attr, char *buf)
 {
-       struct omapfb_device *fbdev = (struct omapfb_device *)dev->driver_data;
+       struct omapfb_device *fbdev = dev_get_drvdata(dev);
        int r;
 
        if (fbdev->panel->get_bklight_level) {
@@ -1397,7 +1397,7 @@ static struct attribute_group panel_attr_grp = {
 static ssize_t omapfb_show_ctrl_name(struct device *dev,
                                     struct device_attribute *attr, char *buf)
 {
-       struct omapfb_device *fbdev = (struct omapfb_device *)dev->driver_data;
+       struct omapfb_device *fbdev = dev_get_drvdata(dev);
 
        return snprintf(buf, PAGE_SIZE, "%s\n", fbdev->ctrl->name);
 }
index aad92f0..6910a98 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/parser.h>
 #include <linux/mount.h>
 #include <linux/seq_file.h>
+#include <linux/smp_lock.h>
 #include <linux/statfs.h>
 #include "adfs.h"
 #include "dir_f.h"
index 9bd7577..88067f3 100644 (file)
@@ -564,7 +564,7 @@ static struct dentry *afs_lookup(struct inode *dir, struct dentry *dentry,
 static int afs_d_revalidate(struct dentry *dentry, struct nameidata *nd)
 {
        struct afs_vnode *vnode, *dir;
-       struct afs_fid fid;
+       struct afs_fid uninitialized_var(fid);
        struct dentry *parent;
        struct key *key;
        void *dir_version;
index ad0514d..e1ea1c2 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/slab.h>
+#include <linux/smp_lock.h>
 #include <linux/fs.h>
 #include <linux/pagemap.h>
 #include <linux/parser.h>
index f3da2eb..00bf8fc 100644 (file)
@@ -19,7 +19,6 @@
 #include <linux/sched.h>
 #include <linux/compat.h>
 #include <linux/syscalls.h>
-#include <linux/smp_lock.h>
 #include <linux/magic.h>
 #include <linux/dcache.h>
 #include <linux/uaccess.h>
index 54bd07d..1e41aad 100644 (file)
@@ -8,7 +8,6 @@
 #include <linux/time.h>
 #include <linux/string.h>
 #include <linux/fs.h>
-#include <linux/smp_lock.h>
 #include <linux/buffer_head.h>
 #include <linux/sched.h>
 #include "bfs.h"
index 6a02126..88b9a3f 100644 (file)
@@ -11,7 +11,6 @@
 
 #include <linux/fs.h>
 #include <linux/buffer_head.h>
-#include <linux/smp_lock.h>
 #include "bfs.h"
 
 #undef DEBUG
index de1e2fd..9d8ba4d 100644 (file)
@@ -26,7 +26,6 @@
 #include <linux/time.h>
 #include <linux/init.h>
 #include <linux/string.h>
-#include <linux/smp_lock.h>
 #include <linux/backing-dev.h>
 #include <linux/mpage.h>
 #include <linux/swap.h>
index 7c3cd24..4b83397 100644 (file)
@@ -22,7 +22,6 @@
 #include <linux/time.h>
 #include <linux/init.h>
 #include <linux/string.h>
-#include <linux/smp_lock.h>
 #include <linux/backing-dev.h>
 #include <linux/mpage.h>
 #include <linux/swap.h>
index 7ffa3d3..791eab1 100644 (file)
@@ -26,7 +26,6 @@
 #include <linux/time.h>
 #include <linux/init.h>
 #include <linux/string.h>
-#include <linux/smp_lock.h>
 #include <linux/backing-dev.h>
 #include <linux/mpage.h>
 #include <linux/swap.h>
index 9f4db84..bd88f25 100644 (file)
@@ -27,7 +27,6 @@
 #include <linux/time.h>
 #include <linux/init.h>
 #include <linux/string.h>
-#include <linux/smp_lock.h>
 #include <linux/backing-dev.h>
 #include <linux/mount.h>
 #include <linux/mpage.h>
index 9f179d4..6d6d06c 100644 (file)
@@ -26,7 +26,6 @@
 #include <linux/init.h>
 #include <linux/seq_file.h>
 #include <linux/string.h>
-#include <linux/smp_lock.h>
 #include <linux/backing-dev.h>
 #include <linux/mount.h>
 #include <linux/mpage.h>
index b7c9d51..a173551 100644 (file)
@@ -13,7 +13,6 @@
 #include <linux/major.h>
 #include <linux/errno.h>
 #include <linux/module.h>
-#include <linux/smp_lock.h>
 #include <linux/seq_file.h>
 
 #include <linux/kobject.h>
index fbadb94..94502da 100644 (file)
@@ -32,7 +32,6 @@
 #include <linux/smb_mount.h>
 #include <linux/ncp_mount.h>
 #include <linux/nfs4_mount.h>
-#include <linux/smp_lock.h>
 #include <linux/syscalls.h>
 #include <linux/ctype.h>
 #include <linux/module.h>
index 626c748..f28f070 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/compiler.h>
 #include <linux/sched.h>
 #include <linux/smp.h>
+#include <linux/smp_lock.h>
 #include <linux/ioctl.h>
 #include <linux/if.h>
 #include <linux/if_bridge.h>
index a343b4e..5ab10c3 100644 (file)
@@ -31,6 +31,7 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
+#include <linux/smp_lock.h>
 #include <linux/string.h>
 #include <linux/parser.h>
 #include <linux/vfs.h>
index 7cb4bad..e743130 100644 (file)
@@ -13,7 +13,6 @@
 #include <linux/sched.h>
 #include <linux/compat.h>
 #include <linux/mount.h>
-#include <linux/smp_lock.h>
 #include <asm/current.h>
 #include <asm/uaccess.h>
 
index 0ddf7e5..9714db3 100644 (file)
@@ -93,20 +93,20 @@ typedef unsigned int ext4_group_t;
 struct ext4_allocation_request {
        /* target inode for block we're allocating */
        struct inode *inode;
+       /* how many blocks we want to allocate */
+       unsigned int len;
        /* logical block in target inode */
        ext4_lblk_t logical;
-       /* phys. target (a hint) */
-       ext4_fsblk_t goal;
        /* the closest logical allocated block to the left */
        ext4_lblk_t lleft;
-       /* phys. block for ^^^ */
-       ext4_fsblk_t pleft;
        /* the closest logical allocated block to the right */
        ext4_lblk_t lright;
-       /* phys. block for ^^^ */
+       /* phys. target (a hint) */
+       ext4_fsblk_t goal;
+       /* phys. block for the closest logical allocated block to the left */
+       ext4_fsblk_t pleft;
+       /* phys. block for the closest logical allocated block to the right */
        ext4_fsblk_t pright;
-       /* how many blocks we want to allocate */
-       unsigned int len;
        /* flags. see above EXT4_MB_HINT_* */
        unsigned int flags;
 };
index ad13a84..eb27fd0 100644 (file)
@@ -43,6 +43,8 @@ int __ext4_journal_forget(const char *where, handle_t *handle,
                        ext4_journal_abort_handle(where, __func__, bh,
                                                  handle, err);
        }
+       else
+               brelse(bh);
        return err;
 }
 
@@ -57,6 +59,8 @@ int __ext4_journal_revoke(const char *where, handle_t *handle,
                        ext4_journal_abort_handle(where, __func__, bh,
                                                  handle, err);
        }
+       else
+               brelse(bh);
        return err;
 }
 
index be2f426..139fb8c 100644 (file)
@@ -131,9 +131,11 @@ int __ext4_journal_get_undo_access(const char *where, handle_t *handle,
 int __ext4_journal_get_write_access(const char *where, handle_t *handle,
                                struct buffer_head *bh);
 
+/* When called with an invalid handle, this will still do a put on the BH */
 int __ext4_journal_forget(const char *where, handle_t *handle,
                                struct buffer_head *bh);
 
+/* When called with an invalid handle, this will still do a put on the BH */
 int __ext4_journal_revoke(const char *where, handle_t *handle,
                                ext4_fsblk_t blocknr, struct buffer_head *bh);
 
@@ -281,10 +283,10 @@ static inline int ext4_should_order_data(struct inode *inode)
 
 static inline int ext4_should_writeback_data(struct inode *inode)
 {
-       if (EXT4_JOURNAL(inode) == NULL)
-               return 0;
        if (!S_ISREG(inode->i_mode))
                return 0;
+       if (EXT4_JOURNAL(inode) == NULL)
+               return 1;
        if (EXT4_I(inode)->i_flags & EXT4_JOURNAL_DATA_FL)
                return 0;
        if (test_opt(inode->i_sb, DATA_FLAGS) == EXT4_MOUNT_WRITEBACK_DATA)
index 50322a0..73ebfb4 100644 (file)
@@ -1977,6 +1977,7 @@ int ext4_ext_calc_credits_for_single_extent(struct inode *inode, int nrblocks,
                         */
                        /* 1 bitmap, 1 block group descriptor */
                        ret = 2 + EXT4_META_TRANS_BLOCKS(inode->i_sb);
+                       return ret;
                }
        }
 
index 2f64573..29e6dc7 100644 (file)
@@ -833,7 +833,7 @@ struct inode *ext4_new_inode(handle_t *handle, struct inode *dir, int mode,
        if (!goal)
                goal = sbi->s_inode_goal;
 
-       if (goal && goal < le32_to_cpu(sbi->s_es->s_inodes_count)) {
+       if (goal && goal <= le32_to_cpu(sbi->s_es->s_inodes_count)) {
                group = (goal - 1) / EXT4_INODES_PER_GROUP(sb);
                ino = (goal - 1) % EXT4_INODES_PER_GROUP(sb);
                ret2 = 0;
index 60a26f3..f9c642b 100644 (file)
@@ -78,16 +78,14 @@ static int ext4_inode_is_fast_symlink(struct inode *inode)
  * but there may still be a record of it in the journal, and that record
  * still needs to be revoked.
  *
- * If the handle isn't valid we're not journaling so there's nothing to do.
+ * If the handle isn't valid we're not journaling, but we still need to
+ * call into ext4_journal_revoke() to put the buffer head.
  */
 int ext4_forget(handle_t *handle, int is_metadata, struct inode *inode,
                struct buffer_head *bh, ext4_fsblk_t blocknr)
 {
        int err;
 
-       if (!ext4_handle_valid(handle))
-               return 0;
-
        might_sleep();
 
        BUFFER_TRACE(bh, "enter");
@@ -1513,14 +1511,14 @@ retry:
                 * Add inode to orphan list in case we crash before
                 * truncate finishes
                 */
-               if (pos + len > inode->i_size)
+               if (pos + len > inode->i_size && ext4_can_truncate(inode))
                        ext4_orphan_add(handle, inode);
 
                ext4_journal_stop(handle);
                if (pos + len > inode->i_size) {
-                       vmtruncate(inode, inode->i_size);
+                       ext4_truncate(inode);
                        /*
-                        * If vmtruncate failed early the inode might
+                        * If truncate failed early the inode might
                         * still be on the orphan list; we need to
                         * make sure the inode is removed from the
                         * orphan list in that case.
@@ -1614,7 +1612,7 @@ static int ext4_ordered_write_end(struct file *file,
                ret2 = ext4_generic_write_end(file, mapping, pos, len, copied,
                                                        page, fsdata);
                copied = ret2;
-               if (pos + len > inode->i_size)
+               if (pos + len > inode->i_size && ext4_can_truncate(inode))
                        /* if we have allocated more blocks and copied
                         * less. We will have blocks allocated outside
                         * inode->i_size. So truncate them
@@ -1628,9 +1626,9 @@ static int ext4_ordered_write_end(struct file *file,
                ret = ret2;
 
        if (pos + len > inode->i_size) {
-               vmtruncate(inode, inode->i_size);
+               ext4_truncate(inode);
                /*
-                * If vmtruncate failed early the inode might still be
+                * If truncate failed early the inode might still be
                 * on the orphan list; we need to make sure the inode
                 * is removed from the orphan list in that case.
                 */
@@ -1655,7 +1653,7 @@ static int ext4_writeback_write_end(struct file *file,
        ret2 = ext4_generic_write_end(file, mapping, pos, len, copied,
                                                        page, fsdata);
        copied = ret2;
-       if (pos + len > inode->i_size)
+       if (pos + len > inode->i_size && ext4_can_truncate(inode))
                /* if we have allocated more blocks and copied
                 * less. We will have blocks allocated outside
                 * inode->i_size. So truncate them
@@ -1670,9 +1668,9 @@ static int ext4_writeback_write_end(struct file *file,
                ret = ret2;
 
        if (pos + len > inode->i_size) {
-               vmtruncate(inode, inode->i_size);
+               ext4_truncate(inode);
                /*
-                * If vmtruncate failed early the inode might still be
+                * If truncate failed early the inode might still be
                 * on the orphan list; we need to make sure the inode
                 * is removed from the orphan list in that case.
                 */
@@ -1722,7 +1720,7 @@ static int ext4_journalled_write_end(struct file *file,
 
        unlock_page(page);
        page_cache_release(page);
-       if (pos + len > inode->i_size)
+       if (pos + len > inode->i_size && ext4_can_truncate(inode))
                /* if we have allocated more blocks and copied
                 * less. We will have blocks allocated outside
                 * inode->i_size. So truncate them
@@ -1733,9 +1731,9 @@ static int ext4_journalled_write_end(struct file *file,
        if (!ret)
                ret = ret2;
        if (pos + len > inode->i_size) {
-               vmtruncate(inode, inode->i_size);
+               ext4_truncate(inode);
                /*
-                * If vmtruncate failed early the inode might still be
+                * If truncate failed early the inode might still be
                 * on the orphan list; we need to make sure the inode
                 * is removed from the orphan list in that case.
                 */
@@ -2305,15 +2303,9 @@ flush_it:
        return;
 }
 
-static int ext4_bh_unmapped_or_delay(handle_t *handle, struct buffer_head *bh)
+static int ext4_bh_delay_or_unwritten(handle_t *handle, struct buffer_head *bh)
 {
-       /*
-        * unmapped buffer is possible for holes.
-        * delay buffer is possible with delayed allocation.
-        * We also need to consider unwritten buffer as unmapped.
-        */
-       return (!buffer_mapped(bh) || buffer_delay(bh) ||
-                               buffer_unwritten(bh)) && buffer_dirty(bh);
+       return (buffer_delay(bh) || buffer_unwritten(bh)) && buffer_dirty(bh);
 }
 
 /*
@@ -2398,9 +2390,9 @@ static int __mpage_da_writepage(struct page *page,
                         * We need to try to allocate
                         * unmapped blocks in the same page.
                         * Otherwise we won't make progress
-                        * with the page in ext4_da_writepage
+                        * with the page in ext4_writepage
                         */
-                       if (ext4_bh_unmapped_or_delay(NULL, bh)) {
+                       if (ext4_bh_delay_or_unwritten(NULL, bh)) {
                                mpage_add_bh_to_extent(mpd, logical,
                                                       bh->b_size,
                                                       bh->b_state);
@@ -2517,7 +2509,6 @@ static int noalloc_get_block_write(struct inode *inode, sector_t iblock,
         * so call get_block_wrap with create = 0
         */
        ret = ext4_get_blocks(NULL, inode, iblock, max_blocks, bh_result, 0);
-       BUG_ON(create && ret == 0);
        if (ret > 0) {
                bh_result->b_size = (ret << inode->i_blkbits);
                ret = 0;
@@ -2525,15 +2516,102 @@ static int noalloc_get_block_write(struct inode *inode, sector_t iblock,
        return ret;
 }
 
+static int bget_one(handle_t *handle, struct buffer_head *bh)
+{
+       get_bh(bh);
+       return 0;
+}
+
+static int bput_one(handle_t *handle, struct buffer_head *bh)
+{
+       put_bh(bh);
+       return 0;
+}
+
+static int __ext4_journalled_writepage(struct page *page,
+                                      struct writeback_control *wbc,
+                                      unsigned int len)
+{
+       struct address_space *mapping = page->mapping;
+       struct inode *inode = mapping->host;
+       struct buffer_head *page_bufs;
+       handle_t *handle = NULL;
+       int ret = 0;
+       int err;
+
+       page_bufs = page_buffers(page);
+       BUG_ON(!page_bufs);
+       walk_page_buffers(handle, page_bufs, 0, len, NULL, bget_one);
+       /* As soon as we unlock the page, it can go away, but we have
+        * references to buffers so we are safe */
+       unlock_page(page);
+
+       handle = ext4_journal_start(inode, ext4_writepage_trans_blocks(inode));
+       if (IS_ERR(handle)) {
+               ret = PTR_ERR(handle);
+               goto out;
+       }
+
+       ret = walk_page_buffers(handle, page_bufs, 0, len, NULL,
+                               do_journal_get_write_access);
+
+       err = walk_page_buffers(handle, page_bufs, 0, len, NULL,
+                               write_end_fn);
+       if (ret == 0)
+               ret = err;
+       err = ext4_journal_stop(handle);
+       if (!ret)
+               ret = err;
+
+       walk_page_buffers(handle, page_bufs, 0, len, NULL, bput_one);
+       EXT4_I(inode)->i_state |= EXT4_STATE_JDATA;
+out:
+       return ret;
+}
+
 /*
+ * Note that we don't need to start a transaction unless we're journaling data
+ * because we should have holes filled from ext4_page_mkwrite(). We even don't
+ * need to file the inode to the transaction's list in ordered mode because if
+ * we are writing back data added by write(), the inode is already there and if
+ * we are writing back data modified via mmap(), noone guarantees in which
+ * transaction the data will hit the disk. In case we are journaling data, we
+ * cannot start transaction directly because transaction start ranks above page
+ * lock so we have to do some magic.
+ *
  * This function can get called via...
  *   - ext4_da_writepages after taking page lock (have journal handle)
  *   - journal_submit_inode_data_buffers (no journal handle)
  *   - shrink_page_list via pdflush (no journal handle)
  *   - grab_page_cache when doing write_begin (have journal handle)
+ *
+ * We don't do any block allocation in this function. If we have page with
+ * multiple blocks we need to write those buffer_heads that are mapped. This
+ * is important for mmaped based write. So if we do with blocksize 1K
+ * truncate(f, 1024);
+ * a = mmap(f, 0, 4096);
+ * a[0] = 'a';
+ * truncate(f, 4096);
+ * we have in the page first buffer_head mapped via page_mkwrite call back
+ * but other bufer_heads would be unmapped but dirty(dirty done via the
+ * do_wp_page). So writepage should write the first block. If we modify
+ * the mmap area beyond 1024 we will again get a page_fault and the
+ * page_mkwrite callback will do the block allocation and mark the
+ * buffer_heads mapped.
+ *
+ * We redirty the page if we have any buffer_heads that is either delay or
+ * unwritten in the page.
+ *
+ * We can get recursively called as show below.
+ *
+ *     ext4_writepage() -> kmalloc() -> __alloc_pages() -> page_launder() ->
+ *             ext4_writepage()
+ *
+ * But since we don't do any block allocation we should not deadlock.
+ * Page also have the dirty flag cleared so we don't get recurive page_lock.
  */
-static int ext4_da_writepage(struct page *page,
-                               struct writeback_control *wbc)
+static int ext4_writepage(struct page *page,
+                         struct writeback_control *wbc)
 {
        int ret = 0;
        loff_t size;
@@ -2541,7 +2619,7 @@ static int ext4_da_writepage(struct page *page,
        struct buffer_head *page_bufs;
        struct inode *inode = page->mapping->host;
 
-       trace_ext4_da_writepage(inode, page);
+       trace_ext4_writepage(inode, page);
        size = i_size_read(inode);
        if (page->index == size >> PAGE_CACHE_SHIFT)
                len = size & ~PAGE_CACHE_MASK;
@@ -2551,7 +2629,7 @@ static int ext4_da_writepage(struct page *page,
        if (page_has_buffers(page)) {
                page_bufs = page_buffers(page);
                if (walk_page_buffers(NULL, page_bufs, 0, len, NULL,
-                                       ext4_bh_unmapped_or_delay)) {
+                                       ext4_bh_delay_or_unwritten)) {
                        /*
                         * We don't want to do  block allocation
                         * So redirty the page and return
@@ -2578,13 +2656,13 @@ static int ext4_da_writepage(struct page *page,
                 * all are mapped and non delay. We don't want to
                 * do block allocation here.
                 */
-               ret = block_prepare_write(page, 0, PAGE_CACHE_SIZE,
+               ret = block_prepare_write(page, 0, len,
                                          noalloc_get_block_write);
                if (!ret) {
                        page_bufs = page_buffers(page);
                        /* check whether all are mapped and non delay */
                        if (walk_page_buffers(NULL, page_bufs, 0, len, NULL,
-                                               ext4_bh_unmapped_or_delay)) {
+                                               ext4_bh_delay_or_unwritten)) {
                                redirty_page_for_writepage(wbc, page);
                                unlock_page(page);
                                return 0;
@@ -2600,7 +2678,16 @@ static int ext4_da_writepage(struct page *page,
                        return 0;
                }
                /* now mark the buffer_heads as dirty and uptodate */
-               block_commit_write(page, 0, PAGE_CACHE_SIZE);
+               block_commit_write(page, 0, len);
+       }
+
+       if (PageChecked(page) && ext4_should_journal_data(inode)) {
+               /*
+                * It's mmapped pagecache.  Add buffers and journal it.  There
+                * doesn't seem much point in redirtying the page here.
+                */
+               ClearPageChecked(page);
+               return __ext4_journalled_writepage(page, wbc, len);
        }
 
        if (test_opt(inode->i_sb, NOBH) && ext4_should_writeback_data(inode))
@@ -2907,7 +2994,7 @@ retry:
                 * i_size_read because we hold i_mutex.
                 */
                if (pos + len > inode->i_size)
-                       vmtruncate(inode, inode->i_size);
+                       ext4_truncate(inode);
        }
 
        if (ret == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries))
@@ -3130,222 +3217,6 @@ static sector_t ext4_bmap(struct address_space *mapping, sector_t block)
        return generic_block_bmap(mapping, block, ext4_get_block);
 }
 
-static int bget_one(handle_t *handle, struct buffer_head *bh)
-{
-       get_bh(bh);
-       return 0;
-}
-
-static int bput_one(handle_t *handle, struct buffer_head *bh)
-{
-       put_bh(bh);
-       return 0;
-}
-
-/*
- * Note that we don't need to start a transaction unless we're journaling data
- * because we should have holes filled from ext4_page_mkwrite(). We even don't
- * need to file the inode to the transaction's list in ordered mode because if
- * we are writing back data added by write(), the inode is already there and if
- * we are writing back data modified via mmap(), noone guarantees in which
- * transaction the data will hit the disk. In case we are journaling data, we
- * cannot start transaction directly because transaction start ranks above page
- * lock so we have to do some magic.
- *
- * In all journaling modes block_write_full_page() will start the I/O.
- *
- * Problem:
- *
- *     ext4_writepage() -> kmalloc() -> __alloc_pages() -> page_launder() ->
- *             ext4_writepage()
- *
- * Similar for:
- *
- *     ext4_file_write() -> generic_file_write() -> __alloc_pages() -> ...
- *
- * Same applies to ext4_get_block().  We will deadlock on various things like
- * lock_journal and i_data_sem
- *
- * Setting PF_MEMALLOC here doesn't work - too many internal memory
- * allocations fail.
- *
- * 16May01: If we're reentered then journal_current_handle() will be
- *         non-zero. We simply *return*.
- *
- * 1 July 2001: @@@ FIXME:
- *   In journalled data mode, a data buffer may be metadata against the
- *   current transaction.  But the same file is part of a shared mapping
- *   and someone does a writepage() on it.
- *
- *   We will move the buffer onto the async_data list, but *after* it has
- *   been dirtied. So there's a small window where we have dirty data on
- *   BJ_Metadata.
- *
- *   Note that this only applies to the last partial page in the file.  The
- *   bit which block_write_full_page() uses prepare/commit for.  (That's
- *   broken code anyway: it's wrong for msync()).
- *
- *   It's a rare case: affects the final partial page, for journalled data
- *   where the file is subject to bith write() and writepage() in the same
- *   transction.  To fix it we'll need a custom block_write_full_page().
- *   We'll probably need that anyway for journalling writepage() output.
- *
- * We don't honour synchronous mounts for writepage().  That would be
- * disastrous.  Any write() or metadata operation will sync the fs for
- * us.
- *
- */
-static int __ext4_normal_writepage(struct page *page,
-                                  struct writeback_control *wbc)
-{
-       struct inode *inode = page->mapping->host;
-
-       if (test_opt(inode->i_sb, NOBH))
-               return nobh_writepage(page, noalloc_get_block_write, wbc);
-       else
-               return block_write_full_page(page, noalloc_get_block_write,
-                                            wbc);
-}
-
-static int ext4_normal_writepage(struct page *page,
-                                struct writeback_control *wbc)
-{
-       struct inode *inode = page->mapping->host;
-       loff_t size = i_size_read(inode);
-       loff_t len;
-
-       trace_ext4_normal_writepage(inode, page);
-       J_ASSERT(PageLocked(page));
-       if (page->index == size >> PAGE_CACHE_SHIFT)
-               len = size & ~PAGE_CACHE_MASK;
-       else
-               len = PAGE_CACHE_SIZE;
-
-       if (page_has_buffers(page)) {
-               /* if page has buffers it should all be mapped
-                * and allocated. If there are not buffers attached
-                * to the page we know the page is dirty but it lost
-                * buffers. That means that at some moment in time
-                * after write_begin() / write_end() has been called
-                * all buffers have been clean and thus they must have been
-                * written at least once. So they are all mapped and we can
-                * happily proceed with mapping them and writing the page.
-                */
-               BUG_ON(walk_page_buffers(NULL, page_buffers(page), 0, len, NULL,
-                                       ext4_bh_unmapped_or_delay));
-       }
-
-       if (!ext4_journal_current_handle())
-               return __ext4_normal_writepage(page, wbc);
-
-       redirty_page_for_writepage(wbc, page);
-       unlock_page(page);
-       return 0;
-}
-
-static int __ext4_journalled_writepage(struct page *page,
-                                      struct writeback_control *wbc)
-{
-       struct address_space *mapping = page->mapping;
-       struct inode *inode = mapping->host;
-       struct buffer_head *page_bufs;
-       handle_t *handle = NULL;
-       int ret = 0;
-       int err;
-
-       ret = block_prepare_write(page, 0, PAGE_CACHE_SIZE,
-                                 noalloc_get_block_write);
-       if (ret != 0)
-               goto out_unlock;
-
-       page_bufs = page_buffers(page);
-       walk_page_buffers(handle, page_bufs, 0, PAGE_CACHE_SIZE, NULL,
-                                                               bget_one);
-       /* As soon as we unlock the page, it can go away, but we have
-        * references to buffers so we are safe */
-       unlock_page(page);
-
-       handle = ext4_journal_start(inode, ext4_writepage_trans_blocks(inode));
-       if (IS_ERR(handle)) {
-               ret = PTR_ERR(handle);
-               goto out;
-       }
-
-       ret = walk_page_buffers(handle, page_bufs, 0,
-                       PAGE_CACHE_SIZE, NULL, do_journal_get_write_access);
-
-       err = walk_page_buffers(handle, page_bufs, 0,
-                               PAGE_CACHE_SIZE, NULL, write_end_fn);
-       if (ret == 0)
-               ret = err;
-       err = ext4_journal_stop(handle);
-       if (!ret)
-               ret = err;
-
-       walk_page_buffers(handle, page_bufs, 0,
-                               PAGE_CACHE_SIZE, NULL, bput_one);
-       EXT4_I(inode)->i_state |= EXT4_STATE_JDATA;
-       goto out;
-
-out_unlock:
-       unlock_page(page);
-out:
-       return ret;
-}
-
-static int ext4_journalled_writepage(struct page *page,
-                                    struct writeback_control *wbc)
-{
-       struct inode *inode = page->mapping->host;
-       loff_t size = i_size_read(inode);
-       loff_t len;
-
-       trace_ext4_journalled_writepage(inode, page);
-       J_ASSERT(PageLocked(page));
-       if (page->index == size >> PAGE_CACHE_SHIFT)
-               len = size & ~PAGE_CACHE_MASK;
-       else
-               len = PAGE_CACHE_SIZE;
-
-       if (page_has_buffers(page)) {
-               /* if page has buffers it should all be mapped
-                * and allocated. If there are not buffers attached
-                * to the page we know the page is dirty but it lost
-                * buffers. That means that at some moment in time
-                * after write_begin() / write_end() has been called
-                * all buffers have been clean and thus they must have been
-                * written at least once. So they are all mapped and we can
-                * happily proceed with mapping them and writing the page.
-                */
-               BUG_ON(walk_page_buffers(NULL, page_buffers(page), 0, len, NULL,
-                                       ext4_bh_unmapped_or_delay));
-       }
-
-       if (ext4_journal_current_handle())
-               goto no_write;
-
-       if (PageChecked(page)) {
-               /*
-                * It's mmapped pagecache.  Add buffers and journal it.  There
-                * doesn't seem much point in redirtying the page here.
-                */
-               ClearPageChecked(page);
-               return __ext4_journalled_writepage(page, wbc);
-       } else {
-               /*
-                * It may be a page full of checkpoint-mode buffers.  We don't
-                * really know unless we go poke around in the buffer_heads.
-                * But block_write_full_page will do the right thing.
-                */
-               return block_write_full_page(page, noalloc_get_block_write,
-                                            wbc);
-       }
-no_write:
-       redirty_page_for_writepage(wbc, page);
-       unlock_page(page);
-       return 0;
-}
-
 static int ext4_readpage(struct file *file, struct page *page)
 {
        return mpage_readpage(page, ext4_get_block);
@@ -3492,7 +3363,7 @@ static int ext4_journalled_set_page_dirty(struct page *page)
 static const struct address_space_operations ext4_ordered_aops = {
        .readpage               = ext4_readpage,
        .readpages              = ext4_readpages,
-       .writepage              = ext4_normal_writepage,
+       .writepage              = ext4_writepage,
        .sync_page              = block_sync_page,
        .write_begin            = ext4_write_begin,
        .write_end              = ext4_ordered_write_end,
@@ -3507,7 +3378,7 @@ static const struct address_space_operations ext4_ordered_aops = {
 static const struct address_space_operations ext4_writeback_aops = {
        .readpage               = ext4_readpage,
        .readpages              = ext4_readpages,
-       .writepage              = ext4_normal_writepage,
+       .writepage              = ext4_writepage,
        .sync_page              = block_sync_page,
        .write_begin            = ext4_write_begin,
        .write_end              = ext4_writeback_write_end,
@@ -3522,7 +3393,7 @@ static const struct address_space_operations ext4_writeback_aops = {
 static const struct address_space_operations ext4_journalled_aops = {
        .readpage               = ext4_readpage,
        .readpages              = ext4_readpages,
-       .writepage              = ext4_journalled_writepage,
+       .writepage              = ext4_writepage,
        .sync_page              = block_sync_page,
        .write_begin            = ext4_write_begin,
        .write_end              = ext4_journalled_write_end,
@@ -3536,7 +3407,7 @@ static const struct address_space_operations ext4_journalled_aops = {
 static const struct address_space_operations ext4_da_aops = {
        .readpage               = ext4_readpage,
        .readpages              = ext4_readpages,
-       .writepage              = ext4_da_writepage,
+       .writepage              = ext4_writepage,
        .writepages             = ext4_da_writepages,
        .sync_page              = block_sync_page,
        .write_begin            = ext4_da_write_begin,
@@ -3583,7 +3454,8 @@ int ext4_block_truncate_page(handle_t *handle,
        struct page *page;
        int err = 0;
 
-       page = grab_cache_page(mapping, from >> PAGE_CACHE_SHIFT);
+       page = find_or_create_page(mapping, from >> PAGE_CACHE_SHIFT,
+                                  mapping_gfp_mask(mapping) & ~__GFP_FS);
        if (!page)
                return -EINVAL;
 
index bb41540..7050a9c 100644 (file)
@@ -12,7 +12,6 @@
 #include <linux/capability.h>
 #include <linux/time.h>
 #include <linux/compat.h>
-#include <linux/smp_lock.h>
 #include <linux/mount.h>
 #include <linux/file.h>
 #include <asm/uaccess.h>
@@ -192,7 +191,7 @@ setversion_out:
        case EXT4_IOC_GROUP_EXTEND: {
                ext4_fsblk_t n_blocks_count;
                struct super_block *sb = inode->i_sb;
-               int err, err2;
+               int err, err2=0;
 
                if (!capable(CAP_SYS_RESOURCE))
                        return -EPERM;
@@ -205,9 +204,11 @@ setversion_out:
                        return err;
 
                err = ext4_group_extend(sb, EXT4_SB(sb)->s_es, n_blocks_count);
-               jbd2_journal_lock_updates(EXT4_SB(sb)->s_journal);
-               err2 = jbd2_journal_flush(EXT4_SB(sb)->s_journal);
-               jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal);
+               if (EXT4_SB(sb)->s_journal) {
+                       jbd2_journal_lock_updates(EXT4_SB(sb)->s_journal);
+                       err2 = jbd2_journal_flush(EXT4_SB(sb)->s_journal);
+                       jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal);
+               }
                if (err == 0)
                        err = err2;
                mnt_drop_write(filp->f_path.mnt);
@@ -252,7 +253,7 @@ setversion_out:
        case EXT4_IOC_GROUP_ADD: {
                struct ext4_new_group_data input;
                struct super_block *sb = inode->i_sb;
-               int err, err2;
+               int err, err2=0;
 
                if (!capable(CAP_SYS_RESOURCE))
                        return -EPERM;
@@ -266,9 +267,11 @@ setversion_out:
                        return err;
 
                err = ext4_group_add(sb, &input);
-               jbd2_journal_lock_updates(EXT4_SB(sb)->s_journal);
-               err2 = jbd2_journal_flush(EXT4_SB(sb)->s_journal);
-               jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal);
+               if (EXT4_SB(sb)->s_journal) {
+                       jbd2_journal_lock_updates(EXT4_SB(sb)->s_journal);
+                       err2 = jbd2_journal_flush(EXT4_SB(sb)->s_journal);
+                       jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal);
+               }
                if (err == 0)
                        err = err2;
                mnt_drop_write(filp->f_path.mnt);
index 519a0a6..cd25846 100644 (file)
@@ -657,7 +657,8 @@ static void ext4_mb_mark_free_simple(struct super_block *sb,
        }
 }
 
-static void ext4_mb_generate_buddy(struct super_block *sb,
+static noinline_for_stack
+void ext4_mb_generate_buddy(struct super_block *sb,
                                void *buddy, void *bitmap, ext4_group_t group)
 {
        struct ext4_group_info *grp = ext4_get_group_info(sb, group);
@@ -1480,7 +1481,8 @@ static void ext4_mb_measure_extent(struct ext4_allocation_context *ac,
        ext4_mb_check_limits(ac, e4b, 0);
 }
 
-static int ext4_mb_try_best_found(struct ext4_allocation_context *ac,
+static noinline_for_stack
+int ext4_mb_try_best_found(struct ext4_allocation_context *ac,
                                        struct ext4_buddy *e4b)
 {
        struct ext4_free_extent ex = ac->ac_b_ex;
@@ -1507,7 +1509,8 @@ static int ext4_mb_try_best_found(struct ext4_allocation_context *ac,
        return 0;
 }
 
-static int ext4_mb_find_by_goal(struct ext4_allocation_context *ac,
+static noinline_for_stack
+int ext4_mb_find_by_goal(struct ext4_allocation_context *ac,
                                struct ext4_buddy *e4b)
 {
        ext4_group_t group = ac->ac_g_ex.fe_group;
@@ -1566,7 +1569,8 @@ static int ext4_mb_find_by_goal(struct ext4_allocation_context *ac,
  * The routine scans buddy structures (not bitmap!) from given order
  * to max order and tries to find big enough chunk to satisfy the req
  */
-static void ext4_mb_simple_scan_group(struct ext4_allocation_context *ac,
+static noinline_for_stack
+void ext4_mb_simple_scan_group(struct ext4_allocation_context *ac,
                                        struct ext4_buddy *e4b)
 {
        struct super_block *sb = ac->ac_sb;
@@ -1609,7 +1613,8 @@ static void ext4_mb_simple_scan_group(struct ext4_allocation_context *ac,
  * In order to optimize scanning, caller must pass number of
  * free blocks in the group, so the routine can know upper limit.
  */
-static void ext4_mb_complex_scan_group(struct ext4_allocation_context *ac,
+static noinline_for_stack
+void ext4_mb_complex_scan_group(struct ext4_allocation_context *ac,
                                        struct ext4_buddy *e4b)
 {
        struct super_block *sb = ac->ac_sb;
@@ -1668,7 +1673,8 @@ static void ext4_mb_complex_scan_group(struct ext4_allocation_context *ac,
  * we try to find stripe-aligned chunks for stripe-size requests
  * XXX should do so at least for multiples of stripe size as well
  */
-static void ext4_mb_scan_aligned(struct ext4_allocation_context *ac,
+static noinline_for_stack
+void ext4_mb_scan_aligned(struct ext4_allocation_context *ac,
                                 struct ext4_buddy *e4b)
 {
        struct super_block *sb = ac->ac_sb;
@@ -1831,7 +1837,8 @@ void ext4_mb_put_buddy_cache_lock(struct super_block *sb,
 
 }
 
-static int ext4_mb_init_group(struct super_block *sb, ext4_group_t group)
+static noinline_for_stack
+int ext4_mb_init_group(struct super_block *sb, ext4_group_t group)
 {
 
        int ret;
@@ -2902,7 +2909,11 @@ int __init init_ext4_mballoc(void)
 
 void exit_ext4_mballoc(void)
 {
-       /* XXX: synchronize_rcu(); */
+       /* 
+        * Wait for completion of call_rcu()'s on ext4_pspace_cachep
+        * before destroying the slab cache.
+        */
+       rcu_barrier();
        kmem_cache_destroy(ext4_pspace_cachep);
        kmem_cache_destroy(ext4_ac_cachep);
        kmem_cache_destroy(ext4_free_ext_cachep);
@@ -3457,7 +3468,8 @@ static void ext4_mb_generate_from_freelist(struct super_block *sb, void *bitmap,
  * used in in-core bitmap. buddy must be generated from this bitmap
  * Need to be called with ext4 group lock held
  */
-static void ext4_mb_generate_from_pa(struct super_block *sb, void *bitmap,
+static noinline_for_stack
+void ext4_mb_generate_from_pa(struct super_block *sb, void *bitmap,
                                        ext4_group_t group)
 {
        struct ext4_group_info *grp = ext4_get_group_info(sb, group);
@@ -4215,14 +4227,9 @@ ext4_mb_initialize_context(struct ext4_allocation_context *ac,
        ext4_get_group_no_and_offset(sb, goal, &group, &block);
 
        /* set up allocation goals */
+       memset(ac, 0, sizeof(struct ext4_allocation_context));
        ac->ac_b_ex.fe_logical = ar->logical;
-       ac->ac_b_ex.fe_group = 0;
-       ac->ac_b_ex.fe_start = 0;
-       ac->ac_b_ex.fe_len = 0;
        ac->ac_status = AC_STATUS_CONTINUE;
-       ac->ac_groups_scanned = 0;
-       ac->ac_ex_scanned = 0;
-       ac->ac_found = 0;
        ac->ac_sb = sb;
        ac->ac_inode = ar->inode;
        ac->ac_o_ex.fe_logical = ar->logical;
@@ -4233,15 +4240,7 @@ ext4_mb_initialize_context(struct ext4_allocation_context *ac,
        ac->ac_g_ex.fe_group = group;
        ac->ac_g_ex.fe_start = block;
        ac->ac_g_ex.fe_len = len;
-       ac->ac_f_ex.fe_len = 0;
        ac->ac_flags = ar->flags;
-       ac->ac_2order = 0;
-       ac->ac_criteria = 0;
-       ac->ac_pa = NULL;
-       ac->ac_bitmap_page = NULL;
-       ac->ac_buddy_page = NULL;
-       ac->alloc_semp = NULL;
-       ac->ac_lg = NULL;
 
        /* we have to define context: we'll we work with a file or
         * locality group. this is a policy, actually */
@@ -4509,10 +4508,7 @@ ext4_fsblk_t ext4_mb_new_blocks(handle_t *handle,
        }
 
        ac = kmem_cache_alloc(ext4_ac_cachep, GFP_NOFS);
-       if (ac) {
-               ac->ac_sb = sb;
-               ac->ac_inode = ar->inode;
-       } else {
+       if (!ac) {
                ar->len = 0;
                *errp = -ENOMEM;
                goto out1;
index 38ff75a..530b4ca 100644 (file)
@@ -16,7 +16,6 @@
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/time.h>
-#include <linux/smp_lock.h>
 #include <linux/buffer_head.h>
 #include <linux/compat.h>
 #include <asm/uaccess.h>
index 82f8873..bbc94ae 100644 (file)
@@ -9,7 +9,6 @@
 #include <linux/module.h>
 #include <linux/time.h>
 #include <linux/buffer_head.h>
-#include <linux/smp_lock.h>
 #include "fat.h"
 
 /* Characters that are undesirable in an MS-DOS file name */
index 73471b7..cb6e835 100644 (file)
@@ -19,7 +19,6 @@
 #include <linux/jiffies.h>
 #include <linux/ctype.h>
 #include <linux/slab.h>
-#include <linux/smp_lock.h>
 #include <linux/buffer_head.h>
 #include <linux/namei.h>
 #include "fat.h"
index a040b76..ae41308 100644 (file)
@@ -19,7 +19,6 @@
 #include <linux/signal.h>
 #include <linux/rcupdate.h>
 #include <linux/pid_namespace.h>
-#include <linux/smp_lock.h>
 
 #include <asm/poll.h>
 #include <asm/siginfo.h>
index cdbd165..1e8af93 100644 (file)
@@ -38,6 +38,7 @@
 #include <linux/buffer_head.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
+#include <linux/smp_lock.h>
 #include <linux/stat.h>
 #include <linux/vfs.h>
 #include <linux/mount.h>
index cbceacb..6484eb7 100644 (file)
@@ -16,7 +16,6 @@
 #include <linux/pagemap.h>
 #include <linux/file.h>
 #include <linux/slab.h>
-#include <linux/blkdev.h>
 
 MODULE_ALIAS_MISCDEV(FUSE_MINOR);
 
index 98d6ef1..148d55c 100644 (file)
@@ -1,12 +1,11 @@
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM gfs2
+
 #if !defined(_TRACE_GFS2_H) || defined(TRACE_HEADER_MULTI_READ)
 #define _TRACE_GFS2_H
 
 #include <linux/tracepoint.h>
 
-#undef TRACE_SYSTEM
-#define TRACE_SYSTEM gfs2
-#define TRACE_INCLUDE_FILE trace_gfs2
-
 #include <linux/fs.h>
 #include <linux/buffer_head.h>
 #include <linux/dlmconstants.h>
@@ -403,5 +402,6 @@ TRACE_EVENT(gfs2_block_alloc,
 /* This part must be outside protection */
 #undef TRACE_INCLUDE_PATH
 #define TRACE_INCLUDE_PATH .
+#define TRACE_INCLUDE_FILE trace_gfs2
 #include <trace/define_trace.h>
 
index 6f833dc..f7fcbe4 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/nls.h>
 #include <linux/parser.h>
 #include <linux/seq_file.h>
+#include <linux/smp_lock.h>
 #include <linux/vfs.h>
 
 #include "hfs_fs.h"
index 9fc3af0..c0759fe 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/pagemap.h>
 #include <linux/fs.h>
 #include <linux/slab.h>
+#include <linux/smp_lock.h>
 #include <linux/vfs.h>
 #include <linux/nls.h>
 
index 6916c41..8865c94 100644 (file)
@@ -6,6 +6,7 @@
  *  directory VFS functions
  */
 
+#include <linux/smp_lock.h>
 #include "hpfs_fn.h"
 
 static int hpfs_dir_release(struct inode *inode, struct file *filp)
index 64ab522..3efabff 100644 (file)
@@ -6,6 +6,7 @@
  *  file VFS functions
  */
 
+#include <linux/smp_lock.h>
 #include "hpfs_fn.h"
 
 #define BLOCKS(size) (((size) + 511) >> 9)
index c2ea31b..701ca54 100644 (file)
@@ -13,7 +13,6 @@
 #include <linux/pagemap.h>
 #include <linux/buffer_head.h>
 #include <linux/slab.h>
-#include <linux/smp_lock.h>
 
 #include "hpfs.h"
 
index 39a1bfb..fe703ae 100644 (file)
@@ -6,6 +6,7 @@
  *  inode VFS functions
  */
 
+#include <linux/smp_lock.h>
 #include "hpfs_fn.h"
 
 void hpfs_init_inode(struct inode *i)
index b649232..82b9c4b 100644 (file)
@@ -6,6 +6,7 @@
  *  adding & removing files & directories
  */
 #include <linux/sched.h>
+#include <linux/smp_lock.h>
 #include "hpfs_fn.h"
 
 static int hpfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
index 18bfd5d..e378cb3 100644 (file)
@@ -297,6 +297,7 @@ int jbd2_journal_write_metadata_buffer(transaction_t *transaction,
        unsigned int new_offset;
        struct buffer_head *bh_in = jh2bh(jh_in);
        struct jbd2_buffer_trigger_type *triggers;
+       journal_t *journal = transaction->t_journal;
 
        /*
         * The buffer really shouldn't be locked: only the current committing
@@ -310,6 +311,11 @@ int jbd2_journal_write_metadata_buffer(transaction_t *transaction,
        J_ASSERT_BH(bh_in, buffer_jbddirty(bh_in));
 
        new_bh = alloc_buffer_head(GFP_NOFS|__GFP_NOFAIL);
+       /* keep subsequent assertions sane */
+       new_bh->b_state = 0;
+       init_buffer(new_bh, NULL, NULL);
+       atomic_set(&new_bh->b_count, 1);
+       new_jh = jbd2_journal_add_journal_head(new_bh); /* This sleeps */
 
        /*
         * If a new transaction has already done a buffer copy-out, then
@@ -388,14 +394,6 @@ repeat:
                kunmap_atomic(mapped_data, KM_USER0);
        }
 
-       /* keep subsequent assertions sane */
-       new_bh->b_state = 0;
-       init_buffer(new_bh, NULL, NULL);
-       atomic_set(&new_bh->b_count, 1);
-       jbd_unlock_bh_state(bh_in);
-
-       new_jh = jbd2_journal_add_journal_head(new_bh); /* This sleeps */
-
        set_bh_page(new_bh, new_page, new_offset);
        new_jh->b_transaction = NULL;
        new_bh->b_size = jh2bh(jh_in)->b_size;
@@ -412,7 +410,11 @@ repeat:
         * copying is moved to the transaction's shadow queue.
         */
        JBUFFER_TRACE(jh_in, "file as BJ_Shadow");
-       jbd2_journal_file_buffer(jh_in, transaction, BJ_Shadow);
+       spin_lock(&journal->j_list_lock);
+       __jbd2_journal_file_buffer(jh_in, transaction, BJ_Shadow);
+       spin_unlock(&journal->j_list_lock);
+       jbd_unlock_bh_state(bh_in);
+
        JBUFFER_TRACE(new_jh, "file as BJ_IO");
        jbd2_journal_file_buffer(new_jh, transaction, BJ_IO);
 
@@ -2410,6 +2412,7 @@ const char *jbd2_dev_to_name(dev_t device)
        int     i = hash_32(device, CACHE_SIZE_BITS);
        char    *ret;
        struct block_device *bd;
+       static struct devname_cache *new_dev;
 
        rcu_read_lock();
        if (devcache[i] && devcache[i]->device == device) {
@@ -2419,20 +2422,20 @@ const char *jbd2_dev_to_name(dev_t device)
        }
        rcu_read_unlock();
 
+       new_dev = kmalloc(sizeof(struct devname_cache), GFP_KERNEL);
+       if (!new_dev)
+               return "NODEV-ALLOCFAILURE"; /* Something non-NULL */
        spin_lock(&devname_cache_lock);
        if (devcache[i]) {
                if (devcache[i]->device == device) {
+                       kfree(new_dev);
                        ret = devcache[i]->devname;
                        spin_unlock(&devname_cache_lock);
                        return ret;
                }
                call_rcu(&devcache[i]->rcu, free_devcache);
        }
-       devcache[i] = kmalloc(sizeof(struct devname_cache), GFP_KERNEL);
-       if (!devcache[i]) {
-               spin_unlock(&devname_cache_lock);
-               return "NODEV-ALLOCFAILURE"; /* Something non-NULL */
-       }
+       devcache[i] = new_dev;
        devcache[i]->device = device;
        bd = bdget(device);
        if (bd) {
index 494501e..6213ac7 100644 (file)
@@ -499,34 +499,15 @@ void jbd2_journal_unlock_updates (journal_t *journal)
        wake_up(&journal->j_wait_transaction_locked);
 }
 
-/*
- * Report any unexpected dirty buffers which turn up.  Normally those
- * indicate an error, but they can occur if the user is running (say)
- * tune2fs to modify the live filesystem, so we need the option of
- * continuing as gracefully as possible.  #
- *
- * The caller should already hold the journal lock and
- * j_list_lock spinlock: most callers will need those anyway
- * in order to probe the buffer's journaling state safely.
- */
-static void jbd_unexpected_dirty_buffer(struct journal_head *jh)
+static void warn_dirty_buffer(struct buffer_head *bh)
 {
-       int jlist;
-
-       /* If this buffer is one which might reasonably be dirty
-        * --- ie. data, or not part of this journal --- then
-        * we're OK to leave it alone, but otherwise we need to
-        * move the dirty bit to the journal's own internal
-        * JBDDirty bit. */
-       jlist = jh->b_jlist;
+       char b[BDEVNAME_SIZE];
 
-       if (jlist == BJ_Metadata || jlist == BJ_Reserved ||
-           jlist == BJ_Shadow || jlist == BJ_Forget) {
-               struct buffer_head *bh = jh2bh(jh);
-
-               if (test_clear_buffer_dirty(bh))
-                       set_buffer_jbddirty(bh);
-       }
+       printk(KERN_WARNING
+              "JBD: Spotted dirty metadata buffer (dev = %s, blocknr = %llu). "
+              "There's a risk of filesystem corruption in case of system "
+              "crash.\n",
+              bdevname(bh->b_bdev, b), (unsigned long long)bh->b_blocknr);
 }
 
 /*
@@ -593,14 +574,16 @@ repeat:
                        if (jh->b_next_transaction)
                                J_ASSERT_JH(jh, jh->b_next_transaction ==
                                                        transaction);
+                       warn_dirty_buffer(bh);
                }
                /*
                 * In any case we need to clean the dirty flag and we must
                 * do it under the buffer lock to be sure we don't race
                 * with running write-out.
                 */
-               JBUFFER_TRACE(jh, "Unexpected dirty buffer");
-               jbd_unexpected_dirty_buffer(jh);
+               JBUFFER_TRACE(jh, "Journalling dirty buffer");
+               clear_buffer_dirty(bh);
+               set_buffer_jbddirty(bh);
        }
 
        unlock_buffer(bh);
@@ -843,6 +826,15 @@ int jbd2_journal_get_create_access(handle_t *handle, struct buffer_head *bh)
        J_ASSERT_JH(jh, buffer_locked(jh2bh(jh)));
 
        if (jh->b_transaction == NULL) {
+               /*
+                * Previous jbd2_journal_forget() could have left the buffer
+                * with jbddirty bit set because it was being committed. When
+                * the commit finished, we've filed the buffer for
+                * checkpointing and marked it dirty. Now we are reallocating
+                * the buffer so the transaction freeing it must have
+                * committed and so it's safe to clear the dirty bit.
+                */
+               clear_buffer_dirty(jh2bh(jh));
                jh->b_transaction = transaction;
 
                /* first access by this transaction */
@@ -1644,8 +1636,13 @@ static int __dispose_buffer(struct journal_head *jh, transaction_t *transaction)
 
        if (jh->b_cp_transaction) {
                JBUFFER_TRACE(jh, "on running+cp transaction");
+               /*
+                * We don't want to write the buffer anymore, clear the
+                * bit so that we don't confuse checks in
+                * __journal_file_buffer
+                */
+               clear_buffer_dirty(bh);
                __jbd2_journal_file_buffer(jh, transaction, BJ_Forget);
-               clear_buffer_jbddirty(bh);
                may_free = 0;
        } else {
                JBUFFER_TRACE(jh, "on running transaction");
@@ -1896,12 +1893,17 @@ void __jbd2_journal_file_buffer(struct journal_head *jh,
        if (jh->b_transaction && jh->b_jlist == jlist)
                return;
 
-       /* The following list of buffer states needs to be consistent
-        * with __jbd_unexpected_dirty_buffer()'s handling of dirty
-        * state. */
-
        if (jlist == BJ_Metadata || jlist == BJ_Reserved ||
            jlist == BJ_Shadow || jlist == BJ_Forget) {
+               /*
+                * For metadata buffers, we track dirty bit in buffer_jbddirty
+                * instead of buffer_dirty. We should not see a dirty bit set
+                * here because we clear it in do_get_write_access but e.g.
+                * tune2fs can modify the sb and set the dirty bit at any time
+                * so we try to gracefully handle that.
+                */
+               if (buffer_dirty(bh))
+                       warn_dirty_buffer(bh);
                if (test_clear_buffer_dirty(bh) ||
                    test_clear_buffer_jbddirty(bh))
                        was_dirty = 1;
index 07a22ca..0035c02 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/slab.h>
+#include <linux/smp_lock.h>
 #include <linux/init.h>
 #include <linux/list.h>
 #include <linux/fs.h>
index f2fdcbc..4336adb 100644 (file)
@@ -7,6 +7,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/smp_lock.h>
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <linux/fs.h>
index 1725037..bd173a6 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/types.h>
 #include <linux/time.h>
 #include <linux/slab.h>
+#include <linux/smp_lock.h>
 #include <linux/in.h>
 #include <linux/sunrpc/svc.h>
 #include <linux/sunrpc/clnt.h>
index 3688e55..e1d28dd 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/types.h>
 #include <linux/time.h>
 #include <linux/slab.h>
+#include <linux/smp_lock.h>
 #include <linux/in.h>
 #include <linux/sunrpc/svc.h>
 #include <linux/sunrpc/clnt.h>
index af05b91..6dd48a4 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/kthread.h>
 #include <linux/module.h>
 #include <linux/sched.h>
+#include <linux/smp_lock.h>
 #include <linux/spinlock.h>
 
 #include <linux/nfs4.h>
index 89f98e9..38d42c2 100644 (file)
@@ -29,7 +29,6 @@
 #include <linux/nfs_fs.h>
 #include <linux/nfs_mount.h>
 #include <linux/pagemap.h>
-#include <linux/smp_lock.h>
 #include <linux/pagevec.h>
 #include <linux/namei.h>
 #include <linux/mount.h>
index 0055b81..0506232 100644 (file)
@@ -26,7 +26,6 @@
 #include <linux/mm.h>
 #include <linux/slab.h>
 #include <linux/pagemap.h>
-#include <linux/smp_lock.h>
 #include <linux/aio.h>
 
 #include <asm/uaccess.h>
index 64f8719..bd7938e 100644 (file)
@@ -30,7 +30,6 @@
 #include <linux/nfs_mount.h>
 #include <linux/nfs4_mount.h>
 #include <linux/lockd/bind.h>
-#include <linux/smp_lock.h>
 #include <linux/seq_file.h>
 #include <linux/mount.h>
 #include <linux/nfs_idmap.h>
index 92ce435..ff0c080 100644 (file)
@@ -45,7 +45,6 @@
 #include <linux/nfs4.h>
 #include <linux/nfs_fs.h>
 #include <linux/nfs_page.h>
-#include <linux/smp_lock.h>
 #include <linux/namei.h>
 #include <linux/mount.h>
 #include <linux/module.h>
index 96c4ebf..73ea5e8 100644 (file)
@@ -18,7 +18,6 @@
 #include <linux/sunrpc/clnt.h>
 #include <linux/nfs_fs.h>
 #include <linux/nfs_page.h>
-#include <linux/smp_lock.h>
 
 #include <asm/system.h>
 
index 35d8131..0a0a2ff 100644 (file)
@@ -19,7 +19,6 @@
 #include <linux/nfs_mount.h>
 #include <linux/nfs_page.h>
 #include <linux/backing-dev.h>
-#include <linux/blkdev.h>
 
 #include <asm/uaccess.h>
 
index 1250fb9..6d08475 100644 (file)
@@ -25,7 +25,6 @@
 #include <linux/init.h>
 #include <linux/inet.h>
 #include <linux/string.h>
-#include <linux/smp_lock.h>
 #include <linux/ctype.h>
 
 #include <linux/nfs.h>
index d4c9884..492c79b 100644 (file)
@@ -18,7 +18,6 @@
 #include <linux/unistd.h>
 #include <linux/slab.h>
 #include <linux/smp.h>
-#include <linux/smp_lock.h>
 #include <linux/freezer.h>
 #include <linux/fs_struct.h>
 #include <linux/kthread.h>
index 54100ac..1a4fa04 100644 (file)
@@ -43,7 +43,6 @@
  */
 
 #include <linux/pagemap.h>
-#include <linux/smp_lock.h>
 #include "nilfs.h"
 #include "page.h"
 
index 9fcd36d..467b413 100644 (file)
@@ -7,7 +7,6 @@
 
 #include <linux/fs.h>
 #include <linux/mount.h>
-#include <linux/smp_lock.h>
 
 #define MLOG_MASK_PREFIX ML_INODE
 #include <cluster/masklog.h>
index 1a9c787..ea4e6cb 100644 (file)
@@ -436,7 +436,7 @@ struct hd_struct *add_partition(struct gendisk *disk, int partno,
        rcu_assign_pointer(ptbl->part[partno], p);
 
        /* suppress uevent if the disk supresses it */
-       if (!dev_get_uevent_suppress(pdev))
+       if (!dev_get_uevent_suppress(ddev))
                kobject_uevent(&pdev->kobj, KOBJ_ADD);
 
        return p;
index f3d47d8..6925b83 100644 (file)
@@ -46,7 +46,6 @@
 #include <linux/reiserfs_acl.h>
 #include <asm/uaccess.h>
 #include <net/checksum.h>
-#include <linux/smp_lock.h>
 #include <linux/stat.h>
 #include <linux/quotaops.h>
 
index 3b52770..cb5fc57 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/fs.h>
 #include <linux/vfs.h>
 #include <linux/slab.h>
+#include <linux/smp_lock.h>
 #include <linux/mutex.h>
 #include <linux/pagemap.h>
 #include <linux/init.h>
index 6db7a6b..8aacd64 100644 (file)
@@ -25,7 +25,6 @@
 /* This file implements EXT2-compatible extended attribute ioctl() calls */
 
 #include <linux/compat.h>
-#include <linux/smp_lock.h>
 #include <linux/mount.h>
 #include "ubifs.h"
 
index f4e2554..0542fd5 100644 (file)
@@ -41,7 +41,6 @@
 #include "xfs_ioctl.h"
 
 #include <linux/dcache.h>
-#include <linux/smp_lock.h>
 
 static struct vm_operations_struct xfs_file_vm_ops;
 
index 3a52a63..1d52425 100644 (file)
@@ -229,6 +229,11 @@ static inline int bdi_rw_congested(struct backing_dev_info *bdi)
                                  (1 << BDI_async_congested));
 }
 
+enum {
+       BLK_RW_ASYNC    = 0,
+       BLK_RW_SYNC     = 1,
+};
+
 void clear_bdi_congested(struct backing_dev_info *bdi, int sync);
 void set_bdi_congested(struct backing_dev_info *bdi, int sync);
 long congestion_wait(int sync, long timeout);
index 0146e0f..e7cb5db 100644 (file)
@@ -70,11 +70,6 @@ enum rq_cmd_type_bits {
        REQ_TYPE_ATA_PC,
 };
 
-enum {
-       BLK_RW_ASYNC    = 0,
-       BLK_RW_SYNC     = 1,
-};
-
 /*
  * For request of type REQ_TYPE_LINUX_BLOCK, rq->cmd[0] is the opcode being
  * sent down (similar to how REQ_TYPE_BLOCK_PC means that ->cmd[] holds a
index 2dac064..0026f26 100644 (file)
@@ -3,7 +3,6 @@
 
 #ifdef CONFIG_CRASH_DUMP
 #include <linux/kexec.h>
-#include <linux/smp_lock.h>
 #include <linux/device.h>
 #include <linux/proc_fs.h>
 
index ed4e39f..aebb810 100644 (file)
@@ -25,8 +25,6 @@
 #include <asm/atomic.h>
 #include <asm/device.h>
 
-#define BUS_ID_SIZE            20
-
 struct device;
 struct device_private;
 struct device_driver;
index 4525747..8246c69 100644 (file)
@@ -2,7 +2,9 @@
 #define LINUX_HARDIRQ_H
 
 #include <linux/preempt.h>
+#ifdef CONFIG_PREEMPT
 #include <linux/smp_lock.h>
+#endif
 #include <linux/lockdep.h>
 #include <linux/ftrace_irq.h>
 #include <asm/hardirq.h>
index 7796aed..6a63807 100644 (file)
@@ -27,6 +27,7 @@ extern void kmemleak_init(void);
 extern void kmemleak_alloc(const void *ptr, size_t size, int min_count,
                           gfp_t gfp);
 extern void kmemleak_free(const void *ptr);
+extern void kmemleak_free_part(const void *ptr, size_t size);
 extern void kmemleak_padding(const void *ptr, unsigned long offset,
                             size_t size);
 extern void kmemleak_not_leak(const void *ptr);
@@ -71,6 +72,9 @@ static inline void kmemleak_alloc_recursive(const void *ptr, size_t size,
 static inline void kmemleak_free(const void *ptr)
 {
 }
+static inline void kmemleak_free_part(const void *ptr, size_t size)
+{
+}
 static inline void kmemleak_free_recursive(const void *ptr, unsigned long flags)
 {
 }
index a84e9ff..1261208 100644 (file)
@@ -40,7 +40,10 @@ enum {
  * Security-relevant compatibility flags that must be
  * cleared upon setuid or setgid exec:
  */
-#define PER_CLEAR_ON_SETID (READ_IMPLIES_EXEC|ADDR_NO_RANDOMIZE)
+#define PER_CLEAR_ON_SETID (READ_IMPLIES_EXEC  | \
+                           ADDR_NO_RANDOMIZE  | \
+                           ADDR_COMPAT_LAYOUT | \
+                           MMAP_PAGE_ZERO)
 
 /*
  * Personality types.
index 7bc4575..26361c4 100644 (file)
@@ -7,7 +7,6 @@
 #ifndef _LINUX_QUOTAOPS_
 #define _LINUX_QUOTAOPS_
 
-#include <linux/smp_lock.h>
 #include <linux/fs.h>
 
 static inline struct quota_info *sb_dqopt(struct super_block *sb)
index b47b3f0..f2c69a2 100644 (file)
@@ -1342,12 +1342,12 @@ static inline int skb_network_offset(const struct sk_buff *skb)
  * shifting the start of the packet by 2 bytes. Drivers should do this
  * with:
  *
- * skb_reserve(NET_IP_ALIGN);
+ * skb_reserve(skb, NET_IP_ALIGN);
  *
  * The downside to this alignment of the IP header is that the DMA is now
  * unaligned. On some architectures the cost of an unaligned DMA is high
  * and this cost outweighs the gains made by aligning the IP header.
- * 
+ *
  * Since this trade off varies between architectures, we allow NET_IP_ALIGN
  * to be overridden.
  */
index 4dcbc2c..c1c862b 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/workqueue.h>
 #include <linux/kobject.h>
 #include <linux/kmemtrace.h>
+#include <linux/kmemleak.h>
 
 enum stat_item {
        ALLOC_FASTPATH,         /* Allocation from cpu slab */
@@ -233,6 +234,7 @@ static __always_inline void *kmalloc_large(size_t size, gfp_t flags)
        unsigned int order = get_order(size);
        void *ret = (void *) __get_free_pages(flags | __GFP_COMP, order);
 
+       kmemleak_alloc(ret, size, 1, flags);
        trace_kmalloc(_THIS_IP_, ret, size, PAGE_SIZE << order, flags);
 
        return ret;
index d8910b6..b99c625 100644 (file)
@@ -12,7 +12,6 @@
 #include <linux/uio.h>
 #include <asm/byteorder.h>
 #include <linux/scatterlist.h>
-#include <linux/smp_lock.h>
 
 /*
  * Buffer adjustment
index 84929e9..b1e3c2f 100644 (file)
@@ -888,8 +888,6 @@ struct usb_driver {
  * struct usb_device_driver - identifies USB device driver to usbcore
  * @name: The driver name should be unique among USB drivers,
  *     and should normally be the same as the module name.
- * @nodename: Callback to provide a naming hint for a possible
- *     device node to create.
  * @probe: Called to see if the driver is willing to manage a particular
  *     device.  If it is, probe returns zero and uses dev_set_drvdata()
  *     to associate driver-specific data with the device.  If unwilling
@@ -924,6 +922,8 @@ extern struct bus_type usb_bus_type;
 /**
  * struct usb_class_driver - identifies a USB driver that wants to use the USB major number
  * @name: the usb class device name for this driver.  Will show up in sysfs.
+ * @nodename: Callback to provide a naming hint for a possible
+ *     device node to create.
  * @fops: pointer to the struct file_operations of this driver.
  * @minor_base: the start of the minor range for this driver.
  *
@@ -1046,6 +1046,8 @@ typedef void (*usb_complete_t)(struct urb *);
  *     the device driver is saying that it provided this DMA address,
  *     which the host controller driver should use in preference to the
  *     transfer_buffer.
+ * @sg: scatter gather buffer list
+ * @num_sgs: number of entries in the sg list
  * @transfer_buffer_length: How big is transfer_buffer.  The transfer may
  *     be broken up into chunks according to the current maximum packet
  *     size for the endpoint, which is a function of the configuration
diff --git a/include/linux/usb/langwell_otg.h b/include/linux/usb/langwell_otg.h
deleted file mode 100644 (file)
index e115ae6..0000000
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * Intel Langwell USB OTG transceiver driver
- * Copyright (C) 2008, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope 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.
- *
- */
-
-#ifndef __LANGWELL_OTG_H__
-#define __LANGWELL_OTG_H__
-
-/* notify transceiver driver about OTG events */
-extern void langwell_update_transceiver(void);
-/* HCD register bus driver */
-extern int langwell_register_host(struct pci_driver *host_driver);
-/* HCD unregister bus driver */
-extern void langwell_unregister_host(struct pci_driver *host_driver);
-/* DCD register bus driver */
-extern int langwell_register_peripheral(struct pci_driver *client_driver);
-/* DCD unregister bus driver */
-extern void langwell_unregister_peripheral(struct pci_driver *client_driver);
-/* No silent failure, output warning message */
-extern void langwell_otg_nsf_msg(unsigned long message);
-
-#define CI_USBCMD              0x30
-#      define USBCMD_RST               BIT(1)
-#      define USBCMD_RS                BIT(0)
-#define CI_USBSTS              0x34
-#      define USBSTS_SLI               BIT(8)
-#      define USBSTS_URI               BIT(6)
-#      define USBSTS_PCI               BIT(2)
-#define CI_PORTSC1             0x74
-#      define PORTSC_PP                BIT(12)
-#      define PORTSC_LS                (BIT(11) | BIT(10))
-#      define PORTSC_SUSP              BIT(7)
-#      define PORTSC_CCS               BIT(0)
-#define CI_HOSTPC1             0xb4
-#      define HOSTPC1_PHCD             BIT(22)
-#define CI_OTGSC               0xf4
-#      define OTGSC_DPIE               BIT(30)
-#      define OTGSC_1MSE               BIT(29)
-#      define OTGSC_BSEIE              BIT(28)
-#      define OTGSC_BSVIE              BIT(27)
-#      define OTGSC_ASVIE              BIT(26)
-#      define OTGSC_AVVIE              BIT(25)
-#      define OTGSC_IDIE               BIT(24)
-#      define OTGSC_DPIS               BIT(22)
-#      define OTGSC_1MSS               BIT(21)
-#      define OTGSC_BSEIS              BIT(20)
-#      define OTGSC_BSVIS              BIT(19)
-#      define OTGSC_ASVIS              BIT(18)
-#      define OTGSC_AVVIS              BIT(17)
-#      define OTGSC_IDIS               BIT(16)
-#      define OTGSC_DPS                BIT(14)
-#      define OTGSC_1MST               BIT(13)
-#      define OTGSC_BSE                BIT(12)
-#      define OTGSC_BSV                BIT(11)
-#      define OTGSC_ASV                BIT(10)
-#      define OTGSC_AVV                BIT(9)
-#      define OTGSC_ID                 BIT(8)
-#      define OTGSC_HABA               BIT(7)
-#      define OTGSC_HADP               BIT(6)
-#      define OTGSC_IDPU               BIT(5)
-#      define OTGSC_DP                 BIT(4)
-#      define OTGSC_OT                 BIT(3)
-#      define OTGSC_HAAR               BIT(2)
-#      define OTGSC_VC                 BIT(1)
-#      define OTGSC_VD                 BIT(0)
-#      define OTGSC_INTEN_MASK         (0x7f << 24)
-#      define OTGSC_INTSTS_MASK        (0x7f << 16)
-#define CI_USBMODE             0xf8
-#      define USBMODE_CM               (BIT(1) | BIT(0))
-#      define USBMODE_IDLE             0
-#      define USBMODE_DEVICE           0x2
-#      define USBMODE_HOST             0x3
-
-#define INTR_DUMMY_MASK (USBSTS_SLI | USBSTS_URI | USBSTS_PCI)
-
-struct otg_hsm {
-       /* Input */
-       int a_bus_resume;
-       int a_bus_suspend;
-       int a_conn;
-       int a_sess_vld;
-       int a_srp_det;
-       int a_vbus_vld;
-       int b_bus_resume;
-       int b_bus_suspend;
-       int b_conn;
-       int b_se0_srp;
-       int b_sess_end;
-       int b_sess_vld;
-       int id;
-
-       /* Internal variables */
-       int a_set_b_hnp_en;
-       int b_srp_done;
-       int b_hnp_enable;
-
-       /* Timeout indicator for timers */
-       int a_wait_vrise_tmout;
-       int a_wait_bcon_tmout;
-       int a_aidl_bdis_tmout;
-       int b_ase0_brst_tmout;
-       int b_bus_suspend_tmout;
-       int b_srp_res_tmout;
-
-       /* Informative variables */
-       int a_bus_drop;
-       int a_bus_req;
-       int a_clr_err;
-       int a_suspend_req;
-       int b_bus_req;
-
-       /* Output */
-       int drv_vbus;
-       int loc_conn;
-       int loc_sof;
-
-       /* Others */
-       int b_bus_suspend_vld;
-};
-
-#define TA_WAIT_VRISE  100
-#define TA_WAIT_BCON   30000
-#define TA_AIDL_BDIS   15000
-#define TB_ASE0_BRST   5000
-#define TB_SE0_SRP     2
-#define TB_SRP_RES     100
-#define TB_BUS_SUSPEND 500
-
-struct langwell_otg_timer {
-       unsigned long expires;  /* Number of count increase to timeout */
-       unsigned long count;    /* Tick counter */
-       void (*function)(unsigned long);        /* Timeout function */
-       unsigned long data;     /* Data passed to function */
-       struct list_head list;
-};
-
-struct langwell_otg {
-       struct otg_transceiver  otg;
-       struct otg_hsm          hsm;
-       void __iomem            *regs;
-       unsigned                region;
-       struct pci_driver       *host_ops;
-       struct pci_driver       *client_ops;
-       struct pci_dev          *pdev;
-       struct work_struct      work;
-       struct workqueue_struct *qwork;
-       spinlock_t              lock;
-       spinlock_t              wq_lock;
-};
-
-static inline struct langwell_otg *otg_to_langwell(struct otg_transceiver *otg)
-{
-       return container_of(otg, struct langwell_otg, otg);
-}
-
-#ifdef DEBUG
-#define otg_dbg(fmt, args...) \
-       printk(KERN_DEBUG fmt , ## args)
-#else
-#define otg_dbg(fmt, args...) \
-       do { } while (0)
-#endif /* DEBUG */
-#endif /* __LANGWELL_OTG_H__ */
index d6b05f4..9a74b46 100644 (file)
@@ -1,3 +1,6 @@
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM block
+
 #if !defined(_TRACE_BLOCK_H) || defined(TRACE_HEADER_MULTI_READ)
 #define _TRACE_BLOCK_H
 
@@ -5,9 +8,6 @@
 #include <linux/blkdev.h>
 #include <linux/tracepoint.h>
 
-#undef TRACE_SYSTEM
-#define TRACE_SYSTEM block
-
 TRACE_EVENT(block_rq_abort,
 
        TP_PROTO(struct request_queue *q, struct request *rq),
index acf4cc9..7d8b5bc 100644 (file)
@@ -1,9 +1,9 @@
-#if !defined(_TRACE_EXT4_H) || defined(TRACE_HEADER_MULTI_READ)
-#define _TRACE_EXT4_H
-
 #undef TRACE_SYSTEM
 #define TRACE_SYSTEM ext4
 
+#if !defined(_TRACE_EXT4_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_EXT4_H
+
 #include <linux/writeback.h>
 #include "../../../fs/ext4/ext4.h"
 #include "../../../fs/ext4/mballoc.h"
@@ -34,7 +34,8 @@ TRACE_EVENT(ext4_free_inode,
 
        TP_printk("dev %s ino %lu mode %d uid %u gid %u blocks %llu",
                  jbd2_dev_to_name(__entry->dev), __entry->ino, __entry->mode,
-                 __entry->uid, __entry->gid, __entry->blocks)
+                 __entry->uid, __entry->gid,
+                 (unsigned long long) __entry->blocks)
 );
 
 TRACE_EVENT(ext4_request_inode,
@@ -189,7 +190,7 @@ TRACE_EVENT(ext4_journalled_write_end,
                  __entry->copied)
 );
 
-TRACE_EVENT(ext4_da_writepage,
+TRACE_EVENT(ext4_writepage,
        TP_PROTO(struct inode *inode, struct page *page),
 
        TP_ARGS(inode, page),
@@ -341,49 +342,6 @@ TRACE_EVENT(ext4_da_write_end,
                  __entry->copied)
 );
 
-TRACE_EVENT(ext4_normal_writepage,
-       TP_PROTO(struct inode *inode, struct page *page),
-
-       TP_ARGS(inode, page),
-
-       TP_STRUCT__entry(
-               __field(        dev_t,  dev                     )
-               __field(        ino_t,  ino                     )
-               __field(        pgoff_t, index                  )
-       ),
-
-       TP_fast_assign(
-               __entry->dev    = inode->i_sb->s_dev;
-               __entry->ino    = inode->i_ino;
-               __entry->index  = page->index;
-       ),
-
-       TP_printk("dev %s ino %lu page_index %lu",
-                 jbd2_dev_to_name(__entry->dev), __entry->ino, __entry->index)
-);
-
-TRACE_EVENT(ext4_journalled_writepage,
-       TP_PROTO(struct inode *inode, struct page *page),
-
-       TP_ARGS(inode, page),
-
-       TP_STRUCT__entry(
-               __field(        dev_t,  dev                     )
-               __field(        ino_t,  ino                     )
-               __field(        pgoff_t, index                  )
-
-       ),
-
-       TP_fast_assign(
-               __entry->dev    = inode->i_sb->s_dev;
-               __entry->ino    = inode->i_ino;
-               __entry->index  = page->index;
-       ),
-
-       TP_printk("dev %s ino %lu page_index %lu",
-                 jbd2_dev_to_name(__entry->dev), __entry->ino, __entry->index)
-);
-
 TRACE_EVENT(ext4_discard_blocks,
        TP_PROTO(struct super_block *sb, unsigned long long blk,
                        unsigned long long count),
index b0c7ede..1cb0c3a 100644 (file)
@@ -1,12 +1,12 @@
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM irq
+
 #if !defined(_TRACE_IRQ_H) || defined(TRACE_HEADER_MULTI_READ)
 #define _TRACE_IRQ_H
 
 #include <linux/tracepoint.h>
 #include <linux/interrupt.h>
 
-#undef TRACE_SYSTEM
-#define TRACE_SYSTEM irq
-
 #define softirq_name(sirq) { sirq##_SOFTIRQ, #sirq }
 #define show_softirq_name(val)                 \
        __print_symbolic(val,                   \
index 845b0b4..10813fa 100644 (file)
@@ -1,12 +1,12 @@
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM jbd2
+
 #if !defined(_TRACE_JBD2_H) || defined(TRACE_HEADER_MULTI_READ)
 #define _TRACE_JBD2_H
 
 #include <linux/jbd2.h>
 #include <linux/tracepoint.h>
 
-#undef TRACE_SYSTEM
-#define TRACE_SYSTEM jbd2
-
 TRACE_EVENT(jbd2_checkpoint,
 
        TP_PROTO(journal_t *journal, int result),
index 9baba50..1493c54 100644 (file)
@@ -1,12 +1,12 @@
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM kmem
+
 #if !defined(_TRACE_KMEM_H) || defined(TRACE_HEADER_MULTI_READ)
 #define _TRACE_KMEM_H
 
 #include <linux/types.h>
 #include <linux/tracepoint.h>
 
-#undef TRACE_SYSTEM
-#define TRACE_SYSTEM kmem
-
 /*
  * The order of these masks is important. Matching masks will be seen
  * first and the left over flags will end up showing by themselves.
index 0e956c9..bcf1d20 100644 (file)
@@ -1,12 +1,12 @@
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM lockdep
+
 #if !defined(_TRACE_LOCKDEP_H) || defined(TRACE_HEADER_MULTI_READ)
 #define _TRACE_LOCKDEP_H
 
 #include <linux/lockdep.h>
 #include <linux/tracepoint.h>
 
-#undef TRACE_SYSTEM
-#define TRACE_SYSTEM lockdep
-
 #ifdef CONFIG_LOCKDEP
 
 TRACE_EVENT(lock_acquire,
index 24ab5bc..8949bb7 100644 (file)
@@ -1,12 +1,12 @@
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM sched
+
 #if !defined(_TRACE_SCHED_H) || defined(TRACE_HEADER_MULTI_READ)
 #define _TRACE_SCHED_H
 
 #include <linux/sched.h>
 #include <linux/tracepoint.h>
 
-#undef TRACE_SYSTEM
-#define TRACE_SYSTEM sched
-
 /*
  * Tracepoint for calling kthread_stop, performed to end a kthread:
  */
index 1e8fabb..e499863 100644 (file)
@@ -1,12 +1,12 @@
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM skb
+
 #if !defined(_TRACE_SKB_H) || defined(TRACE_HEADER_MULTI_READ)
 #define _TRACE_SKB_H
 
 #include <linux/skbuff.h>
 #include <linux/tracepoint.h>
 
-#undef TRACE_SYSTEM
-#define TRACE_SYSTEM skb
-
 /*
  * Tracepoint for free an sk_buff:
  */
index 035f1bf..fcfd9a1 100644 (file)
@@ -1,3 +1,6 @@
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM workqueue
+
 #if !defined(_TRACE_WORKQUEUE_H) || defined(TRACE_HEADER_MULTI_READ)
 #define _TRACE_WORKQUEUE_H
 
@@ -5,9 +8,6 @@
 #include <linux/sched.h>
 #include <linux/tracepoint.h>
 
-#undef TRACE_SYSTEM
-#define TRACE_SYSTEM workqueue
-
 TRACE_EVENT(workqueue_insertion,
 
        TP_PROTO(struct task_struct *wq_thread, struct work_struct *work),
index 794c862..0672ff8 100644 (file)
@@ -247,6 +247,7 @@ again:
        if (err < 0)
                return err;
 
+       page = compound_head(page);
        lock_page(page);
        if (!page->mapping) {
                unlock_page(page);
index 5fa1db4..31310b5 100644 (file)
@@ -36,7 +36,6 @@
 #include <linux/pid_namespace.h>
 #include <linux/init_task.h>
 #include <linux/syscalls.h>
-#include <linux/kmemleak.h>
 
 #define pid_hashfn(nr, ns)     \
        hash_long((unsigned long)nr + (unsigned long)ns, pidhash_shift)
@@ -513,12 +512,6 @@ void __init pidhash_init(void)
        pid_hash = alloc_bootmem(pidhash_size * sizeof(*(pid_hash)));
        if (!pid_hash)
                panic("Could not alloc pidhash!\n");
-       /*
-        * pid_hash contains references to allocated struct pid objects and it
-        * must be scanned by kmemleak to avoid false positives.
-        */
-       kmemleak_alloc(pid_hash, pidhash_size * sizeof(*(pid_hash)), 0,
-                      GFP_KERNEL);
        for (i = 0; i < pidhash_size; i++)
                INIT_HLIST_HEAD(&pid_hash[i]);
 }
index ed97375..bf0014d 100644 (file)
@@ -23,7 +23,6 @@
 #include <linux/console.h>
 #include <linux/cpu.h>
 #include <linux/freezer.h>
-#include <linux/smp_lock.h>
 #include <scsi/scsi_scan.h>
 
 #include <asm/uaccess.h>
index 39af8af..1090b0a 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/init.h>
 #include <linux/mutex.h>
 #include <linux/debugfs.h>
+#include <linux/smp_lock.h>
 #include <linux/time.h>
 #include <linux/uaccess.h>
 
index bce9e01..4521c77 100644 (file)
@@ -768,7 +768,7 @@ static struct tracer_stat function_stats __initdata = {
        .stat_show      = function_stat_show
 };
 
-static void ftrace_profile_debugfs(struct dentry *d_tracer)
+static __init void ftrace_profile_debugfs(struct dentry *d_tracer)
 {
        struct ftrace_profile_stat *stat;
        struct dentry *entry;
@@ -786,7 +786,6 @@ static void ftrace_profile_debugfs(struct dentry *d_tracer)
                         * The files created are permanent, if something happens
                         * we still do not free memory.
                         */
-                       kfree(stat);
                        WARN(1,
                             "Could not allocate stat file for cpu %d\n",
                             cpu);
@@ -813,7 +812,7 @@ static void ftrace_profile_debugfs(struct dentry *d_tracer)
 }
 
 #else /* CONFIG_FUNCTION_PROFILER */
-static void ftrace_profile_debugfs(struct dentry *d_tracer)
+static __init void ftrace_profile_debugfs(struct dentry *d_tracer)
 {
 }
 #endif /* CONFIG_FUNCTION_PROFILER */
index 3aa0a0d..8bc8d8a 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/writeback.h>
 #include <linux/kallsyms.h>
 #include <linux/seq_file.h>
+#include <linux/smp_lock.h>
 #include <linux/notifier.h>
 #include <linux/irqflags.h>
 #include <linux/debugfs.h>
index d2a9ce9..701740c 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/pfn.h>
 #include <linux/bootmem.h>
 #include <linux/module.h>
+#include <linux/kmemleak.h>
 
 #include <asm/bug.h>
 #include <asm/io.h>
@@ -335,6 +336,8 @@ void __init free_bootmem_node(pg_data_t *pgdat, unsigned long physaddr,
 {
        unsigned long start, end;
 
+       kmemleak_free_part(__va(physaddr), size);
+
        start = PFN_UP(physaddr);
        end = PFN_DOWN(physaddr + size);
 
@@ -354,6 +357,8 @@ void __init free_bootmem(unsigned long addr, unsigned long size)
 {
        unsigned long start, end;
 
+       kmemleak_free_part(__va(addr), size);
+
        start = PFN_UP(addr);
        end = PFN_DOWN(addr + size);
 
@@ -516,6 +521,7 @@ find_block:
                region = phys_to_virt(PFN_PHYS(bdata->node_min_pfn) +
                                start_off);
                memset(region, 0, size);
+               kmemleak_alloc(region, size, 1, 0);
                return region;
        }
 
index e766e1d..5aabd41 100644 (file)
  * Kmemleak configuration and common defines.
  */
 #define MAX_TRACE              16      /* stack trace length */
-#define REPORTS_NR             50      /* maximum number of reported leaks */
 #define MSECS_MIN_AGE          5000    /* minimum object age for reporting */
 #define SECS_FIRST_SCAN                60      /* delay before the first scan */
 #define SECS_SCAN_WAIT         600     /* subsequent auto scanning delay */
+#define GRAY_LIST_PASSES       25      /* maximum number of gray list scans */
 
 #define BYTES_PER_POINTER      sizeof(void *)
 
@@ -158,6 +158,8 @@ struct kmemleak_object {
 #define OBJECT_REPORTED                (1 << 1)
 /* flag set to not scan the object */
 #define OBJECT_NO_SCAN         (1 << 2)
+/* flag set on newly allocated objects */
+#define OBJECT_NEW             (1 << 3)
 
 /* the list of all allocated objects */
 static LIST_HEAD(object_list);
@@ -196,9 +198,6 @@ static int kmemleak_stack_scan = 1;
 /* protects the memory scanning, parameters and debug/kmemleak file access */
 static DEFINE_MUTEX(scan_mutex);
 
-/* number of leaks reported (for limitation purposes) */
-static int reported_leaks;
-
 /*
  * Early object allocation/freeing logging. Kmemleak is initialized after the
  * kernel allocator. However, both the kernel allocator and kmemleak may
@@ -211,6 +210,7 @@ static int reported_leaks;
 enum {
        KMEMLEAK_ALLOC,
        KMEMLEAK_FREE,
+       KMEMLEAK_FREE_PART,
        KMEMLEAK_NOT_LEAK,
        KMEMLEAK_IGNORE,
        KMEMLEAK_SCAN_AREA,
@@ -274,6 +274,11 @@ static int color_gray(const struct kmemleak_object *object)
        return object->min_count != -1 && object->count >= object->min_count;
 }
 
+static int color_black(const struct kmemleak_object *object)
+{
+       return object->min_count == -1;
+}
+
 /*
  * Objects are considered unreferenced only if their color is white, they have
  * not be deleted and have a minimum age to avoid false positives caused by
@@ -451,7 +456,7 @@ static void create_object(unsigned long ptr, size_t size, int min_count,
        INIT_HLIST_HEAD(&object->area_list);
        spin_lock_init(&object->lock);
        atomic_set(&object->use_count, 1);
-       object->flags = OBJECT_ALLOCATED;
+       object->flags = OBJECT_ALLOCATED | OBJECT_NEW;
        object->pointer = ptr;
        object->size = size;
        object->min_count = min_count;
@@ -519,27 +524,17 @@ out:
  * Remove the metadata (struct kmemleak_object) for a memory block from the
  * object_list and object_tree_root and decrement its use_count.
  */
-static void delete_object(unsigned long ptr)
+static void __delete_object(struct kmemleak_object *object)
 {
        unsigned long flags;
-       struct kmemleak_object *object;
 
        write_lock_irqsave(&kmemleak_lock, flags);
-       object = lookup_object(ptr, 0);
-       if (!object) {
-#ifdef DEBUG
-               kmemleak_warn("Freeing unknown object at 0x%08lx\n",
-                             ptr);
-#endif
-               write_unlock_irqrestore(&kmemleak_lock, flags);
-               return;
-       }
        prio_tree_remove(&object_tree_root, &object->tree_node);
        list_del_rcu(&object->object_list);
        write_unlock_irqrestore(&kmemleak_lock, flags);
 
        WARN_ON(!(object->flags & OBJECT_ALLOCATED));
-       WARN_ON(atomic_read(&object->use_count) < 1);
+       WARN_ON(atomic_read(&object->use_count) < 2);
 
        /*
         * Locking here also ensures that the corresponding memory block
@@ -551,6 +546,64 @@ static void delete_object(unsigned long ptr)
        put_object(object);
 }
 
+/*
+ * Look up the metadata (struct kmemleak_object) corresponding to ptr and
+ * delete it.
+ */
+static void delete_object_full(unsigned long ptr)
+{
+       struct kmemleak_object *object;
+
+       object = find_and_get_object(ptr, 0);
+       if (!object) {
+#ifdef DEBUG
+               kmemleak_warn("Freeing unknown object at 0x%08lx\n",
+                             ptr);
+#endif
+               return;
+       }
+       __delete_object(object);
+       put_object(object);
+}
+
+/*
+ * Look up the metadata (struct kmemleak_object) corresponding to ptr and
+ * delete it. If the memory block is partially freed, the function may create
+ * additional metadata for the remaining parts of the block.
+ */
+static void delete_object_part(unsigned long ptr, size_t size)
+{
+       struct kmemleak_object *object;
+       unsigned long start, end;
+
+       object = find_and_get_object(ptr, 1);
+       if (!object) {
+#ifdef DEBUG
+               kmemleak_warn("Partially freeing unknown object at 0x%08lx "
+                             "(size %zu)\n", ptr, size);
+#endif
+               return;
+       }
+       __delete_object(object);
+
+       /*
+        * Create one or two objects that may result from the memory block
+        * split. Note that partial freeing is only done by free_bootmem() and
+        * this happens before kmemleak_init() is called. The path below is
+        * only executed during early log recording in kmemleak_init(), so
+        * GFP_KERNEL is enough.
+        */
+       start = object->pointer;
+       end = object->pointer + object->size;
+       if (ptr > start)
+               create_object(start, ptr - start, object->min_count,
+                             GFP_KERNEL);
+       if (ptr + size < end)
+               create_object(ptr + size, end - ptr - size, object->min_count,
+                             GFP_KERNEL);
+
+       put_object(object);
+}
 /*
  * Make a object permanently as gray-colored so that it can no longer be
  * reported as a leak. This is used in general to mark a false positive.
@@ -715,12 +768,27 @@ void kmemleak_free(const void *ptr)
        pr_debug("%s(0x%p)\n", __func__, ptr);
 
        if (atomic_read(&kmemleak_enabled) && ptr && !IS_ERR(ptr))
-               delete_object((unsigned long)ptr);
+               delete_object_full((unsigned long)ptr);
        else if (atomic_read(&kmemleak_early_log))
                log_early(KMEMLEAK_FREE, ptr, 0, 0, 0, 0);
 }
 EXPORT_SYMBOL_GPL(kmemleak_free);
 
+/*
+ * Partial memory freeing function callback. This function is usually called
+ * from bootmem allocator when (part of) a memory block is freed.
+ */
+void kmemleak_free_part(const void *ptr, size_t size)
+{
+       pr_debug("%s(0x%p)\n", __func__, ptr);
+
+       if (atomic_read(&kmemleak_enabled) && ptr && !IS_ERR(ptr))
+               delete_object_part((unsigned long)ptr, size);
+       else if (atomic_read(&kmemleak_early_log))
+               log_early(KMEMLEAK_FREE_PART, ptr, size, 0, 0, 0);
+}
+EXPORT_SYMBOL_GPL(kmemleak_free_part);
+
 /*
  * Mark an already allocated memory block as a false positive. This will cause
  * the block to no longer be reported as leak and always be scanned.
@@ -807,7 +875,7 @@ static int scan_should_stop(void)
  * found to the gray list.
  */
 static void scan_block(void *_start, void *_end,
-                      struct kmemleak_object *scanned)
+                      struct kmemleak_object *scanned, int allow_resched)
 {
        unsigned long *ptr;
        unsigned long *start = PTR_ALIGN(_start, BYTES_PER_POINTER);
@@ -818,6 +886,8 @@ static void scan_block(void *_start, void *_end,
                unsigned long pointer = *ptr;
                struct kmemleak_object *object;
 
+               if (allow_resched)
+                       cond_resched();
                if (scan_should_stop())
                        break;
 
@@ -881,12 +951,12 @@ static void scan_object(struct kmemleak_object *object)
                goto out;
        if (hlist_empty(&object->area_list))
                scan_block((void *)object->pointer,
-                          (void *)(object->pointer + object->size), object);
+                          (void *)(object->pointer + object->size), object, 0);
        else
                hlist_for_each_entry(area, elem, &object->area_list, node)
                        scan_block((void *)(object->pointer + area->offset),
                                   (void *)(object->pointer + area->offset
-                                           + area->length), object);
+                                           + area->length), object, 0);
 out:
        spin_unlock_irqrestore(&object->lock, flags);
 }
@@ -903,6 +973,7 @@ static void kmemleak_scan(void)
        struct task_struct *task;
        int i;
        int new_leaks = 0;
+       int gray_list_pass = 0;
 
        jiffies_last_scan = jiffies;
 
@@ -923,6 +994,7 @@ static void kmemleak_scan(void)
 #endif
                /* reset the reference count (whiten the object) */
                object->count = 0;
+               object->flags &= ~OBJECT_NEW;
                if (color_gray(object) && get_object(object))
                        list_add_tail(&object->gray_list, &gray_list);
 
@@ -931,14 +1003,14 @@ static void kmemleak_scan(void)
        rcu_read_unlock();
 
        /* data/bss scanning */
-       scan_block(_sdata, _edata, NULL);
-       scan_block(__bss_start, __bss_stop, NULL);
+       scan_block(_sdata, _edata, NULL, 1);
+       scan_block(__bss_start, __bss_stop, NULL, 1);
 
 #ifdef CONFIG_SMP
        /* per-cpu sections scanning */
        for_each_possible_cpu(i)
                scan_block(__per_cpu_start + per_cpu_offset(i),
-                          __per_cpu_end + per_cpu_offset(i), NULL);
+                          __per_cpu_end + per_cpu_offset(i), NULL, 1);
 #endif
 
        /*
@@ -960,7 +1032,7 @@ static void kmemleak_scan(void)
                        /* only scan if page is in use */
                        if (page_count(page) == 0)
                                continue;
-                       scan_block(page, page + 1, NULL);
+                       scan_block(page, page + 1, NULL, 1);
                }
        }
 
@@ -972,7 +1044,8 @@ static void kmemleak_scan(void)
                read_lock(&tasklist_lock);
                for_each_process(task)
                        scan_block(task_stack_page(task),
-                                  task_stack_page(task) + THREAD_SIZE, NULL);
+                                  task_stack_page(task) + THREAD_SIZE,
+                                  NULL, 0);
                read_unlock(&tasklist_lock);
        }
 
@@ -984,6 +1057,7 @@ static void kmemleak_scan(void)
         * kmemleak objects cannot be freed from outside the loop because their
         * use_count was increased.
         */
+repeat:
        object = list_entry(gray_list.next, typeof(*object), gray_list);
        while (&object->gray_list != &gray_list) {
                cond_resched();
@@ -1001,12 +1075,38 @@ static void kmemleak_scan(void)
 
                object = tmp;
        }
+
+       if (scan_should_stop() || ++gray_list_pass >= GRAY_LIST_PASSES)
+               goto scan_end;
+
+       /*
+        * Check for new objects allocated during this scanning and add them
+        * to the gray list.
+        */
+       rcu_read_lock();
+       list_for_each_entry_rcu(object, &object_list, object_list) {
+               spin_lock_irqsave(&object->lock, flags);
+               if ((object->flags & OBJECT_NEW) && !color_black(object) &&
+                   get_object(object)) {
+                       object->flags &= ~OBJECT_NEW;
+                       list_add_tail(&object->gray_list, &gray_list);
+               }
+               spin_unlock_irqrestore(&object->lock, flags);
+       }
+       rcu_read_unlock();
+
+       if (!list_empty(&gray_list))
+               goto repeat;
+
+scan_end:
        WARN_ON(!list_empty(&gray_list));
 
        /*
-        * If scanning was stopped do not report any new unreferenced objects.
+        * If scanning was stopped or new objects were being allocated at a
+        * higher rate than gray list scanning, do not report any new
+        * unreferenced objects.
         */
-       if (scan_should_stop())
+       if (scan_should_stop() || gray_list_pass >= GRAY_LIST_PASSES)
                return;
 
        /*
@@ -1039,6 +1139,7 @@ static int kmemleak_scan_thread(void *arg)
        static int first_run = 1;
 
        pr_info("Automatic memory scanning thread started\n");
+       set_user_nice(current, 10);
 
        /*
         * Wait before the first scan to allow the system to fully initialize.
@@ -1101,11 +1202,11 @@ static void *kmemleak_seq_start(struct seq_file *seq, loff_t *pos)
 {
        struct kmemleak_object *object;
        loff_t n = *pos;
+       int err;
 
-       if (!n)
-               reported_leaks = 0;
-       if (reported_leaks >= REPORTS_NR)
-               return NULL;
+       err = mutex_lock_interruptible(&scan_mutex);
+       if (err < 0)
+               return ERR_PTR(err);
 
        rcu_read_lock();
        list_for_each_entry_rcu(object, &object_list, object_list) {
@@ -1131,8 +1232,6 @@ static void *kmemleak_seq_next(struct seq_file *seq, void *v, loff_t *pos)
        struct list_head *n = &prev_obj->object_list;
 
        ++(*pos);
-       if (reported_leaks >= REPORTS_NR)
-               goto out;
 
        rcu_read_lock();
        list_for_each_continue_rcu(n, &object_list) {
@@ -1141,7 +1240,7 @@ static void *kmemleak_seq_next(struct seq_file *seq, void *v, loff_t *pos)
                        break;
        }
        rcu_read_unlock();
-out:
+
        put_object(prev_obj);
        return next_obj;
 }
@@ -1151,8 +1250,15 @@ out:
  */
 static void kmemleak_seq_stop(struct seq_file *seq, void *v)
 {
-       if (v)
-               put_object(v);
+       if (!IS_ERR(v)) {
+               /*
+                * kmemleak_seq_start may return ERR_PTR if the scan_mutex
+                * waiting was interrupted, so only release it if !IS_ERR.
+                */
+               mutex_unlock(&scan_mutex);
+               if (v)
+                       put_object(v);
+       }
 }
 
 /*
@@ -1164,10 +1270,8 @@ static int kmemleak_seq_show(struct seq_file *seq, void *v)
        unsigned long flags;
 
        spin_lock_irqsave(&object->lock, flags);
-       if ((object->flags & OBJECT_REPORTED) && unreferenced_object(object)) {
+       if ((object->flags & OBJECT_REPORTED) && unreferenced_object(object))
                print_unreferenced(seq, object);
-               reported_leaks++;
-       }
        spin_unlock_irqrestore(&object->lock, flags);
        return 0;
 }
@@ -1181,36 +1285,15 @@ static const struct seq_operations kmemleak_seq_ops = {
 
 static int kmemleak_open(struct inode *inode, struct file *file)
 {
-       int ret = 0;
-
        if (!atomic_read(&kmemleak_enabled))
                return -EBUSY;
 
-       ret = mutex_lock_interruptible(&scan_mutex);
-       if (ret < 0)
-               goto out;
-       if (file->f_mode & FMODE_READ) {
-               ret = seq_open(file, &kmemleak_seq_ops);
-               if (ret < 0)
-                       goto scan_unlock;
-       }
-       return ret;
-
-scan_unlock:
-       mutex_unlock(&scan_mutex);
-out:
-       return ret;
+       return seq_open(file, &kmemleak_seq_ops);
 }
 
 static int kmemleak_release(struct inode *inode, struct file *file)
 {
-       int ret = 0;
-
-       if (file->f_mode & FMODE_READ)
-               seq_release(inode, file);
-       mutex_unlock(&scan_mutex);
-
-       return ret;
+       return seq_release(inode, file);
 }
 
 /*
@@ -1230,15 +1313,17 @@ static ssize_t kmemleak_write(struct file *file, const char __user *user_buf,
 {
        char buf[64];
        int buf_size;
-
-       if (!atomic_read(&kmemleak_enabled))
-               return -EBUSY;
+       int ret;
 
        buf_size = min(size, (sizeof(buf) - 1));
        if (strncpy_from_user(buf, user_buf, buf_size) < 0)
                return -EFAULT;
        buf[buf_size] = 0;
 
+       ret = mutex_lock_interruptible(&scan_mutex);
+       if (ret < 0)
+               return ret;
+
        if (strncmp(buf, "off", 3) == 0)
                kmemleak_disable();
        else if (strncmp(buf, "stack=on", 8) == 0)
@@ -1251,11 +1336,10 @@ static ssize_t kmemleak_write(struct file *file, const char __user *user_buf,
                stop_scan_thread();
        else if (strncmp(buf, "scan=", 5) == 0) {
                unsigned long secs;
-               int err;
 
-               err = strict_strtoul(buf + 5, 0, &secs);
-               if (err < 0)
-                       return err;
+               ret = strict_strtoul(buf + 5, 0, &secs);
+               if (ret < 0)
+                       goto out;
                stop_scan_thread();
                if (secs) {
                        jiffies_scan_wait = msecs_to_jiffies(secs * 1000);
@@ -1264,7 +1348,12 @@ static ssize_t kmemleak_write(struct file *file, const char __user *user_buf,
        } else if (strncmp(buf, "scan", 4) == 0)
                kmemleak_scan();
        else
-               return -EINVAL;
+               ret = -EINVAL;
+
+out:
+       mutex_unlock(&scan_mutex);
+       if (ret < 0)
+               return ret;
 
        /* ignore the rest of the buffer, only one command at a time */
        *ppos += size;
@@ -1293,7 +1382,7 @@ static int kmemleak_cleanup_thread(void *arg)
 
        rcu_read_lock();
        list_for_each_entry_rcu(object, &object_list, object_list)
-               delete_object(object->pointer);
+               delete_object_full(object->pointer);
        rcu_read_unlock();
        mutex_unlock(&scan_mutex);
 
@@ -1388,6 +1477,9 @@ void __init kmemleak_init(void)
                case KMEMLEAK_FREE:
                        kmemleak_free(log->ptr);
                        break;
+               case KMEMLEAK_FREE_PART:
+                       kmemleak_free_part(log->ptr, log->size);
+                       break;
                case KMEMLEAK_NOT_LEAK:
                        kmemleak_not_leak(log->ptr);
                        break;
index a35eeab..caa9268 100644 (file)
@@ -4745,8 +4745,10 @@ void *__init alloc_large_system_hash(const char *tablename,
                         * some pages at the end of hash table which
                         * alloc_pages_exact() automatically does
                         */
-                       if (get_order(size) < MAX_ORDER)
+                       if (get_order(size) < MAX_ORDER) {
                                table = alloc_pages_exact(size, GFP_ATOMIC);
+                               kmemleak_alloc(table, size, 1, GFP_ATOMIC);
+                       }
                }
        } while (!table && size > PAGE_SIZE && --log2qty);
 
@@ -4764,16 +4766,6 @@ void *__init alloc_large_system_hash(const char *tablename,
        if (_hash_mask)
                *_hash_mask = (1 << log2qty) - 1;
 
-       /*
-        * If hashdist is set, the table allocation is done with __vmalloc()
-        * which invokes the kmemleak_alloc() callback. This function may also
-        * be called before the slab and kmemleak are initialised when
-        * kmemleak simply buffers the request to be executed later
-        * (GFP_ATOMIC flag ignored in this case).
-        */
-       if (!hashdist)
-               kmemleak_alloc(table, size, 1, GFP_ATOMIC);
-
        return table;
 }
 
index a9201d8..b9f1491 100644 (file)
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -21,7 +21,6 @@
 #include <linux/kmemcheck.h>
 #include <linux/cpu.h>
 #include <linux/cpuset.h>
-#include <linux/kmemleak.h>
 #include <linux/mempolicy.h>
 #include <linux/ctype.h>
 #include <linux/debugobjects.h>
@@ -2835,13 +2834,15 @@ EXPORT_SYMBOL(__kmalloc);
 static void *kmalloc_large_node(size_t size, gfp_t flags, int node)
 {
        struct page *page;
+       void *ptr = NULL;
 
        flags |= __GFP_COMP | __GFP_NOTRACK;
        page = alloc_pages_node(node, flags, get_order(size));
        if (page)
-               return page_address(page);
-       else
-               return NULL;
+               ptr = page_address(page);
+
+       kmemleak_alloc(ptr, size, 1, flags);
+       return ptr;
 }
 
 #ifdef CONFIG_NUMA
@@ -2926,6 +2927,7 @@ void kfree(const void *x)
        page = virt_to_head_page(x);
        if (unlikely(!PageSlab(page))) {
                BUG_ON(!PageCompound(page));
+               kmemleak_free(x);
                put_page(page);
                return;
        }
index 590b839..bfbe137 100644 (file)
@@ -54,6 +54,7 @@
 #include <linux/capability.h>
 #include <linux/module.h>
 #include <linux/if_arp.h>
+#include <linux/smp_lock.h>
 #include <linux/termios.h>     /* For TIOCOUTQ/INQ */
 #include <net/datalink.h>
 #include <net/psnap.h>
index 6354863..ba5d211 100644 (file)
@@ -939,8 +939,23 @@ static struct sock *sk_prot_alloc(struct proto *prot, gfp_t priority,
        struct kmem_cache *slab;
 
        slab = prot->slab;
-       if (slab != NULL)
-               sk = kmem_cache_alloc(slab, priority);
+       if (slab != NULL) {
+               sk = kmem_cache_alloc(slab, priority & ~__GFP_ZERO);
+               if (!sk)
+                       return sk;
+               if (priority & __GFP_ZERO) {
+                       /*
+                        * caches using SLAB_DESTROY_BY_RCU should let
+                        * sk_node.next un-modified. Special care is taken
+                        * when initializing object to zero.
+                        */
+                       if (offsetof(struct sock, sk_node.next) != 0)
+                               memset(sk, 0, offsetof(struct sock, sk_node.next));
+                       memset(&sk->sk_node.pprev, 0,
+                              prot->obj_size - offsetof(struct sock,
+                                                        sk_node.pprev));
+               }
+       }
        else
                sk = kmalloc(prot->obj_size, priority);
 
index 44e2a3d..cb4a0f4 100644 (file)
@@ -735,10 +735,10 @@ static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
        }
 
        tos = tiph->tos;
-       if (tos&1) {
+       if (tos == 1) {
+               tos = 0;
                if (skb->protocol == htons(ETH_P_IP))
                        tos = old_iph->tos;
-               tos &= ~1;
        }
 
        {
index 2470262..7d08210 100644 (file)
@@ -1243,7 +1243,6 @@ int ip_push_pending_frames(struct sock *sk)
                skb->len += tmp_skb->len;
                skb->data_len += tmp_skb->len;
                skb->truesize += tmp_skb->truesize;
-               __sock_put(tmp_skb->sk);
                tmp_skb->destructor = NULL;
                tmp_skb->sk = NULL;
        }
index 7c76e3d..87f8419 100644 (file)
@@ -1484,7 +1484,6 @@ int ip6_push_pending_frames(struct sock *sk)
                skb->len += tmp_skb->len;
                skb->data_len += tmp_skb->len;
                skb->truesize += tmp_skb->truesize;
-               __sock_put(tmp_skb->sk);
                tmp_skb->destructor = NULL;
                tmp_skb->sk = NULL;
        }
index 68e5230..98b7327 100644 (file)
@@ -1018,6 +1018,7 @@ static void ipip6_tunnel_setup(struct net_device *dev)
        dev->hard_header_len    = LL_MAX_HEADER + sizeof(struct iphdr);
        dev->mtu                = ETH_DATA_LEN - sizeof(struct iphdr);
        dev->flags              = IFF_NOARP;
+       dev->priv_flags        &= ~IFF_XMIT_DST_RELEASE;
        dev->iflink             = 0;
        dev->addr_len           = 4;
        dev->features           |= NETIF_F_NETNS_LOCAL;
index 417b0e3..f1118d9 100644 (file)
@@ -41,6 +41,7 @@
 #include <linux/netdevice.h>
 #include <linux/uio.h>
 #include <linux/skbuff.h>
+#include <linux/smp_lock.h>
 #include <linux/socket.h>
 #include <linux/sockios.h>
 #include <linux/string.h>
index cb762c8..80cf29a 100644 (file)
@@ -45,6 +45,7 @@
 #include <linux/capability.h>
 #include <linux/module.h>
 #include <linux/types.h>
+#include <linux/smp_lock.h>
 #include <linux/socket.h>
 #include <linux/sockios.h>
 #include <linux/init.h>
index bccf4d0..b001c36 100644 (file)
 #include <linux/module.h>
 
 #include <linux/kernel.h>
-#include <linux/smp_lock.h>
 #include <linux/skbuff.h>
 #include <linux/tty.h>
 #include <linux/proc_fs.h>
index 6d8ae03..68cbcb1 100644 (file)
@@ -13,6 +13,7 @@
  *     2) as a control channel (write commands, read events)
  */
 
+#include <linux/smp_lock.h>
 #include "irnet_ppp.h"         /* Private header */
 /* Please put other headers in irnet.h - Thanks */
 
index 5bc2f45..ebfcf9b 100644 (file)
@@ -28,7 +28,6 @@
 #include <linux/kallsyms.h>
 #include <linux/mm.h>
 #include <linux/slab.h>
-#include <linux/smp_lock.h>
 #include <linux/utsname.h>
 #include <linux/workqueue.h>
 #include <linux/in6.h>
index 1102ce1..8f459ab 100644 (file)
@@ -16,7 +16,6 @@
 #include <linux/slab.h>
 #include <linux/mempool.h>
 #include <linux/smp.h>
-#include <linux/smp_lock.h>
 #include <linux/spinlock.h>
 #include <linux/mutex.h>
 
index 6f33d33..27d4433 100644 (file)
@@ -5,6 +5,7 @@
  */
 
 #include <linux/sched.h>
+#include <linux/smp_lock.h>
 #include <linux/errno.h>
 #include <linux/freezer.h>
 #include <linux/kthread.h>
index 466e2d2..258daa8 100644 (file)
@@ -48,6 +48,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>      /* support for loadable modules */
 #include <linux/slab.h>                /* kmalloc(), kfree() */
+#include <linux/smp_lock.h>
 #include <linux/mm.h>
 #include <linux/string.h>      /* inline mem*, str* functions */
 
index 21cdc87..5e6c072 100644 (file)
@@ -40,6 +40,7 @@
 #include <linux/errno.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
+#include <linux/smp_lock.h>
 #include <linux/timer.h>
 #include <linux/string.h>
 #include <linux/net.h>
index 9977a75..f24ae37 100644 (file)
@@ -1,20 +1,3 @@
-/*
- * Notice that this file is not protected like a normal header.
- * We also must allow for rereading of this file. The
- *
- *  || defined(TRACE_HEADER_MULTI_READ)
- *
- * serves this purpose.
- */
-#if !defined(_TRACE_EVENT_SAMPLE_H) || defined(TRACE_HEADER_MULTI_READ)
-#define _TRACE_EVENT_SAMPLE_H
-
-/*
- * All trace headers should include tracepoint.h, until we finally
- * make it into a standard header.
- */
-#include <linux/tracepoint.h>
-
 /*
  * If TRACE_SYSTEM is defined, that will be the directory created
  * in the ftrace directory under /debugfs/tracing/events/<system>
  * #define TRACE_INCLUDE_FILE trace-events-sample
  *
  * As we do an the bottom of this file.
+ *
+ * Notice that TRACE_SYSTEM should be defined outside of #if
+ * protection, just like TRACE_INCLUDE_FILE.
  */
 #undef TRACE_SYSTEM
 #define TRACE_SYSTEM sample
 
+/*
+ * Notice that this file is not protected like a normal header.
+ * We also must allow for rereading of this file. The
+ *
+ *  || defined(TRACE_HEADER_MULTI_READ)
+ *
+ * serves this purpose.
+ */
+#if !defined(_TRACE_EVENT_SAMPLE_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_EVENT_SAMPLE_H
+
+/*
+ * All trace headers should include tracepoint.h, until we finally
+ * make it into a standard header.
+ */
+#include <linux/tracepoint.h>
+
 /*
  * The TRACE_EVENT macro is broken up into 5 parts.
  *
index c05f718..8c0fdf8 100644 (file)
@@ -1037,14 +1037,14 @@ static int __devinit wm8988_spi_probe(struct spi_device *spi)
        codec->control_data = spi;
        codec->dev = &spi->dev;
 
-       spi->dev.driver_data = wm8988;
+       dev_set_drvdata(&spi->dev, wm8988);
 
        return wm8988_register(wm8988);
 }
 
 static int __devexit wm8988_spi_remove(struct spi_device *spi)
 {
-       struct wm8988_priv *wm8988 = spi->dev.driver_data;
+       struct wm8988_priv *wm8988 = dev_get_drvdata(&spi->dev);
 
        wm8988_unregister(wm8988);