diff --git a/[refs] b/[refs] index 8441cb17eda9..81f45255d90b 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 989fa940961faa9d51f073bafa58c2b5653d5969 +refs/heads/master: a1a08d1cb0ab148fd74216e4c0b4d4db18fe62c6 diff --git a/trunk/Documentation/driver-model/driver.txt b/trunk/Documentation/driver-model/driver.txt index 60120fb3b961..82132169d47a 100644 --- a/trunk/Documentation/driver-model/driver.txt +++ b/trunk/Documentation/driver-model/driver.txt @@ -207,8 +207,8 @@ Attributes ~~~~~~~~~~ struct driver_attribute { struct attribute attr; - ssize_t (*show)(struct device_driver *driver, char *buf); - ssize_t (*store)(struct device_driver *, const char * buf, size_t count); + 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); }; Device drivers can export attributes via their sysfs directories. diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index 18c3f0c41c95..9d1601ec1311 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -3287,11 +3287,11 @@ F: include/linux/ivtv* JFS FILESYSTEM P: Dave Kleikamp -M: shaggy@linux.vnet.ibm.com +M: shaggy@austin.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: Maintained +S: Supported F: Documentation/filesystems/jfs.txt F: fs/jfs/ diff --git a/trunk/Makefile b/trunk/Makefile index be0abacd042d..0aeec59c1f0a 100644 --- a/trunk/Makefile +++ b/trunk/Makefile @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 6 SUBLEVEL = 31 -EXTRAVERSION = -rc3 +EXTRAVERSION = -rc2 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,-fno-strict-overflow) +KBUILD_CFLAGS += $(call cc-option,-fwrapv) # revert to pre-gcc-4.4 behaviour of .eh_frame KBUILD_CFLAGS += $(call cc-option,-fno-dwarf2-cfi-asm) diff --git a/trunk/arch/alpha/kernel/ptrace.c b/trunk/arch/alpha/kernel/ptrace.c index e072041d19f8..1e9ad52c460e 100644 --- a/trunk/arch/alpha/kernel/ptrace.c +++ b/trunk/arch/alpha/kernel/ptrace.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/blackfin/kernel/ptrace.c b/trunk/arch/blackfin/kernel/ptrace.c index 6a387eec6b65..d76618db50df 100644 --- a/trunk/arch/blackfin/kernel/ptrace.c +++ b/trunk/arch/blackfin/kernel/ptrace.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/blackfin/kernel/sys_bfin.c b/trunk/arch/blackfin/kernel/sys_bfin.c index 3da60fb13ce4..a8f1329c15a4 100644 --- a/trunk/arch/blackfin/kernel/sys_bfin.c +++ b/trunk/arch/blackfin/kernel/sys_bfin.c @@ -29,6 +29,7 @@ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#include #include #include #include diff --git a/trunk/arch/cris/kernel/sys_cris.c b/trunk/arch/cris/kernel/sys_cris.c index 2ad962c7e88e..a79fbd87021b 100644 --- a/trunk/arch/cris/kernel/sys_cris.c +++ b/trunk/arch/cris/kernel/sys_cris.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/ia64/kernel/ptrace.c b/trunk/arch/ia64/kernel/ptrace.c index 9daa87fdb018..92c9689b7d97 100644 --- a/trunk/arch/ia64/kernel/ptrace.c +++ b/trunk/arch/ia64/kernel/ptrace.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/m32r/kernel/ptrace.c b/trunk/arch/m32r/kernel/ptrace.c index 98b8feb12ed8..bf0abe9e1f73 100644 --- a/trunk/arch/m32r/kernel/ptrace.c +++ b/trunk/arch/m32r/kernel/ptrace.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/microblaze/kernel/ptrace.c b/trunk/arch/microblaze/kernel/ptrace.c index 53ff39af6a5c..b86aa623e36d 100644 --- a/trunk/arch/microblaze/kernel/ptrace.c +++ b/trunk/arch/microblaze/kernel/ptrace.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include diff --git a/trunk/arch/microblaze/kernel/signal.c b/trunk/arch/microblaze/kernel/signal.c index 1c80e4fc40ce..493819c25fba 100644 --- a/trunk/arch/microblaze/kernel/signal.c +++ b/trunk/arch/microblaze/kernel/signal.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/microblaze/kernel/sys_microblaze.c b/trunk/arch/microblaze/kernel/sys_microblaze.c index e000bce09b2b..8c9ebac5da10 100644 --- a/trunk/arch/microblaze/kernel/sys_microblaze.c +++ b/trunk/arch/microblaze/kernel/sys_microblaze.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/mips/kernel/ptrace32.c b/trunk/arch/mips/kernel/ptrace32.c index 32644b4a0714..c4f9ac17474a 100644 --- a/trunk/arch/mips/kernel/ptrace32.c +++ b/trunk/arch/mips/kernel/ptrace32.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include diff --git a/trunk/arch/mips/mm/hugetlbpage.c b/trunk/arch/mips/mm/hugetlbpage.c index 8c2834f5919d..471c09aa1614 100644 --- a/trunk/arch/mips/mm/hugetlbpage.c +++ b/trunk/arch/mips/mm/hugetlbpage.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/mn10300/kernel/ptrace.c b/trunk/arch/mn10300/kernel/ptrace.c index cf847dabc1bd..e143339ad28e 100644 --- a/trunk/arch/mn10300/kernel/ptrace.c +++ b/trunk/arch/mn10300/kernel/ptrace.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/mn10300/kernel/signal.c b/trunk/arch/mn10300/kernel/signal.c index feb2f2e810db..9f7572a0f578 100644 --- a/trunk/arch/mn10300/kernel/signal.c +++ b/trunk/arch/mn10300/kernel/signal.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/mn10300/kernel/sys_mn10300.c b/trunk/arch/mn10300/kernel/sys_mn10300.c index 3e52a1054327..bca5a84dc72c 100644 --- a/trunk/arch/mn10300/kernel/sys_mn10300.c +++ b/trunk/arch/mn10300/kernel/sys_mn10300.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -20,6 +21,7 @@ #include #include #include +#include #include #include diff --git a/trunk/arch/mn10300/kernel/traps.c b/trunk/arch/mn10300/kernel/traps.c index 91365adba4f5..0dfdc5001124 100644 --- a/trunk/arch/mn10300/kernel/traps.c +++ b/trunk/arch/mn10300/kernel/traps.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/mn10300/mm/fault.c b/trunk/arch/mn10300/mm/fault.c index 53bb17d0f068..a62e1e138bc1 100644 --- a/trunk/arch/mn10300/mm/fault.c +++ b/trunk/arch/mn10300/mm/fault.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include /* For unblank_screen() */ diff --git a/trunk/arch/mn10300/mm/misalignment.c b/trunk/arch/mn10300/mm/misalignment.c index 30016251f658..94c4a4358065 100644 --- a/trunk/arch/mn10300/mm/misalignment.c +++ b/trunk/arch/mn10300/mm/misalignment.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/powerpc/kernel/ptrace32.c b/trunk/arch/powerpc/kernel/ptrace32.c index 8a6daf4129f6..297632cba047 100644 --- a/trunk/arch/powerpc/kernel/ptrace32.c +++ b/trunk/arch/powerpc/kernel/ptrace32.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/s390/kernel/dis.c b/trunk/arch/s390/kernel/dis.c index db943a7ec513..d2f270c995d9 100644 --- a/trunk/arch/s390/kernel/dis.c +++ b/trunk/arch/s390/kernel/dis.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/s390/kernel/ptrace.c b/trunk/arch/s390/kernel/ptrace.c index 43acd73105b7..490b39934d65 100644 --- a/trunk/arch/s390/kernel/ptrace.c +++ b/trunk/arch/s390/kernel/ptrace.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/s390/mm/fault.c b/trunk/arch/s390/mm/fault.c index e5e119fe03b2..74eb26bf1970 100644 --- a/trunk/arch/s390/mm/fault.c +++ b/trunk/arch/s390/mm/fault.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/sh/mm/tlb-sh3.c b/trunk/arch/sh/mm/tlb-sh3.c index 17cb7c3adf22..7fbfd5a11ffa 100644 --- a/trunk/arch/sh/mm/tlb-sh3.c +++ b/trunk/arch/sh/mm/tlb-sh3.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include diff --git a/trunk/arch/sparc/kernel/ptrace_32.c b/trunk/arch/sparc/kernel/ptrace_32.c index 7e3dfd9bb97e..8ce6285a06d5 100644 --- a/trunk/arch/sparc/kernel/ptrace_32.c +++ b/trunk/arch/sparc/kernel/ptrace_32.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/sparc/kernel/ptrace_64.c b/trunk/arch/sparc/kernel/ptrace_64.c index 4ae91dc2feb9..a941c610e7ce 100644 --- a/trunk/arch/sparc/kernel/ptrace_64.c +++ b/trunk/arch/sparc/kernel/ptrace_64.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/sparc/kernel/time_64.c b/trunk/arch/sparc/kernel/time_64.c index da1218e8ee87..5c12e79b4bdf 100644 --- a/trunk/arch/sparc/kernel/time_64.c +++ b/trunk/arch/sparc/kernel/time_64.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/arch/sparc/kernel/traps_32.c b/trunk/arch/sparc/kernel/traps_32.c index c0490c7bbde0..358283341b47 100644 --- a/trunk/arch/sparc/kernel/traps_32.c +++ b/trunk/arch/sparc/kernel/traps_32.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include diff --git a/trunk/arch/sparc/kernel/vio.c b/trunk/arch/sparc/kernel/vio.c index c28c71449a6c..753d128ed158 100644 --- a/trunk/arch/sparc/kernel/vio.c +++ b/trunk/arch/sparc/kernel/vio.c @@ -224,12 +224,7 @@ static struct vio_dev *vio_create_one(struct mdesc_handle *hp, u64 mp, if (!strcmp(type, "domain-services-port")) bus_id_name = "ds"; - /* - * 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) { + if (strlen(bus_id_name) >= BUS_ID_SIZE - 4) { printk(KERN_ERR "VIO: bus_id_name [%s] is too long.\n", bus_id_name); return NULL; diff --git a/trunk/arch/x86/mm/fault.c b/trunk/arch/x86/mm/fault.c index 85307cc6e45f..bfae139182ff 100644 --- a/trunk/arch/x86/mm/fault.c +++ b/trunk/arch/x86/mm/fault.c @@ -697,7 +697,7 @@ show_signal_msg(struct pt_regs *regs, unsigned long error_code, if (!printk_ratelimit()) return; - printk(KERN_CONT "%s%s[%d]: segfault at %lx ip %p sp %p error %lx", + printk("%s%s[%d]: segfault at %lx ip %p sp %p error %lx", task_pid_nr(tsk) > 1 ? KERN_INFO : KERN_EMERG, tsk->comm, task_pid_nr(tsk), address, (void *)regs->ip, (void *)regs->sp, error_code); diff --git a/trunk/drivers/base/devres.c b/trunk/drivers/base/devres.c index 05dd307e8f02..e8beb8e5b626 100644 --- a/trunk/drivers/base/devres.c +++ b/trunk/drivers/base/devres.c @@ -428,9 +428,6 @@ 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); diff --git a/trunk/drivers/base/firmware_class.c b/trunk/drivers/base/firmware_class.c index f285f441fab9..fc466531260e 100644 --- a/trunk/drivers/base/firmware_class.c +++ b/trunk/drivers/base/firmware_class.c @@ -217,10 +217,8 @@ firmware_data_read(struct kobject *kobj, struct bin_attribute *bin_attr, ret_count = -ENODEV; goto out; } - if (offset > fw->size) { - ret_count = 0; - goto out; - } + if (offset > fw->size) + return 0; if (count > fw->size - offset) count = fw->size - offset; diff --git a/trunk/drivers/block/DAC960.c b/trunk/drivers/block/DAC960.c index 1e6b7c14f697..668dc234b8e2 100644 --- a/trunk/drivers/block/DAC960.c +++ b/trunk/drivers/block/DAC960.c @@ -36,7 +36,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/drivers/block/cciss.c b/trunk/drivers/block/cciss.c index a52cc7fe45ea..65a0655e7fc8 100644 --- a/trunk/drivers/block/cciss.c +++ b/trunk/drivers/block/cciss.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/drivers/block/loop.c b/trunk/drivers/block/loop.c index 5757188cd1fb..801f4ab83302 100644 --- a/trunk/drivers/block/loop.c +++ b/trunk/drivers/block/loop.c @@ -61,6 +61,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/bluetooth/hci_vhci.c b/trunk/drivers/bluetooth/hci_vhci.c index d5cde6d86f89..1df9dda2e377 100644 --- a/trunk/drivers/bluetooth/hci_vhci.c +++ b/trunk/drivers/bluetooth/hci_vhci.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/char/amiserial.c b/trunk/drivers/char/amiserial.c index 6c32fbf07164..72429b6b2fa8 100644 --- a/trunk/drivers/char/amiserial.c +++ b/trunk/drivers/char/amiserial.c @@ -81,7 +81,6 @@ static char *serial_version = "4.30"; #include #include #include -#include #include #include diff --git a/trunk/drivers/char/cyclades.c b/trunk/drivers/char/cyclades.c index 2dafc2da0648..f3366d3f06cf 100644 --- a/trunk/drivers/char/cyclades.c +++ b/trunk/drivers/char/cyclades.c @@ -633,7 +633,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/drivers/char/epca.c b/trunk/drivers/char/epca.c index ff647ca1c489..abef1f7d84fe 100644 --- a/trunk/drivers/char/epca.c +++ b/trunk/drivers/char/epca.c @@ -36,7 +36,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/drivers/char/isicom.c b/trunk/drivers/char/isicom.c index 4f1f4cd670da..621d1184673c 100644 --- a/trunk/drivers/char/isicom.c +++ b/trunk/drivers/char/isicom.c @@ -122,7 +122,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/drivers/char/istallion.c b/trunk/drivers/char/istallion.c index ab2f3349c5c4..0c999f5bb3db 100644 --- a/trunk/drivers/char/istallion.c +++ b/trunk/drivers/char/istallion.c @@ -20,7 +20,6 @@ #include #include -#include #include #include #include diff --git a/trunk/drivers/char/moxa.c b/trunk/drivers/char/moxa.c index dd0083bbb64a..65b6ff2442c6 100644 --- a/trunk/drivers/char/moxa.c +++ b/trunk/drivers/char/moxa.c @@ -34,7 +34,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/drivers/char/mxser.c b/trunk/drivers/char/mxser.c index dbf8d52f31d0..52d953eb30c3 100644 --- a/trunk/drivers/char/mxser.c +++ b/trunk/drivers/char/mxser.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/drivers/char/n_hdlc.c b/trunk/drivers/char/n_hdlc.c index c68118efad84..1c43c8cdee25 100644 --- a/trunk/drivers/char/n_hdlc.c +++ b/trunk/drivers/char/n_hdlc.c @@ -97,7 +97,6 @@ #include #include #include -#include #include /* used in new tty drivers */ #include /* used in new tty drivers */ #include diff --git a/trunk/drivers/char/n_r3964.c b/trunk/drivers/char/n_r3964.c index 6934025a1ac1..2e99158ebb8a 100644 --- a/trunk/drivers/char/n_r3964.c +++ b/trunk/drivers/char/n_r3964.c @@ -58,7 +58,6 @@ #include #include #include -#include #include #include #include /* used in new tty drivers */ diff --git a/trunk/drivers/char/pty.c b/trunk/drivers/char/pty.c index 6e6942c45f5b..9d1b4f548f67 100644 --- a/trunk/drivers/char/pty.c +++ b/trunk/drivers/char/pty.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/drivers/char/rio/rio_linux.c b/trunk/drivers/char/rio/rio_linux.c index d58c2eb07f07..ce81da5b2da9 100644 --- a/trunk/drivers/char/rio/rio_linux.c +++ b/trunk/drivers/char/rio/rio_linux.c @@ -44,7 +44,6 @@ #include #include #include -#include #include #include diff --git a/trunk/drivers/char/riscom8.c b/trunk/drivers/char/riscom8.c index 171711acf5cd..217660451237 100644 --- a/trunk/drivers/char/riscom8.c +++ b/trunk/drivers/char/riscom8.c @@ -47,7 +47,6 @@ #include #include #include -#include #include #include diff --git a/trunk/drivers/char/rocket.c b/trunk/drivers/char/rocket.c index 0e29a23ec4c5..63d5b628477a 100644 --- a/trunk/drivers/char/rocket.c +++ b/trunk/drivers/char/rocket.c @@ -73,7 +73,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/drivers/char/serial167.c b/trunk/drivers/char/serial167.c index 51e7a46787be..f1f24f0ee26f 100644 --- a/trunk/drivers/char/serial167.c +++ b/trunk/drivers/char/serial167.c @@ -52,7 +52,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/drivers/char/specialix.c b/trunk/drivers/char/specialix.c index bfe4cdb2febb..e72be4190a44 100644 --- a/trunk/drivers/char/specialix.c +++ b/trunk/drivers/char/specialix.c @@ -87,7 +87,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/drivers/char/sx.c b/trunk/drivers/char/sx.c index a81ec4fcf6ff..518f2a25d91e 100644 --- a/trunk/drivers/char/sx.c +++ b/trunk/drivers/char/sx.c @@ -216,7 +216,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/drivers/char/synclink.c b/trunk/drivers/char/synclink.c index 813552f14884..afded3a2379c 100644 --- a/trunk/drivers/char/synclink.c +++ b/trunk/drivers/char/synclink.c @@ -81,7 +81,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/drivers/char/synclink_gt.c b/trunk/drivers/char/synclink_gt.c index 91f20a92fddf..a2e67e6df3a1 100644 --- a/trunk/drivers/char/synclink_gt.c +++ b/trunk/drivers/char/synclink_gt.c @@ -62,7 +62,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/drivers/char/synclinkmp.c b/trunk/drivers/char/synclinkmp.c index 8d4a2a8a0a70..6f727e3c53ad 100644 --- a/trunk/drivers/char/synclinkmp.c +++ b/trunk/drivers/char/synclinkmp.c @@ -52,7 +52,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/drivers/char/tpm/tpm.c b/trunk/drivers/char/tpm/tpm.c index b0603b2e5684..ccdd828adcef 100644 --- a/trunk/drivers/char/tpm/tpm.c +++ b/trunk/drivers/char/tpm/tpm.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "tpm.h" diff --git a/trunk/drivers/char/tty_ioctl.c b/trunk/drivers/char/tty_ioctl.c index ad6ba4ed2808..b24f6c6a1ea3 100644 --- a/trunk/drivers/char/tty_ioctl.c +++ b/trunk/drivers/char/tty_ioctl.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include diff --git a/trunk/drivers/char/tty_ldisc.c b/trunk/drivers/char/tty_ldisc.c index 0ef0dc97ba20..913aa8d3f1c5 100644 --- a/trunk/drivers/char/tty_ldisc.c +++ b/trunk/drivers/char/tty_ldisc.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/char/vt.c b/trunk/drivers/char/vt.c index 7947bd1b4cf7..d9113b4c76e3 100644 --- a/trunk/drivers/char/vt.c +++ b/trunk/drivers/char/vt.c @@ -89,7 +89,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/drivers/char/vt_ioctl.c b/trunk/drivers/char/vt_ioctl.c index 95189f288f8c..7539bed0f7e0 100644 --- a/trunk/drivers/char/vt_ioctl.c +++ b/trunk/drivers/char/vt_ioctl.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include diff --git a/trunk/drivers/gpio/vr41xx_giu.c b/trunk/drivers/gpio/vr41xx_giu.c index b16c9a8c03f5..b70e06133e78 100644 --- a/trunk/drivers/gpio/vr41xx_giu.c +++ b/trunk/drivers/gpio/vr41xx_giu.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include diff --git a/trunk/drivers/hid/usbhid/hid-core.c b/trunk/drivers/hid/usbhid/hid-core.c index 3c1fcb7640ab..76c4bbe9dccb 100644 --- a/trunk/drivers/hid/usbhid/hid-core.c +++ b/trunk/drivers/hid/usbhid/hid-core.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/hwmon/abituguru3.c b/trunk/drivers/hwmon/abituguru3.c index 7d3f15d32fdf..ad2b3431b725 100644 --- a/trunk/drivers/hwmon/abituguru3.c +++ b/trunk/drivers/hwmon/abituguru3.c @@ -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, "AB9", /* + AB9 Pro */ { + { 0x0014, NULL /* Abit AB9 Pro, need DMI string */, { { "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, "AB9 QuadGT", { + { 0x0018, NULL /* Unknown, need DMI string */, { { "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, "IX38 QuadGT", { + { 0x001C, NULL /* Unknown, need DMI string */, { { "CPU Core", 0, 0, 10, 1, 0 }, { "DDR2", 1, 0, 20, 1, 0 }, { "DDR2 VTT", 2, 0, 10, 1, 0 }, diff --git a/trunk/drivers/hwmon/max6650.c b/trunk/drivers/hwmon/max6650.c index 58f66be61b1f..86142a858238 100644 --- a/trunk/drivers/hwmon/max6650.c +++ b/trunk/drivers/hwmon/max6650.c @@ -418,7 +418,6 @@ 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; diff --git a/trunk/drivers/hwmon/sht15.c b/trunk/drivers/hwmon/sht15.c index 6290a259456e..56cd6004da36 100644 --- a/trunk/drivers/hwmon/sht15.c +++ b/trunk/drivers/hwmon/sht15.c @@ -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; } diff --git a/trunk/drivers/isdn/hisax/hfc_usb.c b/trunk/drivers/isdn/hisax/hfc_usb.c index 9de54202c90c..8df889b0c1a9 100644 --- a/trunk/drivers/isdn/hisax/hfc_usb.c +++ b/trunk/drivers/isdn/hisax/hfc_usb.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include "hisax.h" diff --git a/trunk/drivers/isdn/i4l/isdn_tty.c b/trunk/drivers/isdn/i4l/isdn_tty.c index 2881a66c1aa9..b4d4522e5071 100644 --- a/trunk/drivers/isdn/i4l/isdn_tty.c +++ b/trunk/drivers/isdn/i4l/isdn_tty.c @@ -13,7 +13,6 @@ #include #include -#include #include "isdn_common.h" #include "isdn_tty.h" #ifdef CONFIG_ISDN_AUDIO diff --git a/trunk/drivers/isdn/mISDN/stack.c b/trunk/drivers/isdn/mISDN/stack.c index 3e1532a180ff..e2f45019ebf0 100644 --- a/trunk/drivers/isdn/mISDN/stack.c +++ b/trunk/drivers/isdn/mISDN/stack.c @@ -17,7 +17,6 @@ #include #include -#include #include "core.h" static u_int *debug; diff --git a/trunk/drivers/media/dvb/bt8xx/dst_ca.c b/trunk/drivers/media/dvb/bt8xx/dst_ca.c index 0e246eaad05a..4601b059b2b2 100644 --- a/trunk/drivers/media/dvb/bt8xx/dst_ca.c +++ b/trunk/drivers/media/dvb/bt8xx/dst_ca.c @@ -21,7 +21,6 @@ #include #include #include -#include #include #include #include "dvbdev.h" diff --git a/trunk/drivers/media/dvb/dvb-core/dvbdev.h b/trunk/drivers/media/dvb/dvb-core/dvbdev.h index 487919bea7ae..79927305e84d 100644 --- a/trunk/drivers/media/dvb/dvb-core/dvbdev.h +++ b/trunk/drivers/media/dvb/dvb-core/dvbdev.h @@ -27,6 +27,7 @@ #include #include #include +#include #define DVB_MAJOR 212 diff --git a/trunk/drivers/media/dvb/ttpci/av7110.c b/trunk/drivers/media/dvb/ttpci/av7110.c index 8d65c652ba50..d1d959ed37b7 100644 --- a/trunk/drivers/media/dvb/ttpci/av7110.c +++ b/trunk/drivers/media/dvb/ttpci/av7110.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include diff --git a/trunk/drivers/media/radio/radio-mr800.c b/trunk/drivers/media/radio/radio-mr800.c index 575bf9d89419..837467f93805 100644 --- a/trunk/drivers/media/radio/radio-mr800.c +++ b/trunk/drivers/media/radio/radio-mr800.c @@ -58,7 +58,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/drivers/media/radio/radio-si470x.c b/trunk/drivers/media/radio/radio-si470x.c index e85f318b4d2b..46d216329611 100644 --- a/trunk/drivers/media/radio/radio-si470x.c +++ b/trunk/drivers/media/radio/radio-si470x.c @@ -127,7 +127,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/drivers/media/video/bt8xx/bttv-driver.c b/trunk/drivers/media/video/bt8xx/bttv-driver.c index d147d29bb0d3..5eb1464af670 100644 --- a/trunk/drivers/media/video/bt8xx/bttv-driver.c +++ b/trunk/drivers/media/video/bt8xx/bttv-driver.c @@ -41,7 +41,6 @@ #include #include #include -#include #include #include #include "bttvp.h" diff --git a/trunk/drivers/media/video/cx23885/cx23885-417.c b/trunk/drivers/media/video/cx23885/cx23885-417.c index 428f0c45e6b7..2943bfd32a94 100644 --- a/trunk/drivers/media/video/cx23885/cx23885-417.c +++ b/trunk/drivers/media/video/cx23885/cx23885-417.c @@ -31,7 +31,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/drivers/media/video/cx23885/cx23885-video.c b/trunk/drivers/media/video/cx23885/cx23885-video.c index 5d6093336300..70836af3ab48 100644 --- a/trunk/drivers/media/video/cx23885/cx23885-video.c +++ b/trunk/drivers/media/video/cx23885/cx23885-video.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/drivers/media/video/cx88/cx88-blackbird.c b/trunk/drivers/media/video/cx88/cx88-blackbird.c index 356d6896da3f..44eacfb0d0d6 100644 --- a/trunk/drivers/media/video/cx88/cx88-blackbird.c +++ b/trunk/drivers/media/video/cx88/cx88-blackbird.c @@ -32,7 +32,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/drivers/media/video/cx88/cx88-video.c b/trunk/drivers/media/video/cx88/cx88-video.c index 2bb54c3ef5cd..b12770848c00 100644 --- a/trunk/drivers/media/video/cx88/cx88-video.c +++ b/trunk/drivers/media/video/cx88/cx88-video.c @@ -31,7 +31,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/drivers/media/video/dabusb.c b/trunk/drivers/media/video/dabusb.c index 0664d111085f..ec2f45dde164 100644 --- a/trunk/drivers/media/video/dabusb.c +++ b/trunk/drivers/media/video/dabusb.c @@ -32,7 +32,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/drivers/media/video/pwc/pwc-if.c b/trunk/drivers/media/video/pwc/pwc-if.c index 8d17cf613306..db25c3034c11 100644 --- a/trunk/drivers/media/video/pwc/pwc-if.c +++ b/trunk/drivers/media/video/pwc/pwc-if.c @@ -62,7 +62,6 @@ #include #include #include -#include #ifdef CONFIG_USB_PWC_INPUT_EVDEV #include #endif diff --git a/trunk/drivers/media/video/pwc/pwc.h b/trunk/drivers/media/video/pwc/pwc.h index 0b658dee05a4..0be6f814f539 100644 --- a/trunk/drivers/media/video/pwc/pwc.h +++ b/trunk/drivers/media/video/pwc/pwc.h @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/media/video/s2255drv.c b/trunk/drivers/media/video/s2255drv.c index 9e3262c0ba37..6be845ccc7d7 100644 --- a/trunk/drivers/media/video/s2255drv.c +++ b/trunk/drivers/media/video/s2255drv.c @@ -48,7 +48,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/drivers/media/video/saa5246a.c b/trunk/drivers/media/video/saa5246a.c index b624a4c01fdc..155804b061e9 100644 --- a/trunk/drivers/media/video/saa5246a.c +++ b/trunk/drivers/media/video/saa5246a.c @@ -43,6 +43,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/media/video/saa5249.c b/trunk/drivers/media/video/saa5249.c index 12835fb82c95..271d6e931b75 100644 --- a/trunk/drivers/media/video/saa5249.c +++ b/trunk/drivers/media/video/saa5249.c @@ -46,6 +46,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/media/video/saa7134/saa7134-empress.c b/trunk/drivers/media/video/saa7134/saa7134-empress.c index 296788c3bf0e..add1757f8930 100644 --- a/trunk/drivers/media/video/saa7134/saa7134-empress.c +++ b/trunk/drivers/media/video/saa7134/saa7134-empress.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include "saa7134-reg.h" diff --git a/trunk/drivers/media/video/se401.c b/trunk/drivers/media/video/se401.c index 85ffc2cba039..c8f05297d0f0 100644 --- a/trunk/drivers/media/video/se401.c +++ b/trunk/drivers/media/video/se401.c @@ -31,7 +31,6 @@ static const char version[] = "0.24"; #include #include #include -#include #include #include #include "se401.h" diff --git a/trunk/drivers/media/video/stk-webcam.c b/trunk/drivers/media/video/stk-webcam.c index 4d6785e63455..2e5937047278 100644 --- a/trunk/drivers/media/video/stk-webcam.c +++ b/trunk/drivers/media/video/stk-webcam.c @@ -27,7 +27,6 @@ #include #include #include -#include #include #include diff --git a/trunk/drivers/media/video/stradis.c b/trunk/drivers/media/video/stradis.c index eaada39c76fd..0eb313082c97 100644 --- a/trunk/drivers/media/video/stradis.c +++ b/trunk/drivers/media/video/stradis.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/drivers/media/video/stv680.c b/trunk/drivers/media/video/stv680.c index 8b4e7dafce7b..75f286f7a2e9 100644 --- a/trunk/drivers/media/video/stv680.c +++ b/trunk/drivers/media/video/stv680.c @@ -62,7 +62,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/drivers/media/video/usbvideo/vicam.c b/trunk/drivers/media/video/usbvideo/vicam.c index 45fce39ec9ad..8d73979596f9 100644 --- a/trunk/drivers/media/video/usbvideo/vicam.c +++ b/trunk/drivers/media/video/usbvideo/vicam.c @@ -43,7 +43,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/drivers/media/video/usbvision/usbvision-video.c b/trunk/drivers/media/video/usbvision/usbvision-video.c index 90d9b5c0e9a7..90b58914f984 100644 --- a/trunk/drivers/media/video/usbvision/usbvision-video.c +++ b/trunk/drivers/media/video/usbvision/usbvision-video.c @@ -50,7 +50,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/drivers/media/video/v4l2-dev.c b/trunk/drivers/media/video/v4l2-dev.c index a7f1b69a7dab..31eac66411d7 100644 --- a/trunk/drivers/media/video/v4l2-dev.c +++ b/trunk/drivers/media/video/v4l2-dev.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include diff --git a/trunk/drivers/media/video/zoran/zoran_driver.c b/trunk/drivers/media/video/zoran/zoran_driver.c index bcdefb1bcb3d..3d7df32a3d87 100644 --- a/trunk/drivers/media/video/zoran/zoran_driver.c +++ b/trunk/drivers/media/video/zoran/zoran_driver.c @@ -49,7 +49,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/drivers/misc/sgi-gru/grufile.c b/trunk/drivers/misc/sgi-gru/grufile.c index aed609832bc2..fa2d93a9fb8d 100644 --- a/trunk/drivers/misc/sgi-gru/grufile.c +++ b/trunk/drivers/misc/sgi-gru/grufile.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/misc/sgi-gru/grukservices.c b/trunk/drivers/misc/sgi-gru/grukservices.c index 79689b10f937..eedbf9c32760 100644 --- a/trunk/drivers/misc/sgi-gru/grukservices.c +++ b/trunk/drivers/misc/sgi-gru/grukservices.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/net/8139too.c b/trunk/drivers/net/8139too.c index 0e2ba21d4441..8ae72ec14456 100644 --- a/trunk/drivers/net/8139too.c +++ b/trunk/drivers/net/8139too.c @@ -908,7 +908,6 @@ 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, diff --git a/trunk/drivers/net/arm/ixp4xx_eth.c b/trunk/drivers/net/arm/ixp4xx_eth.c index 3fe09876e76d..6f42ad728915 100644 --- a/trunk/drivers/net/arm/ixp4xx_eth.c +++ b/trunk/drivers/net/arm/ixp4xx_eth.c @@ -1142,9 +1142,7 @@ 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) diff --git a/trunk/drivers/net/atlx/atl2.c b/trunk/drivers/net/atlx/atl2.c index 204db961029e..c734b1983ec1 100644 --- a/trunk/drivers/net/atlx/atl2.c +++ b/trunk/drivers/net/atlx/atl2.c @@ -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_UCAST | WAKE_BCAST | WAKE_MCAST)) + if (wol->wolopts & (WAKE_MCAST|WAKE_BCAST|WAKE_MCAST)) return -EOPNOTSUPP; /* these settings will always override what we currently have */ diff --git a/trunk/drivers/net/cs89x0.c b/trunk/drivers/net/cs89x0.c index 55445f980f9c..3eee666a9cd2 100644 --- a/trunk/drivers/net/cs89x0.c +++ b/trunk/drivers/net/cs89x0.c @@ -1524,7 +1524,6 @@ 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", @@ -1536,7 +1535,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_irqsave(&lp->lock, flags); + spin_lock_irq(&lp->lock); netif_stop_queue(dev); /* initiate a transmit sequence */ @@ -1550,13 +1549,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_irqrestore(&lp->lock, flags); + spin_unlock_irq(&lp->lock); 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_irqrestore(&lp->lock, flags); + spin_unlock_irq(&lp->lock); lp->stats.tx_bytes += skb->len; dev->trans_start = jiffies; dev_kfree_skb (skb); diff --git a/trunk/drivers/net/ehea/ehea_main.c b/trunk/drivers/net/ehea/ehea_main.c index e8d46cc1bec2..147c4b088fb3 100644 --- a/trunk/drivers/net/ehea/ehea_main.c +++ b/trunk/drivers/net/ehea/ehea_main.c @@ -3080,9 +3080,7 @@ 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, diff --git a/trunk/drivers/net/fec.c b/trunk/drivers/net/fec.c index d4b98074b1b7..0f19b743749b 100644 --- a/trunk/drivers/net/fec.c +++ b/trunk/drivers/net/fec.c @@ -1642,7 +1642,6 @@ 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, diff --git a/trunk/drivers/net/gianfar.c b/trunk/drivers/net/gianfar.c index 43d813ed9f45..4ae1d259fced 100644 --- a/trunk/drivers/net/gianfar.c +++ b/trunk/drivers/net/gianfar.c @@ -156,8 +156,6 @@ 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 diff --git a/trunk/drivers/net/igb/igb_main.c b/trunk/drivers/net/igb/igb_main.c index adb09d32625d..be480292aba1 100644 --- a/trunk/drivers/net/igb/igb_main.c +++ b/trunk/drivers/net/igb/igb_main.c @@ -127,48 +127,14 @@ 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 *); @@ -5452,6 +5418,43 @@ 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) { diff --git a/trunk/drivers/net/irda/irtty-sir.c b/trunk/drivers/net/irda/irtty-sir.c index 20f9bc626688..d53aa9582137 100644 --- a/trunk/drivers/net/irda/irtty-sir.c +++ b/trunk/drivers/net/irda/irtty-sir.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include diff --git a/trunk/drivers/net/isa-skeleton.c b/trunk/drivers/net/isa-skeleton.c index d12377b84358..73585fd8f29f 100644 --- a/trunk/drivers/net/isa-skeleton.c +++ b/trunk/drivers/net/isa-skeleton.c @@ -430,8 +430,7 @@ 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. */ - unsigned long flags; - spin_lock_irqsave(&np->lock, flags); + spin_lock_irq(&np->lock); add_to_tx_ring(np, skb, length); dev->trans_start = jiffies; @@ -447,7 +446,7 @@ static int net_send_packet(struct sk_buff *skb, struct net_device *dev) * is when the transmit statistics are updated. */ - spin_unlock_irqrestore(&np->lock, flags); + spin_unlock_irq(&np->lock); #else /* This is the case for older hardware which takes * a single transmit buffer at a time, and it is diff --git a/trunk/drivers/net/phy/phy_device.c b/trunk/drivers/net/phy/phy_device.c index b10fedd82143..eba937c46376 100644 --- a/trunk/drivers/net/phy/phy_device.c +++ b/trunk/drivers/net/phy/phy_device.c @@ -134,10 +134,8 @@ int phy_scan_fixups(struct phy_device *phydev) err = fixup->run(phydev); - if (err < 0) { - mutex_unlock(&phy_fixup_lock); + if (err < 0) return err; - } } } mutex_unlock(&phy_fixup_lock); diff --git a/trunk/drivers/net/plip.c b/trunk/drivers/net/plip.c index 2ca8b0d84ee2..7a62f781fef2 100644 --- a/trunk/drivers/net/plip.c +++ b/trunk/drivers/net/plip.c @@ -270,9 +270,6 @@ 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. diff --git a/trunk/drivers/net/ps3_gelic_net.c b/trunk/drivers/net/ps3_gelic_net.c index a3932c9f3406..d1a5fb4d6acb 100644 --- a/trunk/drivers/net/ps3_gelic_net.c +++ b/trunk/drivers/net/ps3_gelic_net.c @@ -1411,7 +1411,6 @@ 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, diff --git a/trunk/drivers/net/ps3_gelic_wireless.c b/trunk/drivers/net/ps3_gelic_wireless.c index 6932b08d746b..b6b3ca9bdb21 100644 --- a/trunk/drivers/net/ps3_gelic_wireless.c +++ b/trunk/drivers/net/ps3_gelic_wireless.c @@ -2707,7 +2707,6 @@ 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, diff --git a/trunk/drivers/net/smc91x.c b/trunk/drivers/net/smc91x.c index 1c70e999cc50..fdcbaf8dfa73 100644 --- a/trunk/drivers/net/smc91x.c +++ b/trunk/drivers/net/smc91x.c @@ -1774,7 +1774,6 @@ 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 diff --git a/trunk/drivers/net/smsc911x.c b/trunk/drivers/net/smsc911x.c index 94b6d2658ddc..66067f9d91c0 100644 --- a/trunk/drivers/net/smsc911x.c +++ b/trunk/drivers/net/smsc911x.c @@ -1779,7 +1779,6 @@ 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 diff --git a/trunk/drivers/net/sunvnet.c b/trunk/drivers/net/sunvnet.c index f1e5e4542c2a..a82fb2aca4cb 100644 --- a/trunk/drivers/net/sunvnet.c +++ b/trunk/drivers/net/sunvnet.c @@ -1016,9 +1016,7 @@ 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, diff --git a/trunk/drivers/net/usb/kaweth.c b/trunk/drivers/net/usb/kaweth.c index 1f9ec29fce50..e01314789718 100644 --- a/trunk/drivers/net/usb/kaweth.c +++ b/trunk/drivers/net/usb/kaweth.c @@ -999,9 +999,6 @@ 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( diff --git a/trunk/drivers/net/usb/pegasus.c b/trunk/drivers/net/usb/pegasus.c index 631d269ac980..73acbd244aa1 100644 --- a/trunk/drivers/net/usb/pegasus.c +++ b/trunk/drivers/net/usb/pegasus.c @@ -1493,9 +1493,6 @@ 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 = { diff --git a/trunk/drivers/net/via-rhine.c b/trunk/drivers/net/via-rhine.c index 88c30a58b4bd..d3489a3c4c03 100644 --- a/trunk/drivers/net/via-rhine.c +++ b/trunk/drivers/net/via-rhine.c @@ -621,7 +621,6 @@ 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, diff --git a/trunk/drivers/net/wireless/orinoco/main.c b/trunk/drivers/net/wireless/orinoco/main.c index a370e510f19f..345593c4accb 100644 --- a/trunk/drivers/net/wireless/orinoco/main.c +++ b/trunk/drivers/net/wireless/orinoco/main.c @@ -2521,8 +2521,6 @@ 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, }; @@ -2557,6 +2555,7 @@ 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; diff --git a/trunk/drivers/pci/hotplug/cpci_hotplug_core.c b/trunk/drivers/pci/hotplug/cpci_hotplug_core.c index d703e73fffa7..a5b9f6ae507b 100644 --- a/trunk/drivers/pci/hotplug/cpci_hotplug_core.c +++ b/trunk/drivers/pci/hotplug/cpci_hotplug_core.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/pci/hotplug/cpqphp_ctrl.c b/trunk/drivers/pci/hotplug/cpqphp_ctrl.c index 0ff689afa757..2fa47af992a8 100644 --- a/trunk/drivers/pci/hotplug/cpqphp_ctrl.c +++ b/trunk/drivers/pci/hotplug/cpqphp_ctrl.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/pci/hotplug/cpqphp_sysfs.c b/trunk/drivers/pci/hotplug/cpqphp_sysfs.c index e6089bdb6e5b..8450f4a6568a 100644 --- a/trunk/drivers/pci/hotplug/cpqphp_sysfs.c +++ b/trunk/drivers/pci/hotplug/cpqphp_sysfs.c @@ -33,7 +33,6 @@ #include #include #include -#include #include #include "cpqphp.h" diff --git a/trunk/drivers/pci/hotplug/pciehp_ctrl.c b/trunk/drivers/pci/hotplug/pciehp_ctrl.c index 8aab8edf123e..ff4034502d24 100644 --- a/trunk/drivers/pci/hotplug/pciehp_ctrl.c +++ b/trunk/drivers/pci/hotplug/pciehp_ctrl.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include "../pci.h" diff --git a/trunk/drivers/pci/syscall.c b/trunk/drivers/pci/syscall.c index e1c1ec540893..ec22284eed30 100644 --- a/trunk/drivers/pci/syscall.c +++ b/trunk/drivers/pci/syscall.c @@ -9,6 +9,7 @@ #include #include +#include #include #include #include "pci.h" diff --git a/trunk/drivers/power/wm97xx_battery.c b/trunk/drivers/power/wm97xx_battery.c index b787335a8419..8bde92126d34 100644 --- a/trunk/drivers/power/wm97xx_battery.c +++ b/trunk/drivers/power/wm97xx_battery.c @@ -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(dev_get_drvdata(bat_ps->dev->parent), + return wm97xx_read_aux_adc(bat_ps->dev->parent->driver_data, 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(dev_get_drvdata(bat_ps->dev->parent), + return wm97xx_read_aux_adc(bat_ps->dev->parent->driver_data, pdata->temp_aux) * pdata->temp_mult / pdata->temp_div; } diff --git a/trunk/drivers/s390/block/dasd_ioctl.c b/trunk/drivers/s390/block/dasd_ioctl.c index df918ef27965..4ce3f72ee1c1 100644 --- a/trunk/drivers/s390/block/dasd_ioctl.c +++ b/trunk/drivers/s390/block/dasd_ioctl.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include diff --git a/trunk/drivers/scsi/qla2xxx/qla_mid.c b/trunk/drivers/scsi/qla2xxx/qla_mid.c index cd78c501803a..650bcef08f2a 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_mid.c +++ b/trunk/drivers/scsi/qla2xxx/qla_mid.c @@ -9,6 +9,7 @@ #include #include +#include #include #include diff --git a/trunk/drivers/staging/comedi/drivers/jr3_pci.c b/trunk/drivers/staging/comedi/drivers/jr3_pci.c index e3c3adc282e2..baf83c6a9412 100644 --- a/trunk/drivers/staging/comedi/drivers/jr3_pci.c +++ b/trunk/drivers/staging/comedi/drivers/jr3_pci.c @@ -45,8 +45,6 @@ Devices: [JR3] PCI force sensor board (jr3_pci) #include #include #include -#include -#include #include "comedi_pci.h" #include "jr3_pci.h" diff --git a/trunk/drivers/staging/comedi/drivers/s626.c b/trunk/drivers/staging/comedi/drivers/s626.c index 5d9bab352c1d..92121cf8c45c 100644 --- a/trunk/drivers/staging/comedi/drivers/s626.c +++ b/trunk/drivers/staging/comedi/drivers/s626.c @@ -111,13 +111,9 @@ 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, 0x6000, 0x0272, 0, 0, 0}, + {PCI_VENDOR_ID_S626, PCI_DEVICE_ID_S626, PCI_ANY_ID, PCI_ANY_ID, 0, 0, + 0}, {0} }; @@ -503,26 +499,25 @@ static int s626_attach(struct comedi_device *dev, struct comedi_devconfig *it) resource_size_t resourceStart; dma_addr_t appdma; struct comedi_subdevice *s; - const struct pci_device_id *ids; - struct pci_dev *pdev = NULL; + struct pci_dev *pdev; if (alloc_private(dev, sizeof(struct s626_private)) < 0) return -ENOMEM; - 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) { + 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]) { /* matches requested bus/slot */ - if (pdev->bus->number == it->options[0] && - PCI_SLOT(pdev->devfn) == it->options[1]) - break; - } else break; - } while (1); + } + } else { + /* no bus/slot specified */ + break; + } } devpriv->pdev = pdev; diff --git a/trunk/drivers/staging/go7007/s2250-loader.c b/trunk/drivers/staging/go7007/s2250-loader.c index bb22347af60e..a5e4acab089e 100644 --- a/trunk/drivers/staging/go7007/s2250-loader.c +++ b/trunk/drivers/staging/go7007/s2250-loader.c @@ -17,7 +17,6 @@ #include #include -#include #include #include diff --git a/trunk/drivers/staging/meilhaus/TODO b/trunk/drivers/staging/meilhaus/TODO index d6ce39823de6..6ec25203089c 100644 --- a/trunk/drivers/staging/meilhaus/TODO +++ b/trunk/drivers/staging/meilhaus/TODO @@ -7,4 +7,4 @@ TODO: - possible comedi merge Please send cleanup patches to Greg Kroah-Hartman -and CC: David Kiliani and Meilhaus Support +and CC: David Kiliani diff --git a/trunk/drivers/staging/rspiusb/rspiusb.c b/trunk/drivers/staging/rspiusb/rspiusb.c index 2f8155c1968b..1cdfe69585ea 100644 --- a/trunk/drivers/staging/rspiusb/rspiusb.c +++ b/trunk/drivers/staging/rspiusb/rspiusb.c @@ -444,7 +444,8 @@ static void piusb_write_bulk_callback(struct urb *urb) __func__, status); pdx->pendingWrite = 0; - kfree(urb->transfer_buffer); + usb_buffer_free(urb->dev, urb->transfer_buffer_length, + urb->transfer_buffer, urb->transfer_dma); } int piusb_output(struct ioctl_struct *io, unsigned char *uBuf, int len, @@ -456,7 +457,9 @@ int piusb_output(struct ioctl_struct *io, unsigned char *uBuf, int len, urb = usb_alloc_urb(0, GFP_KERNEL); if (urb != NULL) { - kbuf = kmalloc(len, GFP_KERNEL); + kbuf = + usb_buffer_alloc(pdx->udev, len, GFP_KERNEL, + &urb->transfer_dma); if (!kbuf) { dev_err(&pdx->udev->dev, "buffer_alloc failed\n"); return -ENOMEM; @@ -467,6 +470,7 @@ 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, @@ -637,7 +641,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; @@ -708,7 +712,9 @@ static int MapUserBuffer(struct ioctl_struct *io, struct device_extension *pdx) usb_fill_bulk_urb(pdx->PixelUrb[frameInfo][i], pdx->udev, epAddr, - NULL, // non-DMA HC? buy a better hardware + (dma_addr_t *) sg_dma_address(&pdx-> + sgl[frameInfo] + [i]), sg_dma_len(&pdx->sgl[frameInfo][i]), piusb_readPIXEL_callback, (void *)pdx); pdx->PixelUrb[frameInfo][i]->transfer_dma = diff --git a/trunk/drivers/staging/rt2870/rt2870.h b/trunk/drivers/staging/rt2870/rt2870.h index 29e3b53e52a1..5e5b3f2b7eb1 100644 --- a/trunk/drivers/staging/rt2870/rt2870.h +++ b/trunk/drivers/staging/rt2870/rt2870.h @@ -89,7 +89,6 @@ {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. */ \ diff --git a/trunk/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac_wx.c b/trunk/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac_wx.c index 54b4b718f84a..93af37e2d31a 100644 --- a/trunk/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac_wx.c +++ b/trunk/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac_wx.c @@ -461,19 +461,19 @@ int ieee80211_wx_get_name(struct ieee80211_device *ieee, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) { - strlcpy(wrqu->name, "802.11", IFNAMSIZ); + strcpy(wrqu->name, "802.11"); if(ieee->modulation & IEEE80211_CCK_MODULATION){ - strlcat(wrqu->name, "b", IFNAMSIZ); + strcat(wrqu->name, "b"); if(ieee->modulation & IEEE80211_OFDM_MODULATION) - strlcat(wrqu->name, "/g", IFNAMSIZ); + strcat(wrqu->name, "/g"); }else if(ieee->modulation & IEEE80211_OFDM_MODULATION) - strlcat(wrqu->name, "g", IFNAMSIZ); + strcat(wrqu->name, "g"); if((ieee->state == IEEE80211_LINKED) || (ieee->state == IEEE80211_LINKED_SCANNING)) - strlcat(wrqu->name," link", IFNAMSIZ); + strcat(wrqu->name," linked"); else if(ieee->state != IEEE80211_NOLINK) - strlcat(wrqu->name," .....", IFNAMSIZ); + strcat(wrqu->name," link.."); return 0; diff --git a/trunk/drivers/staging/rtl8192su/Kconfig b/trunk/drivers/staging/rtl8192su/Kconfig index 770f41280f21..4b5552c5926e 100644 --- a/trunk/drivers/staging/rtl8192su/Kconfig +++ b/trunk/drivers/staging/rtl8192su/Kconfig @@ -1,6 +1,6 @@ config RTL8192SU tristate "RealTek RTL8192SU Wireless LAN NIC driver" depends on PCI - depends on WIRELESS_EXT + depends on WIRELESS_EXT && COMPAT_NET_DEV_OPS default N ---help--- diff --git a/trunk/drivers/staging/rtl8192su/ieee80211/ieee80211_module.c b/trunk/drivers/staging/rtl8192su/ieee80211/ieee80211_module.c index 759032db4a34..f408b4583b82 100644 --- a/trunk/drivers/staging/rtl8192su/ieee80211/ieee80211_module.c +++ b/trunk/drivers/staging/rtl8192su/ieee80211/ieee80211_module.c @@ -118,6 +118,7 @@ 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; diff --git a/trunk/drivers/staging/rtl8192su/ieee80211/ieee80211_softmac_wx.c b/trunk/drivers/staging/rtl8192su/ieee80211/ieee80211_softmac_wx.c index 191dc3fbbe32..1f50c46dcb90 100644 --- a/trunk/drivers/staging/rtl8192su/ieee80211/ieee80211_softmac_wx.c +++ b/trunk/drivers/staging/rtl8192su/ieee80211/ieee80211_softmac_wx.c @@ -548,21 +548,21 @@ int ieee80211_wx_get_name(struct ieee80211_device *ieee, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) { - strlcpy(wrqu->name, "802.11", IFNAMSIZ); + strcpy(wrqu->name, "802.11"); if(ieee->modulation & IEEE80211_CCK_MODULATION){ - strlcat(wrqu->name, "b", IFNAMSIZ); + strcat(wrqu->name, "b"); if(ieee->modulation & IEEE80211_OFDM_MODULATION) - strlcat(wrqu->name, "/g", IFNAMSIZ); + strcat(wrqu->name, "/g"); }else if(ieee->modulation & IEEE80211_OFDM_MODULATION) - strlcat(wrqu->name, "g", IFNAMSIZ); + strcat(wrqu->name, "g"); if (ieee->mode & (IEEE_N_24G | IEEE_N_5G)) - strlcat(wrqu->name, "/n", IFNAMSIZ); + strcat(wrqu->name, "/n"); if((ieee->state == IEEE80211_LINKED) || (ieee->state == IEEE80211_LINKED_SCANNING)) - strlcat(wrqu->name, " link", IFNAMSIZ); + strcat(wrqu->name," linked"); else if(ieee->state != IEEE80211_NOLINK) - strlcat(wrqu->name, " .....", IFNAMSIZ); + strcat(wrqu->name," link.."); return 0; diff --git a/trunk/drivers/staging/rtl8192su/r8192U_core.c b/trunk/drivers/staging/rtl8192su/r8192U_core.c index 4ab250743e81..f1423d714496 100644 --- a/trunk/drivers/staging/rtl8192su/r8192U_core.c +++ b/trunk/drivers/staging/rtl8192su/r8192U_core.c @@ -12132,19 +12132,6 @@ 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) @@ -12199,7 +12186,15 @@ static void * __devinit rtl8192_usb_probe(struct usb_device *udev, priv->ops = &rtl8192u_ops; #endif - dev->netdev_ops = &rtl8192_netdev_ops; + 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; //DMESG("Oops: i'm coming\n"); #if WIRELESS_EXT >= 12 diff --git a/trunk/drivers/staging/rtl8192su/r8192U_pm.c b/trunk/drivers/staging/rtl8192su/r8192U_pm.c index b1531a8d0cde..92c95aa36638 100644 --- a/trunk/drivers/staging/rtl8192su/r8192U_pm.c +++ b/trunk/drivers/staging/rtl8192su/r8192U_pm.c @@ -35,9 +35,7 @@ int rtl8192U_suspend(struct usb_interface *intf, pm_message_t state) return 0; } - if (dev->netdev_ops->ndo_stop) - dev->netdev_ops->ndo_stop(dev); - + dev->stop(dev); mdelay(10); netif_device_detach(dev); @@ -63,9 +61,7 @@ int rtl8192U_resume (struct usb_interface *intf) } netif_device_attach(dev); - - if (dev->netdev_ops->ndo_open) - dev->netdev_ops->ndo_open(dev); + dev->open(dev); } return 0; diff --git a/trunk/drivers/staging/serqt_usb2/serqt_usb2.c b/trunk/drivers/staging/serqt_usb2/serqt_usb2.c index a9bd4106beb7..90b29b564631 100644 --- a/trunk/drivers/staging/serqt_usb2/serqt_usb2.c +++ b/trunk/drivers/staging/serqt_usb2/serqt_usb2.c @@ -866,7 +866,7 @@ static void qt_release(struct usb_serial *serial) } -static int qt_open(struct tty_struct *tty, +int qt_open(struct tty_struct *tty, struct usb_serial_port *port, struct file *filp) { struct usb_serial *serial; @@ -1041,19 +1041,17 @@ static void qt_block_until_empty(struct tty_struct *tty, } } -static void qt_close( struct usb_serial_port *port) +static void qt_close(struct tty_struct *tty, struct usb_serial_port *port, + struct file *filp) { 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); diff --git a/trunk/drivers/staging/stlc45xx/stlc45xx.c b/trunk/drivers/staging/stlc45xx/stlc45xx.c index a137c78fac09..cfdaac9b747e 100644 --- a/trunk/drivers/staging/stlc45xx/stlc45xx.c +++ b/trunk/drivers/staging/stlc45xx/stlc45xx.c @@ -2235,6 +2235,24 @@ 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; @@ -2277,14 +2295,6 @@ 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) @@ -2347,6 +2357,7 @@ 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, diff --git a/trunk/drivers/staging/usbip/usbip_common.c b/trunk/drivers/staging/usbip/usbip_common.c index 251220dc8851..22f93dd0ba03 100644 --- a/trunk/drivers/staging/usbip/usbip_common.c +++ b/trunk/drivers/staging/usbip/usbip_common.c @@ -18,7 +18,6 @@ */ #include -#include #include #include #include diff --git a/trunk/drivers/staging/vt6655/device_main.c b/trunk/drivers/staging/vt6655/device_main.c index f43ca416e4a8..a10ed27acbc2 100644 --- a/trunk/drivers/staging/vt6655/device_main.c +++ b/trunk/drivers/staging/vt6655/device_main.c @@ -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, (long)&chip_info_table[0]}, +{ 0x1106, 0x3253, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (int)&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, pm_message_t state); +static int viawget_suspend(struct pci_dev *pcid, u32 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, PMSG_HIBERNATE); + viawget_suspend(pdev, 3); } } } @@ -3949,7 +3949,7 @@ device_notify_reboot(struct notifier_block *nb, unsigned long event, void *p) } static int -viawget_suspend(struct pci_dev *pcid, pm_message_t state) +viawget_suspend(struct pci_dev *pcid, u32 state) { int power_status; // to silence the compiler @@ -3971,7 +3971,7 @@ viawget_suspend(struct pci_dev *pcid, pm_message_t state) memset(pMgmt->abyCurrBSSID, 0, 6); pMgmt->eCurrState = WMAC_STATE_IDLE; pci_disable_device(pcid); - power_status = pci_set_power_state(pcid, pci_choose_state(pcid, state)); + power_status = pci_set_power_state(pcid, state); spin_unlock_irq(&pDevice->lock); return 0; } diff --git a/trunk/drivers/telephony/ixj.c b/trunk/drivers/telephony/ixj.c index 40de151f2789..a913efc69669 100644 --- a/trunk/drivers/telephony/ixj.c +++ b/trunk/drivers/telephony/ixj.c @@ -257,7 +257,6 @@ #include /* everything... */ #include /* error codes */ #include -#include #include #include #include diff --git a/trunk/drivers/telephony/phonedev.c b/trunk/drivers/telephony/phonedev.c index f3873f650bb4..b52cc830c0b4 100644 --- a/trunk/drivers/telephony/phonedev.c +++ b/trunk/drivers/telephony/phonedev.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include diff --git a/trunk/drivers/usb/class/cdc-acm.c b/trunk/drivers/usb/class/cdc-acm.c index 5b15d9d8896b..3f1045993474 100644 --- a/trunk/drivers/usb/class/cdc-acm.c +++ b/trunk/drivers/usb/class/cdc-acm.c @@ -387,7 +387,6 @@ 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"); @@ -463,20 +462,11 @@ static void acm_rx_tasklet(unsigned long _acm) rcv->buffer = buf; - 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); + 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; @@ -1237,14 +1227,9 @@ static int acm_probe(struct usb_interface *intf, goto alloc_fail7; } - 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); + 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; } diff --git a/trunk/drivers/usb/class/cdc-wdm.c b/trunk/drivers/usb/class/cdc-wdm.c index ba589d4ca8bc..0fe434505ac4 100644 --- a/trunk/drivers/usb/class/cdc-wdm.c +++ b/trunk/drivers/usb/class/cdc-wdm.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/usb/class/usbtmc.c b/trunk/drivers/usb/class/usbtmc.c index b09a527f7341..3703789d0d2a 100644 --- a/trunk/drivers/usb/class/usbtmc.c +++ b/trunk/drivers/usb/class/usbtmc.c @@ -751,7 +751,7 @@ static int get_capabilities(struct usbtmc_device_data *data) { struct device *dev = &data->usb_dev->dev; char *buffer; - int rv = 0; + int rv; 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); - goto err_out; + return rv; } dev_dbg(dev, "GET_CAPABILITIES returned %x\n", buffer[0]); @@ -773,8 +773,7 @@ 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]); - rv = -EPERM; - goto err_out; + return -EPERM; } data->capabilities.interface_capabilities = buffer[4]; @@ -782,9 +781,8 @@ 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 rv; + return 0; } #define capability_attribute(name) \ diff --git a/trunk/drivers/usb/core/Kconfig b/trunk/drivers/usb/core/Kconfig index ad925946f869..69280c35b5cb 100644 --- a/trunk/drivers/usb/core/Kconfig +++ b/trunk/drivers/usb/core/Kconfig @@ -28,7 +28,7 @@ comment "Miscellaneous USB options" depends on USB config USB_DEVICEFS - bool "USB device filesystem (DEPRECATED)" + bool "USB device filesystem (DEPRECATED)" if EMBEDDED depends on USB ---help--- If you say Y here (and to "/proc file system support" in the "File diff --git a/trunk/drivers/usb/core/devices.c b/trunk/drivers/usb/core/devices.c index 96f11715cd26..73c108d117b4 100644 --- a/trunk/drivers/usb/core/devices.c +++ b/trunk/drivers/usb/core/devices.c @@ -136,19 +136,17 @@ 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 */ }; diff --git a/trunk/drivers/usb/core/devio.c b/trunk/drivers/usb/core/devio.c index 38b8bce782d6..308609039c73 100644 --- a/trunk/drivers/usb/core/devio.c +++ b/trunk/drivers/usb/core/devio.c @@ -325,34 +325,21 @@ 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; - signr = as->signr; - if (signr) { + if (as->signr) { sinfo.si_signo = as->signr; sinfo.si_errno = as->status; sinfo.si_code = SI_ASYNCIO; sinfo.si_addr = as->userurb; - pid = as->pid; - uid = as->uid; - euid = as->euid; - secid = as->secid; + kill_pid_info_as_uid(as->signr, &sinfo, as->pid, as->uid, + as->euid, 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); } @@ -995,7 +982,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_length > 0 && !uurb->buffer) + if (!uurb->buffer) return -EINVAL; if (!(uurb->type == USBDEVFS_URB_TYPE_CONTROL && (uurb->endpoint & ~USB_ENDPOINT_DIR_MASK) == 0)) { @@ -1051,6 +1038,11 @@ 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", @@ -1070,6 +1062,9 @@ 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; @@ -1111,34 +1106,27 @@ 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; } - if (uurb->buffer_length > 0 && - !access_ok(is_in ? VERIFY_WRITE : VERIFY_READ, - uurb->buffer, uurb->buffer_length)) { - kfree(isopkt); - kfree(dr); - return -EFAULT; - } as = alloc_async(uurb->number_of_packets); if (!as) { kfree(isopkt); kfree(dr); 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->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) | @@ -1181,7 +1169,7 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, kfree(isopkt); as->ps = ps; as->userurb = arg; - if (is_in && uurb->buffer_length > 0) + if (uurb->endpoint & USB_DIR_IN) as->userbuffer = uurb->buffer; else as->userbuffer = NULL; @@ -1191,9 +1179,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 && uurb->buffer_length > 0) { + if (!is_in) { if (copy_from_user(as->urb->transfer_buffer, uurb->buffer, - uurb->buffer_length)) { + as->urb->transfer_buffer_length)) { free_async(as); return -EFAULT; } @@ -1243,22 +1231,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)) - goto err_out; + return -EFAULT; if (put_user(as->status, &userurb->status)) - goto err_out; + return -EFAULT; if (put_user(urb->actual_length, &userurb->actual_length)) - goto err_out; + return -EFAULT; if (put_user(urb->error_count, &userurb->error_count)) - goto err_out; + return -EFAULT; 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)) - goto err_out; + return -EFAULT; if (put_user(urb->iso_frame_desc[i].status, &userurb->iso_frame_desc[i].status)) - goto err_out; + return -EFAULT; } } @@ -1267,10 +1255,6 @@ 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) diff --git a/trunk/drivers/usb/core/hcd.h b/trunk/drivers/usb/core/hcd.h index ec5c67ea07b7..d397ecfd5b17 100644 --- a/trunk/drivers/usb/core/hcd.h +++ b/trunk/drivers/usb/core/hcd.h @@ -227,10 +227,6 @@ 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 *); diff --git a/trunk/drivers/usb/core/hub.c b/trunk/drivers/usb/core/hub.c index 71f86c60d83c..2af3b4f06054 100644 --- a/trunk/drivers/usb/core/hub.c +++ b/trunk/drivers/usb/core/hub.c @@ -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_work(struct work_struct *work) +static void hub_tt_kevent (struct work_struct *work) { struct usb_hub *hub = - container_of(work, struct usb_hub, tt.clear_work); + container_of(work, struct usb_hub, tt.kevent); unsigned long flags; int limit = 100; @@ -462,7 +462,6 @@ static void hub_tt_work(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; @@ -472,25 +471,21 @@ static void hub_tt_work(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_clear_tt_buffer - clear control/bulk TT state in high speed hub - * @urb: an URB associated with the failed or incomplete split transaction + * 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 * * 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 @@ -500,10 +495,8 @@ static void hub_tt_work(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. */ -int usb_hub_clear_tt_buffer(struct urb *urb) +void usb_hub_tt_clear_buffer (struct usb_device *udev, int pipe) { - struct usb_device *udev = urb->dev; - int pipe = urb->pipe; struct usb_tt *tt = udev->tt; unsigned long flags; struct usb_tt_clear *clear; @@ -515,7 +508,7 @@ int usb_hub_clear_tt_buffer(struct urb *urb) 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 -ENOMEM; + return; } /* info that CLEAR_TT_BUFFER needs */ @@ -527,19 +520,14 @@ int usb_hub_clear_tt_buffer(struct urb *urb) : (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->clear_work); + schedule_work (&tt->kevent); spin_unlock_irqrestore (&tt->lock, flags); - return 0; } -EXPORT_SYMBOL_GPL(usb_hub_clear_tt_buffer); +EXPORT_SYMBOL_GPL(usb_hub_tt_clear_buffer); /* If do_delay is false, return the number of milliseconds the caller * needs to delay. @@ -830,7 +818,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.clear_work); + cancel_work_sync(&hub->tt.kevent); } /* caller has locked the hub device */ @@ -947,7 +935,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.clear_work, hub_tt_work); + INIT_WORK (&hub->tt.kevent, hub_tt_kevent); switch (hdev->descriptor.bDeviceProtocol) { case 0: break; diff --git a/trunk/drivers/usb/core/hub.h b/trunk/drivers/usb/core/hub.h index de8081f065ed..889c0f32a40b 100644 --- a/trunk/drivers/usb/core/hub.h +++ b/trunk/drivers/usb/core/hub.h @@ -188,18 +188,16 @@ 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 clear_work; + struct work_struct kevent; }; struct usb_tt_clear { struct list_head clear_list; unsigned tt; u16 devinfo; - struct usb_hcd *hcd; - struct usb_host_endpoint *ep; }; -extern int usb_hub_clear_tt_buffer(struct urb *urb); +extern void usb_hub_tt_clear_buffer(struct usb_device *dev, int pipe); extern void usb_ep0_reinit(struct usb_device *); #endif /* __LINUX_HUB_H */ diff --git a/trunk/drivers/usb/core/message.c b/trunk/drivers/usb/core/message.c index 9720e699f472..2bed83caacb1 100644 --- a/trunk/drivers/usb/core/message.c +++ b/trunk/drivers/usb/core/message.c @@ -806,48 +806,6 @@ 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 @@ -879,9 +837,24 @@ int usb_string(struct usb_device *dev, int index, char *buf, size_t size) if (!tbuf) return -ENOMEM; - err = usb_get_langid(dev, tbuf); - if (err < 0) - goto errout; + /* 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_string_sub(dev, dev->string_langid, index, tbuf); if (err < 0) diff --git a/trunk/drivers/usb/gadget/Kconfig b/trunk/drivers/usb/gadget/Kconfig index 7f8e83a954ac..5d1ddf485d1e 100644 --- a/trunk/drivers/usb/gadget/Kconfig +++ b/trunk/drivers/usb/gadget/Kconfig @@ -286,27 +286,6 @@ 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 @@ -342,6 +321,27 @@ 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,7 +604,6 @@ 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 diff --git a/trunk/drivers/usb/gadget/amd5536udc.c b/trunk/drivers/usb/gadget/amd5536udc.c index 77352ccc245e..826f3adde5d8 100644 --- a/trunk/drivers/usb/gadget/amd5536udc.c +++ b/trunk/drivers/usb/gadget/amd5536udc.c @@ -48,6 +48,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/usb/gadget/audio.c b/trunk/drivers/usb/gadget/audio.c index 9f80f4e970bd..94de7e864614 100644 --- a/trunk/drivers/usb/gadget/audio.c +++ b/trunk/drivers/usb/gadget/audio.c @@ -42,9 +42,9 @@ * Instead: allocate your own, using normal USB-IF procedures. */ -/* 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 */ +/* Thanks to NetChip Technologies for donating this product ID. */ +#define AUDIO_VENDOR_NUM 0x0525 /* NetChip */ +#define AUDIO_PRODUCT_NUM 0xa4a1 /* Linux-USB Audio Gadget */ /*-------------------------------------------------------------------------*/ diff --git a/trunk/drivers/usb/gadget/ether.c b/trunk/drivers/usb/gadget/ether.c index bd102f5052ba..d006dc652e02 100644 --- a/trunk/drivers/usb/gadget/ether.c +++ b/trunk/drivers/usb/gadget/ether.c @@ -293,16 +293,15 @@ 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); - if (!has_rndis()) - 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), + 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; } diff --git a/trunk/drivers/usb/gadget/langwell_udc.c b/trunk/drivers/usb/gadget/langwell_udc.c index a3913519fd58..6829d5961359 100644 --- a/trunk/drivers/usb/gadget/langwell_udc.c +++ b/trunk/drivers/usb/gadget/langwell_udc.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/usb/gadget/pxa25x_udc.c b/trunk/drivers/usb/gadget/pxa25x_udc.c index ed21e263f832..0ce4e2819847 100644 --- a/trunk/drivers/usb/gadget/pxa25x_udc.c +++ b/trunk/drivers/usb/gadget/pxa25x_udc.c @@ -139,7 +139,7 @@ static int is_vbus_present(void) { struct pxa2xx_udc_mach_info *mach = the_controller->mach; - if (gpio_is_valid(mach->gpio_vbus)) { + if (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 (gpio_is_valid(mach->gpio_pullup)) + if (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 (gpio_is_valid(mach->gpio_pullup)) + if (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 (!gpio_is_valid(udc->mach->gpio_pullup) && !udc->mach->udc_command) + if (!udc->mach->gpio_pullup && !udc->mach->udc_command) return -EOPNOTSUPP; udc->pullup = (is_active != 0); @@ -1802,13 +1802,11 @@ 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 } } @@ -2162,7 +2160,7 @@ static int __init pxa25x_udc_probe(struct platform_device *pdev) dev->dev = &pdev->dev; dev->mach = pdev->dev.platform_data; - if (gpio_is_valid(dev->mach->gpio_vbus)) { + if (dev->mach->gpio_vbus) { if ((retval = gpio_request(dev->mach->gpio_vbus, "pxa25x_udc GPIO VBUS"))) { dev_dbg(&pdev->dev, @@ -2175,7 +2173,7 @@ static int __init pxa25x_udc_probe(struct platform_device *pdev) } else vbus_irq = 0; - if (gpio_is_valid(dev->mach->gpio_pullup)) { + if (dev->mach->gpio_pullup) { if ((retval = gpio_request(dev->mach->gpio_pullup, "pca25x_udc GPIO PULLUP"))) { dev_dbg(&pdev->dev, @@ -2258,10 +2256,10 @@ static int __init pxa25x_udc_probe(struct platform_device *pdev) #endif free_irq(irq, dev); err_irq1: - if (gpio_is_valid(dev->mach->gpio_pullup)) + if (dev->mach->gpio_pullup) gpio_free(dev->mach->gpio_pullup); err_gpio_pullup: - if (gpio_is_valid(dev->mach->gpio_vbus)) + if (dev->mach->gpio_vbus) gpio_free(dev->mach->gpio_vbus); err_gpio_vbus: clk_put(dev->clk); @@ -2296,11 +2294,11 @@ static int __exit pxa25x_udc_remove(struct platform_device *pdev) free_irq(LUBBOCK_USB_IRQ, dev); } #endif - if (gpio_is_valid(dev->mach->gpio_vbus)) { + if (dev->mach->gpio_vbus) { free_irq(gpio_to_irq(dev->mach->gpio_vbus), dev); gpio_free(dev->mach->gpio_vbus); } - if (gpio_is_valid(dev->mach->gpio_pullup)) + if (dev->mach->gpio_pullup) gpio_free(dev->mach->gpio_pullup); clk_put(dev->clk); @@ -2331,7 +2329,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 (!gpio_is_valid(udc->mach->gpio_pullup) && !udc->mach->udc_command) + if (!udc->mach->gpio_pullup && !udc->mach->udc_command) WARNING("USB host won't detect disconnect!\n"); udc->suspended = 1; diff --git a/trunk/drivers/usb/gadget/rndis.c b/trunk/drivers/usb/gadget/rndis.c index ca41b0b5afb3..2b4660e08c4d 100644 --- a/trunk/drivers/usb/gadget/rndis.c +++ b/trunk/drivers/usb/gadget/rndis.c @@ -442,8 +442,6 @@ 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) */ diff --git a/trunk/drivers/usb/gadget/s3c2410_udc.c b/trunk/drivers/usb/gadget/s3c2410_udc.c index a9b452fe6221..9a2b8920532d 100644 --- a/trunk/drivers/usb/gadget/s3c2410_udc.c +++ b/trunk/drivers/usb/gadget/s3c2410_udc.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/usb/host/Kconfig b/trunk/drivers/usb/host/Kconfig index 1a920c70b5a1..0c03471f0d41 100644 --- a/trunk/drivers/usb/host/Kconfig +++ b/trunk/drivers/usb/host/Kconfig @@ -181,27 +181,26 @@ 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_BE - bool "OHCI support for OF platform bus (big endian)" +config USB_OHCI_HCD_PPC_OF + bool "OHCI support for PPC USB controller on OF platform bus" depends on USB_OHCI_HCD && PPC_OF - select USB_OHCI_BIG_ENDIAN_DESC - select USB_OHCI_BIG_ENDIAN_MMIO + default y ---help--- - Enables support for big-endian USB controllers present on the + 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 + select USB_OHCI_BIG_ENDIAN_DESC + select USB_OHCI_BIG_ENDIAN_MMIO + config USB_OHCI_HCD_PPC_OF_LE - bool "OHCI support for OF platform bus (little endian)" - depends on USB_OHCI_HCD && PPC_OF + bool "Support little endian HC" + depends on USB_OHCI_HCD_PPC_OF + default n 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" diff --git a/trunk/drivers/usb/host/ehci-au1xxx.c b/trunk/drivers/usb/host/ehci-au1xxx.c index 59d208d94d4e..c3a778bd359c 100644 --- a/trunk/drivers/usb/host/ehci-au1xxx.c +++ b/trunk/drivers/usb/host/ehci-au1xxx.c @@ -113,8 +113,6 @@ 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) diff --git a/trunk/drivers/usb/host/ehci-fsl.c b/trunk/drivers/usb/host/ehci-fsl.c index 991174937db3..bf86809c5120 100644 --- a/trunk/drivers/usb/host/ehci-fsl.c +++ b/trunk/drivers/usb/host/ehci-fsl.c @@ -325,8 +325,6 @@ 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) diff --git a/trunk/drivers/usb/host/ehci-hcd.c b/trunk/drivers/usb/host/ehci-hcd.c index 7d03549c3339..2b72473544d3 100644 --- a/trunk/drivers/usb/host/ehci-hcd.c +++ b/trunk/drivers/usb/host/ehci-hcd.c @@ -1003,8 +1003,6 @@ ehci_endpoint_disable (struct usb_hcd *hcd, struct usb_host_endpoint *ep) 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; @@ -1032,14 +1030,12 @@ 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; - spin_lock_irqsave(&ehci->lock, flags); + rescan: + spin_lock_irq(&ehci->lock); qh = ep->hcpriv; /* For Bulk and Interrupt endpoints we maintain the toggle state @@ -1048,24 +1044,29 @@ 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_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(). + } 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. */ - if (eptype == USB_ENDPOINT_XFER_BULK) { - unlink_async(ehci, qh); - } else { - intr_deschedule(ehci, qh); - (void) qh_schedule(ehci, qh); + 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); + } } + spin_unlock_irq(&ehci->lock); + schedule_timeout_uninterruptible(1); + goto rescan; } } - spin_unlock_irqrestore(&ehci->lock, flags); + spin_unlock_irq(&ehci->lock); } static int ehci_get_frame (struct usb_hcd *hcd) diff --git a/trunk/drivers/usb/host/ehci-ixp4xx.c b/trunk/drivers/usb/host/ehci-ixp4xx.c index 89b7c70c6ed6..a44bb4a94954 100644 --- a/trunk/drivers/usb/host/ehci-ixp4xx.c +++ b/trunk/drivers/usb/host/ehci-ixp4xx.c @@ -61,8 +61,6 @@ 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) diff --git a/trunk/drivers/usb/host/ehci-orion.c b/trunk/drivers/usb/host/ehci-orion.c index dc2ac613a9d1..770dd9aba62a 100644 --- a/trunk/drivers/usb/host/ehci-orion.c +++ b/trunk/drivers/usb/host/ehci-orion.c @@ -165,8 +165,6 @@ 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 diff --git a/trunk/drivers/usb/host/ehci-pci.c b/trunk/drivers/usb/host/ehci-pci.c index c2f1b7df918c..f3683e1da161 100644 --- a/trunk/drivers/usb/host/ehci-pci.c +++ b/trunk/drivers/usb/host/ehci-pci.c @@ -404,8 +404,6 @@ 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, }; /*-------------------------------------------------------------------------*/ diff --git a/trunk/drivers/usb/host/ehci-ppc-of.c b/trunk/drivers/usb/host/ehci-ppc-of.c index 36f96da129f5..fbd272288fc2 100644 --- a/trunk/drivers/usb/host/ehci-ppc-of.c +++ b/trunk/drivers/usb/host/ehci-ppc-of.c @@ -79,8 +79,6 @@ 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, }; diff --git a/trunk/drivers/usb/host/ehci-ps3.c b/trunk/drivers/usb/host/ehci-ps3.c index 1dee33b9139e..93f7035d00a1 100644 --- a/trunk/drivers/usb/host/ehci-ps3.c +++ b/trunk/drivers/usb/host/ehci-ps3.c @@ -75,8 +75,6 @@ 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) diff --git a/trunk/drivers/usb/host/ehci-q.c b/trunk/drivers/usb/host/ehci-q.c index 9a1384747f3b..3192f683f807 100644 --- a/trunk/drivers/usb/host/ehci-q.c +++ b/trunk/drivers/usb/host/ehci-q.c @@ -93,22 +93,6 @@ 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); @@ -139,55 +123,6 @@ 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, @@ -214,14 +149,6 @@ 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; @@ -230,15 +157,21 @@ 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 */ - 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 */ + /* 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 */ status = -EPROTO; - } ehci_vdbg (ehci, "dev%d ep%d%s qtd token %08x --> status %d\n", @@ -246,6 +179,28 @@ 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; @@ -436,16 +391,9 @@ 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. @@ -471,13 +419,6 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh) && (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, @@ -893,7 +834,6 @@ qh_make ( 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; } @@ -907,10 +847,6 @@ 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); @@ -928,7 +864,7 @@ static void qh_link_async (struct ehci_hcd *ehci, struct ehci_qh *qh) } } - /* clear halt and/or toggle; and maybe recover from silicon quirk */ + /* clear halt and maybe recover from silicon quirk */ if (qh->qh_state == QH_STATE_IDLE) qh_refresh (ehci, qh); diff --git a/trunk/drivers/usb/host/ehci-sched.c b/trunk/drivers/usb/host/ehci-sched.c index 74f7f83b29ad..9d1babc7ff65 100644 --- a/trunk/drivers/usb/host/ehci-sched.c +++ b/trunk/drivers/usb/host/ehci-sched.c @@ -1619,14 +1619,11 @@ 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); - urb->actual_length += desc->actual_length; - } + if (!(t & EHCI_ISOC_BABBLE)) + desc->actual_length = EHCI_ITD_LENGTH (t); } else if (likely ((t & EHCI_ISOC_ACTIVE) == 0)) { desc->status = 0; - desc->actual_length = EHCI_ITD_LENGTH(t); - urb->actual_length += desc->actual_length; + desc->actual_length = EHCI_ITD_LENGTH (t); } else { /* URB was too late */ desc->status = -EXDEV; @@ -2017,8 +2014,7 @@ sitd_complete ( desc->status = -EPROTO; } else { desc->status = 0; - desc->actual_length = desc->length - SITD_LENGTH(t); - urb->actual_length += desc->actual_length; + desc->actual_length = desc->length - SITD_LENGTH (t); } stream->depth -= stream->interval << 3; diff --git a/trunk/drivers/usb/host/ehci.h b/trunk/drivers/usb/host/ehci.h index 2bfff30f4704..90ad3395bb21 100644 --- a/trunk/drivers/usb/host/ehci.h +++ b/trunk/drivers/usb/host/ehci.h @@ -354,9 +354,7 @@ 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))); /*-------------------------------------------------------------------------*/ diff --git a/trunk/drivers/usb/host/fhci-sched.c b/trunk/drivers/usb/host/fhci-sched.c index 62a226b61670..bb63b68ddb77 100644 --- a/trunk/drivers/usb/host/fhci-sched.c +++ b/trunk/drivers/usb/host/fhci-sched.c @@ -576,7 +576,9 @@ 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) + if (fhci_ioports_check_bus_state(fhci) == 1 && + usb->port_status != FHCI_PORT_LOW && + usb->port_status != FHCI_PORT_FULL) fhci_device_connected_interrupt(fhci); } usb_er &= ~USB_E_RESET_MASK; @@ -603,7 +605,9 @@ irqreturn_t fhci_irq(struct usb_hcd *hcd) } if (usb_er & USB_E_IDLE_MASK) { - if (usb->port_status == FHCI_PORT_DISABLED) { + if (usb->port_status == FHCI_PORT_DISABLED && + usb->port_status != FHCI_PORT_LOW && + usb->port_status != FHCI_PORT_FULL) { usb_er &= ~USB_E_RESET_MASK; fhci_device_connected_interrupt(fhci); } else if (usb->port_status == diff --git a/trunk/drivers/usb/host/isp1760-if.c b/trunk/drivers/usb/host/isp1760-if.c index d4feebfc63bd..3fa3a1702796 100644 --- a/trunk/drivers/usb/host/isp1760-if.c +++ b/trunk/drivers/usb/host/isp1760-if.c @@ -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 = __devexit_p(isp1760_plat_remove), + .remove = isp1760_plat_remove, .driver = { .name = "isp1760", }, diff --git a/trunk/drivers/usb/host/r8a66597-hcd.c b/trunk/drivers/usb/host/r8a66597-hcd.c index e18f74946e68..56976cc0352a 100644 --- a/trunk/drivers/usb/host/r8a66597-hcd.c +++ b/trunk/drivers/usb/host/r8a66597-hcd.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/usb/misc/iowarrior.c b/trunk/drivers/usb/misc/iowarrior.c index 90e1a8dedfa9..3c5fe5cee05a 100644 --- a/trunk/drivers/usb/misc/iowarrior.c +++ b/trunk/drivers/usb/misc/iowarrior.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include diff --git a/trunk/drivers/usb/misc/rio500.c b/trunk/drivers/usb/misc/rio500.c index d645f3899fe1..deb95bb49fd1 100644 --- a/trunk/drivers/usb/misc/rio500.c +++ b/trunk/drivers/usb/misc/rio500.c @@ -32,7 +32,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/drivers/usb/misc/usblcd.c b/trunk/drivers/usb/misc/usblcd.c index 29092b8e59ce..e0ff9ccd866b 100644 --- a/trunk/drivers/usb/misc/usblcd.c +++ b/trunk/drivers/usb/misc/usblcd.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/drivers/usb/musb/cppi_dma.h b/trunk/drivers/usb/musb/cppi_dma.h index 59bf949e589b..8a39de3e6e47 100644 --- a/trunk/drivers/usb/musb/cppi_dma.h +++ b/trunk/drivers/usb/musb/cppi_dma.h @@ -5,6 +5,7 @@ #include #include +#include #include #include diff --git a/trunk/drivers/usb/musb/davinci.c b/trunk/drivers/usb/musb/davinci.c index e16ff605c458..180d7daa4099 100644 --- a/trunk/drivers/usb/musb/davinci.c +++ b/trunk/drivers/usb/musb/davinci.c @@ -35,14 +35,13 @@ #include #include #include -#include #include #include "musb_core.h" #ifdef CONFIG_MACH_DAVINCI_EVM -#define GPIO_nVBUS_DRV 144 +#define GPIO_nVBUS_DRV 87 #endif #include "davinci.h" @@ -330,6 +329,7 @@ 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,9 +343,7 @@ 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 - * (OTG_TIME_A_WAIT_VRISE) but we don't check for that. - */ + /* NOTE: this must complete poweron within 100 msec */ davinci_source_power(musb, drvvbus, 0); DBG(2, "VBUS %s (%s)%s, devctl %02x\n", drvvbus ? "on" : "off", @@ -413,21 +411,6 @@ 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); @@ -454,15 +437,6 @@ 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 */ diff --git a/trunk/drivers/usb/musb/musb_core.h b/trunk/drivers/usb/musb/musb_core.h index 381d648a36b8..f3772ca3b2cf 100644 --- a/trunk/drivers/usb/musb/musb_core.h +++ b/trunk/drivers/usb/musb/musb_core.h @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/usb/musb/musb_host.c b/trunk/drivers/usb/musb/musb_host.c index cf94511485f2..94a2a350a414 100644 --- a/trunk/drivers/usb/musb/musb_host.c +++ b/trunk/drivers/usb/musb/musb_host.c @@ -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 (status == 0 && urb->error_count) + if (urb->error_count) status = -EXDEV; break; } @@ -2235,30 +2235,13 @@ 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 (!is_host_active(musb)) + if (musb->xceiv->state == OTG_STATE_A_SUSPEND) return 0; - 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)); + 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); return -EBUSY; } else return 0; diff --git a/trunk/drivers/usb/otg/Kconfig b/trunk/drivers/usb/otg/Kconfig index aa884d072f0b..69feeec1628c 100644 --- a/trunk/drivers/usb/otg/Kconfig +++ b/trunk/drivers/usb/otg/Kconfig @@ -59,4 +59,18 @@ 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 diff --git a/trunk/drivers/usb/otg/Makefile b/trunk/drivers/usb/otg/Makefile index 208167856529..6d1abdd3c0ac 100644 --- a/trunk/drivers/usb/otg/Makefile +++ b/trunk/drivers/usb/otg/Makefile @@ -9,6 +9,7 @@ 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/trunk/drivers/usb/otg/langwell_otg.c b/trunk/drivers/usb/otg/langwell_otg.c new file mode 100644 index 000000000000..6f628d0e9f39 --- /dev/null +++ b/trunk/drivers/usb/otg/langwell_otg.c @@ -0,0 +1,1915 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../core/hcd.h" + +#include + +#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 , Hao Wu "); +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); diff --git a/trunk/drivers/usb/otg/nop-usb-xceiv.c b/trunk/drivers/usb/otg/nop-usb-xceiv.c index af456b48985f..9ed5ea568679 100644 --- a/trunk/drivers/usb/otg/nop-usb-xceiv.c +++ b/trunk/drivers/usb/otg/nop-usb-xceiv.c @@ -53,7 +53,6 @@ EXPORT_SYMBOL(usb_nop_xceiv_register); void usb_nop_xceiv_unregister(void) { platform_device_unregister(pd); - pd = NULL; } EXPORT_SYMBOL(usb_nop_xceiv_unregister); diff --git a/trunk/drivers/usb/serial/console.c b/trunk/drivers/usb/serial/console.c index 0e4f2e41ace5..247b61bfb7f4 100644 --- a/trunk/drivers/usb/serial/console.c +++ b/trunk/drivers/usb/serial/console.c @@ -169,11 +169,9 @@ static int usb_console_setup(struct console *co, char *options) kfree(tty); } } - /* 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. */ + /* 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 */ port->console = 1; retval = 0; @@ -206,7 +204,7 @@ static void usb_console_write(struct console *co, dbg("%s - port %d, %d byte(s)", __func__, port->number, count); - if (!port->console) { + if (!port->port.count) { dbg("%s - port not opened", __func__); return; } @@ -302,7 +300,8 @@ void usb_serial_console_exit(void) { if (usbcons_info.port) { unregister_console(&usbcons); - usbcons_info.port->console = 0; + if (usbcons_info.port->port.count) + usbcons_info.port->port.count--; usbcons_info.port = NULL; } } diff --git a/trunk/drivers/usb/serial/cp210x.c b/trunk/drivers/usb/serial/cp210x.c index e9a40b820fd4..2b9eeda62bfe 100644 --- a/trunk/drivers/usb/serial/cp210x.c +++ b/trunk/drivers/usb/serial/cp210x.c @@ -67,8 +67,6 @@ 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 */ diff --git a/trunk/drivers/usb/serial/cypress_m8.c b/trunk/drivers/usb/serial/cypress_m8.c index 59adfe123110..9734085fd2fe 100644 --- a/trunk/drivers/usb/serial/cypress_m8.c +++ b/trunk/drivers/usb/serial/cypress_m8.c @@ -1228,8 +1228,8 @@ static void cypress_read_int_callback(struct urb *urb) /* precursor to disconnect so just go away */ return; case -EPIPE: - /* Can't call usb_clear_halt while in_interrupt */ - /* FALLS THROUGH */ + usb_clear_halt(port->serial->dev, 0x81); + break; default: /* something ugly is going on... */ dev_err(&urb->dev->dev, diff --git a/trunk/drivers/usb/serial/ftdi_sio.c b/trunk/drivers/usb/serial/ftdi_sio.c index 60c64cc5be2a..5f08702f672f 100644 --- a/trunk/drivers/usb/serial/ftdi_sio.c +++ b/trunk/drivers/usb/serial/ftdi_sio.c @@ -33,7 +33,6 @@ #include #include #include -#include #include #include #include @@ -108,7 +107,6 @@ 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); @@ -120,10 +118,6 @@ 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, }; @@ -197,7 +191,6 @@ 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) }, @@ -586,9 +579,6 @@ 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) }, @@ -654,16 +644,6 @@ 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) }, @@ -680,8 +660,6 @@ 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) }, @@ -689,6 +667,7 @@ 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) }, @@ -1044,16 +1023,6 @@ 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__); @@ -1584,39 +1553,6 @@ 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 @@ -2686,5 +2622,3 @@ 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"); diff --git a/trunk/drivers/usb/serial/ftdi_sio.h b/trunk/drivers/usb/serial/ftdi_sio.h index c9fbd7415092..f1d440a728a3 100644 --- a/trunk/drivers/usb/serial/ftdi_sio.h +++ b/trunk/drivers/usb/serial/ftdi_sio.h @@ -506,7 +506,6 @@ * * 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 */ @@ -615,9 +614,6 @@ #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 @@ -739,15 +735,6 @@ /* 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) */ @@ -861,6 +848,9 @@ #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 @@ -944,8 +934,6 @@ #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 diff --git a/trunk/drivers/usb/serial/mos7840.c b/trunk/drivers/usb/serial/mos7840.c index c31940a307f8..c40f95c1951c 100644 --- a/trunk/drivers/usb/serial/mos7840.c +++ b/trunk/drivers/usb/serial/mos7840.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/drivers/usb/serial/option.c b/trunk/drivers/usb/serial/option.c index 98262dd552bb..575816e6ba37 100644 --- a/trunk/drivers/usb/serial/option.c +++ b/trunk/drivers/usb/serial/option.c @@ -206,7 +206,6 @@ 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 @@ -308,20 +307,11 @@ 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) }, @@ -440,7 +430,6 @@ 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 */ @@ -540,13 +529,8 @@ 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(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(0x1da5, 0x4515) }, /* BenQ H20 */ { 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); @@ -748,6 +732,7 @@ 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 " @@ -875,6 +860,7 @@ 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)", @@ -935,11 +921,23 @@ static int option_open(struct tty_struct *tty, dbg("%s", __func__); - /* Start reading from the IN endpoint */ + /* Reset low level data toggle and start reading from endpoints */ 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", @@ -948,6 +946,16 @@ 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; @@ -1210,6 +1218,7 @@ 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) { diff --git a/trunk/drivers/usb/serial/pl2303.c b/trunk/drivers/usb/serial/pl2303.c index 7d15bfa7c2db..efaf59c4f5d0 100644 --- a/trunk/drivers/usb/serial/pl2303.c +++ b/trunk/drivers/usb/serial/pl2303.c @@ -94,7 +94,6 @@ 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 */ }; diff --git a/trunk/drivers/usb/serial/pl2303.h b/trunk/drivers/usb/serial/pl2303.h index 12aac7d2462d..1d7a22e3a9fd 100644 --- a/trunk/drivers/usb/serial/pl2303.h +++ b/trunk/drivers/usb/serial/pl2303.h @@ -122,7 +122,3 @@ /* 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 diff --git a/trunk/drivers/usb/serial/sierra.c b/trunk/drivers/usb/serial/sierra.c index f48d05e0acc1..032f7aeb40a4 100644 --- a/trunk/drivers/usb/serial/sierra.c +++ b/trunk/drivers/usb/serial/sierra.c @@ -181,50 +181,35 @@ 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, 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, 0x0220) }, /* Sierra Wireless MC5725 */ { 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 T598 */ + /* Sierra Wireless Device */ { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x0025, 0xFF, 0xFF, 0xFF) }, - { 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, 0x0026) }, /* Sierra Wireless Device */ + { USB_DEVICE(0x1199, 0x0027) }, /* Sierra Wireless Device */ + { USB_DEVICE(0x1199, 0x0028) }, /* Sierra Wireless Device */ { USB_DEVICE(0x1199, 0x6802) }, /* 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, 0x6803) }, /* Sierra Wireless MC8765 */ { USB_DEVICE(0x1199, 0x6812) }, /* Sierra Wireless MC8775 & AC 875U */ - { USB_DEVICE(0x1199, 0x6813) }, /* Sierra Wireless MC8775 */ + { USB_DEVICE(0x1199, 0x6813) }, /* Sierra Wireless MC8775 (Lenovo) */ { USB_DEVICE(0x1199, 0x6815) }, /* Sierra Wireless MC8775 */ - { USB_DEVICE(0x1199, 0x6816) }, /* Sierra Wireless MC8775 */ + { USB_DEVICE(0x03f0, 0x1e1d) }, /* HP hs2300 a.k.a 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 */ @@ -242,13 +227,16 @@ 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 C888, Air Card 501, USB 303, USB 304 */ + /* Sierra Wireless Device */ { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6890, 0xFF, 0xFF, 0xFF)}, - /* Sierra Wireless C22/C33 */ + /* Sierra Wireless Device */ { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6891, 0xFF, 0xFF, 0xFF)}, - /* Sierra Wireless HSPA Non-Composite Device */ + /* Sierra Wireless Device */ { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6892, 0xFF, 0xFF, 0xFF)}, - { USB_DEVICE(0x1199, 0x6893) }, /* Sierra Wireless Device */ + + { USB_DEVICE(0x1199, 0x0112) }, /* Sierra Wireless AirCard 580 */ + { USB_DEVICE(0x0F3D, 0x0112) }, /* Airprime/Sierra PC 5220 */ + { USB_DEVICE(0x1199, 0x68A3), /* Sierra Wireless Direct IP modems */ .driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist }, @@ -826,7 +814,7 @@ static int sierra_startup(struct usb_serial *serial) return 0; } -static void sierra_release(struct usb_serial *serial) +static void sierra_disconnect(struct usb_serial *serial) { int i; struct usb_serial_port *port; @@ -842,6 +830,7 @@ static void sierra_release(struct usb_serial *serial) if (!portdata) continue; kfree(portdata); + usb_set_serial_port_data(port, NULL); } } @@ -864,7 +853,7 @@ static struct usb_serial_driver sierra_device = { .tiocmget = sierra_tiocmget, .tiocmset = sierra_tiocmset, .attach = sierra_startup, - .release = sierra_release, + .disconnect = sierra_disconnect, .read_int_callback = sierra_instat_callback, }; diff --git a/trunk/drivers/usb/serial/ti_usb_3410_5052.c b/trunk/drivers/usb/serial/ti_usb_3410_5052.c index 14971a926990..991d8232e376 100644 --- a/trunk/drivers/usb/serial/ti_usb_3410_5052.c +++ b/trunk/drivers/usb/serial/ti_usb_3410_5052.c @@ -191,6 +191,7 @@ 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] = { @@ -1657,7 +1658,7 @@ static int ti_do_download(struct usb_device *dev, int pipe, u8 cs = 0; int done; struct ti_firmware_header *header; - int status = 0; + int status; int len; for (pos = sizeof(struct ti_firmware_header); pos < size; pos++) diff --git a/trunk/drivers/usb/serial/usb-serial.c b/trunk/drivers/usb/serial/usb-serial.c index bd7581b3a48a..a84216464ca0 100644 --- a/trunk/drivers/usb/serial/usb-serial.c +++ b/trunk/drivers/usb/serial/usb-serial.c @@ -21,7 +21,6 @@ #include #include #include -#include #include #include #include @@ -221,8 +220,7 @@ static int serial_open (struct tty_struct *tty, struct file *filp) tty->driver_data = port; tty_port_tty_set(&port->port, tty); - /* If the console is attached, the device is already open */ - if (port->port.count == 1 && !port->console) { + if (port->port.count == 1) { /* lock this module before we call it * this may fail, which means we must bail out, diff --git a/trunk/drivers/usb/storage/option_ms.c b/trunk/drivers/usb/storage/option_ms.c index 773a5cd38c5a..d41cc0a970f7 100644 --- a/trunk/drivers/usb/storage/option_ms.c +++ b/trunk/drivers/usb/storage/option_ms.c @@ -118,9 +118,6 @@ 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, diff --git a/trunk/drivers/video/fbmem.c b/trunk/drivers/video/fbmem.c index a85c818be945..53ea05645ff8 100644 --- a/trunk/drivers/video/fbmem.c +++ b/trunk/drivers/video/fbmem.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/video/omap/omapfb_main.c b/trunk/drivers/video/omap/omapfb_main.c index 8862233d57b6..4ea99bfc37b4 100644 --- a/trunk/drivers/video/omap/omapfb_main.c +++ b/trunk/drivers/video/omap/omapfb_main.c @@ -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 = dev_get_drvdata(dev); + struct omapfb_device *fbdev = (struct omapfb_device *)dev->driver_data; 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 = dev_get_drvdata(dev); + struct omapfb_device *fbdev = (struct omapfb_device *)dev->driver_data; 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 = dev_get_drvdata(dev); + struct omapfb_device *fbdev = (struct omapfb_device *)dev->driver_data; 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 = dev_get_drvdata(dev); + struct omapfb_device *fbdev = (struct omapfb_device *)dev->driver_data; 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 = dev_get_drvdata(dev); + struct omapfb_device *fbdev = (struct omapfb_device *)dev->driver_data; 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 = dev_get_drvdata(dev); + struct omapfb_device *fbdev = (struct omapfb_device *)dev->driver_data; 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 = dev_get_drvdata(dev); + struct omapfb_device *fbdev = (struct omapfb_device *)dev->driver_data; return snprintf(buf, PAGE_SIZE, "%s\n", fbdev->ctrl->name); } diff --git a/trunk/fs/adfs/super.c b/trunk/fs/adfs/super.c index 6910a98bd73c..aad92f0a1048 100644 --- a/trunk/fs/adfs/super.c +++ b/trunk/fs/adfs/super.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include "adfs.h" #include "dir_f.h" diff --git a/trunk/fs/afs/dir.c b/trunk/fs/afs/dir.c index 88067f36e5e7..9bd757774c9e 100644 --- a/trunk/fs/afs/dir.c +++ b/trunk/fs/afs/dir.c @@ -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 uninitialized_var(fid); + struct afs_fid fid; struct dentry *parent; struct key *key; void *dir_version; diff --git a/trunk/fs/afs/super.c b/trunk/fs/afs/super.c index e1ea1c240b6a..ad0514d0115f 100644 --- a/trunk/fs/afs/super.c +++ b/trunk/fs/afs/super.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/fs/autofs4/dev-ioctl.c b/trunk/fs/autofs4/dev-ioctl.c index 00bf8fcb245f..f3da2eb51f56 100644 --- a/trunk/fs/autofs4/dev-ioctl.c +++ b/trunk/fs/autofs4/dev-ioctl.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/fs/bfs/dir.c b/trunk/fs/bfs/dir.c index 1e41aadb1068..54bd07d44e68 100644 --- a/trunk/fs/bfs/dir.c +++ b/trunk/fs/bfs/dir.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include "bfs.h" diff --git a/trunk/fs/bfs/file.c b/trunk/fs/bfs/file.c index 88b9a3ff44e4..6a021265f018 100644 --- a/trunk/fs/bfs/file.c +++ b/trunk/fs/bfs/file.c @@ -11,6 +11,7 @@ #include #include +#include #include "bfs.h" #undef DEBUG diff --git a/trunk/fs/btrfs/compression.c b/trunk/fs/btrfs/compression.c index 9d8ba4d54a37..de1e2fd32080 100644 --- a/trunk/fs/btrfs/compression.c +++ b/trunk/fs/btrfs/compression.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/fs/btrfs/file.c b/trunk/fs/btrfs/file.c index 4b833972273a..7c3cd248d8d6 100644 --- a/trunk/fs/btrfs/file.c +++ b/trunk/fs/btrfs/file.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/fs/btrfs/inode.c b/trunk/fs/btrfs/inode.c index 791eab19e330..7ffa3d34ea19 100644 --- a/trunk/fs/btrfs/inode.c +++ b/trunk/fs/btrfs/inode.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/fs/btrfs/ioctl.c b/trunk/fs/btrfs/ioctl.c index bd88f25889f7..9f4db848db10 100644 --- a/trunk/fs/btrfs/ioctl.c +++ b/trunk/fs/btrfs/ioctl.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/fs/btrfs/super.c b/trunk/fs/btrfs/super.c index 6d6d06cb6dfc..9f179d4832d5 100644 --- a/trunk/fs/btrfs/super.c +++ b/trunk/fs/btrfs/super.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/fs/char_dev.c b/trunk/fs/char_dev.c index a173551e19d7..b7c9d5187a75 100644 --- a/trunk/fs/char_dev.c +++ b/trunk/fs/char_dev.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include diff --git a/trunk/fs/compat.c b/trunk/fs/compat.c index 94502dab972a..fbadb947727b 100644 --- a/trunk/fs/compat.c +++ b/trunk/fs/compat.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/fs/compat_ioctl.c b/trunk/fs/compat_ioctl.c index f28f070a60fc..626c7483b4de 100644 --- a/trunk/fs/compat_ioctl.c +++ b/trunk/fs/compat_ioctl.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/fs/exofs/super.c b/trunk/fs/exofs/super.c index 5ab10c3bbebe..a343b4ea62f6 100644 --- a/trunk/fs/exofs/super.c +++ b/trunk/fs/exofs/super.c @@ -31,7 +31,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include #include #include #include diff --git a/trunk/fs/ext2/ioctl.c b/trunk/fs/ext2/ioctl.c index e7431309bdca..7cb4badef927 100644 --- a/trunk/fs/ext2/ioctl.c +++ b/trunk/fs/ext2/ioctl.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include diff --git a/trunk/fs/ext4/ext4.h b/trunk/fs/ext4/ext4.h index 9714db393efe..0ddf7e55abe1 100644 --- a/trunk/fs/ext4/ext4.h +++ b/trunk/fs/ext4/ext4.h @@ -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. 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 */ + /* phys. block for ^^^ */ ext4_fsblk_t pright; + /* how many blocks we want to allocate */ + unsigned int len; /* flags. see above EXT4_MB_HINT_* */ unsigned int flags; }; diff --git a/trunk/fs/ext4/ext4_jbd2.c b/trunk/fs/ext4/ext4_jbd2.c index eb27fd0f2ee8..ad13a84644e1 100644 --- a/trunk/fs/ext4/ext4_jbd2.c +++ b/trunk/fs/ext4/ext4_jbd2.c @@ -43,8 +43,6 @@ int __ext4_journal_forget(const char *where, handle_t *handle, ext4_journal_abort_handle(where, __func__, bh, handle, err); } - else - brelse(bh); return err; } @@ -59,8 +57,6 @@ int __ext4_journal_revoke(const char *where, handle_t *handle, ext4_journal_abort_handle(where, __func__, bh, handle, err); } - else - brelse(bh); return err; } diff --git a/trunk/fs/ext4/ext4_jbd2.h b/trunk/fs/ext4/ext4_jbd2.h index 139fb8cb87e4..be2f426f6805 100644 --- a/trunk/fs/ext4/ext4_jbd2.h +++ b/trunk/fs/ext4/ext4_jbd2.h @@ -131,11 +131,9 @@ 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); @@ -283,10 +281,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) diff --git a/trunk/fs/ext4/extents.c b/trunk/fs/ext4/extents.c index 73ebfb44ad75..50322a09bd01 100644 --- a/trunk/fs/ext4/extents.c +++ b/trunk/fs/ext4/extents.c @@ -1977,7 +1977,6 @@ 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; } } diff --git a/trunk/fs/ext4/ialloc.c b/trunk/fs/ext4/ialloc.c index 29e6dc7299b8..2f645732e3b7 100644 --- a/trunk/fs/ext4/ialloc.c +++ b/trunk/fs/ext4/ialloc.c @@ -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; diff --git a/trunk/fs/ext4/inode.c b/trunk/fs/ext4/inode.c index f9c642b22efa..60a26f3a6f8b 100644 --- a/trunk/fs/ext4/inode.c +++ b/trunk/fs/ext4/inode.c @@ -78,14 +78,16 @@ 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, but we still need to - * call into ext4_journal_revoke() to put the buffer head. + * If the handle isn't valid we're not journaling so there's nothing to do. */ 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"); @@ -1511,14 +1513,14 @@ static int ext4_write_begin(struct file *file, struct address_space *mapping, * Add inode to orphan list in case we crash before * truncate finishes */ - if (pos + len > inode->i_size && ext4_can_truncate(inode)) + if (pos + len > inode->i_size) ext4_orphan_add(handle, inode); ext4_journal_stop(handle); if (pos + len > inode->i_size) { - ext4_truncate(inode); + vmtruncate(inode, inode->i_size); /* - * If truncate failed early the inode might + * If vmtruncate 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. @@ -1612,7 +1614,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 && ext4_can_truncate(inode)) + if (pos + len > inode->i_size) /* if we have allocated more blocks and copied * less. We will have blocks allocated outside * inode->i_size. So truncate them @@ -1626,9 +1628,9 @@ static int ext4_ordered_write_end(struct file *file, ret = ret2; if (pos + len > inode->i_size) { - ext4_truncate(inode); + vmtruncate(inode, inode->i_size); /* - * If truncate failed early the inode might still be + * If vmtruncate 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. */ @@ -1653,7 +1655,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 && ext4_can_truncate(inode)) + if (pos + len > inode->i_size) /* if we have allocated more blocks and copied * less. We will have blocks allocated outside * inode->i_size. So truncate them @@ -1668,9 +1670,9 @@ static int ext4_writeback_write_end(struct file *file, ret = ret2; if (pos + len > inode->i_size) { - ext4_truncate(inode); + vmtruncate(inode, inode->i_size); /* - * If truncate failed early the inode might still be + * If vmtruncate 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. */ @@ -1720,7 +1722,7 @@ static int ext4_journalled_write_end(struct file *file, unlock_page(page); page_cache_release(page); - if (pos + len > inode->i_size && ext4_can_truncate(inode)) + if (pos + len > inode->i_size) /* if we have allocated more blocks and copied * less. We will have blocks allocated outside * inode->i_size. So truncate them @@ -1731,9 +1733,9 @@ static int ext4_journalled_write_end(struct file *file, if (!ret) ret = ret2; if (pos + len > inode->i_size) { - ext4_truncate(inode); + vmtruncate(inode, inode->i_size); /* - * If truncate failed early the inode might still be + * If vmtruncate 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. */ @@ -2303,9 +2305,15 @@ static void mpage_add_bh_to_extent(struct mpage_da_data *mpd, return; } -static int ext4_bh_delay_or_unwritten(handle_t *handle, struct buffer_head *bh) +static int ext4_bh_unmapped_or_delay(handle_t *handle, struct buffer_head *bh) { - return (buffer_delay(bh) || buffer_unwritten(bh)) && buffer_dirty(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); } /* @@ -2390,9 +2398,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_writepage + * with the page in ext4_da_writepage */ - if (ext4_bh_delay_or_unwritten(NULL, bh)) { + if (ext4_bh_unmapped_or_delay(NULL, bh)) { mpage_add_bh_to_extent(mpd, logical, bh->b_size, bh->b_state); @@ -2509,6 +2517,7 @@ 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; @@ -2516,102 +2525,15 @@ 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_writepage(struct page *page, - struct writeback_control *wbc) +static int ext4_da_writepage(struct page *page, + struct writeback_control *wbc) { int ret = 0; loff_t size; @@ -2619,7 +2541,7 @@ static int ext4_writepage(struct page *page, struct buffer_head *page_bufs; struct inode *inode = page->mapping->host; - trace_ext4_writepage(inode, page); + trace_ext4_da_writepage(inode, page); size = i_size_read(inode); if (page->index == size >> PAGE_CACHE_SHIFT) len = size & ~PAGE_CACHE_MASK; @@ -2629,7 +2551,7 @@ static int ext4_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_delay_or_unwritten)) { + ext4_bh_unmapped_or_delay)) { /* * We don't want to do block allocation * So redirty the page and return @@ -2656,13 +2578,13 @@ static int ext4_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, len, + ret = block_prepare_write(page, 0, PAGE_CACHE_SIZE, 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_delay_or_unwritten)) { + ext4_bh_unmapped_or_delay)) { redirty_page_for_writepage(wbc, page); unlock_page(page); return 0; @@ -2678,16 +2600,7 @@ static int ext4_writepage(struct page *page, return 0; } /* now mark the buffer_heads as dirty and uptodate */ - 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); + block_commit_write(page, 0, PAGE_CACHE_SIZE); } if (test_opt(inode->i_sb, NOBH) && ext4_should_writeback_data(inode)) @@ -2994,7 +2907,7 @@ static int ext4_da_write_begin(struct file *file, struct address_space *mapping, * i_size_read because we hold i_mutex. */ if (pos + len > inode->i_size) - ext4_truncate(inode); + vmtruncate(inode, inode->i_size); } if (ret == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries)) @@ -3217,6 +3130,222 @@ 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); @@ -3363,7 +3492,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_writepage, + .writepage = ext4_normal_writepage, .sync_page = block_sync_page, .write_begin = ext4_write_begin, .write_end = ext4_ordered_write_end, @@ -3378,7 +3507,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_writepage, + .writepage = ext4_normal_writepage, .sync_page = block_sync_page, .write_begin = ext4_write_begin, .write_end = ext4_writeback_write_end, @@ -3393,7 +3522,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_writepage, + .writepage = ext4_journalled_writepage, .sync_page = block_sync_page, .write_begin = ext4_write_begin, .write_end = ext4_journalled_write_end, @@ -3407,7 +3536,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_writepage, + .writepage = ext4_da_writepage, .writepages = ext4_da_writepages, .sync_page = block_sync_page, .write_begin = ext4_da_write_begin, @@ -3454,8 +3583,7 @@ int ext4_block_truncate_page(handle_t *handle, struct page *page; int err = 0; - page = find_or_create_page(mapping, from >> PAGE_CACHE_SHIFT, - mapping_gfp_mask(mapping) & ~__GFP_FS); + page = grab_cache_page(mapping, from >> PAGE_CACHE_SHIFT); if (!page) return -EINVAL; diff --git a/trunk/fs/ext4/ioctl.c b/trunk/fs/ext4/ioctl.c index 7050a9cd04a4..bb415408fdb6 100644 --- a/trunk/fs/ext4/ioctl.c +++ b/trunk/fs/ext4/ioctl.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -191,7 +192,7 @@ long ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) case EXT4_IOC_GROUP_EXTEND: { ext4_fsblk_t n_blocks_count; struct super_block *sb = inode->i_sb; - int err, err2=0; + int err, err2; if (!capable(CAP_SYS_RESOURCE)) return -EPERM; @@ -204,11 +205,9 @@ long ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) return err; err = ext4_group_extend(sb, EXT4_SB(sb)->s_es, n_blocks_count); - 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); - } + 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); @@ -253,7 +252,7 @@ long ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) case EXT4_IOC_GROUP_ADD: { struct ext4_new_group_data input; struct super_block *sb = inode->i_sb; - int err, err2=0; + int err, err2; if (!capable(CAP_SYS_RESOURCE)) return -EPERM; @@ -267,11 +266,9 @@ long ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) return err; err = ext4_group_add(sb, &input); - 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); - } + 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); diff --git a/trunk/fs/ext4/mballoc.c b/trunk/fs/ext4/mballoc.c index cd258463e2a9..519a0a686d94 100644 --- a/trunk/fs/ext4/mballoc.c +++ b/trunk/fs/ext4/mballoc.c @@ -657,8 +657,7 @@ static void ext4_mb_mark_free_simple(struct super_block *sb, } } -static noinline_for_stack -void ext4_mb_generate_buddy(struct super_block *sb, +static 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); @@ -1481,8 +1480,7 @@ static void ext4_mb_measure_extent(struct ext4_allocation_context *ac, ext4_mb_check_limits(ac, e4b, 0); } -static noinline_for_stack -int ext4_mb_try_best_found(struct ext4_allocation_context *ac, +static int ext4_mb_try_best_found(struct ext4_allocation_context *ac, struct ext4_buddy *e4b) { struct ext4_free_extent ex = ac->ac_b_ex; @@ -1509,8 +1507,7 @@ int ext4_mb_try_best_found(struct ext4_allocation_context *ac, return 0; } -static noinline_for_stack -int ext4_mb_find_by_goal(struct ext4_allocation_context *ac, +static 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; @@ -1569,8 +1566,7 @@ 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 noinline_for_stack -void ext4_mb_simple_scan_group(struct ext4_allocation_context *ac, +static void ext4_mb_simple_scan_group(struct ext4_allocation_context *ac, struct ext4_buddy *e4b) { struct super_block *sb = ac->ac_sb; @@ -1613,8 +1609,7 @@ 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 noinline_for_stack -void ext4_mb_complex_scan_group(struct ext4_allocation_context *ac, +static void ext4_mb_complex_scan_group(struct ext4_allocation_context *ac, struct ext4_buddy *e4b) { struct super_block *sb = ac->ac_sb; @@ -1673,8 +1668,7 @@ 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 noinline_for_stack -void ext4_mb_scan_aligned(struct ext4_allocation_context *ac, +static void ext4_mb_scan_aligned(struct ext4_allocation_context *ac, struct ext4_buddy *e4b) { struct super_block *sb = ac->ac_sb; @@ -1837,8 +1831,7 @@ void ext4_mb_put_buddy_cache_lock(struct super_block *sb, } -static noinline_for_stack -int ext4_mb_init_group(struct super_block *sb, ext4_group_t group) +static int ext4_mb_init_group(struct super_block *sb, ext4_group_t group) { int ret; @@ -2909,11 +2902,7 @@ int __init init_ext4_mballoc(void) void exit_ext4_mballoc(void) { - /* - * Wait for completion of call_rcu()'s on ext4_pspace_cachep - * before destroying the slab cache. - */ - rcu_barrier(); + /* XXX: synchronize_rcu(); */ kmem_cache_destroy(ext4_pspace_cachep); kmem_cache_destroy(ext4_ac_cachep); kmem_cache_destroy(ext4_free_ext_cachep); @@ -3468,8 +3457,7 @@ 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 noinline_for_stack -void ext4_mb_generate_from_pa(struct super_block *sb, void *bitmap, +static 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); @@ -4227,9 +4215,14 @@ 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; @@ -4240,7 +4233,15 @@ 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 */ @@ -4508,7 +4509,10 @@ ext4_fsblk_t ext4_mb_new_blocks(handle_t *handle, } ac = kmem_cache_alloc(ext4_ac_cachep, GFP_NOFS); - if (!ac) { + if (ac) { + ac->ac_sb = sb; + ac->ac_inode = ar->inode; + } else { ar->len = 0; *errp = -ENOMEM; goto out1; diff --git a/trunk/fs/fat/dir.c b/trunk/fs/fat/dir.c index 530b4ca01510..38ff75a0fe22 100644 --- a/trunk/fs/fat/dir.c +++ b/trunk/fs/fat/dir.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/fs/fat/namei_msdos.c b/trunk/fs/fat/namei_msdos.c index bbc94ae4fd77..82f88733b681 100644 --- a/trunk/fs/fat/namei_msdos.c +++ b/trunk/fs/fat/namei_msdos.c @@ -9,6 +9,7 @@ #include #include #include +#include #include "fat.h" /* Characters that are undesirable in an MS-DOS file name */ diff --git a/trunk/fs/fat/namei_vfat.c b/trunk/fs/fat/namei_vfat.c index cb6e83557112..73471b7ecc8c 100644 --- a/trunk/fs/fat/namei_vfat.c +++ b/trunk/fs/fat/namei_vfat.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include "fat.h" diff --git a/trunk/fs/fcntl.c b/trunk/fs/fcntl.c index ae413086db97..a040b764f8e3 100644 --- a/trunk/fs/fcntl.c +++ b/trunk/fs/fcntl.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include diff --git a/trunk/fs/freevxfs/vxfs_super.c b/trunk/fs/freevxfs/vxfs_super.c index 1e8af939b3e4..cdbd1654e4cd 100644 --- a/trunk/fs/freevxfs/vxfs_super.c +++ b/trunk/fs/freevxfs/vxfs_super.c @@ -38,7 +38,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/fs/fuse/dev.c b/trunk/fs/fuse/dev.c index 6484eb75acd6..cbceacbc0bf9 100644 --- a/trunk/fs/fuse/dev.c +++ b/trunk/fs/fuse/dev.c @@ -16,6 +16,7 @@ #include #include #include +#include MODULE_ALIAS_MISCDEV(FUSE_MINOR); diff --git a/trunk/fs/gfs2/trace_gfs2.h b/trunk/fs/gfs2/trace_gfs2.h index 148d55c14171..98d6ef1c1dc0 100644 --- a/trunk/fs/gfs2/trace_gfs2.h +++ b/trunk/fs/gfs2/trace_gfs2.h @@ -1,11 +1,12 @@ -#undef TRACE_SYSTEM -#define TRACE_SYSTEM gfs2 - #if !defined(_TRACE_GFS2_H) || defined(TRACE_HEADER_MULTI_READ) #define _TRACE_GFS2_H #include +#undef TRACE_SYSTEM +#define TRACE_SYSTEM gfs2 +#define TRACE_INCLUDE_FILE trace_gfs2 + #include #include #include @@ -402,6 +403,5 @@ 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 diff --git a/trunk/fs/hfs/super.c b/trunk/fs/hfs/super.c index f7fcbe49da72..6f833dc8e910 100644 --- a/trunk/fs/hfs/super.c +++ b/trunk/fs/hfs/super.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include "hfs_fs.h" diff --git a/trunk/fs/hfsplus/super.c b/trunk/fs/hfsplus/super.c index c0759fe0855b..9fc3af0c0dab 100644 --- a/trunk/fs/hfsplus/super.c +++ b/trunk/fs/hfsplus/super.c @@ -12,7 +12,6 @@ #include #include #include -#include #include #include diff --git a/trunk/fs/hpfs/dir.c b/trunk/fs/hpfs/dir.c index 8865c94f55f6..6916c41d7017 100644 --- a/trunk/fs/hpfs/dir.c +++ b/trunk/fs/hpfs/dir.c @@ -6,7 +6,6 @@ * directory VFS functions */ -#include #include "hpfs_fn.h" static int hpfs_dir_release(struct inode *inode, struct file *filp) diff --git a/trunk/fs/hpfs/file.c b/trunk/fs/hpfs/file.c index 3efabff00367..64ab52259204 100644 --- a/trunk/fs/hpfs/file.c +++ b/trunk/fs/hpfs/file.c @@ -6,7 +6,6 @@ * file VFS functions */ -#include #include "hpfs_fn.h" #define BLOCKS(size) (((size) + 511) >> 9) diff --git a/trunk/fs/hpfs/hpfs_fn.h b/trunk/fs/hpfs/hpfs_fn.h index 701ca54c0867..c2ea31bae313 100644 --- a/trunk/fs/hpfs/hpfs_fn.h +++ b/trunk/fs/hpfs/hpfs_fn.h @@ -13,6 +13,7 @@ #include #include #include +#include #include "hpfs.h" diff --git a/trunk/fs/hpfs/inode.c b/trunk/fs/hpfs/inode.c index fe703ae46bc7..39a1bfbea312 100644 --- a/trunk/fs/hpfs/inode.c +++ b/trunk/fs/hpfs/inode.c @@ -6,7 +6,6 @@ * inode VFS functions */ -#include #include "hpfs_fn.h" void hpfs_init_inode(struct inode *i) diff --git a/trunk/fs/hpfs/namei.c b/trunk/fs/hpfs/namei.c index 82b9c4ba9ed0..b649232dde97 100644 --- a/trunk/fs/hpfs/namei.c +++ b/trunk/fs/hpfs/namei.c @@ -6,7 +6,6 @@ * adding & removing files & directories */ #include -#include #include "hpfs_fn.h" static int hpfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) diff --git a/trunk/fs/jbd2/journal.c b/trunk/fs/jbd2/journal.c index e378cb383979..18bfd5dab642 100644 --- a/trunk/fs/jbd2/journal.c +++ b/trunk/fs/jbd2/journal.c @@ -297,7 +297,6 @@ 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 @@ -311,11 +310,6 @@ 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 @@ -394,6 +388,14 @@ int jbd2_journal_write_metadata_buffer(transaction_t *transaction, 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; @@ -410,11 +412,7 @@ int jbd2_journal_write_metadata_buffer(transaction_t *transaction, * copying is moved to the transaction's shadow queue. */ JBUFFER_TRACE(jh_in, "file as 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); - + jbd2_journal_file_buffer(jh_in, transaction, BJ_Shadow); JBUFFER_TRACE(new_jh, "file as BJ_IO"); jbd2_journal_file_buffer(new_jh, transaction, BJ_IO); @@ -2412,7 +2410,6 @@ 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) { @@ -2422,20 +2419,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] = new_dev; + 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]->device = device; bd = bdget(device); if (bd) { diff --git a/trunk/fs/jbd2/transaction.c b/trunk/fs/jbd2/transaction.c index 6213ac728f30..494501edba6b 100644 --- a/trunk/fs/jbd2/transaction.c +++ b/trunk/fs/jbd2/transaction.c @@ -499,15 +499,34 @@ void jbd2_journal_unlock_updates (journal_t *journal) wake_up(&journal->j_wait_transaction_locked); } -static void warn_dirty_buffer(struct buffer_head *bh) +/* + * 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) { - char b[BDEVNAME_SIZE]; + 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; - 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); + 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); + } } /* @@ -574,16 +593,14 @@ do_get_write_access(handle_t *handle, struct journal_head *jh, 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, "Journalling dirty buffer"); - clear_buffer_dirty(bh); - set_buffer_jbddirty(bh); + JBUFFER_TRACE(jh, "Unexpected dirty buffer"); + jbd_unexpected_dirty_buffer(jh); } unlock_buffer(bh); @@ -826,15 +843,6 @@ 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 */ @@ -1636,13 +1644,8 @@ 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"); @@ -1893,17 +1896,12 @@ 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; diff --git a/trunk/fs/jffs2/super.c b/trunk/fs/jffs2/super.c index 0035c021395a..07a22caf2687 100644 --- a/trunk/fs/jffs2/super.c +++ b/trunk/fs/jffs2/super.c @@ -12,7 +12,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/fs/lockd/clntproc.c b/trunk/fs/lockd/clntproc.c index 4336adba952a..f2fdcbce143e 100644 --- a/trunk/fs/lockd/clntproc.c +++ b/trunk/fs/lockd/clntproc.c @@ -7,7 +7,6 @@ */ #include -#include #include #include #include diff --git a/trunk/fs/lockd/svc4proc.c b/trunk/fs/lockd/svc4proc.c index bd173a6ca3b1..1725037374c5 100644 --- a/trunk/fs/lockd/svc4proc.c +++ b/trunk/fs/lockd/svc4proc.c @@ -10,7 +10,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/fs/lockd/svcproc.c b/trunk/fs/lockd/svcproc.c index e1d28ddd2169..3688e55901fc 100644 --- a/trunk/fs/lockd/svcproc.c +++ b/trunk/fs/lockd/svcproc.c @@ -10,7 +10,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/fs/nfs/delegation.c b/trunk/fs/nfs/delegation.c index 6dd48a4405b4..af05b918cb5b 100644 --- a/trunk/fs/nfs/delegation.c +++ b/trunk/fs/nfs/delegation.c @@ -10,7 +10,6 @@ #include #include #include -#include #include #include diff --git a/trunk/fs/nfs/dir.c b/trunk/fs/nfs/dir.c index 38d42c29fb92..89f98e9a024b 100644 --- a/trunk/fs/nfs/dir.c +++ b/trunk/fs/nfs/dir.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/fs/nfs/file.c b/trunk/fs/nfs/file.c index 05062329b678..0055b813ec2c 100644 --- a/trunk/fs/nfs/file.c +++ b/trunk/fs/nfs/file.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include diff --git a/trunk/fs/nfs/inode.c b/trunk/fs/nfs/inode.c index bd7938eda6a8..64f87194d390 100644 --- a/trunk/fs/nfs/inode.c +++ b/trunk/fs/nfs/inode.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/fs/nfs/nfs4proc.c b/trunk/fs/nfs/nfs4proc.c index ff0c080db59b..92ce43517814 100644 --- a/trunk/fs/nfs/nfs4proc.c +++ b/trunk/fs/nfs/nfs4proc.c @@ -45,6 +45,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/fs/nfs/read.c b/trunk/fs/nfs/read.c index 73ea5e8d66ce..96c4ebfa46f4 100644 --- a/trunk/fs/nfs/read.c +++ b/trunk/fs/nfs/read.c @@ -18,6 +18,7 @@ #include #include #include +#include #include diff --git a/trunk/fs/nfs/write.c b/trunk/fs/nfs/write.c index 0a0a2ff767c3..35d81316163f 100644 --- a/trunk/fs/nfs/write.c +++ b/trunk/fs/nfs/write.c @@ -19,6 +19,7 @@ #include #include #include +#include #include diff --git a/trunk/fs/nfsd/nfsctl.c b/trunk/fs/nfsd/nfsctl.c index 6d0847562d87..1250fb978ac1 100644 --- a/trunk/fs/nfsd/nfsctl.c +++ b/trunk/fs/nfsd/nfsctl.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include diff --git a/trunk/fs/nfsd/nfssvc.c b/trunk/fs/nfsd/nfssvc.c index 492c79b7800b..d4c9884cd54b 100644 --- a/trunk/fs/nfsd/nfssvc.c +++ b/trunk/fs/nfsd/nfssvc.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/fs/nilfs2/dir.c b/trunk/fs/nilfs2/dir.c index 1a4fa04cf071..54100acc1102 100644 --- a/trunk/fs/nilfs2/dir.c +++ b/trunk/fs/nilfs2/dir.c @@ -43,6 +43,7 @@ */ #include +#include #include "nilfs.h" #include "page.h" diff --git a/trunk/fs/ocfs2/ioctl.c b/trunk/fs/ocfs2/ioctl.c index 467b413bec21..9fcd36dcc9a0 100644 --- a/trunk/fs/ocfs2/ioctl.c +++ b/trunk/fs/ocfs2/ioctl.c @@ -7,6 +7,7 @@ #include #include +#include #define MLOG_MASK_PREFIX ML_INODE #include diff --git a/trunk/fs/partitions/check.c b/trunk/fs/partitions/check.c index ea4e6cb29e13..1a9c7878f864 100644 --- a/trunk/fs/partitions/check.c +++ b/trunk/fs/partitions/check.c @@ -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(ddev)) + if (!dev_get_uevent_suppress(pdev)) kobject_uevent(&pdev->kobj, KOBJ_ADD); return p; diff --git a/trunk/fs/reiserfs/xattr.c b/trunk/fs/reiserfs/xattr.c index 6925b835a43b..f3d47d856848 100644 --- a/trunk/fs/reiserfs/xattr.c +++ b/trunk/fs/reiserfs/xattr.c @@ -46,6 +46,7 @@ #include #include #include +#include #include #include diff --git a/trunk/fs/squashfs/super.c b/trunk/fs/squashfs/super.c index cb5fc57e370b..3b52770f46ff 100644 --- a/trunk/fs/squashfs/super.c +++ b/trunk/fs/squashfs/super.c @@ -30,7 +30,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/fs/ubifs/ioctl.c b/trunk/fs/ubifs/ioctl.c index 8aacd64957a2..6db7a6be6c97 100644 --- a/trunk/fs/ubifs/ioctl.c +++ b/trunk/fs/ubifs/ioctl.c @@ -25,6 +25,7 @@ /* This file implements EXT2-compatible extended attribute ioctl() calls */ #include +#include #include #include "ubifs.h" diff --git a/trunk/fs/xfs/linux-2.6/xfs_file.c b/trunk/fs/xfs/linux-2.6/xfs_file.c index 0542fd507649..f4e255441574 100644 --- a/trunk/fs/xfs/linux-2.6/xfs_file.c +++ b/trunk/fs/xfs/linux-2.6/xfs_file.c @@ -41,6 +41,7 @@ #include "xfs_ioctl.h" #include +#include static struct vm_operations_struct xfs_file_vm_ops; diff --git a/trunk/include/linux/backing-dev.h b/trunk/include/linux/backing-dev.h index 1d52425a6118..3a52a63c1351 100644 --- a/trunk/include/linux/backing-dev.h +++ b/trunk/include/linux/backing-dev.h @@ -229,11 +229,6 @@ 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); diff --git a/trunk/include/linux/blkdev.h b/trunk/include/linux/blkdev.h index e7cb5dbf6c26..0146e0fecf1a 100644 --- a/trunk/include/linux/blkdev.h +++ b/trunk/include/linux/blkdev.h @@ -70,6 +70,11 @@ 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 diff --git a/trunk/include/linux/crash_dump.h b/trunk/include/linux/crash_dump.h index 0026f267da20..2dac064d8359 100644 --- a/trunk/include/linux/crash_dump.h +++ b/trunk/include/linux/crash_dump.h @@ -3,6 +3,7 @@ #ifdef CONFIG_CRASH_DUMP #include +#include #include #include diff --git a/trunk/include/linux/device.h b/trunk/include/linux/device.h index aebb81036db2..ed4e39f2c423 100644 --- a/trunk/include/linux/device.h +++ b/trunk/include/linux/device.h @@ -25,6 +25,8 @@ #include #include +#define BUS_ID_SIZE 20 + struct device; struct device_private; struct device_driver; diff --git a/trunk/include/linux/hardirq.h b/trunk/include/linux/hardirq.h index 8246c697863d..45257475623c 100644 --- a/trunk/include/linux/hardirq.h +++ b/trunk/include/linux/hardirq.h @@ -2,9 +2,7 @@ #define LINUX_HARDIRQ_H #include -#ifdef CONFIG_PREEMPT #include -#endif #include #include #include diff --git a/trunk/include/linux/kmemleak.h b/trunk/include/linux/kmemleak.h index 6a63807f714e..7796aed6cdd5 100644 --- a/trunk/include/linux/kmemleak.h +++ b/trunk/include/linux/kmemleak.h @@ -27,7 +27,6 @@ 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); @@ -72,9 +71,6 @@ 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) { } diff --git a/trunk/include/linux/personality.h b/trunk/include/linux/personality.h index 126120819a0d..a84e9ff9b27e 100644 --- a/trunk/include/linux/personality.h +++ b/trunk/include/linux/personality.h @@ -40,10 +40,7 @@ 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 | \ - ADDR_COMPAT_LAYOUT | \ - MMAP_PAGE_ZERO) +#define PER_CLEAR_ON_SETID (READ_IMPLIES_EXEC|ADDR_NO_RANDOMIZE) /* * Personality types. diff --git a/trunk/include/linux/quotaops.h b/trunk/include/linux/quotaops.h index 26361c4c037a..7bc457593684 100644 --- a/trunk/include/linux/quotaops.h +++ b/trunk/include/linux/quotaops.h @@ -7,6 +7,7 @@ #ifndef _LINUX_QUOTAOPS_ #define _LINUX_QUOTAOPS_ +#include #include static inline struct quota_info *sb_dqopt(struct super_block *sb) diff --git a/trunk/include/linux/skbuff.h b/trunk/include/linux/skbuff.h index f2c69a2cca17..b47b3f039d14 100644 --- a/trunk/include/linux/skbuff.h +++ b/trunk/include/linux/skbuff.h @@ -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(skb, NET_IP_ALIGN); + * skb_reserve(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. */ diff --git a/trunk/include/linux/slub_def.h b/trunk/include/linux/slub_def.h index c1c862b1d01a..4dcbc2c71491 100644 --- a/trunk/include/linux/slub_def.h +++ b/trunk/include/linux/slub_def.h @@ -11,7 +11,6 @@ #include #include #include -#include enum stat_item { ALLOC_FASTPATH, /* Allocation from cpu slab */ @@ -234,7 +233,6 @@ 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; diff --git a/trunk/include/linux/sunrpc/xdr.h b/trunk/include/linux/sunrpc/xdr.h index b99c625fddfe..d8910b68e1bd 100644 --- a/trunk/include/linux/sunrpc/xdr.h +++ b/trunk/include/linux/sunrpc/xdr.h @@ -12,6 +12,7 @@ #include #include #include +#include /* * Buffer adjustment diff --git a/trunk/include/linux/usb.h b/trunk/include/linux/usb.h index b1e3c2fbfe11..84929e914034 100644 --- a/trunk/include/linux/usb.h +++ b/trunk/include/linux/usb.h @@ -888,6 +888,8 @@ 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 @@ -922,8 +924,6 @@ 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,8 +1046,6 @@ 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/trunk/include/linux/usb/langwell_otg.h b/trunk/include/linux/usb/langwell_otg.h new file mode 100644 index 000000000000..e115ae6df1da --- /dev/null +++ b/trunk/include/linux/usb/langwell_otg.h @@ -0,0 +1,177 @@ +/* + * 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__ */ diff --git a/trunk/include/trace/events/block.h b/trunk/include/trace/events/block.h index 9a74b468a229..d6b05f42dd44 100644 --- a/trunk/include/trace/events/block.h +++ b/trunk/include/trace/events/block.h @@ -1,6 +1,3 @@ -#undef TRACE_SYSTEM -#define TRACE_SYSTEM block - #if !defined(_TRACE_BLOCK_H) || defined(TRACE_HEADER_MULTI_READ) #define _TRACE_BLOCK_H @@ -8,6 +5,9 @@ #include #include +#undef TRACE_SYSTEM +#define TRACE_SYSTEM block + TRACE_EVENT(block_rq_abort, TP_PROTO(struct request_queue *q, struct request *rq), diff --git a/trunk/include/trace/events/ext4.h b/trunk/include/trace/events/ext4.h index 7d8b5bc74185..acf4cc9cd36d 100644 --- a/trunk/include/trace/events/ext4.h +++ b/trunk/include/trace/events/ext4.h @@ -1,9 +1,9 @@ -#undef TRACE_SYSTEM -#define TRACE_SYSTEM ext4 - #if !defined(_TRACE_EXT4_H) || defined(TRACE_HEADER_MULTI_READ) #define _TRACE_EXT4_H +#undef TRACE_SYSTEM +#define TRACE_SYSTEM ext4 + #include #include "../../../fs/ext4/ext4.h" #include "../../../fs/ext4/mballoc.h" @@ -34,8 +34,7 @@ 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, - (unsigned long long) __entry->blocks) + __entry->uid, __entry->gid, __entry->blocks) ); TRACE_EVENT(ext4_request_inode, @@ -190,7 +189,7 @@ TRACE_EVENT(ext4_journalled_write_end, __entry->copied) ); -TRACE_EVENT(ext4_writepage, +TRACE_EVENT(ext4_da_writepage, TP_PROTO(struct inode *inode, struct page *page), TP_ARGS(inode, page), @@ -342,6 +341,49 @@ 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), diff --git a/trunk/include/trace/events/irq.h b/trunk/include/trace/events/irq.h index 1cb0c3aa11e6..b0c7ede55eb1 100644 --- a/trunk/include/trace/events/irq.h +++ b/trunk/include/trace/events/irq.h @@ -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 #include +#undef TRACE_SYSTEM +#define TRACE_SYSTEM irq + #define softirq_name(sirq) { sirq##_SOFTIRQ, #sirq } #define show_softirq_name(val) \ __print_symbolic(val, \ diff --git a/trunk/include/trace/events/jbd2.h b/trunk/include/trace/events/jbd2.h index 10813fa0c8d0..845b0b4b48fd 100644 --- a/trunk/include/trace/events/jbd2.h +++ b/trunk/include/trace/events/jbd2.h @@ -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 #include +#undef TRACE_SYSTEM +#define TRACE_SYSTEM jbd2 + TRACE_EVENT(jbd2_checkpoint, TP_PROTO(journal_t *journal, int result), diff --git a/trunk/include/trace/events/kmem.h b/trunk/include/trace/events/kmem.h index 1493c541f9c4..9baba50d6512 100644 --- a/trunk/include/trace/events/kmem.h +++ b/trunk/include/trace/events/kmem.h @@ -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 #include +#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. diff --git a/trunk/include/trace/events/lockdep.h b/trunk/include/trace/events/lockdep.h index bcf1d209a00d..0e956c9dfd7e 100644 --- a/trunk/include/trace/events/lockdep.h +++ b/trunk/include/trace/events/lockdep.h @@ -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 #include +#undef TRACE_SYSTEM +#define TRACE_SYSTEM lockdep + #ifdef CONFIG_LOCKDEP TRACE_EVENT(lock_acquire, diff --git a/trunk/include/trace/events/sched.h b/trunk/include/trace/events/sched.h index 8949bb7eb082..24ab5bcff7b2 100644 --- a/trunk/include/trace/events/sched.h +++ b/trunk/include/trace/events/sched.h @@ -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 #include +#undef TRACE_SYSTEM +#define TRACE_SYSTEM sched + /* * Tracepoint for calling kthread_stop, performed to end a kthread: */ diff --git a/trunk/include/trace/events/skb.h b/trunk/include/trace/events/skb.h index e499863b9669..1e8fabb57c06 100644 --- a/trunk/include/trace/events/skb.h +++ b/trunk/include/trace/events/skb.h @@ -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 #include +#undef TRACE_SYSTEM +#define TRACE_SYSTEM skb + /* * Tracepoint for free an sk_buff: */ diff --git a/trunk/include/trace/events/workqueue.h b/trunk/include/trace/events/workqueue.h index fcfd9a1e4b96..035f1bff288e 100644 --- a/trunk/include/trace/events/workqueue.h +++ b/trunk/include/trace/events/workqueue.h @@ -1,6 +1,3 @@ -#undef TRACE_SYSTEM -#define TRACE_SYSTEM workqueue - #if !defined(_TRACE_WORKQUEUE_H) || defined(TRACE_HEADER_MULTI_READ) #define _TRACE_WORKQUEUE_H @@ -8,6 +5,9 @@ #include #include +#undef TRACE_SYSTEM +#define TRACE_SYSTEM workqueue + TRACE_EVENT(workqueue_insertion, TP_PROTO(struct task_struct *wq_thread, struct work_struct *work), diff --git a/trunk/kernel/futex.c b/trunk/kernel/futex.c index 0672ff88f159..794c862125fe 100644 --- a/trunk/kernel/futex.c +++ b/trunk/kernel/futex.c @@ -247,7 +247,6 @@ get_futex_key(u32 __user *uaddr, int fshared, union futex_key *key, int rw) if (err < 0) return err; - page = compound_head(page); lock_page(page); if (!page->mapping) { unlock_page(page); diff --git a/trunk/kernel/pid.c b/trunk/kernel/pid.c index 31310b5d3f50..5fa1db48d8b7 100644 --- a/trunk/kernel/pid.c +++ b/trunk/kernel/pid.c @@ -36,6 +36,7 @@ #include #include #include +#include #define pid_hashfn(nr, ns) \ hash_long((unsigned long)nr + (unsigned long)ns, pidhash_shift) @@ -512,6 +513,12 @@ 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]); } diff --git a/trunk/kernel/power/user.c b/trunk/kernel/power/user.c index bf0014d6a5f0..ed97375daae9 100644 --- a/trunk/kernel/power/user.c +++ b/trunk/kernel/power/user.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include diff --git a/trunk/kernel/trace/blktrace.c b/trunk/kernel/trace/blktrace.c index 1090b0aed9ba..39af8af6fc30 100644 --- a/trunk/kernel/trace/blktrace.c +++ b/trunk/kernel/trace/blktrace.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include diff --git a/trunk/kernel/trace/ftrace.c b/trunk/kernel/trace/ftrace.c index 4521c77d1a1a..bce9e01a29c8 100644 --- a/trunk/kernel/trace/ftrace.c +++ b/trunk/kernel/trace/ftrace.c @@ -768,7 +768,7 @@ static struct tracer_stat function_stats __initdata = { .stat_show = function_stat_show }; -static __init void ftrace_profile_debugfs(struct dentry *d_tracer) +static void ftrace_profile_debugfs(struct dentry *d_tracer) { struct ftrace_profile_stat *stat; struct dentry *entry; @@ -786,6 +786,7 @@ static __init 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); @@ -812,7 +813,7 @@ static __init void ftrace_profile_debugfs(struct dentry *d_tracer) } #else /* CONFIG_FUNCTION_PROFILER */ -static __init void ftrace_profile_debugfs(struct dentry *d_tracer) +static void ftrace_profile_debugfs(struct dentry *d_tracer) { } #endif /* CONFIG_FUNCTION_PROFILER */ diff --git a/trunk/kernel/trace/trace.c b/trunk/kernel/trace/trace.c index 8bc8d8afea6a..3aa0a0dfdfa8 100644 --- a/trunk/kernel/trace/trace.c +++ b/trunk/kernel/trace/trace.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/mm/bootmem.c b/trunk/mm/bootmem.c index 701740c9e81b..d2a9ce952768 100644 --- a/trunk/mm/bootmem.c +++ b/trunk/mm/bootmem.c @@ -12,7 +12,6 @@ #include #include #include -#include #include #include @@ -336,8 +335,6 @@ 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); @@ -357,8 +354,6 @@ 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); @@ -521,7 +516,6 @@ static void * __init alloc_bootmem_core(struct bootmem_data *bdata, region = phys_to_virt(PFN_PHYS(bdata->node_min_pfn) + start_off); memset(region, 0, size); - kmemleak_alloc(region, size, 1, 0); return region; } diff --git a/trunk/mm/kmemleak.c b/trunk/mm/kmemleak.c index 5aabd41ffb8f..e766e1da09d2 100644 --- a/trunk/mm/kmemleak.c +++ b/trunk/mm/kmemleak.c @@ -103,10 +103,10 @@ * 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,8 +158,6 @@ 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); @@ -198,6 +196,9 @@ 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 @@ -210,7 +211,6 @@ static DEFINE_MUTEX(scan_mutex); enum { KMEMLEAK_ALLOC, KMEMLEAK_FREE, - KMEMLEAK_FREE_PART, KMEMLEAK_NOT_LEAK, KMEMLEAK_IGNORE, KMEMLEAK_SCAN_AREA, @@ -274,11 +274,6 @@ 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 @@ -456,7 +451,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_NEW; + object->flags = OBJECT_ALLOCATED; object->pointer = ptr; object->size = size; object->min_count = min_count; @@ -524,17 +519,27 @@ static void create_object(unsigned long ptr, size_t size, int min_count, * 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(struct kmemleak_object *object) +static void delete_object(unsigned long ptr) { 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) < 2); + WARN_ON(atomic_read(&object->use_count) < 1); /* * Locking here also ensures that the corresponding memory block @@ -546,64 +551,6 @@ static void __delete_object(struct kmemleak_object *object) 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. @@ -768,27 +715,12 @@ 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_full((unsigned long)ptr); + delete_object((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. @@ -875,7 +807,7 @@ static int scan_should_stop(void) * found to the gray list. */ static void scan_block(void *_start, void *_end, - struct kmemleak_object *scanned, int allow_resched) + struct kmemleak_object *scanned) { unsigned long *ptr; unsigned long *start = PTR_ALIGN(_start, BYTES_PER_POINTER); @@ -886,8 +818,6 @@ 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; @@ -951,12 +881,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, 0); + (void *)(object->pointer + object->size), object); 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, 0); + + area->length), object); out: spin_unlock_irqrestore(&object->lock, flags); } @@ -973,7 +903,6 @@ static void kmemleak_scan(void) struct task_struct *task; int i; int new_leaks = 0; - int gray_list_pass = 0; jiffies_last_scan = jiffies; @@ -994,7 +923,6 @@ 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); @@ -1003,14 +931,14 @@ static void kmemleak_scan(void) rcu_read_unlock(); /* data/bss scanning */ - scan_block(_sdata, _edata, NULL, 1); - scan_block(__bss_start, __bss_stop, NULL, 1); + scan_block(_sdata, _edata, NULL); + scan_block(__bss_start, __bss_stop, NULL); #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, 1); + __per_cpu_end + per_cpu_offset(i), NULL); #endif /* @@ -1032,7 +960,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, 1); + scan_block(page, page + 1, NULL); } } @@ -1044,8 +972,7 @@ 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, 0); + task_stack_page(task) + THREAD_SIZE, NULL); read_unlock(&tasklist_lock); } @@ -1057,7 +984,6 @@ 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(); @@ -1075,38 +1001,12 @@ 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 or new objects were being allocated at a - * higher rate than gray list scanning, do not report any new - * unreferenced objects. + * If scanning was stopped do not report any new unreferenced objects. */ - if (scan_should_stop() || gray_list_pass >= GRAY_LIST_PASSES) + if (scan_should_stop()) return; /* @@ -1139,7 +1039,6 @@ 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. @@ -1202,11 +1101,11 @@ static void *kmemleak_seq_start(struct seq_file *seq, loff_t *pos) { struct kmemleak_object *object; loff_t n = *pos; - int err; - err = mutex_lock_interruptible(&scan_mutex); - if (err < 0) - return ERR_PTR(err); + if (!n) + reported_leaks = 0; + if (reported_leaks >= REPORTS_NR) + return NULL; rcu_read_lock(); list_for_each_entry_rcu(object, &object_list, object_list) { @@ -1232,6 +1131,8 @@ 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) { @@ -1240,7 +1141,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; } @@ -1250,15 +1151,8 @@ static void *kmemleak_seq_next(struct seq_file *seq, void *v, loff_t *pos) */ static void kmemleak_seq_stop(struct seq_file *seq, void *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); - } + if (v) + put_object(v); } /* @@ -1270,8 +1164,10 @@ 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; } @@ -1285,15 +1181,36 @@ 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; - return seq_open(file, &kmemleak_seq_ops); + 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; } static int kmemleak_release(struct inode *inode, struct file *file) { - return seq_release(inode, file); + int ret = 0; + + if (file->f_mode & FMODE_READ) + seq_release(inode, file); + mutex_unlock(&scan_mutex); + + return ret; } /* @@ -1313,17 +1230,15 @@ static ssize_t kmemleak_write(struct file *file, const char __user *user_buf, { char buf[64]; int buf_size; - int ret; + + if (!atomic_read(&kmemleak_enabled)) + return -EBUSY; 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) @@ -1336,10 +1251,11 @@ 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; - ret = strict_strtoul(buf + 5, 0, &secs); - if (ret < 0) - goto out; + err = strict_strtoul(buf + 5, 0, &secs); + if (err < 0) + return err; stop_scan_thread(); if (secs) { jiffies_scan_wait = msecs_to_jiffies(secs * 1000); @@ -1348,12 +1264,7 @@ static ssize_t kmemleak_write(struct file *file, const char __user *user_buf, } else if (strncmp(buf, "scan", 4) == 0) kmemleak_scan(); else - ret = -EINVAL; - -out: - mutex_unlock(&scan_mutex); - if (ret < 0) - return ret; + return -EINVAL; /* ignore the rest of the buffer, only one command at a time */ *ppos += size; @@ -1382,7 +1293,7 @@ static int kmemleak_cleanup_thread(void *arg) rcu_read_lock(); list_for_each_entry_rcu(object, &object_list, object_list) - delete_object_full(object->pointer); + delete_object(object->pointer); rcu_read_unlock(); mutex_unlock(&scan_mutex); @@ -1477,9 +1388,6 @@ 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; diff --git a/trunk/mm/page_alloc.c b/trunk/mm/page_alloc.c index caa92689aac9..a35eeab2724c 100644 --- a/trunk/mm/page_alloc.c +++ b/trunk/mm/page_alloc.c @@ -4745,10 +4745,8 @@ 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); @@ -4766,6 +4764,16 @@ 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; } diff --git a/trunk/mm/slub.c b/trunk/mm/slub.c index b9f1491a58a1..a9201d83178b 100644 --- a/trunk/mm/slub.c +++ b/trunk/mm/slub.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -2834,15 +2835,13 @@ 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) - ptr = page_address(page); - - kmemleak_alloc(ptr, size, 1, flags); - return ptr; + return page_address(page); + else + return NULL; } #ifdef CONFIG_NUMA @@ -2927,7 +2926,6 @@ 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; } diff --git a/trunk/net/appletalk/ddp.c b/trunk/net/appletalk/ddp.c index bfbe13786bb4..590b83963622 100644 --- a/trunk/net/appletalk/ddp.c +++ b/trunk/net/appletalk/ddp.c @@ -54,7 +54,6 @@ #include #include #include -#include #include /* For TIOCOUTQ/INQ */ #include #include diff --git a/trunk/net/core/sock.c b/trunk/net/core/sock.c index ba5d2116aea1..6354863b1c68 100644 --- a/trunk/net/core/sock.c +++ b/trunk/net/core/sock.c @@ -939,23 +939,8 @@ 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 & ~__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)); - } - } + if (slab != NULL) + sk = kmem_cache_alloc(slab, priority); else sk = kmalloc(prot->obj_size, priority); diff --git a/trunk/net/ipv4/ip_gre.c b/trunk/net/ipv4/ip_gre.c index cb4a0f4bd5e5..44e2a3d2359a 100644 --- a/trunk/net/ipv4/ip_gre.c +++ b/trunk/net/ipv4/ip_gre.c @@ -735,10 +735,10 @@ static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) } tos = tiph->tos; - if (tos == 1) { - tos = 0; + if (tos&1) { if (skb->protocol == htons(ETH_P_IP)) tos = old_iph->tos; + tos &= ~1; } { diff --git a/trunk/net/ipv4/ip_output.c b/trunk/net/ipv4/ip_output.c index 7d0821054729..247026282669 100644 --- a/trunk/net/ipv4/ip_output.c +++ b/trunk/net/ipv4/ip_output.c @@ -1243,6 +1243,7 @@ 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; } diff --git a/trunk/net/ipv6/ip6_output.c b/trunk/net/ipv6/ip6_output.c index 87f8419a68fd..7c76e3d18215 100644 --- a/trunk/net/ipv6/ip6_output.c +++ b/trunk/net/ipv6/ip6_output.c @@ -1484,6 +1484,7 @@ 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; } diff --git a/trunk/net/ipv6/sit.c b/trunk/net/ipv6/sit.c index 98b7327d0949..68e52308e552 100644 --- a/trunk/net/ipv6/sit.c +++ b/trunk/net/ipv6/sit.c @@ -1018,7 +1018,6 @@ 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; diff --git a/trunk/net/ipx/af_ipx.c b/trunk/net/ipx/af_ipx.c index f1118d92a191..417b0e309495 100644 --- a/trunk/net/ipx/af_ipx.c +++ b/trunk/net/ipx/af_ipx.c @@ -41,7 +41,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/net/irda/af_irda.c b/trunk/net/irda/af_irda.c index 80cf29aae096..cb762c8723ea 100644 --- a/trunk/net/irda/af_irda.c +++ b/trunk/net/irda/af_irda.c @@ -45,7 +45,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/net/irda/irnet/irnet.h b/trunk/net/irda/irnet/irnet.h index b001c361ad30..bccf4d0059f0 100644 --- a/trunk/net/irda/irnet/irnet.h +++ b/trunk/net/irda/irnet/irnet.h @@ -241,6 +241,7 @@ #include #include +#include #include #include #include diff --git a/trunk/net/irda/irnet/irnet_ppp.c b/trunk/net/irda/irnet/irnet_ppp.c index 68cbcb19cbd8..6d8ae03c14f5 100644 --- a/trunk/net/irda/irnet/irnet_ppp.c +++ b/trunk/net/irda/irnet/irnet_ppp.c @@ -13,7 +13,6 @@ * 2) as a control channel (write commands, read events) */ -#include #include "irnet_ppp.h" /* Private header */ /* Please put other headers in irnet.h - Thanks */ diff --git a/trunk/net/sunrpc/clnt.c b/trunk/net/sunrpc/clnt.c index ebfcf9b89909..5bc2f45bddf0 100644 --- a/trunk/net/sunrpc/clnt.c +++ b/trunk/net/sunrpc/clnt.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/net/sunrpc/sched.c b/trunk/net/sunrpc/sched.c index 8f459abe97cf..1102ce1251f7 100644 --- a/trunk/net/sunrpc/sched.c +++ b/trunk/net/sunrpc/sched.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include diff --git a/trunk/net/sunrpc/svc_xprt.c b/trunk/net/sunrpc/svc_xprt.c index 27d44332f017..6f33d33cc064 100644 --- a/trunk/net/sunrpc/svc_xprt.c +++ b/trunk/net/sunrpc/svc_xprt.c @@ -5,7 +5,6 @@ */ #include -#include #include #include #include diff --git a/trunk/net/wanrouter/wanmain.c b/trunk/net/wanrouter/wanmain.c index 258daa80ad92..466e2d22d256 100644 --- a/trunk/net/wanrouter/wanmain.c +++ b/trunk/net/wanrouter/wanmain.c @@ -48,7 +48,6 @@ #include #include /* support for loadable modules */ #include /* kmalloc(), kfree() */ -#include #include #include /* inline mem*, str* functions */ diff --git a/trunk/net/x25/af_x25.c b/trunk/net/x25/af_x25.c index 5e6c072c64d3..21cdc872004e 100644 --- a/trunk/net/x25/af_x25.c +++ b/trunk/net/x25/af_x25.c @@ -40,7 +40,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/samples/trace_events/trace-events-sample.h b/trunk/samples/trace_events/trace-events-sample.h index f24ae370e514..9977a756fb32 100644 --- a/trunk/samples/trace_events/trace-events-sample.h +++ b/trunk/samples/trace_events/trace-events-sample.h @@ -1,3 +1,20 @@ +/* + * 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 + /* * If TRACE_SYSTEM is defined, that will be the directory created * in the ftrace directory under /debugfs/tracing/events/ @@ -17,30 +34,10 @@ * #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 - /* * The TRACE_EVENT macro is broken up into 5 parts. * diff --git a/trunk/sound/soc/codecs/wm8988.c b/trunk/sound/soc/codecs/wm8988.c index 8c0fdf84aac3..c05f71803aa8 100644 --- a/trunk/sound/soc/codecs/wm8988.c +++ b/trunk/sound/soc/codecs/wm8988.c @@ -1037,14 +1037,14 @@ static int __devinit wm8988_spi_probe(struct spi_device *spi) codec->control_data = spi; codec->dev = &spi->dev; - dev_set_drvdata(&spi->dev, wm8988); + spi->dev.driver_data = wm8988; return wm8988_register(wm8988); } static int __devexit wm8988_spi_remove(struct spi_device *spi) { - struct wm8988_priv *wm8988 = dev_get_drvdata(&spi->dev); + struct wm8988_priv *wm8988 = spi->dev.driver_data; wm8988_unregister(wm8988);