From ebe56266b27d6052d7721f72620b438f67e90934 Mon Sep 17 00:00:00 2001 From: Stefan Haberland Date: Mon, 31 Jan 2011 11:30:03 +0100 Subject: [PATCH] --- yaml --- r: 232739 b: refs/heads/master c: f602f6d694a99a0141c066c8f0b360a0b3c16915 h: refs/heads/master i: 232737: 544511da7da99c912dee0ef10a712f00c88ab928 232735: 19df1499244b2ebd773cfb198c501ea766db4e22 v: v3 --- [refs] | 2 +- .../feature-removal-schedule.txt | 16 -- trunk/MAINTAINERS | 30 +- trunk/Makefile | 2 +- trunk/arch/arm/include/asm/io.h | 33 ++- trunk/arch/arm/kernel/head.S | 22 +- .../include/mach/debug-macro.S | 4 +- .../arm/mach-omap1/include/mach/entry-macro.S | 13 + trunk/arch/arm/mach-omap1/irq.c | 2 +- trunk/arch/arm/mach-omap2/dma.c | 2 +- .../arm/mach-omap2/include/mach/entry-macro.S | 14 + trunk/arch/arm/mach-omap2/io.c | 6 +- trunk/arch/arm/mach-omap2/mux.c | 2 +- trunk/arch/arm/mm/init.c | 6 - trunk/arch/microblaze/kernel/head.S | 14 +- .../microblaze/kernel/hw_exception_handler.S | 4 + trunk/arch/microblaze/lib/fastcopy.S | 4 - trunk/drivers/gpu/stub/Kconfig | 2 - trunk/drivers/mmc/host/mmci.c | 11 +- trunk/drivers/s390/block/dasd_alias.c | 6 + .../ath6kl/miscdrv/ar3kps/ar3kpsconfig.c | 4 +- .../staging/brcm80211/sys/wl_mac80211.c | 45 ++- .../staging/brcm80211/sys/wlc_mac80211.c | 1 + .../drivers/staging/comedi/drivers/ni_labpc.c | 3 +- trunk/drivers/staging/hv/blkvsc_drv.c | 1 - trunk/drivers/staging/hv/netvsc.c | 2 +- trunk/drivers/staging/hv/netvsc_drv.c | 1 + trunk/drivers/staging/iio/adc/ad7476_core.c | 2 +- trunk/drivers/staging/iio/adc/ad7887_core.c | 2 +- trunk/drivers/staging/iio/adc/ad799x_core.c | 2 +- trunk/drivers/staging/iio/dac/ad5446.c | 2 +- trunk/drivers/staging/rt2860/rt_main_dev.c | 2 + trunk/drivers/staging/rt2860/usb_main_dev.c | 1 - trunk/drivers/staging/rtl8712/hal_init.c | 11 +- trunk/drivers/staging/rtl8712/usb_intf.c | 145 +++------- trunk/drivers/staging/speakup/kobjects.c | 2 +- .../staging/ste_rmi4/synaptics_i2c_rmi4.c | 19 +- .../drivers/staging/tidspbridge/core/io_sm.c | 8 +- .../staging/tidspbridge/core/tiomap3430.c | 15 +- .../tidspbridge/include/dspbridge/io_sm.h | 21 +- trunk/drivers/staging/usbip/stub.h | 1 - trunk/drivers/staging/usbip/stub_dev.c | 18 +- trunk/drivers/staging/usbip/stub_rx.c | 4 +- trunk/drivers/staging/usbip/vhci.h | 6 +- trunk/drivers/staging/usbip/vhci_hcd.c | 54 +--- trunk/drivers/staging/usbip/vhci_rx.c | 50 +--- trunk/drivers/staging/xgifb/vb_setmode.c | 6 +- trunk/drivers/tty/n_hdlc.c | 90 +++--- trunk/drivers/tty/serial/8250.c | 3 +- trunk/drivers/tty/serial/Kconfig | 1 - trunk/drivers/tty/tty_io.c | 4 +- trunk/drivers/tty/vt/vt.c | 11 +- trunk/drivers/usb/class/cdc-wdm.c | 2 +- trunk/drivers/usb/core/endpoint.c | 2 +- trunk/drivers/usb/core/hcd-pci.c | 7 +- trunk/drivers/usb/core/hub.c | 21 -- trunk/drivers/usb/gadget/Kconfig | 7 +- trunk/drivers/usb/gadget/ci13xxx_udc.c | 268 +++++++++--------- trunk/drivers/usb/gadget/ci13xxx_udc.h | 9 +- trunk/drivers/usb/gadget/composite.c | 5 +- trunk/drivers/usb/gadget/pch_udc.c | 127 ++++----- trunk/drivers/usb/gadget/printer.c | 19 +- trunk/drivers/usb/host/ehci-fsl.c | 13 + trunk/drivers/usb/host/ehci-fsl.h | 3 + trunk/drivers/usb/host/ehci-hcd.c | 19 +- trunk/drivers/usb/host/ehci-mxc.c | 25 +- trunk/drivers/usb/host/ehci-pci.c | 33 +-- trunk/drivers/usb/host/fsl-mph-dr-of.c | 11 +- trunk/drivers/usb/host/xhci-ring.c | 91 +++--- trunk/drivers/usb/host/xhci.c | 60 ++-- trunk/drivers/usb/host/xhci.h | 16 +- trunk/drivers/usb/misc/usbled.c | 2 +- trunk/drivers/usb/misc/uss720.c | 1 + trunk/drivers/usb/otg/nop-usb-xceiv.c | 2 - trunk/drivers/usb/otg/ulpi.c | 2 +- trunk/drivers/usb/serial/ch341.c | 10 - trunk/drivers/usb/serial/cp210x.c | 16 +- trunk/drivers/usb/serial/digi_acceleport.c | 10 + trunk/drivers/usb/serial/ftdi_sio.c | 12 +- trunk/drivers/usb/serial/ftdi_sio_ids.h | 22 +- trunk/drivers/usb/serial/generic.c | 20 -- trunk/drivers/usb/serial/io_tables.h | 1 - trunk/drivers/usb/serial/iuu_phoenix.c | 1 - trunk/drivers/usb/serial/keyspan.h | 4 - trunk/drivers/usb/serial/keyspan_pda.c | 17 ++ trunk/drivers/usb/serial/moto_modem.c | 1 - trunk/drivers/usb/serial/option.c | 23 +- trunk/drivers/usb/serial/oti6858.c | 1 - trunk/drivers/usb/serial/pl2303.c | 12 - trunk/drivers/usb/serial/pl2303.h | 1 - trunk/drivers/usb/serial/qcaux.c | 3 - trunk/drivers/usb/serial/siemens_mpi.c | 1 - trunk/drivers/usb/serial/spcp8x5.c | 7 +- trunk/drivers/usb/serial/usb-serial.c | 8 +- trunk/drivers/usb/serial/usb_debug.c | 1 - trunk/drivers/usb/storage/unusual_cypress.h | 5 - trunk/drivers/usb/storage/unusual_devs.h | 18 -- trunk/fs/cifs/Kconfig | 1 - trunk/fs/cifs/cifs_dfs_ref.c | 9 +- trunk/fs/cifs/cifsencrypt.c | 5 +- trunk/fs/cifs/cifsfs.h | 2 +- trunk/fs/cifs/cifssmb.c | 3 + trunk/fs/cifs/file.c | 8 +- trunk/fs/cifs/link.c | 3 +- trunk/fs/cifs/misc.c | 116 ++++---- trunk/fs/cifs/readdir.c | 3 + trunk/fs/cifs/smbencrypt.c | 3 +- trunk/fs/cifs/transport.c | 62 +--- trunk/fs/eventpoll.c | 16 +- trunk/fs/exec.c | 4 +- trunk/fs/fcntl.c | 2 +- trunk/fs/ioctl.c | 7 - trunk/fs/lockd/host.c | 9 +- trunk/fs/nfs/callback.c | 109 +++++-- trunk/fs/nfs/callback.h | 4 +- trunk/fs/nfs/callback_proc.c | 12 +- trunk/fs/nfs/callback_xdr.c | 5 +- trunk/fs/nfs/client.c | 15 +- trunk/fs/nfs/delegation.c | 6 +- trunk/fs/nfs/direct.c | 34 +-- trunk/fs/nfs/inode.c | 26 +- trunk/fs/nfs/internal.h | 3 +- trunk/fs/nfs/nfs3acl.c | 4 +- trunk/fs/nfs/nfs3xdr.c | 5 +- trunk/fs/nfs/nfs4filelayoutdev.c | 9 +- trunk/fs/nfs/nfs4proc.c | 30 +- trunk/fs/nfs/nfs4state.c | 6 + trunk/fs/nfs/nfs4xdr.c | 9 +- trunk/fs/nfs/pnfs.c | 2 +- trunk/fs/nfs/write.c | 2 +- trunk/fs/nfs_common/nfsacl.c | 54 +--- trunk/fs/posix_acl.c | 17 +- trunk/fs/xfs/linux-2.6/xfs_ioctl.c | 20 +- trunk/fs/xfs/quota/xfs_qm.c | 46 +-- trunk/fs/xfs/xfs_alloc.h | 16 -- trunk/fs/xfs/xfs_bmap.c | 61 ++-- trunk/fs/xfs/xfs_buf_item.c | 12 +- trunk/fs/xfs/xfs_extfree_item.c | 3 +- trunk/fs/xfs/xfs_iomap.c | 7 +- trunk/fs/xfs/xfs_log.h | 2 +- trunk/fs/xfs/xfs_log_cil.c | 15 +- trunk/fs/xfs/xfs_trans.c | 41 +-- trunk/include/linux/fs.h | 5 +- trunk/include/linux/kernel.h | 2 +- trunk/include/linux/nfsacl.h | 4 +- trunk/include/linux/posix_acl.h | 1 - trunk/include/linux/res_counter.h | 20 -- trunk/include/linux/sunrpc/bc_xprt.h | 13 + trunk/include/linux/sunrpc/svc_xprt.h | 1 + trunk/include/linux/usb/hcd.h | 1 - trunk/include/linux/usb/serial.h | 3 - trunk/mm/huge_memory.c | 7 +- trunk/mm/memcontrol.c | 67 +---- trunk/mm/memory-failure.c | 94 ++---- trunk/mm/migrate.c | 7 +- trunk/mm/mlock.c | 7 - trunk/net/sunrpc/svcsock.c | 4 +- 157 files changed, 1072 insertions(+), 1663 deletions(-) diff --git a/[refs] b/[refs] index c42004794c85..f0e38f8ac8d5 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: d54cdc8ca7aabc69e145a62155855db42b04ed0b +refs/heads/master: f602f6d694a99a0141c066c8f0b360a0b3c16915 diff --git a/trunk/Documentation/feature-removal-schedule.txt b/trunk/Documentation/feature-removal-schedule.txt index b3f35e5f9c95..b959659c5df4 100644 --- a/trunk/Documentation/feature-removal-schedule.txt +++ b/trunk/Documentation/feature-removal-schedule.txt @@ -603,19 +603,3 @@ Why: The adm9240, w83792d and w83793 hardware monitoring drivers have Who: Jean Delvare ---------------------------- - -What: noswapaccount kernel command line parameter -When: 2.6.40 -Why: The original implementation of memsw feature enabled by - CONFIG_CGROUP_MEM_RES_CTLR_SWAP could be disabled by the noswapaccount - kernel parameter (introduced in 2.6.29-rc1). Later on, this decision - turned out to be not ideal because we cannot have the feature compiled - in and disabled by default and let only interested to enable it - (e.g. general distribution kernels might need it). Therefore we have - added swapaccount[=0|1] parameter (introduced in 2.6.37) which provides - the both possibilities. If we remove noswapaccount we will have - less command line parameters with the same functionality and we - can also cleanup the parameter handling a bit (). -Who: Michal Hocko - ----------------------------- diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index 9511bff301c9..9d12977b6baf 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -978,8 +978,6 @@ S: Maintained F: arch/arm/plat-samsung/ F: arch/arm/plat-s3c24xx/ F: arch/arm/plat-s5p/ -F: drivers/*/*s3c2410* -F: drivers/*/*/*s3c2410* ARM/S3C2410 ARM ARCHITECTURE M: Ben Dooks @@ -3141,12 +3139,6 @@ S: Maintained F: net/ieee802154/ F: drivers/ieee802154/ -IKANOS/ADI EAGLE ADSL USB DRIVER -M: Matthieu Castet -M: Stanislaw Gruszka -S: Maintained -F: drivers/usb/atm/ueagle-atm.c - INTEGRITY MEASUREMENT ARCHITECTURE (IMA) M: Mimi Zohar S: Supported @@ -5616,20 +5608,18 @@ F: include/linux/sfi*.h SIMTEC EB110ATX (Chalice CATS) P: Ben Dooks -P: Vincent Sanders -M: Simtec Linux Team +M: Vincent Sanders W: http://www.simtec.co.uk/products/EB110ATX/ S: Supported SIMTEC EB2410ITX (BAST) P: Ben Dooks -P: Vincent Sanders -M: Simtec Linux Team +M: Vincent Sanders W: http://www.simtec.co.uk/products/EB2410ITX/ S: Supported -F: arch/arm/mach-s3c2410/mach-bast.c -F: arch/arm/mach-s3c2410/bast-ide.c -F: arch/arm/mach-s3c2410/bast-irq.c +F: arch/arm/mach-s3c2410/ +F: drivers/*/*s3c2410* +F: drivers/*/*/*s3c2410* TI DAVINCI MACHINE SUPPORT M: Kevin Hilman @@ -6604,16 +6594,6 @@ S: Maintained F: drivers/char/virtio_console.c F: include/linux/virtio_console.h -VIRTIO CORE, NET AND BLOCK DRIVERS -M: Rusty Russell -M: "Michael S. Tsirkin" -L: virtualization@lists.linux-foundation.org -S: Maintained -F: drivers/virtio/ -F: drivers/net/virtio_net.c -F: drivers/block/virtio_blk.c -F: include/linux/virtio_*.h - VIRTIO HOST (VHOST) M: "Michael S. Tsirkin" L: kvm@vger.kernel.org diff --git a/trunk/Makefile b/trunk/Makefile index 66e7e977ddc0..1f474953427f 100644 --- a/trunk/Makefile +++ b/trunk/Makefile @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 6 SUBLEVEL = 38 -EXTRAVERSION = -rc3 +EXTRAVERSION = -rc2 NAME = Flesh-Eating Bats with Fangs # *DOCUMENTATION* diff --git a/trunk/arch/arm/include/asm/io.h b/trunk/arch/arm/include/asm/io.h index d66605dea55a..20e0f7c9e03e 100644 --- a/trunk/arch/arm/include/asm/io.h +++ b/trunk/arch/arm/include/asm/io.h @@ -95,15 +95,6 @@ static inline void __iomem *__typesafe_io(unsigned long addr) return (void __iomem *)addr; } -/* IO barriers */ -#ifdef CONFIG_ARM_DMA_MEM_BUFFERABLE -#define __iormb() rmb() -#define __iowmb() wmb() -#else -#define __iormb() do { } while (0) -#define __iowmb() do { } while (0) -#endif - /* * Now, pick up the machine-defined IO definitions */ @@ -134,17 +125,17 @@ static inline void __iomem *__typesafe_io(unsigned long addr) * The {in,out}[bwl] macros are for emulating x86-style PCI/ISA IO space. */ #ifdef __io -#define outb(v,p) ({ __iowmb(); __raw_writeb(v,__io(p)); }) -#define outw(v,p) ({ __iowmb(); __raw_writew((__force __u16) \ - cpu_to_le16(v),__io(p)); }) -#define outl(v,p) ({ __iowmb(); __raw_writel((__force __u32) \ - cpu_to_le32(v),__io(p)); }) +#define outb(v,p) __raw_writeb(v,__io(p)) +#define outw(v,p) __raw_writew((__force __u16) \ + cpu_to_le16(v),__io(p)) +#define outl(v,p) __raw_writel((__force __u32) \ + cpu_to_le32(v),__io(p)) -#define inb(p) ({ __u8 __v = __raw_readb(__io(p)); __iormb(); __v; }) +#define inb(p) ({ __u8 __v = __raw_readb(__io(p)); __v; }) #define inw(p) ({ __u16 __v = le16_to_cpu((__force __le16) \ - __raw_readw(__io(p))); __iormb(); __v; }) + __raw_readw(__io(p))); __v; }) #define inl(p) ({ __u32 __v = le32_to_cpu((__force __le32) \ - __raw_readl(__io(p))); __iormb(); __v; }) + __raw_readl(__io(p))); __v; }) #define outsb(p,d,l) __raw_writesb(__io(p),d,l) #define outsw(p,d,l) __raw_writesw(__io(p),d,l) @@ -201,6 +192,14 @@ extern void _memset_io(volatile void __iomem *, int, size_t); #define writel_relaxed(v,c) ((void)__raw_writel((__force u32) \ cpu_to_le32(v),__mem_pci(c))) +#ifdef CONFIG_ARM_DMA_MEM_BUFFERABLE +#define __iormb() rmb() +#define __iowmb() wmb() +#else +#define __iormb() do { } while (0) +#define __iowmb() do { } while (0) +#endif + #define readb(c) ({ u8 __v = readb_relaxed(c); __iormb(); __v; }) #define readw(c) ({ u16 __v = readw_relaxed(c); __iormb(); __v; }) #define readl(c) ({ u32 __v = readl_relaxed(c); __iormb(); __v; }) diff --git a/trunk/arch/arm/kernel/head.S b/trunk/arch/arm/kernel/head.S index c0225da3fb21..f17d9a09e8fb 100644 --- a/trunk/arch/arm/kernel/head.S +++ b/trunk/arch/arm/kernel/head.S @@ -392,22 +392,24 @@ ENDPROC(__turn_mmu_on) #ifdef CONFIG_SMP_ON_UP __fixup_smp: - and r3, r9, #0x000f0000 @ architecture version - teq r3, #0x000f0000 @ CPU ID supported? + mov r4, #0x00070000 + orr r3, r4, #0xff000000 @ mask 0xff070000 + orr r4, r4, #0x41000000 @ val 0x41070000 + and r0, r9, r3 + teq r0, r4 @ ARM CPU and ARMv6/v7? bne __fixup_smp_on_up @ no, assume UP - bic r3, r9, #0x00ff0000 - bic r3, r3, #0x0000000f @ mask 0xff00fff0 - mov r4, #0x41000000 + orr r3, r3, #0x0000ff00 + orr r3, r3, #0x000000f0 @ mask 0xff07fff0 orr r4, r4, #0x0000b000 - orr r4, r4, #0x00000020 @ val 0x4100b020 - teq r3, r4 @ ARM 11MPCore? + orr r4, r4, #0x00000020 @ val 0x4107b020 + and r0, r9, r3 + teq r0, r4 @ ARM 11MPCore? moveq pc, lr @ yes, assume SMP mrc p15, 0, r0, c0, c0, 5 @ read MPIDR - and r0, r0, #0xc0000000 @ multiprocessing extensions and - teq r0, #0x80000000 @ not part of a uniprocessor system? - moveq pc, lr @ yes, assume SMP + tst r0, #1 << 31 + movne pc, lr @ bit 31 => SMP __fixup_smp_on_up: adr r0, 1f diff --git a/trunk/arch/arm/mach-footbridge/include/mach/debug-macro.S b/trunk/arch/arm/mach-footbridge/include/mach/debug-macro.S index 30b971d65815..3c9e0c40c679 100644 --- a/trunk/arch/arm/mach-footbridge/include/mach/debug-macro.S +++ b/trunk/arch/arm/mach-footbridge/include/mach/debug-macro.S @@ -17,8 +17,8 @@ /* For NetWinder debugging */ .macro addruart, rp, rv mov \rp, #0x000003f8 - orr \rv, \rp, #0xff000000 @ virtual - orr \rp, \rp, #0x7c000000 @ physical + orr \rv, \rp, #0x7c000000 @ physical + orr \rp, \rp, #0xff000000 @ virtual .endm #define UART_SHIFT 0 diff --git a/trunk/arch/arm/mach-omap1/include/mach/entry-macro.S b/trunk/arch/arm/mach-omap1/include/mach/entry-macro.S index bfb4fb1d7382..c9be6d4d83e2 100644 --- a/trunk/arch/arm/mach-omap1/include/mach/entry-macro.S +++ b/trunk/arch/arm/mach-omap1/include/mach/entry-macro.S @@ -14,6 +14,19 @@ #include #include +/* + * We use __glue to avoid errors with multiple definitions of + * .globl omap_irq_flags as it's included from entry-armv.S but not + * from entry-common.S. + */ +#ifdef __glue + .pushsection .data + .globl omap_irq_flags +omap_irq_flags: + .word 0 + .popsection +#endif + .macro disable_fiq .endm diff --git a/trunk/arch/arm/mach-omap1/irq.c b/trunk/arch/arm/mach-omap1/irq.c index 731dd33bff51..47701584df35 100644 --- a/trunk/arch/arm/mach-omap1/irq.c +++ b/trunk/arch/arm/mach-omap1/irq.c @@ -57,7 +57,6 @@ struct omap_irq_bank { unsigned long wake_enable; }; -u32 omap_irq_flags; static unsigned int irq_bank_count; static struct omap_irq_bank *irq_banks; @@ -177,6 +176,7 @@ static struct irq_chip omap_irq_chip = { void __init omap_init_irq(void) { + extern unsigned int omap_irq_flags; int i, j; #if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850) diff --git a/trunk/arch/arm/mach-omap2/dma.c b/trunk/arch/arm/mach-omap2/dma.c index 34922b2d2e3f..d2f15f5cfd36 100644 --- a/trunk/arch/arm/mach-omap2/dma.c +++ b/trunk/arch/arm/mach-omap2/dma.c @@ -264,7 +264,7 @@ static int __init omap2_system_dma_init_dev(struct omap_hwmod *oh, void *unused) if (IS_ERR(od)) { pr_err("%s: Cant build omap_device for %s:%s.\n", __func__, name, oh->name); - return PTR_ERR(od); + return IS_ERR(od); } mem = platform_get_resource(&od->pdev, IORESOURCE_MEM, 0); diff --git a/trunk/arch/arm/mach-omap2/include/mach/entry-macro.S b/trunk/arch/arm/mach-omap2/include/mach/entry-macro.S index 81985a665cb3..befa321c4c13 100644 --- a/trunk/arch/arm/mach-omap2/include/mach/entry-macro.S +++ b/trunk/arch/arm/mach-omap2/include/mach/entry-macro.S @@ -38,6 +38,20 @@ */ #ifdef MULTI_OMAP2 + +/* + * We use __glue to avoid errors with multiple definitions of + * .globl omap_irq_base as it's included from entry-armv.S but not + * from entry-common.S. + */ +#ifdef __glue + .pushsection .data + .globl omap_irq_base +omap_irq_base: + .word 0 + .popsection +#endif + /* * Configure the interrupt base on the first interrupt. * See also omap_irq_base_init for setting omap_irq_base. diff --git a/trunk/arch/arm/mach-omap2/io.c b/trunk/arch/arm/mach-omap2/io.c index c2032041d26f..e66687b0b9de 100644 --- a/trunk/arch/arm/mach-omap2/io.c +++ b/trunk/arch/arm/mach-omap2/io.c @@ -314,13 +314,14 @@ static int _set_hwmod_postsetup_state(struct omap_hwmod *oh, void *data) return omap_hwmod_set_postsetup_state(oh, *(u8 *)data); } -void __iomem *omap_irq_base; - /* * Initialize asm_irq_base for entry-macro.S */ static inline void omap_irq_base_init(void) { + extern void __iomem *omap_irq_base; + +#ifdef MULTI_OMAP2 if (cpu_is_omap24xx()) omap_irq_base = OMAP2_L4_IO_ADDRESS(OMAP24XX_IC_BASE); else if (cpu_is_omap34xx()) @@ -329,6 +330,7 @@ static inline void omap_irq_base_init(void) omap_irq_base = OMAP2_L4_IO_ADDRESS(OMAP44XX_GIC_CPU_BASE); else pr_err("Could not initialize omap_irq_base\n"); +#endif } void __init omap2_init_common_infrastructure(void) diff --git a/trunk/arch/arm/mach-omap2/mux.c b/trunk/arch/arm/mach-omap2/mux.c index fae49d12bc76..df8d2f2872c6 100644 --- a/trunk/arch/arm/mach-omap2/mux.c +++ b/trunk/arch/arm/mach-omap2/mux.c @@ -160,7 +160,7 @@ static int __init _omap_mux_get_by_name(struct omap_mux_partition *partition, struct omap_mux *mux = NULL; struct omap_mux_entry *e; const char *mode_name; - int found = 0, found_mode = 0, mode0_len = 0; + int found = 0, found_mode, mode0_len = 0; struct list_head *muxmodes = &partition->muxmodes; mode_name = strchr(muxname, '.'); diff --git a/trunk/arch/arm/mm/init.c b/trunk/arch/arm/mm/init.c index cddd684364da..5164069ced42 100644 --- a/trunk/arch/arm/mm/init.c +++ b/trunk/arch/arm/mm/init.c @@ -297,12 +297,6 @@ void __init arm_memblock_init(struct meminfo *mi, struct machine_desc *mdesc) memblock_reserve(__pa(_stext), _end - _stext); #endif #ifdef CONFIG_BLK_DEV_INITRD - if (phys_initrd_size && - memblock_is_region_reserved(phys_initrd_start, phys_initrd_size)) { - pr_err("INITRD: 0x%08lx+0x%08lx overlaps in-use memory region - disabling initrd\n", - phys_initrd_start, phys_initrd_size); - phys_initrd_start = phys_initrd_size = 0; - } if (phys_initrd_size) { memblock_reserve(phys_initrd_start, phys_initrd_size); diff --git a/trunk/arch/microblaze/kernel/head.S b/trunk/arch/microblaze/kernel/head.S index 0db20b5abb54..42434008209e 100644 --- a/trunk/arch/microblaze/kernel/head.S +++ b/trunk/arch/microblaze/kernel/head.S @@ -77,18 +77,8 @@ real_start: We ensure r7 points to a valid FDT, just in case the bootloader is broken or non-existent */ beqi r7, no_fdt_arg /* NULL pointer? don't copy */ -/* Does r7 point to a valid FDT? Load HEADER magic number */ - /* Run time Big/Little endian platform */ - /* Save 1 as word and load byte - 0 - BIG, 1 - LITTLE */ - addik r11, r0, 0x1 /* BIG/LITTLE checking value */ - /* __bss_start will be zeroed later - it is just temp location */ - swi r11, r0, TOPHYS(__bss_start) - lbui r11, r0, TOPHYS(__bss_start) - beqid r11, big_endian /* DO NOT break delay stop dependency */ - lw r11, r0, r7 /* Big endian load in delay slot */ - lwr r11, r0, r7 /* Little endian load */ -big_endian: - rsubi r11, r11, OF_DT_HEADER /* Check FDT header */ + lw r11, r0, r7 /* Does r7 point to a */ + rsubi r11, r11, OF_DT_HEADER /* valid FDT? */ beqi r11, _prepare_copy_fdt or r7, r0, r0 /* clear R7 when not valid DTB */ bnei r11, no_fdt_arg /* No - get out of here */ diff --git a/trunk/arch/microblaze/kernel/hw_exception_handler.S b/trunk/arch/microblaze/kernel/hw_exception_handler.S index 782680de3121..25f6e07d8de8 100644 --- a/trunk/arch/microblaze/kernel/hw_exception_handler.S +++ b/trunk/arch/microblaze/kernel/hw_exception_handler.S @@ -147,6 +147,10 @@ #if CONFIG_XILINX_MICROBLAZE0_USE_BARREL > 0 #define BSRLI(rD, rA, imm) \ bsrli rD, rA, imm + #elif CONFIG_XILINX_MICROBLAZE0_USE_DIV > 0 + #define BSRLI(rD, rA, imm) \ + ori rD, r0, (1 << imm); \ + idivu rD, rD, rA #else #define BSRLI(rD, rA, imm) BSRLI ## imm (rD, rA) /* Only the used shift constants defined here - add more if needed */ diff --git a/trunk/arch/microblaze/lib/fastcopy.S b/trunk/arch/microblaze/lib/fastcopy.S index 62021d7e249e..fdc48bb065d8 100644 --- a/trunk/arch/microblaze/lib/fastcopy.S +++ b/trunk/arch/microblaze/lib/fastcopy.S @@ -29,10 +29,6 @@ * between mem locations with size of xfer spec'd in bytes */ -#ifdef __MICROBLAZEEL__ -#error Microblaze LE not support ASM optimized lib func. Disable OPT_LIB_ASM. -#endif - #include .text .globl memcpy diff --git a/trunk/drivers/gpu/stub/Kconfig b/trunk/drivers/gpu/stub/Kconfig index 70e60a4bb678..09aea5f1556d 100644 --- a/trunk/drivers/gpu/stub/Kconfig +++ b/trunk/drivers/gpu/stub/Kconfig @@ -1,13 +1,11 @@ config STUB_POULSBO tristate "Intel GMA500 Stub Driver" depends on PCI - depends on NET # for THERMAL # Poulsbo stub depends on ACPI_VIDEO when ACPI is enabled # but for select to work, need to select ACPI_VIDEO's dependencies, ick select BACKLIGHT_CLASS_DEVICE if ACPI select INPUT if ACPI select ACPI_VIDEO if ACPI - select THERMAL if ACPI help Choose this option if you have a system that has Intel GMA500 (Poulsbo) integrated graphics. If M is selected, the module will diff --git a/trunk/drivers/mmc/host/mmci.c b/trunk/drivers/mmc/host/mmci.c index 2d6de3e03e2d..4b8dcd5b2a01 100644 --- a/trunk/drivers/mmc/host/mmci.c +++ b/trunk/drivers/mmc/host/mmci.c @@ -14,7 +14,6 @@ #include #include #include -#include #include #include #include @@ -284,19 +283,19 @@ mmci_data_irq(struct mmci_host *host, struct mmc_data *data, u32 remain, success; /* Calculate how far we are into the transfer */ - remain = readl(host->base + MMCIDATACNT); + remain = readl(host->base + MMCIDATACNT) << 2; success = data->blksz * data->blocks - remain; dev_dbg(mmc_dev(host->mmc), "MCI ERROR IRQ (status %08x)\n", status); if (status & MCI_DATACRCFAIL) { /* Last block was not successful */ - host->data_xfered = round_down(success - 1, data->blksz); + host->data_xfered = ((success / data->blksz) - 1 * data->blksz); data->error = -EILSEQ; } else if (status & MCI_DATATIMEOUT) { - host->data_xfered = round_down(success, data->blksz); + host->data_xfered = success; data->error = -ETIMEDOUT; } else if (status & (MCI_TXUNDERRUN|MCI_RXOVERRUN)) { - host->data_xfered = round_down(success, data->blksz); + host->data_xfered = success; data->error = -EIO; } @@ -320,7 +319,7 @@ mmci_data_irq(struct mmci_host *host, struct mmc_data *data, if (status & MCI_DATABLOCKEND) dev_err(mmc_dev(host->mmc), "stray MCI_DATABLOCKEND interrupt\n"); - if (status & MCI_DATAEND || data->error) { + if (status & MCI_DATAEND) { mmci_stop_data(host); if (!data->error) diff --git a/trunk/drivers/s390/block/dasd_alias.c b/trunk/drivers/s390/block/dasd_alias.c index 4155805dcdff..2b771f18d1ad 100644 --- a/trunk/drivers/s390/block/dasd_alias.c +++ b/trunk/drivers/s390/block/dasd_alias.c @@ -319,6 +319,9 @@ void dasd_alias_disconnect_device_from_lcu(struct dasd_device *device) private = (struct dasd_eckd_private *) device->private; lcu = private->lcu; + /* nothing to do if already disconnected */ + if (!lcu) + return; device->discipline->get_uid(device, &uid); spin_lock_irqsave(&lcu->lock, flags); list_del_init(&device->alias_list); @@ -680,6 +683,9 @@ int dasd_alias_remove_device(struct dasd_device *device) private = (struct dasd_eckd_private *) device->private; lcu = private->lcu; + /* nothing to do if already removed */ + if (!lcu) + return 0; spin_lock_irqsave(&lcu->lock, flags); _remove_device_from_lcu(lcu, device); spin_unlock_irqrestore(&lcu->lock, flags); diff --git a/trunk/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.c b/trunk/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.c index 29b8ab44ea47..0e298dba9fc8 100644 --- a/trunk/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.c +++ b/trunk/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.c @@ -360,8 +360,8 @@ int PSSendOps(void *arg) status = 1; goto complete; } - len = min(firmware->size, MAX_BDADDR_FORMAT_LENGTH - 1); - memcpy(config_bdaddr, firmware->data, len); + len = (firmware->size > MAX_BDADDR_FORMAT_LENGTH)? MAX_BDADDR_FORMAT_LENGTH: firmware->size; + memcpy(config_bdaddr, firmware->data,len); config_bdaddr[len] = '\0'; write_bdaddr(hdev,config_bdaddr,BDADDR_TYPE_STRING); A_RELEASE_FIRMWARE(firmware); diff --git a/trunk/drivers/staging/brcm80211/sys/wl_mac80211.c b/trunk/drivers/staging/brcm80211/sys/wl_mac80211.c index f1235884cc5d..bdd629d72a75 100644 --- a/trunk/drivers/staging/brcm80211/sys/wl_mac80211.c +++ b/trunk/drivers/staging/brcm80211/sys/wl_mac80211.c @@ -209,8 +209,11 @@ static void wl_ops_stop(struct ieee80211_hw *hw) struct wl_info *wl = hw->priv; ASSERT(wl); WL_LOCK(wl); + wl_down(wl); ieee80211_stop_queues(hw); WL_UNLOCK(wl); + + return; } static int @@ -243,14 +246,7 @@ wl_ops_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) static void wl_ops_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { - struct wl_info *wl; - - wl = HW_TO_WL(hw); - - /* put driver in down state */ - WL_LOCK(wl); - wl_down(wl); - WL_UNLOCK(wl); + return; } static int @@ -783,7 +779,7 @@ static struct wl_info *wl_attach(u16 vendor, u16 device, unsigned long regs, wl_found++; return wl; -fail: + fail: wl_free(wl); fail1: return NULL; @@ -1094,6 +1090,7 @@ wl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) return 0; } +#ifdef LINUXSTA_PS static int wl_suspend(struct pci_dev *pdev, pm_message_t state) { struct wl_info *wl; @@ -1108,12 +1105,11 @@ static int wl_suspend(struct pci_dev *pdev, pm_message_t state) return -ENODEV; } - /* only need to flag hw is down for proper resume */ WL_LOCK(wl); + wl_down(wl); wl->pub->hw_up = false; WL_UNLOCK(wl); - - pci_save_state(pdev); + pci_save_state(pdev, wl->pci_psstate); pci_disable_device(pdev); return pci_set_power_state(pdev, PCI_D3hot); } @@ -1137,7 +1133,7 @@ static int wl_resume(struct pci_dev *pdev) if (err) return err; - pci_restore_state(pdev); + pci_restore_state(pdev, wl->pci_psstate); err = pci_enable_device(pdev); if (err) @@ -1149,12 +1145,13 @@ static int wl_resume(struct pci_dev *pdev) if ((val & 0x0000ff00) != 0) pci_write_config_dword(pdev, 0x40, val & 0xffff00ff); - /* - * done. driver will be put in up state - * in wl_ops_add_interface() call. - */ + WL_LOCK(wl); + err = wl_up(wl); + WL_UNLOCK(wl); + return err; } +#endif /* LINUXSTA_PS */ static void wl_remove(struct pci_dev *pdev) { @@ -1187,12 +1184,14 @@ static void wl_remove(struct pci_dev *pdev) } static struct pci_driver wl_pci_driver = { - .name = "brcm80211", - .probe = wl_pci_probe, - .suspend = wl_suspend, - .resume = wl_resume, - .remove = __devexit_p(wl_remove), - .id_table = wl_id_table, + .name = "brcm80211", + .probe = wl_pci_probe, +#ifdef LINUXSTA_PS + .suspend = wl_suspend, + .resume = wl_resume, +#endif /* LINUXSTA_PS */ + .remove = __devexit_p(wl_remove), + .id_table = wl_id_table, }; /** diff --git a/trunk/drivers/staging/brcm80211/sys/wlc_mac80211.c b/trunk/drivers/staging/brcm80211/sys/wlc_mac80211.c index a1303863686c..1d5d01ac0a9b 100644 --- a/trunk/drivers/staging/brcm80211/sys/wlc_mac80211.c +++ b/trunk/drivers/staging/brcm80211/sys/wlc_mac80211.c @@ -5126,6 +5126,7 @@ wlc_sendpkt_mac80211(struct wlc_info *wlc, struct sk_buff *sdu, fifo = prio2fifo[prio]; ASSERT((uint) skb_headroom(sdu) >= TXOFF); + ASSERT(!(sdu->cloned)); ASSERT(!(sdu->next)); ASSERT(!(sdu->prev)); ASSERT(fifo < NFIFO); diff --git a/trunk/drivers/staging/comedi/drivers/ni_labpc.c b/trunk/drivers/staging/comedi/drivers/ni_labpc.c index 0728c3c0cb0e..4d1868d04bac 100644 --- a/trunk/drivers/staging/comedi/drivers/ni_labpc.c +++ b/trunk/drivers/staging/comedi/drivers/ni_labpc.c @@ -575,8 +575,7 @@ int labpc_common_attach(struct comedi_device *dev, unsigned long iobase, /* grab our IRQ */ if (irq) { isr_flags = 0; - if (thisboard->bustype == pci_bustype - || thisboard->bustype == pcmcia_bustype) + if (thisboard->bustype == pci_bustype) isr_flags |= IRQF_SHARED; if (request_irq(irq, labpc_interrupt, isr_flags, driver_labpc.driver_name, dev)) { diff --git a/trunk/drivers/staging/hv/blkvsc_drv.c b/trunk/drivers/staging/hv/blkvsc_drv.c index 4fb809485d9e..b3d05fcfe6d2 100644 --- a/trunk/drivers/staging/hv/blkvsc_drv.c +++ b/trunk/drivers/staging/hv/blkvsc_drv.c @@ -368,7 +368,6 @@ static int blkvsc_probe(struct device *device) blkdev->gd->first_minor = 0; blkdev->gd->fops = &block_ops; blkdev->gd->private_data = blkdev; - blkdev->gd->driverfs_dev = &(blkdev->device_ctx->device); sprintf(blkdev->gd->disk_name, "hd%c", 'a' + devnum); blkvsc_do_inquiry(blkdev); diff --git a/trunk/drivers/staging/hv/netvsc.c b/trunk/drivers/staging/hv/netvsc.c index 0edbe7483a4c..df9cd131e953 100644 --- a/trunk/drivers/staging/hv/netvsc.c +++ b/trunk/drivers/staging/hv/netvsc.c @@ -1279,7 +1279,7 @@ static void netvsc_channel_cb(void *context) /* ASSERT(device); */ packet = kzalloc(NETVSC_PACKET_SIZE * sizeof(unsigned char), - GFP_ATOMIC); + GFP_KERNEL); if (!packet) return; buffer = packet; diff --git a/trunk/drivers/staging/hv/netvsc_drv.c b/trunk/drivers/staging/hv/netvsc_drv.c index 54706a16dc0a..0147b407512c 100644 --- a/trunk/drivers/staging/hv/netvsc_drv.c +++ b/trunk/drivers/staging/hv/netvsc_drv.c @@ -358,6 +358,7 @@ static int netvsc_probe(struct device *device) /* Set initial state */ netif_carrier_off(net); + netif_stop_queue(net); net_device_ctx = netdev_priv(net); net_device_ctx->device_ctx = device_ctx; diff --git a/trunk/drivers/staging/iio/adc/ad7476_core.c b/trunk/drivers/staging/iio/adc/ad7476_core.c index b8b54da67c63..deb68c8a6e18 100644 --- a/trunk/drivers/staging/iio/adc/ad7476_core.c +++ b/trunk/drivers/staging/iio/adc/ad7476_core.c @@ -68,7 +68,7 @@ static ssize_t ad7476_show_scale(struct device *dev, /* Corresponds to Vref / 2^(bits) */ unsigned int scale_uv = (st->int_vref_mv * 1000) >> st->chip_info->bits; - return sprintf(buf, "%d.%03d\n", scale_uv / 1000, scale_uv % 1000); + return sprintf(buf, "%d.%d\n", scale_uv / 1000, scale_uv % 1000); } static IIO_DEVICE_ATTR(in_scale, S_IRUGO, ad7476_show_scale, NULL, 0); diff --git a/trunk/drivers/staging/iio/adc/ad7887_core.c b/trunk/drivers/staging/iio/adc/ad7887_core.c index 5d85efab658c..685908995d49 100644 --- a/trunk/drivers/staging/iio/adc/ad7887_core.c +++ b/trunk/drivers/staging/iio/adc/ad7887_core.c @@ -68,7 +68,7 @@ static ssize_t ad7887_show_scale(struct device *dev, /* Corresponds to Vref / 2^(bits) */ unsigned int scale_uv = (st->int_vref_mv * 1000) >> st->chip_info->bits; - return sprintf(buf, "%d.%03d\n", scale_uv / 1000, scale_uv % 1000); + return sprintf(buf, "%d.%d\n", scale_uv / 1000, scale_uv % 1000); } static IIO_DEVICE_ATTR(in_scale, S_IRUGO, ad7887_show_scale, NULL, 0); diff --git a/trunk/drivers/staging/iio/adc/ad799x_core.c b/trunk/drivers/staging/iio/adc/ad799x_core.c index 89ccf375a188..6309d521a864 100644 --- a/trunk/drivers/staging/iio/adc/ad799x_core.c +++ b/trunk/drivers/staging/iio/adc/ad799x_core.c @@ -432,7 +432,7 @@ static ssize_t ad799x_show_scale(struct device *dev, /* Corresponds to Vref / 2^(bits) */ unsigned int scale_uv = (st->int_vref_mv * 1000) >> st->chip_info->bits; - return sprintf(buf, "%d.%03d\n", scale_uv / 1000, scale_uv % 1000); + return sprintf(buf, "%d.%d\n", scale_uv / 1000, scale_uv % 1000); } static IIO_DEVICE_ATTR(in_scale, S_IRUGO, ad799x_show_scale, NULL, 0); diff --git a/trunk/drivers/staging/iio/dac/ad5446.c b/trunk/drivers/staging/iio/dac/ad5446.c index 0f87ecac82fc..e3387cd31145 100644 --- a/trunk/drivers/staging/iio/dac/ad5446.c +++ b/trunk/drivers/staging/iio/dac/ad5446.c @@ -87,7 +87,7 @@ static ssize_t ad5446_show_scale(struct device *dev, /* Corresponds to Vref / 2^(bits) */ unsigned int scale_uv = (st->vref_mv * 1000) >> st->chip_info->bits; - return sprintf(buf, "%d.%03d\n", scale_uv / 1000, scale_uv % 1000); + return sprintf(buf, "%d.%d\n", scale_uv / 1000, scale_uv % 1000); } static IIO_DEVICE_ATTR(out_scale, S_IRUGO, ad5446_show_scale, NULL, 0); diff --git a/trunk/drivers/staging/rt2860/rt_main_dev.c b/trunk/drivers/staging/rt2860/rt_main_dev.c index 236dd36d349a..701561d6b6fd 100644 --- a/trunk/drivers/staging/rt2860/rt_main_dev.c +++ b/trunk/drivers/staging/rt2860/rt_main_dev.c @@ -484,6 +484,8 @@ struct net_device *RtmpPhyNetDevInit(struct rt_rtmp_adapter *pAd, net_dev->ml_priv = (void *)pAd; pAd->net_dev = net_dev; + netif_stop_queue(net_dev); + return net_dev; } diff --git a/trunk/drivers/staging/rt2860/usb_main_dev.c b/trunk/drivers/staging/rt2860/usb_main_dev.c index 322bf49ee906..ee68d51caa4e 100644 --- a/trunk/drivers/staging/rt2860/usb_main_dev.c +++ b/trunk/drivers/staging/rt2860/usb_main_dev.c @@ -106,7 +106,6 @@ struct usb_device_id rtusb_usb_id[] = { {USB_DEVICE(0x0411, 0x016f)}, /* MelCo.,Inc. WLI-UC-G301N */ {USB_DEVICE(0x1737, 0x0070)}, /* Linksys WUSB100 */ {USB_DEVICE(0x1737, 0x0071)}, /* Linksys WUSB600N */ - {USB_DEVICE(0x1737, 0x0078)}, /* Linksys WUSB100v2 */ {USB_DEVICE(0x0411, 0x00e8)}, /* Buffalo WLI-UC-G300N */ {USB_DEVICE(0x050d, 0x815c)}, /* Belkin F5D8053 */ {USB_DEVICE(0x100D, 0x9031)}, /* Motorola 2770 */ diff --git a/trunk/drivers/staging/rtl8712/hal_init.c b/trunk/drivers/staging/rtl8712/hal_init.c index 84be383abec3..32088a641eba 100644 --- a/trunk/drivers/staging/rtl8712/hal_init.c +++ b/trunk/drivers/staging/rtl8712/hal_init.c @@ -128,13 +128,12 @@ static u8 rtl8712_dl_fw(struct _adapter *padapter) u8 *ptmpchar = NULL, *ppayload, *ptr; struct tx_desc *ptx_desc; u32 txdscp_sz = sizeof(struct tx_desc); - u8 ret = _FAIL; ulfilelength = rtl871x_open_fw(padapter, &phfwfile_hdl, &pmappedfw); if (pmappedfw && (ulfilelength > 0)) { update_fwhdr(&fwhdr, pmappedfw); if (chk_fwhdr(&fwhdr, ulfilelength) == _FAIL) - goto firmware_rel; + goto exit_fail; fill_fwpriv(padapter, &fwhdr.fwpriv); /* firmware check ok */ maxlen = (fwhdr.img_IMEM_size > fwhdr.img_SRAM_size) ? @@ -142,7 +141,7 @@ static u8 rtl8712_dl_fw(struct _adapter *padapter) maxlen += txdscp_sz; ptmpchar = _malloc(maxlen + FWBUFF_ALIGN_SZ); if (ptmpchar == NULL) - goto firmware_rel; + return _FAIL; ptx_desc = (struct tx_desc *)(ptmpchar + FWBUFF_ALIGN_SZ - ((addr_t)(ptmpchar) & (FWBUFF_ALIGN_SZ - 1))); @@ -274,13 +273,11 @@ static u8 rtl8712_dl_fw(struct _adapter *padapter) goto exit_fail; } else goto exit_fail; - ret = _SUCCESS; + return _SUCCESS; exit_fail: kfree(ptmpchar); -firmware_rel: - release_firmware((struct firmware *)phfwfile_hdl); - return ret; + return _FAIL; } uint rtl8712_hal_init(struct _adapter *padapter) diff --git a/trunk/drivers/staging/rtl8712/usb_intf.c b/trunk/drivers/staging/rtl8712/usb_intf.c index 21ce2af447b5..a692ee88b9e9 100644 --- a/trunk/drivers/staging/rtl8712/usb_intf.c +++ b/trunk/drivers/staging/rtl8712/usb_intf.c @@ -47,123 +47,54 @@ static int r871xu_drv_init(struct usb_interface *pusb_intf, static void r871xu_dev_remove(struct usb_interface *pusb_intf); static struct usb_device_id rtl871x_usb_id_tbl[] = { - -/* RTL8188SU */ - /* Realtek */ - {USB_DEVICE(0x0BDA, 0x8171)}, + /*92SU + * Realtek */ + {USB_DEVICE(0x0bda, 0x8171)}, + {USB_DEVICE(0x0bda, 0x8172)}, {USB_DEVICE(0x0bda, 0x8173)}, + {USB_DEVICE(0x0bda, 0x8174)}, {USB_DEVICE(0x0bda, 0x8712)}, {USB_DEVICE(0x0bda, 0x8713)}, {USB_DEVICE(0x0bda, 0xC512)}, - /* Abocom */ + /* Abocom */ {USB_DEVICE(0x07B8, 0x8188)}, - /* ASUS */ - {USB_DEVICE(0x0B05, 0x1786)}, - {USB_DEVICE(0x0B05, 0x1791)}, /* 11n mode disable */ - /* Belkin */ - {USB_DEVICE(0x050D, 0x945A)}, /* Corega */ - {USB_DEVICE(0x07AA, 0x0047)}, - /* D-Link */ - {USB_DEVICE(0x2001, 0x3306)}, - {USB_DEVICE(0x07D1, 0x3306)}, /* 11n mode disable */ - /* Edimax */ - {USB_DEVICE(0x7392, 0x7611)}, + {USB_DEVICE(0x07aa, 0x0047)}, + /* Dlink */ + {USB_DEVICE(0x07d1, 0x3303)}, + {USB_DEVICE(0x07d1, 0x3302)}, + {USB_DEVICE(0x07d1, 0x3300)}, + /* Dlink for Skyworth */ + {USB_DEVICE(0x14b2, 0x3300)}, + {USB_DEVICE(0x14b2, 0x3301)}, + {USB_DEVICE(0x14b2, 0x3302)}, /* EnGenius */ {USB_DEVICE(0x1740, 0x9603)}, - /* Hawking */ - {USB_DEVICE(0x0E66, 0x0016)}, - /* Hercules */ - {USB_DEVICE(0x06F8, 0xE034)}, - {USB_DEVICE(0x06F8, 0xE032)}, - /* Logitec */ - {USB_DEVICE(0x0789, 0x0167)}, - /* PCI */ - {USB_DEVICE(0x2019, 0xAB28)}, - {USB_DEVICE(0x2019, 0xED16)}, - /* Sitecom */ - {USB_DEVICE(0x0DF6, 0x0057)}, - {USB_DEVICE(0x0DF6, 0x0045)}, - {USB_DEVICE(0x0DF6, 0x0059)}, /* 11n mode disable */ - {USB_DEVICE(0x0DF6, 0x004B)}, - {USB_DEVICE(0x0DF6, 0x0063)}, - /* Sweex */ - {USB_DEVICE(0x177F, 0x0154)}, - /* Thinkware */ - {USB_DEVICE(0x0BDA, 0x5077)}, - /* Toshiba */ - {USB_DEVICE(0x1690, 0x0752)}, - /* - */ - {USB_DEVICE(0x20F4, 0x646B)}, - {USB_DEVICE(0x083A, 0xC512)}, - -/* RTL8191SU */ - /* Realtek */ - {USB_DEVICE(0x0BDA, 0x8172)}, - /* Amigo */ - {USB_DEVICE(0x0EB0, 0x9061)}, - /* ASUS/EKB */ - {USB_DEVICE(0x0BDA, 0x8172)}, - {USB_DEVICE(0x13D3, 0x3323)}, - {USB_DEVICE(0x13D3, 0x3311)}, /* 11n mode disable */ - {USB_DEVICE(0x13D3, 0x3342)}, - /* ASUS/EKBLenovo */ - {USB_DEVICE(0x13D3, 0x3333)}, - {USB_DEVICE(0x13D3, 0x3334)}, - {USB_DEVICE(0x13D3, 0x3335)}, /* 11n mode disable */ - {USB_DEVICE(0x13D3, 0x3336)}, /* 11n mode disable */ - /* ASUS/Media BOX */ - {USB_DEVICE(0x13D3, 0x3309)}, + {USB_DEVICE(0x1740, 0x9605)}, /* Belkin */ - {USB_DEVICE(0x050D, 0x815F)}, - /* D-Link */ - {USB_DEVICE(0x07D1, 0x3302)}, - {USB_DEVICE(0x07D1, 0x3300)}, - {USB_DEVICE(0x07D1, 0x3303)}, + {USB_DEVICE(0x050d, 0x815F)}, + {USB_DEVICE(0x050d, 0x945A)}, + {USB_DEVICE(0x050d, 0x845A)}, + /* Guillemot */ + {USB_DEVICE(0x06f8, 0xe031)}, /* Edimax */ + {USB_DEVICE(0x7392, 0x7611)}, {USB_DEVICE(0x7392, 0x7612)}, - /* EnGenius */ - {USB_DEVICE(0x1740, 0x9605)}, - /* Guillemot */ - {USB_DEVICE(0x06F8, 0xE031)}, + {USB_DEVICE(0x7392, 0x7622)}, + /* Sitecom */ + {USB_DEVICE(0x0DF6, 0x0045)}, /* Hawking */ {USB_DEVICE(0x0E66, 0x0015)}, - /* Mediao */ + {USB_DEVICE(0x0E66, 0x0016)}, + {USB_DEVICE(0x0b05, 0x1786)}, + {USB_DEVICE(0x0b05, 0x1791)}, /* 11n mode disable */ + {USB_DEVICE(0x13D3, 0x3306)}, - /* PCI */ - {USB_DEVICE(0x2019, 0xED18)}, - {USB_DEVICE(0x2019, 0x4901)}, - /* Sitecom */ - {USB_DEVICE(0x0DF6, 0x0058)}, - {USB_DEVICE(0x0DF6, 0x0049)}, - {USB_DEVICE(0x0DF6, 0x004C)}, - {USB_DEVICE(0x0DF6, 0x0064)}, - /* Skyworth */ - {USB_DEVICE(0x14b2, 0x3300)}, - {USB_DEVICE(0x14b2, 0x3301)}, - {USB_DEVICE(0x14B2, 0x3302)}, - /* - */ - {USB_DEVICE(0x04F2, 0xAFF2)}, - {USB_DEVICE(0x04F2, 0xAFF5)}, - {USB_DEVICE(0x04F2, 0xAFF6)}, - {USB_DEVICE(0x13D3, 0x3339)}, - {USB_DEVICE(0x13D3, 0x3340)}, /* 11n mode disable */ - {USB_DEVICE(0x13D3, 0x3341)}, /* 11n mode disable */ + {USB_DEVICE(0x13D3, 0x3309)}, {USB_DEVICE(0x13D3, 0x3310)}, + {USB_DEVICE(0x13D3, 0x3311)}, /* 11n mode disable */ {USB_DEVICE(0x13D3, 0x3325)}, - -/* RTL8192SU */ - /* Realtek */ - {USB_DEVICE(0x0BDA, 0x8174)}, - {USB_DEVICE(0x0BDA, 0x8174)}, - /* Belkin */ - {USB_DEVICE(0x050D, 0x845A)}, - /* Corega */ - {USB_DEVICE(0x07AA, 0x0051)}, - /* Edimax */ - {USB_DEVICE(0x7392, 0x7622)}, - /* NEC */ - {USB_DEVICE(0x0409, 0x02B6)}, + {USB_DEVICE(0x083A, 0xC512)}, {} }; @@ -172,20 +103,8 @@ MODULE_DEVICE_TABLE(usb, rtl871x_usb_id_tbl); static struct specific_device_id specific_device_id_tbl[] = { {.idVendor = 0x0b05, .idProduct = 0x1791, .flags = SPEC_DEV_ID_DISABLE_HT}, - {.idVendor = 0x0df6, .idProduct = 0x0059, - .flags = SPEC_DEV_ID_DISABLE_HT}, - {.idVendor = 0x13d3, .idProduct = 0x3306, - .flags = SPEC_DEV_ID_DISABLE_HT}, {.idVendor = 0x13D3, .idProduct = 0x3311, .flags = SPEC_DEV_ID_DISABLE_HT}, - {.idVendor = 0x13d3, .idProduct = 0x3335, - .flags = SPEC_DEV_ID_DISABLE_HT}, - {.idVendor = 0x13d3, .idProduct = 0x3336, - .flags = SPEC_DEV_ID_DISABLE_HT}, - {.idVendor = 0x13d3, .idProduct = 0x3340, - .flags = SPEC_DEV_ID_DISABLE_HT}, - {.idVendor = 0x13d3, .idProduct = 0x3341, - .flags = SPEC_DEV_ID_DISABLE_HT}, {} }; diff --git a/trunk/drivers/staging/speakup/kobjects.c b/trunk/drivers/staging/speakup/kobjects.c index 07a7f5432597..408bb9b3303e 100644 --- a/trunk/drivers/staging/speakup/kobjects.c +++ b/trunk/drivers/staging/speakup/kobjects.c @@ -332,7 +332,7 @@ static ssize_t silent_store(struct kobject *kobj, struct kobj_attribute *attr, unsigned long flags; len = strlen(buf); - if (len > 0 && len < 3) { + if (len > 0 || len < 3) { ch = buf[0]; if (ch == '\n') ch = '0'; diff --git a/trunk/drivers/staging/ste_rmi4/synaptics_i2c_rmi4.c b/trunk/drivers/staging/ste_rmi4/synaptics_i2c_rmi4.c index 80183a7e6624..e8f047e86a32 100644 --- a/trunk/drivers/staging/ste_rmi4/synaptics_i2c_rmi4.c +++ b/trunk/drivers/staging/ste_rmi4/synaptics_i2c_rmi4.c @@ -986,6 +986,12 @@ static int __devinit synaptics_rmi4_probe input_set_abs_params(rmi4_data->input_dev, ABS_MT_TOUCH_MAJOR, 0, MAX_TOUCH_MAJOR, 0, 0); + retval = input_register_device(rmi4_data->input_dev); + if (retval) { + dev_err(&client->dev, "%s:input register failed\n", __func__); + goto err_input_register; + } + /* Clear interrupts */ synaptics_rmi4_i2c_block_read(rmi4_data, rmi4_data->fn01_data_base_addr + 1, intr_status, @@ -997,20 +1003,15 @@ static int __devinit synaptics_rmi4_probe if (retval) { dev_err(&client->dev, "%s:Unable to get attn irq %d\n", __func__, platformdata->irq_number); - goto err_unset_clientdata; - } - - retval = input_register_device(rmi4_data->input_dev); - if (retval) { - dev_err(&client->dev, "%s:input register failed\n", __func__); - goto err_free_irq; + goto err_request_irq; } return retval; -err_free_irq: +err_request_irq: free_irq(platformdata->irq_number, rmi4_data); -err_unset_clientdata: + input_unregister_device(rmi4_data->input_dev); +err_input_register: i2c_set_clientdata(client, NULL); err_query_dev: if (platformdata->regulator_en) { diff --git a/trunk/drivers/staging/tidspbridge/core/io_sm.c b/trunk/drivers/staging/tidspbridge/core/io_sm.c index 27e0aa81a584..571864555ddd 100644 --- a/trunk/drivers/staging/tidspbridge/core/io_sm.c +++ b/trunk/drivers/staging/tidspbridge/core/io_sm.c @@ -949,7 +949,7 @@ void io_dpc(unsigned long ref_data) * Calls the Bridge's CHNL_ISR to determine if this interrupt is ours, then * schedules a DPC to dispatch I/O. */ -int io_mbox_msg(struct notifier_block *self, unsigned long len, void *msg) +void io_mbox_msg(u32 msg) { struct io_mgr *pio_mgr; struct dev_object *dev_obj; @@ -959,9 +959,9 @@ int io_mbox_msg(struct notifier_block *self, unsigned long len, void *msg) dev_get_io_mgr(dev_obj, &pio_mgr); if (!pio_mgr) - return NOTIFY_BAD; + return; - pio_mgr->intr_val = (u16)((u32)msg); + pio_mgr->intr_val = (u16)msg; if (pio_mgr->intr_val & MBX_PM_CLASS) io_dispatch_pm(pio_mgr); @@ -973,7 +973,7 @@ int io_mbox_msg(struct notifier_block *self, unsigned long len, void *msg) spin_unlock_irqrestore(&pio_mgr->dpc_lock, flags); tasklet_schedule(&pio_mgr->dpc_tasklet); } - return NOTIFY_OK; + return; } /* diff --git a/trunk/drivers/staging/tidspbridge/core/tiomap3430.c b/trunk/drivers/staging/tidspbridge/core/tiomap3430.c index a3f69f6f505f..a3b0a183d570 100644 --- a/trunk/drivers/staging/tidspbridge/core/tiomap3430.c +++ b/trunk/drivers/staging/tidspbridge/core/tiomap3430.c @@ -223,10 +223,6 @@ static struct bridge_drv_interface drv_interface_fxns = { bridge_msg_set_queue_id, }; -static struct notifier_block dsp_mbox_notifier = { - .notifier_call = io_mbox_msg, -}; - static inline void flush_all(struct bridge_dev_context *dev_context) { if (dev_context->dw_brd_state == BRD_DSP_HIBERNATION || @@ -557,7 +553,7 @@ static int bridge_brd_start(struct bridge_dev_context *dev_ctxt, * Enable Mailbox events and also drain any pending * stale messages. */ - dev_context->mbox = omap_mbox_get("dsp", &dsp_mbox_notifier); + dev_context->mbox = omap_mbox_get("dsp"); if (IS_ERR(dev_context->mbox)) { dev_context->mbox = NULL; pr_err("%s: Failed to get dsp mailbox handle\n", @@ -567,6 +563,8 @@ static int bridge_brd_start(struct bridge_dev_context *dev_ctxt, } if (!status) { + dev_context->mbox->rxq->callback = (int (*)(void *))io_mbox_msg; + /*PM_IVA2GRPSEL_PER = 0xC0;*/ temp = readl(resources->dw_per_pm_base + 0xA8); temp = (temp & 0xFFFFFF30) | 0xC0; @@ -687,7 +685,7 @@ static int bridge_brd_stop(struct bridge_dev_context *dev_ctxt) /* Disable the mailbox interrupts */ if (dev_context->mbox) { omap_mbox_disable_irq(dev_context->mbox, IRQ_RX); - omap_mbox_put(dev_context->mbox, &dsp_mbox_notifier); + omap_mbox_put(dev_context->mbox); dev_context->mbox = NULL; } /* Reset IVA2 clocks*/ @@ -788,7 +786,10 @@ static int bridge_dev_create(struct bridge_dev_context pt_attrs = kzalloc(sizeof(struct pg_table_attrs), GFP_KERNEL); if (pt_attrs != NULL) { - pt_attrs->l1_size = SZ_16K; /* 4096 entries of 32 bits */ + /* Assuming that we use only DSP's memory map + * until 0x4000:0000 , we would need only 1024 + * L1 enties i.e L1 size = 4K */ + pt_attrs->l1_size = 0x1000; align_size = pt_attrs->l1_size; /* Align sizes are expected to be power of 2 */ /* we like to get aligned on L1 table size */ diff --git a/trunk/drivers/staging/tidspbridge/include/dspbridge/io_sm.h b/trunk/drivers/staging/tidspbridge/include/dspbridge/io_sm.h index 8242c70e09dd..18aec55d8647 100644 --- a/trunk/drivers/staging/tidspbridge/include/dspbridge/io_sm.h +++ b/trunk/drivers/staging/tidspbridge/include/dspbridge/io_sm.h @@ -72,17 +72,22 @@ extern void io_dpc(unsigned long ref_data); /* * ======== io_mbox_msg ======== * Purpose: - * Main message handler for the shared memory Bridge channel manager. - * Determine if this message is ours, then schedules a DPC to - * dispatch I/O. + * Main interrupt handler for the shared memory Bridge channel manager. + * Calls the Bridge's chnlsm_isr to determine if this interrupt is ours, + * then schedules a DPC to dispatch I/O. * Parameters: - * self: Pointer to its own notifier_block struct. - * len: Length of message. - * msg: Message code received. + * ref_data: Pointer to the channel manager object for this board. + * Set in an initial call to ISR_Install(). * Returns: - * NOTIFY_OK if handled; NOTIFY_BAD otherwise. + * TRUE if interrupt handled; FALSE otherwise. + * Requires: + * Must be in locked memory if executing in kernel mode. + * Must only call functions which are in locked memory if Kernel mode. + * Must only call asynchronous services. + * Interrupts are disabled and EOI for this interrupt has been sent. + * Ensures: */ -int io_mbox_msg(struct notifier_block *self, unsigned long len, void *msg); +void io_mbox_msg(u32 msg); /* * ======== io_request_chnl ======== diff --git a/trunk/drivers/staging/usbip/stub.h b/trunk/drivers/staging/usbip/stub.h index d73267961ef4..30dbfb6d16f2 100644 --- a/trunk/drivers/staging/usbip/stub.h +++ b/trunk/drivers/staging/usbip/stub.h @@ -32,7 +32,6 @@ struct stub_device { struct usb_interface *interface; - struct usb_device *udev; struct list_head list; struct usbip_device ud; diff --git a/trunk/drivers/staging/usbip/stub_dev.c b/trunk/drivers/staging/usbip/stub_dev.c index a7ce51cc8909..b186b5fed2b9 100644 --- a/trunk/drivers/staging/usbip/stub_dev.c +++ b/trunk/drivers/staging/usbip/stub_dev.c @@ -258,11 +258,10 @@ static void stub_shutdown_connection(struct usbip_device *ud) static void stub_device_reset(struct usbip_device *ud) { struct stub_device *sdev = container_of(ud, struct stub_device, ud); - struct usb_device *udev = sdev->udev; + struct usb_device *udev = interface_to_usbdev(sdev->interface); int ret; usbip_udbg("device reset"); - ret = usb_lock_device_for_reset(udev, sdev->interface); if (ret < 0) { dev_err(&udev->dev, "lock for reset\n"); @@ -310,8 +309,7 @@ static void stub_device_unusable(struct usbip_device *ud) * * Allocates and initializes a new stub_device struct. */ -static struct stub_device *stub_device_alloc(struct usb_device *udev, - struct usb_interface *interface) +static struct stub_device *stub_device_alloc(struct usb_interface *interface) { struct stub_device *sdev; int busnum = interface_to_busnum(interface); @@ -326,8 +324,7 @@ static struct stub_device *stub_device_alloc(struct usb_device *udev, return NULL; } - sdev->interface = usb_get_intf(interface); - sdev->udev = usb_get_dev(udev); + sdev->interface = interface; /* * devid is defined with devnum when this driver is first allocated. @@ -453,12 +450,11 @@ static int stub_probe(struct usb_interface *interface, return err; } - usb_get_intf(interface); return 0; } /* ok. this is my device. */ - sdev = stub_device_alloc(udev, interface); + sdev = stub_device_alloc(interface); if (!sdev) return -ENOMEM; @@ -480,8 +476,6 @@ static int stub_probe(struct usb_interface *interface, dev_err(&interface->dev, "create sysfs files for %s\n", udev_busid); usb_set_intfdata(interface, NULL); - usb_put_intf(interface); - busid_priv->interf_count = 0; busid_priv->sdev = NULL; @@ -551,7 +545,6 @@ static void stub_disconnect(struct usb_interface *interface) if (busid_priv->interf_count > 1) { busid_priv->interf_count--; shutdown_busid(busid_priv); - usb_put_intf(interface); return; } @@ -561,9 +554,6 @@ static void stub_disconnect(struct usb_interface *interface) /* 1. shutdown the current connection */ shutdown_busid(busid_priv); - usb_put_dev(sdev->udev); - usb_put_intf(interface); - /* 3. free sdev */ busid_priv->sdev = NULL; stub_device_free(sdev); diff --git a/trunk/drivers/staging/usbip/stub_rx.c b/trunk/drivers/staging/usbip/stub_rx.c index ae6ac82754a4..3de6fd2539dc 100644 --- a/trunk/drivers/staging/usbip/stub_rx.c +++ b/trunk/drivers/staging/usbip/stub_rx.c @@ -364,7 +364,7 @@ static struct stub_priv *stub_priv_alloc(struct stub_device *sdev, static int get_pipe(struct stub_device *sdev, int epnum, int dir) { - struct usb_device *udev = sdev->udev; + struct usb_device *udev = interface_to_usbdev(sdev->interface); struct usb_host_endpoint *ep; struct usb_endpoint_descriptor *epd = NULL; @@ -484,7 +484,7 @@ static void stub_recv_cmd_submit(struct stub_device *sdev, int ret; struct stub_priv *priv; struct usbip_device *ud = &sdev->ud; - struct usb_device *udev = sdev->udev; + struct usb_device *udev = interface_to_usbdev(sdev->interface); int pipe = get_pipe(sdev, pdu->base.ep, pdu->base.direction); diff --git a/trunk/drivers/staging/usbip/vhci.h b/trunk/drivers/staging/usbip/vhci.h index afc3b1a71881..41a1fe5138f4 100644 --- a/trunk/drivers/staging/usbip/vhci.h +++ b/trunk/drivers/staging/usbip/vhci.h @@ -100,6 +100,9 @@ struct vhci_hcd { * But, the index of this array begins from 0. */ struct vhci_device vdev[VHCI_NPORTS]; + + /* vhci_device which has not been assiged its address yet */ + int pending_port; }; @@ -116,9 +119,6 @@ void rh_port_disconnect(int rhport); void vhci_rx_loop(struct usbip_task *ut); void vhci_tx_loop(struct usbip_task *ut); -struct urb *pickup_urb_and_free_priv(struct vhci_device *vdev, - __u32 seqnum); - #define hardware (&the_controller->pdev.dev) static inline struct vhci_device *port_to_vdev(__u32 port) diff --git a/trunk/drivers/staging/usbip/vhci_hcd.c b/trunk/drivers/staging/usbip/vhci_hcd.c index a35fe61268de..08bd26a245d5 100644 --- a/trunk/drivers/staging/usbip/vhci_hcd.c +++ b/trunk/drivers/staging/usbip/vhci_hcd.c @@ -138,6 +138,8 @@ void rh_port_connect(int rhport, enum usb_device_speed speed) * the_controller->vdev[rhport].ud.status = VDEV_CONNECT; * spin_unlock(&the_controller->vdev[rhport].ud.lock); */ + the_controller->pending_port = rhport; + spin_unlock_irqrestore(&the_controller->lock, flags); usb_hcd_poll_rh_status(vhci_to_hcd(the_controller)); @@ -557,7 +559,6 @@ static int vhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, struct device *dev = &urb->dev->dev; int ret = 0; unsigned long flags; - struct vhci_device *vdev; usbip_dbg_vhci_hc("enter, usb_hcd %p urb %p mem_flags %d\n", hcd, urb, mem_flags); @@ -573,18 +574,6 @@ static int vhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, return urb->status; } - vdev = port_to_vdev(urb->dev->portnum-1); - - /* refuse enqueue for dead connection */ - spin_lock(&vdev->ud.lock); - if (vdev->ud.status == VDEV_ST_NULL || vdev->ud.status == VDEV_ST_ERROR) { - usbip_uerr("enqueue for inactive port %d\n", vdev->rhport); - spin_unlock(&vdev->ud.lock); - spin_unlock_irqrestore(&the_controller->lock, flags); - return -ENODEV; - } - spin_unlock(&vdev->ud.lock); - ret = usb_hcd_link_urb_to_ep(hcd, urb); if (ret) goto no_need_unlink; @@ -603,6 +592,8 @@ static int vhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, __u8 type = usb_pipetype(urb->pipe); struct usb_ctrlrequest *ctrlreq = (struct usb_ctrlrequest *) urb->setup_packet; + struct vhci_device *vdev = + port_to_vdev(the_controller->pending_port); if (type != PIPE_CONTROL || !ctrlreq) { dev_err(dev, "invalid request to devnum 0\n"); @@ -616,9 +607,7 @@ static int vhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, dev_info(dev, "SetAddress Request (%d) to port %d\n", ctrlreq->wValue, vdev->rhport); - if (vdev->udev) - usb_put_dev(vdev->udev); - vdev->udev = usb_get_dev(urb->dev); + vdev->udev = urb->dev; spin_lock(&vdev->ud.lock); vdev->ud.status = VDEV_ST_USED; @@ -638,9 +627,8 @@ static int vhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, "Get_Descriptor to device 0 " "(get max pipe size)\n"); - if (vdev->udev) - usb_put_dev(vdev->udev); - vdev->udev = usb_get_dev(urb->dev); + /* FIXME: reference count? (usb_get_dev()) */ + vdev->udev = urb->dev; goto out; default: @@ -817,6 +805,7 @@ static int vhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) return 0; } + static void vhci_device_unlink_cleanup(struct vhci_device *vdev) { struct vhci_unlink *unlink, *tmp; @@ -824,34 +813,11 @@ static void vhci_device_unlink_cleanup(struct vhci_device *vdev) spin_lock(&vdev->priv_lock); list_for_each_entry_safe(unlink, tmp, &vdev->unlink_tx, list) { - usbip_uinfo("unlink cleanup tx %lu\n", unlink->unlink_seqnum); list_del(&unlink->list); kfree(unlink); } list_for_each_entry_safe(unlink, tmp, &vdev->unlink_rx, list) { - struct urb *urb; - - /* give back URB of unanswered unlink request */ - usbip_uinfo("unlink cleanup rx %lu\n", unlink->unlink_seqnum); - - urb = pickup_urb_and_free_priv(vdev, unlink->unlink_seqnum); - if (!urb) { - usbip_uinfo("the urb (seqnum %lu) was already given back\n", - unlink->unlink_seqnum); - list_del(&unlink->list); - kfree(unlink); - continue; - } - - urb->status = -ENODEV; - - spin_lock(&the_controller->lock); - usb_hcd_unlink_urb_from_ep(vhci_to_hcd(the_controller), urb); - spin_unlock(&the_controller->lock); - - usb_hcd_giveback_urb(vhci_to_hcd(the_controller), urb, urb->status); - list_del(&unlink->list); kfree(unlink); } @@ -921,10 +887,6 @@ static void vhci_device_reset(struct usbip_device *ud) vdev->speed = 0; vdev->devid = 0; - if (vdev->udev) - usb_put_dev(vdev->udev); - vdev->udev = NULL; - ud->tcp_socket = NULL; ud->status = VDEV_ST_NULL; diff --git a/trunk/drivers/staging/usbip/vhci_rx.c b/trunk/drivers/staging/usbip/vhci_rx.c index bf6991470941..8147d7202b2d 100644 --- a/trunk/drivers/staging/usbip/vhci_rx.c +++ b/trunk/drivers/staging/usbip/vhci_rx.c @@ -23,14 +23,16 @@ #include "vhci.h" -/* get URB from transmitted urb queue. caller must hold vdev->priv_lock */ -struct urb *pickup_urb_and_free_priv(struct vhci_device *vdev, +/* get URB from transmitted urb queue */ +static struct urb *pickup_urb_and_free_priv(struct vhci_device *vdev, __u32 seqnum) { struct vhci_priv *priv, *tmp; struct urb *urb = NULL; int status; + spin_lock(&vdev->priv_lock); + list_for_each_entry_safe(priv, tmp, &vdev->priv_rx, list) { if (priv->seqnum == seqnum) { urb = priv->urb; @@ -61,6 +63,8 @@ struct urb *pickup_urb_and_free_priv(struct vhci_device *vdev, } } + spin_unlock(&vdev->priv_lock); + return urb; } @@ -70,11 +74,9 @@ static void vhci_recv_ret_submit(struct vhci_device *vdev, struct usbip_device *ud = &vdev->ud; struct urb *urb; - spin_lock(&vdev->priv_lock); urb = pickup_urb_and_free_priv(vdev, pdu->base.seqnum); - spin_unlock(&vdev->priv_lock); if (!urb) { usbip_uerr("cannot find a urb of seqnum %u\n", @@ -159,12 +161,7 @@ static void vhci_recv_ret_unlink(struct vhci_device *vdev, return; } - spin_lock(&vdev->priv_lock); - urb = pickup_urb_and_free_priv(vdev, unlink->unlink_seqnum); - - spin_unlock(&vdev->priv_lock); - if (!urb) { /* * I get the result of a unlink request. But, it seems that I @@ -193,19 +190,6 @@ static void vhci_recv_ret_unlink(struct vhci_device *vdev, return; } -static int vhci_priv_tx_empty(struct vhci_device *vdev) -{ - int empty = 0; - - spin_lock(&vdev->priv_lock); - - empty = list_empty(&vdev->priv_rx); - - spin_unlock(&vdev->priv_lock); - - return empty; -} - /* recv a pdu */ static void vhci_rx_pdu(struct usbip_device *ud) { @@ -218,29 +202,11 @@ static void vhci_rx_pdu(struct usbip_device *ud) memset(&pdu, 0, sizeof(pdu)); + /* 1. receive a pdu header */ ret = usbip_xmit(0, ud->tcp_socket, (char *) &pdu, sizeof(pdu), 0); - if (ret < 0) { - if (ret == -ECONNRESET) - usbip_uinfo("connection reset by peer\n"); - else if (ret == -EAGAIN) { - /* ignore if connection was idle */ - if (vhci_priv_tx_empty(vdev)) - return; - usbip_uinfo("connection timed out with pending urbs\n"); - } else if (ret != -ERESTARTSYS) - usbip_uinfo("xmit failed %d\n", ret); - - usbip_event_add(ud, VDEV_EVENT_ERROR_TCP); - return; - } - if (ret == 0) { - usbip_uinfo("connection closed"); - usbip_event_add(ud, VDEV_EVENT_DOWN); - return; - } if (ret != sizeof(pdu)) { - usbip_uerr("received pdu size is %d, should be %d\n", + usbip_uerr("receiving pdu failed! size is %d, should be %d\n", ret, (unsigned int)sizeof(pdu)); usbip_event_add(ud, VDEV_EVENT_ERROR_TCP); return; diff --git a/trunk/drivers/staging/xgifb/vb_setmode.c b/trunk/drivers/staging/xgifb/vb_setmode.c index e19b932492e1..7016fdd2509f 100644 --- a/trunk/drivers/staging/xgifb/vb_setmode.c +++ b/trunk/drivers/staging/xgifb/vb_setmode.c @@ -3954,8 +3954,8 @@ void XGI_GetCRT2ResInfo(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned char XGI_IsLCDDualLink(struct vb_device_info *pVBInfo) { - if ((pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) && - (pVBInfo->LCDInfo & SetLCDDualLink)) /* shampoo0129 */ + if ((((pVBInfo->VBInfo & SetCRT2ToLCD) | SetCRT2ToLCDA)) + && (pVBInfo->LCDInfo & SetLCDDualLink)) /* shampoo0129 */ return 1; return 0; @@ -8773,7 +8773,7 @@ unsigned short XGI_GetVCLK2Ptr(unsigned short ModeNo, if (pVBInfo->IF_DEF_LVDS == 0) { CRT2Index = CRT2Index >> 6; /* for LCD */ - if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { /*301b*/ + if (((pVBInfo->VBInfo & SetCRT2ToLCD) | SetCRT2ToLCDA)) { /*301b*/ if (pVBInfo->LCDResInfo != Panel1024x768) VCLKIndex = LCDXlat2VCLK[CRT2Index]; else diff --git a/trunk/drivers/tty/n_hdlc.c b/trunk/drivers/tty/n_hdlc.c index 52fc0c9a6364..47d32281032c 100644 --- a/trunk/drivers/tty/n_hdlc.c +++ b/trunk/drivers/tty/n_hdlc.c @@ -581,9 +581,8 @@ static ssize_t n_hdlc_tty_read(struct tty_struct *tty, struct file *file, __u8 __user *buf, size_t nr) { struct n_hdlc *n_hdlc = tty2n_hdlc(tty); - int ret = 0; + int ret; struct n_hdlc_buf *rbuf; - DECLARE_WAITQUEUE(wait, current); if (debuglevel >= DEBUG_LEVEL_INFO) printk("%s(%d)n_hdlc_tty_read() called\n",__FILE__,__LINE__); @@ -599,55 +598,57 @@ static ssize_t n_hdlc_tty_read(struct tty_struct *tty, struct file *file, return -EFAULT; } - add_wait_queue(&tty->read_wait, &wait); + tty_lock(); for (;;) { if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) { - ret = -EIO; - break; + tty_unlock(); + return -EIO; } - if (tty_hung_up_p(file)) - break; - set_current_state(TASK_INTERRUPTIBLE); + n_hdlc = tty2n_hdlc (tty); + if (!n_hdlc || n_hdlc->magic != HDLC_MAGIC || + tty != n_hdlc->tty) { + tty_unlock(); + return 0; + } rbuf = n_hdlc_buf_get(&n_hdlc->rx_buf_list); - if (rbuf) { - if (rbuf->count > nr) { - /* too large for caller's buffer */ - ret = -EOVERFLOW; - } else { - if (copy_to_user(buf, rbuf->buf, rbuf->count)) - ret = -EFAULT; - else - ret = rbuf->count; - } - - if (n_hdlc->rx_free_buf_list.count > - DEFAULT_RX_BUF_COUNT) - kfree(rbuf); - else - n_hdlc_buf_put(&n_hdlc->rx_free_buf_list, rbuf); + if (rbuf) break; - } /* no data */ if (file->f_flags & O_NONBLOCK) { - ret = -EAGAIN; - break; + tty_unlock(); + return -EAGAIN; } - - schedule(); - + + interruptible_sleep_on (&tty->read_wait); if (signal_pending(current)) { - ret = -EINTR; - break; + tty_unlock(); + return -EINTR; } } - - remove_wait_queue(&tty->read_wait, &wait); - __set_current_state(TASK_RUNNING); - + + if (rbuf->count > nr) + /* frame too large for caller's buffer (discard frame) */ + ret = -EOVERFLOW; + else { + /* Copy the data to the caller's buffer */ + if (copy_to_user(buf, rbuf->buf, rbuf->count)) + ret = -EFAULT; + else + ret = rbuf->count; + } + + /* return HDLC buffer to free list unless the free list */ + /* count has exceeded the default value, in which case the */ + /* buffer is freed back to the OS to conserve memory */ + if (n_hdlc->rx_free_buf_list.count > DEFAULT_RX_BUF_COUNT) + kfree(rbuf); + else + n_hdlc_buf_put(&n_hdlc->rx_free_buf_list,rbuf); + tty_unlock(); return ret; } /* end of n_hdlc_tty_read() */ @@ -690,15 +691,14 @@ static ssize_t n_hdlc_tty_write(struct tty_struct *tty, struct file *file, count = maxframe; } - add_wait_queue(&tty->write_wait, &wait); + tty_lock(); - for (;;) { - set_current_state(TASK_INTERRUPTIBLE); + add_wait_queue(&tty->write_wait, &wait); + set_current_state(TASK_INTERRUPTIBLE); - tbuf = n_hdlc_buf_get(&n_hdlc->tx_free_buf_list); - if (tbuf) - break; - + /* Allocate transmit buffer */ + /* sleep until transmit buffer available */ + while (!(tbuf = n_hdlc_buf_get(&n_hdlc->tx_free_buf_list))) { if (file->f_flags & O_NONBLOCK) { error = -EAGAIN; break; @@ -719,7 +719,7 @@ static ssize_t n_hdlc_tty_write(struct tty_struct *tty, struct file *file, } } - __set_current_state(TASK_RUNNING); + set_current_state(TASK_RUNNING); remove_wait_queue(&tty->write_wait, &wait); if (!error) { @@ -731,7 +731,7 @@ static ssize_t n_hdlc_tty_write(struct tty_struct *tty, struct file *file, n_hdlc_buf_put(&n_hdlc->tx_buf_list,tbuf); n_hdlc_send_frames(n_hdlc,tty); } - + tty_unlock(); return error; } /* end of n_hdlc_tty_write() */ diff --git a/trunk/drivers/tty/serial/8250.c b/trunk/drivers/tty/serial/8250.c index 3975df6f7fdb..b25e6e490530 100644 --- a/trunk/drivers/tty/serial/8250.c +++ b/trunk/drivers/tty/serial/8250.c @@ -236,8 +236,7 @@ static const struct serial8250_config uart_config[] = { .fifo_size = 128, .tx_loadsz = 128, .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, - /* UART_CAP_EFR breaks billionon CF bluetooth card. */ - .flags = UART_CAP_FIFO | UART_CAP_SLEEP, + .flags = UART_CAP_FIFO | UART_CAP_EFR | UART_CAP_SLEEP, }, [PORT_16654] = { .name = "ST16654", diff --git a/trunk/drivers/tty/serial/Kconfig b/trunk/drivers/tty/serial/Kconfig index 2b8334601c8b..b1682d7f1d8a 100644 --- a/trunk/drivers/tty/serial/Kconfig +++ b/trunk/drivers/tty/serial/Kconfig @@ -1518,7 +1518,6 @@ config SERIAL_BCM63XX_CONSOLE config SERIAL_GRLIB_GAISLER_APBUART tristate "GRLIB APBUART serial support" depends on OF - select SERIAL_CORE ---help--- Add support for the GRLIB APBUART serial port. diff --git a/trunk/drivers/tty/tty_io.c b/trunk/drivers/tty/tty_io.c index 0065da4b11c1..6158eae0f64a 100644 --- a/trunk/drivers/tty/tty_io.c +++ b/trunk/drivers/tty/tty_io.c @@ -3257,7 +3257,7 @@ static ssize_t show_cons_active(struct device *dev, ssize_t count = 0; console_lock(); - for_each_console(c) { + for (c = console_drivers; c; c = c->next) { if (!c->device) continue; if (!c->write) @@ -3306,7 +3306,7 @@ int __init tty_init(void) if (IS_ERR(consdev)) consdev = NULL; else - WARN_ON(device_create_file(consdev, &dev_attr_active) < 0); + device_create_file(consdev, &dev_attr_active); #ifdef CONFIG_VT vty_init(&console_fops); diff --git a/trunk/drivers/tty/vt/vt.c b/trunk/drivers/tty/vt/vt.c index 147ede3423df..b230bd3f056f 100644 --- a/trunk/drivers/tty/vt/vt.c +++ b/trunk/drivers/tty/vt/vt.c @@ -2994,7 +2994,7 @@ int __init vty_init(const struct file_operations *console_fops) if (IS_ERR(tty0dev)) tty0dev = NULL; else - WARN_ON(device_create_file(tty0dev, &dev_attr_active) < 0); + device_create_file(tty0dev, &dev_attr_active); vcs_init(); @@ -3545,7 +3545,7 @@ int register_con_driver(const struct consw *csw, int first, int last) /* already registered */ if (con_driver->con == csw) - retval = -EBUSY; + retval = -EINVAL; } if (retval) @@ -3656,12 +3656,7 @@ int take_over_console(const struct consw *csw, int first, int last, int deflt) int err; err = register_con_driver(csw, first, last); - /* if we get an busy error we still want to bind the console driver - * and return success, as we may have unbound the console driver -  * but not unregistered it. - */ - if (err == -EBUSY) - err = 0; + if (!err) bind_con_driver(csw, first, last, deflt); diff --git a/trunk/drivers/usb/class/cdc-wdm.c b/trunk/drivers/usb/class/cdc-wdm.c index 47085e5879ab..6ee4451bfe2d 100644 --- a/trunk/drivers/usb/class/cdc-wdm.c +++ b/trunk/drivers/usb/class/cdc-wdm.c @@ -342,7 +342,7 @@ static ssize_t wdm_write goto outnp; } - if (!(file->f_flags & O_NONBLOCK)) + if (!file->f_flags && O_NONBLOCK) r = wait_event_interruptible(desc->wait, !test_bit(WDM_IN_USE, &desc->flags)); else diff --git a/trunk/drivers/usb/core/endpoint.c b/trunk/drivers/usb/core/endpoint.c index df502a98d0df..9da250563027 100644 --- a/trunk/drivers/usb/core/endpoint.c +++ b/trunk/drivers/usb/core/endpoint.c @@ -192,12 +192,12 @@ int usb_create_ep_devs(struct device *parent, ep_dev->dev.parent = parent; ep_dev->dev.release = ep_device_release; dev_set_name(&ep_dev->dev, "ep_%02x", endpoint->desc.bEndpointAddress); + device_enable_async_suspend(&ep_dev->dev); retval = device_register(&ep_dev->dev); if (retval) goto error_register; - device_enable_async_suspend(&ep_dev->dev); endpoint->ep_dev = ep_dev; return retval; diff --git a/trunk/drivers/usb/core/hcd-pci.c b/trunk/drivers/usb/core/hcd-pci.c index f71e8e307e0f..b55d46070a25 100644 --- a/trunk/drivers/usb/core/hcd-pci.c +++ b/trunk/drivers/usb/core/hcd-pci.c @@ -405,12 +405,7 @@ static int suspend_common(struct device *dev, bool do_wakeup) return retval; } - /* If MSI-X is enabled, the driver will have synchronized all vectors - * in pci_suspend(). If MSI or legacy PCI is enabled, that will be - * synchronized here. - */ - if (!hcd->msix_enabled) - synchronize_irq(pci_dev->irq); + synchronize_irq(pci_dev->irq); /* Downstream ports from this root hub should already be quiesced, so * there will be no DMA activity. Now we can shut down the upstream diff --git a/trunk/drivers/usb/core/hub.c b/trunk/drivers/usb/core/hub.c index 4310cc4b1cb5..b98efae6a1cf 100644 --- a/trunk/drivers/usb/core/hub.c +++ b/trunk/drivers/usb/core/hub.c @@ -676,8 +676,6 @@ static void hub_init_func3(struct work_struct *ws); static void hub_activate(struct usb_hub *hub, enum hub_activation_type type) { struct usb_device *hdev = hub->hdev; - struct usb_hcd *hcd; - int ret; int port1; int status; bool need_debounce_delay = false; @@ -716,25 +714,6 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type) usb_autopm_get_interface_no_resume( to_usb_interface(hub->intfdev)); return; /* Continues at init2: below */ - } else if (type == HUB_RESET_RESUME) { - /* The internal host controller state for the hub device - * may be gone after a host power loss on system resume. - * Update the device's info so the HW knows it's a hub. - */ - hcd = bus_to_hcd(hdev->bus); - if (hcd->driver->update_hub_device) { - ret = hcd->driver->update_hub_device(hcd, hdev, - &hub->tt, GFP_NOIO); - if (ret < 0) { - dev_err(hub->intfdev, "Host not " - "accepting hub info " - "update.\n"); - dev_err(hub->intfdev, "LS/FS devices " - "and hubs may not work " - "under this hub\n."); - } - } - hub_power_on(hub, true); } else { hub_power_on(hub, true); } diff --git a/trunk/drivers/usb/gadget/Kconfig b/trunk/drivers/usb/gadget/Kconfig index 06bb9d4587e9..1dc9739277b4 100644 --- a/trunk/drivers/usb/gadget/Kconfig +++ b/trunk/drivers/usb/gadget/Kconfig @@ -509,7 +509,7 @@ config USB_LANGWELL select USB_GADGET_SELECTED config USB_GADGET_EG20T - boolean "Intel EG20T PCH/OKI SEMICONDUCTOR ML7213 IOH UDC" + boolean "Intel EG20T(Topcliff) USB Device controller" depends on PCI select USB_GADGET_DUALSPEED help @@ -525,11 +525,6 @@ config USB_GADGET_EG20T This driver dose not support interrupt transfer or isochronous transfer modes. - This driver also can be used for OKI SEMICONDUCTOR's ML7213 which is - for IVI(In-Vehicle Infotainment) use. - ML7213 is companion chip for Intel Atom E6xx series. - ML7213 is completely compatible for Intel EG20T PCH. - config USB_EG20T tristate depends on USB_GADGET_EG20T diff --git a/trunk/drivers/usb/gadget/ci13xxx_udc.c b/trunk/drivers/usb/gadget/ci13xxx_udc.c index a1c67ae1572a..31656a2b4ab4 100644 --- a/trunk/drivers/usb/gadget/ci13xxx_udc.c +++ b/trunk/drivers/usb/gadget/ci13xxx_udc.c @@ -76,21 +76,10 @@ static DEFINE_SPINLOCK(udc_lock); /* control endpoint description */ static const struct usb_endpoint_descriptor -ctrl_endpt_out_desc = { +ctrl_endpt_desc = { .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, - .bEndpointAddress = USB_DIR_OUT, - .bmAttributes = USB_ENDPOINT_XFER_CONTROL, - .wMaxPacketSize = cpu_to_le16(CTRL_PAYLOAD_MAX), -}; - -static const struct usb_endpoint_descriptor -ctrl_endpt_in_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, - - .bEndpointAddress = USB_DIR_IN, .bmAttributes = USB_ENDPOINT_XFER_CONTROL, .wMaxPacketSize = cpu_to_le16(CTRL_PAYLOAD_MAX), }; @@ -276,11 +265,11 @@ static int hw_device_init(void __iomem *base) hw_bank.size /= sizeof(u32); reg = hw_aread(ABS_DCCPARAMS, DCCPARAMS_DEN) >> ffs_nr(DCCPARAMS_DEN); - hw_ep_max = reg * 2; /* cache hw ENDPT_MAX */ - - if (hw_ep_max == 0 || hw_ep_max > ENDPT_MAX) + if (reg == 0 || reg > ENDPT_MAX) return -ENODEV; + hw_ep_max = reg; /* cache hw ENDPT_MAX */ + /* setup lock mode ? */ /* ENDPTSETUPSTAT is '0' by default */ @@ -1208,17 +1197,16 @@ static ssize_t show_qheads(struct device *dev, struct device_attribute *attr, } spin_lock_irqsave(udc->lock, flags); - for (i = 0; i < hw_ep_max/2; i++) { - struct ci13xxx_ep *mEpRx = &udc->ci13xxx_ep[i]; - struct ci13xxx_ep *mEpTx = &udc->ci13xxx_ep[i + hw_ep_max/2]; + for (i = 0; i < hw_ep_max; i++) { + struct ci13xxx_ep *mEp = &udc->ci13xxx_ep[i]; n += scnprintf(buf + n, PAGE_SIZE - n, "EP=%02i: RX=%08X TX=%08X\n", - i, (u32)mEpRx->qh.dma, (u32)mEpTx->qh.dma); + i, (u32)mEp->qh[RX].dma, (u32)mEp->qh[TX].dma); for (j = 0; j < (sizeof(struct ci13xxx_qh)/sizeof(u32)); j++) { n += scnprintf(buf + n, PAGE_SIZE - n, " %04X: %08X %08X\n", j, - *((u32 *)mEpRx->qh.ptr + j), - *((u32 *)mEpTx->qh.ptr + j)); + *((u32 *)mEp->qh[RX].ptr + j), + *((u32 *)mEp->qh[TX].ptr + j)); } } spin_unlock_irqrestore(udc->lock, flags); @@ -1305,7 +1293,7 @@ static ssize_t show_requests(struct device *dev, struct device_attribute *attr, unsigned long flags; struct list_head *ptr = NULL; struct ci13xxx_req *req = NULL; - unsigned i, j, n = 0, qSize = sizeof(struct ci13xxx_td)/sizeof(u32); + unsigned i, j, k, n = 0, qSize = sizeof(struct ci13xxx_td)/sizeof(u32); dbg_trace("[%s] %p\n", __func__, buf); if (attr == NULL || buf == NULL) { @@ -1315,20 +1303,22 @@ static ssize_t show_requests(struct device *dev, struct device_attribute *attr, spin_lock_irqsave(udc->lock, flags); for (i = 0; i < hw_ep_max; i++) - list_for_each(ptr, &udc->ci13xxx_ep[i].qh.queue) - { - req = list_entry(ptr, struct ci13xxx_req, queue); - - n += scnprintf(buf + n, PAGE_SIZE - n, - "EP=%02i: TD=%08X %s\n", - i % hw_ep_max/2, (u32)req->dma, - ((i < hw_ep_max/2) ? "RX" : "TX")); + for (k = RX; k <= TX; k++) + list_for_each(ptr, &udc->ci13xxx_ep[i].qh[k].queue) + { + req = list_entry(ptr, + struct ci13xxx_req, queue); - for (j = 0; j < qSize; j++) n += scnprintf(buf + n, PAGE_SIZE - n, - " %04X: %08X\n", j, - *((u32 *)req->ptr + j)); - } + "EP=%02i: TD=%08X %s\n", + i, (u32)req->dma, + ((k == RX) ? "RX" : "TX")); + + for (j = 0; j < qSize; j++) + n += scnprintf(buf + n, PAGE_SIZE - n, + " %04X: %08X\n", j, + *((u32 *)req->ptr + j)); + } spin_unlock_irqrestore(udc->lock, flags); return n; @@ -1477,12 +1467,12 @@ static int _hardware_enqueue(struct ci13xxx_ep *mEp, struct ci13xxx_req *mReq) * At this point it's guaranteed exclusive access to qhead * (endpt is not primed) so it's no need to use tripwire */ - mEp->qh.ptr->td.next = mReq->dma; /* TERMINATE = 0 */ - mEp->qh.ptr->td.token &= ~TD_STATUS; /* clear status */ + mEp->qh[mEp->dir].ptr->td.next = mReq->dma; /* TERMINATE = 0 */ + mEp->qh[mEp->dir].ptr->td.token &= ~TD_STATUS; /* clear status */ if (mReq->req.zero == 0) - mEp->qh.ptr->cap |= QH_ZLT; + mEp->qh[mEp->dir].ptr->cap |= QH_ZLT; else - mEp->qh.ptr->cap &= ~QH_ZLT; + mEp->qh[mEp->dir].ptr->cap &= ~QH_ZLT; wmb(); /* synchronize before ep prime */ @@ -1552,11 +1542,11 @@ __acquires(mEp->lock) hw_ep_flush(mEp->num, mEp->dir); - while (!list_empty(&mEp->qh.queue)) { + while (!list_empty(&mEp->qh[mEp->dir].queue)) { /* pop oldest request */ struct ci13xxx_req *mReq = \ - list_entry(mEp->qh.queue.next, + list_entry(mEp->qh[mEp->dir].queue.next, struct ci13xxx_req, queue); list_del_init(&mReq->queue); mReq->req.status = -ESHUTDOWN; @@ -1581,6 +1571,8 @@ static int _gadget_stop_activity(struct usb_gadget *gadget) { struct usb_ep *ep; struct ci13xxx *udc = container_of(gadget, struct ci13xxx, gadget); + struct ci13xxx_ep *mEp = container_of(gadget->ep0, + struct ci13xxx_ep, ep); trace("%p", gadget); @@ -1591,8 +1583,7 @@ static int _gadget_stop_activity(struct usb_gadget *gadget) gadget_for_each_ep(ep, gadget) { usb_ep_fifo_flush(ep); } - usb_ep_fifo_flush(&udc->ep0out.ep); - usb_ep_fifo_flush(&udc->ep0in.ep); + usb_ep_fifo_flush(gadget->ep0); udc->driver->disconnect(gadget); @@ -1600,12 +1591,11 @@ static int _gadget_stop_activity(struct usb_gadget *gadget) gadget_for_each_ep(ep, gadget) { usb_ep_disable(ep); } - usb_ep_disable(&udc->ep0out.ep); - usb_ep_disable(&udc->ep0in.ep); + usb_ep_disable(gadget->ep0); - if (udc->status != NULL) { - usb_ep_free_request(&udc->ep0in.ep, udc->status); - udc->status = NULL; + if (mEp->status != NULL) { + usb_ep_free_request(gadget->ep0, mEp->status); + mEp->status = NULL; } return 0; @@ -1624,6 +1614,7 @@ static void isr_reset_handler(struct ci13xxx *udc) __releases(udc->lock) __acquires(udc->lock) { + struct ci13xxx_ep *mEp = &udc->ci13xxx_ep[0]; int retval; trace("%p", udc); @@ -1644,15 +1635,11 @@ __acquires(udc->lock) if (retval) goto done; - retval = usb_ep_enable(&udc->ep0out.ep, &ctrl_endpt_out_desc); - if (retval) - goto done; - - retval = usb_ep_enable(&udc->ep0in.ep, &ctrl_endpt_in_desc); + retval = usb_ep_enable(&mEp->ep, &ctrl_endpt_desc); if (!retval) { - udc->status = usb_ep_alloc_request(&udc->ep0in.ep, GFP_ATOMIC); - if (udc->status == NULL) { - usb_ep_disable(&udc->ep0out.ep); + mEp->status = usb_ep_alloc_request(&mEp->ep, GFP_ATOMIC); + if (mEp->status == NULL) { + usb_ep_disable(&mEp->ep); retval = -ENOMEM; } } @@ -1685,17 +1672,16 @@ static void isr_get_status_complete(struct usb_ep *ep, struct usb_request *req) /** * isr_get_status_response: get_status request response - * @udc: udc struct + * @ep: endpoint * @setup: setup request packet * * This function returns an error code */ -static int isr_get_status_response(struct ci13xxx *udc, +static int isr_get_status_response(struct ci13xxx_ep *mEp, struct usb_ctrlrequest *setup) __releases(mEp->lock) __acquires(mEp->lock) { - struct ci13xxx_ep *mEp = &udc->ep0in; struct usb_request *req = NULL; gfp_t gfp_flags = GFP_ATOMIC; int dir, num, retval; @@ -1750,23 +1736,27 @@ __acquires(mEp->lock) /** * isr_setup_status_phase: queues the status phase of a setup transation - * @udc: udc struct + * @mEp: endpoint * * This function returns an error code */ -static int isr_setup_status_phase(struct ci13xxx *udc) +static int isr_setup_status_phase(struct ci13xxx_ep *mEp) __releases(mEp->lock) __acquires(mEp->lock) { int retval; - struct ci13xxx_ep *mEp; - trace("%p", udc); + trace("%p", mEp); + + /* mEp is always valid & configured */ - mEp = (udc->ep0_dir == TX) ? &udc->ep0out : &udc->ep0in; + if (mEp->type == USB_ENDPOINT_XFER_CONTROL) + mEp->dir = (mEp->dir == TX) ? RX : TX; + + mEp->status->no_interrupt = 1; spin_unlock(mEp->lock); - retval = usb_ep_queue(&mEp->ep, udc->status, GFP_ATOMIC); + retval = usb_ep_queue(&mEp->ep, mEp->status, GFP_ATOMIC); spin_lock(mEp->lock); return retval; @@ -1788,11 +1778,11 @@ __acquires(mEp->lock) trace("%p", mEp); - if (list_empty(&mEp->qh.queue)) + if (list_empty(&mEp->qh[mEp->dir].queue)) return -EINVAL; /* pop oldest request */ - mReq = list_entry(mEp->qh.queue.next, + mReq = list_entry(mEp->qh[mEp->dir].queue.next, struct ci13xxx_req, queue); list_del_init(&mReq->queue); @@ -1804,10 +1794,10 @@ __acquires(mEp->lock) dbg_done(_usb_addr(mEp), mReq->ptr->token, retval); - if (!list_empty(&mEp->qh.queue)) { + if (!list_empty(&mEp->qh[mEp->dir].queue)) { struct ci13xxx_req* mReqEnq; - mReqEnq = list_entry(mEp->qh.queue.next, + mReqEnq = list_entry(mEp->qh[mEp->dir].queue.next, struct ci13xxx_req, queue); _hardware_enqueue(mEp, mReqEnq); } @@ -1846,14 +1836,16 @@ __acquires(udc->lock) int type, num, err = -EINVAL; struct usb_ctrlrequest req; + if (mEp->desc == NULL) continue; /* not configured */ - if (hw_test_and_clear_complete(i)) { + if ((mEp->dir == RX && hw_test_and_clear_complete(i)) || + (mEp->dir == TX && hw_test_and_clear_complete(i + 16))) { err = isr_tr_complete_low(mEp); if (mEp->type == USB_ENDPOINT_XFER_CONTROL) { if (err > 0) /* needs status phase */ - err = isr_setup_status_phase(udc); + err = isr_setup_status_phase(mEp); if (err < 0) { dbg_event(_usb_addr(mEp), "ERROR", err); @@ -1874,22 +1866,15 @@ __acquires(udc->lock) continue; } - /* - * Flush data and handshake transactions of previous - * setup packet. - */ - _ep_nuke(&udc->ep0out); - _ep_nuke(&udc->ep0in); - /* read_setup_packet */ do { hw_test_and_set_setup_guard(); - memcpy(&req, &mEp->qh.ptr->setup, sizeof(req)); + memcpy(&req, &mEp->qh[RX].ptr->setup, sizeof(req)); } while (!hw_test_and_clear_setup_guard()); type = req.bRequestType; - udc->ep0_dir = (type & USB_DIR_IN) ? TX : RX; + mEp->dir = (type & USB_DIR_IN) ? TX : RX; dbg_setup(_usb_addr(mEp), &req); @@ -1910,7 +1895,7 @@ __acquires(udc->lock) if (err) break; } - err = isr_setup_status_phase(udc); + err = isr_setup_status_phase(mEp); break; case USB_REQ_GET_STATUS: if (type != (USB_DIR_IN|USB_RECIP_DEVICE) && @@ -1920,7 +1905,7 @@ __acquires(udc->lock) if (le16_to_cpu(req.wLength) != 2 || le16_to_cpu(req.wValue) != 0) break; - err = isr_get_status_response(udc, &req); + err = isr_get_status_response(mEp, &req); break; case USB_REQ_SET_ADDRESS: if (type != (USB_DIR_OUT|USB_RECIP_DEVICE)) @@ -1931,7 +1916,7 @@ __acquires(udc->lock) err = hw_usb_set_address((u8)le16_to_cpu(req.wValue)); if (err) break; - err = isr_setup_status_phase(udc); + err = isr_setup_status_phase(mEp); break; case USB_REQ_SET_FEATURE: if (type != (USB_DIR_OUT|USB_RECIP_ENDPOINT) && @@ -1947,12 +1932,12 @@ __acquires(udc->lock) spin_lock(udc->lock); if (err) break; - err = isr_setup_status_phase(udc); + err = isr_setup_status_phase(mEp); break; default: delegate: if (req.wLength == 0) /* no data phase */ - udc->ep0_dir = TX; + mEp->dir = TX; spin_unlock(udc->lock); err = udc->driver->setup(&udc->gadget, &req); @@ -1983,7 +1968,7 @@ static int ep_enable(struct usb_ep *ep, const struct usb_endpoint_descriptor *desc) { struct ci13xxx_ep *mEp = container_of(ep, struct ci13xxx_ep, ep); - int retval = 0; + int direction, retval = 0; unsigned long flags; trace("%p, %p", ep, desc); @@ -1997,7 +1982,7 @@ static int ep_enable(struct usb_ep *ep, mEp->desc = desc; - if (!list_empty(&mEp->qh.queue)) + if (!list_empty(&mEp->qh[mEp->dir].queue)) warn("enabling a non-empty endpoint!"); mEp->dir = usb_endpoint_dir_in(desc) ? TX : RX; @@ -2006,22 +1991,29 @@ static int ep_enable(struct usb_ep *ep, mEp->ep.maxpacket = __constant_le16_to_cpu(desc->wMaxPacketSize); - dbg_event(_usb_addr(mEp), "ENABLE", 0); + direction = mEp->dir; + do { + dbg_event(_usb_addr(mEp), "ENABLE", 0); - mEp->qh.ptr->cap = 0; + mEp->qh[mEp->dir].ptr->cap = 0; - if (mEp->type == USB_ENDPOINT_XFER_CONTROL) - mEp->qh.ptr->cap |= QH_IOS; - else if (mEp->type == USB_ENDPOINT_XFER_ISOC) - mEp->qh.ptr->cap &= ~QH_MULT; - else - mEp->qh.ptr->cap &= ~QH_ZLT; + if (mEp->type == USB_ENDPOINT_XFER_CONTROL) + mEp->qh[mEp->dir].ptr->cap |= QH_IOS; + else if (mEp->type == USB_ENDPOINT_XFER_ISOC) + mEp->qh[mEp->dir].ptr->cap &= ~QH_MULT; + else + mEp->qh[mEp->dir].ptr->cap &= ~QH_ZLT; + + mEp->qh[mEp->dir].ptr->cap |= + (mEp->ep.maxpacket << ffs_nr(QH_MAX_PKT)) & QH_MAX_PKT; + mEp->qh[mEp->dir].ptr->td.next |= TD_TERMINATE; /* needed? */ - mEp->qh.ptr->cap |= - (mEp->ep.maxpacket << ffs_nr(QH_MAX_PKT)) & QH_MAX_PKT; - mEp->qh.ptr->td.next |= TD_TERMINATE; /* needed? */ + retval |= hw_ep_enable(mEp->num, mEp->dir, mEp->type); + + if (mEp->type == USB_ENDPOINT_XFER_CONTROL) + mEp->dir = (mEp->dir == TX) ? RX : TX; - retval |= hw_ep_enable(mEp->num, mEp->dir, mEp->type); + } while (mEp->dir != direction); spin_unlock_irqrestore(mEp->lock, flags); return retval; @@ -2154,7 +2146,7 @@ static int ep_queue(struct usb_ep *ep, struct usb_request *req, spin_lock_irqsave(mEp->lock, flags); if (mEp->type == USB_ENDPOINT_XFER_CONTROL && - !list_empty(&mEp->qh.queue)) { + !list_empty(&mEp->qh[mEp->dir].queue)) { _ep_nuke(mEp); retval = -EOVERFLOW; warn("endpoint ctrl %X nuked", _usb_addr(mEp)); @@ -2178,9 +2170,9 @@ static int ep_queue(struct usb_ep *ep, struct usb_request *req, /* push request */ mReq->req.status = -EINPROGRESS; mReq->req.actual = 0; - list_add_tail(&mReq->queue, &mEp->qh.queue); + list_add_tail(&mReq->queue, &mEp->qh[mEp->dir].queue); - if (list_is_singular(&mEp->qh.queue)) + if (list_is_singular(&mEp->qh[mEp->dir].queue)) retval = _hardware_enqueue(mEp, mReq); if (retval == -EALREADY) { @@ -2207,7 +2199,7 @@ static int ep_dequeue(struct usb_ep *ep, struct usb_request *req) trace("%p, %p", ep, req); if (ep == NULL || req == NULL || mEp->desc == NULL || - list_empty(&mReq->queue) || list_empty(&mEp->qh.queue)) + list_empty(&mReq->queue) || list_empty(&mEp->qh[mEp->dir].queue)) return -EINVAL; spin_lock_irqsave(mEp->lock, flags); @@ -2252,7 +2244,7 @@ static int ep_set_halt(struct usb_ep *ep, int value) #ifndef STALL_IN /* g_file_storage MS compliant but g_zero fails chapter 9 compliance */ if (value && mEp->type == USB_ENDPOINT_XFER_BULK && mEp->dir == TX && - !list_empty(&mEp->qh.queue)) { + !list_empty(&mEp->qh[mEp->dir].queue)) { spin_unlock_irqrestore(mEp->lock, flags); return -EAGAIN; } @@ -2363,7 +2355,7 @@ static int ci13xxx_vbus_session(struct usb_gadget *_gadget, int is_active) if (is_active) { pm_runtime_get_sync(&_gadget->dev); hw_device_reset(udc); - hw_device_state(udc->ep0out.qh.dma); + hw_device_state(udc->ci13xxx_ep[0].qh[RX].dma); } else { hw_device_state(0); if (udc->udc_driver->notify_event) @@ -2398,8 +2390,7 @@ int usb_gadget_probe_driver(struct usb_gadget_driver *driver, int (*bind)(struct usb_gadget *)) { struct ci13xxx *udc = _udc; - unsigned long flags; - int i, j; + unsigned long i, k, flags; int retval = -ENOMEM; trace("%p", driver); @@ -2436,46 +2427,45 @@ int usb_gadget_probe_driver(struct usb_gadget_driver *driver, info("hw_ep_max = %d", hw_ep_max); + udc->driver = driver; udc->gadget.dev.driver = NULL; retval = 0; - for (i = 0; i < hw_ep_max/2; i++) { - for (j = RX; j <= TX; j++) { - int k = i + j * hw_ep_max/2; - struct ci13xxx_ep *mEp = &udc->ci13xxx_ep[k]; + for (i = 0; i < hw_ep_max; i++) { + struct ci13xxx_ep *mEp = &udc->ci13xxx_ep[i]; - scnprintf(mEp->name, sizeof(mEp->name), "ep%i%s", i, - (j == TX) ? "in" : "out"); + scnprintf(mEp->name, sizeof(mEp->name), "ep%i", (int)i); - mEp->lock = udc->lock; - mEp->device = &udc->gadget.dev; - mEp->td_pool = udc->td_pool; + mEp->lock = udc->lock; + mEp->device = &udc->gadget.dev; + mEp->td_pool = udc->td_pool; - mEp->ep.name = mEp->name; - mEp->ep.ops = &usb_ep_ops; - mEp->ep.maxpacket = CTRL_PAYLOAD_MAX; + mEp->ep.name = mEp->name; + mEp->ep.ops = &usb_ep_ops; + mEp->ep.maxpacket = CTRL_PAYLOAD_MAX; - INIT_LIST_HEAD(&mEp->qh.queue); + /* this allocation cannot be random */ + for (k = RX; k <= TX; k++) { + INIT_LIST_HEAD(&mEp->qh[k].queue); spin_unlock_irqrestore(udc->lock, flags); - mEp->qh.ptr = dma_pool_alloc(udc->qh_pool, GFP_KERNEL, - &mEp->qh.dma); + mEp->qh[k].ptr = dma_pool_alloc(udc->qh_pool, + GFP_KERNEL, + &mEp->qh[k].dma); spin_lock_irqsave(udc->lock, flags); - if (mEp->qh.ptr == NULL) + if (mEp->qh[k].ptr == NULL) retval = -ENOMEM; else - memset(mEp->qh.ptr, 0, sizeof(*mEp->qh.ptr)); - - /* skip ep0 out and in endpoints */ - if (i == 0) - continue; - - list_add_tail(&mEp->ep.ep_list, &udc->gadget.ep_list); + memset(mEp->qh[k].ptr, 0, + sizeof(*mEp->qh[k].ptr)); } + if (i == 0) + udc->gadget.ep0 = &mEp->ep; + else + list_add_tail(&mEp->ep.ep_list, &udc->gadget.ep_list); } if (retval) goto done; - udc->gadget.ep0 = &udc->ep0in.ep; /* bind gadget */ driver->driver.bus = NULL; udc->gadget.dev.driver = &driver->driver; @@ -2489,7 +2479,6 @@ int usb_gadget_probe_driver(struct usb_gadget_driver *driver, goto done; } - udc->driver = driver; pm_runtime_get_sync(&udc->gadget.dev); if (udc->udc_driver->flags & CI13XXX_PULLUP_ON_VBUS) { if (udc->vbus_active) { @@ -2501,12 +2490,14 @@ int usb_gadget_probe_driver(struct usb_gadget_driver *driver, } } - retval = hw_device_state(udc->ep0out.qh.dma); + retval = hw_device_state(udc->ci13xxx_ep[0].qh[RX].dma); if (retval) pm_runtime_put_sync(&udc->gadget.dev); done: spin_unlock_irqrestore(udc->lock, flags); + if (retval) + usb_gadget_unregister_driver(driver); return retval; } EXPORT_SYMBOL(usb_gadget_probe_driver); @@ -2519,7 +2510,7 @@ EXPORT_SYMBOL(usb_gadget_probe_driver); int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) { struct ci13xxx *udc = _udc; - unsigned long i, flags; + unsigned long i, k, flags; trace("%p", driver); @@ -2555,14 +2546,17 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) for (i = 0; i < hw_ep_max; i++) { struct ci13xxx_ep *mEp = &udc->ci13xxx_ep[i]; - if (!list_empty(&mEp->ep.ep_list)) + if (i == 0) + udc->gadget.ep0 = NULL; + else if (!list_empty(&mEp->ep.ep_list)) list_del_init(&mEp->ep.ep_list); - if (mEp->qh.ptr != NULL) - dma_pool_free(udc->qh_pool, mEp->qh.ptr, mEp->qh.dma); + for (k = RX; k <= TX; k++) + if (mEp->qh[k].ptr != NULL) + dma_pool_free(udc->qh_pool, + mEp->qh[k].ptr, mEp->qh[k].dma); } - udc->gadget.ep0 = NULL; udc->driver = NULL; spin_unlock_irqrestore(udc->lock, flags); diff --git a/trunk/drivers/usb/gadget/ci13xxx_udc.h b/trunk/drivers/usb/gadget/ci13xxx_udc.h index a2492b65f98c..f61fed07f76b 100644 --- a/trunk/drivers/usb/gadget/ci13xxx_udc.h +++ b/trunk/drivers/usb/gadget/ci13xxx_udc.h @@ -20,7 +20,7 @@ * DEFINE *****************************************************************************/ #define CI13XXX_PAGE_SIZE 4096ul /* page size for TD's */ -#define ENDPT_MAX (32) +#define ENDPT_MAX (16) #define CTRL_PAYLOAD_MAX (64) #define RX (0) /* similar to USB_DIR_OUT but can be used as an index */ #define TX (1) /* similar to USB_DIR_IN but can be used as an index */ @@ -88,7 +88,8 @@ struct ci13xxx_ep { struct list_head queue; struct ci13xxx_qh *ptr; dma_addr_t dma; - } qh; + } qh[2]; + struct usb_request *status; int wedge; /* global resources */ @@ -118,13 +119,9 @@ struct ci13xxx { struct dma_pool *qh_pool; /* DMA pool for queue heads */ struct dma_pool *td_pool; /* DMA pool for transfer descs */ - struct usb_request *status; /* ep0 status request */ struct usb_gadget gadget; /* USB slave device */ struct ci13xxx_ep ci13xxx_ep[ENDPT_MAX]; /* extended endpts */ - u32 ep0_dir; /* ep0 direction */ -#define ep0out ci13xxx_ep[0] -#define ep0in ci13xxx_ep[16] struct usb_gadget_driver *driver; /* 3rd party gadget driver */ struct ci13xxx_udc_driver *udc_driver; /* device controller driver */ diff --git a/trunk/drivers/usb/gadget/composite.c b/trunk/drivers/usb/gadget/composite.c index 1ba4befe336b..f6ff8456d52d 100644 --- a/trunk/drivers/usb/gadget/composite.c +++ b/trunk/drivers/usb/gadget/composite.c @@ -928,9 +928,8 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) */ switch (ctrl->bRequestType & USB_RECIP_MASK) { case USB_RECIP_INTERFACE: - if (!cdev->config || w_index >= MAX_CONFIG_INTERFACES) - break; - f = cdev->config->interface[intf]; + if (cdev->config) + f = cdev->config->interface[intf]; break; case USB_RECIP_ENDPOINT: diff --git a/trunk/drivers/usb/gadget/pch_udc.c b/trunk/drivers/usb/gadget/pch_udc.c index b120dbb64d0f..0c8dd81dddca 100644 --- a/trunk/drivers/usb/gadget/pch_udc.c +++ b/trunk/drivers/usb/gadget/pch_udc.c @@ -198,10 +198,10 @@ #define PCH_UDC_BRLEN 0x0F /* Burst length */ #define PCH_UDC_THLEN 0x1F /* Threshold length */ /* Value of EP Buffer Size */ -#define UDC_EP0IN_BUFF_SIZE 16 -#define UDC_EPIN_BUFF_SIZE 256 -#define UDC_EP0OUT_BUFF_SIZE 16 -#define UDC_EPOUT_BUFF_SIZE 256 +#define UDC_EP0IN_BUFF_SIZE 64 +#define UDC_EPIN_BUFF_SIZE 512 +#define UDC_EP0OUT_BUFF_SIZE 64 +#define UDC_EPOUT_BUFF_SIZE 512 /* Value of EP maximum packet size */ #define UDC_EP0IN_MAX_PKT_SIZE 64 #define UDC_EP0OUT_MAX_PKT_SIZE 64 @@ -351,7 +351,7 @@ struct pch_udc_dev { struct pci_pool *data_requests; struct pci_pool *stp_requests; dma_addr_t dma_addr; - void *ep0out_buf; + unsigned long ep0out_buf[64]; struct usb_ctrlrequest setup_data; unsigned long phys_addr; void __iomem *base_addr; @@ -361,8 +361,6 @@ struct pch_udc_dev { #define PCH_UDC_PCI_BAR 1 #define PCI_DEVICE_ID_INTEL_EG20T_UDC 0x8808 -#define PCI_VENDOR_ID_ROHM 0x10DB -#define PCI_DEVICE_ID_ML7213_IOH_UDC 0x801D static const char ep0_string[] = "ep0in"; static DEFINE_SPINLOCK(udc_stall_spinlock); /* stall spin lock */ @@ -1221,11 +1219,11 @@ static void complete_req(struct pch_udc_ep *ep, struct pch_udc_request *req, dev = ep->dev; if (req->dma_mapped) { if (ep->in) - dma_unmap_single(&dev->pdev->dev, req->req.dma, - req->req.length, DMA_TO_DEVICE); + pci_unmap_single(dev->pdev, req->req.dma, + req->req.length, PCI_DMA_TODEVICE); else - dma_unmap_single(&dev->pdev->dev, req->req.dma, - req->req.length, DMA_FROM_DEVICE); + pci_unmap_single(dev->pdev, req->req.dma, + req->req.length, PCI_DMA_FROMDEVICE); req->dma_mapped = 0; req->req.dma = DMA_ADDR_INVALID; } @@ -1416,6 +1414,7 @@ static void pch_udc_start_rxrequest(struct pch_udc_ep *ep, pch_udc_clear_dma(ep->dev, DMA_DIR_RX); td_data = req->td_data; + ep->td_data = req->td_data; /* Set the status bits for all descriptors */ while (1) { td_data->status = (td_data->status & ~PCH_UDC_BUFF_STS) | @@ -1614,19 +1613,15 @@ static int pch_udc_pcd_queue(struct usb_ep *usbep, struct usb_request *usbreq, if (usbreq->length && ((usbreq->dma == DMA_ADDR_INVALID) || !usbreq->dma)) { if (ep->in) - usbreq->dma = dma_map_single(&dev->pdev->dev, - usbreq->buf, - usbreq->length, - DMA_TO_DEVICE); + usbreq->dma = pci_map_single(dev->pdev, usbreq->buf, + usbreq->length, PCI_DMA_TODEVICE); else - usbreq->dma = dma_map_single(&dev->pdev->dev, - usbreq->buf, - usbreq->length, - DMA_FROM_DEVICE); + usbreq->dma = pci_map_single(dev->pdev, usbreq->buf, + usbreq->length, PCI_DMA_FROMDEVICE); req->dma_mapped = 1; } if (usbreq->length > 0) { - retval = prepare_dma(ep, req, GFP_ATOMIC); + retval = prepare_dma(ep, req, gfp); if (retval) goto probe_end; } @@ -1651,6 +1646,7 @@ static int pch_udc_pcd_queue(struct usb_ep *usbep, struct usb_request *usbreq, pch_udc_wait_ep_stall(ep); pch_udc_ep_clear_nak(ep); pch_udc_enable_ep_interrupts(ep->dev, (1 << ep->num)); + pch_udc_set_dma(dev, DMA_DIR_TX); } } /* Now add this request to the ep's pending requests */ @@ -1930,7 +1926,6 @@ static void pch_udc_complete_receiver(struct pch_udc_ep *ep) PCH_UDC_BS_DMA_DONE) return; pch_udc_clear_dma(ep->dev, DMA_DIR_RX); - pch_udc_ep_set_ddptr(ep, 0); if ((req->td_data_last->status & PCH_UDC_RXTX_STS) != PCH_UDC_RTS_SUCC) { dev_err(&dev->pdev->dev, "Invalid RXTX status (0x%08x) " @@ -1968,7 +1963,7 @@ static void pch_udc_svc_data_in(struct pch_udc_dev *dev, int ep_num) u32 epsts; struct pch_udc_ep *ep; - ep = &dev->ep[UDC_EPIN_IDX(ep_num)]; + ep = &dev->ep[2*ep_num]; epsts = ep->epsts; ep->epsts = 0; @@ -2013,7 +2008,7 @@ static void pch_udc_svc_data_out(struct pch_udc_dev *dev, int ep_num) struct pch_udc_ep *ep; struct pch_udc_request *req = NULL; - ep = &dev->ep[UDC_EPOUT_IDX(ep_num)]; + ep = &dev->ep[2*ep_num + 1]; epsts = ep->epsts; ep->epsts = 0; @@ -2030,11 +2025,10 @@ static void pch_udc_svc_data_out(struct pch_udc_dev *dev, int ep_num) } if (epsts & UDC_EPSTS_HE) return; - if (epsts & UDC_EPSTS_RSS) { + if (epsts & UDC_EPSTS_RSS) pch_udc_ep_set_stall(ep); pch_udc_enable_ep_interrupts(ep->dev, PCH_UDC_EPINT(ep->in, ep->num)); - } if (epsts & UDC_EPSTS_RCS) { if (!dev->prot_stall) { pch_udc_ep_clear_stall(ep); @@ -2066,10 +2060,8 @@ static void pch_udc_svc_control_in(struct pch_udc_dev *dev) { u32 epsts; struct pch_udc_ep *ep; - struct pch_udc_ep *ep_out; ep = &dev->ep[UDC_EP0IN_IDX]; - ep_out = &dev->ep[UDC_EP0OUT_IDX]; epsts = ep->epsts; ep->epsts = 0; @@ -2081,16 +2073,8 @@ static void pch_udc_svc_control_in(struct pch_udc_dev *dev) return; if (epsts & UDC_EPSTS_HE) return; - if ((epsts & UDC_EPSTS_TDC) && (!dev->stall)) { + if ((epsts & UDC_EPSTS_TDC) && (!dev->stall)) pch_udc_complete_transfer(ep); - pch_udc_clear_dma(dev, DMA_DIR_RX); - ep_out->td_data->status = (ep_out->td_data->status & - ~PCH_UDC_BUFF_STS) | - PCH_UDC_BS_HST_RDY; - pch_udc_ep_clear_nak(ep_out); - pch_udc_set_dma(dev, DMA_DIR_RX); - pch_udc_ep_set_rrdy(ep_out); - } /* On IN interrupt, provide data if we have any */ if ((epsts & UDC_EPSTS_IN) && !(epsts & UDC_EPSTS_TDC) && !(epsts & UDC_EPSTS_TXEMPTY)) @@ -2118,9 +2102,11 @@ static void pch_udc_svc_control_out(struct pch_udc_dev *dev) dev->stall = 0; dev->ep[UDC_EP0IN_IDX].halted = 0; dev->ep[UDC_EP0OUT_IDX].halted = 0; + /* In data not ready */ + pch_udc_ep_set_nak(&(dev->ep[UDC_EP0IN_IDX])); dev->setup_data = ep->td_stp->request; pch_udc_init_setup_buff(ep->td_stp); - pch_udc_clear_dma(dev, DMA_DIR_RX); + pch_udc_clear_dma(dev, DMA_DIR_TX); pch_udc_ep_fifo_flush(&(dev->ep[UDC_EP0IN_IDX]), dev->ep[UDC_EP0IN_IDX].in); if ((dev->setup_data.bRequestType & USB_DIR_IN)) @@ -2136,23 +2122,14 @@ static void pch_udc_svc_control_out(struct pch_udc_dev *dev) setup_supported = dev->driver->setup(&dev->gadget, &dev->setup_data); spin_lock(&dev->lock); - - if (dev->setup_data.bRequestType & USB_DIR_IN) { - ep->td_data->status = (ep->td_data->status & - ~PCH_UDC_BUFF_STS) | - PCH_UDC_BS_HST_RDY; - pch_udc_ep_set_ddptr(ep, ep->td_data_phys); - } /* ep0 in returns data on IN phase */ if (setup_supported >= 0 && setup_supported < UDC_EP0IN_MAX_PKT_SIZE) { pch_udc_ep_clear_nak(&(dev->ep[UDC_EP0IN_IDX])); /* Gadget would have queued a request when * we called the setup */ - if (!(dev->setup_data.bRequestType & USB_DIR_IN)) { - pch_udc_set_dma(dev, DMA_DIR_RX); - pch_udc_ep_clear_nak(ep); - } + pch_udc_set_dma(dev, DMA_DIR_RX); + pch_udc_ep_clear_nak(ep); } else if (setup_supported < 0) { /* if unsupported request, then stall */ pch_udc_ep_set_stall(&(dev->ep[UDC_EP0IN_IDX])); @@ -2165,13 +2142,22 @@ static void pch_udc_svc_control_out(struct pch_udc_dev *dev) } } else if ((((stat & UDC_EPSTS_OUT_MASK) >> UDC_EPSTS_OUT_SHIFT) == UDC_EPSTS_OUT_DATA) && !dev->stall) { - pch_udc_clear_dma(dev, DMA_DIR_RX); - pch_udc_ep_set_ddptr(ep, 0); - if (!list_empty(&ep->queue)) { + if (list_empty(&ep->queue)) { + dev_err(&dev->pdev->dev, "%s: No request\n", __func__); + ep->td_data->status = (ep->td_data->status & + ~PCH_UDC_BUFF_STS) | + PCH_UDC_BS_HST_RDY; + pch_udc_set_dma(dev, DMA_DIR_RX); + } else { + /* control write */ + /* next function will pickuo an clear the status */ ep->epsts = stat; - pch_udc_svc_data_out(dev, PCH_UDC_EP0); + + pch_udc_svc_data_out(dev, 0); + /* re-program desc. pointer for possible ZLPs */ + pch_udc_ep_set_ddptr(ep, ep->td_data_phys); + pch_udc_set_dma(dev, DMA_DIR_RX); } - pch_udc_set_dma(dev, DMA_DIR_RX); } pch_udc_ep_set_rrdy(ep); } @@ -2188,7 +2174,7 @@ static void pch_udc_postsvc_epinters(struct pch_udc_dev *dev, int ep_num) struct pch_udc_ep *ep; struct pch_udc_request *req; - ep = &dev->ep[UDC_EPIN_IDX(ep_num)]; + ep = &dev->ep[2*ep_num]; if (!list_empty(&ep->queue)) { req = list_entry(ep->queue.next, struct pch_udc_request, queue); pch_udc_enable_ep_interrupts(ep->dev, @@ -2210,13 +2196,13 @@ static void pch_udc_read_all_epstatus(struct pch_udc_dev *dev, u32 ep_intr) for (i = 0; i < PCH_UDC_USED_EP_NUM; i++) { /* IN */ if (ep_intr & (0x1 << i)) { - ep = &dev->ep[UDC_EPIN_IDX(i)]; + ep = &dev->ep[2*i]; ep->epsts = pch_udc_read_ep_status(ep); pch_udc_clear_ep_status(ep, ep->epsts); } /* OUT */ if (ep_intr & (0x10000 << i)) { - ep = &dev->ep[UDC_EPOUT_IDX(i)]; + ep = &dev->ep[2*i+1]; ep->epsts = pch_udc_read_ep_status(ep); pch_udc_clear_ep_status(ep, ep->epsts); } @@ -2577,6 +2563,9 @@ static void pch_udc_pcd_reinit(struct pch_udc_dev *dev) dev->ep[UDC_EP0IN_IDX].ep.maxpacket = UDC_EP0IN_MAX_PKT_SIZE; dev->ep[UDC_EP0OUT_IDX].ep.maxpacket = UDC_EP0OUT_MAX_PKT_SIZE; + dev->dma_addr = pci_map_single(dev->pdev, dev->ep0out_buf, 256, + PCI_DMA_FROMDEVICE); + /* remove ep0 in and out from the list. They have own pointer */ list_del_init(&dev->ep[UDC_EP0IN_IDX].ep.ep_list); list_del_init(&dev->ep[UDC_EP0OUT_IDX].ep.ep_list); @@ -2648,13 +2637,6 @@ static int init_dma_pools(struct pch_udc_dev *dev) dev->ep[UDC_EP0IN_IDX].td_stp_phys = 0; dev->ep[UDC_EP0IN_IDX].td_data = NULL; dev->ep[UDC_EP0IN_IDX].td_data_phys = 0; - - dev->ep0out_buf = kzalloc(UDC_EP0OUT_BUFF_SIZE * 4, GFP_KERNEL); - if (!dev->ep0out_buf) - return -ENOMEM; - dev->dma_addr = dma_map_single(&dev->pdev->dev, dev->ep0out_buf, - UDC_EP0OUT_BUFF_SIZE * 4, - DMA_FROM_DEVICE); return 0; } @@ -2718,8 +2700,7 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) pch_udc_disable_interrupts(dev, UDC_DEVINT_MSK); - /* Assures that there are no pending requests with this driver */ - driver->disconnect(&dev->gadget); + /* Assues that there are no pending requets with this driver */ driver->unbind(&dev->gadget); dev->gadget.dev.driver = NULL; dev->driver = NULL; @@ -2769,11 +2750,6 @@ static void pch_udc_remove(struct pci_dev *pdev) pci_pool_destroy(dev->stp_requests); } - if (dev->dma_addr) - dma_unmap_single(&dev->pdev->dev, dev->dma_addr, - UDC_EP0OUT_BUFF_SIZE * 4, DMA_FROM_DEVICE); - kfree(dev->ep0out_buf); - pch_udc_exit(dev); if (dev->irq_registered) @@ -2816,7 +2792,11 @@ static int pch_udc_resume(struct pci_dev *pdev) int ret; pci_set_power_state(pdev, PCI_D0); - pci_restore_state(pdev); + ret = pci_restore_state(pdev); + if (ret) { + dev_err(&pdev->dev, "%s: pci_restore_state failed\n", __func__); + return ret; + } ret = pci_enable_device(pdev); if (ret) { dev_err(&pdev->dev, "%s: pci_enable_device failed\n", __func__); @@ -2934,11 +2914,6 @@ static DEFINE_PCI_DEVICE_TABLE(pch_udc_pcidev_id) = { .class = (PCI_CLASS_SERIAL_USB << 8) | 0xfe, .class_mask = 0xffffffff, }, - { - PCI_DEVICE(PCI_VENDOR_ID_ROHM, PCI_DEVICE_ID_ML7213_IOH_UDC), - .class = (PCI_CLASS_SERIAL_USB << 8) | 0xfe, - .class_mask = 0xffffffff, - }, { 0 }, }; diff --git a/trunk/drivers/usb/gadget/printer.c b/trunk/drivers/usb/gadget/printer.c index 12ff6cffedc9..2fc8636316c5 100644 --- a/trunk/drivers/usb/gadget/printer.c +++ b/trunk/drivers/usb/gadget/printer.c @@ -131,31 +131,31 @@ static struct printer_dev usb_printer_gadget; * parameters are in UTF-8 (superset of ASCII's 7 bit characters). */ -static ushort idVendor; +static ushort __initdata idVendor; module_param(idVendor, ushort, S_IRUGO); MODULE_PARM_DESC(idVendor, "USB Vendor ID"); -static ushort idProduct; +static ushort __initdata idProduct; module_param(idProduct, ushort, S_IRUGO); MODULE_PARM_DESC(idProduct, "USB Product ID"); -static ushort bcdDevice; +static ushort __initdata bcdDevice; module_param(bcdDevice, ushort, S_IRUGO); MODULE_PARM_DESC(bcdDevice, "USB Device version (BCD)"); -static char *iManufacturer; +static char *__initdata iManufacturer; module_param(iManufacturer, charp, S_IRUGO); MODULE_PARM_DESC(iManufacturer, "USB Manufacturer string"); -static char *iProduct; +static char *__initdata iProduct; module_param(iProduct, charp, S_IRUGO); MODULE_PARM_DESC(iProduct, "USB Product string"); -static char *iSerialNum; +static char *__initdata iSerialNum; module_param(iSerialNum, charp, S_IRUGO); MODULE_PARM_DESC(iSerialNum, "1"); -static char *iPNPstring; +static char *__initdata iPNPstring; module_param(iPNPstring, charp, S_IRUGO); MODULE_PARM_DESC(iPNPstring, "MFG:linux;MDL:g_printer;CLS:PRINTER;SN:1;"); @@ -1596,12 +1596,13 @@ cleanup(void) int status; mutex_lock(&usb_printer_gadget.lock_printer_io); + class_destroy(usb_gadget_class); + unregister_chrdev_region(g_printer_devno, 2); + status = usb_gadget_unregister_driver(&printer_driver); if (status) ERROR(dev, "usb_gadget_unregister_driver %x\n", status); - unregister_chrdev_region(g_printer_devno, 2); - class_destroy(usb_gadget_class); mutex_unlock(&usb_printer_gadget.lock_printer_io); } module_exit(cleanup); diff --git a/trunk/drivers/usb/host/ehci-fsl.c b/trunk/drivers/usb/host/ehci-fsl.c index 5c761df7fa83..86e42892016d 100644 --- a/trunk/drivers/usb/host/ehci-fsl.c +++ b/trunk/drivers/usb/host/ehci-fsl.c @@ -52,6 +52,7 @@ static int usb_hcd_fsl_probe(const struct hc_driver *driver, struct resource *res; int irq; int retval; + unsigned int temp; pr_debug("initializing FSL-SOC USB Controller\n"); @@ -125,6 +126,18 @@ static int usb_hcd_fsl_probe(const struct hc_driver *driver, goto err3; } + /* + * Check if it is MPC5121 SoC, otherwise set pdata->have_sysif_regs + * flag for 83xx or 8536 system interface registers. + */ + if (pdata->big_endian_mmio) + temp = in_be32(hcd->regs + FSL_SOC_USB_ID); + else + temp = in_le32(hcd->regs + FSL_SOC_USB_ID); + + if ((temp & ID_MSK) != (~((temp & NID_MSK) >> 8) & ID_MSK)) + pdata->have_sysif_regs = 1; + /* Enable USB controller, 83xx or 8536 */ if (pdata->have_sysif_regs) setbits32(hcd->regs + FSL_SOC_USB_CTRL, 0x4); diff --git a/trunk/drivers/usb/host/ehci-fsl.h b/trunk/drivers/usb/host/ehci-fsl.h index 3fabed33d940..2c8353795226 100644 --- a/trunk/drivers/usb/host/ehci-fsl.h +++ b/trunk/drivers/usb/host/ehci-fsl.h @@ -19,6 +19,9 @@ #define _EHCI_FSL_H /* offsets for the non-ehci registers in the FSL SOC USB controller */ +#define FSL_SOC_USB_ID 0x0 +#define ID_MSK 0x3f +#define NID_MSK 0x3f00 #define FSL_SOC_USB_ULPIVP 0x170 #define FSL_SOC_USB_PORTSC1 0x184 #define PORT_PTS_MSK (3<<30) diff --git a/trunk/drivers/usb/host/ehci-hcd.c b/trunk/drivers/usb/host/ehci-hcd.c index 74dcf49bd015..6fee3cd58efe 100644 --- a/trunk/drivers/usb/host/ehci-hcd.c +++ b/trunk/drivers/usb/host/ehci-hcd.c @@ -572,8 +572,6 @@ static int ehci_init(struct usb_hcd *hcd) ehci->iaa_watchdog.function = ehci_iaa_watchdog; ehci->iaa_watchdog.data = (unsigned long) ehci; - hcc_params = ehci_readl(ehci, &ehci->caps->hcc_params); - /* * hw default: 1K periodic list heads, one per frame. * periodic_size can shrink by USBCMD update if hcc_params allows. @@ -581,20 +579,11 @@ static int ehci_init(struct usb_hcd *hcd) ehci->periodic_size = DEFAULT_I_TDPS; INIT_LIST_HEAD(&ehci->cached_itd_list); INIT_LIST_HEAD(&ehci->cached_sitd_list); - - if (HCC_PGM_FRAMELISTLEN(hcc_params)) { - /* periodic schedule size can be smaller than default */ - switch (EHCI_TUNE_FLS) { - case 0: ehci->periodic_size = 1024; break; - case 1: ehci->periodic_size = 512; break; - case 2: ehci->periodic_size = 256; break; - default: BUG(); - } - } if ((retval = ehci_mem_init(ehci, GFP_KERNEL)) < 0) return retval; /* controllers may cache some of the periodic schedule ... */ + hcc_params = ehci_readl(ehci, &ehci->caps->hcc_params); if (HCC_ISOC_CACHE(hcc_params)) // full frame cache ehci->i_thresh = 2 + 8; else // N microframes cached @@ -648,6 +637,12 @@ static int ehci_init(struct usb_hcd *hcd) /* periodic schedule size can be smaller than default */ temp &= ~(3 << 2); temp |= (EHCI_TUNE_FLS << 2); + switch (EHCI_TUNE_FLS) { + case 0: ehci->periodic_size = 1024; break; + case 1: ehci->periodic_size = 512; break; + case 2: ehci->periodic_size = 256; break; + default: BUG(); + } } if (HCC_LPM(hcc_params)) { /* support link power management EHCI 1.1 addendum */ diff --git a/trunk/drivers/usb/host/ehci-mxc.c b/trunk/drivers/usb/host/ehci-mxc.c index c8e360d7d975..fa59b26fc5bc 100644 --- a/trunk/drivers/usb/host/ehci-mxc.c +++ b/trunk/drivers/usb/host/ehci-mxc.c @@ -21,13 +21,10 @@ #include #include #include -#include #include #include -#include - #define ULPI_VIEWPORT_OFFSET 0x170 struct ehci_mxc_priv { @@ -117,7 +114,6 @@ static int ehci_mxc_drv_probe(struct platform_device *pdev) struct usb_hcd *hcd; struct resource *res; int irq, ret; - unsigned int flags; struct ehci_mxc_priv *priv; struct device *dev = &pdev->dev; struct ehci_hcd *ehci; @@ -181,8 +177,8 @@ static int ehci_mxc_drv_probe(struct platform_device *pdev) clk_enable(priv->ahbclk); } - /* "dr" device has its own clock on i.MX51 */ - if (cpu_is_mx51() && (pdev->id == 0)) { + /* "dr" device has its own clock */ + if (pdev->id == 0) { priv->phy1clk = clk_get(dev, "usb_phy1"); if (IS_ERR(priv->phy1clk)) { ret = PTR_ERR(priv->phy1clk); @@ -244,23 +240,6 @@ static int ehci_mxc_drv_probe(struct platform_device *pdev) if (ret) goto err_add; - if (pdata->otg) { - /* - * efikamx and efikasb have some hardware bug which is - * preventing usb to work unless CHRGVBUS is set. - * It's in violation of USB specs - */ - if (machine_is_mx51_efikamx() || machine_is_mx51_efikasb()) { - flags = otg_io_read(pdata->otg, ULPI_OTG_CTRL); - flags |= ULPI_OTG_CTRL_CHRGVBUS; - ret = otg_io_write(pdata->otg, flags, ULPI_OTG_CTRL); - if (ret) { - dev_err(dev, "unable to set CHRVBUS\n"); - goto err_add; - } - } - } - return 0; err_add: diff --git a/trunk/drivers/usb/host/ehci-pci.c b/trunk/drivers/usb/host/ehci-pci.c index bed07d4aab06..76179c39c0e3 100644 --- a/trunk/drivers/usb/host/ehci-pci.c +++ b/trunk/drivers/usb/host/ehci-pci.c @@ -44,35 +44,28 @@ static int ehci_pci_reinit(struct ehci_hcd *ehci, struct pci_dev *pdev) return 0; } -static int ehci_quirk_amd_hudson(struct ehci_hcd *ehci) +static int ehci_quirk_amd_SB800(struct ehci_hcd *ehci) { struct pci_dev *amd_smbus_dev; u8 rev = 0; amd_smbus_dev = pci_get_device(PCI_VENDOR_ID_ATI, 0x4385, NULL); - if (amd_smbus_dev) { - pci_read_config_byte(amd_smbus_dev, PCI_REVISION_ID, &rev); - if (rev < 0x40) { - pci_dev_put(amd_smbus_dev); - amd_smbus_dev = NULL; - return 0; - } - } else { - amd_smbus_dev = pci_get_device(PCI_VENDOR_ID_AMD, 0x780b, NULL); - if (!amd_smbus_dev) - return 0; - pci_read_config_byte(amd_smbus_dev, PCI_REVISION_ID, &rev); - if (rev < 0x11 || rev > 0x18) { - pci_dev_put(amd_smbus_dev); - amd_smbus_dev = NULL; - return 0; - } + if (!amd_smbus_dev) + return 0; + + pci_read_config_byte(amd_smbus_dev, PCI_REVISION_ID, &rev); + if (rev < 0x40) { + pci_dev_put(amd_smbus_dev); + amd_smbus_dev = NULL; + return 0; } if (!amd_nb_dev) amd_nb_dev = pci_get_device(PCI_VENDOR_ID_AMD, 0x1510, NULL); + if (!amd_nb_dev) + ehci_err(ehci, "QUIRK: unable to get AMD NB device\n"); - ehci_info(ehci, "QUIRK: Enable exception for AMD Hudson ASPM\n"); + ehci_info(ehci, "QUIRK: Enable AMD SB800 L1 fix\n"); pci_dev_put(amd_smbus_dev); amd_smbus_dev = NULL; @@ -138,7 +131,7 @@ static int ehci_pci_setup(struct usb_hcd *hcd) /* cache this readonly data; minimize chip reads */ ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); - if (ehci_quirk_amd_hudson(ehci)) + if (ehci_quirk_amd_SB800(ehci)) ehci->amd_l1_fix = 1; retval = ehci_halt(ehci); diff --git a/trunk/drivers/usb/host/fsl-mph-dr-of.c b/trunk/drivers/usb/host/fsl-mph-dr-of.c index 79a66d622f9c..574b99ea0700 100644 --- a/trunk/drivers/usb/host/fsl-mph-dr-of.c +++ b/trunk/drivers/usb/host/fsl-mph-dr-of.c @@ -262,24 +262,19 @@ static void fsl_usb2_mpc5121_exit(struct platform_device *pdev) } } -static struct fsl_usb2_platform_data fsl_usb2_mpc5121_pd = { +struct fsl_usb2_platform_data fsl_usb2_mpc5121_pd = { .big_endian_desc = 1, .big_endian_mmio = 1, .es = 1, - .have_sysif_regs = 0, .le_setup_buf = 1, .init = fsl_usb2_mpc5121_init, .exit = fsl_usb2_mpc5121_exit, }; #endif /* CONFIG_PPC_MPC512x */ -static struct fsl_usb2_platform_data fsl_usb2_mpc8xxx_pd = { - .have_sysif_regs = 1, -}; - static const struct of_device_id fsl_usb2_mph_dr_of_match[] = { - { .compatible = "fsl-usb2-mph", .data = &fsl_usb2_mpc8xxx_pd, }, - { .compatible = "fsl-usb2-dr", .data = &fsl_usb2_mpc8xxx_pd, }, + { .compatible = "fsl-usb2-mph", }, + { .compatible = "fsl-usb2-dr", }, #ifdef CONFIG_PPC_MPC512x { .compatible = "fsl,mpc5121-usb2-dr", .data = &fsl_usb2_mpc5121_pd, }, #endif diff --git a/trunk/drivers/usb/host/xhci-ring.c b/trunk/drivers/usb/host/xhci-ring.c index 3e8211c1ce5a..df558f6f84e3 100644 --- a/trunk/drivers/usb/host/xhci-ring.c +++ b/trunk/drivers/usb/host/xhci-ring.c @@ -308,8 +308,11 @@ static int room_on_ring(struct xhci_hcd *xhci, struct xhci_ring *ring, /* Ring the host controller doorbell after placing a command on the ring */ void xhci_ring_cmd_db(struct xhci_hcd *xhci) { + u32 temp; + xhci_dbg(xhci, "// Ding dong!\n"); - xhci_writel(xhci, DB_VALUE_HOST, &xhci->dba->doorbell[0]); + temp = xhci_readl(xhci, &xhci->dba->doorbell[0]) & DB_MASK; + xhci_writel(xhci, temp | DB_TARGET_HOST, &xhci->dba->doorbell[0]); /* Flush PCI posted writes */ xhci_readl(xhci, &xhci->dba->doorbell[0]); } @@ -319,24 +322,26 @@ void xhci_ring_ep_doorbell(struct xhci_hcd *xhci, unsigned int ep_index, unsigned int stream_id) { + struct xhci_virt_ep *ep; + unsigned int ep_state; + u32 field; __u32 __iomem *db_addr = &xhci->dba->doorbell[slot_id]; - struct xhci_virt_ep *ep = &xhci->devs[slot_id]->eps[ep_index]; - unsigned int ep_state = ep->ep_state; + ep = &xhci->devs[slot_id]->eps[ep_index]; + ep_state = ep->ep_state; /* Don't ring the doorbell for this endpoint if there are pending - * cancellations because we don't want to interrupt processing. + * cancellations because the we don't want to interrupt processing. * We don't want to restart any stream rings if there's a set dequeue * pointer command pending because the device can choose to start any * stream once the endpoint is on the HW schedule. * FIXME - check all the stream rings for pending cancellations. */ - if ((ep_state & EP_HALT_PENDING) || (ep_state & SET_DEQ_PENDING) || - (ep_state & EP_HALTED)) - return; - xhci_writel(xhci, DB_VALUE(ep_index, stream_id), db_addr); - /* The CPU has better things to do at this point than wait for a - * write-posting flush. It'll get there soon enough. - */ + if (!(ep_state & EP_HALT_PENDING) && !(ep_state & SET_DEQ_PENDING) + && !(ep_state & EP_HALTED)) { + field = xhci_readl(xhci, db_addr) & DB_MASK; + field |= EPI_TO_DB(ep_index) | STREAM_ID_TO_DB(stream_id); + xhci_writel(xhci, field, db_addr); + } } /* Ring the doorbell for any rings with pending URBs */ @@ -1183,7 +1188,7 @@ static void handle_port_status(struct xhci_hcd *xhci, addr = &xhci->op_regs->port_status_base + NUM_PORT_REGS * (port_id - 1); temp = xhci_readl(xhci, addr); - if (hcd->state == HC_STATE_SUSPENDED) { + if ((temp & PORT_CONNECT) && (hcd->state == HC_STATE_SUSPENDED)) { xhci_dbg(xhci, "resume root hub\n"); usb_hcd_resume_root_hub(hcd); } @@ -1705,7 +1710,8 @@ static int process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_td *td, /* Others already handled above */ break; } - xhci_dbg(xhci, "ep %#x - asked for %d bytes, " + dev_dbg(&td->urb->dev->dev, + "ep %#x - asked for %d bytes, " "%d bytes untransferred\n", td->urb->ep->desc.bEndpointAddress, td->urb->transfer_buffer_length, @@ -2383,8 +2389,7 @@ static unsigned int count_sg_trbs_needed(struct xhci_hcd *xhci, struct urb *urb) } xhci_dbg(xhci, "\n"); if (!in_interrupt()) - xhci_dbg(xhci, "ep %#x - urb len = %d, sglist used, " - "num_trbs = %d\n", + dev_dbg(&urb->dev->dev, "ep %#x - urb len = %d, sglist used, num_trbs = %d\n", urb->ep->desc.bEndpointAddress, urb->transfer_buffer_length, num_trbs); @@ -2409,17 +2414,14 @@ static void check_trb_math(struct urb *urb, int num_trbs, int running_total) static void giveback_first_trb(struct xhci_hcd *xhci, int slot_id, unsigned int ep_index, unsigned int stream_id, int start_cycle, - struct xhci_generic_trb *start_trb) + struct xhci_generic_trb *start_trb, struct xhci_td *td) { /* * Pass all the TRBs to the hardware at once and make sure this write * isn't reordered. */ wmb(); - if (start_cycle) - start_trb->field[3] |= start_cycle; - else - start_trb->field[3] &= ~0x1; + start_trb->field[3] |= start_cycle; xhci_ring_ep_doorbell(xhci, slot_id, ep_index, stream_id); } @@ -2447,7 +2449,7 @@ int xhci_queue_intr_tx(struct xhci_hcd *xhci, gfp_t mem_flags, * to set the polling interval (once the API is added). */ if (xhci_interval != ep_interval) { - if (printk_ratelimit()) + if (!printk_ratelimit()) dev_dbg(&urb->dev->dev, "Driver uses different interval" " (%d microframe%s) than xHCI " "(%d microframe%s)\n", @@ -2549,11 +2551,9 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags, u32 remainder = 0; /* Don't change the cycle bit of the first TRB until later */ - if (first_trb) { + if (first_trb) first_trb = false; - if (start_cycle == 0) - field |= 0x1; - } else + else field |= ep_ring->cycle_state; /* Chain all the TRBs together; clear the chain bit in the last @@ -2625,7 +2625,7 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags, check_trb_math(urb, num_trbs, running_total); giveback_first_trb(xhci, slot_id, ep_index, urb->stream_id, - start_cycle, start_trb); + start_cycle, start_trb, td); return 0; } @@ -2671,8 +2671,7 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags, /* FIXME: this doesn't deal with URB_ZERO_PACKET - need one more */ if (!in_interrupt()) - xhci_dbg(xhci, "ep %#x - urb len = %#x (%d), " - "addr = %#llx, num_trbs = %d\n", + dev_dbg(&urb->dev->dev, "ep %#x - urb len = %#x (%d), addr = %#llx, num_trbs = %d\n", urb->ep->desc.bEndpointAddress, urb->transfer_buffer_length, urb->transfer_buffer_length, @@ -2712,11 +2711,9 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags, field = 0; /* Don't change the cycle bit of the first TRB until later */ - if (first_trb) { + if (first_trb) first_trb = false; - if (start_cycle == 0) - field |= 0x1; - } else + else field |= ep_ring->cycle_state; /* Chain all the TRBs together; clear the chain bit in the last @@ -2760,7 +2757,7 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags, check_trb_math(urb, num_trbs, running_total); giveback_first_trb(xhci, slot_id, ep_index, urb->stream_id, - start_cycle, start_trb); + start_cycle, start_trb, td); return 0; } @@ -2821,17 +2818,13 @@ int xhci_queue_ctrl_tx(struct xhci_hcd *xhci, gfp_t mem_flags, /* Queue setup TRB - see section 6.4.1.2.1 */ /* FIXME better way to translate setup_packet into two u32 fields? */ setup = (struct usb_ctrlrequest *) urb->setup_packet; - field = 0; - field |= TRB_IDT | TRB_TYPE(TRB_SETUP); - if (start_cycle == 0) - field |= 0x1; queue_trb(xhci, ep_ring, false, true, /* FIXME endianness is probably going to bite my ass here. */ setup->bRequestType | setup->bRequest << 8 | setup->wValue << 16, setup->wIndex | setup->wLength << 16, TRB_LEN(8) | TRB_INTR_TARGET(0), /* Immediate data in pointer */ - field); + TRB_IDT | TRB_TYPE(TRB_SETUP)); /* If there's data, queue data TRBs */ field = 0; @@ -2866,7 +2859,7 @@ int xhci_queue_ctrl_tx(struct xhci_hcd *xhci, gfp_t mem_flags, field | TRB_IOC | TRB_TYPE(TRB_STATUS) | ep_ring->cycle_state); giveback_first_trb(xhci, slot_id, ep_index, 0, - start_cycle, start_trb); + start_cycle, start_trb, td); return 0; } @@ -2907,7 +2900,6 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags, int running_total, trb_buff_len, td_len, td_remain_len, ret; u64 start_addr, addr; int i, j; - bool more_trbs_coming; ep_ring = xhci->devs[slot_id]->eps[ep_index].ring; @@ -2918,7 +2910,7 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags, } if (!in_interrupt()) - xhci_dbg(xhci, "ep %#x - urb len = %#x (%d)," + dev_dbg(&urb->dev->dev, "ep %#x - urb len = %#x (%d)," " addr = %#llx, num_tds = %d\n", urb->ep->desc.bEndpointAddress, urb->transfer_buffer_length, @@ -2958,10 +2950,7 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags, field |= TRB_TYPE(TRB_ISOC); /* Assume URB_ISO_ASAP is set */ field |= TRB_SIA; - if (i == 0) { - if (start_cycle == 0) - field |= 0x1; - } else + if (i > 0) field |= ep_ring->cycle_state; first_trb = false; } else { @@ -2976,11 +2965,9 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags, */ if (j < trbs_per_td - 1) { field |= TRB_CHAIN; - more_trbs_coming = true; } else { td->last_trb = ep_ring->enqueue; field |= TRB_IOC; - more_trbs_coming = false; } /* Calculate TRB length */ @@ -2993,7 +2980,7 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags, length_field = TRB_LEN(trb_buff_len) | remainder | TRB_INTR_TARGET(0); - queue_trb(xhci, ep_ring, false, more_trbs_coming, + queue_trb(xhci, ep_ring, false, false, lower_32_bits(addr), upper_32_bits(addr), length_field, @@ -3016,8 +3003,10 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags, } } - giveback_first_trb(xhci, slot_id, ep_index, urb->stream_id, - start_cycle, start_trb); + wmb(); + start_trb->field[3] |= start_cycle; + + xhci_ring_ep_doorbell(xhci, slot_id, ep_index, urb->stream_id); return 0; } @@ -3075,7 +3064,7 @@ int xhci_queue_isoc_tx_prepare(struct xhci_hcd *xhci, gfp_t mem_flags, * to set the polling interval (once the API is added). */ if (xhci_interval != ep_interval) { - if (printk_ratelimit()) + if (!printk_ratelimit()) dev_dbg(&urb->dev->dev, "Driver uses different interval" " (%d microframe%s) than xHCI " "(%d microframe%s)\n", diff --git a/trunk/drivers/usb/host/xhci.c b/trunk/drivers/usb/host/xhci.c index 34cf4e165877..45e4a3108cc3 100644 --- a/trunk/drivers/usb/host/xhci.c +++ b/trunk/drivers/usb/host/xhci.c @@ -226,8 +226,7 @@ static int xhci_setup_msi(struct xhci_hcd *xhci) static int xhci_setup_msix(struct xhci_hcd *xhci) { int i, ret = 0; - struct usb_hcd *hcd = xhci_to_hcd(xhci); - struct pci_dev *pdev = to_pci_dev(hcd->self.controller); + struct pci_dev *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller); /* * calculate number of msi-x vectors supported. @@ -266,7 +265,6 @@ static int xhci_setup_msix(struct xhci_hcd *xhci) goto disable_msix; } - hcd->msix_enabled = 1; return ret; disable_msix: @@ -282,8 +280,7 @@ static int xhci_setup_msix(struct xhci_hcd *xhci) /* Free any IRQs and disable MSI-X */ static void xhci_cleanup_msix(struct xhci_hcd *xhci) { - struct usb_hcd *hcd = xhci_to_hcd(xhci); - struct pci_dev *pdev = to_pci_dev(hcd->self.controller); + struct pci_dev *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller); xhci_free_irq(xhci); @@ -295,7 +292,6 @@ static void xhci_cleanup_msix(struct xhci_hcd *xhci) pci_disable_msi(pdev); } - hcd->msix_enabled = 0; return; } @@ -512,9 +508,8 @@ void xhci_stop(struct usb_hcd *hcd) spin_lock_irq(&xhci->lock); xhci_halt(xhci); xhci_reset(xhci); - spin_unlock_irq(&xhci->lock); - xhci_cleanup_msix(xhci); + spin_unlock_irq(&xhci->lock); #ifdef CONFIG_USB_XHCI_HCD_DEBUGGING /* Tell the event ring poll function not to reschedule */ @@ -549,9 +544,8 @@ void xhci_shutdown(struct usb_hcd *hcd) spin_lock_irq(&xhci->lock); xhci_halt(xhci); - spin_unlock_irq(&xhci->lock); - xhci_cleanup_msix(xhci); + spin_unlock_irq(&xhci->lock); xhci_dbg(xhci, "xhci_shutdown completed - status = %x\n", xhci_readl(xhci, &xhci->op_regs->status)); @@ -653,7 +647,6 @@ int xhci_suspend(struct xhci_hcd *xhci) int rc = 0; struct usb_hcd *hcd = xhci_to_hcd(xhci); u32 command; - int i; spin_lock_irq(&xhci->lock); clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); @@ -684,14 +677,9 @@ int xhci_suspend(struct xhci_hcd *xhci) spin_unlock_irq(&xhci->lock); return -ETIMEDOUT; } - spin_unlock_irq(&xhci->lock); - /* step 5: remove core well power */ - /* synchronize irq when using MSI-X */ - if (xhci->msix_entries) { - for (i = 0; i < xhci->msix_count; i++) - synchronize_irq(xhci->msix_entries[i].vector); - } + xhci_cleanup_msix(xhci); + spin_unlock_irq(&xhci->lock); return rc; } @@ -706,6 +694,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) { u32 command, temp = 0; struct usb_hcd *hcd = xhci_to_hcd(xhci); + struct pci_dev *pdev = to_pci_dev(hcd->self.controller); int old_state, retval; old_state = hcd->state; @@ -740,8 +729,9 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) xhci_dbg(xhci, "Stop HCD\n"); xhci_halt(xhci); xhci_reset(xhci); + if (hibernated) + xhci_cleanup_msix(xhci); spin_unlock_irq(&xhci->lock); - xhci_cleanup_msix(xhci); #ifdef CONFIG_USB_XHCI_HCD_DEBUGGING /* Tell the event ring poll function not to reschedule */ @@ -775,6 +765,30 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) return retval; } + spin_unlock_irq(&xhci->lock); + /* Re-setup MSI-X */ + if (hcd->irq) + free_irq(hcd->irq, hcd); + hcd->irq = -1; + + retval = xhci_setup_msix(xhci); + if (retval) + /* fall back to msi*/ + retval = xhci_setup_msi(xhci); + + if (retval) { + /* fall back to legacy interrupt*/ + retval = request_irq(pdev->irq, &usb_hcd_irq, IRQF_SHARED, + hcd->irq_descr, hcd); + if (retval) { + xhci_err(xhci, "request interrupt %d failed\n", + pdev->irq); + return retval; + } + hcd->irq = pdev->irq; + } + + spin_lock_irq(&xhci->lock); /* step 4: set Run/Stop bit */ command = xhci_readl(xhci, &xhci->op_regs->command); command |= CMD_RUN; @@ -2431,12 +2445,8 @@ int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev) xhci_err(xhci, "Error while assigning device slot ID\n"); return 0; } - /* xhci_alloc_virt_device() does not touch rings; no need to lock. - * Use GFP_NOIO, since this function can be called from - * xhci_discover_or_reset_device(), which may be called as part of - * mass storage driver error handling. - */ - if (!xhci_alloc_virt_device(xhci, xhci->slot_id, udev, GFP_NOIO)) { + /* xhci_alloc_virt_device() does not touch rings; no need to lock */ + if (!xhci_alloc_virt_device(xhci, xhci->slot_id, udev, GFP_KERNEL)) { /* Disable slot, if we can do it without mem alloc */ xhci_warn(xhci, "Could not allocate xHCI USB device data structures\n"); spin_lock_irqsave(&xhci->lock, flags); diff --git a/trunk/drivers/usb/host/xhci.h b/trunk/drivers/usb/host/xhci.h index 7f236fd22015..170c367112d2 100644 --- a/trunk/drivers/usb/host/xhci.h +++ b/trunk/drivers/usb/host/xhci.h @@ -436,18 +436,22 @@ struct xhci_run_regs { /** * struct doorbell_array * - * Bits 0 - 7: Endpoint target - * Bits 8 - 15: RsvdZ - * Bits 16 - 31: Stream ID - * * Section 5.6 */ struct xhci_doorbell_array { u32 doorbell[256]; }; -#define DB_VALUE(ep, stream) ((((ep) + 1) & 0xff) | ((stream) << 16)) -#define DB_VALUE_HOST 0x00000000 +#define DB_TARGET_MASK 0xFFFFFF00 +#define DB_STREAM_ID_MASK 0x0000FFFF +#define DB_TARGET_HOST 0x0 +#define DB_STREAM_ID_HOST 0x0 +#define DB_MASK (0xff << 8) + +/* Endpoint Target - bits 0:7 */ +#define EPI_TO_DB(p) (((p) + 1) & 0xff) +#define STREAM_ID_TO_DB(p) (((p) & 0xffff) << 16) + /** * struct xhci_protocol_caps diff --git a/trunk/drivers/usb/misc/usbled.c b/trunk/drivers/usb/misc/usbled.c index 1616ad1793a4..1732d9bc097e 100644 --- a/trunk/drivers/usb/misc/usbled.c +++ b/trunk/drivers/usb/misc/usbled.c @@ -45,7 +45,7 @@ struct usb_led { static void change_color(struct usb_led *led) { - int retval = 0; + int retval; unsigned char *buffer; buffer = kmalloc(8, GFP_KERNEL); diff --git a/trunk/drivers/usb/misc/uss720.c b/trunk/drivers/usb/misc/uss720.c index f7a205738032..4ff21587ab03 100644 --- a/trunk/drivers/usb/misc/uss720.c +++ b/trunk/drivers/usb/misc/uss720.c @@ -776,6 +776,7 @@ static const struct usb_device_id uss720_table[] = { { USB_DEVICE(0x0557, 0x2001) }, { USB_DEVICE(0x0729, 0x1284) }, { USB_DEVICE(0x1293, 0x0002) }, + { USB_DEVICE(0x1293, 0x0002) }, { USB_DEVICE(0x050d, 0x0002) }, { } /* Terminating entry */ }; diff --git a/trunk/drivers/usb/otg/nop-usb-xceiv.c b/trunk/drivers/usb/otg/nop-usb-xceiv.c index 8acf165fe13b..e70014ab0976 100644 --- a/trunk/drivers/usb/otg/nop-usb-xceiv.c +++ b/trunk/drivers/usb/otg/nop-usb-xceiv.c @@ -132,8 +132,6 @@ static int __devinit nop_usb_xceiv_probe(struct platform_device *pdev) platform_set_drvdata(pdev, nop); - BLOCKING_INIT_NOTIFIER_HEAD(&nop->otg.notifier); - return 0; exit: kfree(nop); diff --git a/trunk/drivers/usb/otg/ulpi.c b/trunk/drivers/usb/otg/ulpi.c index 770d799d5afb..059d9ac0ab5b 100644 --- a/trunk/drivers/usb/otg/ulpi.c +++ b/trunk/drivers/usb/otg/ulpi.c @@ -45,7 +45,7 @@ struct ulpi_info { /* ULPI hardcoded IDs, used for probing */ static struct ulpi_info ulpi_ids[] = { ULPI_INFO(ULPI_ID(0x04cc, 0x1504), "NXP ISP1504"), - ULPI_INFO(ULPI_ID(0x0424, 0x0006), "SMSC USB331x"), + ULPI_INFO(ULPI_ID(0x0424, 0x0006), "SMSC USB3319"), }; static int ulpi_set_otg_flags(struct otg_transceiver *otg) diff --git a/trunk/drivers/usb/serial/ch341.c b/trunk/drivers/usb/serial/ch341.c index 7b8815ddf368..63f7cc45bcac 100644 --- a/trunk/drivers/usb/serial/ch341.c +++ b/trunk/drivers/usb/serial/ch341.c @@ -486,22 +486,12 @@ static void ch341_read_int_callback(struct urb *urb) if (actual_length >= 4) { struct ch341_private *priv = usb_get_serial_port_data(port); unsigned long flags; - u8 prev_line_status = priv->line_status; spin_lock_irqsave(&priv->lock, flags); priv->line_status = (~(data[2])) & CH341_BITS_MODEM_STAT; if ((data[1] & CH341_MULT_STAT)) priv->multi_status_change = 1; spin_unlock_irqrestore(&priv->lock, flags); - - if ((priv->line_status ^ prev_line_status) & CH341_BIT_DCD) { - struct tty_struct *tty = tty_port_tty_get(&port->port); - if (tty) - usb_serial_handle_dcd_change(port, tty, - priv->line_status & CH341_BIT_DCD); - tty_kref_put(tty); - } - wake_up_interruptible(&priv->delta_msr_wait); } diff --git a/trunk/drivers/usb/serial/cp210x.c b/trunk/drivers/usb/serial/cp210x.c index 735ea03157ab..8d7731dbf478 100644 --- a/trunk/drivers/usb/serial/cp210x.c +++ b/trunk/drivers/usb/serial/cp210x.c @@ -49,6 +49,7 @@ static int cp210x_tiocmset_port(struct usb_serial_port *port, struct file *, static void cp210x_break_ctl(struct tty_struct *, int); static int cp210x_startup(struct usb_serial *); static void cp210x_dtr_rts(struct usb_serial_port *p, int on); +static int cp210x_carrier_raised(struct usb_serial_port *p); static int debug; @@ -86,6 +87,7 @@ static const struct usb_device_id id_table[] = { { USB_DEVICE(0x10C4, 0x8115) }, /* Arygon NFC/Mifare Reader */ { USB_DEVICE(0x10C4, 0x813D) }, /* Burnside Telecom Deskmobile */ { USB_DEVICE(0x10C4, 0x813F) }, /* Tams Master Easy Control */ + { USB_DEVICE(0x10C4, 0x8149) }, /* West Mountain Radio Computerized Battery Analyzer */ { USB_DEVICE(0x10C4, 0x814A) }, /* West Mountain Radio RIGblaster P&P */ { USB_DEVICE(0x10C4, 0x814B) }, /* West Mountain Radio RIGtalk */ { USB_DEVICE(0x10C4, 0x8156) }, /* B&G H3000 link cable */ @@ -108,9 +110,7 @@ static const struct usb_device_id id_table[] = { { USB_DEVICE(0x10C4, 0x8341) }, /* Siemens MC35PU GPRS Modem */ { USB_DEVICE(0x10C4, 0x8382) }, /* Cygnal Integrated Products, Inc. */ { USB_DEVICE(0x10C4, 0x83A8) }, /* Amber Wireless AMB2560 */ - { USB_DEVICE(0x10C4, 0x83D8) }, /* DekTec DTA Plus VHF/UHF Booster/Attenuator */ { USB_DEVICE(0x10C4, 0x8411) }, /* Kyocera GPS Module */ - { USB_DEVICE(0x10C4, 0x8418) }, /* IRZ Automation Teleport SG-10 GSM/GPRS Modem */ { USB_DEVICE(0x10C4, 0x846E) }, /* BEI USB Sensor Interface (VCP) */ { USB_DEVICE(0x10C4, 0x8477) }, /* Balluff RFID */ { USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */ @@ -165,7 +165,8 @@ static struct usb_serial_driver cp210x_device = { .tiocmget = cp210x_tiocmget, .tiocmset = cp210x_tiocmset, .attach = cp210x_startup, - .dtr_rts = cp210x_dtr_rts + .dtr_rts = cp210x_dtr_rts, + .carrier_raised = cp210x_carrier_raised }; /* Config request types */ @@ -764,6 +765,15 @@ static int cp210x_tiocmget (struct tty_struct *tty, struct file *file) return result; } +static int cp210x_carrier_raised(struct usb_serial_port *p) +{ + unsigned int control; + cp210x_get_config(p, CP210X_GET_MDMSTS, &control, 1); + if (control & CONTROL_DCD) + return 1; + return 0; +} + static void cp210x_break_ctl (struct tty_struct *tty, int break_state) { struct usb_serial_port *port = tty->driver_data; diff --git a/trunk/drivers/usb/serial/digi_acceleport.c b/trunk/drivers/usb/serial/digi_acceleport.c index 666e5a6edd82..b92070c103cd 100644 --- a/trunk/drivers/usb/serial/digi_acceleport.c +++ b/trunk/drivers/usb/serial/digi_acceleport.c @@ -455,6 +455,7 @@ static int digi_write_room(struct tty_struct *tty); static int digi_chars_in_buffer(struct tty_struct *tty); static int digi_open(struct tty_struct *tty, struct usb_serial_port *port); static void digi_close(struct usb_serial_port *port); +static int digi_carrier_raised(struct usb_serial_port *port); static void digi_dtr_rts(struct usb_serial_port *port, int on); static int digi_startup_device(struct usb_serial *serial); static int digi_startup(struct usb_serial *serial); @@ -510,6 +511,7 @@ static struct usb_serial_driver digi_acceleport_2_device = { .open = digi_open, .close = digi_close, .dtr_rts = digi_dtr_rts, + .carrier_raised = digi_carrier_raised, .write = digi_write, .write_room = digi_write_room, .write_bulk_callback = digi_write_bulk_callback, @@ -1337,6 +1339,14 @@ static void digi_dtr_rts(struct usb_serial_port *port, int on) digi_set_modem_signals(port, on * (TIOCM_DTR|TIOCM_RTS), 1); } +static int digi_carrier_raised(struct usb_serial_port *port) +{ + struct digi_port *priv = usb_get_serial_port_data(port); + if (priv->dp_modem_signals & TIOCM_CD) + return 1; + return 0; +} + static int digi_open(struct tty_struct *tty, struct usb_serial_port *port) { int ret; diff --git a/trunk/drivers/usb/serial/ftdi_sio.c b/trunk/drivers/usb/serial/ftdi_sio.c index 4787c0cd063f..a2668d089260 100644 --- a/trunk/drivers/usb/serial/ftdi_sio.c +++ b/trunk/drivers/usb/serial/ftdi_sio.c @@ -676,17 +676,7 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(FTDI_VID, FTDI_PCDJ_DAC2_PID) }, { USB_DEVICE(FTDI_VID, FTDI_RRCIRKITS_LOCOBUFFER_PID) }, { USB_DEVICE(FTDI_VID, FTDI_ASK_RDR400_PID) }, - { USB_DEVICE(ICOM_VID, ICOM_ID_1_PID) }, - { USB_DEVICE(ICOM_VID, ICOM_OPC_U_UC_PID) }, - { USB_DEVICE(ICOM_VID, ICOM_ID_RP2C1_PID) }, - { USB_DEVICE(ICOM_VID, ICOM_ID_RP2C2_PID) }, - { USB_DEVICE(ICOM_VID, ICOM_ID_RP2D_PID) }, - { USB_DEVICE(ICOM_VID, ICOM_ID_RP2VT_PID) }, - { USB_DEVICE(ICOM_VID, ICOM_ID_RP2VR_PID) }, - { USB_DEVICE(ICOM_VID, ICOM_ID_RP4KVT_PID) }, - { USB_DEVICE(ICOM_VID, ICOM_ID_RP4KVR_PID) }, - { USB_DEVICE(ICOM_VID, ICOM_ID_RP2KVT_PID) }, - { USB_DEVICE(ICOM_VID, ICOM_ID_RP2KVR_PID) }, + { USB_DEVICE(ICOM_ID1_VID, ICOM_ID1_PID) }, { USB_DEVICE(FTDI_VID, FTDI_ACG_HFDUAL_PID) }, { USB_DEVICE(FTDI_VID, FTDI_YEI_SERVOCENTER31_PID) }, { USB_DEVICE(FTDI_VID, FTDI_THORLABS_PID) }, diff --git a/trunk/drivers/usb/serial/ftdi_sio_ids.h b/trunk/drivers/usb/serial/ftdi_sio_ids.h index ed160def8584..bf0867285481 100644 --- a/trunk/drivers/usb/serial/ftdi_sio_ids.h +++ b/trunk/drivers/usb/serial/ftdi_sio_ids.h @@ -569,23 +569,11 @@ #define OCT_US101_PID 0x0421 /* OCT US101 USB to RS-232 */ /* - * Definitions for Icom Inc. devices - */ -#define ICOM_VID 0x0C26 /* Icom vendor ID */ -/* Note: ID-1 is a communications tranceiver for HAM-radio operators */ -#define ICOM_ID_1_PID 0x0004 /* ID-1 USB to RS-232 */ -/* Note: OPC is an Optional cable to connect an Icom Tranceiver */ -#define ICOM_OPC_U_UC_PID 0x0018 /* OPC-478UC, OPC-1122U cloning cable */ -/* Note: ID-RP* devices are Icom Repeater Devices for HAM-radio */ -#define ICOM_ID_RP2C1_PID 0x0009 /* ID-RP2C Asset 1 to RS-232 */ -#define ICOM_ID_RP2C2_PID 0x000A /* ID-RP2C Asset 2 to RS-232 */ -#define ICOM_ID_RP2D_PID 0x000B /* ID-RP2D configuration port*/ -#define ICOM_ID_RP2VT_PID 0x000C /* ID-RP2V Transmit config port */ -#define ICOM_ID_RP2VR_PID 0x000D /* ID-RP2V Receive config port */ -#define ICOM_ID_RP4KVT_PID 0x0010 /* ID-RP4000V Transmit config port */ -#define ICOM_ID_RP4KVR_PID 0x0011 /* ID-RP4000V Receive config port */ -#define ICOM_ID_RP2KVT_PID 0x0012 /* ID-RP2000V Transmit config port */ -#define ICOM_ID_RP2KVR_PID 0x0013 /* ID-RP2000V Receive config port */ + * Icom ID-1 digital transceiver + */ + +#define ICOM_ID1_VID 0x0C26 +#define ICOM_ID1_PID 0x0004 /* * GN Otometrics (http://www.otometrics.com) diff --git a/trunk/drivers/usb/serial/generic.c b/trunk/drivers/usb/serial/generic.c index e4db5ad2bc55..e6833e216fc9 100644 --- a/trunk/drivers/usb/serial/generic.c +++ b/trunk/drivers/usb/serial/generic.c @@ -479,26 +479,6 @@ int usb_serial_handle_break(struct usb_serial_port *port) } EXPORT_SYMBOL_GPL(usb_serial_handle_break); -/** - * usb_serial_handle_dcd_change - handle a change of carrier detect state - * @port: usb_serial_port structure for the open port - * @tty: tty_struct structure for the port - * @status: new carrier detect status, nonzero if active - */ -void usb_serial_handle_dcd_change(struct usb_serial_port *usb_port, - struct tty_struct *tty, unsigned int status) -{ - struct tty_port *port = &usb_port->port; - - dbg("%s - port %d, status %d", __func__, usb_port->number, status); - - if (status) - wake_up_interruptible(&port->open_wait); - else if (tty && !C_CLOCAL(tty)) - tty_hangup(tty); -} -EXPORT_SYMBOL_GPL(usb_serial_handle_dcd_change); - int usb_serial_generic_resume(struct usb_serial *serial) { struct usb_serial_port *port; diff --git a/trunk/drivers/usb/serial/io_tables.h b/trunk/drivers/usb/serial/io_tables.h index 178b22eb32b1..6ab2a3f97fe8 100644 --- a/trunk/drivers/usb/serial/io_tables.h +++ b/trunk/drivers/usb/serial/io_tables.h @@ -199,7 +199,6 @@ static struct usb_serial_driver epic_device = { .name = "epic", }, .description = "EPiC device", - .usb_driver = &io_driver, .id_table = Epic_port_id_table, .num_ports = 1, .open = edge_open, diff --git a/trunk/drivers/usb/serial/iuu_phoenix.c b/trunk/drivers/usb/serial/iuu_phoenix.c index 99b97c04896f..12ed594f5f80 100644 --- a/trunk/drivers/usb/serial/iuu_phoenix.c +++ b/trunk/drivers/usb/serial/iuu_phoenix.c @@ -1275,7 +1275,6 @@ static struct usb_serial_driver iuu_device = { .name = "iuu_phoenix", }, .id_table = id_table, - .usb_driver = &iuu_driver, .num_ports = 1, .bulk_in_size = 512, .bulk_out_size = 512, diff --git a/trunk/drivers/usb/serial/keyspan.h b/trunk/drivers/usb/serial/keyspan.h index ce134dc28ddf..2d8baf6ac472 100644 --- a/trunk/drivers/usb/serial/keyspan.h +++ b/trunk/drivers/usb/serial/keyspan.h @@ -546,7 +546,6 @@ static struct usb_serial_driver keyspan_pre_device = { .name = "keyspan_no_firm", }, .description = "Keyspan - (without firmware)", - .usb_driver = &keyspan_driver, .id_table = keyspan_pre_ids, .num_ports = 1, .attach = keyspan_fake_startup, @@ -558,7 +557,6 @@ static struct usb_serial_driver keyspan_1port_device = { .name = "keyspan_1", }, .description = "Keyspan 1 port adapter", - .usb_driver = &keyspan_driver, .id_table = keyspan_1port_ids, .num_ports = 1, .open = keyspan_open, @@ -581,7 +579,6 @@ static struct usb_serial_driver keyspan_2port_device = { .name = "keyspan_2", }, .description = "Keyspan 2 port adapter", - .usb_driver = &keyspan_driver, .id_table = keyspan_2port_ids, .num_ports = 2, .open = keyspan_open, @@ -604,7 +601,6 @@ static struct usb_serial_driver keyspan_4port_device = { .name = "keyspan_4", }, .description = "Keyspan 4 port adapter", - .usb_driver = &keyspan_driver, .id_table = keyspan_4port_ids, .num_ports = 4, .open = keyspan_open, diff --git a/trunk/drivers/usb/serial/keyspan_pda.c b/trunk/drivers/usb/serial/keyspan_pda.c index 554a8693a463..a10dd5676ccc 100644 --- a/trunk/drivers/usb/serial/keyspan_pda.c +++ b/trunk/drivers/usb/serial/keyspan_pda.c @@ -679,6 +679,22 @@ static void keyspan_pda_dtr_rts(struct usb_serial_port *port, int on) } } +static int keyspan_pda_carrier_raised(struct usb_serial_port *port) +{ + struct usb_serial *serial = port->serial; + unsigned char modembits; + + /* If we can read the modem status and the DCD is low then + carrier is not raised yet */ + if (keyspan_pda_get_modem_info(serial, &modembits) >= 0) { + if (!(modembits & (1>>6))) + return 0; + } + /* Carrier raised, or we failed (eg disconnected) so + progress accordingly */ + return 1; +} + static int keyspan_pda_open(struct tty_struct *tty, struct usb_serial_port *port) @@ -865,6 +881,7 @@ static struct usb_serial_driver keyspan_pda_device = { .id_table = id_table_std, .num_ports = 1, .dtr_rts = keyspan_pda_dtr_rts, + .carrier_raised = keyspan_pda_carrier_raised, .open = keyspan_pda_open, .close = keyspan_pda_close, .write = keyspan_pda_write, diff --git a/trunk/drivers/usb/serial/moto_modem.c b/trunk/drivers/usb/serial/moto_modem.c index 653465f61d4a..cf1718394e18 100644 --- a/trunk/drivers/usb/serial/moto_modem.c +++ b/trunk/drivers/usb/serial/moto_modem.c @@ -44,7 +44,6 @@ static struct usb_serial_driver moto_device = { .name = "moto-modem", }, .id_table = id_table, - .usb_driver = &moto_driver, .num_ports = 1, }; diff --git a/trunk/drivers/usb/serial/option.c b/trunk/drivers/usb/serial/option.c index 5f46838dfee5..748778288d94 100644 --- a/trunk/drivers/usb/serial/option.c +++ b/trunk/drivers/usb/serial/option.c @@ -382,16 +382,7 @@ static void option_instat_callback(struct urb *urb); #define HAIER_VENDOR_ID 0x201e #define HAIER_PRODUCT_CE100 0x2009 -/* Cinterion (formerly Siemens) products */ -#define SIEMENS_VENDOR_ID 0x0681 -#define CINTERION_VENDOR_ID 0x1e2d -#define CINTERION_PRODUCT_HC25_MDM 0x0047 -#define CINTERION_PRODUCT_HC25_MDMNET 0x0040 -#define CINTERION_PRODUCT_HC28_MDM 0x004C -#define CINTERION_PRODUCT_HC28_MDMNET 0x004A /* same for HC28J */ -#define CINTERION_PRODUCT_EU3_E 0x0051 -#define CINTERION_PRODUCT_EU3_P 0x0052 -#define CINTERION_PRODUCT_PH8 0x0053 +#define CINTERION_VENDOR_ID 0x0681 /* Olivetti products */ #define OLIVETTI_VENDOR_ID 0x0b3c @@ -953,17 +944,7 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100F) }, { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1011)}, { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1012)}, - /* Cinterion */ - { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_EU3_E) }, - { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_EU3_P) }, - { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_PH8) }, - { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_HC28_MDM) }, - { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_HC28_MDMNET) }, - { USB_DEVICE(SIEMENS_VENDOR_ID, CINTERION_PRODUCT_HC25_MDM) }, - { USB_DEVICE(SIEMENS_VENDOR_ID, CINTERION_PRODUCT_HC25_MDMNET) }, - { USB_DEVICE(SIEMENS_VENDOR_ID, CINTERION_PRODUCT_HC28_MDM) }, /* HC28 enumerates with Siemens or Cinterion VID depending on FW revision */ - { USB_DEVICE(SIEMENS_VENDOR_ID, CINTERION_PRODUCT_HC28_MDMNET) }, - + { USB_DEVICE(CINTERION_VENDOR_ID, 0x0047) }, { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD100) }, { USB_DEVICE(CELOT_VENDOR_ID, CELOT_PRODUCT_CT680M) }, /* CT-650 CDMA 450 1xEVDO modem */ { USB_DEVICE(ONDA_VENDOR_ID, ONDA_MT825UP) }, /* ONDA MT825UP modem */ diff --git a/trunk/drivers/usb/serial/oti6858.c b/trunk/drivers/usb/serial/oti6858.c index 73613205be7a..5be866bb7a41 100644 --- a/trunk/drivers/usb/serial/oti6858.c +++ b/trunk/drivers/usb/serial/oti6858.c @@ -157,7 +157,6 @@ static struct usb_serial_driver oti6858_device = { .name = "oti6858", }, .id_table = id_table, - .usb_driver = &oti6858_driver, .num_ports = 1, .open = oti6858_open, .close = oti6858_close, diff --git a/trunk/drivers/usb/serial/pl2303.c b/trunk/drivers/usb/serial/pl2303.c index 08c9181b8e48..8ae4c6cbc38a 100644 --- a/trunk/drivers/usb/serial/pl2303.c +++ b/trunk/drivers/usb/serial/pl2303.c @@ -50,7 +50,6 @@ static const struct usb_device_id id_table[] = { { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_MMX) }, { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_GPRS) }, { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_HCR331) }, - { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_MOTOROLA) }, { USB_DEVICE(IODATA_VENDOR_ID, IODATA_PRODUCT_ID) }, { USB_DEVICE(IODATA_VENDOR_ID, IODATA_PRODUCT_ID_RSAQ5) }, { USB_DEVICE(ATEN_VENDOR_ID, ATEN_PRODUCT_ID) }, @@ -678,11 +677,9 @@ static void pl2303_update_line_status(struct usb_serial_port *port, { struct pl2303_private *priv = usb_get_serial_port_data(port); - struct tty_struct *tty; unsigned long flags; u8 status_idx = UART_STATE; u8 length = UART_STATE + 1; - u8 prev_line_status; u16 idv, idp; idv = le16_to_cpu(port->serial->dev->descriptor.idVendor); @@ -704,20 +701,11 @@ static void pl2303_update_line_status(struct usb_serial_port *port, /* Save off the uart status for others to look at */ spin_lock_irqsave(&priv->lock, flags); - prev_line_status = priv->line_status; priv->line_status = data[status_idx]; spin_unlock_irqrestore(&priv->lock, flags); if (priv->line_status & UART_BREAK_ERROR) usb_serial_handle_break(port); wake_up_interruptible(&priv->delta_msr_wait); - - tty = tty_port_tty_get(&port->port); - if (!tty) - return; - if ((priv->line_status ^ prev_line_status) & UART_DCD) - usb_serial_handle_dcd_change(port, tty, - priv->line_status & UART_DCD); - tty_kref_put(tty); } static void pl2303_read_int_callback(struct urb *urb) diff --git a/trunk/drivers/usb/serial/pl2303.h b/trunk/drivers/usb/serial/pl2303.h index 1b025f75dafd..43eb9bdad422 100644 --- a/trunk/drivers/usb/serial/pl2303.h +++ b/trunk/drivers/usb/serial/pl2303.h @@ -21,7 +21,6 @@ #define PL2303_PRODUCT_ID_MMX 0x0612 #define PL2303_PRODUCT_ID_GPRS 0x0609 #define PL2303_PRODUCT_ID_HCR331 0x331a -#define PL2303_PRODUCT_ID_MOTOROLA 0x0307 #define ATEN_VENDOR_ID 0x0557 #define ATEN_VENDOR_ID2 0x0547 diff --git a/trunk/drivers/usb/serial/qcaux.c b/trunk/drivers/usb/serial/qcaux.c index 30b73e68a904..214a3e504292 100644 --- a/trunk/drivers/usb/serial/qcaux.c +++ b/trunk/drivers/usb/serial/qcaux.c @@ -36,7 +36,6 @@ #define UTSTARCOM_PRODUCT_UM175_V1 0x3712 #define UTSTARCOM_PRODUCT_UM175_V2 0x3714 #define UTSTARCOM_PRODUCT_UM175_ALLTEL 0x3715 -#define PANTECH_PRODUCT_UML290_VZW 0x3718 /* CMOTECH devices */ #define CMOTECH_VENDOR_ID 0x16d8 @@ -67,7 +66,6 @@ static struct usb_device_id id_table[] = { { USB_DEVICE_AND_INTERFACE_INFO(LG_VENDOR_ID, LG_PRODUCT_VX4400_6000, 0xff, 0xff, 0x00) }, { USB_DEVICE_AND_INTERFACE_INFO(SANYO_VENDOR_ID, SANYO_PRODUCT_KATANA_LX, 0xff, 0xff, 0x00) }, { USB_DEVICE_AND_INTERFACE_INFO(SAMSUNG_VENDOR_ID, SAMSUNG_PRODUCT_U520, 0xff, 0x00, 0x00) }, - { USB_DEVICE_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, PANTECH_PRODUCT_UML290_VZW, 0xff, 0xff, 0xff) }, { }, }; MODULE_DEVICE_TABLE(usb, id_table); @@ -86,7 +84,6 @@ static struct usb_serial_driver qcaux_device = { .name = "qcaux", }, .id_table = id_table, - .usb_driver = &qcaux_driver, .num_ports = 1, }; diff --git a/trunk/drivers/usb/serial/siemens_mpi.c b/trunk/drivers/usb/serial/siemens_mpi.c index 74cd4ccdb3fc..cb8195cabfde 100644 --- a/trunk/drivers/usb/serial/siemens_mpi.c +++ b/trunk/drivers/usb/serial/siemens_mpi.c @@ -42,7 +42,6 @@ static struct usb_serial_driver siemens_usb_mpi_device = { .name = "siemens_mpi", }, .id_table = id_table, - .usb_driver = &siemens_usb_mpi_driver, .num_ports = 1, }; diff --git a/trunk/drivers/usb/serial/spcp8x5.c b/trunk/drivers/usb/serial/spcp8x5.c index cbfb70bffdd0..765aa983bf58 100644 --- a/trunk/drivers/usb/serial/spcp8x5.c +++ b/trunk/drivers/usb/serial/spcp8x5.c @@ -133,7 +133,7 @@ struct spcp8x5_usb_ctrl_arg { /* how come ??? */ #define UART_STATE 0x08 -#define UART_STATE_TRANSIENT_MASK 0x75 +#define UART_STATE_TRANSIENT_MASK 0x74 #define UART_DCD 0x01 #define UART_DSR 0x02 #define UART_BREAK_ERROR 0x04 @@ -525,10 +525,6 @@ static void spcp8x5_process_read_urb(struct urb *urb) /* overrun is special, not associated with a char */ if (status & UART_OVERRUN_ERROR) tty_insert_flip_char(tty, 0, TTY_OVERRUN); - - if (status & UART_DCD) - usb_serial_handle_dcd_change(port, tty, - priv->line_status & MSR_STATUS_LINE_DCD); } tty_insert_flip_string_fixed_flag(tty, data, tty_flag, @@ -649,7 +645,6 @@ static struct usb_serial_driver spcp8x5_device = { .name = "SPCP8x5", }, .id_table = id_table, - .usb_driver = &spcp8x5_driver, .num_ports = 1, .open = spcp8x5_open, .dtr_rts = spcp8x5_dtr_rts, diff --git a/trunk/drivers/usb/serial/usb-serial.c b/trunk/drivers/usb/serial/usb-serial.c index 546a52179bec..6954de50c0ff 100644 --- a/trunk/drivers/usb/serial/usb-serial.c +++ b/trunk/drivers/usb/serial/usb-serial.c @@ -1344,15 +1344,11 @@ int usb_serial_register(struct usb_serial_driver *driver) return -ENODEV; fixup_generic(driver); + if (driver->usb_driver) + driver->usb_driver->supports_autosuspend = 1; if (!driver->description) driver->description = driver->driver.name; - if (!driver->usb_driver) { - WARN(1, "Serial driver %s has no usb_driver\n", - driver->description); - return -EINVAL; - } - driver->usb_driver->supports_autosuspend = 1; /* Add this device to our list of devices */ mutex_lock(&table_lock); diff --git a/trunk/drivers/usb/serial/usb_debug.c b/trunk/drivers/usb/serial/usb_debug.c index 95a82148ee81..f2ed6a31be77 100644 --- a/trunk/drivers/usb/serial/usb_debug.c +++ b/trunk/drivers/usb/serial/usb_debug.c @@ -75,7 +75,6 @@ static struct usb_serial_driver debug_device = { .name = "debug", }, .id_table = id_table, - .usb_driver = &debug_driver, .num_ports = 1, .bulk_out_size = USB_DEBUG_MAX_PACKET_SIZE, .break_ctl = usb_debug_break_ctl, diff --git a/trunk/drivers/usb/storage/unusual_cypress.h b/trunk/drivers/usb/storage/unusual_cypress.h index 2c8553026222..c854fdebe0ae 100644 --- a/trunk/drivers/usb/storage/unusual_cypress.h +++ b/trunk/drivers/usb/storage/unusual_cypress.h @@ -31,9 +31,4 @@ UNUSUAL_DEV( 0x04b4, 0x6831, 0x0000, 0x9999, "Cypress ISD-300LP", USB_SC_CYP_ATACB, USB_PR_DEVICE, NULL, 0), -UNUSUAL_DEV( 0x14cd, 0x6116, 0x0000, 0x9999, - "Super Top", - "USB 2.0 SATA BRIDGE", - USB_SC_CYP_ATACB, USB_PR_DEVICE, NULL, 0), - #endif /* defined(CONFIG_USB_STORAGE_CYPRESS_ATACB) || ... */ diff --git a/trunk/drivers/usb/storage/unusual_devs.h b/trunk/drivers/usb/storage/unusual_devs.h index 24bd5d7c3deb..fcc1e32ce256 100644 --- a/trunk/drivers/usb/storage/unusual_devs.h +++ b/trunk/drivers/usb/storage/unusual_devs.h @@ -1044,15 +1044,6 @@ UNUSUAL_DEV( 0x084d, 0x0011, 0x0110, 0x0110, USB_SC_DEVICE, USB_PR_DEVICE, NULL, US_FL_BULK32), -/* Reported by - * The device reports a vendor-specific device class, requiring an - * explicit vendor/product match. - */ -UNUSUAL_DEV( 0x0851, 0x1542, 0x0002, 0x0002, - "MagicPixel", - "FW_Omega2", - USB_SC_DEVICE, USB_PR_DEVICE, NULL, 0), - /* Andrew Lunn * PanDigital Digital Picture Frame. Does not like ALLOW_MEDIUM_REMOVAL * on LUN 4. @@ -1881,15 +1872,6 @@ UNUSUAL_DEV( 0x1908, 0x3335, 0x0200, 0x0200, USB_SC_DEVICE, USB_PR_DEVICE, NULL, US_FL_NO_READ_DISC_INFO ), -/* Patch by Richard Schütz - * This external hard drive enclosure uses a JMicron chip which - * needs the US_FL_IGNORE_RESIDUE flag to work properly. */ -UNUSUAL_DEV( 0x1e68, 0x001b, 0x0000, 0x0000, - "TrekStor GmbH & Co. KG", - "DataStation maxi g.u", - USB_SC_DEVICE, USB_PR_DEVICE, NULL, - US_FL_IGNORE_RESIDUE | US_FL_SANE_SENSE ), - UNUSUAL_DEV( 0x2116, 0x0320, 0x0001, 0x0001, "ST", "2A", diff --git a/trunk/fs/cifs/Kconfig b/trunk/fs/cifs/Kconfig index 7cb0f7f847e4..ee45648b0d1a 100644 --- a/trunk/fs/cifs/Kconfig +++ b/trunk/fs/cifs/Kconfig @@ -3,7 +3,6 @@ config CIFS depends on INET select NLS select CRYPTO - select CRYPTO_MD4 select CRYPTO_MD5 select CRYPTO_HMAC select CRYPTO_ARC4 diff --git a/trunk/fs/cifs/cifs_dfs_ref.c b/trunk/fs/cifs/cifs_dfs_ref.c index 0a265ad9e426..f1c68629f277 100644 --- a/trunk/fs/cifs/cifs_dfs_ref.c +++ b/trunk/fs/cifs/cifs_dfs_ref.c @@ -282,6 +282,8 @@ static struct vfsmount *cifs_dfs_do_automount(struct dentry *mntpt) cFYI(1, "in %s", __func__); BUG_ON(IS_ROOT(mntpt)); + xid = GetXid(); + /* * The MSDFS spec states that paths in DFS referral requests and * responses must be prefixed by a single '\' character instead of @@ -291,7 +293,7 @@ static struct vfsmount *cifs_dfs_do_automount(struct dentry *mntpt) mnt = ERR_PTR(-ENOMEM); full_path = build_path_from_dentry(mntpt); if (full_path == NULL) - goto cdda_exit; + goto free_xid; cifs_sb = CIFS_SB(mntpt->d_inode->i_sb); tlink = cifs_sb_tlink(cifs_sb); @@ -301,11 +303,9 @@ static struct vfsmount *cifs_dfs_do_automount(struct dentry *mntpt) } ses = tlink_tcon(tlink)->ses; - xid = GetXid(); rc = get_dfs_path(xid, ses, full_path + 1, cifs_sb->local_nls, &num_referrals, &referrals, cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); - FreeXid(xid); cifs_put_tlink(tlink); @@ -338,7 +338,8 @@ static struct vfsmount *cifs_dfs_do_automount(struct dentry *mntpt) free_dfs_info_array(referrals, num_referrals); free_full_path: kfree(full_path); -cdda_exit: +free_xid: + FreeXid(xid); cFYI(1, "leaving %s" , __func__); return mnt; } diff --git a/trunk/fs/cifs/cifsencrypt.c b/trunk/fs/cifs/cifsencrypt.c index a51585f9852b..0db5f1de0227 100644 --- a/trunk/fs/cifs/cifsencrypt.c +++ b/trunk/fs/cifs/cifsencrypt.c @@ -657,10 +657,9 @@ calc_seckey(struct cifsSesInfo *ses) get_random_bytes(sec_key, CIFS_SESS_KEY_SIZE); tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC); - if (IS_ERR(tfm_arc4)) { - rc = PTR_ERR(tfm_arc4); + if (!tfm_arc4 || IS_ERR(tfm_arc4)) { cERROR(1, "could not allocate crypto API arc4\n"); - return rc; + return PTR_ERR(tfm_arc4); } desc.tfm = tfm_arc4; diff --git a/trunk/fs/cifs/cifsfs.h b/trunk/fs/cifs/cifsfs.h index 4a3330235d55..14789a97304e 100644 --- a/trunk/fs/cifs/cifsfs.h +++ b/trunk/fs/cifs/cifsfs.h @@ -127,5 +127,5 @@ extern long cifs_ioctl(struct file *filep, unsigned int cmd, unsigned long arg); extern const struct export_operations cifs_export_ops; #endif /* EXPERIMENTAL */ -#define CIFS_VERSION "1.70" +#define CIFS_VERSION "1.69" #endif /* _CIFSFS_H */ diff --git a/trunk/fs/cifs/cifssmb.c b/trunk/fs/cifs/cifssmb.c index 46c66ed01af4..3106f5e5c633 100644 --- a/trunk/fs/cifs/cifssmb.c +++ b/trunk/fs/cifs/cifssmb.c @@ -4914,6 +4914,7 @@ CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon, __u64 size, __u16 fid, __u32 pid_of_opener, bool SetAllocation) { struct smb_com_transaction2_sfi_req *pSMB = NULL; + char *data_offset; struct file_end_of_file_info *parm_data; int rc = 0; __u16 params, param_offset, offset, byte_count, count; @@ -4937,6 +4938,8 @@ CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon, __u64 size, param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4; offset = param_offset + params; + data_offset = (char *) (&pSMB->hdr.Protocol) + offset; + count = sizeof(struct file_end_of_file_info); pSMB->MaxParameterCount = cpu_to_le16(2); /* BB find exact max SMB PDU from sess structure BB */ diff --git a/trunk/fs/cifs/file.c b/trunk/fs/cifs/file.c index 74c0a282d012..0de17c1db608 100644 --- a/trunk/fs/cifs/file.c +++ b/trunk/fs/cifs/file.c @@ -346,6 +346,7 @@ int cifs_open(struct inode *inode, struct file *file) struct cifsTconInfo *tcon; struct tcon_link *tlink; struct cifsFileInfo *pCifsFile = NULL; + struct cifsInodeInfo *pCifsInode; char *full_path = NULL; bool posix_open_ok = false; __u16 netfid; @@ -360,6 +361,8 @@ int cifs_open(struct inode *inode, struct file *file) } tcon = tlink_tcon(tlink); + pCifsInode = CIFS_I(file->f_path.dentry->d_inode); + full_path = build_path_from_dentry(file->f_path.dentry); if (full_path == NULL) { rc = -ENOMEM; @@ -1143,6 +1146,7 @@ static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to) char *write_data; int rc = -EFAULT; int bytes_written = 0; + struct cifs_sb_info *cifs_sb; struct inode *inode; struct cifsFileInfo *open_file; @@ -1150,6 +1154,7 @@ static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to) return -EFAULT; inode = page->mapping->host; + cifs_sb = CIFS_SB(inode->i_sb); offset += (loff_t)from; write_data = kmap(page); @@ -1662,8 +1667,7 @@ static ssize_t cifs_iovec_write(struct file *file, const struct iovec *iov, unsigned long nr_segs, loff_t *poffset) { - size_t total_written = 0; - unsigned int written = 0; + size_t total_written = 0, written = 0; unsigned long num_pages, npages; size_t copied, len, cur_len, i; struct kvec *to_send; diff --git a/trunk/fs/cifs/link.c b/trunk/fs/cifs/link.c index e8804d373404..02cd60aefbff 100644 --- a/trunk/fs/cifs/link.c +++ b/trunk/fs/cifs/link.c @@ -55,9 +55,8 @@ symlink_hash(unsigned int link_len, const char *link_str, u8 *md5_hash) md5 = crypto_alloc_shash("md5", 0, 0); if (IS_ERR(md5)) { - rc = PTR_ERR(md5); cERROR(1, "%s: Crypto md5 allocation error %d\n", __func__, rc); - return rc; + return PTR_ERR(md5); } size = sizeof(struct shash_desc) + crypto_shash_descsize(md5); sdescmd5 = kmalloc(size, GFP_KERNEL); diff --git a/trunk/fs/cifs/misc.c b/trunk/fs/cifs/misc.c index 2a930a752a78..a09e077ba925 100644 --- a/trunk/fs/cifs/misc.c +++ b/trunk/fs/cifs/misc.c @@ -236,7 +236,10 @@ __u16 GetNextMid(struct TCP_Server_Info *server) { __u16 mid = 0; __u16 last_mid; - bool collision; + int collision; + + if (server == NULL) + return mid; spin_lock(&GlobalMid_Lock); last_mid = server->CurrentMid; /* we do not want to loop forever */ @@ -249,38 +252,24 @@ __u16 GetNextMid(struct TCP_Server_Info *server) (and it would also have to have been a request that did not time out) */ while (server->CurrentMid != last_mid) { + struct list_head *tmp; struct mid_q_entry *mid_entry; - unsigned int num_mids; - collision = false; + collision = 0; if (server->CurrentMid == 0) server->CurrentMid++; - num_mids = 0; - list_for_each_entry(mid_entry, &server->pending_mid_q, qhead) { - ++num_mids; - if (mid_entry->mid == server->CurrentMid && - mid_entry->midState == MID_REQUEST_SUBMITTED) { + list_for_each(tmp, &server->pending_mid_q) { + mid_entry = list_entry(tmp, struct mid_q_entry, qhead); + + if ((mid_entry->mid == server->CurrentMid) && + (mid_entry->midState == MID_REQUEST_SUBMITTED)) { /* This mid is in use, try a different one */ - collision = true; + collision = 1; break; } } - - /* - * if we have more than 32k mids in the list, then something - * is very wrong. Possibly a local user is trying to DoS the - * box by issuing long-running calls and SIGKILL'ing them. If - * we get to 2^16 mids then we're in big trouble as this - * function could loop forever. - * - * Go ahead and assign out the mid in this situation, but force - * an eventual reconnect to clean out the pending_mid_q. - */ - if (num_mids > 32768) - server->tcpStatus = CifsNeedReconnect; - - if (!collision) { + if (collision == 0) { mid = server->CurrentMid; break; } @@ -392,31 +381,29 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ , } static int -check_smb_hdr(struct smb_hdr *smb, __u16 mid) +checkSMBhdr(struct smb_hdr *smb, __u16 mid) { - /* does it have the right SMB "signature" ? */ - if (*(__le32 *) smb->Protocol != cpu_to_le32(0x424d53ff)) { - cERROR(1, "Bad protocol string signature header 0x%x", - *(unsigned int *)smb->Protocol); - return 1; - } - - /* Make sure that message ids match */ - if (mid != smb->Mid) { - cERROR(1, "Mids do not match. received=%u expected=%u", - smb->Mid, mid); - return 1; + /* Make sure that this really is an SMB, that it is a response, + and that the message ids match */ + if ((*(__le32 *) smb->Protocol == cpu_to_le32(0x424d53ff)) && + (mid == smb->Mid)) { + if (smb->Flags & SMBFLG_RESPONSE) + return 0; + else { + /* only one valid case where server sends us request */ + if (smb->Command == SMB_COM_LOCKING_ANDX) + return 0; + else + cERROR(1, "Received Request not response"); + } + } else { /* bad signature or mid */ + if (*(__le32 *) smb->Protocol != cpu_to_le32(0x424d53ff)) + cERROR(1, "Bad protocol string signature header %x", + *(unsigned int *) smb->Protocol); + if (mid != smb->Mid) + cERROR(1, "Mids do not match"); } - - /* if it's a response then accept */ - if (smb->Flags & SMBFLG_RESPONSE) - return 0; - - /* only one valid case where server sends us request */ - if (smb->Command == SMB_COM_LOCKING_ANDX) - return 0; - - cERROR(1, "Server sent request, not response. mid=%u", smb->Mid); + cERROR(1, "bad smb detected. The Mid=%d", smb->Mid); return 1; } @@ -461,7 +448,7 @@ checkSMB(struct smb_hdr *smb, __u16 mid, unsigned int length) return 1; } - if (check_smb_hdr(smb, mid)) + if (checkSMBhdr(smb, mid)) return 1; clc_len = smbCalcSize_LE(smb); @@ -478,26 +465,25 @@ checkSMB(struct smb_hdr *smb, __u16 mid, unsigned int length) if (((4 + len) & 0xFFFF) == (clc_len & 0xFFFF)) return 0; /* bcc wrapped */ } - cFYI(1, "Calculated size %u vs length %u mismatch for mid=%u", + cFYI(1, "Calculated size %d vs length %d mismatch for mid %d", clc_len, 4 + len, smb->Mid); - - if (4 + len < clc_len) { - cERROR(1, "RFC1001 size %u smaller than SMB for mid=%u", + /* Windows XP can return a few bytes too much, presumably + an illegal pad, at the end of byte range lock responses + so we allow for that three byte pad, as long as actual + received length is as long or longer than calculated length */ + /* We have now had to extend this more, since there is a + case in which it needs to be bigger still to handle a + malformed response to transact2 findfirst from WinXP when + access denied is returned and thus bcc and wct are zero + but server says length is 0x21 bytes too long as if the server + forget to reset the smb rfc1001 length when it reset the + wct and bcc to minimum size and drop the t2 parms and data */ + if ((4+len > clc_len) && (len <= clc_len + 512)) + return 0; + else { + cERROR(1, "RFC1001 size %d bigger than SMB for Mid=%d", len, smb->Mid); return 1; - } else if (len > clc_len + 512) { - /* - * Some servers (Windows XP in particular) send more - * data than the lengths in the SMB packet would - * indicate on certain calls (byte range locks and - * trans2 find first calls in particular). While the - * client can handle such a frame by ignoring the - * trailing data, we choose limit the amount of extra - * data to 512 bytes. - */ - cERROR(1, "RFC1001 size %u more than 512 bytes larger " - "than SMB for mid=%u", len, smb->Mid); - return 1; } } return 0; diff --git a/trunk/fs/cifs/readdir.c b/trunk/fs/cifs/readdir.c index f8e4cd2a7912..7f25cc3d2256 100644 --- a/trunk/fs/cifs/readdir.c +++ b/trunk/fs/cifs/readdir.c @@ -764,6 +764,7 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir) { int rc = 0; int xid, i; + struct cifs_sb_info *cifs_sb; struct cifsTconInfo *pTcon; struct cifsFileInfo *cifsFile = NULL; char *current_entry; @@ -774,6 +775,8 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir) xid = GetXid(); + cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); + /* * Ensure FindFirst doesn't fail before doing filldir() for '.' and * '..'. Otherwise we won't be able to notify VFS in case of failure. diff --git a/trunk/fs/cifs/smbencrypt.c b/trunk/fs/cifs/smbencrypt.c index b5041c849981..b5450e9f40c0 100644 --- a/trunk/fs/cifs/smbencrypt.c +++ b/trunk/fs/cifs/smbencrypt.c @@ -58,9 +58,8 @@ mdfour(unsigned char *md4_hash, unsigned char *link_str, int link_len) md4 = crypto_alloc_shash("md4", 0, 0); if (IS_ERR(md4)) { - rc = PTR_ERR(md4); cERROR(1, "%s: Crypto md4 allocation error %d\n", __func__, rc); - return rc; + return PTR_ERR(md4); } size = sizeof(struct shash_desc) + crypto_shash_descsize(md4); sdescmd4 = kmalloc(size, GFP_KERNEL); diff --git a/trunk/fs/cifs/transport.c b/trunk/fs/cifs/transport.c index b8c5e2eb43d0..c1ccca1a933f 100644 --- a/trunk/fs/cifs/transport.c +++ b/trunk/fs/cifs/transport.c @@ -236,9 +236,9 @@ smb_sendv(struct TCP_Server_Info *server, struct kvec *iov, int n_vec) server->tcpStatus = CifsNeedReconnect; } - if (rc < 0 && rc != -EINTR) + if (rc < 0) { cERROR(1, "Error %d sending data on socket to server", rc); - else + } else rc = 0; /* Don't want to modify the buffer as a @@ -570,33 +570,17 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses, #endif mutex_unlock(&ses->server->srv_mutex); + cifs_small_buf_release(in_buf); - if (rc < 0) { - cifs_small_buf_release(in_buf); + if (rc < 0) goto out; - } - if (long_op == CIFS_ASYNC_OP) { - cifs_small_buf_release(in_buf); + if (long_op == CIFS_ASYNC_OP) goto out; - } rc = wait_for_response(ses->server, midQ); - if (rc != 0) { - send_nt_cancel(ses->server, in_buf, midQ); - spin_lock(&GlobalMid_Lock); - if (midQ->midState == MID_REQUEST_SUBMITTED) { - midQ->callback = DeleteMidQEntry; - spin_unlock(&GlobalMid_Lock); - cifs_small_buf_release(in_buf); - atomic_dec(&ses->server->inFlight); - wake_up(&ses->server->request_q); - return rc; - } - spin_unlock(&GlobalMid_Lock); - } - - cifs_small_buf_release(in_buf); + if (rc != 0) + goto out; rc = sync_mid_result(midQ, ses->server); if (rc != 0) { @@ -740,19 +724,8 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses, goto out; rc = wait_for_response(ses->server, midQ); - if (rc != 0) { - send_nt_cancel(ses->server, in_buf, midQ); - spin_lock(&GlobalMid_Lock); - if (midQ->midState == MID_REQUEST_SUBMITTED) { - /* no longer considered to be "in-flight" */ - midQ->callback = DeleteMidQEntry; - spin_unlock(&GlobalMid_Lock); - atomic_dec(&ses->server->inFlight); - wake_up(&ses->server->request_q); - return rc; - } - spin_unlock(&GlobalMid_Lock); - } + if (rc != 0) + goto out; rc = sync_mid_result(midQ, ses->server); if (rc != 0) { @@ -949,21 +922,10 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon, } } - rc = wait_for_response(ses->server, midQ); - if (rc) { - send_nt_cancel(ses->server, in_buf, midQ); - spin_lock(&GlobalMid_Lock); - if (midQ->midState == MID_REQUEST_SUBMITTED) { - /* no longer considered to be "in-flight" */ - midQ->callback = DeleteMidQEntry; - spin_unlock(&GlobalMid_Lock); - return rc; - } - spin_unlock(&GlobalMid_Lock); + if (wait_for_response(ses->server, midQ) == 0) { + /* We got the response - restart system call. */ + rstart = 1; } - - /* We got the response - restart system call. */ - rstart = 1; } rc = sync_mid_result(midQ, ses->server); diff --git a/trunk/fs/eventpoll.c b/trunk/fs/eventpoll.c index 267d0ada4541..cc8a9b7d6064 100644 --- a/trunk/fs/eventpoll.c +++ b/trunk/fs/eventpoll.c @@ -1114,17 +1114,6 @@ static int ep_send_events(struct eventpoll *ep, return ep_scan_ready_list(ep, ep_send_events_proc, &esed); } -static inline struct timespec ep_set_mstimeout(long ms) -{ - struct timespec now, ts = { - .tv_sec = ms / MSEC_PER_SEC, - .tv_nsec = NSEC_PER_MSEC * (ms % MSEC_PER_SEC), - }; - - ktime_get_ts(&now); - return timespec_add_safe(now, ts); -} - static int ep_poll(struct eventpoll *ep, struct epoll_event __user *events, int maxevents, long timeout) { @@ -1132,11 +1121,12 @@ static int ep_poll(struct eventpoll *ep, struct epoll_event __user *events, unsigned long flags; long slack; wait_queue_t wait; + struct timespec end_time; ktime_t expires, *to = NULL; if (timeout > 0) { - struct timespec end_time = ep_set_mstimeout(timeout); - + ktime_get_ts(&end_time); + timespec_add_ns(&end_time, (u64)timeout * NSEC_PER_MSEC); slack = select_estimate_accuracy(&end_time); to = &expires; *to = timespec_to_ktime(end_time); diff --git a/trunk/fs/exec.c b/trunk/fs/exec.c index 52a447d9b6ab..c62efcb959c7 100644 --- a/trunk/fs/exec.c +++ b/trunk/fs/exec.c @@ -120,7 +120,7 @@ SYSCALL_DEFINE1(uselib, const char __user *, library) goto out; file = do_filp_open(AT_FDCWD, tmp, - O_LARGEFILE | O_RDONLY | __FMODE_EXEC, 0, + O_LARGEFILE | O_RDONLY | FMODE_EXEC, 0, MAY_READ | MAY_EXEC | MAY_OPEN); putname(tmp); error = PTR_ERR(file); @@ -723,7 +723,7 @@ struct file *open_exec(const char *name) int err; file = do_filp_open(AT_FDCWD, name, - O_LARGEFILE | O_RDONLY | __FMODE_EXEC, 0, + O_LARGEFILE | O_RDONLY | FMODE_EXEC, 0, MAY_EXEC | MAY_OPEN); if (IS_ERR(file)) goto out; diff --git a/trunk/fs/fcntl.c b/trunk/fs/fcntl.c index cb1026181bdc..ecc8b3954ed6 100644 --- a/trunk/fs/fcntl.c +++ b/trunk/fs/fcntl.c @@ -815,7 +815,7 @@ static int __init fcntl_init(void) __O_SYNC | O_DSYNC | FASYNC | O_DIRECT | O_LARGEFILE | O_DIRECTORY | O_NOFOLLOW | O_NOATIME | O_CLOEXEC | - __FMODE_EXEC + FMODE_EXEC )); fasync_cache = kmem_cache_create("fasync_cache", diff --git a/trunk/fs/ioctl.c b/trunk/fs/ioctl.c index 1eebeb72b202..a59635e295fa 100644 --- a/trunk/fs/ioctl.c +++ b/trunk/fs/ioctl.c @@ -273,13 +273,6 @@ int __generic_block_fiemap(struct inode *inode, len = isize; } - /* - * Some filesystems can't deal with being asked to map less than - * blocksize, so make sure our len is at least block length. - */ - if (logical_to_blk(inode, len) == 0) - len = blk_to_logical(inode, 1); - start_blk = logical_to_blk(inode, start); last_blk = logical_to_blk(inode, start + len - 1); diff --git a/trunk/fs/lockd/host.c b/trunk/fs/lockd/host.c index b7c99bfb3da6..5f1bcb2f06f3 100644 --- a/trunk/fs/lockd/host.c +++ b/trunk/fs/lockd/host.c @@ -520,7 +520,7 @@ static struct nlm_host *next_host_state(struct hlist_head *cache, struct nsm_handle *nsm, const struct nlm_reboot *info) { - struct nlm_host *host; + struct nlm_host *host = NULL; struct hlist_head *chain; struct hlist_node *pos; @@ -532,13 +532,12 @@ static struct nlm_host *next_host_state(struct hlist_head *cache, host->h_state++; nlm_get_host(host); - mutex_unlock(&nlm_host_mutex); - return host; + goto out; } } - +out: mutex_unlock(&nlm_host_mutex); - return NULL; + return host; } /** diff --git a/trunk/fs/nfs/callback.c b/trunk/fs/nfs/callback.c index e3d294269058..199016528fcb 100644 --- a/trunk/fs/nfs/callback.c +++ b/trunk/fs/nfs/callback.c @@ -134,6 +134,33 @@ nfs4_callback_up(struct svc_serv *serv) } #if defined(CONFIG_NFS_V4_1) +/* + * * CB_SEQUENCE operations will fail until the callback sessionid is set. + * */ +int nfs4_set_callback_sessionid(struct nfs_client *clp) +{ + struct svc_serv *serv = clp->cl_rpcclient->cl_xprt->bc_serv; + struct nfs4_sessionid *bc_sid; + + if (!serv->sv_bc_xprt) + return -EINVAL; + + /* on success freed in xprt_free */ + bc_sid = kmalloc(sizeof(struct nfs4_sessionid), GFP_KERNEL); + if (!bc_sid) + return -ENOMEM; + memcpy(bc_sid->data, &clp->cl_session->sess_id.data, + NFS4_MAX_SESSIONID_LEN); + spin_lock_bh(&serv->sv_cb_lock); + serv->sv_bc_xprt->xpt_bc_sid = bc_sid; + spin_unlock_bh(&serv->sv_cb_lock); + dprintk("%s set xpt_bc_sid=%u:%u:%u:%u for sv_bc_xprt %p\n", __func__, + ((u32 *)bc_sid->data)[0], ((u32 *)bc_sid->data)[1], + ((u32 *)bc_sid->data)[2], ((u32 *)bc_sid->data)[3], + serv->sv_bc_xprt); + return 0; +} + /* * The callback service for NFSv4.1 callbacks */ @@ -239,6 +266,10 @@ static inline void nfs_callback_bc_serv(u32 minorversion, struct rpc_xprt *xprt, struct nfs_callback_data *cb_info) { } +int nfs4_set_callback_sessionid(struct nfs_client *clp) +{ + return 0; +} #endif /* CONFIG_NFS_V4_1 */ /* @@ -328,58 +359,78 @@ void nfs_callback_down(int minorversion) mutex_unlock(&nfs_callback_mutex); } -/* Boolean check of RPC_AUTH_GSS principal */ -int -check_gss_callback_principal(struct nfs_client *clp, struct svc_rqst *rqstp) +static int check_gss_callback_principal(struct nfs_client *clp, + struct svc_rqst *rqstp) { struct rpc_clnt *r = clp->cl_rpcclient; char *p = svc_gss_principal(rqstp); - if (rqstp->rq_authop->flavour != RPC_AUTH_GSS) - return 1; - /* No RPC_AUTH_GSS on NFSv4.1 back channel yet */ if (clp->cl_minorversion != 0) - return 0; + return SVC_DROP; /* * It might just be a normal user principal, in which case * userspace won't bother to tell us the name at all. */ if (p == NULL) - return 0; + return SVC_DENIED; /* Expect a GSS_C_NT_HOSTBASED_NAME like "nfs@serverhostname" */ if (memcmp(p, "nfs@", 4) != 0) - return 0; + return SVC_DENIED; p += 4; if (strcmp(p, r->cl_server) != 0) - return 0; - return 1; + return SVC_DENIED; + return SVC_OK; } -/* - * pg_authenticate method for nfsv4 callback threads. - * - * The authflavor has been negotiated, so an incorrect flavor is a server - * bug. Drop packets with incorrect authflavor. - * - * All other checking done after NFS decoding where the nfs_client can be - * found in nfs4_callback_compound - */ +/* pg_authenticate method helper */ +static struct nfs_client *nfs_cb_find_client(struct svc_rqst *rqstp) +{ + struct nfs4_sessionid *sessionid = bc_xprt_sid(rqstp); + int is_cb_compound = rqstp->rq_proc == CB_COMPOUND ? 1 : 0; + + dprintk("--> %s rq_proc %d\n", __func__, rqstp->rq_proc); + if (svc_is_backchannel(rqstp)) + /* Sessionid (usually) set after CB_NULL ping */ + return nfs4_find_client_sessionid(svc_addr(rqstp), sessionid, + is_cb_compound); + else + /* No callback identifier in pg_authenticate */ + return nfs4_find_client_no_ident(svc_addr(rqstp)); +} + +/* pg_authenticate method for nfsv4 callback threads. */ static int nfs_callback_authenticate(struct svc_rqst *rqstp) { + struct nfs_client *clp; + RPC_IFDEBUG(char buf[RPC_MAX_ADDRBUFLEN]); + int ret = SVC_OK; + + /* Don't talk to strangers */ + clp = nfs_cb_find_client(rqstp); + if (clp == NULL) + return SVC_DROP; + + dprintk("%s: %s NFSv4 callback!\n", __func__, + svc_print_addr(rqstp, buf, sizeof(buf))); + switch (rqstp->rq_authop->flavour) { - case RPC_AUTH_NULL: - if (rqstp->rq_proc != CB_NULL) - return SVC_DROP; - break; - case RPC_AUTH_GSS: - /* No RPC_AUTH_GSS support yet in NFSv4.1 */ - if (svc_is_backchannel(rqstp)) - return SVC_DROP; + case RPC_AUTH_NULL: + if (rqstp->rq_proc != CB_NULL) + ret = SVC_DENIED; + break; + case RPC_AUTH_UNIX: + break; + case RPC_AUTH_GSS: + ret = check_gss_callback_principal(clp, rqstp); + break; + default: + ret = SVC_DENIED; } - return SVC_OK; + nfs_put_client(clp); + return ret; } /* diff --git a/trunk/fs/nfs/callback.h b/trunk/fs/nfs/callback.h index 46d93ce7311b..d3b44f9bd747 100644 --- a/trunk/fs/nfs/callback.h +++ b/trunk/fs/nfs/callback.h @@ -7,7 +7,6 @@ */ #ifndef __LINUX_FS_NFS_CALLBACK_H #define __LINUX_FS_NFS_CALLBACK_H -#include #define NFS4_CALLBACK 0x40000000 #define NFS4_CALLBACK_XDRSIZE 2048 @@ -38,6 +37,7 @@ enum nfs4_callback_opnum { struct cb_process_state { __be32 drc_status; struct nfs_client *clp; + struct nfs4_sessionid *svc_sid; /* v4.1 callback service sessionid */ }; struct cb_compound_hdr_arg { @@ -168,7 +168,7 @@ extern unsigned nfs4_callback_layoutrecall( extern void nfs4_check_drain_bc_complete(struct nfs4_session *ses); extern void nfs4_cb_take_slot(struct nfs_client *clp); #endif /* CONFIG_NFS_V4_1 */ -extern int check_gss_callback_principal(struct nfs_client *, struct svc_rqst *); + extern __be32 nfs4_callback_getattr(struct cb_getattrargs *args, struct cb_getattrres *res, struct cb_process_state *cps); diff --git a/trunk/fs/nfs/callback_proc.c b/trunk/fs/nfs/callback_proc.c index 89587573fe50..4bb91cb2620d 100644 --- a/trunk/fs/nfs/callback_proc.c +++ b/trunk/fs/nfs/callback_proc.c @@ -373,11 +373,17 @@ __be32 nfs4_callback_sequence(struct cb_sequenceargs *args, { struct nfs_client *clp; int i; - __be32 status = htonl(NFS4ERR_BADSESSION); + __be32 status; cps->clp = NULL; - clp = nfs4_find_client_sessionid(args->csa_addr, &args->csa_sessionid); + status = htonl(NFS4ERR_BADSESSION); + /* Incoming session must match the callback session */ + if (memcmp(&args->csa_sessionid, cps->svc_sid, NFS4_MAX_SESSIONID_LEN)) + goto out; + + clp = nfs4_find_client_sessionid(args->csa_addr, + &args->csa_sessionid, 1); if (clp == NULL) goto out; @@ -408,9 +414,9 @@ __be32 nfs4_callback_sequence(struct cb_sequenceargs *args, res->csr_highestslotid = NFS41_BC_MAX_CALLBACKS - 1; res->csr_target_highestslotid = NFS41_BC_MAX_CALLBACKS - 1; nfs4_cb_take_slot(clp); + cps->clp = clp; /* put in nfs4_callback_compound */ out: - cps->clp = clp; /* put in nfs4_callback_compound */ for (i = 0; i < args->csa_nrclists; i++) kfree(args->csa_rclists[i].rcl_refcalls); kfree(args->csa_rclists); diff --git a/trunk/fs/nfs/callback_xdr.c b/trunk/fs/nfs/callback_xdr.c index 14e0f9371d14..23112c263f81 100644 --- a/trunk/fs/nfs/callback_xdr.c +++ b/trunk/fs/nfs/callback_xdr.c @@ -794,9 +794,10 @@ static __be32 nfs4_callback_compound(struct svc_rqst *rqstp, void *argp, void *r if (hdr_arg.minorversion == 0) { cps.clp = nfs4_find_client_ident(hdr_arg.cb_ident); - if (!cps.clp || !check_gss_callback_principal(cps.clp, rqstp)) + if (!cps.clp) return rpc_drop_reply; - } + } else + cps.svc_sid = bc_xprt_sid(rqstp); hdr_res.taglen = hdr_arg.taglen; hdr_res.tag = hdr_arg.tag; diff --git a/trunk/fs/nfs/client.c b/trunk/fs/nfs/client.c index bd3ca32879e7..192f2f860265 100644 --- a/trunk/fs/nfs/client.c +++ b/trunk/fs/nfs/client.c @@ -1206,11 +1206,16 @@ nfs4_find_client_ident(int cb_ident) * For CB_COMPOUND calls, find a client by IP address, protocol version, * minorversion, and sessionID * + * CREATE_SESSION triggers a CB_NULL ping from servers. The callback service + * sessionid can only be set after the CREATE_SESSION return, so a CB_NULL + * can arrive before the callback sessionid is set. For CB_NULL calls, + * find a client by IP address protocol version, and minorversion. + * * Returns NULL if no such client */ struct nfs_client * nfs4_find_client_sessionid(const struct sockaddr *addr, - struct nfs4_sessionid *sid) + struct nfs4_sessionid *sid, int is_cb_compound) { struct nfs_client *clp; @@ -1222,9 +1227,9 @@ nfs4_find_client_sessionid(const struct sockaddr *addr, if (!nfs4_has_session(clp)) continue; - /* Match sessionid*/ - if (memcmp(clp->cl_session->sess_id.data, - sid->data, NFS4_MAX_SESSIONID_LEN) != 0) + /* Match sessionid unless cb_null call*/ + if (is_cb_compound && (memcmp(clp->cl_session->sess_id.data, + sid->data, NFS4_MAX_SESSIONID_LEN) != 0)) continue; atomic_inc(&clp->cl_count); @@ -1239,7 +1244,7 @@ nfs4_find_client_sessionid(const struct sockaddr *addr, struct nfs_client * nfs4_find_client_sessionid(const struct sockaddr *addr, - struct nfs4_sessionid *sid) + struct nfs4_sessionid *sid, int is_cb_compound) { return NULL; } diff --git a/trunk/fs/nfs/delegation.c b/trunk/fs/nfs/delegation.c index bbbc6bf5cb2e..364e4328f392 100644 --- a/trunk/fs/nfs/delegation.c +++ b/trunk/fs/nfs/delegation.c @@ -23,6 +23,8 @@ static void nfs_do_free_delegation(struct nfs_delegation *delegation) { + if (delegation->cred) + put_rpccred(delegation->cred); kfree(delegation); } @@ -35,10 +37,6 @@ static void nfs_free_delegation_callback(struct rcu_head *head) static void nfs_free_delegation(struct nfs_delegation *delegation) { - if (delegation->cred) { - put_rpccred(delegation->cred); - delegation->cred = NULL; - } call_rcu(&delegation->rcu, nfs_free_delegation_callback); } diff --git a/trunk/fs/nfs/direct.c b/trunk/fs/nfs/direct.c index 9943a75bb6d1..e6ace0d93c71 100644 --- a/trunk/fs/nfs/direct.c +++ b/trunk/fs/nfs/direct.c @@ -407,18 +407,15 @@ static ssize_t nfs_direct_read_schedule_iovec(struct nfs_direct_req *dreq, pos += vec->iov_len; } - /* - * If no bytes were started, return the error, and let the - * generic layer handle the completion. - */ - if (requested_bytes == 0) { - nfs_direct_req_release(dreq); - return result < 0 ? result : -EIO; - } - if (put_dreq(dreq)) nfs_direct_complete(dreq); - return 0; + + if (requested_bytes != 0) + return 0; + + if (result < 0) + return result; + return -EIO; } static ssize_t nfs_direct_read(struct kiocb *iocb, const struct iovec *iov, @@ -844,18 +841,15 @@ static ssize_t nfs_direct_write_schedule_iovec(struct nfs_direct_req *dreq, pos += vec->iov_len; } - /* - * If no bytes were started, return the error, and let the - * generic layer handle the completion. - */ - if (requested_bytes == 0) { - nfs_direct_req_release(dreq); - return result < 0 ? result : -EIO; - } - if (put_dreq(dreq)) nfs_direct_write_complete(dreq, dreq->inode); - return 0; + + if (requested_bytes != 0) + return 0; + + if (result < 0) + return result; + return -EIO; } static ssize_t nfs_direct_write(struct kiocb *iocb, const struct iovec *iov, diff --git a/trunk/fs/nfs/inode.c b/trunk/fs/nfs/inode.c index 1cc600e77bb4..d8512423ba72 100644 --- a/trunk/fs/nfs/inode.c +++ b/trunk/fs/nfs/inode.c @@ -881,10 +881,9 @@ int nfs_revalidate_mapping(struct inode *inode, struct address_space *mapping) return ret; } -static unsigned long nfs_wcc_update_inode(struct inode *inode, struct nfs_fattr *fattr) +static void nfs_wcc_update_inode(struct inode *inode, struct nfs_fattr *fattr) { struct nfs_inode *nfsi = NFS_I(inode); - unsigned long ret = 0; if ((fattr->valid & NFS_ATTR_FATTR_PRECHANGE) && (fattr->valid & NFS_ATTR_FATTR_CHANGE) @@ -892,32 +891,25 @@ static unsigned long nfs_wcc_update_inode(struct inode *inode, struct nfs_fattr nfsi->change_attr = fattr->change_attr; if (S_ISDIR(inode->i_mode)) nfsi->cache_validity |= NFS_INO_INVALID_DATA; - ret |= NFS_INO_INVALID_ATTR; } /* If we have atomic WCC data, we may update some attributes */ if ((fattr->valid & NFS_ATTR_FATTR_PRECTIME) && (fattr->valid & NFS_ATTR_FATTR_CTIME) - && timespec_equal(&inode->i_ctime, &fattr->pre_ctime)) { - memcpy(&inode->i_ctime, &fattr->ctime, sizeof(inode->i_ctime)); - ret |= NFS_INO_INVALID_ATTR; - } + && timespec_equal(&inode->i_ctime, &fattr->pre_ctime)) + memcpy(&inode->i_ctime, &fattr->ctime, sizeof(inode->i_ctime)); if ((fattr->valid & NFS_ATTR_FATTR_PREMTIME) && (fattr->valid & NFS_ATTR_FATTR_MTIME) && timespec_equal(&inode->i_mtime, &fattr->pre_mtime)) { - memcpy(&inode->i_mtime, &fattr->mtime, sizeof(inode->i_mtime)); - if (S_ISDIR(inode->i_mode)) - nfsi->cache_validity |= NFS_INO_INVALID_DATA; - ret |= NFS_INO_INVALID_ATTR; + memcpy(&inode->i_mtime, &fattr->mtime, sizeof(inode->i_mtime)); + if (S_ISDIR(inode->i_mode)) + nfsi->cache_validity |= NFS_INO_INVALID_DATA; } if ((fattr->valid & NFS_ATTR_FATTR_PRESIZE) && (fattr->valid & NFS_ATTR_FATTR_SIZE) && i_size_read(inode) == nfs_size_to_loff_t(fattr->pre_size) - && nfsi->npages == 0) { - i_size_write(inode, nfs_size_to_loff_t(fattr->size)); - ret |= NFS_INO_INVALID_ATTR; - } - return ret; + && nfsi->npages == 0) + i_size_write(inode, nfs_size_to_loff_t(fattr->size)); } /** @@ -1231,7 +1223,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) | NFS_INO_REVAL_PAGECACHE); /* Do atomic weak cache consistency updates */ - invalid |= nfs_wcc_update_inode(inode, fattr); + nfs_wcc_update_inode(inode, fattr); /* More cache consistency checks */ if (fattr->valid & NFS_ATTR_FATTR_CHANGE) { diff --git a/trunk/fs/nfs/internal.h b/trunk/fs/nfs/internal.h index cf9fdbdabc67..4644f04b4b46 100644 --- a/trunk/fs/nfs/internal.h +++ b/trunk/fs/nfs/internal.h @@ -133,7 +133,8 @@ extern void nfs_put_client(struct nfs_client *); extern struct nfs_client *nfs4_find_client_no_ident(const struct sockaddr *); extern struct nfs_client *nfs4_find_client_ident(int); extern struct nfs_client * -nfs4_find_client_sessionid(const struct sockaddr *, struct nfs4_sessionid *); +nfs4_find_client_sessionid(const struct sockaddr *, struct nfs4_sessionid *, + int); extern struct nfs_server *nfs_create_server( const struct nfs_parsed_mount_data *, struct nfs_fh *); diff --git a/trunk/fs/nfs/nfs3acl.c b/trunk/fs/nfs/nfs3acl.c index 274342771655..9f88c5f4c7e2 100644 --- a/trunk/fs/nfs/nfs3acl.c +++ b/trunk/fs/nfs/nfs3acl.c @@ -311,8 +311,8 @@ static int nfs3_proc_setacls(struct inode *inode, struct posix_acl *acl, if (!nfs_server_capable(inode, NFS_CAP_ACLS)) goto out; - /* We are doing this here because XDR marshalling does not - * return any results, it BUGs. */ + /* We are doing this here, because XDR marshalling can only + return -ENOMEM. */ status = -ENOSPC; if (acl != NULL && acl->a_count > NFS_ACL_MAX_ENTRIES) goto out; diff --git a/trunk/fs/nfs/nfs3xdr.c b/trunk/fs/nfs/nfs3xdr.c index 183c6b123d0f..01c5e8b1941d 100644 --- a/trunk/fs/nfs/nfs3xdr.c +++ b/trunk/fs/nfs/nfs3xdr.c @@ -1328,13 +1328,10 @@ static void nfs3_xdr_enc_setacl3args(struct rpc_rqst *req, encode_nfs_fh3(xdr, NFS_FH(args->inode)); encode_uint32(xdr, args->mask); - - base = req->rq_slen; if (args->npages != 0) xdr_write_pages(xdr, args->pages, 0, args->len); - else - xdr_reserve_space(xdr, NFS_ACL_INLINE_BUFSIZE); + base = req->rq_slen; error = nfsacl_encode(xdr->buf, base, args->inode, (args->mask & NFS_ACL) ? args->acl_access : NULL, 1, 0); diff --git a/trunk/fs/nfs/nfs4filelayoutdev.c b/trunk/fs/nfs/nfs4filelayoutdev.c index f5c9b125e8cc..51fe64ace55a 100644 --- a/trunk/fs/nfs/nfs4filelayoutdev.c +++ b/trunk/fs/nfs/nfs4filelayoutdev.c @@ -214,7 +214,7 @@ decode_and_add_ds(__be32 **pp, struct inode *inode) /* ipv6 length plus port is legal */ if (rlen > INET6_ADDRSTRLEN + 8) { - dprintk("%s: Invalid address, length %d\n", __func__, + dprintk("%s Invalid address, length %d\n", __func__, rlen); goto out_err; } @@ -225,11 +225,6 @@ decode_and_add_ds(__be32 **pp, struct inode *inode) /* replace the port dots with dashes for the in4_pton() delimiter*/ for (i = 0; i < 2; i++) { char *res = strrchr(buf, '.'); - if (!res) { - dprintk("%s: Failed finding expected dots in port\n", - __func__); - goto out_free; - } *res = '-'; } @@ -245,7 +240,7 @@ decode_and_add_ds(__be32 **pp, struct inode *inode) port = htons((tmp[0] << 8) | (tmp[1])); ds = nfs4_pnfs_ds_add(inode, ip_addr, port); - dprintk("%s: Decoded address and port %s\n", __func__, buf); + dprintk("%s Decoded address and port %s\n", __func__, buf); out_free: kfree(buf); out_err: diff --git a/trunk/fs/nfs/nfs4proc.c b/trunk/fs/nfs/nfs4proc.c index 78936a8f40ab..9d992b0346e3 100644 --- a/trunk/fs/nfs/nfs4proc.c +++ b/trunk/fs/nfs/nfs4proc.c @@ -50,7 +50,6 @@ #include #include #include -#include #include "nfs4_fs.h" #include "delegation.h" @@ -4573,16 +4572,27 @@ int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred) *p = htonl((u32)clp->cl_boot_time.tv_nsec); args.verifier = &verifier; - args.id_len = scnprintf(args.id, sizeof(args.id), - "%s/%s.%s/%u", - clp->cl_ipaddr, - init_utsname()->nodename, - init_utsname()->domainname, - clp->cl_rpcclient->cl_auth->au_flavor); + while (1) { + args.id_len = scnprintf(args.id, sizeof(args.id), + "%s/%s %u", + clp->cl_ipaddr, + rpc_peeraddr2str(clp->cl_rpcclient, + RPC_DISPLAY_ADDR), + clp->cl_id_uniquifier); - status = rpc_call_sync(clp->cl_rpcclient, &msg, 0); - if (!status) - status = nfs4_check_cl_exchange_flags(clp->cl_exchange_flags); + status = rpc_call_sync(clp->cl_rpcclient, &msg, 0); + + if (status != -NFS4ERR_CLID_INUSE) + break; + + if (signalled()) + break; + + if (++clp->cl_id_uniquifier == 0) + break; + } + + status = nfs4_check_cl_exchange_flags(clp->cl_exchange_flags); dprintk("<-- %s status= %d\n", __func__, status); return status; } diff --git a/trunk/fs/nfs/nfs4state.c b/trunk/fs/nfs/nfs4state.c index e6742b57a04c..2336d532cf66 100644 --- a/trunk/fs/nfs/nfs4state.c +++ b/trunk/fs/nfs/nfs4state.c @@ -232,6 +232,12 @@ int nfs41_init_clientid(struct nfs_client *clp, struct rpc_cred *cred) status = nfs4_proc_create_session(clp); if (status != 0) goto out; + status = nfs4_set_callback_sessionid(clp); + if (status != 0) { + printk(KERN_WARNING "Sessionid not set. No callback service\n"); + nfs_callback_down(1); + status = 0; + } nfs41_setup_state_renewal(clp); nfs_mark_client_ready(clp, NFS_CS_READY); out: diff --git a/trunk/fs/nfs/nfs4xdr.c b/trunk/fs/nfs/nfs4xdr.c index 4e2c168b6ee9..2ab8e5cb8f59 100644 --- a/trunk/fs/nfs/nfs4xdr.c +++ b/trunk/fs/nfs/nfs4xdr.c @@ -6086,11 +6086,11 @@ int nfs4_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, __be32 *p = xdr_inline_decode(xdr, 4); if (unlikely(!p)) goto out_overflow; - if (*p == xdr_zero) { + if (!ntohl(*p++)) { p = xdr_inline_decode(xdr, 4); if (unlikely(!p)) goto out_overflow; - if (*p == xdr_zero) + if (!ntohl(*p++)) return -EAGAIN; entry->eof = 1; return -EBADCOOKIE; @@ -6101,7 +6101,7 @@ int nfs4_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, goto out_overflow; entry->prev_cookie = entry->cookie; p = xdr_decode_hyper(p, &entry->cookie); - entry->len = be32_to_cpup(p); + entry->len = ntohl(*p++); p = xdr_inline_decode(xdr, entry->len); if (unlikely(!p)) @@ -6132,6 +6132,9 @@ int nfs4_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, if (entry->fattr->valid & NFS_ATTR_FATTR_TYPE) entry->d_type = nfs_umode_to_dtype(entry->fattr->mode); + if (verify_attr_len(xdr, p, len) < 0) + goto out_overflow; + return 0; out_overflow: diff --git a/trunk/fs/nfs/pnfs.c b/trunk/fs/nfs/pnfs.c index 1b1bc1a0fb0a..bc4089769735 100644 --- a/trunk/fs/nfs/pnfs.c +++ b/trunk/fs/nfs/pnfs.c @@ -951,7 +951,7 @@ pnfs_put_deviceid_cache(struct nfs_client *clp) { struct pnfs_deviceid_cache *local = clp->cl_devid_cache; - dprintk("--> %s ({%d})\n", __func__, atomic_read(&local->dc_ref)); + dprintk("--> %s cl_devid_cache %p\n", __func__, clp->cl_devid_cache); if (atomic_dec_and_lock(&local->dc_ref, &clp->cl_lock)) { int i; /* Verify cache is empty */ diff --git a/trunk/fs/nfs/write.c b/trunk/fs/nfs/write.c index c8278f4046cb..10d648ea128b 100644 --- a/trunk/fs/nfs/write.c +++ b/trunk/fs/nfs/write.c @@ -932,7 +932,7 @@ static int nfs_flush_multi(struct inode *inode, struct list_head *head, unsigned while (!list_empty(&list)) { data = list_entry(list.next, struct nfs_write_data, pages); list_del(&data->pages); - nfs_writedata_free(data); + nfs_writedata_release(data); } nfs_redirty_request(req); return -ENOMEM; diff --git a/trunk/fs/nfs_common/nfsacl.c b/trunk/fs/nfs_common/nfsacl.c index 84c27d69d421..fc1c52571c03 100644 --- a/trunk/fs/nfs_common/nfsacl.c +++ b/trunk/fs/nfs_common/nfsacl.c @@ -42,11 +42,6 @@ struct nfsacl_encode_desc { gid_t gid; }; -struct nfsacl_simple_acl { - struct posix_acl acl; - struct posix_acl_entry ace[4]; -}; - static int xdr_nfsace_encode(struct xdr_array2_desc *desc, void *elem) { @@ -77,20 +72,9 @@ xdr_nfsace_encode(struct xdr_array2_desc *desc, void *elem) return 0; } -/** - * nfsacl_encode - Encode an NFSv3 ACL - * - * @buf: destination xdr_buf to contain XDR encoded ACL - * @base: byte offset in xdr_buf where XDR'd ACL begins - * @inode: inode of file whose ACL this is - * @acl: posix_acl to encode - * @encode_entries: whether to encode ACEs as well - * @typeflag: ACL type: NFS_ACL_DEFAULT or zero - * - * Returns size of encoded ACL in bytes or a negative errno value. - */ -int nfsacl_encode(struct xdr_buf *buf, unsigned int base, struct inode *inode, - struct posix_acl *acl, int encode_entries, int typeflag) +unsigned int +nfsacl_encode(struct xdr_buf *buf, unsigned int base, struct inode *inode, + struct posix_acl *acl, int encode_entries, int typeflag) { int entries = (acl && acl->a_count) ? max_t(int, acl->a_count, 4) : 0; struct nfsacl_encode_desc nfsacl_desc = { @@ -104,22 +88,17 @@ int nfsacl_encode(struct xdr_buf *buf, unsigned int base, struct inode *inode, .uid = inode->i_uid, .gid = inode->i_gid, }; - struct nfsacl_simple_acl aclbuf; int err; + struct posix_acl *acl2 = NULL; if (entries > NFS_ACL_MAX_ENTRIES || xdr_encode_word(buf, base, entries)) return -EINVAL; if (encode_entries && acl && acl->a_count == 3) { - struct posix_acl *acl2 = &aclbuf.acl; - - /* Avoid the use of posix_acl_alloc(). nfsacl_encode() is - * invoked in contexts where a memory allocation failure is - * fatal. Fortunately this fake ACL is small enough to - * construct on the stack. */ - memset(acl2, 0, sizeof(acl2)); - posix_acl_init(acl2, 4); - + /* Fake up an ACL_MASK entry. */ + acl2 = posix_acl_alloc(4, GFP_KERNEL); + if (!acl2) + return -ENOMEM; /* Insert entries in canonical order: other orders seem to confuse Solaris VxFS. */ acl2->a_entries[0] = acl->a_entries[0]; /* ACL_USER_OBJ */ @@ -130,6 +109,8 @@ int nfsacl_encode(struct xdr_buf *buf, unsigned int base, struct inode *inode, nfsacl_desc.acl = acl2; } err = xdr_encode_array2(buf, base + 4, &nfsacl_desc.desc); + if (acl2) + posix_acl_release(acl2); if (!err) err = 8 + nfsacl_desc.desc.elem_size * nfsacl_desc.desc.array_len; @@ -243,18 +224,9 @@ posix_acl_from_nfsacl(struct posix_acl *acl) return 0; } -/** - * nfsacl_decode - Decode an NFSv3 ACL - * - * @buf: xdr_buf containing XDR'd ACL data to decode - * @base: byte offset in xdr_buf where XDR'd ACL begins - * @aclcnt: count of ACEs in decoded posix_acl - * @pacl: buffer in which to place decoded posix_acl - * - * Returns the length of the decoded ACL in bytes, or a negative errno value. - */ -int nfsacl_decode(struct xdr_buf *buf, unsigned int base, unsigned int *aclcnt, - struct posix_acl **pacl) +unsigned int +nfsacl_decode(struct xdr_buf *buf, unsigned int base, unsigned int *aclcnt, + struct posix_acl **pacl) { struct nfsacl_decode_desc nfsacl_desc = { .desc = { diff --git a/trunk/fs/posix_acl.c b/trunk/fs/posix_acl.c index b1cf6bf4b41d..39df95a0ec25 100644 --- a/trunk/fs/posix_acl.c +++ b/trunk/fs/posix_acl.c @@ -22,7 +22,6 @@ #include -EXPORT_SYMBOL(posix_acl_init); EXPORT_SYMBOL(posix_acl_alloc); EXPORT_SYMBOL(posix_acl_clone); EXPORT_SYMBOL(posix_acl_valid); @@ -32,16 +31,6 @@ EXPORT_SYMBOL(posix_acl_create_masq); EXPORT_SYMBOL(posix_acl_chmod_masq); EXPORT_SYMBOL(posix_acl_permission); -/* - * Init a fresh posix_acl - */ -void -posix_acl_init(struct posix_acl *acl, int count) -{ - atomic_set(&acl->a_refcount, 1); - acl->a_count = count; -} - /* * Allocate a new ACL with the specified number of entries. */ @@ -51,8 +40,10 @@ posix_acl_alloc(int count, gfp_t flags) const size_t size = sizeof(struct posix_acl) + count * sizeof(struct posix_acl_entry); struct posix_acl *acl = kmalloc(size, flags); - if (acl) - posix_acl_init(acl, count); + if (acl) { + atomic_set(&acl->a_refcount, 1); + acl->a_count = count; + } return acl; } diff --git a/trunk/fs/xfs/linux-2.6/xfs_ioctl.c b/trunk/fs/xfs/linux-2.6/xfs_ioctl.c index f5e2a19e0f8e..b06ede1d0bed 100644 --- a/trunk/fs/xfs/linux-2.6/xfs_ioctl.c +++ b/trunk/fs/xfs/linux-2.6/xfs_ioctl.c @@ -985,22 +985,10 @@ xfs_ioctl_setattr( /* * Extent size must be a multiple of the appropriate block - * size, if set at all. It must also be smaller than the - * maximum extent size supported by the filesystem. - * - * Also, for non-realtime files, limit the extent size hint to - * half the size of the AGs in the filesystem so alignment - * doesn't result in extents larger than an AG. + * size, if set at all. */ if (fa->fsx_extsize != 0) { - xfs_extlen_t size; - xfs_fsblock_t extsize_fsb; - - extsize_fsb = XFS_B_TO_FSB(mp, fa->fsx_extsize); - if (extsize_fsb > MAXEXTLEN) { - code = XFS_ERROR(EINVAL); - goto error_return; - } + xfs_extlen_t size; if (XFS_IS_REALTIME_INODE(ip) || ((mask & FSX_XFLAGS) && @@ -1009,10 +997,6 @@ xfs_ioctl_setattr( mp->m_sb.sb_blocklog; } else { size = mp->m_sb.sb_blocksize; - if (extsize_fsb > mp->m_sb.sb_agblocks / 2) { - code = XFS_ERROR(EINVAL); - goto error_return; - } } if (fa->fsx_extsize % size) { diff --git a/trunk/fs/xfs/quota/xfs_qm.c b/trunk/fs/xfs/quota/xfs_qm.c index 206a2815ced6..f8e854b4fde8 100644 --- a/trunk/fs/xfs/quota/xfs_qm.c +++ b/trunk/fs/xfs/quota/xfs_qm.c @@ -1863,14 +1863,12 @@ xfs_qm_dqreclaim_one(void) xfs_dquot_t *dqpout; xfs_dquot_t *dqp; int restarts; - int startagain; restarts = 0; dqpout = NULL; /* lockorder: hashchainlock, freelistlock, mplistlock, dqlock, dqflock */ -again: - startagain = 0; +startagain: mutex_lock(&xfs_Gqm->qm_dqfrlist_lock); list_for_each_entry(dqp, &xfs_Gqm->qm_dqfrlist, q_freelist) { @@ -1887,10 +1885,13 @@ xfs_qm_dqreclaim_one(void) ASSERT(! (dqp->dq_flags & XFS_DQ_INACTIVE)); trace_xfs_dqreclaim_want(dqp); + + xfs_dqunlock(dqp); + mutex_unlock(&xfs_Gqm->qm_dqfrlist_lock); + if (++restarts >= XFS_QM_RECLAIM_MAX_RESTARTS) + return NULL; XQM_STATS_INC(xqmstats.xs_qm_dqwants); - restarts++; - startagain = 1; - goto dqunlock; + goto startagain; } /* @@ -1905,20 +1906,23 @@ xfs_qm_dqreclaim_one(void) ASSERT(list_empty(&dqp->q_mplist)); list_del_init(&dqp->q_freelist); xfs_Gqm->qm_dqfrlist_cnt--; + xfs_dqunlock(dqp); dqpout = dqp; XQM_STATS_INC(xqmstats.xs_qm_dqinact_reclaims); - goto dqunlock; + break; } ASSERT(dqp->q_hash); ASSERT(!list_empty(&dqp->q_mplist)); /* - * Try to grab the flush lock. If this dquot is in the process - * of getting flushed to disk, we don't want to reclaim it. + * Try to grab the flush lock. If this dquot is in the process of + * getting flushed to disk, we don't want to reclaim it. */ - if (!xfs_dqflock_nowait(dqp)) - goto dqunlock; + if (!xfs_dqflock_nowait(dqp)) { + xfs_dqunlock(dqp); + continue; + } /* * We have the flush lock so we know that this is not in the @@ -1940,7 +1944,8 @@ xfs_qm_dqreclaim_one(void) xfs_fs_cmn_err(CE_WARN, mp, "xfs_qm_dqreclaim: dquot %p flush failed", dqp); } - goto dqunlock; + xfs_dqunlock(dqp); /* dqflush unlocks dqflock */ + continue; } /* @@ -1962,8 +1967,13 @@ xfs_qm_dqreclaim_one(void) */ if (!mutex_trylock(&mp->m_quotainfo->qi_dqlist_lock)) { restarts++; - startagain = 1; - goto qhunlock; + mutex_unlock(&dqp->q_hash->qh_lock); + xfs_dqfunlock(dqp); + xfs_dqunlock(dqp); + mutex_unlock(&xfs_Gqm->qm_dqfrlist_lock); + if (restarts++ >= XFS_QM_RECLAIM_MAX_RESTARTS) + return NULL; + goto startagain; } ASSERT(dqp->q_nrefs == 0); @@ -1976,20 +1986,14 @@ xfs_qm_dqreclaim_one(void) xfs_Gqm->qm_dqfrlist_cnt--; dqpout = dqp; mutex_unlock(&mp->m_quotainfo->qi_dqlist_lock); -qhunlock: mutex_unlock(&dqp->q_hash->qh_lock); dqfunlock: xfs_dqfunlock(dqp); -dqunlock: xfs_dqunlock(dqp); if (dqpout) break; if (restarts >= XFS_QM_RECLAIM_MAX_RESTARTS) - break; - if (startagain) { - mutex_unlock(&xfs_Gqm->qm_dqfrlist_lock); - goto again; - } + return NULL; } mutex_unlock(&xfs_Gqm->qm_dqfrlist_lock); return dqpout; diff --git a/trunk/fs/xfs/xfs_alloc.h b/trunk/fs/xfs/xfs_alloc.h index d0b3bc72005b..0ab56b32c7eb 100644 --- a/trunk/fs/xfs/xfs_alloc.h +++ b/trunk/fs/xfs/xfs_alloc.h @@ -74,22 +74,6 @@ typedef unsigned int xfs_alloctype_t; */ #define XFS_ALLOC_SET_ASIDE(mp) (4 + ((mp)->m_sb.sb_agcount * 4)) -/* - * When deciding how much space to allocate out of an AG, we limit the - * allocation maximum size to the size the AG. However, we cannot use all the - * blocks in the AG - some are permanently used by metadata. These - * blocks are generally: - * - the AG superblock, AGF, AGI and AGFL - * - the AGF (bno and cnt) and AGI btree root blocks - * - 4 blocks on the AGFL according to XFS_ALLOC_SET_ASIDE() limits - * - * The AG headers are sector sized, so the amount of space they take up is - * dependent on filesystem geometry. The others are all single blocks. - */ -#define XFS_ALLOC_AG_MAX_USABLE(mp) \ - ((mp)->m_sb.sb_agblocks - XFS_BB_TO_FSB(mp, XFS_FSS_TO_BB(mp, 4)) - 7) - - /* * Argument structure for xfs_alloc routines. * This is turned into a structure to avoid having 20 arguments passed diff --git a/trunk/fs/xfs/xfs_bmap.c b/trunk/fs/xfs/xfs_bmap.c index dc3afd7739ff..4111cd3966c7 100644 --- a/trunk/fs/xfs/xfs_bmap.c +++ b/trunk/fs/xfs/xfs_bmap.c @@ -1038,34 +1038,17 @@ xfs_bmap_add_extent_delay_real( * Filling in the middle part of a previous delayed allocation. * Contiguity is impossible here. * This case is avoided almost all the time. - * - * We start with a delayed allocation: - * - * +ddddddddddddddddddddddddddddddddddddddddddddddddddddddd+ - * PREV @ idx - * - * and we are allocating: - * +rrrrrrrrrrrrrrrrr+ - * new - * - * and we set it up for insertion as: - * +ddddddddddddddddddd+rrrrrrrrrrrrrrrrr+ddddddddddddddddd+ - * new - * PREV @ idx LEFT RIGHT - * inserted at idx + 1 */ temp = new->br_startoff - PREV.br_startoff; - temp2 = PREV.br_startoff + PREV.br_blockcount - new_endoff; trace_xfs_bmap_pre_update(ip, idx, 0, _THIS_IP_); - xfs_bmbt_set_blockcount(ep, temp); /* truncate PREV */ - LEFT = *new; - RIGHT.br_state = PREV.br_state; - RIGHT.br_startblock = nullstartblock( - (int)xfs_bmap_worst_indlen(ip, temp2)); - RIGHT.br_startoff = new_endoff; - RIGHT.br_blockcount = temp2; - /* insert LEFT (r[0]) and RIGHT (r[1]) at the same time */ - xfs_iext_insert(ip, idx + 1, 2, &LEFT, state); + xfs_bmbt_set_blockcount(ep, temp); + r[0] = *new; + r[1].br_state = PREV.br_state; + r[1].br_startblock = 0; + r[1].br_startoff = new_endoff; + temp2 = PREV.br_startoff + PREV.br_blockcount - new_endoff; + r[1].br_blockcount = temp2; + xfs_iext_insert(ip, idx + 1, 2, &r[0], state); ip->i_df.if_lastex = idx + 1; ip->i_d.di_nextents++; if (cur == NULL) @@ -2447,7 +2430,7 @@ xfs_bmap_btalloc_nullfb( startag = ag = 0; pag = xfs_perag_get(mp, ag); - while (*blen < args->maxlen) { + while (*blen < ap->alen) { if (!pag->pagf_init) { error = xfs_alloc_pagf_init(mp, args->tp, ag, XFS_ALLOC_FLAG_TRYLOCK); @@ -2469,7 +2452,7 @@ xfs_bmap_btalloc_nullfb( notinit = 1; if (xfs_inode_is_filestream(ap->ip)) { - if (*blen >= args->maxlen) + if (*blen >= ap->alen) break; if (ap->userdata) { @@ -2515,14 +2498,14 @@ xfs_bmap_btalloc_nullfb( * If the best seen length is less than the request * length, use the best as the minimum. */ - else if (*blen < args->maxlen) + else if (*blen < ap->alen) args->minlen = *blen; /* - * Otherwise we've seen an extent as big as maxlen, + * Otherwise we've seen an extent as big as alen, * use that as the minimum. */ else - args->minlen = args->maxlen; + args->minlen = ap->alen; /* * set the failure fallback case to look in the selected @@ -2590,9 +2573,7 @@ xfs_bmap_btalloc( args.tp = ap->tp; args.mp = mp; args.fsbno = ap->rval; - - /* Trim the allocation back to the maximum an AG can fit. */ - args.maxlen = MIN(ap->alen, XFS_ALLOC_AG_MAX_USABLE(mp)); + args.maxlen = MIN(ap->alen, mp->m_sb.sb_agblocks); args.firstblock = ap->firstblock; blen = 0; if (nullfb) { @@ -2640,7 +2621,7 @@ xfs_bmap_btalloc( /* * Adjust for alignment */ - if (blen > args.alignment && blen <= args.maxlen) + if (blen > args.alignment && blen <= ap->alen) args.minlen = blen - args.alignment; args.minalignslop = 0; } else { @@ -2659,7 +2640,7 @@ xfs_bmap_btalloc( * of minlen+alignment+slop doesn't go up * between the calls. */ - if (blen > mp->m_dalign && blen <= args.maxlen) + if (blen > mp->m_dalign && blen <= ap->alen) nextminlen = blen - mp->m_dalign; else nextminlen = args.minlen; @@ -4504,16 +4485,6 @@ xfs_bmapi( /* Figure out the extent size, adjust alen */ extsz = xfs_get_extsz_hint(ip); if (extsz) { - /* - * make sure we don't exceed a single - * extent length when we align the - * extent by reducing length we are - * going to allocate by the maximum - * amount extent size aligment may - * require. - */ - alen = XFS_FILBLKS_MIN(len, - MAXEXTLEN - (2 * extsz - 1)); error = xfs_bmap_extsize_align(mp, &got, &prev, extsz, rt, eof, diff --git a/trunk/fs/xfs/xfs_buf_item.c b/trunk/fs/xfs/xfs_buf_item.c index 6f8c21ce0d6d..98c6f73b6752 100644 --- a/trunk/fs/xfs/xfs_buf_item.c +++ b/trunk/fs/xfs/xfs_buf_item.c @@ -427,15 +427,13 @@ xfs_buf_item_unpin( if (remove) { /* - * If we are in a transaction context, we have to - * remove the log item from the transaction as we are - * about to release our reference to the buffer. If we - * don't, the unlock that occurs later in - * xfs_trans_uncommit() will try to reference the + * We have to remove the log item from the transaction + * as we are about to release our reference to the + * buffer. If we don't, the unlock that occurs later + * in xfs_trans_uncommit() will ry to reference the * buffer which we no longer have a hold on. */ - if (lip->li_desc) - xfs_trans_del_item(lip); + xfs_trans_del_item(lip); /* * Since the transaction no longer refers to the buffer, diff --git a/trunk/fs/xfs/xfs_extfree_item.c b/trunk/fs/xfs/xfs_extfree_item.c index d22e62623437..75f2ef60e579 100644 --- a/trunk/fs/xfs/xfs_extfree_item.c +++ b/trunk/fs/xfs/xfs_extfree_item.c @@ -138,8 +138,7 @@ xfs_efi_item_unpin( if (remove) { ASSERT(!(lip->li_flags & XFS_LI_IN_AIL)); - if (lip->li_desc) - xfs_trans_del_item(lip); + xfs_trans_del_item(lip); xfs_efi_item_free(efip); return; } diff --git a/trunk/fs/xfs/xfs_iomap.c b/trunk/fs/xfs/xfs_iomap.c index 8a0f044750c3..55582bd66659 100644 --- a/trunk/fs/xfs/xfs_iomap.c +++ b/trunk/fs/xfs/xfs_iomap.c @@ -337,12 +337,7 @@ xfs_iomap_prealloc_size( int shift = 0; int64_t freesp; - /* - * rounddown_pow_of_two() returns an undefined result - * if we pass in alloc_blocks = 0. Hence the "+ 1" to - * ensure we always pass in a non-zero value. - */ - alloc_blocks = XFS_B_TO_FSB(mp, ip->i_size) + 1; + alloc_blocks = XFS_B_TO_FSB(mp, ip->i_size); alloc_blocks = XFS_FILEOFF_MIN(MAXEXTLEN, rounddown_pow_of_two(alloc_blocks)); diff --git a/trunk/fs/xfs/xfs_log.h b/trunk/fs/xfs/xfs_log.h index 3bd3291ef8d2..916eb7db14d9 100644 --- a/trunk/fs/xfs/xfs_log.h +++ b/trunk/fs/xfs/xfs_log.h @@ -191,7 +191,7 @@ void xfs_log_ticket_put(struct xlog_ticket *ticket); xlog_tid_t xfs_log_get_trans_ident(struct xfs_trans *tp); -void xfs_log_commit_cil(struct xfs_mount *mp, struct xfs_trans *tp, +int xfs_log_commit_cil(struct xfs_mount *mp, struct xfs_trans *tp, struct xfs_log_vec *log_vector, xfs_lsn_t *commit_lsn, int flags); bool xfs_log_item_in_current_chkpt(struct xfs_log_item *lip); diff --git a/trunk/fs/xfs/xfs_log_cil.c b/trunk/fs/xfs/xfs_log_cil.c index 9ca59be08977..9dc8125d04e5 100644 --- a/trunk/fs/xfs/xfs_log_cil.c +++ b/trunk/fs/xfs/xfs_log_cil.c @@ -543,7 +543,7 @@ xlog_cil_push( error = xlog_write(log, &lvhdr, tic, &ctx->start_lsn, NULL, 0); if (error) - goto out_abort_free_ticket; + goto out_abort; /* * now that we've written the checkpoint into the log, strictly @@ -569,9 +569,8 @@ xlog_cil_push( } spin_unlock(&cil->xc_cil_lock); - /* xfs_log_done always frees the ticket on error. */ commit_lsn = xfs_log_done(log->l_mp, tic, &commit_iclog, 0); - if (commit_lsn == -1) + if (error || commit_lsn == -1) goto out_abort; /* attach all the transactions w/ busy extents to iclog */ @@ -601,8 +600,6 @@ xlog_cil_push( kmem_free(new_ctx); return 0; -out_abort_free_ticket: - xfs_log_ticket_put(tic); out_abort: xlog_cil_committed(ctx, XFS_LI_ABORTED); return XFS_ERROR(EIO); @@ -625,7 +622,7 @@ xlog_cil_push( * background commit, returns without it held once background commits are * allowed again. */ -void +int xfs_log_commit_cil( struct xfs_mount *mp, struct xfs_trans *tp, @@ -640,6 +637,11 @@ xfs_log_commit_cil( if (flags & XFS_TRANS_RELEASE_LOG_RES) log_flags = XFS_LOG_REL_PERM_RESERV; + if (XLOG_FORCED_SHUTDOWN(log)) { + xlog_cil_free_logvec(log_vector); + return XFS_ERROR(EIO); + } + /* * do all the hard work of formatting items (including memory * allocation) outside the CIL context lock. This prevents stalling CIL @@ -699,6 +701,7 @@ xfs_log_commit_cil( */ if (push) xlog_cil_push(log, 0); + return 0; } /* diff --git a/trunk/fs/xfs/xfs_trans.c b/trunk/fs/xfs/xfs_trans.c index 76922793f64f..33dbc4e0ad62 100644 --- a/trunk/fs/xfs/xfs_trans.c +++ b/trunk/fs/xfs/xfs_trans.c @@ -1446,14 +1446,6 @@ xfs_log_item_batch_insert( * Bulk operation version of xfs_trans_committed that takes a log vector of * items to insert into the AIL. This uses bulk AIL insertion techniques to * minimise lock traffic. - * - * If we are called with the aborted flag set, it is because a log write during - * a CIL checkpoint commit has failed. In this case, all the items in the - * checkpoint have already gone through IOP_COMMITED and IOP_UNLOCK, which - * means that checkpoint commit abort handling is treated exactly the same - * as an iclog write error even though we haven't started any IO yet. Hence in - * this case all we need to do is IOP_COMMITTED processing, followed by an - * IOP_UNPIN(aborted) call. */ void xfs_trans_committed_bulk( @@ -1480,16 +1472,6 @@ xfs_trans_committed_bulk( if (XFS_LSN_CMP(item_lsn, (xfs_lsn_t)-1) == 0) continue; - /* - * if we are aborting the operation, no point in inserting the - * object into the AIL as we are in a shutdown situation. - */ - if (aborted) { - ASSERT(XFS_FORCED_SHUTDOWN(ailp->xa_mount)); - IOP_UNPIN(lip, 1); - continue; - } - if (item_lsn != commit_lsn) { /* @@ -1521,24 +1503,20 @@ xfs_trans_committed_bulk( } /* - * Called from the trans_commit code when we notice that the filesystem is in - * the middle of a forced shutdown. - * - * When we are called here, we have already pinned all the items in the - * transaction. However, neither IOP_COMMITTING or IOP_UNLOCK has been called - * so we can simply walk the items in the transaction, unpin them with an abort - * flag and then free the items. Note that unpinning the items can result in - * them being freed immediately, so we need to use a safe list traversal method - * here. + * Called from the trans_commit code when we notice that + * the filesystem is in the middle of a forced shutdown. */ STATIC void xfs_trans_uncommit( struct xfs_trans *tp, uint flags) { - struct xfs_log_item_desc *lidp, *n; + struct xfs_log_item_desc *lidp; - list_for_each_entry_safe(lidp, n, &tp->t_items, lid_trans) { + list_for_each_entry(lidp, &tp->t_items, lid_trans) { + /* + * Unpin all but those that aren't dirty. + */ if (lidp->lid_flags & XFS_LID_DIRTY) IOP_UNPIN(lidp->lid_item, 1); } @@ -1755,6 +1733,7 @@ xfs_trans_commit_cil( int flags) { struct xfs_log_vec *log_vector; + int error; /* * Get each log item to allocate a vector structure for @@ -1765,7 +1744,9 @@ xfs_trans_commit_cil( if (!log_vector) return ENOMEM; - xfs_log_commit_cil(mp, tp, log_vector, commit_lsn, flags); + error = xfs_log_commit_cil(mp, tp, log_vector, commit_lsn, flags); + if (error) + return error; current_restore_flags_nested(&tp->t_pflags, PF_FSTRANS); xfs_trans_free(tp); diff --git a/trunk/include/linux/fs.h b/trunk/include/linux/fs.h index bd3215940c37..32b38cd829d3 100644 --- a/trunk/include/linux/fs.h +++ b/trunk/include/linux/fs.h @@ -2555,12 +2555,9 @@ int proc_nr_inodes(struct ctl_table *table, int write, void __user *buffer, size_t *lenp, loff_t *ppos); int __init get_filesystem_list(char *buf); -#define __FMODE_EXEC ((__force int) FMODE_EXEC) -#define __FMODE_NONOTIFY ((__force int) FMODE_NONOTIFY) - #define ACC_MODE(x) ("\004\002\006\006"[(x)&O_ACCMODE]) #define OPEN_FMODE(flag) ((__force fmode_t)(((flag + 1) & O_ACCMODE) | \ - (flag & __FMODE_NONOTIFY))) + (flag & FMODE_NONOTIFY))) #endif /* __KERNEL__ */ #endif /* _LINUX_FS_H */ diff --git a/trunk/include/linux/kernel.h b/trunk/include/linux/kernel.h index 2fe6e84894a4..e2f4d6af2125 100644 --- a/trunk/include/linux/kernel.h +++ b/trunk/include/linux/kernel.h @@ -588,7 +588,7 @@ struct sysinfo { /** * BUILD_BUG_ON - break compile if a condition is true. - * @condition: the condition which the compiler should know is false. + * @cond: the condition which the compiler should know is false. * * If you have some code which relies on certain constants being equal, or * other compile-time-evaluated condition, you should use BUILD_BUG_ON to diff --git a/trunk/include/linux/nfsacl.h b/trunk/include/linux/nfsacl.h index fabcb1e5c460..f321b578edeb 100644 --- a/trunk/include/linux/nfsacl.h +++ b/trunk/include/linux/nfsacl.h @@ -51,10 +51,10 @@ nfsacl_size(struct posix_acl *acl_access, struct posix_acl *acl_default) return w; } -extern int +extern unsigned int nfsacl_encode(struct xdr_buf *buf, unsigned int base, struct inode *inode, struct posix_acl *acl, int encode_entries, int typeflag); -extern int +extern unsigned int nfsacl_decode(struct xdr_buf *buf, unsigned int base, unsigned int *aclcnt, struct posix_acl **pacl); diff --git a/trunk/include/linux/posix_acl.h b/trunk/include/linux/posix_acl.h index 54211c1cd926..d68283a898bb 100644 --- a/trunk/include/linux/posix_acl.h +++ b/trunk/include/linux/posix_acl.h @@ -71,7 +71,6 @@ posix_acl_release(struct posix_acl *acl) /* posix_acl.c */ -extern void posix_acl_init(struct posix_acl *, int); extern struct posix_acl *posix_acl_alloc(int, gfp_t); extern struct posix_acl *posix_acl_clone(const struct posix_acl *, gfp_t); extern int posix_acl_valid(const struct posix_acl *); diff --git a/trunk/include/linux/res_counter.h b/trunk/include/linux/res_counter.h index a5930cb66145..fcb9884df618 100644 --- a/trunk/include/linux/res_counter.h +++ b/trunk/include/linux/res_counter.h @@ -182,26 +182,6 @@ static inline bool res_counter_check_under_limit(struct res_counter *cnt) return ret; } -/** - * res_counter_check_margin - check if the counter allows charging - * @cnt: the resource counter to check - * @bytes: the number of bytes to check the remaining space against - * - * Returns a boolean value on whether the counter can be charged - * @bytes or whether this would exceed the limit. - */ -static inline bool res_counter_check_margin(struct res_counter *cnt, - unsigned long bytes) -{ - bool ret; - unsigned long flags; - - spin_lock_irqsave(&cnt->lock, flags); - ret = cnt->limit - cnt->usage >= bytes; - spin_unlock_irqrestore(&cnt->lock, flags); - return ret; -} - static inline bool res_counter_check_under_soft_limit(struct res_counter *cnt) { bool ret; diff --git a/trunk/include/linux/sunrpc/bc_xprt.h b/trunk/include/linux/sunrpc/bc_xprt.h index 082884295f80..c50b458b8a3f 100644 --- a/trunk/include/linux/sunrpc/bc_xprt.h +++ b/trunk/include/linux/sunrpc/bc_xprt.h @@ -47,6 +47,14 @@ static inline int svc_is_backchannel(const struct svc_rqst *rqstp) return 1; return 0; } +static inline struct nfs4_sessionid *bc_xprt_sid(struct svc_rqst *rqstp) +{ + if (svc_is_backchannel(rqstp)) + return (struct nfs4_sessionid *) + rqstp->rq_server->sv_bc_xprt->xpt_bc_sid; + return NULL; +} + #else /* CONFIG_NFS_V4_1 */ static inline int xprt_setup_backchannel(struct rpc_xprt *xprt, unsigned int min_reqs) @@ -59,6 +67,11 @@ static inline int svc_is_backchannel(const struct svc_rqst *rqstp) return 0; } +static inline struct nfs4_sessionid *bc_xprt_sid(struct svc_rqst *rqstp) +{ + return NULL; +} + static inline void xprt_free_bc_request(struct rpc_rqst *req) { } diff --git a/trunk/include/linux/sunrpc/svc_xprt.h b/trunk/include/linux/sunrpc/svc_xprt.h index 7ad9751a0d87..059877b4d85b 100644 --- a/trunk/include/linux/sunrpc/svc_xprt.h +++ b/trunk/include/linux/sunrpc/svc_xprt.h @@ -77,6 +77,7 @@ struct svc_xprt { size_t xpt_remotelen; /* length of address */ struct rpc_wait_queue xpt_bc_pending; /* backchannel wait queue */ struct list_head xpt_users; /* callbacks on free */ + void *xpt_bc_sid; /* back channel session ID */ struct net *xpt_net; struct rpc_xprt *xpt_bc_xprt; /* NFSv4.1 backchannel */ diff --git a/trunk/include/linux/usb/hcd.h b/trunk/include/linux/usb/hcd.h index a854fe89484e..dd6ee49a0844 100644 --- a/trunk/include/linux/usb/hcd.h +++ b/trunk/include/linux/usb/hcd.h @@ -112,7 +112,6 @@ struct usb_hcd { /* Flags that get set only during HCD registration or removal. */ unsigned rh_registered:1;/* is root hub registered? */ unsigned rh_pollable:1; /* may we poll the root hub? */ - unsigned msix_enabled:1; /* driver has MSI-X enabled? */ /* The next flag is a stopgap, to be removed when all the HCDs * support the new root-hub polling mechanism. */ diff --git a/trunk/include/linux/usb/serial.h b/trunk/include/linux/usb/serial.h index c9049139a7a5..16d682f4f7c3 100644 --- a/trunk/include/linux/usb/serial.h +++ b/trunk/include/linux/usb/serial.h @@ -347,9 +347,6 @@ extern int usb_serial_generic_prepare_write_buffer(struct usb_serial_port *port, extern int usb_serial_handle_sysrq_char(struct usb_serial_port *port, unsigned int ch); extern int usb_serial_handle_break(struct usb_serial_port *port); -extern void usb_serial_handle_dcd_change(struct usb_serial_port *usb_port, - struct tty_struct *tty, - unsigned int status); extern int usb_serial_bus_register(struct usb_serial_driver *device); diff --git a/trunk/mm/huge_memory.c b/trunk/mm/huge_memory.c index b6c1ce3c53b5..e187454d82f6 100644 --- a/trunk/mm/huge_memory.c +++ b/trunk/mm/huge_memory.c @@ -1162,12 +1162,7 @@ static void __split_huge_page_refcount(struct page *page) /* after clearing PageTail the gup refcount can be released */ smp_mb(); - /* - * retain hwpoison flag of the poisoned tail page: - * fix for the unsuitable process killed on Guest Machine(KVM) - * by the memory-failure. - */ - page_tail->flags &= ~PAGE_FLAGS_CHECK_AT_PREP | __PG_HWPOISON; + page_tail->flags &= ~PAGE_FLAGS_CHECK_AT_PREP; page_tail->flags |= (page->flags & ((1L << PG_referenced) | (1L << PG_swapbacked) | diff --git a/trunk/mm/memcontrol.c b/trunk/mm/memcontrol.c index da53a252b259..3878cfe399dc 100644 --- a/trunk/mm/memcontrol.c +++ b/trunk/mm/memcontrol.c @@ -612,10 +612,8 @@ static void mem_cgroup_charge_statistics(struct mem_cgroup *mem, /* pagein of a big page is an event. So, ignore page size */ if (nr_pages > 0) __this_cpu_inc(mem->stat->count[MEM_CGROUP_STAT_PGPGIN_COUNT]); - else { + else __this_cpu_inc(mem->stat->count[MEM_CGROUP_STAT_PGPGOUT_COUNT]); - nr_pages = -nr_pages; /* for event */ - } __this_cpu_add(mem->stat->count[MEM_CGROUP_EVENTS], nr_pages); @@ -1113,23 +1111,6 @@ static bool mem_cgroup_check_under_limit(struct mem_cgroup *mem) return false; } -/** - * mem_cgroup_check_margin - check if the memory cgroup allows charging - * @mem: memory cgroup to check - * @bytes: the number of bytes the caller intends to charge - * - * Returns a boolean value on whether @mem can be charged @bytes or - * whether this would exceed the limit. - */ -static bool mem_cgroup_check_margin(struct mem_cgroup *mem, unsigned long bytes) -{ - if (!res_counter_check_margin(&mem->res, bytes)) - return false; - if (do_swap_account && !res_counter_check_margin(&mem->memsw, bytes)) - return false; - return true; -} - static unsigned int get_swappiness(struct mem_cgroup *memcg) { struct cgroup *cgrp = memcg->css.cgroup; @@ -1856,34 +1837,23 @@ static int __mem_cgroup_do_charge(struct mem_cgroup *mem, gfp_t gfp_mask, flags |= MEM_CGROUP_RECLAIM_NOSWAP; } else mem_over_limit = mem_cgroup_from_res_counter(fail_res, res); - /* - * csize can be either a huge page (HPAGE_SIZE), a batch of - * regular pages (CHARGE_SIZE), or a single regular page - * (PAGE_SIZE). - * - * Never reclaim on behalf of optional batching, retry with a - * single page instead. - */ - if (csize == CHARGE_SIZE) + + if (csize > PAGE_SIZE) /* change csize and retry */ return CHARGE_RETRY; if (!(gfp_mask & __GFP_WAIT)) return CHARGE_WOULDBLOCK; ret = mem_cgroup_hierarchical_reclaim(mem_over_limit, NULL, - gfp_mask, flags); - if (mem_cgroup_check_margin(mem_over_limit, csize)) - return CHARGE_RETRY; + gfp_mask, flags); /* - * Even though the limit is exceeded at this point, reclaim - * may have been able to free some pages. Retry the charge - * before killing the task. - * - * Only for regular pages, though: huge pages are rather - * unlikely to succeed so close to the limit, and we fall back - * to regular pages anyway in case of failure. + * try_to_free_mem_cgroup_pages() might not give us a full + * picture of reclaim. Some pages are reclaimed and might be + * moved to swap cache or just unmapped from the cgroup. + * Check the limit again to see if the reclaim reduced the + * current usage of the cgroup before giving up */ - if (csize == PAGE_SIZE && ret) + if (ret || mem_cgroup_check_under_limit(mem_over_limit)) return CHARGE_RETRY; /* @@ -2353,19 +2323,13 @@ static int mem_cgroup_charge_common(struct page *page, struct mm_struct *mm, gfp_t gfp_mask, enum charge_type ctype) { struct mem_cgroup *mem = NULL; - int page_size = PAGE_SIZE; struct page_cgroup *pc; - bool oom = true; int ret; + int page_size = PAGE_SIZE; if (PageTransHuge(page)) { page_size <<= compound_order(page); VM_BUG_ON(!PageTransHuge(page)); - /* - * Never OOM-kill a process for a huge page. The - * fault handler will fall back to regular pages. - */ - oom = false; } pc = lookup_page_cgroup(page); @@ -2374,7 +2338,7 @@ static int mem_cgroup_charge_common(struct page *page, struct mm_struct *mm, return 0; prefetchw(pc); - ret = __mem_cgroup_try_charge(mm, gfp_mask, &mem, oom, page_size); + ret = __mem_cgroup_try_charge(mm, gfp_mask, &mem, true, page_size); if (ret || !mem) return ret; @@ -5060,9 +5024,9 @@ struct cgroup_subsys mem_cgroup_subsys = { static int __init enable_swap_account(char *s) { /* consider enabled if no parameter or 1 is given */ - if (!(*s) || !strcmp(s, "=1")) + if (!s || !strcmp(s, "1")) really_do_swap_account = 1; - else if (!strcmp(s, "=0")) + else if (!strcmp(s, "0")) really_do_swap_account = 0; return 1; } @@ -5070,8 +5034,7 @@ __setup("swapaccount", enable_swap_account); static int __init disable_swap_account(char *s) { - printk_once("noswapaccount is deprecated and will be removed in 2.6.40. Use swapaccount=0 instead\n"); - enable_swap_account("=0"); + enable_swap_account("0"); return 1; } __setup("noswapaccount", disable_swap_account); diff --git a/trunk/mm/memory-failure.c b/trunk/mm/memory-failure.c index 0207c2f6f8bd..548fbd70f026 100644 --- a/trunk/mm/memory-failure.c +++ b/trunk/mm/memory-failure.c @@ -233,8 +233,8 @@ void shake_page(struct page *p, int access) } /* - * Only call shrink_slab here (which would also shrink other caches) if - * access is not potentially fatal. + * Only all shrink_slab here (which would also + * shrink other caches) if access is not potentially fatal. */ if (access) { int nr; @@ -386,6 +386,8 @@ static void collect_procs_anon(struct page *page, struct list_head *to_kill, struct task_struct *tsk; struct anon_vma *av; + if (!PageHuge(page) && unlikely(split_huge_page(page))) + return; read_lock(&tasklist_lock); av = page_lock_anon_vma(page); if (av == NULL) /* Not actually mapped anymore */ @@ -854,7 +856,6 @@ static int hwpoison_user_mappings(struct page *p, unsigned long pfn, int ret; int kill = 1; struct page *hpage = compound_head(p); - struct page *ppage; if (PageReserved(p) || PageSlab(p)) return SWAP_SUCCESS; @@ -895,44 +896,6 @@ static int hwpoison_user_mappings(struct page *p, unsigned long pfn, } } - /* - * ppage: poisoned page - * if p is regular page(4k page) - * ppage == real poisoned page; - * else p is hugetlb or THP, ppage == head page. - */ - ppage = hpage; - - if (PageTransHuge(hpage)) { - /* - * Verify that this isn't a hugetlbfs head page, the check for - * PageAnon is just for avoid tripping a split_huge_page - * internal debug check, as split_huge_page refuses to deal with - * anything that isn't an anon page. PageAnon can't go away fro - * under us because we hold a refcount on the hpage, without a - * refcount on the hpage. split_huge_page can't be safely called - * in the first place, having a refcount on the tail isn't - * enough * to be safe. - */ - if (!PageHuge(hpage) && PageAnon(hpage)) { - if (unlikely(split_huge_page(hpage))) { - /* - * FIXME: if splitting THP is failed, it is - * better to stop the following operation rather - * than causing panic by unmapping. System might - * survive if the page is freed later. - */ - printk(KERN_INFO - "MCE %#lx: failed to split THP\n", pfn); - - BUG_ON(!PageHWPoison(p)); - return SWAP_FAIL; - } - /* THP is split, so ppage should be the real poisoned page. */ - ppage = p; - } - } - /* * First collect all the processes that have the page * mapped in dirty form. This has to be done before try_to_unmap, @@ -942,18 +905,12 @@ static int hwpoison_user_mappings(struct page *p, unsigned long pfn, * there's nothing that can be done. */ if (kill) - collect_procs(ppage, &tokill); - - if (hpage != ppage) - lock_page_nosync(ppage); + collect_procs(hpage, &tokill); - ret = try_to_unmap(ppage, ttu); + ret = try_to_unmap(hpage, ttu); if (ret != SWAP_SUCCESS) printk(KERN_ERR "MCE %#lx: failed to unmap page (mapcount=%d)\n", - pfn, page_mapcount(ppage)); - - if (hpage != ppage) - unlock_page(ppage); + pfn, page_mapcount(hpage)); /* * Now that the dirty bit has been propagated to the @@ -964,7 +921,7 @@ static int hwpoison_user_mappings(struct page *p, unsigned long pfn, * use a more force-full uncatchable kill to prevent * any accesses to the poisoned memory. */ - kill_procs_ao(&tokill, !!PageDirty(ppage), trapno, + kill_procs_ao(&tokill, !!PageDirty(hpage), trapno, ret != SWAP_SUCCESS, p, pfn); return ret; @@ -1065,22 +1022,19 @@ int __memory_failure(unsigned long pfn, int trapno, int flags) * The check (unnecessarily) ignores LRU pages being isolated and * walked by the page reclaim code, however that's not a big loss. */ - if (!PageHuge(p) && !PageTransCompound(p)) { - if (!PageLRU(p)) - shake_page(p, 0); - if (!PageLRU(p)) { - /* - * shake_page could have turned it free. - */ - if (is_free_buddy_page(p)) { - action_result(pfn, "free buddy, 2nd try", - DELAYED); - return 0; - } - action_result(pfn, "non LRU", IGNORED); - put_page(p); - return -EBUSY; + if (!PageLRU(p) && !PageHuge(p)) + shake_page(p, 0); + if (!PageLRU(p) && !PageHuge(p)) { + /* + * shake_page could have turned it free. + */ + if (is_free_buddy_page(p)) { + action_result(pfn, "free buddy, 2nd try", DELAYED); + return 0; } + action_result(pfn, "non LRU", IGNORED); + put_page(p); + return -EBUSY; } /* @@ -1110,7 +1064,7 @@ int __memory_failure(unsigned long pfn, int trapno, int flags) * For error on the tail page, we should set PG_hwpoison * on the head page to show that the hugepage is hwpoisoned */ - if (PageHuge(p) && PageTail(p) && TestSetPageHWPoison(hpage)) { + if (PageTail(p) && TestSetPageHWPoison(hpage)) { action_result(pfn, "hugepage already hardware poisoned", IGNORED); unlock_page(hpage); @@ -1341,10 +1295,7 @@ static int soft_offline_huge_page(struct page *page, int flags) ret = migrate_huge_pages(&pagelist, new_page, MPOL_MF_MOVE_ALL, 0, true); if (ret) { - struct page *page1, *page2; - list_for_each_entry_safe(page1, page2, &pagelist, lru) - put_page(page1); - + putback_lru_pages(&pagelist); pr_debug("soft offline: %#lx: migration failed %d, type %lx\n", pfn, ret, page->flags); if (ret > 0) @@ -1468,7 +1419,6 @@ int soft_offline_page(struct page *page, int flags) ret = migrate_pages(&pagelist, new_page, MPOL_MF_MOVE_ALL, 0, true); if (ret) { - putback_lru_pages(&pagelist); pr_info("soft offline: %#lx: migration failed %d, type %lx\n", pfn, ret, page->flags); if (ret > 0) diff --git a/trunk/mm/migrate.c b/trunk/mm/migrate.c index 766115253807..9f29a3b7aac2 100644 --- a/trunk/mm/migrate.c +++ b/trunk/mm/migrate.c @@ -772,7 +772,6 @@ static int unmap_and_move(new_page_t get_new_page, unsigned long private, unlock: unlock_page(page); -move_newpage: if (rc != -EAGAIN) { /* * A page that has been migrated has all references @@ -786,6 +785,8 @@ static int unmap_and_move(new_page_t get_new_page, unsigned long private, putback_lru_page(page); } +move_newpage: + /* * Move the new page to the LRU. If migration was not successful * then this will free the page. @@ -980,6 +981,10 @@ int migrate_huge_pages(struct list_head *from, } rc = 0; out: + + list_for_each_entry_safe(page, page2, from, lru) + put_page(page); + if (rc) return rc; diff --git a/trunk/mm/mlock.c b/trunk/mm/mlock.c index c3924c7f00be..13e81ee8be9d 100644 --- a/trunk/mm/mlock.c +++ b/trunk/mm/mlock.c @@ -178,13 +178,6 @@ static long __mlock_vma_pages_range(struct vm_area_struct *vma, if ((vma->vm_flags & (VM_WRITE | VM_SHARED)) == VM_WRITE) gup_flags |= FOLL_WRITE; - /* - * We want mlock to succeed for regions that have any permissions - * other than PROT_NONE. - */ - if (vma->vm_flags & (VM_READ | VM_WRITE | VM_EXEC)) - gup_flags |= FOLL_FORCE; - if (vma->vm_flags & VM_LOCKED) gup_flags |= FOLL_MLOCK; diff --git a/trunk/net/sunrpc/svcsock.c b/trunk/net/sunrpc/svcsock.c index d802e941d365..7bd3bbba4710 100644 --- a/trunk/net/sunrpc/svcsock.c +++ b/trunk/net/sunrpc/svcsock.c @@ -1609,7 +1609,9 @@ static struct svc_xprt *svc_bc_create_socket(struct svc_serv *serv, */ static void svc_bc_sock_free(struct svc_xprt *xprt) { - if (xprt) + if (xprt) { + kfree(xprt->xpt_bc_sid); kfree(container_of(xprt, struct svc_sock, sk_xprt)); + } } #endif /* CONFIG_NFS_V4_1 */