diff options
86 files changed, 594 insertions, 429 deletions
diff --git a/arch/m68k/include/asm/irqflags.h b/arch/m68k/include/asm/irqflags.h index 4a5b284a1550..7ef4115b8c4a 100644 --- a/arch/m68k/include/asm/irqflags.h +++ b/arch/m68k/include/asm/irqflags.h | |||
| @@ -2,7 +2,9 @@ | |||
| 2 | #define _M68K_IRQFLAGS_H | 2 | #define _M68K_IRQFLAGS_H |
| 3 | 3 | ||
| 4 | #include <linux/types.h> | 4 | #include <linux/types.h> |
| 5 | #ifdef CONFIG_MMU | ||
| 5 | #include <linux/hardirq.h> | 6 | #include <linux/hardirq.h> |
| 7 | #endif | ||
| 6 | #include <linux/preempt.h> | 8 | #include <linux/preempt.h> |
| 7 | #include <asm/thread_info.h> | 9 | #include <asm/thread_info.h> |
| 8 | #include <asm/entry.h> | 10 | #include <asm/entry.h> |
diff --git a/arch/m68k/include/asm/machdep.h b/arch/m68k/include/asm/machdep.h index 789f3b2de0e9..415d5484916c 100644 --- a/arch/m68k/include/asm/machdep.h +++ b/arch/m68k/include/asm/machdep.h | |||
| @@ -40,5 +40,6 @@ extern unsigned long hw_timer_offset(void); | |||
| 40 | extern irqreturn_t arch_timer_interrupt(int irq, void *dummy); | 40 | extern irqreturn_t arch_timer_interrupt(int irq, void *dummy); |
| 41 | 41 | ||
| 42 | extern void config_BSP(char *command, int len); | 42 | extern void config_BSP(char *command, int len); |
| 43 | extern void do_IRQ(int irq, struct pt_regs *fp); | ||
| 43 | 44 | ||
| 44 | #endif /* _M68K_MACHDEP_H */ | 45 | #endif /* _M68K_MACHDEP_H */ |
diff --git a/arch/tile/include/asm/highmem.h b/arch/tile/include/asm/highmem.h index e0f7ee186721..b2a6c5de79ab 100644 --- a/arch/tile/include/asm/highmem.h +++ b/arch/tile/include/asm/highmem.h | |||
| @@ -23,7 +23,6 @@ | |||
| 23 | 23 | ||
| 24 | #include <linux/interrupt.h> | 24 | #include <linux/interrupt.h> |
| 25 | #include <linux/threads.h> | 25 | #include <linux/threads.h> |
| 26 | #include <asm/kmap_types.h> | ||
| 27 | #include <asm/tlbflush.h> | 26 | #include <asm/tlbflush.h> |
| 28 | #include <asm/homecache.h> | 27 | #include <asm/homecache.h> |
| 29 | 28 | ||
diff --git a/arch/tile/include/asm/kmap_types.h b/arch/tile/include/asm/kmap_types.h index 1480106d1c05..3d0f20246260 100644 --- a/arch/tile/include/asm/kmap_types.h +++ b/arch/tile/include/asm/kmap_types.h | |||
| @@ -16,28 +16,42 @@ | |||
| 16 | #define _ASM_TILE_KMAP_TYPES_H | 16 | #define _ASM_TILE_KMAP_TYPES_H |
| 17 | 17 | ||
| 18 | /* | 18 | /* |
| 19 | * In TILE Linux each set of four of these uses another 16MB chunk of | 19 | * In 32-bit TILE Linux we have to balance the desire to have a lot of |
| 20 | * address space, given 64 tiles and 64KB pages, so we only enable | 20 | * nested atomic mappings with the fact that large page sizes and many |
| 21 | * ones that are required by the kernel configuration. | 21 | * processors chew up address space quickly. In a typical |
| 22 | * 64-processor, 64KB-page layout build, making KM_TYPE_NR one larger | ||
| 23 | * adds 4MB of required address-space. For now we leave KM_TYPE_NR | ||
| 24 | * set to depth 8. | ||
| 22 | */ | 25 | */ |
| 23 | enum km_type { | 26 | enum km_type { |
| 27 | KM_TYPE_NR = 8 | ||
| 28 | }; | ||
| 29 | |||
| 30 | /* | ||
| 31 | * We provide dummy definitions of all the stray values that used to be | ||
| 32 | * required for kmap_atomic() and no longer are. | ||
| 33 | */ | ||
| 34 | enum { | ||
| 24 | KM_BOUNCE_READ, | 35 | KM_BOUNCE_READ, |
| 25 | KM_SKB_SUNRPC_DATA, | 36 | KM_SKB_SUNRPC_DATA, |
| 26 | KM_SKB_DATA_SOFTIRQ, | 37 | KM_SKB_DATA_SOFTIRQ, |
| 27 | KM_USER0, | 38 | KM_USER0, |
| 28 | KM_USER1, | 39 | KM_USER1, |
| 29 | KM_BIO_SRC_IRQ, | 40 | KM_BIO_SRC_IRQ, |
| 41 | KM_BIO_DST_IRQ, | ||
| 42 | KM_PTE0, | ||
| 43 | KM_PTE1, | ||
| 30 | KM_IRQ0, | 44 | KM_IRQ0, |
| 31 | KM_IRQ1, | 45 | KM_IRQ1, |
| 32 | KM_SOFTIRQ0, | 46 | KM_SOFTIRQ0, |
| 33 | KM_SOFTIRQ1, | 47 | KM_SOFTIRQ1, |
| 34 | KM_MEMCPY0, | 48 | KM_SYNC_ICACHE, |
| 35 | KM_MEMCPY1, | 49 | KM_SYNC_DCACHE, |
| 36 | #if defined(CONFIG_HIGHPTE) | 50 | KM_UML_USERCOPY, |
| 37 | KM_PTE0, | 51 | KM_IRQ_PTE, |
| 38 | KM_PTE1, | 52 | KM_NMI, |
| 39 | #endif | 53 | KM_NMI_PTE, |
| 40 | KM_TYPE_NR | 54 | KM_KDB |
| 41 | }; | 55 | }; |
| 42 | 56 | ||
| 43 | #endif /* _ASM_TILE_KMAP_TYPES_H */ | 57 | #endif /* _ASM_TILE_KMAP_TYPES_H */ |
diff --git a/arch/tile/include/asm/pgtable.h b/arch/tile/include/asm/pgtable.h index dc4ccdd855bc..a6604e9485da 100644 --- a/arch/tile/include/asm/pgtable.h +++ b/arch/tile/include/asm/pgtable.h | |||
| @@ -344,10 +344,8 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) | |||
| 344 | #define pgd_offset_k(address) pgd_offset(&init_mm, address) | 344 | #define pgd_offset_k(address) pgd_offset(&init_mm, address) |
| 345 | 345 | ||
| 346 | #if defined(CONFIG_HIGHPTE) | 346 | #if defined(CONFIG_HIGHPTE) |
| 347 | extern pte_t *_pte_offset_map(pmd_t *, unsigned long address, enum km_type); | 347 | extern pte_t *pte_offset_map(pmd_t *, unsigned long address); |
| 348 | #define pte_offset_map(dir, address) \ | 348 | #define pte_unmap(pte) kunmap_atomic(pte) |
| 349 | _pte_offset_map(dir, address, KM_PTE0) | ||
| 350 | #define pte_unmap(pte) kunmap_atomic(pte, KM_PTE0) | ||
| 351 | #else | 349 | #else |
| 352 | #define pte_offset_map(dir, address) pte_offset_kernel(dir, address) | 350 | #define pte_offset_map(dir, address) pte_offset_kernel(dir, address) |
| 353 | #define pte_unmap(pte) do { } while (0) | 351 | #define pte_unmap(pte) do { } while (0) |
diff --git a/arch/tile/include/asm/stat.h b/arch/tile/include/asm/stat.h index 3dc90fa92c70..b16e5db8f0e7 100644 --- a/arch/tile/include/asm/stat.h +++ b/arch/tile/include/asm/stat.h | |||
| @@ -1 +1,4 @@ | |||
| 1 | #ifdef CONFIG_COMPAT | ||
| 2 | #define __ARCH_WANT_STAT64 /* Used for compat_sys_stat64() etc. */ | ||
| 3 | #endif | ||
| 1 | #include <asm-generic/stat.h> | 4 | #include <asm-generic/stat.h> |
diff --git a/arch/tile/include/asm/unistd.h b/arch/tile/include/asm/unistd.h index f2e3ff485333..b35c2db71199 100644 --- a/arch/tile/include/asm/unistd.h +++ b/arch/tile/include/asm/unistd.h | |||
| @@ -41,6 +41,7 @@ __SYSCALL(__NR_cmpxchg_badaddr, sys_cmpxchg_badaddr) | |||
| 41 | #ifdef CONFIG_COMPAT | 41 | #ifdef CONFIG_COMPAT |
| 42 | #define __ARCH_WANT_SYS_LLSEEK | 42 | #define __ARCH_WANT_SYS_LLSEEK |
| 43 | #endif | 43 | #endif |
| 44 | #define __ARCH_WANT_SYS_NEWFSTATAT | ||
| 44 | #endif | 45 | #endif |
| 45 | 46 | ||
| 46 | #endif /* _ASM_TILE_UNISTD_H */ | 47 | #endif /* _ASM_TILE_UNISTD_H */ |
diff --git a/arch/tile/kernel/compat.c b/arch/tile/kernel/compat.c index 77739cdd9462..67617a05e602 100644 --- a/arch/tile/kernel/compat.c +++ b/arch/tile/kernel/compat.c | |||
| @@ -148,11 +148,11 @@ long tile_compat_sys_msgrcv(int msqid, | |||
| 148 | #define compat_sys_readahead sys32_readahead | 148 | #define compat_sys_readahead sys32_readahead |
| 149 | #define compat_sys_sync_file_range compat_sys_sync_file_range2 | 149 | #define compat_sys_sync_file_range compat_sys_sync_file_range2 |
| 150 | 150 | ||
| 151 | /* The native 64-bit "struct stat" matches the 32-bit "struct stat64". */ | 151 | /* We leverage the "struct stat64" type for 32-bit time_t/nsec. */ |
| 152 | #define compat_sys_stat64 sys_newstat | 152 | #define compat_sys_stat64 sys_stat64 |
| 153 | #define compat_sys_lstat64 sys_newlstat | 153 | #define compat_sys_lstat64 sys_lstat64 |
| 154 | #define compat_sys_fstat64 sys_newfstat | 154 | #define compat_sys_fstat64 sys_fstat64 |
| 155 | #define compat_sys_fstatat64 sys_newfstatat | 155 | #define compat_sys_fstatat64 sys_fstatat64 |
| 156 | 156 | ||
| 157 | /* The native sys_ptrace dynamically handles compat binaries. */ | 157 | /* The native sys_ptrace dynamically handles compat binaries. */ |
| 158 | #define compat_sys_ptrace sys_ptrace | 158 | #define compat_sys_ptrace sys_ptrace |
diff --git a/arch/tile/kernel/early_printk.c b/arch/tile/kernel/early_printk.c index 2c54fd43a8a0..493a0e66d916 100644 --- a/arch/tile/kernel/early_printk.c +++ b/arch/tile/kernel/early_printk.c | |||
| @@ -54,7 +54,7 @@ void early_printk(const char *fmt, ...) | |||
| 54 | void early_panic(const char *fmt, ...) | 54 | void early_panic(const char *fmt, ...) |
| 55 | { | 55 | { |
| 56 | va_list ap; | 56 | va_list ap; |
| 57 | raw_local_irq_disable_all(); | 57 | arch_local_irq_disable_all(); |
| 58 | va_start(ap, fmt); | 58 | va_start(ap, fmt); |
| 59 | early_printk("Kernel panic - not syncing: "); | 59 | early_printk("Kernel panic - not syncing: "); |
| 60 | early_vprintk(fmt, ap); | 60 | early_vprintk(fmt, ap); |
diff --git a/arch/tile/kernel/hardwall.c b/arch/tile/kernel/hardwall.c index 1e54a7843410..e910530436e6 100644 --- a/arch/tile/kernel/hardwall.c +++ b/arch/tile/kernel/hardwall.c | |||
| @@ -151,12 +151,12 @@ enum direction_protect { | |||
| 151 | 151 | ||
| 152 | static void enable_firewall_interrupts(void) | 152 | static void enable_firewall_interrupts(void) |
| 153 | { | 153 | { |
| 154 | raw_local_irq_unmask_now(INT_UDN_FIREWALL); | 154 | arch_local_irq_unmask_now(INT_UDN_FIREWALL); |
| 155 | } | 155 | } |
| 156 | 156 | ||
| 157 | static void disable_firewall_interrupts(void) | 157 | static void disable_firewall_interrupts(void) |
| 158 | { | 158 | { |
| 159 | raw_local_irq_mask_now(INT_UDN_FIREWALL); | 159 | arch_local_irq_mask_now(INT_UDN_FIREWALL); |
| 160 | } | 160 | } |
| 161 | 161 | ||
| 162 | /* Set up hardwall on this cpu based on the passed hardwall_info. */ | 162 | /* Set up hardwall on this cpu based on the passed hardwall_info. */ |
| @@ -768,13 +768,13 @@ static int hardwall_release(struct inode *inode, struct file *file) | |||
| 768 | } | 768 | } |
| 769 | 769 | ||
| 770 | static const struct file_operations dev_hardwall_fops = { | 770 | static const struct file_operations dev_hardwall_fops = { |
| 771 | .open = nonseekable_open, | ||
| 771 | .unlocked_ioctl = hardwall_ioctl, | 772 | .unlocked_ioctl = hardwall_ioctl, |
| 772 | #ifdef CONFIG_COMPAT | 773 | #ifdef CONFIG_COMPAT |
| 773 | .compat_ioctl = hardwall_compat_ioctl, | 774 | .compat_ioctl = hardwall_compat_ioctl, |
| 774 | #endif | 775 | #endif |
| 775 | .flush = hardwall_flush, | 776 | .flush = hardwall_flush, |
| 776 | .release = hardwall_release, | 777 | .release = hardwall_release, |
| 777 | .llseek = noop_llseek, | ||
| 778 | }; | 778 | }; |
| 779 | 779 | ||
| 780 | static struct cdev hardwall_dev; | 780 | static struct cdev hardwall_dev; |
diff --git a/arch/tile/kernel/irq.c b/arch/tile/kernel/irq.c index e63917687e99..128805ef8f2c 100644 --- a/arch/tile/kernel/irq.c +++ b/arch/tile/kernel/irq.c | |||
| @@ -26,7 +26,7 @@ | |||
| 26 | #define IS_HW_CLEARED 1 | 26 | #define IS_HW_CLEARED 1 |
| 27 | 27 | ||
| 28 | /* | 28 | /* |
| 29 | * The set of interrupts we enable for raw_local_irq_enable(). | 29 | * The set of interrupts we enable for arch_local_irq_enable(). |
| 30 | * This is initialized to have just a single interrupt that the kernel | 30 | * This is initialized to have just a single interrupt that the kernel |
| 31 | * doesn't actually use as a sentinel. During kernel init, | 31 | * doesn't actually use as a sentinel. During kernel init, |
| 32 | * interrupts are added as the kernel gets prepared to support them. | 32 | * interrupts are added as the kernel gets prepared to support them. |
| @@ -225,7 +225,7 @@ void __cpuinit setup_irq_regs(void) | |||
| 225 | /* Enable interrupt delivery. */ | 225 | /* Enable interrupt delivery. */ |
| 226 | unmask_irqs(~0UL); | 226 | unmask_irqs(~0UL); |
| 227 | #if CHIP_HAS_IPI() | 227 | #if CHIP_HAS_IPI() |
| 228 | raw_local_irq_unmask(INT_IPI_K); | 228 | arch_local_irq_unmask(INT_IPI_K); |
| 229 | #endif | 229 | #endif |
| 230 | } | 230 | } |
| 231 | 231 | ||
diff --git a/arch/tile/kernel/machine_kexec.c b/arch/tile/kernel/machine_kexec.c index ba7a265d6179..0d8b9e933487 100644 --- a/arch/tile/kernel/machine_kexec.c +++ b/arch/tile/kernel/machine_kexec.c | |||
| @@ -182,13 +182,13 @@ static void kexec_find_and_set_command_line(struct kimage *image) | |||
| 182 | 182 | ||
| 183 | if ((entry & IND_SOURCE)) { | 183 | if ((entry & IND_SOURCE)) { |
| 184 | void *va = | 184 | void *va = |
| 185 | kmap_atomic_pfn(entry >> PAGE_SHIFT, KM_USER0); | 185 | kmap_atomic_pfn(entry >> PAGE_SHIFT); |
| 186 | r = kexec_bn2cl(va); | 186 | r = kexec_bn2cl(va); |
| 187 | if (r) { | 187 | if (r) { |
| 188 | command_line = r; | 188 | command_line = r; |
| 189 | break; | 189 | break; |
| 190 | } | 190 | } |
| 191 | kunmap_atomic(va, KM_USER0); | 191 | kunmap_atomic(va); |
| 192 | } | 192 | } |
| 193 | } | 193 | } |
| 194 | 194 | ||
| @@ -198,7 +198,7 @@ static void kexec_find_and_set_command_line(struct kimage *image) | |||
| 198 | 198 | ||
| 199 | hverr = hv_set_command_line( | 199 | hverr = hv_set_command_line( |
| 200 | (HV_VirtAddr) command_line, strlen(command_line)); | 200 | (HV_VirtAddr) command_line, strlen(command_line)); |
| 201 | kunmap_atomic(command_line, KM_USER0); | 201 | kunmap_atomic(command_line); |
| 202 | } else { | 202 | } else { |
| 203 | pr_info("%s: no command line found; making empty\n", | 203 | pr_info("%s: no command line found; making empty\n", |
| 204 | __func__); | 204 | __func__); |
diff --git a/arch/tile/kernel/messaging.c b/arch/tile/kernel/messaging.c index 997e3933f726..0858ee6b520f 100644 --- a/arch/tile/kernel/messaging.c +++ b/arch/tile/kernel/messaging.c | |||
| @@ -34,7 +34,7 @@ void __cpuinit init_messaging(void) | |||
| 34 | panic("hv_register_message_state: error %d", rc); | 34 | panic("hv_register_message_state: error %d", rc); |
| 35 | 35 | ||
| 36 | /* Make sure downcall interrupts will be enabled. */ | 36 | /* Make sure downcall interrupts will be enabled. */ |
| 37 | raw_local_irq_unmask(INT_INTCTRL_K); | 37 | arch_local_irq_unmask(INT_INTCTRL_K); |
| 38 | } | 38 | } |
| 39 | 39 | ||
| 40 | void hv_message_intr(struct pt_regs *regs, int intnum) | 40 | void hv_message_intr(struct pt_regs *regs, int intnum) |
diff --git a/arch/tile/kernel/ptrace.c b/arch/tile/kernel/ptrace.c index 9cd29884c09f..e92e40527d6d 100644 --- a/arch/tile/kernel/ptrace.c +++ b/arch/tile/kernel/ptrace.c | |||
| @@ -50,10 +50,10 @@ long arch_ptrace(struct task_struct *child, long request, | |||
| 50 | { | 50 | { |
| 51 | unsigned long __user *datap = (long __user __force *)data; | 51 | unsigned long __user *datap = (long __user __force *)data; |
| 52 | unsigned long tmp; | 52 | unsigned long tmp; |
| 53 | int i; | ||
| 54 | long ret = -EIO; | 53 | long ret = -EIO; |
| 55 | unsigned long *childregs; | ||
| 56 | char *childreg; | 54 | char *childreg; |
| 55 | struct pt_regs copyregs; | ||
| 56 | int ex1_offset; | ||
| 57 | 57 | ||
| 58 | switch (request) { | 58 | switch (request) { |
| 59 | 59 | ||
| @@ -80,6 +80,16 @@ long arch_ptrace(struct task_struct *child, long request, | |||
| 80 | if (addr >= PTREGS_SIZE) | 80 | if (addr >= PTREGS_SIZE) |
| 81 | break; | 81 | break; |
| 82 | childreg = (char *)task_pt_regs(child) + addr; | 82 | childreg = (char *)task_pt_regs(child) + addr; |
| 83 | |||
| 84 | /* Guard against overwrites of the privilege level. */ | ||
| 85 | ex1_offset = PTREGS_OFFSET_EX1; | ||
| 86 | #if defined(CONFIG_COMPAT) && defined(__BIG_ENDIAN) | ||
| 87 | if (is_compat_task()) /* point at low word */ | ||
| 88 | ex1_offset += sizeof(compat_long_t); | ||
| 89 | #endif | ||
| 90 | if (addr == ex1_offset) | ||
| 91 | data = PL_ICS_EX1(USER_PL, EX1_ICS(data)); | ||
| 92 | |||
| 83 | #ifdef CONFIG_COMPAT | 93 | #ifdef CONFIG_COMPAT |
| 84 | if (is_compat_task()) { | 94 | if (is_compat_task()) { |
| 85 | if (addr & (sizeof(compat_long_t)-1)) | 95 | if (addr & (sizeof(compat_long_t)-1)) |
| @@ -96,26 +106,19 @@ long arch_ptrace(struct task_struct *child, long request, | |||
| 96 | break; | 106 | break; |
| 97 | 107 | ||
| 98 | case PTRACE_GETREGS: /* Get all registers from the child. */ | 108 | case PTRACE_GETREGS: /* Get all registers from the child. */ |
| 99 | if (!access_ok(VERIFY_WRITE, datap, PTREGS_SIZE)) | 109 | if (copy_to_user(datap, task_pt_regs(child), |
| 100 | break; | 110 | sizeof(struct pt_regs)) == 0) { |
| 101 | childregs = (long *)task_pt_regs(child); | 111 | ret = 0; |
| 102 | for (i = 0; i < sizeof(struct pt_regs)/sizeof(unsigned long); | ||
| 103 | ++i) { | ||
| 104 | ret = __put_user(childregs[i], &datap[i]); | ||
| 105 | if (ret != 0) | ||
| 106 | break; | ||
| 107 | } | 112 | } |
| 108 | break; | 113 | break; |
| 109 | 114 | ||
| 110 | case PTRACE_SETREGS: /* Set all registers in the child. */ | 115 | case PTRACE_SETREGS: /* Set all registers in the child. */ |
| 111 | if (!access_ok(VERIFY_READ, datap, PTREGS_SIZE)) | 116 | if (copy_from_user(©regs, datap, |
| 112 | break; | 117 | sizeof(struct pt_regs)) == 0) { |
| 113 | childregs = (long *)task_pt_regs(child); | 118 | copyregs.ex1 = |
| 114 | for (i = 0; i < sizeof(struct pt_regs)/sizeof(unsigned long); | 119 | PL_ICS_EX1(USER_PL, EX1_ICS(copyregs.ex1)); |
| 115 | ++i) { | 120 | *task_pt_regs(child) = copyregs; |
| 116 | ret = __get_user(childregs[i], &datap[i]); | 121 | ret = 0; |
| 117 | if (ret != 0) | ||
| 118 | break; | ||
| 119 | } | 122 | } |
| 120 | break; | 123 | break; |
| 121 | 124 | ||
diff --git a/arch/tile/kernel/reboot.c b/arch/tile/kernel/reboot.c index acd86d20beba..baa3d905fee2 100644 --- a/arch/tile/kernel/reboot.c +++ b/arch/tile/kernel/reboot.c | |||
| @@ -27,7 +27,7 @@ | |||
| 27 | void machine_halt(void) | 27 | void machine_halt(void) |
| 28 | { | 28 | { |
| 29 | warn_early_printk(); | 29 | warn_early_printk(); |
| 30 | raw_local_irq_disable_all(); | 30 | arch_local_irq_disable_all(); |
| 31 | smp_send_stop(); | 31 | smp_send_stop(); |
| 32 | hv_halt(); | 32 | hv_halt(); |
| 33 | } | 33 | } |
| @@ -35,14 +35,14 @@ void machine_halt(void) | |||
| 35 | void machine_power_off(void) | 35 | void machine_power_off(void) |
| 36 | { | 36 | { |
| 37 | warn_early_printk(); | 37 | warn_early_printk(); |
| 38 | raw_local_irq_disable_all(); | 38 | arch_local_irq_disable_all(); |
| 39 | smp_send_stop(); | 39 | smp_send_stop(); |
| 40 | hv_power_off(); | 40 | hv_power_off(); |
| 41 | } | 41 | } |
| 42 | 42 | ||
| 43 | void machine_restart(char *cmd) | 43 | void machine_restart(char *cmd) |
| 44 | { | 44 | { |
| 45 | raw_local_irq_disable_all(); | 45 | arch_local_irq_disable_all(); |
| 46 | smp_send_stop(); | 46 | smp_send_stop(); |
| 47 | hv_restart((HV_VirtAddr) "vmlinux", (HV_VirtAddr) cmd); | 47 | hv_restart((HV_VirtAddr) "vmlinux", (HV_VirtAddr) cmd); |
| 48 | } | 48 | } |
diff --git a/arch/tile/kernel/setup.c b/arch/tile/kernel/setup.c index ae51cad12da0..fb0b3cbeae14 100644 --- a/arch/tile/kernel/setup.c +++ b/arch/tile/kernel/setup.c | |||
| @@ -868,14 +868,14 @@ void __cpuinit setup_cpu(int boot) | |||
| 868 | 868 | ||
| 869 | /* Allow asynchronous TLB interrupts. */ | 869 | /* Allow asynchronous TLB interrupts. */ |
| 870 | #if CHIP_HAS_TILE_DMA() | 870 | #if CHIP_HAS_TILE_DMA() |
| 871 | raw_local_irq_unmask(INT_DMATLB_MISS); | 871 | arch_local_irq_unmask(INT_DMATLB_MISS); |
| 872 | raw_local_irq_unmask(INT_DMATLB_ACCESS); | 872 | arch_local_irq_unmask(INT_DMATLB_ACCESS); |
| 873 | #endif | 873 | #endif |
| 874 | #if CHIP_HAS_SN_PROC() | 874 | #if CHIP_HAS_SN_PROC() |
| 875 | raw_local_irq_unmask(INT_SNITLB_MISS); | 875 | arch_local_irq_unmask(INT_SNITLB_MISS); |
| 876 | #endif | 876 | #endif |
| 877 | #ifdef __tilegx__ | 877 | #ifdef __tilegx__ |
| 878 | raw_local_irq_unmask(INT_SINGLE_STEP_K); | 878 | arch_local_irq_unmask(INT_SINGLE_STEP_K); |
| 879 | #endif | 879 | #endif |
| 880 | 880 | ||
| 881 | /* | 881 | /* |
diff --git a/arch/tile/kernel/signal.c b/arch/tile/kernel/signal.c index fb28e85ae3ae..687719d4abd1 100644 --- a/arch/tile/kernel/signal.c +++ b/arch/tile/kernel/signal.c | |||
| @@ -71,6 +71,9 @@ int restore_sigcontext(struct pt_regs *regs, | |||
| 71 | for (i = 0; i < sizeof(struct pt_regs)/sizeof(long); ++i) | 71 | for (i = 0; i < sizeof(struct pt_regs)/sizeof(long); ++i) |
| 72 | err |= __get_user(regs->regs[i], &sc->gregs[i]); | 72 | err |= __get_user(regs->regs[i], &sc->gregs[i]); |
| 73 | 73 | ||
| 74 | /* Ensure that the PL is always set to USER_PL. */ | ||
| 75 | regs->ex1 = PL_ICS_EX1(USER_PL, EX1_ICS(regs->ex1)); | ||
| 76 | |||
| 74 | regs->faultnum = INT_SWINT_1_SIGRETURN; | 77 | regs->faultnum = INT_SWINT_1_SIGRETURN; |
| 75 | 78 | ||
| 76 | err |= __get_user(*pr0, &sc->gregs[0]); | 79 | err |= __get_user(*pr0, &sc->gregs[0]); |
| @@ -330,7 +333,7 @@ void do_signal(struct pt_regs *regs) | |||
| 330 | current_thread_info()->status &= ~TS_RESTORE_SIGMASK; | 333 | current_thread_info()->status &= ~TS_RESTORE_SIGMASK; |
| 331 | } | 334 | } |
| 332 | 335 | ||
| 333 | return; | 336 | goto done; |
| 334 | } | 337 | } |
| 335 | 338 | ||
| 336 | /* Did we come from a system call? */ | 339 | /* Did we come from a system call? */ |
| @@ -358,4 +361,8 @@ void do_signal(struct pt_regs *regs) | |||
| 358 | current_thread_info()->status &= ~TS_RESTORE_SIGMASK; | 361 | current_thread_info()->status &= ~TS_RESTORE_SIGMASK; |
| 359 | sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); | 362 | sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); |
| 360 | } | 363 | } |
| 364 | |||
| 365 | done: | ||
| 366 | /* Avoid double syscall restart if there are nested signals. */ | ||
| 367 | regs->faultnum = INT_SWINT_1_SIGRETURN; | ||
| 361 | } | 368 | } |
diff --git a/arch/tile/kernel/smp.c b/arch/tile/kernel/smp.c index 75255d90aff3..9575b37a8b75 100644 --- a/arch/tile/kernel/smp.c +++ b/arch/tile/kernel/smp.c | |||
| @@ -115,7 +115,7 @@ static void smp_start_cpu_interrupt(void) | |||
| 115 | static void smp_stop_cpu_interrupt(void) | 115 | static void smp_stop_cpu_interrupt(void) |
| 116 | { | 116 | { |
| 117 | set_cpu_online(smp_processor_id(), 0); | 117 | set_cpu_online(smp_processor_id(), 0); |
| 118 | raw_local_irq_disable_all(); | 118 | arch_local_irq_disable_all(); |
| 119 | for (;;) | 119 | for (;;) |
| 120 | asm("nap"); | 120 | asm("nap"); |
| 121 | } | 121 | } |
diff --git a/arch/tile/kernel/time.c b/arch/tile/kernel/time.c index 6bed820e1421..f2e156e44692 100644 --- a/arch/tile/kernel/time.c +++ b/arch/tile/kernel/time.c | |||
| @@ -132,7 +132,7 @@ static int tile_timer_set_next_event(unsigned long ticks, | |||
| 132 | { | 132 | { |
| 133 | BUG_ON(ticks > MAX_TICK); | 133 | BUG_ON(ticks > MAX_TICK); |
| 134 | __insn_mtspr(SPR_TILE_TIMER_CONTROL, ticks); | 134 | __insn_mtspr(SPR_TILE_TIMER_CONTROL, ticks); |
| 135 | raw_local_irq_unmask_now(INT_TILE_TIMER); | 135 | arch_local_irq_unmask_now(INT_TILE_TIMER); |
| 136 | return 0; | 136 | return 0; |
| 137 | } | 137 | } |
| 138 | 138 | ||
| @@ -143,7 +143,7 @@ static int tile_timer_set_next_event(unsigned long ticks, | |||
| 143 | static void tile_timer_set_mode(enum clock_event_mode mode, | 143 | static void tile_timer_set_mode(enum clock_event_mode mode, |
| 144 | struct clock_event_device *evt) | 144 | struct clock_event_device *evt) |
| 145 | { | 145 | { |
| 146 | raw_local_irq_mask_now(INT_TILE_TIMER); | 146 | arch_local_irq_mask_now(INT_TILE_TIMER); |
| 147 | } | 147 | } |
| 148 | 148 | ||
| 149 | /* | 149 | /* |
| @@ -172,7 +172,7 @@ void __cpuinit setup_tile_timer(void) | |||
| 172 | evt->cpumask = cpumask_of(smp_processor_id()); | 172 | evt->cpumask = cpumask_of(smp_processor_id()); |
| 173 | 173 | ||
| 174 | /* Start out with timer not firing. */ | 174 | /* Start out with timer not firing. */ |
| 175 | raw_local_irq_mask_now(INT_TILE_TIMER); | 175 | arch_local_irq_mask_now(INT_TILE_TIMER); |
| 176 | 176 | ||
| 177 | /* Register tile timer. */ | 177 | /* Register tile timer. */ |
| 178 | clockevents_register_device(evt); | 178 | clockevents_register_device(evt); |
| @@ -188,7 +188,7 @@ void do_timer_interrupt(struct pt_regs *regs, int fault_num) | |||
| 188 | * Mask the timer interrupt here, since we are a oneshot timer | 188 | * Mask the timer interrupt here, since we are a oneshot timer |
| 189 | * and there are now by definition no events pending. | 189 | * and there are now by definition no events pending. |
| 190 | */ | 190 | */ |
| 191 | raw_local_irq_mask(INT_TILE_TIMER); | 191 | arch_local_irq_mask(INT_TILE_TIMER); |
| 192 | 192 | ||
| 193 | /* Track time spent here in an interrupt context */ | 193 | /* Track time spent here in an interrupt context */ |
| 194 | irq_enter(); | 194 | irq_enter(); |
diff --git a/arch/tile/lib/memcpy_tile64.c b/arch/tile/lib/memcpy_tile64.c index dfedea7b266b..f7d4a6ad61e8 100644 --- a/arch/tile/lib/memcpy_tile64.c +++ b/arch/tile/lib/memcpy_tile64.c | |||
| @@ -54,7 +54,7 @@ typedef unsigned long (*memcpy_t)(void *, const void *, unsigned long); | |||
| 54 | * we must run with interrupts disabled to avoid the risk of some | 54 | * we must run with interrupts disabled to avoid the risk of some |
| 55 | * other code seeing the incoherent data in our cache. (Recall that | 55 | * other code seeing the incoherent data in our cache. (Recall that |
| 56 | * our cache is indexed by PA, so even if the other code doesn't use | 56 | * our cache is indexed by PA, so even if the other code doesn't use |
| 57 | * our KM_MEMCPY virtual addresses, they'll still hit in cache using | 57 | * our kmap_atomic virtual addresses, they'll still hit in cache using |
| 58 | * the normal VAs that aren't supposed to hit in cache.) | 58 | * the normal VAs that aren't supposed to hit in cache.) |
| 59 | */ | 59 | */ |
| 60 | static void memcpy_multicache(void *dest, const void *source, | 60 | static void memcpy_multicache(void *dest, const void *source, |
| @@ -64,6 +64,7 @@ static void memcpy_multicache(void *dest, const void *source, | |||
| 64 | unsigned long flags, newsrc, newdst; | 64 | unsigned long flags, newsrc, newdst; |
| 65 | pmd_t *pmdp; | 65 | pmd_t *pmdp; |
| 66 | pte_t *ptep; | 66 | pte_t *ptep; |
| 67 | int type0, type1; | ||
| 67 | int cpu = get_cpu(); | 68 | int cpu = get_cpu(); |
| 68 | 69 | ||
| 69 | /* | 70 | /* |
| @@ -77,7 +78,8 @@ static void memcpy_multicache(void *dest, const void *source, | |||
| 77 | sim_allow_multiple_caching(1); | 78 | sim_allow_multiple_caching(1); |
| 78 | 79 | ||
| 79 | /* Set up the new dest mapping */ | 80 | /* Set up the new dest mapping */ |
| 80 | idx = FIX_KMAP_BEGIN + (KM_TYPE_NR * cpu) + KM_MEMCPY0; | 81 | type0 = kmap_atomic_idx_push(); |
| 82 | idx = FIX_KMAP_BEGIN + (KM_TYPE_NR * cpu) + type0; | ||
| 81 | newdst = __fix_to_virt(idx) + ((unsigned long)dest & (PAGE_SIZE-1)); | 83 | newdst = __fix_to_virt(idx) + ((unsigned long)dest & (PAGE_SIZE-1)); |
| 82 | pmdp = pmd_offset(pud_offset(pgd_offset_k(newdst), newdst), newdst); | 84 | pmdp = pmd_offset(pud_offset(pgd_offset_k(newdst), newdst), newdst); |
| 83 | ptep = pte_offset_kernel(pmdp, newdst); | 85 | ptep = pte_offset_kernel(pmdp, newdst); |
| @@ -87,7 +89,8 @@ static void memcpy_multicache(void *dest, const void *source, | |||
| 87 | } | 89 | } |
| 88 | 90 | ||
| 89 | /* Set up the new source mapping */ | 91 | /* Set up the new source mapping */ |
| 90 | idx += (KM_MEMCPY0 - KM_MEMCPY1); | 92 | type1 = kmap_atomic_idx_push(); |
| 93 | idx += (type0 - type1); | ||
| 91 | src_pte = hv_pte_set_nc(src_pte); | 94 | src_pte = hv_pte_set_nc(src_pte); |
| 92 | src_pte = hv_pte_clear_writable(src_pte); /* be paranoid */ | 95 | src_pte = hv_pte_clear_writable(src_pte); /* be paranoid */ |
| 93 | newsrc = __fix_to_virt(idx) + ((unsigned long)source & (PAGE_SIZE-1)); | 96 | newsrc = __fix_to_virt(idx) + ((unsigned long)source & (PAGE_SIZE-1)); |
| @@ -119,6 +122,8 @@ static void memcpy_multicache(void *dest, const void *source, | |||
| 119 | * We're done: notify the simulator that all is back to normal, | 122 | * We're done: notify the simulator that all is back to normal, |
| 120 | * and re-enable interrupts and pre-emption. | 123 | * and re-enable interrupts and pre-emption. |
| 121 | */ | 124 | */ |
| 125 | kmap_atomic_idx_pop(); | ||
| 126 | kmap_atomic_idx_pop(); | ||
| 122 | sim_allow_multiple_caching(0); | 127 | sim_allow_multiple_caching(0); |
| 123 | local_irq_restore(flags); | 128 | local_irq_restore(flags); |
| 124 | put_cpu(); | 129 | put_cpu(); |
diff --git a/arch/tile/mm/highmem.c b/arch/tile/mm/highmem.c index abb57331cf6e..31dbbd9afe47 100644 --- a/arch/tile/mm/highmem.c +++ b/arch/tile/mm/highmem.c | |||
| @@ -227,7 +227,7 @@ EXPORT_SYMBOL(kmap_atomic_prot); | |||
| 227 | void *__kmap_atomic(struct page *page) | 227 | void *__kmap_atomic(struct page *page) |
| 228 | { | 228 | { |
| 229 | /* PAGE_NONE is a magic value that tells us to check immutability. */ | 229 | /* PAGE_NONE is a magic value that tells us to check immutability. */ |
| 230 | return kmap_atomic_prot(page, type, PAGE_NONE); | 230 | return kmap_atomic_prot(page, PAGE_NONE); |
| 231 | } | 231 | } |
| 232 | EXPORT_SYMBOL(__kmap_atomic); | 232 | EXPORT_SYMBOL(__kmap_atomic); |
| 233 | 233 | ||
diff --git a/arch/tile/mm/init.c b/arch/tile/mm/init.c index 78e1982cb6c9..0b9ce69b0ee5 100644 --- a/arch/tile/mm/init.c +++ b/arch/tile/mm/init.c | |||
| @@ -988,8 +988,12 @@ static long __write_once initfree = 1; | |||
| 988 | /* Select whether to free (1) or mark unusable (0) the __init pages. */ | 988 | /* Select whether to free (1) or mark unusable (0) the __init pages. */ |
| 989 | static int __init set_initfree(char *str) | 989 | static int __init set_initfree(char *str) |
| 990 | { | 990 | { |
| 991 | strict_strtol(str, 0, &initfree); | 991 | long val; |
| 992 | pr_info("initfree: %s free init pages\n", initfree ? "will" : "won't"); | 992 | if (strict_strtol(str, 0, &val)) { |
| 993 | initfree = val; | ||
| 994 | pr_info("initfree: %s free init pages\n", | ||
| 995 | initfree ? "will" : "won't"); | ||
| 996 | } | ||
| 993 | return 1; | 997 | return 1; |
| 994 | } | 998 | } |
| 995 | __setup("initfree=", set_initfree); | 999 | __setup("initfree=", set_initfree); |
diff --git a/arch/tile/mm/pgtable.c b/arch/tile/mm/pgtable.c index 335c24621c41..1f5430c53d0d 100644 --- a/arch/tile/mm/pgtable.c +++ b/arch/tile/mm/pgtable.c | |||
| @@ -134,9 +134,9 @@ void __set_fixmap(enum fixed_addresses idx, unsigned long phys, pgprot_t flags) | |||
| 134 | } | 134 | } |
| 135 | 135 | ||
| 136 | #if defined(CONFIG_HIGHPTE) | 136 | #if defined(CONFIG_HIGHPTE) |
| 137 | pte_t *_pte_offset_map(pmd_t *dir, unsigned long address, enum km_type type) | 137 | pte_t *_pte_offset_map(pmd_t *dir, unsigned long address) |
| 138 | { | 138 | { |
| 139 | pte_t *pte = kmap_atomic(pmd_page(*dir), type) + | 139 | pte_t *pte = kmap_atomic(pmd_page(*dir)) + |
| 140 | (pmd_ptfn(*dir) << HV_LOG2_PAGE_TABLE_ALIGN) & ~PAGE_MASK; | 140 | (pmd_ptfn(*dir) << HV_LOG2_PAGE_TABLE_ALIGN) & ~PAGE_MASK; |
| 141 | return &pte[pte_index(address)]; | 141 | return &pte[pte_index(address)]; |
| 142 | } | 142 | } |
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c index 767107cce982..8f19b380ca83 100644 --- a/drivers/block/floppy.c +++ b/drivers/block/floppy.c | |||
| @@ -4363,9 +4363,9 @@ out_unreg_blkdev: | |||
| 4363 | out_put_disk: | 4363 | out_put_disk: |
| 4364 | while (dr--) { | 4364 | while (dr--) { |
| 4365 | del_timer(&motor_off_timer[dr]); | 4365 | del_timer(&motor_off_timer[dr]); |
| 4366 | put_disk(disks[dr]); | ||
| 4367 | if (disks[dr]->queue) | 4366 | if (disks[dr]->queue) |
| 4368 | blk_cleanup_queue(disks[dr]->queue); | 4367 | blk_cleanup_queue(disks[dr]->queue); |
| 4368 | put_disk(disks[dr]); | ||
| 4369 | } | 4369 | } |
| 4370 | return err; | 4370 | return err; |
| 4371 | } | 4371 | } |
diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c index 9dcb17d51aee..84eb607d6c03 100644 --- a/drivers/firewire/ohci.c +++ b/drivers/firewire/ohci.c | |||
| @@ -577,17 +577,11 @@ static int ohci_update_phy_reg(struct fw_card *card, int addr, | |||
| 577 | return ret; | 577 | return ret; |
| 578 | } | 578 | } |
| 579 | 579 | ||
| 580 | static int ar_context_add_page(struct ar_context *ctx) | 580 | static void ar_context_link_page(struct ar_context *ctx, |
| 581 | struct ar_buffer *ab, dma_addr_t ab_bus) | ||
| 581 | { | 582 | { |
| 582 | struct device *dev = ctx->ohci->card.device; | ||
| 583 | struct ar_buffer *ab; | ||
| 584 | dma_addr_t uninitialized_var(ab_bus); | ||
| 585 | size_t offset; | 583 | size_t offset; |
| 586 | 584 | ||
| 587 | ab = dma_alloc_coherent(dev, PAGE_SIZE, &ab_bus, GFP_ATOMIC); | ||
| 588 | if (ab == NULL) | ||
| 589 | return -ENOMEM; | ||
| 590 | |||
| 591 | ab->next = NULL; | 585 | ab->next = NULL; |
| 592 | memset(&ab->descriptor, 0, sizeof(ab->descriptor)); | 586 | memset(&ab->descriptor, 0, sizeof(ab->descriptor)); |
| 593 | ab->descriptor.control = cpu_to_le16(DESCRIPTOR_INPUT_MORE | | 587 | ab->descriptor.control = cpu_to_le16(DESCRIPTOR_INPUT_MORE | |
| @@ -606,6 +600,19 @@ static int ar_context_add_page(struct ar_context *ctx) | |||
| 606 | 600 | ||
| 607 | reg_write(ctx->ohci, CONTROL_SET(ctx->regs), CONTEXT_WAKE); | 601 | reg_write(ctx->ohci, CONTROL_SET(ctx->regs), CONTEXT_WAKE); |
| 608 | flush_writes(ctx->ohci); | 602 | flush_writes(ctx->ohci); |
| 603 | } | ||
| 604 | |||
| 605 | static int ar_context_add_page(struct ar_context *ctx) | ||
| 606 | { | ||
| 607 | struct device *dev = ctx->ohci->card.device; | ||
| 608 | struct ar_buffer *ab; | ||
| 609 | dma_addr_t uninitialized_var(ab_bus); | ||
| 610 | |||
| 611 | ab = dma_alloc_coherent(dev, PAGE_SIZE, &ab_bus, GFP_ATOMIC); | ||
| 612 | if (ab == NULL) | ||
| 613 | return -ENOMEM; | ||
| 614 | |||
| 615 | ar_context_link_page(ctx, ab, ab_bus); | ||
| 609 | 616 | ||
| 610 | return 0; | 617 | return 0; |
| 611 | } | 618 | } |
| @@ -730,16 +737,17 @@ static __le32 *handle_ar_packet(struct ar_context *ctx, __le32 *buffer) | |||
| 730 | static void ar_context_tasklet(unsigned long data) | 737 | static void ar_context_tasklet(unsigned long data) |
| 731 | { | 738 | { |
| 732 | struct ar_context *ctx = (struct ar_context *)data; | 739 | struct ar_context *ctx = (struct ar_context *)data; |
| 733 | struct fw_ohci *ohci = ctx->ohci; | ||
| 734 | struct ar_buffer *ab; | 740 | struct ar_buffer *ab; |
| 735 | struct descriptor *d; | 741 | struct descriptor *d; |
| 736 | void *buffer, *end; | 742 | void *buffer, *end; |
| 743 | __le16 res_count; | ||
| 737 | 744 | ||
| 738 | ab = ctx->current_buffer; | 745 | ab = ctx->current_buffer; |
| 739 | d = &ab->descriptor; | 746 | d = &ab->descriptor; |
| 740 | 747 | ||
| 741 | if (d->res_count == 0) { | 748 | res_count = ACCESS_ONCE(d->res_count); |
| 742 | size_t size, rest, offset; | 749 | if (res_count == 0) { |
| 750 | size_t size, size2, rest, pktsize, size3, offset; | ||
| 743 | dma_addr_t start_bus; | 751 | dma_addr_t start_bus; |
| 744 | void *start; | 752 | void *start; |
| 745 | 753 | ||
| @@ -750,29 +758,63 @@ static void ar_context_tasklet(unsigned long data) | |||
| 750 | */ | 758 | */ |
| 751 | 759 | ||
| 752 | offset = offsetof(struct ar_buffer, data); | 760 | offset = offsetof(struct ar_buffer, data); |
| 753 | start = buffer = ab; | 761 | start = ab; |
| 754 | start_bus = le32_to_cpu(ab->descriptor.data_address) - offset; | 762 | start_bus = le32_to_cpu(ab->descriptor.data_address) - offset; |
| 763 | buffer = ab->data; | ||
| 755 | 764 | ||
| 756 | ab = ab->next; | 765 | ab = ab->next; |
| 757 | d = &ab->descriptor; | 766 | d = &ab->descriptor; |
| 758 | size = buffer + PAGE_SIZE - ctx->pointer; | 767 | size = start + PAGE_SIZE - ctx->pointer; |
| 768 | /* valid buffer data in the next page */ | ||
| 759 | rest = le16_to_cpu(d->req_count) - le16_to_cpu(d->res_count); | 769 | rest = le16_to_cpu(d->req_count) - le16_to_cpu(d->res_count); |
| 770 | /* what actually fits in this page */ | ||
| 771 | size2 = min(rest, (size_t)PAGE_SIZE - offset - size); | ||
| 760 | memmove(buffer, ctx->pointer, size); | 772 | memmove(buffer, ctx->pointer, size); |
| 761 | memcpy(buffer + size, ab->data, rest); | 773 | memcpy(buffer + size, ab->data, size2); |
| 762 | ctx->current_buffer = ab; | 774 | |
| 763 | ctx->pointer = (void *) ab->data + rest; | 775 | while (size > 0) { |
| 764 | end = buffer + size + rest; | 776 | void *next = handle_ar_packet(ctx, buffer); |
| 777 | pktsize = next - buffer; | ||
| 778 | if (pktsize >= size) { | ||
| 779 | /* | ||
| 780 | * We have handled all the data that was | ||
| 781 | * originally in this page, so we can now | ||
| 782 | * continue in the next page. | ||
| 783 | */ | ||
| 784 | buffer = next; | ||
| 785 | break; | ||
| 786 | } | ||
| 787 | /* move the next packet to the start of the buffer */ | ||
| 788 | memmove(buffer, next, size + size2 - pktsize); | ||
| 789 | size -= pktsize; | ||
| 790 | /* fill up this page again */ | ||
| 791 | size3 = min(rest - size2, | ||
| 792 | (size_t)PAGE_SIZE - offset - size - size2); | ||
| 793 | memcpy(buffer + size + size2, | ||
| 794 | (void *) ab->data + size2, size3); | ||
| 795 | size2 += size3; | ||
| 796 | } | ||
| 765 | 797 | ||
| 766 | while (buffer < end) | 798 | if (rest > 0) { |
| 767 | buffer = handle_ar_packet(ctx, buffer); | 799 | /* handle the packets that are fully in the next page */ |
| 800 | buffer = (void *) ab->data + | ||
| 801 | (buffer - (start + offset + size)); | ||
| 802 | end = (void *) ab->data + rest; | ||
| 803 | |||
| 804 | while (buffer < end) | ||
| 805 | buffer = handle_ar_packet(ctx, buffer); | ||
| 768 | 806 | ||
| 769 | dma_free_coherent(ohci->card.device, PAGE_SIZE, | 807 | ctx->current_buffer = ab; |
| 770 | start, start_bus); | 808 | ctx->pointer = end; |
| 771 | ar_context_add_page(ctx); | 809 | |
| 810 | ar_context_link_page(ctx, start, start_bus); | ||
| 811 | } else { | ||
| 812 | ctx->pointer = start + PAGE_SIZE; | ||
| 813 | } | ||
| 772 | } else { | 814 | } else { |
| 773 | buffer = ctx->pointer; | 815 | buffer = ctx->pointer; |
| 774 | ctx->pointer = end = | 816 | ctx->pointer = end = |
| 775 | (void *) ab + PAGE_SIZE - le16_to_cpu(d->res_count); | 817 | (void *) ab + PAGE_SIZE - le16_to_cpu(res_count); |
| 776 | 818 | ||
| 777 | while (buffer < end) | 819 | while (buffer < end) |
| 778 | buffer = handle_ar_packet(ctx, buffer); | 820 | buffer = handle_ar_packet(ctx, buffer); |
diff --git a/drivers/hwmon/ltc4261.c b/drivers/hwmon/ltc4261.c index 267626178678..4b50601027d3 100644 --- a/drivers/hwmon/ltc4261.c +++ b/drivers/hwmon/ltc4261.c | |||
| @@ -82,7 +82,7 @@ static struct ltc4261_data *ltc4261_update_device(struct device *dev) | |||
| 82 | val = i2c_smbus_read_byte_data(client, i); | 82 | val = i2c_smbus_read_byte_data(client, i); |
| 83 | if (unlikely(val < 0)) { | 83 | if (unlikely(val < 0)) { |
| 84 | dev_dbg(dev, | 84 | dev_dbg(dev, |
| 85 | "Failed to read ADC value: error %d", | 85 | "Failed to read ADC value: error %d\n", |
| 86 | val); | 86 | val); |
| 87 | ret = ERR_PTR(val); | 87 | ret = ERR_PTR(val); |
| 88 | goto abort; | 88 | goto abort; |
| @@ -230,8 +230,7 @@ static int ltc4261_probe(struct i2c_client *client, | |||
| 230 | return -ENODEV; | 230 | return -ENODEV; |
| 231 | 231 | ||
| 232 | if (i2c_smbus_read_byte_data(client, LTC4261_STATUS) < 0) { | 232 | if (i2c_smbus_read_byte_data(client, LTC4261_STATUS) < 0) { |
| 233 | dev_err(&client->dev, "Failed to read register %d:%02x:%02x\n", | 233 | dev_err(&client->dev, "Failed to read status register\n"); |
| 234 | adapter->id, client->addr, LTC4261_STATUS); | ||
| 235 | return -ENODEV; | 234 | return -ENODEV; |
| 236 | } | 235 | } |
| 237 | 236 | ||
diff --git a/drivers/isdn/hisax/isar.c b/drivers/isdn/hisax/isar.c index 40b914bded8c..2e72227bd071 100644 --- a/drivers/isdn/hisax/isar.c +++ b/drivers/isdn/hisax/isar.c | |||
| @@ -1427,8 +1427,8 @@ modeisar(struct BCState *bcs, int mode, int bc) | |||
| 1427 | &bcs->hw.isar.reg->Flags)) | 1427 | &bcs->hw.isar.reg->Flags)) |
| 1428 | bcs->hw.isar.dpath = 1; | 1428 | bcs->hw.isar.dpath = 1; |
| 1429 | else { | 1429 | else { |
| 1430 | printk(KERN_WARNING"isar modeisar analog funktions only with DP1\n"); | 1430 | printk(KERN_WARNING"isar modeisar analog functions only with DP1\n"); |
| 1431 | debugl1(cs, "isar modeisar analog funktions only with DP1"); | 1431 | debugl1(cs, "isar modeisar analog functions only with DP1"); |
| 1432 | return(1); | 1432 | return(1); |
| 1433 | } | 1433 | } |
| 1434 | break; | 1434 | break; |
diff --git a/drivers/leds/leds-net5501.c b/drivers/leds/leds-net5501.c index 3063f591f0dc..1739557a9038 100644 --- a/drivers/leds/leds-net5501.c +++ b/drivers/leds/leds-net5501.c | |||
| @@ -92,3 +92,5 @@ unmap: | |||
| 92 | } | 92 | } |
| 93 | 93 | ||
| 94 | arch_initcall(soekris_init); | 94 | arch_initcall(soekris_init); |
| 95 | |||
| 96 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/net/atlx/atl1.c b/drivers/net/atlx/atl1.c index 43579b3b24ac..53363108994e 100644 --- a/drivers/net/atlx/atl1.c +++ b/drivers/net/atlx/atl1.c | |||
| @@ -3043,7 +3043,6 @@ static int __devinit atl1_probe(struct pci_dev *pdev, | |||
| 3043 | atl1_pcie_patch(adapter); | 3043 | atl1_pcie_patch(adapter); |
| 3044 | /* assume we have no link for now */ | 3044 | /* assume we have no link for now */ |
| 3045 | netif_carrier_off(netdev); | 3045 | netif_carrier_off(netdev); |
| 3046 | netif_stop_queue(netdev); | ||
| 3047 | 3046 | ||
| 3048 | setup_timer(&adapter->phy_config_timer, atl1_phy_config, | 3047 | setup_timer(&adapter->phy_config_timer, atl1_phy_config, |
| 3049 | (unsigned long)adapter); | 3048 | (unsigned long)adapter); |
diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h index 9eea225decaf..863e73a85fbe 100644 --- a/drivers/net/bnx2x/bnx2x.h +++ b/drivers/net/bnx2x/bnx2x.h | |||
| @@ -20,8 +20,8 @@ | |||
| 20 | * (you will need to reboot afterwards) */ | 20 | * (you will need to reboot afterwards) */ |
| 21 | /* #define BNX2X_STOP_ON_ERROR */ | 21 | /* #define BNX2X_STOP_ON_ERROR */ |
| 22 | 22 | ||
| 23 | #define DRV_MODULE_VERSION "1.60.00-3" | 23 | #define DRV_MODULE_VERSION "1.60.00-4" |
| 24 | #define DRV_MODULE_RELDATE "2010/10/19" | 24 | #define DRV_MODULE_RELDATE "2010/11/01" |
| 25 | #define BNX2X_BC_VER 0x040200 | 25 | #define BNX2X_BC_VER 0x040200 |
| 26 | 26 | ||
| 27 | #define BNX2X_MULTI_QUEUE | 27 | #define BNX2X_MULTI_QUEUE |
diff --git a/drivers/net/bnx2x/bnx2x_hsi.h b/drivers/net/bnx2x/bnx2x_hsi.h index 18c8e23a0e82..4cfd4e9b5586 100644 --- a/drivers/net/bnx2x/bnx2x_hsi.h +++ b/drivers/net/bnx2x/bnx2x_hsi.h | |||
| @@ -244,7 +244,14 @@ struct port_hw_cfg { /* port 0: 0x12c port 1: 0x2bc */ | |||
| 244 | 244 | ||
| 245 | u16 xgxs_config_tx[4]; /* 0x1A0 */ | 245 | u16 xgxs_config_tx[4]; /* 0x1A0 */ |
| 246 | 246 | ||
| 247 | u32 Reserved1[57]; /* 0x1A8 */ | 247 | u32 Reserved1[56]; /* 0x1A8 */ |
| 248 | u32 default_cfg; /* 0x288 */ | ||
| 249 | /* Enable BAM on KR */ | ||
| 250 | #define PORT_HW_CFG_ENABLE_BAM_ON_KR_MASK 0x00100000 | ||
| 251 | #define PORT_HW_CFG_ENABLE_BAM_ON_KR_SHIFT 20 | ||
| 252 | #define PORT_HW_CFG_ENABLE_BAM_ON_KR_DISABLED 0x00000000 | ||
| 253 | #define PORT_HW_CFG_ENABLE_BAM_ON_KR_ENABLED 0x00100000 | ||
| 254 | |||
| 248 | u32 speed_capability_mask2; /* 0x28C */ | 255 | u32 speed_capability_mask2; /* 0x28C */ |
| 249 | #define PORT_HW_CFG_SPEED_CAPABILITY2_D3_MASK 0x0000FFFF | 256 | #define PORT_HW_CFG_SPEED_CAPABILITY2_D3_MASK 0x0000FFFF |
| 250 | #define PORT_HW_CFG_SPEED_CAPABILITY2_D3_SHIFT 0 | 257 | #define PORT_HW_CFG_SPEED_CAPABILITY2_D3_SHIFT 0 |
diff --git a/drivers/net/bnx2x/bnx2x_link.c b/drivers/net/bnx2x/bnx2x_link.c index 2326774df843..580919619252 100644 --- a/drivers/net/bnx2x/bnx2x_link.c +++ b/drivers/net/bnx2x/bnx2x_link.c | |||
| @@ -610,7 +610,7 @@ static u8 bnx2x_bmac_enable(struct link_params *params, | |||
| 610 | /* reset and unreset the BigMac */ | 610 | /* reset and unreset the BigMac */ |
| 611 | REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR, | 611 | REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR, |
| 612 | (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port)); | 612 | (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port)); |
| 613 | udelay(10); | 613 | msleep(1); |
| 614 | 614 | ||
| 615 | REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET, | 615 | REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET, |
| 616 | (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port)); | 616 | (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port)); |
| @@ -3525,13 +3525,19 @@ static u8 bnx2x_8073_config_init(struct bnx2x_phy *phy, | |||
| 3525 | DP(NETIF_MSG_LINK, "Before rom RX_ALARM(port1): 0x%x\n", tmp1); | 3525 | DP(NETIF_MSG_LINK, "Before rom RX_ALARM(port1): 0x%x\n", tmp1); |
| 3526 | 3526 | ||
| 3527 | /* Enable CL37 BAM */ | 3527 | /* Enable CL37 BAM */ |
| 3528 | bnx2x_cl45_read(bp, phy, | 3528 | if (REG_RD(bp, params->shmem_base + |
| 3529 | MDIO_AN_DEVAD, | 3529 | offsetof(struct shmem_region, dev_info. |
| 3530 | MDIO_AN_REG_8073_BAM, &val); | 3530 | port_hw_config[params->port].default_cfg)) & |
| 3531 | bnx2x_cl45_write(bp, phy, | 3531 | PORT_HW_CFG_ENABLE_BAM_ON_KR_ENABLED) { |
| 3532 | MDIO_AN_DEVAD, | ||
| 3533 | MDIO_AN_REG_8073_BAM, val | 1); | ||
| 3534 | 3532 | ||
| 3533 | bnx2x_cl45_read(bp, phy, | ||
| 3534 | MDIO_AN_DEVAD, | ||
| 3535 | MDIO_AN_REG_8073_BAM, &val); | ||
| 3536 | bnx2x_cl45_write(bp, phy, | ||
| 3537 | MDIO_AN_DEVAD, | ||
| 3538 | MDIO_AN_REG_8073_BAM, val | 1); | ||
| 3539 | DP(NETIF_MSG_LINK, "Enable CL37 BAM on KR\n"); | ||
| 3540 | } | ||
| 3535 | if (params->loopback_mode == LOOPBACK_EXT) { | 3541 | if (params->loopback_mode == LOOPBACK_EXT) { |
| 3536 | bnx2x_807x_force_10G(bp, phy); | 3542 | bnx2x_807x_force_10G(bp, phy); |
| 3537 | DP(NETIF_MSG_LINK, "Forced speed 10G on 807X\n"); | 3543 | DP(NETIF_MSG_LINK, "Forced speed 10G on 807X\n"); |
| @@ -5302,7 +5308,7 @@ static u8 bnx2x_848xx_cmn_config_init(struct bnx2x_phy *phy, | |||
| 5302 | { | 5308 | { |
| 5303 | struct bnx2x *bp = params->bp; | 5309 | struct bnx2x *bp = params->bp; |
| 5304 | u16 autoneg_val, an_1000_val, an_10_100_val; | 5310 | u16 autoneg_val, an_1000_val, an_10_100_val; |
| 5305 | bnx2x_wait_reset_complete(bp, phy); | 5311 | |
| 5306 | bnx2x_bits_en(bp, NIG_REG_LATCH_BC_0 + params->port*4, | 5312 | bnx2x_bits_en(bp, NIG_REG_LATCH_BC_0 + params->port*4, |
| 5307 | 1 << NIG_LATCH_BC_ENABLE_MI_INT); | 5313 | 1 << NIG_LATCH_BC_ENABLE_MI_INT); |
| 5308 | 5314 | ||
| @@ -5431,6 +5437,7 @@ static u8 bnx2x_8481_config_init(struct bnx2x_phy *phy, | |||
| 5431 | 5437 | ||
| 5432 | /* HW reset */ | 5438 | /* HW reset */ |
| 5433 | bnx2x_ext_phy_hw_reset(bp, params->port); | 5439 | bnx2x_ext_phy_hw_reset(bp, params->port); |
| 5440 | bnx2x_wait_reset_complete(bp, phy); | ||
| 5434 | 5441 | ||
| 5435 | bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15); | 5442 | bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15); |
| 5436 | return bnx2x_848xx_cmn_config_init(phy, params, vars); | 5443 | return bnx2x_848xx_cmn_config_init(phy, params, vars); |
| @@ -5441,7 +5448,7 @@ static u8 bnx2x_848x3_config_init(struct bnx2x_phy *phy, | |||
| 5441 | struct link_vars *vars) | 5448 | struct link_vars *vars) |
| 5442 | { | 5449 | { |
| 5443 | struct bnx2x *bp = params->bp; | 5450 | struct bnx2x *bp = params->bp; |
| 5444 | u8 port = params->port, initialize = 1; | 5451 | u8 port, initialize = 1; |
| 5445 | u16 val; | 5452 | u16 val; |
| 5446 | u16 temp; | 5453 | u16 temp; |
| 5447 | u32 actual_phy_selection; | 5454 | u32 actual_phy_selection; |
| @@ -5450,11 +5457,16 @@ static u8 bnx2x_848x3_config_init(struct bnx2x_phy *phy, | |||
| 5450 | /* This is just for MDIO_CTL_REG_84823_MEDIA register. */ | 5457 | /* This is just for MDIO_CTL_REG_84823_MEDIA register. */ |
| 5451 | 5458 | ||
| 5452 | msleep(1); | 5459 | msleep(1); |
| 5460 | if (CHIP_IS_E2(bp)) | ||
| 5461 | port = BP_PATH(bp); | ||
| 5462 | else | ||
| 5463 | port = params->port; | ||
| 5453 | bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3, | 5464 | bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3, |
| 5454 | MISC_REGISTERS_GPIO_OUTPUT_HIGH, | 5465 | MISC_REGISTERS_GPIO_OUTPUT_HIGH, |
| 5455 | port); | 5466 | port); |
| 5456 | msleep(200); /* 100 is not enough */ | 5467 | bnx2x_wait_reset_complete(bp, phy); |
| 5457 | 5468 | /* Wait for GPHY to come out of reset */ | |
| 5469 | msleep(50); | ||
| 5458 | /* BCM84823 requires that XGXS links up first @ 10G for normal | 5470 | /* BCM84823 requires that XGXS links up first @ 10G for normal |
| 5459 | behavior */ | 5471 | behavior */ |
| 5460 | temp = vars->line_speed; | 5472 | temp = vars->line_speed; |
| @@ -5625,7 +5637,11 @@ static void bnx2x_848x3_link_reset(struct bnx2x_phy *phy, | |||
| 5625 | struct link_params *params) | 5637 | struct link_params *params) |
| 5626 | { | 5638 | { |
| 5627 | struct bnx2x *bp = params->bp; | 5639 | struct bnx2x *bp = params->bp; |
| 5628 | u8 port = params->port; | 5640 | u8 port; |
| 5641 | if (CHIP_IS_E2(bp)) | ||
| 5642 | port = BP_PATH(bp); | ||
| 5643 | else | ||
| 5644 | port = params->port; | ||
| 5629 | bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3, | 5645 | bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3, |
| 5630 | MISC_REGISTERS_GPIO_OUTPUT_LOW, | 5646 | MISC_REGISTERS_GPIO_OUTPUT_LOW, |
| 5631 | port); | 5647 | port); |
| @@ -6928,7 +6944,7 @@ u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars, | |||
| 6928 | u8 reset_ext_phy) | 6944 | u8 reset_ext_phy) |
| 6929 | { | 6945 | { |
| 6930 | struct bnx2x *bp = params->bp; | 6946 | struct bnx2x *bp = params->bp; |
| 6931 | u8 phy_index, port = params->port; | 6947 | u8 phy_index, port = params->port, clear_latch_ind = 0; |
| 6932 | DP(NETIF_MSG_LINK, "Resetting the link of port %d\n", port); | 6948 | DP(NETIF_MSG_LINK, "Resetting the link of port %d\n", port); |
| 6933 | /* disable attentions */ | 6949 | /* disable attentions */ |
| 6934 | vars->link_status = 0; | 6950 | vars->link_status = 0; |
| @@ -6966,9 +6982,18 @@ u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars, | |||
| 6966 | params->phy[phy_index].link_reset( | 6982 | params->phy[phy_index].link_reset( |
| 6967 | ¶ms->phy[phy_index], | 6983 | ¶ms->phy[phy_index], |
| 6968 | params); | 6984 | params); |
| 6985 | if (params->phy[phy_index].flags & | ||
| 6986 | FLAGS_REARM_LATCH_SIGNAL) | ||
| 6987 | clear_latch_ind = 1; | ||
| 6969 | } | 6988 | } |
| 6970 | } | 6989 | } |
| 6971 | 6990 | ||
| 6991 | if (clear_latch_ind) { | ||
| 6992 | /* Clear latching indication */ | ||
| 6993 | bnx2x_rearm_latch_signal(bp, port, 0); | ||
| 6994 | bnx2x_bits_dis(bp, NIG_REG_LATCH_BC_0 + port*4, | ||
| 6995 | 1 << NIG_LATCH_BC_ENABLE_MI_INT); | ||
| 6996 | } | ||
| 6972 | if (params->phy[INT_PHY].link_reset) | 6997 | if (params->phy[INT_PHY].link_reset) |
| 6973 | params->phy[INT_PHY].link_reset( | 6998 | params->phy[INT_PHY].link_reset( |
| 6974 | ¶ms->phy[INT_PHY], params); | 6999 | ¶ms->phy[INT_PHY], params); |
| @@ -6999,6 +7024,7 @@ static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, | |||
| 6999 | s8 port; | 7024 | s8 port; |
| 7000 | s8 port_of_path = 0; | 7025 | s8 port_of_path = 0; |
| 7001 | 7026 | ||
| 7027 | bnx2x_ext_phy_hw_reset(bp, 0); | ||
| 7002 | /* PART1 - Reset both phys */ | 7028 | /* PART1 - Reset both phys */ |
| 7003 | for (port = PORT_MAX - 1; port >= PORT_0; port--) { | 7029 | for (port = PORT_MAX - 1; port >= PORT_0; port--) { |
| 7004 | u32 shmem_base, shmem2_base; | 7030 | u32 shmem_base, shmem2_base; |
| @@ -7021,7 +7047,8 @@ static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, | |||
| 7021 | return -EINVAL; | 7047 | return -EINVAL; |
| 7022 | } | 7048 | } |
| 7023 | /* disable attentions */ | 7049 | /* disable attentions */ |
| 7024 | bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4, | 7050 | bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + |
| 7051 | port_of_path*4, | ||
| 7025 | (NIG_MASK_XGXS0_LINK_STATUS | | 7052 | (NIG_MASK_XGXS0_LINK_STATUS | |
| 7026 | NIG_MASK_XGXS0_LINK10G | | 7053 | NIG_MASK_XGXS0_LINK10G | |
| 7027 | NIG_MASK_SERDES0_LINK_STATUS | | 7054 | NIG_MASK_SERDES0_LINK_STATUS | |
| @@ -7132,7 +7159,7 @@ static u8 bnx2x_8726_common_init_phy(struct bnx2x *bp, | |||
| 7132 | (1<<(MISC_REGISTERS_GPIO_3 + MISC_REGISTERS_GPIO_PORT_SHIFT))); | 7159 | (1<<(MISC_REGISTERS_GPIO_3 + MISC_REGISTERS_GPIO_PORT_SHIFT))); |
| 7133 | REG_WR(bp, MISC_REG_GPIO_EVENT_EN, val); | 7160 | REG_WR(bp, MISC_REG_GPIO_EVENT_EN, val); |
| 7134 | 7161 | ||
| 7135 | bnx2x_ext_phy_hw_reset(bp, 1); | 7162 | bnx2x_ext_phy_hw_reset(bp, 0); |
| 7136 | msleep(5); | 7163 | msleep(5); |
| 7137 | for (port = 0; port < PORT_MAX; port++) { | 7164 | for (port = 0; port < PORT_MAX; port++) { |
| 7138 | u32 shmem_base, shmem2_base; | 7165 | u32 shmem_base, shmem2_base; |
diff --git a/drivers/net/caif/caif_spi.c b/drivers/net/caif/caif_spi.c index 8427533fe313..8b4cea57a6c5 100644 --- a/drivers/net/caif/caif_spi.c +++ b/drivers/net/caif/caif_spi.c | |||
| @@ -33,6 +33,9 @@ MODULE_LICENSE("GPL"); | |||
| 33 | MODULE_AUTHOR("Daniel Martensson<daniel.martensson@stericsson.com>"); | 33 | MODULE_AUTHOR("Daniel Martensson<daniel.martensson@stericsson.com>"); |
| 34 | MODULE_DESCRIPTION("CAIF SPI driver"); | 34 | MODULE_DESCRIPTION("CAIF SPI driver"); |
| 35 | 35 | ||
| 36 | /* Returns the number of padding bytes for alignment. */ | ||
| 37 | #define PAD_POW2(x, pow) ((((x)&((pow)-1))==0) ? 0 : (((pow)-((x)&((pow)-1))))) | ||
| 38 | |||
| 36 | static int spi_loop; | 39 | static int spi_loop; |
| 37 | module_param(spi_loop, bool, S_IRUGO); | 40 | module_param(spi_loop, bool, S_IRUGO); |
| 38 | MODULE_PARM_DESC(spi_loop, "SPI running in loopback mode."); | 41 | MODULE_PARM_DESC(spi_loop, "SPI running in loopback mode."); |
| @@ -41,7 +44,10 @@ MODULE_PARM_DESC(spi_loop, "SPI running in loopback mode."); | |||
| 41 | module_param(spi_frm_align, int, S_IRUGO); | 44 | module_param(spi_frm_align, int, S_IRUGO); |
| 42 | MODULE_PARM_DESC(spi_frm_align, "SPI frame alignment."); | 45 | MODULE_PARM_DESC(spi_frm_align, "SPI frame alignment."); |
| 43 | 46 | ||
| 44 | /* SPI padding options. */ | 47 | /* |
| 48 | * SPI padding options. | ||
| 49 | * Warning: must be a base of 2 (& operation used) and can not be zero ! | ||
| 50 | */ | ||
| 45 | module_param(spi_up_head_align, int, S_IRUGO); | 51 | module_param(spi_up_head_align, int, S_IRUGO); |
| 46 | MODULE_PARM_DESC(spi_up_head_align, "SPI uplink head alignment."); | 52 | MODULE_PARM_DESC(spi_up_head_align, "SPI uplink head alignment."); |
| 47 | 53 | ||
| @@ -240,15 +246,13 @@ static ssize_t dbgfs_frame(struct file *file, char __user *user_buf, | |||
| 240 | static const struct file_operations dbgfs_state_fops = { | 246 | static const struct file_operations dbgfs_state_fops = { |
| 241 | .open = dbgfs_open, | 247 | .open = dbgfs_open, |
| 242 | .read = dbgfs_state, | 248 | .read = dbgfs_state, |
| 243 | .owner = THIS_MODULE, | 249 | .owner = THIS_MODULE |
| 244 | .llseek = default_llseek, | ||
| 245 | }; | 250 | }; |
| 246 | 251 | ||
| 247 | static const struct file_operations dbgfs_frame_fops = { | 252 | static const struct file_operations dbgfs_frame_fops = { |
| 248 | .open = dbgfs_open, | 253 | .open = dbgfs_open, |
| 249 | .read = dbgfs_frame, | 254 | .read = dbgfs_frame, |
| 250 | .owner = THIS_MODULE, | 255 | .owner = THIS_MODULE |
| 251 | .llseek = default_llseek, | ||
| 252 | }; | 256 | }; |
| 253 | 257 | ||
| 254 | static inline void dev_debugfs_add(struct cfspi *cfspi) | 258 | static inline void dev_debugfs_add(struct cfspi *cfspi) |
| @@ -337,6 +341,9 @@ int cfspi_xmitfrm(struct cfspi *cfspi, u8 *buf, size_t len) | |||
| 337 | u8 *dst = buf; | 341 | u8 *dst = buf; |
| 338 | caif_assert(buf); | 342 | caif_assert(buf); |
| 339 | 343 | ||
| 344 | if (cfspi->slave && !cfspi->slave_talked) | ||
| 345 | cfspi->slave_talked = true; | ||
| 346 | |||
| 340 | do { | 347 | do { |
| 341 | struct sk_buff *skb; | 348 | struct sk_buff *skb; |
| 342 | struct caif_payload_info *info; | 349 | struct caif_payload_info *info; |
| @@ -357,8 +364,8 @@ int cfspi_xmitfrm(struct cfspi *cfspi, u8 *buf, size_t len) | |||
| 357 | * Compute head offset i.e. number of bytes to add to | 364 | * Compute head offset i.e. number of bytes to add to |
| 358 | * get the start of the payload aligned. | 365 | * get the start of the payload aligned. |
| 359 | */ | 366 | */ |
| 360 | if (spi_up_head_align) { | 367 | if (spi_up_head_align > 1) { |
| 361 | spad = 1 + ((info->hdr_len + 1) & spi_up_head_align); | 368 | spad = 1 + PAD_POW2((info->hdr_len + 1), spi_up_head_align); |
| 362 | *dst = (u8)(spad - 1); | 369 | *dst = (u8)(spad - 1); |
| 363 | dst += spad; | 370 | dst += spad; |
| 364 | } | 371 | } |
| @@ -373,7 +380,7 @@ int cfspi_xmitfrm(struct cfspi *cfspi, u8 *buf, size_t len) | |||
| 373 | * Compute tail offset i.e. number of bytes to add to | 380 | * Compute tail offset i.e. number of bytes to add to |
| 374 | * get the complete CAIF frame aligned. | 381 | * get the complete CAIF frame aligned. |
| 375 | */ | 382 | */ |
| 376 | epad = (skb->len + spad) & spi_up_tail_align; | 383 | epad = PAD_POW2((skb->len + spad), spi_up_tail_align); |
| 377 | dst += epad; | 384 | dst += epad; |
| 378 | 385 | ||
| 379 | dev_kfree_skb(skb); | 386 | dev_kfree_skb(skb); |
| @@ -417,14 +424,14 @@ int cfspi_xmitlen(struct cfspi *cfspi) | |||
| 417 | * Compute head offset i.e. number of bytes to add to | 424 | * Compute head offset i.e. number of bytes to add to |
| 418 | * get the start of the payload aligned. | 425 | * get the start of the payload aligned. |
| 419 | */ | 426 | */ |
| 420 | if (spi_up_head_align) | 427 | if (spi_up_head_align > 1) |
| 421 | spad = 1 + ((info->hdr_len + 1) & spi_up_head_align); | 428 | spad = 1 + PAD_POW2((info->hdr_len + 1), spi_up_head_align); |
| 422 | 429 | ||
| 423 | /* | 430 | /* |
| 424 | * Compute tail offset i.e. number of bytes to add to | 431 | * Compute tail offset i.e. number of bytes to add to |
| 425 | * get the complete CAIF frame aligned. | 432 | * get the complete CAIF frame aligned. |
| 426 | */ | 433 | */ |
| 427 | epad = (skb->len + spad) & spi_up_tail_align; | 434 | epad = PAD_POW2((skb->len + spad), spi_up_tail_align); |
| 428 | 435 | ||
| 429 | if ((skb->len + spad + epad + frm_len) <= CAIF_MAX_SPI_FRAME) { | 436 | if ((skb->len + spad + epad + frm_len) <= CAIF_MAX_SPI_FRAME) { |
| 430 | skb_queue_tail(&cfspi->chead, skb); | 437 | skb_queue_tail(&cfspi->chead, skb); |
| @@ -433,6 +440,7 @@ int cfspi_xmitlen(struct cfspi *cfspi) | |||
| 433 | } else { | 440 | } else { |
| 434 | /* Put back packet. */ | 441 | /* Put back packet. */ |
| 435 | skb_queue_head(&cfspi->qhead, skb); | 442 | skb_queue_head(&cfspi->qhead, skb); |
| 443 | break; | ||
| 436 | } | 444 | } |
| 437 | } while (pkts <= CAIF_MAX_SPI_PKTS); | 445 | } while (pkts <= CAIF_MAX_SPI_PKTS); |
| 438 | 446 | ||
| @@ -453,6 +461,15 @@ static void cfspi_ss_cb(bool assert, struct cfspi_ifc *ifc) | |||
| 453 | { | 461 | { |
| 454 | struct cfspi *cfspi = (struct cfspi *)ifc->priv; | 462 | struct cfspi *cfspi = (struct cfspi *)ifc->priv; |
| 455 | 463 | ||
| 464 | /* | ||
| 465 | * The slave device is the master on the link. Interrupts before the | ||
| 466 | * slave has transmitted are considered spurious. | ||
| 467 | */ | ||
| 468 | if (cfspi->slave && !cfspi->slave_talked) { | ||
| 469 | printk(KERN_WARNING "CFSPI: Spurious SS interrupt.\n"); | ||
| 470 | return; | ||
| 471 | } | ||
| 472 | |||
| 456 | if (!in_interrupt()) | 473 | if (!in_interrupt()) |
| 457 | spin_lock(&cfspi->lock); | 474 | spin_lock(&cfspi->lock); |
| 458 | if (assert) { | 475 | if (assert) { |
| @@ -465,7 +482,8 @@ static void cfspi_ss_cb(bool assert, struct cfspi_ifc *ifc) | |||
| 465 | spin_unlock(&cfspi->lock); | 482 | spin_unlock(&cfspi->lock); |
| 466 | 483 | ||
| 467 | /* Wake up the xfer thread. */ | 484 | /* Wake up the xfer thread. */ |
| 468 | wake_up_interruptible(&cfspi->wait); | 485 | if (assert) |
| 486 | wake_up_interruptible(&cfspi->wait); | ||
| 469 | } | 487 | } |
| 470 | 488 | ||
| 471 | static void cfspi_xfer_done_cb(struct cfspi_ifc *ifc) | 489 | static void cfspi_xfer_done_cb(struct cfspi_ifc *ifc) |
| @@ -523,7 +541,7 @@ int cfspi_rxfrm(struct cfspi *cfspi, u8 *buf, size_t len) | |||
| 523 | * Compute head offset i.e. number of bytes added to | 541 | * Compute head offset i.e. number of bytes added to |
| 524 | * get the start of the payload aligned. | 542 | * get the start of the payload aligned. |
| 525 | */ | 543 | */ |
| 526 | if (spi_down_head_align) { | 544 | if (spi_down_head_align > 1) { |
| 527 | spad = 1 + *src; | 545 | spad = 1 + *src; |
| 528 | src += spad; | 546 | src += spad; |
| 529 | } | 547 | } |
| @@ -564,7 +582,7 @@ int cfspi_rxfrm(struct cfspi *cfspi, u8 *buf, size_t len) | |||
| 564 | * Compute tail offset i.e. number of bytes added to | 582 | * Compute tail offset i.e. number of bytes added to |
| 565 | * get the complete CAIF frame aligned. | 583 | * get the complete CAIF frame aligned. |
| 566 | */ | 584 | */ |
| 567 | epad = (pkt_len + spad) & spi_down_tail_align; | 585 | epad = PAD_POW2((pkt_len + spad), spi_down_tail_align); |
| 568 | src += epad; | 586 | src += epad; |
| 569 | } while ((src - buf) < len); | 587 | } while ((src - buf) < len); |
| 570 | 588 | ||
| @@ -625,11 +643,20 @@ int cfspi_spi_probe(struct platform_device *pdev) | |||
| 625 | cfspi->ndev = ndev; | 643 | cfspi->ndev = ndev; |
| 626 | cfspi->pdev = pdev; | 644 | cfspi->pdev = pdev; |
| 627 | 645 | ||
| 628 | /* Set flow info */ | 646 | /* Set flow info. */ |
| 629 | cfspi->flow_off_sent = 0; | 647 | cfspi->flow_off_sent = 0; |
| 630 | cfspi->qd_low_mark = LOW_WATER_MARK; | 648 | cfspi->qd_low_mark = LOW_WATER_MARK; |
| 631 | cfspi->qd_high_mark = HIGH_WATER_MARK; | 649 | cfspi->qd_high_mark = HIGH_WATER_MARK; |
| 632 | 650 | ||
| 651 | /* Set slave info. */ | ||
| 652 | if (!strncmp(cfspi_spi_driver.driver.name, "cfspi_sspi", 10)) { | ||
| 653 | cfspi->slave = true; | ||
| 654 | cfspi->slave_talked = false; | ||
| 655 | } else { | ||
| 656 | cfspi->slave = false; | ||
| 657 | cfspi->slave_talked = false; | ||
| 658 | } | ||
| 659 | |||
| 633 | /* Assign the SPI device. */ | 660 | /* Assign the SPI device. */ |
| 634 | cfspi->dev = dev; | 661 | cfspi->dev = dev; |
| 635 | /* Assign the device ifc to this SPI interface. */ | 662 | /* Assign the device ifc to this SPI interface. */ |
diff --git a/drivers/net/caif/caif_spi_slave.c b/drivers/net/caif/caif_spi_slave.c index 2111dbfea6fe..1b9943a4edab 100644 --- a/drivers/net/caif/caif_spi_slave.c +++ b/drivers/net/caif/caif_spi_slave.c | |||
| @@ -36,10 +36,15 @@ static inline int forward_to_spi_cmd(struct cfspi *cfspi) | |||
| 36 | #endif | 36 | #endif |
| 37 | 37 | ||
| 38 | int spi_frm_align = 2; | 38 | int spi_frm_align = 2; |
| 39 | int spi_up_head_align = 1; | 39 | |
| 40 | int spi_up_tail_align; | 40 | /* |
| 41 | int spi_down_head_align = 3; | 41 | * SPI padding options. |
| 42 | int spi_down_tail_align = 1; | 42 | * Warning: must be a base of 2 (& operation used) and can not be zero ! |
| 43 | */ | ||
| 44 | int spi_up_head_align = 1 << 1; | ||
| 45 | int spi_up_tail_align = 1 << 0; | ||
| 46 | int spi_down_head_align = 1 << 2; | ||
| 47 | int spi_down_tail_align = 1 << 1; | ||
| 43 | 48 | ||
| 44 | #ifdef CONFIG_DEBUG_FS | 49 | #ifdef CONFIG_DEBUG_FS |
| 45 | static inline void debugfs_store_prev(struct cfspi *cfspi) | 50 | static inline void debugfs_store_prev(struct cfspi *cfspi) |
diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c index 407d4e272075..046d846c652d 100644 --- a/drivers/net/cxgb3/cxgb3_main.c +++ b/drivers/net/cxgb3/cxgb3_main.c | |||
| @@ -3341,7 +3341,6 @@ static int __devinit init_one(struct pci_dev *pdev, | |||
| 3341 | adapter->name = adapter->port[i]->name; | 3341 | adapter->name = adapter->port[i]->name; |
| 3342 | 3342 | ||
| 3343 | __set_bit(i, &adapter->registered_device_map); | 3343 | __set_bit(i, &adapter->registered_device_map); |
| 3344 | netif_tx_stop_all_queues(adapter->port[i]); | ||
| 3345 | } | 3344 | } |
| 3346 | } | 3345 | } |
| 3347 | if (!adapter->registered_device_map) { | 3346 | if (!adapter->registered_device_map) { |
diff --git a/drivers/net/cxgb4/cxgb4_main.c b/drivers/net/cxgb4/cxgb4_main.c index f17703f410b3..f50bc98310f8 100644 --- a/drivers/net/cxgb4/cxgb4_main.c +++ b/drivers/net/cxgb4/cxgb4_main.c | |||
| @@ -3736,7 +3736,6 @@ static int __devinit init_one(struct pci_dev *pdev, | |||
| 3736 | 3736 | ||
| 3737 | __set_bit(i, &adapter->registered_device_map); | 3737 | __set_bit(i, &adapter->registered_device_map); |
| 3738 | adapter->chan_map[adap2pinfo(adapter, i)->tx_chan] = i; | 3738 | adapter->chan_map[adap2pinfo(adapter, i)->tx_chan] = i; |
| 3739 | netif_tx_stop_all_queues(adapter->port[i]); | ||
| 3740 | } | 3739 | } |
| 3741 | } | 3740 | } |
| 3742 | if (!adapter->registered_device_map) { | 3741 | if (!adapter->registered_device_map) { |
diff --git a/drivers/net/cxgb4vf/cxgb4vf_main.c b/drivers/net/cxgb4vf/cxgb4vf_main.c index 555ecc5a2e93..6de5e2e448a5 100644 --- a/drivers/net/cxgb4vf/cxgb4vf_main.c +++ b/drivers/net/cxgb4vf/cxgb4vf_main.c | |||
| @@ -2600,7 +2600,6 @@ static int __devinit cxgb4vf_pci_probe(struct pci_dev *pdev, | |||
| 2600 | pi->xact_addr_filt = -1; | 2600 | pi->xact_addr_filt = -1; |
| 2601 | pi->rx_offload = RX_CSO; | 2601 | pi->rx_offload = RX_CSO; |
| 2602 | netif_carrier_off(netdev); | 2602 | netif_carrier_off(netdev); |
| 2603 | netif_tx_stop_all_queues(netdev); | ||
| 2604 | netdev->irq = pdev->irq; | 2603 | netdev->irq = pdev->irq; |
| 2605 | 2604 | ||
| 2606 | netdev->features = (NETIF_F_SG | NETIF_F_TSO | NETIF_F_TSO6 | | 2605 | netdev->features = (NETIF_F_SG | NETIF_F_TSO | NETIF_F_TSO6 | |
diff --git a/drivers/net/ibm_newemac/core.c b/drivers/net/ibm_newemac/core.c index 385dc3204cb7..06bb9b799458 100644 --- a/drivers/net/ibm_newemac/core.c +++ b/drivers/net/ibm_newemac/core.c | |||
| @@ -2871,7 +2871,6 @@ static int __devinit emac_probe(struct platform_device *ofdev, | |||
| 2871 | SET_ETHTOOL_OPS(ndev, &emac_ethtool_ops); | 2871 | SET_ETHTOOL_OPS(ndev, &emac_ethtool_ops); |
| 2872 | 2872 | ||
| 2873 | netif_carrier_off(ndev); | 2873 | netif_carrier_off(ndev); |
| 2874 | netif_stop_queue(ndev); | ||
| 2875 | 2874 | ||
| 2876 | err = register_netdev(ndev); | 2875 | err = register_netdev(ndev); |
| 2877 | if (err) { | 2876 | if (err) { |
diff --git a/drivers/net/jme.c b/drivers/net/jme.c index d85edf3119c2..c57d9a43ceca 100644 --- a/drivers/net/jme.c +++ b/drivers/net/jme.c | |||
| @@ -2955,11 +2955,7 @@ jme_init_one(struct pci_dev *pdev, | |||
| 2955 | * Tell stack that we are not ready to work until open() | 2955 | * Tell stack that we are not ready to work until open() |
| 2956 | */ | 2956 | */ |
| 2957 | netif_carrier_off(netdev); | 2957 | netif_carrier_off(netdev); |
| 2958 | netif_stop_queue(netdev); | ||
| 2959 | 2958 | ||
| 2960 | /* | ||
| 2961 | * Register netdev | ||
| 2962 | */ | ||
| 2963 | rc = register_netdev(netdev); | 2959 | rc = register_netdev(netdev); |
| 2964 | if (rc) { | 2960 | if (rc) { |
| 2965 | pr_err("Cannot register net device\n"); | 2961 | pr_err("Cannot register net device\n"); |
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index a75ba9517404..e1d30d7f2071 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c | |||
| @@ -41,9 +41,6 @@ | |||
| 41 | MODULE_DESCRIPTION("QLogic/NetXen (1/10) GbE Converged Ethernet Driver"); | 41 | MODULE_DESCRIPTION("QLogic/NetXen (1/10) GbE Converged Ethernet Driver"); |
| 42 | MODULE_LICENSE("GPL"); | 42 | MODULE_LICENSE("GPL"); |
| 43 | MODULE_VERSION(NETXEN_NIC_LINUX_VERSIONID); | 43 | MODULE_VERSION(NETXEN_NIC_LINUX_VERSIONID); |
| 44 | MODULE_FIRMWARE(NX_P2_MN_ROMIMAGE_NAME); | ||
| 45 | MODULE_FIRMWARE(NX_P3_CT_ROMIMAGE_NAME); | ||
| 46 | MODULE_FIRMWARE(NX_P3_MN_ROMIMAGE_NAME); | ||
| 47 | MODULE_FIRMWARE(NX_UNIFIED_ROMIMAGE_NAME); | 44 | MODULE_FIRMWARE(NX_UNIFIED_ROMIMAGE_NAME); |
| 48 | 45 | ||
| 49 | char netxen_nic_driver_name[] = "netxen_nic"; | 46 | char netxen_nic_driver_name[] = "netxen_nic"; |
diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index 7a298cdf9ab3..a3dcd04be22f 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c | |||
| @@ -1450,7 +1450,6 @@ qlcnic_setup_netdev(struct qlcnic_adapter *adapter, | |||
| 1450 | netdev->irq = adapter->msix_entries[0].vector; | 1450 | netdev->irq = adapter->msix_entries[0].vector; |
| 1451 | 1451 | ||
| 1452 | netif_carrier_off(netdev); | 1452 | netif_carrier_off(netdev); |
| 1453 | netif_stop_queue(netdev); | ||
| 1454 | 1453 | ||
| 1455 | err = register_netdev(netdev); | 1454 | err = register_netdev(netdev); |
| 1456 | if (err) { | 1455 | if (err) { |
diff --git a/drivers/net/smsc911x.h b/drivers/net/smsc911x.h index 52f38e12a879..50f712e99e96 100644 --- a/drivers/net/smsc911x.h +++ b/drivers/net/smsc911x.h | |||
| @@ -22,7 +22,7 @@ | |||
| 22 | #define __SMSC911X_H__ | 22 | #define __SMSC911X_H__ |
| 23 | 23 | ||
| 24 | #define TX_FIFO_LOW_THRESHOLD ((u32)1600) | 24 | #define TX_FIFO_LOW_THRESHOLD ((u32)1600) |
| 25 | #define SMSC911X_EEPROM_SIZE ((u32)7) | 25 | #define SMSC911X_EEPROM_SIZE ((u32)128) |
| 26 | #define USE_DEBUG 0 | 26 | #define USE_DEBUG 0 |
| 27 | 27 | ||
| 28 | /* This is the maximum number of packets to be received every | 28 | /* This is the maximum number of packets to be received every |
diff --git a/drivers/net/tulip/de2104x.c b/drivers/net/tulip/de2104x.c index 28e1ffb13db9..c78a50586c1d 100644 --- a/drivers/net/tulip/de2104x.c +++ b/drivers/net/tulip/de2104x.c | |||
| @@ -2021,7 +2021,6 @@ static int __devinit de_init_one (struct pci_dev *pdev, | |||
| 2021 | de->media_timer.data = (unsigned long) de; | 2021 | de->media_timer.data = (unsigned long) de; |
| 2022 | 2022 | ||
| 2023 | netif_carrier_off(dev); | 2023 | netif_carrier_off(dev); |
| 2024 | netif_stop_queue(dev); | ||
| 2025 | 2024 | ||
| 2026 | /* wake up device, assign resources */ | 2025 | /* wake up device, assign resources */ |
| 2027 | rc = pci_enable_device(pdev); | 2026 | rc = pci_enable_device(pdev); |
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index ca7fc9df1ccf..c04d49e31f81 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c | |||
| @@ -45,6 +45,7 @@ | |||
| 45 | #include <linux/usb/usbnet.h> | 45 | #include <linux/usb/usbnet.h> |
| 46 | #include <linux/slab.h> | 46 | #include <linux/slab.h> |
| 47 | #include <linux/kernel.h> | 47 | #include <linux/kernel.h> |
| 48 | #include <linux/pm_runtime.h> | ||
| 48 | 49 | ||
| 49 | #define DRIVER_VERSION "22-Aug-2005" | 50 | #define DRIVER_VERSION "22-Aug-2005" |
| 50 | 51 | ||
| @@ -1273,6 +1274,16 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod) | |||
| 1273 | struct usb_device *xdev; | 1274 | struct usb_device *xdev; |
| 1274 | int status; | 1275 | int status; |
| 1275 | const char *name; | 1276 | const char *name; |
| 1277 | struct usb_driver *driver = to_usb_driver(udev->dev.driver); | ||
| 1278 | |||
| 1279 | /* usbnet already took usb runtime pm, so have to enable the feature | ||
| 1280 | * for usb interface, otherwise usb_autopm_get_interface may return | ||
| 1281 | * failure if USB_SUSPEND(RUNTIME_PM) is enabled. | ||
| 1282 | */ | ||
| 1283 | if (!driver->supports_autosuspend) { | ||
| 1284 | driver->supports_autosuspend = 1; | ||
| 1285 | pm_runtime_enable(&udev->dev); | ||
| 1286 | } | ||
| 1276 | 1287 | ||
| 1277 | name = udev->dev.driver->name; | 1288 | name = udev->dev.driver->name; |
| 1278 | info = (struct driver_info *) prod->driver_info; | 1289 | info = (struct driver_info *) prod->driver_info; |
diff --git a/drivers/usb/gadget/u_ether.c b/drivers/usb/gadget/u_ether.c index cb23355f52d3..fbe86ca95802 100644 --- a/drivers/usb/gadget/u_ether.c +++ b/drivers/usb/gadget/u_ether.c | |||
| @@ -811,7 +811,6 @@ int gether_setup(struct usb_gadget *g, u8 ethaddr[ETH_ALEN]) | |||
| 811 | INFO(dev, "MAC %pM\n", net->dev_addr); | 811 | INFO(dev, "MAC %pM\n", net->dev_addr); |
| 812 | INFO(dev, "HOST MAC %pM\n", dev->host_mac); | 812 | INFO(dev, "HOST MAC %pM\n", dev->host_mac); |
| 813 | 813 | ||
| 814 | netif_stop_queue(net); | ||
| 815 | the_dev = dev; | 814 | the_dev = dev; |
| 816 | } | 815 | } |
| 817 | 816 | ||
diff --git a/fs/cifs/TODO b/fs/cifs/TODO index 5aff46c61e52..355abcdcda98 100644 --- a/fs/cifs/TODO +++ b/fs/cifs/TODO | |||
| @@ -81,7 +81,7 @@ u) DOS attrs - returned as pseudo-xattr in Samba format (check VFAT and NTFS for | |||
| 81 | 81 | ||
| 82 | v) mount check for unmatched uids | 82 | v) mount check for unmatched uids |
| 83 | 83 | ||
| 84 | w) Add support for new vfs entry points for setlease and fallocate | 84 | w) Add support for new vfs entry point for fallocate |
| 85 | 85 | ||
| 86 | x) Fix Samba 3 server to handle Linux kernel aio so dbench with lots of | 86 | x) Fix Samba 3 server to handle Linux kernel aio so dbench with lots of |
| 87 | processes can proceed better in parallel (on the server) | 87 | processes can proceed better in parallel (on the server) |
diff --git a/fs/cifs/cifs_fs_sb.h b/fs/cifs/cifs_fs_sb.h index 525ba59a4105..e9a393c9c2ca 100644 --- a/fs/cifs/cifs_fs_sb.h +++ b/fs/cifs/cifs_fs_sb.h | |||
| @@ -15,7 +15,7 @@ | |||
| 15 | * the GNU Lesser General Public License for more details. | 15 | * the GNU Lesser General Public License for more details. |
| 16 | * | 16 | * |
| 17 | */ | 17 | */ |
| 18 | #include <linux/radix-tree.h> | 18 | #include <linux/rbtree.h> |
| 19 | 19 | ||
| 20 | #ifndef _CIFS_FS_SB_H | 20 | #ifndef _CIFS_FS_SB_H |
| 21 | #define _CIFS_FS_SB_H | 21 | #define _CIFS_FS_SB_H |
| @@ -42,9 +42,9 @@ | |||
| 42 | #define CIFS_MOUNT_MULTIUSER 0x20000 /* multiuser mount */ | 42 | #define CIFS_MOUNT_MULTIUSER 0x20000 /* multiuser mount */ |
| 43 | 43 | ||
| 44 | struct cifs_sb_info { | 44 | struct cifs_sb_info { |
| 45 | struct radix_tree_root tlink_tree; | 45 | struct rb_root tlink_tree; |
| 46 | #define CIFS_TLINK_MASTER_TAG 0 /* is "master" (mount) tcon */ | ||
| 47 | spinlock_t tlink_tree_lock; | 46 | spinlock_t tlink_tree_lock; |
| 47 | struct tcon_link *master_tlink; | ||
| 48 | struct nls_table *local_nls; | 48 | struct nls_table *local_nls; |
| 49 | unsigned int rsize; | 49 | unsigned int rsize; |
| 50 | unsigned int wsize; | 50 | unsigned int wsize; |
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 75c4eaa79588..9c3789762ab7 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c | |||
| @@ -116,7 +116,7 @@ cifs_read_super(struct super_block *sb, void *data, | |||
| 116 | return -ENOMEM; | 116 | return -ENOMEM; |
| 117 | 117 | ||
| 118 | spin_lock_init(&cifs_sb->tlink_tree_lock); | 118 | spin_lock_init(&cifs_sb->tlink_tree_lock); |
| 119 | INIT_RADIX_TREE(&cifs_sb->tlink_tree, GFP_KERNEL); | 119 | cifs_sb->tlink_tree = RB_ROOT; |
| 120 | 120 | ||
| 121 | rc = bdi_setup_and_register(&cifs_sb->bdi, "cifs", BDI_CAP_MAP_COPY); | 121 | rc = bdi_setup_and_register(&cifs_sb->bdi, "cifs", BDI_CAP_MAP_COPY); |
| 122 | if (rc) { | 122 | if (rc) { |
| @@ -321,8 +321,7 @@ cifs_alloc_inode(struct super_block *sb) | |||
| 321 | /* Until the file is open and we have gotten oplock | 321 | /* Until the file is open and we have gotten oplock |
| 322 | info back from the server, can not assume caching of | 322 | info back from the server, can not assume caching of |
| 323 | file data or metadata */ | 323 | file data or metadata */ |
| 324 | cifs_inode->clientCanCacheRead = false; | 324 | cifs_set_oplock_level(cifs_inode, 0); |
| 325 | cifs_inode->clientCanCacheAll = false; | ||
| 326 | cifs_inode->delete_pending = false; | 325 | cifs_inode->delete_pending = false; |
| 327 | cifs_inode->invalid_mapping = false; | 326 | cifs_inode->invalid_mapping = false; |
| 328 | cifs_inode->vfs_inode.i_blkbits = 14; /* 2**14 = CIFS_MAX_MSGSIZE */ | 327 | cifs_inode->vfs_inode.i_blkbits = 14; /* 2**14 = CIFS_MAX_MSGSIZE */ |
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index f259e4d7612d..b577bf0a1bb3 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h | |||
| @@ -336,7 +336,8 @@ struct cifsTconInfo { | |||
| 336 | * "get" on the container. | 336 | * "get" on the container. |
| 337 | */ | 337 | */ |
| 338 | struct tcon_link { | 338 | struct tcon_link { |
| 339 | unsigned long tl_index; | 339 | struct rb_node tl_rbnode; |
| 340 | uid_t tl_uid; | ||
| 340 | unsigned long tl_flags; | 341 | unsigned long tl_flags; |
| 341 | #define TCON_LINK_MASTER 0 | 342 | #define TCON_LINK_MASTER 0 |
| 342 | #define TCON_LINK_PENDING 1 | 343 | #define TCON_LINK_PENDING 1 |
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index edb6d90efdf2..7ed69b6b5fe6 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h | |||
| @@ -104,6 +104,7 @@ extern struct timespec cifs_NTtimeToUnix(__le64 utc_nanoseconds_since_1601); | |||
| 104 | extern u64 cifs_UnixTimeToNT(struct timespec); | 104 | extern u64 cifs_UnixTimeToNT(struct timespec); |
| 105 | extern struct timespec cnvrtDosUnixTm(__le16 le_date, __le16 le_time, | 105 | extern struct timespec cnvrtDosUnixTm(__le16 le_date, __le16 le_time, |
| 106 | int offset); | 106 | int offset); |
| 107 | extern void cifs_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock); | ||
| 107 | 108 | ||
| 108 | extern struct cifsFileInfo *cifs_new_fileinfo(__u16 fileHandle, | 109 | extern struct cifsFileInfo *cifs_new_fileinfo(__u16 fileHandle, |
| 109 | struct file *file, struct tcon_link *tlink, | 110 | struct file *file, struct tcon_link *tlink, |
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 9eb327defa1d..251a17c03545 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c | |||
| @@ -116,6 +116,7 @@ struct smb_vol { | |||
| 116 | 116 | ||
| 117 | static int ipv4_connect(struct TCP_Server_Info *server); | 117 | static int ipv4_connect(struct TCP_Server_Info *server); |
| 118 | static int ipv6_connect(struct TCP_Server_Info *server); | 118 | static int ipv6_connect(struct TCP_Server_Info *server); |
| 119 | static void tlink_rb_insert(struct rb_root *root, struct tcon_link *new_tlink); | ||
| 119 | static void cifs_prune_tlinks(struct work_struct *work); | 120 | static void cifs_prune_tlinks(struct work_struct *work); |
| 120 | 121 | ||
| 121 | /* | 122 | /* |
| @@ -2900,24 +2901,16 @@ remote_path_check: | |||
| 2900 | goto mount_fail_check; | 2901 | goto mount_fail_check; |
| 2901 | } | 2902 | } |
| 2902 | 2903 | ||
| 2903 | tlink->tl_index = pSesInfo->linux_uid; | 2904 | tlink->tl_uid = pSesInfo->linux_uid; |
| 2904 | tlink->tl_tcon = tcon; | 2905 | tlink->tl_tcon = tcon; |
| 2905 | tlink->tl_time = jiffies; | 2906 | tlink->tl_time = jiffies; |
| 2906 | set_bit(TCON_LINK_MASTER, &tlink->tl_flags); | 2907 | set_bit(TCON_LINK_MASTER, &tlink->tl_flags); |
| 2907 | set_bit(TCON_LINK_IN_TREE, &tlink->tl_flags); | 2908 | set_bit(TCON_LINK_IN_TREE, &tlink->tl_flags); |
| 2908 | 2909 | ||
| 2909 | rc = radix_tree_preload(GFP_KERNEL); | 2910 | cifs_sb->master_tlink = tlink; |
| 2910 | if (rc == -ENOMEM) { | ||
| 2911 | kfree(tlink); | ||
| 2912 | goto mount_fail_check; | ||
| 2913 | } | ||
| 2914 | |||
| 2915 | spin_lock(&cifs_sb->tlink_tree_lock); | 2911 | spin_lock(&cifs_sb->tlink_tree_lock); |
| 2916 | radix_tree_insert(&cifs_sb->tlink_tree, pSesInfo->linux_uid, tlink); | 2912 | tlink_rb_insert(&cifs_sb->tlink_tree, tlink); |
| 2917 | radix_tree_tag_set(&cifs_sb->tlink_tree, pSesInfo->linux_uid, | ||
| 2918 | CIFS_TLINK_MASTER_TAG); | ||
| 2919 | spin_unlock(&cifs_sb->tlink_tree_lock); | 2913 | spin_unlock(&cifs_sb->tlink_tree_lock); |
| 2920 | radix_tree_preload_end(); | ||
| 2921 | 2914 | ||
| 2922 | queue_delayed_work(system_nrt_wq, &cifs_sb->prune_tlinks, | 2915 | queue_delayed_work(system_nrt_wq, &cifs_sb->prune_tlinks, |
| 2923 | TLINK_IDLE_EXPIRE); | 2916 | TLINK_IDLE_EXPIRE); |
| @@ -3107,32 +3100,25 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses, | |||
| 3107 | int | 3100 | int |
| 3108 | cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb) | 3101 | cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb) |
| 3109 | { | 3102 | { |
| 3110 | int i, ret; | 3103 | struct rb_root *root = &cifs_sb->tlink_tree; |
| 3104 | struct rb_node *node; | ||
| 3105 | struct tcon_link *tlink; | ||
| 3111 | char *tmp; | 3106 | char *tmp; |
| 3112 | struct tcon_link *tlink[8]; | ||
| 3113 | unsigned long index = 0; | ||
| 3114 | 3107 | ||
| 3115 | cancel_delayed_work_sync(&cifs_sb->prune_tlinks); | 3108 | cancel_delayed_work_sync(&cifs_sb->prune_tlinks); |
| 3116 | 3109 | ||
| 3117 | do { | 3110 | spin_lock(&cifs_sb->tlink_tree_lock); |
| 3118 | spin_lock(&cifs_sb->tlink_tree_lock); | 3111 | while ((node = rb_first(root))) { |
| 3119 | ret = radix_tree_gang_lookup(&cifs_sb->tlink_tree, | 3112 | tlink = rb_entry(node, struct tcon_link, tl_rbnode); |
| 3120 | (void **)tlink, index, | 3113 | cifs_get_tlink(tlink); |
| 3121 | ARRAY_SIZE(tlink)); | 3114 | clear_bit(TCON_LINK_IN_TREE, &tlink->tl_flags); |
| 3122 | /* increment index for next pass */ | 3115 | rb_erase(node, root); |
| 3123 | if (ret > 0) | ||
| 3124 | index = tlink[ret - 1]->tl_index + 1; | ||
| 3125 | for (i = 0; i < ret; i++) { | ||
| 3126 | cifs_get_tlink(tlink[i]); | ||
| 3127 | clear_bit(TCON_LINK_IN_TREE, &tlink[i]->tl_flags); | ||
| 3128 | radix_tree_delete(&cifs_sb->tlink_tree, | ||
| 3129 | tlink[i]->tl_index); | ||
| 3130 | } | ||
| 3131 | spin_unlock(&cifs_sb->tlink_tree_lock); | ||
| 3132 | 3116 | ||
| 3133 | for (i = 0; i < ret; i++) | 3117 | spin_unlock(&cifs_sb->tlink_tree_lock); |
| 3134 | cifs_put_tlink(tlink[i]); | 3118 | cifs_put_tlink(tlink); |
| 3135 | } while (ret != 0); | 3119 | spin_lock(&cifs_sb->tlink_tree_lock); |
| 3120 | } | ||
| 3121 | spin_unlock(&cifs_sb->tlink_tree_lock); | ||
| 3136 | 3122 | ||
| 3137 | tmp = cifs_sb->prepath; | 3123 | tmp = cifs_sb->prepath; |
| 3138 | cifs_sb->prepathlen = 0; | 3124 | cifs_sb->prepathlen = 0; |
| @@ -3271,22 +3257,10 @@ out: | |||
| 3271 | return tcon; | 3257 | return tcon; |
| 3272 | } | 3258 | } |
| 3273 | 3259 | ||
| 3274 | static struct tcon_link * | 3260 | static inline struct tcon_link * |
| 3275 | cifs_sb_master_tlink(struct cifs_sb_info *cifs_sb) | 3261 | cifs_sb_master_tlink(struct cifs_sb_info *cifs_sb) |
| 3276 | { | 3262 | { |
| 3277 | struct tcon_link *tlink; | 3263 | return cifs_sb->master_tlink; |
| 3278 | unsigned int ret; | ||
| 3279 | |||
| 3280 | spin_lock(&cifs_sb->tlink_tree_lock); | ||
| 3281 | ret = radix_tree_gang_lookup_tag(&cifs_sb->tlink_tree, (void **)&tlink, | ||
| 3282 | 0, 1, CIFS_TLINK_MASTER_TAG); | ||
| 3283 | spin_unlock(&cifs_sb->tlink_tree_lock); | ||
| 3284 | |||
| 3285 | /* the master tcon should always be present */ | ||
| 3286 | if (ret == 0) | ||
| 3287 | BUG(); | ||
| 3288 | |||
| 3289 | return tlink; | ||
| 3290 | } | 3264 | } |
| 3291 | 3265 | ||
| 3292 | struct cifsTconInfo * | 3266 | struct cifsTconInfo * |
| @@ -3302,6 +3276,47 @@ cifs_sb_tcon_pending_wait(void *unused) | |||
| 3302 | return signal_pending(current) ? -ERESTARTSYS : 0; | 3276 | return signal_pending(current) ? -ERESTARTSYS : 0; |
| 3303 | } | 3277 | } |
| 3304 | 3278 | ||
| 3279 | /* find and return a tlink with given uid */ | ||
| 3280 | static struct tcon_link * | ||
| 3281 | tlink_rb_search(struct rb_root *root, uid_t uid) | ||
| 3282 | { | ||
| 3283 | struct rb_node *node = root->rb_node; | ||
| 3284 | struct tcon_link *tlink; | ||
| 3285 | |||
| 3286 | while (node) { | ||
| 3287 | tlink = rb_entry(node, struct tcon_link, tl_rbnode); | ||
| 3288 | |||
| 3289 | if (tlink->tl_uid > uid) | ||
| 3290 | node = node->rb_left; | ||
| 3291 | else if (tlink->tl_uid < uid) | ||
| 3292 | node = node->rb_right; | ||
| 3293 | else | ||
| 3294 | return tlink; | ||
| 3295 | } | ||
| 3296 | return NULL; | ||
| 3297 | } | ||
| 3298 | |||
| 3299 | /* insert a tcon_link into the tree */ | ||
| 3300 | static void | ||
| 3301 | tlink_rb_insert(struct rb_root *root, struct tcon_link *new_tlink) | ||
| 3302 | { | ||
| 3303 | struct rb_node **new = &(root->rb_node), *parent = NULL; | ||
| 3304 | struct tcon_link *tlink; | ||
| 3305 | |||
| 3306 | while (*new) { | ||
| 3307 | tlink = rb_entry(*new, struct tcon_link, tl_rbnode); | ||
| 3308 | parent = *new; | ||
| 3309 | |||
| 3310 | if (tlink->tl_uid > new_tlink->tl_uid) | ||
| 3311 | new = &((*new)->rb_left); | ||
| 3312 | else | ||
| 3313 | new = &((*new)->rb_right); | ||
| 3314 | } | ||
| 3315 | |||
| 3316 | rb_link_node(&new_tlink->tl_rbnode, parent, new); | ||
| 3317 | rb_insert_color(&new_tlink->tl_rbnode, root); | ||
| 3318 | } | ||
| 3319 | |||
| 3305 | /* | 3320 | /* |
| 3306 | * Find or construct an appropriate tcon given a cifs_sb and the fsuid of the | 3321 | * Find or construct an appropriate tcon given a cifs_sb and the fsuid of the |
| 3307 | * current task. | 3322 | * current task. |
| @@ -3309,7 +3324,7 @@ cifs_sb_tcon_pending_wait(void *unused) | |||
| 3309 | * If the superblock doesn't refer to a multiuser mount, then just return | 3324 | * If the superblock doesn't refer to a multiuser mount, then just return |
| 3310 | * the master tcon for the mount. | 3325 | * the master tcon for the mount. |
| 3311 | * | 3326 | * |
| 3312 | * First, search the radix tree for an existing tcon for this fsuid. If one | 3327 | * First, search the rbtree for an existing tcon for this fsuid. If one |
| 3313 | * exists, then check to see if it's pending construction. If it is then wait | 3328 | * exists, then check to see if it's pending construction. If it is then wait |
| 3314 | * for construction to complete. Once it's no longer pending, check to see if | 3329 | * for construction to complete. Once it's no longer pending, check to see if |
| 3315 | * it failed and either return an error or retry construction, depending on | 3330 | * it failed and either return an error or retry construction, depending on |
| @@ -3322,14 +3337,14 @@ struct tcon_link * | |||
| 3322 | cifs_sb_tlink(struct cifs_sb_info *cifs_sb) | 3337 | cifs_sb_tlink(struct cifs_sb_info *cifs_sb) |
| 3323 | { | 3338 | { |
| 3324 | int ret; | 3339 | int ret; |
| 3325 | unsigned long fsuid = (unsigned long) current_fsuid(); | 3340 | uid_t fsuid = current_fsuid(); |
| 3326 | struct tcon_link *tlink, *newtlink; | 3341 | struct tcon_link *tlink, *newtlink; |
| 3327 | 3342 | ||
| 3328 | if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER)) | 3343 | if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER)) |
| 3329 | return cifs_get_tlink(cifs_sb_master_tlink(cifs_sb)); | 3344 | return cifs_get_tlink(cifs_sb_master_tlink(cifs_sb)); |
| 3330 | 3345 | ||
| 3331 | spin_lock(&cifs_sb->tlink_tree_lock); | 3346 | spin_lock(&cifs_sb->tlink_tree_lock); |
| 3332 | tlink = radix_tree_lookup(&cifs_sb->tlink_tree, fsuid); | 3347 | tlink = tlink_rb_search(&cifs_sb->tlink_tree, fsuid); |
| 3333 | if (tlink) | 3348 | if (tlink) |
| 3334 | cifs_get_tlink(tlink); | 3349 | cifs_get_tlink(tlink); |
| 3335 | spin_unlock(&cifs_sb->tlink_tree_lock); | 3350 | spin_unlock(&cifs_sb->tlink_tree_lock); |
| @@ -3338,36 +3353,24 @@ cifs_sb_tlink(struct cifs_sb_info *cifs_sb) | |||
| 3338 | newtlink = kzalloc(sizeof(*tlink), GFP_KERNEL); | 3353 | newtlink = kzalloc(sizeof(*tlink), GFP_KERNEL); |
| 3339 | if (newtlink == NULL) | 3354 | if (newtlink == NULL) |
| 3340 | return ERR_PTR(-ENOMEM); | 3355 | return ERR_PTR(-ENOMEM); |
| 3341 | newtlink->tl_index = fsuid; | 3356 | newtlink->tl_uid = fsuid; |
| 3342 | newtlink->tl_tcon = ERR_PTR(-EACCES); | 3357 | newtlink->tl_tcon = ERR_PTR(-EACCES); |
| 3343 | set_bit(TCON_LINK_PENDING, &newtlink->tl_flags); | 3358 | set_bit(TCON_LINK_PENDING, &newtlink->tl_flags); |
| 3344 | set_bit(TCON_LINK_IN_TREE, &newtlink->tl_flags); | 3359 | set_bit(TCON_LINK_IN_TREE, &newtlink->tl_flags); |
| 3345 | cifs_get_tlink(newtlink); | 3360 | cifs_get_tlink(newtlink); |
| 3346 | 3361 | ||
| 3347 | ret = radix_tree_preload(GFP_KERNEL); | ||
| 3348 | if (ret != 0) { | ||
| 3349 | kfree(newtlink); | ||
| 3350 | return ERR_PTR(ret); | ||
| 3351 | } | ||
| 3352 | |||
| 3353 | spin_lock(&cifs_sb->tlink_tree_lock); | 3362 | spin_lock(&cifs_sb->tlink_tree_lock); |
| 3354 | /* was one inserted after previous search? */ | 3363 | /* was one inserted after previous search? */ |
| 3355 | tlink = radix_tree_lookup(&cifs_sb->tlink_tree, fsuid); | 3364 | tlink = tlink_rb_search(&cifs_sb->tlink_tree, fsuid); |
| 3356 | if (tlink) { | 3365 | if (tlink) { |
| 3357 | cifs_get_tlink(tlink); | 3366 | cifs_get_tlink(tlink); |
| 3358 | spin_unlock(&cifs_sb->tlink_tree_lock); | 3367 | spin_unlock(&cifs_sb->tlink_tree_lock); |
| 3359 | radix_tree_preload_end(); | ||
| 3360 | kfree(newtlink); | 3368 | kfree(newtlink); |
| 3361 | goto wait_for_construction; | 3369 | goto wait_for_construction; |
| 3362 | } | 3370 | } |
| 3363 | ret = radix_tree_insert(&cifs_sb->tlink_tree, fsuid, newtlink); | ||
| 3364 | spin_unlock(&cifs_sb->tlink_tree_lock); | ||
| 3365 | radix_tree_preload_end(); | ||
| 3366 | if (ret) { | ||
| 3367 | kfree(newtlink); | ||
| 3368 | return ERR_PTR(ret); | ||
| 3369 | } | ||
| 3370 | tlink = newtlink; | 3371 | tlink = newtlink; |
| 3372 | tlink_rb_insert(&cifs_sb->tlink_tree, tlink); | ||
| 3373 | spin_unlock(&cifs_sb->tlink_tree_lock); | ||
| 3371 | } else { | 3374 | } else { |
| 3372 | wait_for_construction: | 3375 | wait_for_construction: |
| 3373 | ret = wait_on_bit(&tlink->tl_flags, TCON_LINK_PENDING, | 3376 | ret = wait_on_bit(&tlink->tl_flags, TCON_LINK_PENDING, |
| @@ -3413,39 +3416,39 @@ cifs_prune_tlinks(struct work_struct *work) | |||
| 3413 | { | 3416 | { |
| 3414 | struct cifs_sb_info *cifs_sb = container_of(work, struct cifs_sb_info, | 3417 | struct cifs_sb_info *cifs_sb = container_of(work, struct cifs_sb_info, |
| 3415 | prune_tlinks.work); | 3418 | prune_tlinks.work); |
| 3416 | struct tcon_link *tlink[8]; | 3419 | struct rb_root *root = &cifs_sb->tlink_tree; |
| 3417 | unsigned long now = jiffies; | 3420 | struct rb_node *node = rb_first(root); |
| 3418 | unsigned long index = 0; | 3421 | struct rb_node *tmp; |
| 3419 | int i, ret; | 3422 | struct tcon_link *tlink; |
| 3420 | 3423 | ||
| 3421 | do { | 3424 | /* |
| 3422 | spin_lock(&cifs_sb->tlink_tree_lock); | 3425 | * Because we drop the spinlock in the loop in order to put the tlink |
| 3423 | ret = radix_tree_gang_lookup(&cifs_sb->tlink_tree, | 3426 | * it's not guarded against removal of links from the tree. The only |
| 3424 | (void **)tlink, index, | 3427 | * places that remove entries from the tree are this function and |
| 3425 | ARRAY_SIZE(tlink)); | 3428 | * umounts. Because this function is non-reentrant and is canceled |
| 3426 | /* increment index for next pass */ | 3429 | * before umount can proceed, this is safe. |
| 3427 | if (ret > 0) | 3430 | */ |
| 3428 | index = tlink[ret - 1]->tl_index + 1; | 3431 | spin_lock(&cifs_sb->tlink_tree_lock); |
| 3429 | for (i = 0; i < ret; i++) { | 3432 | node = rb_first(root); |
| 3430 | if (test_bit(TCON_LINK_MASTER, &tlink[i]->tl_flags) || | 3433 | while (node != NULL) { |
| 3431 | atomic_read(&tlink[i]->tl_count) != 0 || | 3434 | tmp = node; |
| 3432 | time_after(tlink[i]->tl_time + TLINK_IDLE_EXPIRE, | 3435 | node = rb_next(tmp); |
| 3433 | now)) { | 3436 | tlink = rb_entry(tmp, struct tcon_link, tl_rbnode); |
| 3434 | tlink[i] = NULL; | 3437 | |
| 3435 | continue; | 3438 | if (test_bit(TCON_LINK_MASTER, &tlink->tl_flags) || |
| 3436 | } | 3439 | atomic_read(&tlink->tl_count) != 0 || |
| 3437 | cifs_get_tlink(tlink[i]); | 3440 | time_after(tlink->tl_time + TLINK_IDLE_EXPIRE, jiffies)) |
| 3438 | clear_bit(TCON_LINK_IN_TREE, &tlink[i]->tl_flags); | 3441 | continue; |
| 3439 | radix_tree_delete(&cifs_sb->tlink_tree, | ||
| 3440 | tlink[i]->tl_index); | ||
| 3441 | } | ||
| 3442 | spin_unlock(&cifs_sb->tlink_tree_lock); | ||
| 3443 | 3442 | ||
| 3444 | for (i = 0; i < ret; i++) { | 3443 | cifs_get_tlink(tlink); |
| 3445 | if (tlink[i] != NULL) | 3444 | clear_bit(TCON_LINK_IN_TREE, &tlink->tl_flags); |
| 3446 | cifs_put_tlink(tlink[i]); | 3445 | rb_erase(tmp, root); |
| 3447 | } | 3446 | |
| 3448 | } while (ret != 0); | 3447 | spin_unlock(&cifs_sb->tlink_tree_lock); |
| 3448 | cifs_put_tlink(tlink); | ||
| 3449 | spin_lock(&cifs_sb->tlink_tree_lock); | ||
| 3450 | } | ||
| 3451 | spin_unlock(&cifs_sb->tlink_tree_lock); | ||
| 3449 | 3452 | ||
| 3450 | queue_delayed_work(system_nrt_wq, &cifs_sb->prune_tlinks, | 3453 | queue_delayed_work(system_nrt_wq, &cifs_sb->prune_tlinks, |
| 3451 | TLINK_IDLE_EXPIRE); | 3454 | TLINK_IDLE_EXPIRE); |
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index ae82159cf7fa..06c3e83fa387 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
| @@ -146,12 +146,7 @@ client_can_cache: | |||
| 146 | rc = cifs_get_inode_info(&inode, full_path, buf, inode->i_sb, | 146 | rc = cifs_get_inode_info(&inode, full_path, buf, inode->i_sb, |
| 147 | xid, NULL); | 147 | xid, NULL); |
| 148 | 148 | ||
| 149 | if ((oplock & 0xF) == OPLOCK_EXCLUSIVE) { | 149 | cifs_set_oplock_level(pCifsInode, oplock); |
| 150 | pCifsInode->clientCanCacheAll = true; | ||
| 151 | pCifsInode->clientCanCacheRead = true; | ||
| 152 | cFYI(1, "Exclusive Oplock granted on inode %p", inode); | ||
| 153 | } else if ((oplock & 0xF) == OPLOCK_READ) | ||
| 154 | pCifsInode->clientCanCacheRead = true; | ||
| 155 | 150 | ||
| 156 | return rc; | 151 | return rc; |
| 157 | } | 152 | } |
| @@ -253,12 +248,7 @@ cifs_new_fileinfo(__u16 fileHandle, struct file *file, | |||
| 253 | list_add_tail(&pCifsFile->flist, &pCifsInode->openFileList); | 248 | list_add_tail(&pCifsFile->flist, &pCifsInode->openFileList); |
| 254 | spin_unlock(&cifs_file_list_lock); | 249 | spin_unlock(&cifs_file_list_lock); |
| 255 | 250 | ||
| 256 | if ((oplock & 0xF) == OPLOCK_EXCLUSIVE) { | 251 | cifs_set_oplock_level(pCifsInode, oplock); |
| 257 | pCifsInode->clientCanCacheAll = true; | ||
| 258 | pCifsInode->clientCanCacheRead = true; | ||
| 259 | cFYI(1, "Exclusive Oplock inode %p", inode); | ||
| 260 | } else if ((oplock & 0xF) == OPLOCK_READ) | ||
| 261 | pCifsInode->clientCanCacheRead = true; | ||
| 262 | 252 | ||
| 263 | file->private_data = pCifsFile; | 253 | file->private_data = pCifsFile; |
| 264 | return pCifsFile; | 254 | return pCifsFile; |
| @@ -271,8 +261,9 @@ cifs_new_fileinfo(__u16 fileHandle, struct file *file, | |||
| 271 | */ | 261 | */ |
| 272 | void cifsFileInfo_put(struct cifsFileInfo *cifs_file) | 262 | void cifsFileInfo_put(struct cifsFileInfo *cifs_file) |
| 273 | { | 263 | { |
| 264 | struct inode *inode = cifs_file->dentry->d_inode; | ||
| 274 | struct cifsTconInfo *tcon = tlink_tcon(cifs_file->tlink); | 265 | struct cifsTconInfo *tcon = tlink_tcon(cifs_file->tlink); |
| 275 | struct cifsInodeInfo *cifsi = CIFS_I(cifs_file->dentry->d_inode); | 266 | struct cifsInodeInfo *cifsi = CIFS_I(inode); |
| 276 | struct cifsLockInfo *li, *tmp; | 267 | struct cifsLockInfo *li, *tmp; |
| 277 | 268 | ||
| 278 | spin_lock(&cifs_file_list_lock); | 269 | spin_lock(&cifs_file_list_lock); |
| @@ -288,8 +279,7 @@ void cifsFileInfo_put(struct cifsFileInfo *cifs_file) | |||
| 288 | if (list_empty(&cifsi->openFileList)) { | 279 | if (list_empty(&cifsi->openFileList)) { |
| 289 | cFYI(1, "closing last open instance for inode %p", | 280 | cFYI(1, "closing last open instance for inode %p", |
| 290 | cifs_file->dentry->d_inode); | 281 | cifs_file->dentry->d_inode); |
| 291 | cifsi->clientCanCacheRead = false; | 282 | cifs_set_oplock_level(cifsi, 0); |
| 292 | cifsi->clientCanCacheAll = false; | ||
| 293 | } | 283 | } |
| 294 | spin_unlock(&cifs_file_list_lock); | 284 | spin_unlock(&cifs_file_list_lock); |
| 295 | 285 | ||
| @@ -607,8 +597,6 @@ reopen_success: | |||
| 607 | rc = filemap_write_and_wait(inode->i_mapping); | 597 | rc = filemap_write_and_wait(inode->i_mapping); |
| 608 | mapping_set_error(inode->i_mapping, rc); | 598 | mapping_set_error(inode->i_mapping, rc); |
| 609 | 599 | ||
| 610 | pCifsInode->clientCanCacheAll = false; | ||
| 611 | pCifsInode->clientCanCacheRead = false; | ||
| 612 | if (tcon->unix_ext) | 600 | if (tcon->unix_ext) |
| 613 | rc = cifs_get_inode_info_unix(&inode, | 601 | rc = cifs_get_inode_info_unix(&inode, |
| 614 | full_path, inode->i_sb, xid); | 602 | full_path, inode->i_sb, xid); |
| @@ -622,18 +610,9 @@ reopen_success: | |||
| 622 | invalidate the current end of file on the server | 610 | invalidate the current end of file on the server |
| 623 | we can not go to the server to get the new inod | 611 | we can not go to the server to get the new inod |
| 624 | info */ | 612 | info */ |
| 625 | if ((oplock & 0xF) == OPLOCK_EXCLUSIVE) { | 613 | |
| 626 | pCifsInode->clientCanCacheAll = true; | 614 | cifs_set_oplock_level(pCifsInode, oplock); |
| 627 | pCifsInode->clientCanCacheRead = true; | 615 | |
| 628 | cFYI(1, "Exclusive Oplock granted on inode %p", | ||
| 629 | pCifsFile->dentry->d_inode); | ||
| 630 | } else if ((oplock & 0xF) == OPLOCK_READ) { | ||
| 631 | pCifsInode->clientCanCacheRead = true; | ||
| 632 | pCifsInode->clientCanCacheAll = false; | ||
| 633 | } else { | ||
| 634 | pCifsInode->clientCanCacheRead = false; | ||
| 635 | pCifsInode->clientCanCacheAll = false; | ||
| 636 | } | ||
| 637 | cifs_relock_file(pCifsFile); | 616 | cifs_relock_file(pCifsFile); |
| 638 | 617 | ||
| 639 | reopen_error_exit: | 618 | reopen_error_exit: |
| @@ -775,12 +754,6 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) | |||
| 775 | 754 | ||
| 776 | cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); | 755 | cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); |
| 777 | tcon = tlink_tcon(((struct cifsFileInfo *)file->private_data)->tlink); | 756 | tcon = tlink_tcon(((struct cifsFileInfo *)file->private_data)->tlink); |
| 778 | |||
| 779 | if (file->private_data == NULL) { | ||
| 780 | rc = -EBADF; | ||
| 781 | FreeXid(xid); | ||
| 782 | return rc; | ||
| 783 | } | ||
| 784 | netfid = ((struct cifsFileInfo *)file->private_data)->netfid; | 757 | netfid = ((struct cifsFileInfo *)file->private_data)->netfid; |
| 785 | 758 | ||
| 786 | if ((tcon->ses->capabilities & CAP_UNIX) && | 759 | if ((tcon->ses->capabilities & CAP_UNIX) && |
| @@ -956,6 +929,7 @@ cifs_update_eof(struct cifsInodeInfo *cifsi, loff_t offset, | |||
| 956 | ssize_t cifs_user_write(struct file *file, const char __user *write_data, | 929 | ssize_t cifs_user_write(struct file *file, const char __user *write_data, |
| 957 | size_t write_size, loff_t *poffset) | 930 | size_t write_size, loff_t *poffset) |
| 958 | { | 931 | { |
| 932 | struct inode *inode = file->f_path.dentry->d_inode; | ||
| 959 | int rc = 0; | 933 | int rc = 0; |
| 960 | unsigned int bytes_written = 0; | 934 | unsigned int bytes_written = 0; |
| 961 | unsigned int total_written; | 935 | unsigned int total_written; |
| @@ -963,7 +937,7 @@ ssize_t cifs_user_write(struct file *file, const char __user *write_data, | |||
| 963 | struct cifsTconInfo *pTcon; | 937 | struct cifsTconInfo *pTcon; |
| 964 | int xid, long_op; | 938 | int xid, long_op; |
| 965 | struct cifsFileInfo *open_file; | 939 | struct cifsFileInfo *open_file; |
| 966 | struct cifsInodeInfo *cifsi = CIFS_I(file->f_path.dentry->d_inode); | 940 | struct cifsInodeInfo *cifsi = CIFS_I(inode); |
| 967 | 941 | ||
| 968 | cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); | 942 | cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); |
| 969 | 943 | ||
| @@ -1029,21 +1003,17 @@ ssize_t cifs_user_write(struct file *file, const char __user *write_data, | |||
| 1029 | 1003 | ||
| 1030 | cifs_stats_bytes_written(pTcon, total_written); | 1004 | cifs_stats_bytes_written(pTcon, total_written); |
| 1031 | 1005 | ||
| 1032 | /* since the write may have blocked check these pointers again */ | ||
| 1033 | if ((file->f_path.dentry) && (file->f_path.dentry->d_inode)) { | ||
| 1034 | struct inode *inode = file->f_path.dentry->d_inode; | ||
| 1035 | /* Do not update local mtime - server will set its actual value on write | 1006 | /* Do not update local mtime - server will set its actual value on write |
| 1036 | * inode->i_ctime = inode->i_mtime = | 1007 | * inode->i_ctime = inode->i_mtime = |
| 1037 | * current_fs_time(inode->i_sb);*/ | 1008 | * current_fs_time(inode->i_sb);*/ |
| 1038 | if (total_written > 0) { | 1009 | if (total_written > 0) { |
| 1039 | spin_lock(&inode->i_lock); | 1010 | spin_lock(&inode->i_lock); |
| 1040 | if (*poffset > file->f_path.dentry->d_inode->i_size) | 1011 | if (*poffset > inode->i_size) |
| 1041 | i_size_write(file->f_path.dentry->d_inode, | 1012 | i_size_write(inode, *poffset); |
| 1042 | *poffset); | 1013 | spin_unlock(&inode->i_lock); |
| 1043 | spin_unlock(&inode->i_lock); | ||
| 1044 | } | ||
| 1045 | mark_inode_dirty_sync(file->f_path.dentry->d_inode); | ||
| 1046 | } | 1014 | } |
| 1015 | mark_inode_dirty_sync(inode); | ||
| 1016 | |||
| 1047 | FreeXid(xid); | 1017 | FreeXid(xid); |
| 1048 | return total_written; | 1018 | return total_written; |
| 1049 | } | 1019 | } |
| @@ -1178,7 +1148,7 @@ struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode, | |||
| 1178 | bool fsuid_only) | 1148 | bool fsuid_only) |
| 1179 | { | 1149 | { |
| 1180 | struct cifsFileInfo *open_file; | 1150 | struct cifsFileInfo *open_file; |
| 1181 | struct cifs_sb_info *cifs_sb = CIFS_SB(cifs_inode->vfs_inode.i_sb); | 1151 | struct cifs_sb_info *cifs_sb; |
| 1182 | bool any_available = false; | 1152 | bool any_available = false; |
| 1183 | int rc; | 1153 | int rc; |
| 1184 | 1154 | ||
| @@ -1192,6 +1162,8 @@ struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode, | |||
| 1192 | return NULL; | 1162 | return NULL; |
| 1193 | } | 1163 | } |
| 1194 | 1164 | ||
| 1165 | cifs_sb = CIFS_SB(cifs_inode->vfs_inode.i_sb); | ||
| 1166 | |||
| 1195 | /* only filter by fsuid on multiuser mounts */ | 1167 | /* only filter by fsuid on multiuser mounts */ |
| 1196 | if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER)) | 1168 | if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER)) |
| 1197 | fsuid_only = false; | 1169 | fsuid_only = false; |
diff --git a/fs/cifs/ioctl.c b/fs/cifs/ioctl.c index 077bf756f342..2fa22f20cfc5 100644 --- a/fs/cifs/ioctl.c +++ b/fs/cifs/ioctl.c | |||
| @@ -63,8 +63,6 @@ long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg) | |||
| 63 | #ifdef CONFIG_CIFS_POSIX | 63 | #ifdef CONFIG_CIFS_POSIX |
| 64 | case FS_IOC_GETFLAGS: | 64 | case FS_IOC_GETFLAGS: |
| 65 | if (CIFS_UNIX_EXTATTR_CAP & caps) { | 65 | if (CIFS_UNIX_EXTATTR_CAP & caps) { |
| 66 | if (pSMBFile == NULL) | ||
| 67 | break; | ||
| 68 | rc = CIFSGetExtAttr(xid, tcon, pSMBFile->netfid, | 66 | rc = CIFSGetExtAttr(xid, tcon, pSMBFile->netfid, |
| 69 | &ExtAttrBits, &ExtAttrMask); | 67 | &ExtAttrBits, &ExtAttrMask); |
| 70 | if (rc == 0) | 68 | if (rc == 0) |
| @@ -80,8 +78,6 @@ long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg) | |||
| 80 | rc = -EFAULT; | 78 | rc = -EFAULT; |
| 81 | break; | 79 | break; |
| 82 | } | 80 | } |
| 83 | if (pSMBFile == NULL) | ||
| 84 | break; | ||
| 85 | /* rc= CIFSGetExtAttr(xid,tcon,pSMBFile->netfid, | 81 | /* rc= CIFSGetExtAttr(xid,tcon,pSMBFile->netfid, |
| 86 | extAttrBits, &ExtAttrMask);*/ | 82 | extAttrBits, &ExtAttrMask);*/ |
| 87 | } | 83 | } |
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c index c4e296fe3518..43f10281bc19 100644 --- a/fs/cifs/misc.c +++ b/fs/cifs/misc.c | |||
| @@ -569,10 +569,9 @@ is_valid_oplock_break(struct smb_hdr *buf, struct TCP_Server_Info *srv) | |||
| 569 | 569 | ||
| 570 | cFYI(1, "file id match, oplock break"); | 570 | cFYI(1, "file id match, oplock break"); |
| 571 | pCifsInode = CIFS_I(netfile->dentry->d_inode); | 571 | pCifsInode = CIFS_I(netfile->dentry->d_inode); |
| 572 | pCifsInode->clientCanCacheAll = false; | ||
| 573 | if (pSMB->OplockLevel == 0) | ||
| 574 | pCifsInode->clientCanCacheRead = false; | ||
| 575 | 572 | ||
| 573 | cifs_set_oplock_level(pCifsInode, | ||
| 574 | pSMB->OplockLevel); | ||
| 576 | /* | 575 | /* |
| 577 | * cifs_oplock_break_put() can't be called | 576 | * cifs_oplock_break_put() can't be called |
| 578 | * from here. Get reference after queueing | 577 | * from here. Get reference after queueing |
| @@ -722,3 +721,23 @@ cifs_autodisable_serverino(struct cifs_sb_info *cifs_sb) | |||
| 722 | cifs_sb_master_tcon(cifs_sb)->treeName); | 721 | cifs_sb_master_tcon(cifs_sb)->treeName); |
| 723 | } | 722 | } |
| 724 | } | 723 | } |
| 724 | |||
| 725 | void cifs_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock) | ||
| 726 | { | ||
| 727 | oplock &= 0xF; | ||
| 728 | |||
| 729 | if (oplock == OPLOCK_EXCLUSIVE) { | ||
| 730 | cinode->clientCanCacheAll = true; | ||
| 731 | cinode->clientCanCacheRead = true; | ||
| 732 | cFYI(1, "Exclusive Oplock granted on inode %p", | ||
| 733 | &cinode->vfs_inode); | ||
| 734 | } else if (oplock == OPLOCK_READ) { | ||
| 735 | cinode->clientCanCacheAll = false; | ||
| 736 | cinode->clientCanCacheRead = true; | ||
| 737 | cFYI(1, "Level II Oplock granted on inode %p", | ||
| 738 | &cinode->vfs_inode); | ||
| 739 | } else { | ||
| 740 | cinode->clientCanCacheAll = false; | ||
| 741 | cinode->clientCanCacheRead = false; | ||
| 742 | } | ||
| 743 | } | ||
diff --git a/include/asm-generic/stat.h b/include/asm-generic/stat.h index 47e64170305d..bd8cad21998e 100644 --- a/include/asm-generic/stat.h +++ b/include/asm-generic/stat.h | |||
| @@ -33,18 +33,18 @@ struct stat { | |||
| 33 | int st_blksize; /* Optimal block size for I/O. */ | 33 | int st_blksize; /* Optimal block size for I/O. */ |
| 34 | int __pad2; | 34 | int __pad2; |
| 35 | long st_blocks; /* Number 512-byte blocks allocated. */ | 35 | long st_blocks; /* Number 512-byte blocks allocated. */ |
| 36 | int st_atime; /* Time of last access. */ | 36 | long st_atime; /* Time of last access. */ |
| 37 | unsigned int st_atime_nsec; | 37 | unsigned long st_atime_nsec; |
| 38 | int st_mtime; /* Time of last modification. */ | 38 | long st_mtime; /* Time of last modification. */ |
| 39 | unsigned int st_mtime_nsec; | 39 | unsigned long st_mtime_nsec; |
| 40 | int st_ctime; /* Time of last status change. */ | 40 | long st_ctime; /* Time of last status change. */ |
| 41 | unsigned int st_ctime_nsec; | 41 | unsigned long st_ctime_nsec; |
| 42 | unsigned int __unused4; | 42 | unsigned int __unused4; |
| 43 | unsigned int __unused5; | 43 | unsigned int __unused5; |
| 44 | }; | 44 | }; |
| 45 | 45 | ||
| 46 | #if __BITS_PER_LONG != 64 | ||
| 47 | /* This matches struct stat64 in glibc2.1. Only used for 32 bit. */ | 46 | /* This matches struct stat64 in glibc2.1. Only used for 32 bit. */ |
| 47 | #if __BITS_PER_LONG != 64 || defined(__ARCH_WANT_STAT64) | ||
| 48 | struct stat64 { | 48 | struct stat64 { |
| 49 | unsigned long long st_dev; /* Device. */ | 49 | unsigned long long st_dev; /* Device. */ |
| 50 | unsigned long long st_ino; /* File serial number. */ | 50 | unsigned long long st_ino; /* File serial number. */ |
diff --git a/include/net/caif/caif_dev.h b/include/net/caif/caif_dev.h index 6da573c75d54..8eff83b95366 100644 --- a/include/net/caif/caif_dev.h +++ b/include/net/caif/caif_dev.h | |||
| @@ -28,7 +28,7 @@ struct caif_param { | |||
| 28 | * @sockaddr: Socket address to connect. | 28 | * @sockaddr: Socket address to connect. |
| 29 | * @priority: Priority of the connection. | 29 | * @priority: Priority of the connection. |
| 30 | * @link_selector: Link selector (high bandwidth or low latency) | 30 | * @link_selector: Link selector (high bandwidth or low latency) |
| 31 | * @link_name: Name of the CAIF Link Layer to use. | 31 | * @ifindex: kernel index of the interface. |
| 32 | * @param: Connect Request parameters (CAIF_SO_REQ_PARAM). | 32 | * @param: Connect Request parameters (CAIF_SO_REQ_PARAM). |
| 33 | * | 33 | * |
| 34 | * This struct is used when connecting a CAIF channel. | 34 | * This struct is used when connecting a CAIF channel. |
| @@ -39,7 +39,7 @@ struct caif_connect_request { | |||
| 39 | struct sockaddr_caif sockaddr; | 39 | struct sockaddr_caif sockaddr; |
| 40 | enum caif_channel_priority priority; | 40 | enum caif_channel_priority priority; |
| 41 | enum caif_link_selector link_selector; | 41 | enum caif_link_selector link_selector; |
| 42 | char link_name[16]; | 42 | int ifindex; |
| 43 | struct caif_param param; | 43 | struct caif_param param; |
| 44 | }; | 44 | }; |
| 45 | 45 | ||
diff --git a/include/net/caif/caif_spi.h b/include/net/caif/caif_spi.h index ce4570dff020..87c3d11b8e55 100644 --- a/include/net/caif/caif_spi.h +++ b/include/net/caif/caif_spi.h | |||
| @@ -121,6 +121,8 @@ struct cfspi { | |||
| 121 | wait_queue_head_t wait; | 121 | wait_queue_head_t wait; |
| 122 | spinlock_t lock; | 122 | spinlock_t lock; |
| 123 | bool flow_stop; | 123 | bool flow_stop; |
| 124 | bool slave; | ||
| 125 | bool slave_talked; | ||
| 124 | #ifdef CONFIG_DEBUG_FS | 126 | #ifdef CONFIG_DEBUG_FS |
| 125 | enum cfspi_state dbg_state; | 127 | enum cfspi_state dbg_state; |
| 126 | u16 pcmd; | 128 | u16 pcmd; |
diff --git a/include/net/caif/cfcnfg.h b/include/net/caif/cfcnfg.h index bd646faffa47..f688478bfb84 100644 --- a/include/net/caif/cfcnfg.h +++ b/include/net/caif/cfcnfg.h | |||
| @@ -139,10 +139,10 @@ struct dev_info *cfcnfg_get_phyid(struct cfcnfg *cnfg, | |||
| 139 | enum cfcnfg_phy_preference phy_pref); | 139 | enum cfcnfg_phy_preference phy_pref); |
| 140 | 140 | ||
| 141 | /** | 141 | /** |
| 142 | * cfcnfg_get_named() - Get the Physical Identifier of CAIF Link Layer | 142 | * cfcnfg_get_id_from_ifi() - Get the Physical Identifier of ifindex, |
| 143 | * it matches caif physical id with the kernel interface id. | ||
| 143 | * @cnfg: Configuration object | 144 | * @cnfg: Configuration object |
| 144 | * @name: Name of the Physical Layer (Caif Link Layer) | 145 | * @ifi: ifindex obtained from socket.c bindtodevice. |
| 145 | */ | 146 | */ |
| 146 | int cfcnfg_get_named(struct cfcnfg *cnfg, char *name); | 147 | int cfcnfg_get_id_from_ifi(struct cfcnfg *cnfg, int ifi); |
| 147 | |||
| 148 | #endif /* CFCNFG_H_ */ | 148 | #endif /* CFCNFG_H_ */ |
diff --git a/include/net/netlink.h b/include/net/netlink.h index f3b201d335b3..9801c55de5d6 100644 --- a/include/net/netlink.h +++ b/include/net/netlink.h | |||
| @@ -384,7 +384,7 @@ static inline int nlmsg_parse(const struct nlmsghdr *nlh, int hdrlen, | |||
| 384 | * | 384 | * |
| 385 | * Returns the first attribute which matches the specified type. | 385 | * Returns the first attribute which matches the specified type. |
| 386 | */ | 386 | */ |
| 387 | static inline struct nlattr *nlmsg_find_attr(struct nlmsghdr *nlh, | 387 | static inline struct nlattr *nlmsg_find_attr(const struct nlmsghdr *nlh, |
| 388 | int hdrlen, int attrtype) | 388 | int hdrlen, int attrtype) |
| 389 | { | 389 | { |
| 390 | return nla_find(nlmsg_attrdata(nlh, hdrlen), | 390 | return nla_find(nlmsg_attrdata(nlh, hdrlen), |
diff --git a/kernel/exit.c b/kernel/exit.c index b194febf5799..21aa7b3001fb 100644 --- a/kernel/exit.c +++ b/kernel/exit.c | |||
| @@ -96,6 +96,14 @@ static void __exit_signal(struct task_struct *tsk) | |||
| 96 | sig->tty = NULL; | 96 | sig->tty = NULL; |
| 97 | } else { | 97 | } else { |
| 98 | /* | 98 | /* |
| 99 | * This can only happen if the caller is de_thread(). | ||
| 100 | * FIXME: this is the temporary hack, we should teach | ||
| 101 | * posix-cpu-timers to handle this case correctly. | ||
| 102 | */ | ||
| 103 | if (unlikely(has_group_leader_pid(tsk))) | ||
| 104 | posix_cpu_timers_exit_group(tsk); | ||
| 105 | |||
| 106 | /* | ||
| 99 | * If there is any task waiting for the group exit | 107 | * If there is any task waiting for the group exit |
| 100 | * then notify it: | 108 | * then notify it: |
| 101 | */ | 109 | */ |
diff --git a/kernel/relay.c b/kernel/relay.c index c7cf397fb929..859ea5a9605f 100644 --- a/kernel/relay.c +++ b/kernel/relay.c | |||
| @@ -70,17 +70,10 @@ static const struct vm_operations_struct relay_file_mmap_ops = { | |||
| 70 | */ | 70 | */ |
| 71 | static struct page **relay_alloc_page_array(unsigned int n_pages) | 71 | static struct page **relay_alloc_page_array(unsigned int n_pages) |
| 72 | { | 72 | { |
| 73 | struct page **array; | 73 | const size_t pa_size = n_pages * sizeof(struct page *); |
| 74 | size_t pa_size = n_pages * sizeof(struct page *); | 74 | if (pa_size > PAGE_SIZE) |
| 75 | 75 | return vzalloc(pa_size); | |
| 76 | if (pa_size > PAGE_SIZE) { | 76 | return kzalloc(pa_size, GFP_KERNEL); |
| 77 | array = vmalloc(pa_size); | ||
| 78 | if (array) | ||
| 79 | memset(array, 0, pa_size); | ||
| 80 | } else { | ||
| 81 | array = kzalloc(pa_size, GFP_KERNEL); | ||
| 82 | } | ||
| 83 | return array; | ||
| 84 | } | 77 | } |
| 85 | 78 | ||
| 86 | /* | 79 | /* |
diff --git a/kernel/watchdog.c b/kernel/watchdog.c index bafba687a6d8..6e3c41a4024c 100644 --- a/kernel/watchdog.c +++ b/kernel/watchdog.c | |||
| @@ -43,7 +43,7 @@ static DEFINE_PER_CPU(unsigned long, hrtimer_interrupts_saved); | |||
| 43 | static DEFINE_PER_CPU(struct perf_event *, watchdog_ev); | 43 | static DEFINE_PER_CPU(struct perf_event *, watchdog_ev); |
| 44 | #endif | 44 | #endif |
| 45 | 45 | ||
| 46 | static int __initdata no_watchdog; | 46 | static int no_watchdog; |
| 47 | 47 | ||
| 48 | 48 | ||
| 49 | /* boot commands */ | 49 | /* boot commands */ |
diff --git a/net/caif/caif_config_util.c b/net/caif/caif_config_util.c index 76ae68303d3a..d522d8c1703e 100644 --- a/net/caif/caif_config_util.c +++ b/net/caif/caif_config_util.c | |||
| @@ -16,11 +16,18 @@ int connect_req_to_link_param(struct cfcnfg *cnfg, | |||
| 16 | { | 16 | { |
| 17 | struct dev_info *dev_info; | 17 | struct dev_info *dev_info; |
| 18 | enum cfcnfg_phy_preference pref; | 18 | enum cfcnfg_phy_preference pref; |
| 19 | int res; | ||
| 20 | |||
| 19 | memset(l, 0, sizeof(*l)); | 21 | memset(l, 0, sizeof(*l)); |
| 20 | l->priority = s->priority; | 22 | /* In caif protocol low value is high priority */ |
| 23 | l->priority = CAIF_PRIO_MAX - s->priority + 1; | ||
| 21 | 24 | ||
| 22 | if (s->link_name[0] != '\0') | 25 | if (s->ifindex != 0){ |
| 23 | l->phyid = cfcnfg_get_named(cnfg, s->link_name); | 26 | res = cfcnfg_get_id_from_ifi(cnfg, s->ifindex); |
| 27 | if (res < 0) | ||
| 28 | return res; | ||
| 29 | l->phyid = res; | ||
| 30 | } | ||
| 24 | else { | 31 | else { |
| 25 | switch (s->link_selector) { | 32 | switch (s->link_selector) { |
| 26 | case CAIF_LINK_HIGH_BANDW: | 33 | case CAIF_LINK_HIGH_BANDW: |
diff --git a/net/caif/caif_dev.c b/net/caif/caif_dev.c index b99369a055d1..a42a408306e4 100644 --- a/net/caif/caif_dev.c +++ b/net/caif/caif_dev.c | |||
| @@ -307,6 +307,8 @@ static int caif_device_notify(struct notifier_block *me, unsigned long what, | |||
| 307 | 307 | ||
| 308 | case NETDEV_UNREGISTER: | 308 | case NETDEV_UNREGISTER: |
| 309 | caifd = caif_get(dev); | 309 | caifd = caif_get(dev); |
| 310 | if (caifd == NULL) | ||
| 311 | break; | ||
| 310 | netdev_info(dev, "unregister\n"); | 312 | netdev_info(dev, "unregister\n"); |
| 311 | atomic_set(&caifd->state, what); | 313 | atomic_set(&caifd->state, what); |
| 312 | caif_device_destroy(dev); | 314 | caif_device_destroy(dev); |
diff --git a/net/caif/caif_socket.c b/net/caif/caif_socket.c index 2eca2dd0000f..1bf0cf503796 100644 --- a/net/caif/caif_socket.c +++ b/net/caif/caif_socket.c | |||
| @@ -716,8 +716,7 @@ static int setsockopt(struct socket *sock, | |||
| 716 | { | 716 | { |
| 717 | struct sock *sk = sock->sk; | 717 | struct sock *sk = sock->sk; |
| 718 | struct caifsock *cf_sk = container_of(sk, struct caifsock, sk); | 718 | struct caifsock *cf_sk = container_of(sk, struct caifsock, sk); |
| 719 | int prio, linksel; | 719 | int linksel; |
| 720 | struct ifreq ifreq; | ||
| 721 | 720 | ||
| 722 | if (cf_sk->sk.sk_socket->state != SS_UNCONNECTED) | 721 | if (cf_sk->sk.sk_socket->state != SS_UNCONNECTED) |
| 723 | return -ENOPROTOOPT; | 722 | return -ENOPROTOOPT; |
| @@ -735,33 +734,6 @@ static int setsockopt(struct socket *sock, | |||
| 735 | release_sock(&cf_sk->sk); | 734 | release_sock(&cf_sk->sk); |
| 736 | return 0; | 735 | return 0; |
| 737 | 736 | ||
| 738 | case SO_PRIORITY: | ||
| 739 | if (lvl != SOL_SOCKET) | ||
| 740 | goto bad_sol; | ||
| 741 | if (ol < sizeof(int)) | ||
| 742 | return -EINVAL; | ||
| 743 | if (copy_from_user(&prio, ov, sizeof(int))) | ||
| 744 | return -EINVAL; | ||
| 745 | lock_sock(&(cf_sk->sk)); | ||
| 746 | cf_sk->conn_req.priority = prio; | ||
| 747 | release_sock(&cf_sk->sk); | ||
| 748 | return 0; | ||
| 749 | |||
| 750 | case SO_BINDTODEVICE: | ||
| 751 | if (lvl != SOL_SOCKET) | ||
| 752 | goto bad_sol; | ||
| 753 | if (ol < sizeof(struct ifreq)) | ||
| 754 | return -EINVAL; | ||
| 755 | if (copy_from_user(&ifreq, ov, sizeof(ifreq))) | ||
| 756 | return -EFAULT; | ||
| 757 | lock_sock(&(cf_sk->sk)); | ||
| 758 | strncpy(cf_sk->conn_req.link_name, ifreq.ifr_name, | ||
| 759 | sizeof(cf_sk->conn_req.link_name)); | ||
| 760 | cf_sk->conn_req.link_name | ||
| 761 | [sizeof(cf_sk->conn_req.link_name)-1] = 0; | ||
| 762 | release_sock(&cf_sk->sk); | ||
| 763 | return 0; | ||
| 764 | |||
| 765 | case CAIFSO_REQ_PARAM: | 737 | case CAIFSO_REQ_PARAM: |
| 766 | if (lvl != SOL_CAIF) | 738 | if (lvl != SOL_CAIF) |
| 767 | goto bad_sol; | 739 | goto bad_sol; |
| @@ -880,6 +852,18 @@ static int caif_connect(struct socket *sock, struct sockaddr *uaddr, | |||
| 880 | sock->state = SS_CONNECTING; | 852 | sock->state = SS_CONNECTING; |
| 881 | sk->sk_state = CAIF_CONNECTING; | 853 | sk->sk_state = CAIF_CONNECTING; |
| 882 | 854 | ||
| 855 | /* Check priority value comming from socket */ | ||
| 856 | /* if priority value is out of range it will be ajusted */ | ||
| 857 | if (cf_sk->sk.sk_priority > CAIF_PRIO_MAX) | ||
| 858 | cf_sk->conn_req.priority = CAIF_PRIO_MAX; | ||
| 859 | else if (cf_sk->sk.sk_priority < CAIF_PRIO_MIN) | ||
| 860 | cf_sk->conn_req.priority = CAIF_PRIO_MIN; | ||
| 861 | else | ||
| 862 | cf_sk->conn_req.priority = cf_sk->sk.sk_priority; | ||
| 863 | |||
| 864 | /*ifindex = id of the interface.*/ | ||
| 865 | cf_sk->conn_req.ifindex = cf_sk->sk.sk_bound_dev_if; | ||
| 866 | |||
| 883 | dbfs_atomic_inc(&cnt.num_connect_req); | 867 | dbfs_atomic_inc(&cnt.num_connect_req); |
| 884 | cf_sk->layer.receive = caif_sktrecv_cb; | 868 | cf_sk->layer.receive = caif_sktrecv_cb; |
| 885 | err = caif_connect_client(&cf_sk->conn_req, | 869 | err = caif_connect_client(&cf_sk->conn_req, |
| @@ -905,6 +889,7 @@ static int caif_connect(struct socket *sock, struct sockaddr *uaddr, | |||
| 905 | cf_sk->maxframe = mtu - (headroom + tailroom); | 889 | cf_sk->maxframe = mtu - (headroom + tailroom); |
| 906 | if (cf_sk->maxframe < 1) { | 890 | if (cf_sk->maxframe < 1) { |
| 907 | pr_warn("CAIF Interface MTU too small (%d)\n", dev->mtu); | 891 | pr_warn("CAIF Interface MTU too small (%d)\n", dev->mtu); |
| 892 | err = -ENODEV; | ||
| 908 | goto out; | 893 | goto out; |
| 909 | } | 894 | } |
| 910 | 895 | ||
| @@ -1142,7 +1127,7 @@ static int caif_create(struct net *net, struct socket *sock, int protocol, | |||
| 1142 | set_rx_flow_on(cf_sk); | 1127 | set_rx_flow_on(cf_sk); |
| 1143 | 1128 | ||
| 1144 | /* Set default options on configuration */ | 1129 | /* Set default options on configuration */ |
| 1145 | cf_sk->conn_req.priority = CAIF_PRIO_NORMAL; | 1130 | cf_sk->sk.sk_priority= CAIF_PRIO_NORMAL; |
| 1146 | cf_sk->conn_req.link_selector = CAIF_LINK_LOW_LATENCY; | 1131 | cf_sk->conn_req.link_selector = CAIF_LINK_LOW_LATENCY; |
| 1147 | cf_sk->conn_req.protocol = protocol; | 1132 | cf_sk->conn_req.protocol = protocol; |
| 1148 | /* Increase the number of sockets created. */ | 1133 | /* Increase the number of sockets created. */ |
diff --git a/net/caif/cfcnfg.c b/net/caif/cfcnfg.c index 41adafd18914..21ede141018a 100644 --- a/net/caif/cfcnfg.c +++ b/net/caif/cfcnfg.c | |||
| @@ -173,18 +173,15 @@ static struct cfcnfg_phyinfo *cfcnfg_get_phyinfo(struct cfcnfg *cnfg, | |||
| 173 | return NULL; | 173 | return NULL; |
| 174 | } | 174 | } |
| 175 | 175 | ||
| 176 | int cfcnfg_get_named(struct cfcnfg *cnfg, char *name) | 176 | |
| 177 | int cfcnfg_get_id_from_ifi(struct cfcnfg *cnfg, int ifi) | ||
| 177 | { | 178 | { |
| 178 | int i; | 179 | int i; |
| 179 | 180 | for (i = 0; i < MAX_PHY_LAYERS; i++) | |
| 180 | /* Try to match with specified name */ | 181 | if (cnfg->phy_layers[i].frm_layer != NULL && |
| 181 | for (i = 0; i < MAX_PHY_LAYERS; i++) { | 182 | cnfg->phy_layers[i].ifindex == ifi) |
| 182 | if (cnfg->phy_layers[i].frm_layer != NULL | 183 | return i; |
| 183 | && strcmp(cnfg->phy_layers[i].phy_layer->name, | 184 | return -ENODEV; |
| 184 | name) == 0) | ||
| 185 | return cnfg->phy_layers[i].frm_layer->id; | ||
| 186 | } | ||
| 187 | return 0; | ||
| 188 | } | 185 | } |
| 189 | 186 | ||
| 190 | int cfcnfg_disconn_adapt_layer(struct cfcnfg *cnfg, struct cflayer *adap_layer) | 187 | int cfcnfg_disconn_adapt_layer(struct cfcnfg *cnfg, struct cflayer *adap_layer) |
diff --git a/net/caif/cfctrl.c b/net/caif/cfctrl.c index 08f267a109aa..3cd8f978e309 100644 --- a/net/caif/cfctrl.c +++ b/net/caif/cfctrl.c | |||
| @@ -361,11 +361,10 @@ void cfctrl_cancel_req(struct cflayer *layr, struct cflayer *adap_layer) | |||
| 361 | struct cfctrl_request_info *p, *tmp; | 361 | struct cfctrl_request_info *p, *tmp; |
| 362 | struct cfctrl *ctrl = container_obj(layr); | 362 | struct cfctrl *ctrl = container_obj(layr); |
| 363 | spin_lock(&ctrl->info_list_lock); | 363 | spin_lock(&ctrl->info_list_lock); |
| 364 | pr_warn("enter\n"); | ||
| 365 | 364 | ||
| 366 | list_for_each_entry_safe(p, tmp, &ctrl->list, list) { | 365 | list_for_each_entry_safe(p, tmp, &ctrl->list, list) { |
| 367 | if (p->client_layer == adap_layer) { | 366 | if (p->client_layer == adap_layer) { |
| 368 | pr_warn("cancel req :%d\n", p->sequence_no); | 367 | pr_debug("cancel req :%d\n", p->sequence_no); |
| 369 | list_del(&p->list); | 368 | list_del(&p->list); |
| 370 | kfree(p); | 369 | kfree(p); |
| 371 | } | 370 | } |
diff --git a/net/caif/cfdbgl.c b/net/caif/cfdbgl.c index 496fda9ac66f..11a2af4c162a 100644 --- a/net/caif/cfdbgl.c +++ b/net/caif/cfdbgl.c | |||
| @@ -12,6 +12,8 @@ | |||
| 12 | #include <net/caif/cfsrvl.h> | 12 | #include <net/caif/cfsrvl.h> |
| 13 | #include <net/caif/cfpkt.h> | 13 | #include <net/caif/cfpkt.h> |
| 14 | 14 | ||
| 15 | #define container_obj(layr) ((struct cfsrvl *) layr) | ||
| 16 | |||
| 15 | static int cfdbgl_receive(struct cflayer *layr, struct cfpkt *pkt); | 17 | static int cfdbgl_receive(struct cflayer *layr, struct cfpkt *pkt); |
| 16 | static int cfdbgl_transmit(struct cflayer *layr, struct cfpkt *pkt); | 18 | static int cfdbgl_transmit(struct cflayer *layr, struct cfpkt *pkt); |
| 17 | 19 | ||
| @@ -38,5 +40,17 @@ static int cfdbgl_receive(struct cflayer *layr, struct cfpkt *pkt) | |||
| 38 | 40 | ||
| 39 | static int cfdbgl_transmit(struct cflayer *layr, struct cfpkt *pkt) | 41 | static int cfdbgl_transmit(struct cflayer *layr, struct cfpkt *pkt) |
| 40 | { | 42 | { |
| 43 | struct cfsrvl *service = container_obj(layr); | ||
| 44 | struct caif_payload_info *info; | ||
| 45 | int ret; | ||
| 46 | |||
| 47 | if (!cfsrvl_ready(service, &ret)) | ||
| 48 | return ret; | ||
| 49 | |||
| 50 | /* Add info for MUX-layer to route the packet out */ | ||
| 51 | info = cfpkt_info(pkt); | ||
| 52 | info->channel_id = service->layer.id; | ||
| 53 | info->dev_info = &service->dev_info; | ||
| 54 | |||
| 41 | return layr->dn->transmit(layr->dn, pkt); | 55 | return layr->dn->transmit(layr->dn, pkt); |
| 42 | } | 56 | } |
diff --git a/net/caif/cfrfml.c b/net/caif/cfrfml.c index bde8481e8d25..e2fb5fa75795 100644 --- a/net/caif/cfrfml.c +++ b/net/caif/cfrfml.c | |||
| @@ -193,7 +193,7 @@ out: | |||
| 193 | 193 | ||
| 194 | static int cfrfml_transmit_segment(struct cfrfml *rfml, struct cfpkt *pkt) | 194 | static int cfrfml_transmit_segment(struct cfrfml *rfml, struct cfpkt *pkt) |
| 195 | { | 195 | { |
| 196 | caif_assert(cfpkt_getlen(pkt) >= rfml->fragment_size); | 196 | caif_assert(cfpkt_getlen(pkt) < rfml->fragment_size); |
| 197 | 197 | ||
| 198 | /* Add info for MUX-layer to route the packet out. */ | 198 | /* Add info for MUX-layer to route the packet out. */ |
| 199 | cfpkt_info(pkt)->channel_id = rfml->serv.layer.id; | 199 | cfpkt_info(pkt)->channel_id = rfml->serv.layer.id; |
diff --git a/net/core/dev.c b/net/core/dev.c index 35dfb8318483..0dd54a69dace 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
| @@ -2131,7 +2131,7 @@ static struct netdev_queue *dev_pick_tx(struct net_device *dev, | |||
| 2131 | } else { | 2131 | } else { |
| 2132 | struct sock *sk = skb->sk; | 2132 | struct sock *sk = skb->sk; |
| 2133 | queue_index = sk_tx_queue_get(sk); | 2133 | queue_index = sk_tx_queue_get(sk); |
| 2134 | if (queue_index < 0) { | 2134 | if (queue_index < 0 || queue_index >= dev->real_num_tx_queues) { |
| 2135 | 2135 | ||
| 2136 | queue_index = 0; | 2136 | queue_index = 0; |
| 2137 | if (dev->real_num_tx_queues > 1) | 2137 | if (dev->real_num_tx_queues > 1) |
diff --git a/net/ipv4/fib_lookup.h b/net/ipv4/fib_lookup.h index a29edf2219c8..c079cc0ec651 100644 --- a/net/ipv4/fib_lookup.h +++ b/net/ipv4/fib_lookup.h | |||
| @@ -47,11 +47,8 @@ extern int fib_detect_death(struct fib_info *fi, int order, | |||
| 47 | static inline void fib_result_assign(struct fib_result *res, | 47 | static inline void fib_result_assign(struct fib_result *res, |
| 48 | struct fib_info *fi) | 48 | struct fib_info *fi) |
| 49 | { | 49 | { |
| 50 | if (res->fi != NULL) | 50 | /* we used to play games with refcounts, but we now use RCU */ |
| 51 | fib_info_put(res->fi); | ||
| 52 | res->fi = fi; | 51 | res->fi = fi; |
| 53 | if (fi != NULL) | ||
| 54 | atomic_inc(&fi->fib_clntref); | ||
| 55 | } | 52 | } |
| 56 | 53 | ||
| 57 | #endif /* _FIB_LOOKUP_H */ | 54 | #endif /* _FIB_LOOKUP_H */ |
diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c index ba8042665849..2ada17129fce 100644 --- a/net/ipv4/inet_diag.c +++ b/net/ipv4/inet_diag.c | |||
| @@ -490,9 +490,11 @@ static int inet_csk_diag_dump(struct sock *sk, | |||
| 490 | { | 490 | { |
| 491 | struct inet_diag_req *r = NLMSG_DATA(cb->nlh); | 491 | struct inet_diag_req *r = NLMSG_DATA(cb->nlh); |
| 492 | 492 | ||
| 493 | if (cb->nlh->nlmsg_len > 4 + NLMSG_SPACE(sizeof(*r))) { | 493 | if (nlmsg_attrlen(cb->nlh, sizeof(*r))) { |
| 494 | struct inet_diag_entry entry; | 494 | struct inet_diag_entry entry; |
| 495 | struct rtattr *bc = (struct rtattr *)(r + 1); | 495 | const struct nlattr *bc = nlmsg_find_attr(cb->nlh, |
| 496 | sizeof(*r), | ||
| 497 | INET_DIAG_REQ_BYTECODE); | ||
| 496 | struct inet_sock *inet = inet_sk(sk); | 498 | struct inet_sock *inet = inet_sk(sk); |
| 497 | 499 | ||
| 498 | entry.family = sk->sk_family; | 500 | entry.family = sk->sk_family; |
| @@ -512,7 +514,7 @@ static int inet_csk_diag_dump(struct sock *sk, | |||
| 512 | entry.dport = ntohs(inet->inet_dport); | 514 | entry.dport = ntohs(inet->inet_dport); |
| 513 | entry.userlocks = sk->sk_userlocks; | 515 | entry.userlocks = sk->sk_userlocks; |
| 514 | 516 | ||
| 515 | if (!inet_diag_bc_run(RTA_DATA(bc), RTA_PAYLOAD(bc), &entry)) | 517 | if (!inet_diag_bc_run(nla_data(bc), nla_len(bc), &entry)) |
| 516 | return 0; | 518 | return 0; |
| 517 | } | 519 | } |
| 518 | 520 | ||
| @@ -527,9 +529,11 @@ static int inet_twsk_diag_dump(struct inet_timewait_sock *tw, | |||
| 527 | { | 529 | { |
| 528 | struct inet_diag_req *r = NLMSG_DATA(cb->nlh); | 530 | struct inet_diag_req *r = NLMSG_DATA(cb->nlh); |
| 529 | 531 | ||
| 530 | if (cb->nlh->nlmsg_len > 4 + NLMSG_SPACE(sizeof(*r))) { | 532 | if (nlmsg_attrlen(cb->nlh, sizeof(*r))) { |
| 531 | struct inet_diag_entry entry; | 533 | struct inet_diag_entry entry; |
| 532 | struct rtattr *bc = (struct rtattr *)(r + 1); | 534 | const struct nlattr *bc = nlmsg_find_attr(cb->nlh, |
| 535 | sizeof(*r), | ||
| 536 | INET_DIAG_REQ_BYTECODE); | ||
| 533 | 537 | ||
| 534 | entry.family = tw->tw_family; | 538 | entry.family = tw->tw_family; |
| 535 | #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) | 539 | #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) |
| @@ -548,7 +552,7 @@ static int inet_twsk_diag_dump(struct inet_timewait_sock *tw, | |||
| 548 | entry.dport = ntohs(tw->tw_dport); | 552 | entry.dport = ntohs(tw->tw_dport); |
| 549 | entry.userlocks = 0; | 553 | entry.userlocks = 0; |
| 550 | 554 | ||
| 551 | if (!inet_diag_bc_run(RTA_DATA(bc), RTA_PAYLOAD(bc), &entry)) | 555 | if (!inet_diag_bc_run(nla_data(bc), nla_len(bc), &entry)) |
| 552 | return 0; | 556 | return 0; |
| 553 | } | 557 | } |
| 554 | 558 | ||
| @@ -618,7 +622,7 @@ static int inet_diag_dump_reqs(struct sk_buff *skb, struct sock *sk, | |||
| 618 | struct inet_diag_req *r = NLMSG_DATA(cb->nlh); | 622 | struct inet_diag_req *r = NLMSG_DATA(cb->nlh); |
| 619 | struct inet_connection_sock *icsk = inet_csk(sk); | 623 | struct inet_connection_sock *icsk = inet_csk(sk); |
| 620 | struct listen_sock *lopt; | 624 | struct listen_sock *lopt; |
| 621 | struct rtattr *bc = NULL; | 625 | const struct nlattr *bc = NULL; |
| 622 | struct inet_sock *inet = inet_sk(sk); | 626 | struct inet_sock *inet = inet_sk(sk); |
| 623 | int j, s_j; | 627 | int j, s_j; |
| 624 | int reqnum, s_reqnum; | 628 | int reqnum, s_reqnum; |
| @@ -638,8 +642,9 @@ static int inet_diag_dump_reqs(struct sk_buff *skb, struct sock *sk, | |||
| 638 | if (!lopt || !lopt->qlen) | 642 | if (!lopt || !lopt->qlen) |
| 639 | goto out; | 643 | goto out; |
| 640 | 644 | ||
| 641 | if (cb->nlh->nlmsg_len > 4 + NLMSG_SPACE(sizeof(*r))) { | 645 | if (nlmsg_attrlen(cb->nlh, sizeof(*r))) { |
| 642 | bc = (struct rtattr *)(r + 1); | 646 | bc = nlmsg_find_attr(cb->nlh, sizeof(*r), |
| 647 | INET_DIAG_REQ_BYTECODE); | ||
| 643 | entry.sport = inet->inet_num; | 648 | entry.sport = inet->inet_num; |
| 644 | entry.userlocks = sk->sk_userlocks; | 649 | entry.userlocks = sk->sk_userlocks; |
| 645 | } | 650 | } |
| @@ -672,8 +677,8 @@ static int inet_diag_dump_reqs(struct sk_buff *skb, struct sock *sk, | |||
| 672 | &ireq->rmt_addr; | 677 | &ireq->rmt_addr; |
| 673 | entry.dport = ntohs(ireq->rmt_port); | 678 | entry.dport = ntohs(ireq->rmt_port); |
| 674 | 679 | ||
| 675 | if (!inet_diag_bc_run(RTA_DATA(bc), | 680 | if (!inet_diag_bc_run(nla_data(bc), |
| 676 | RTA_PAYLOAD(bc), &entry)) | 681 | nla_len(bc), &entry)) |
| 677 | continue; | 682 | continue; |
| 678 | } | 683 | } |
| 679 | 684 | ||
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c index 3cad2591ace0..3fac340a28d5 100644 --- a/net/ipv4/netfilter/arp_tables.c +++ b/net/ipv4/netfilter/arp_tables.c | |||
| @@ -927,6 +927,7 @@ static int get_info(struct net *net, void __user *user, | |||
| 927 | private = &tmp; | 927 | private = &tmp; |
| 928 | } | 928 | } |
| 929 | #endif | 929 | #endif |
| 930 | memset(&info, 0, sizeof(info)); | ||
| 930 | info.valid_hooks = t->valid_hooks; | 931 | info.valid_hooks = t->valid_hooks; |
| 931 | memcpy(info.hook_entry, private->hook_entry, | 932 | memcpy(info.hook_entry, private->hook_entry, |
| 932 | sizeof(info.hook_entry)); | 933 | sizeof(info.hook_entry)); |
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c index d31b007a6d80..a846d633b3b6 100644 --- a/net/ipv4/netfilter/ip_tables.c +++ b/net/ipv4/netfilter/ip_tables.c | |||
| @@ -1124,6 +1124,7 @@ static int get_info(struct net *net, void __user *user, | |||
| 1124 | private = &tmp; | 1124 | private = &tmp; |
| 1125 | } | 1125 | } |
| 1126 | #endif | 1126 | #endif |
| 1127 | memset(&info, 0, sizeof(info)); | ||
| 1127 | info.valid_hooks = t->valid_hooks; | 1128 | info.valid_hooks = t->valid_hooks; |
| 1128 | memcpy(info.hook_entry, private->hook_entry, | 1129 | memcpy(info.hook_entry, private->hook_entry, |
| 1129 | sizeof(info.hook_entry)); | 1130 | sizeof(info.hook_entry)); |
diff --git a/net/ipv4/netfilter/nf_nat_core.c b/net/ipv4/netfilter/nf_nat_core.c index 295c97431e43..c04787ce1a71 100644 --- a/net/ipv4/netfilter/nf_nat_core.c +++ b/net/ipv4/netfilter/nf_nat_core.c | |||
| @@ -47,26 +47,6 @@ __nf_nat_proto_find(u_int8_t protonum) | |||
| 47 | return rcu_dereference(nf_nat_protos[protonum]); | 47 | return rcu_dereference(nf_nat_protos[protonum]); |
| 48 | } | 48 | } |
| 49 | 49 | ||
| 50 | static const struct nf_nat_protocol * | ||
| 51 | nf_nat_proto_find_get(u_int8_t protonum) | ||
| 52 | { | ||
| 53 | const struct nf_nat_protocol *p; | ||
| 54 | |||
| 55 | rcu_read_lock(); | ||
| 56 | p = __nf_nat_proto_find(protonum); | ||
| 57 | if (!try_module_get(p->me)) | ||
| 58 | p = &nf_nat_unknown_protocol; | ||
| 59 | rcu_read_unlock(); | ||
| 60 | |||
| 61 | return p; | ||
| 62 | } | ||
| 63 | |||
| 64 | static void | ||
| 65 | nf_nat_proto_put(const struct nf_nat_protocol *p) | ||
| 66 | { | ||
| 67 | module_put(p->me); | ||
| 68 | } | ||
| 69 | |||
| 70 | /* We keep an extra hash for each conntrack, for fast searching. */ | 50 | /* We keep an extra hash for each conntrack, for fast searching. */ |
| 71 | static inline unsigned int | 51 | static inline unsigned int |
| 72 | hash_by_src(const struct net *net, u16 zone, | 52 | hash_by_src(const struct net *net, u16 zone, |
| @@ -588,6 +568,26 @@ static struct nf_ct_ext_type nat_extend __read_mostly = { | |||
| 588 | #include <linux/netfilter/nfnetlink.h> | 568 | #include <linux/netfilter/nfnetlink.h> |
| 589 | #include <linux/netfilter/nfnetlink_conntrack.h> | 569 | #include <linux/netfilter/nfnetlink_conntrack.h> |
| 590 | 570 | ||
| 571 | static const struct nf_nat_protocol * | ||
| 572 | nf_nat_proto_find_get(u_int8_t protonum) | ||
| 573 | { | ||
| 574 | const struct nf_nat_protocol *p; | ||
| 575 | |||
| 576 | rcu_read_lock(); | ||
| 577 | p = __nf_nat_proto_find(protonum); | ||
| 578 | if (!try_module_get(p->me)) | ||
| 579 | p = &nf_nat_unknown_protocol; | ||
| 580 | rcu_read_unlock(); | ||
| 581 | |||
| 582 | return p; | ||
| 583 | } | ||
| 584 | |||
| 585 | static void | ||
| 586 | nf_nat_proto_put(const struct nf_nat_protocol *p) | ||
| 587 | { | ||
| 588 | module_put(p->me); | ||
| 589 | } | ||
| 590 | |||
| 591 | static const struct nla_policy protonat_nla_policy[CTA_PROTONAT_MAX+1] = { | 591 | static const struct nla_policy protonat_nla_policy[CTA_PROTONAT_MAX+1] = { |
| 592 | [CTA_PROTONAT_PORT_MIN] = { .type = NLA_U16 }, | 592 | [CTA_PROTONAT_PORT_MIN] = { .type = NLA_U16 }, |
| 593 | [CTA_PROTONAT_PORT_MAX] = { .type = NLA_U16 }, | 593 | [CTA_PROTONAT_PORT_MAX] = { .type = NLA_U16 }, |
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c index 51df035897e7..455582384ece 100644 --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c | |||
| @@ -1137,6 +1137,7 @@ static int get_info(struct net *net, void __user *user, | |||
| 1137 | private = &tmp; | 1137 | private = &tmp; |
| 1138 | } | 1138 | } |
| 1139 | #endif | 1139 | #endif |
| 1140 | memset(&info, 0, sizeof(info)); | ||
| 1140 | info.valid_hooks = t->valid_hooks; | 1141 | info.valid_hooks = t->valid_hooks; |
| 1141 | memcpy(info.hook_entry, private->hook_entry, | 1142 | memcpy(info.hook_entry, private->hook_entry, |
| 1142 | sizeof(info.hook_entry)); | 1143 | sizeof(info.hook_entry)); |
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 25661f968f3f..fc328339be99 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
| @@ -2741,6 +2741,7 @@ static void __net_exit ip6_route_net_exit(struct net *net) | |||
| 2741 | kfree(net->ipv6.ip6_prohibit_entry); | 2741 | kfree(net->ipv6.ip6_prohibit_entry); |
| 2742 | kfree(net->ipv6.ip6_blk_hole_entry); | 2742 | kfree(net->ipv6.ip6_blk_hole_entry); |
| 2743 | #endif | 2743 | #endif |
| 2744 | dst_entries_destroy(&net->ipv6.ip6_dst_ops); | ||
| 2744 | } | 2745 | } |
| 2745 | 2746 | ||
| 2746 | static struct pernet_operations ip6_route_net_ops = { | 2747 | static struct pernet_operations ip6_route_net_ops = { |
| @@ -2832,5 +2833,6 @@ void ip6_route_cleanup(void) | |||
| 2832 | xfrm6_fini(); | 2833 | xfrm6_fini(); |
| 2833 | fib6_gc_cleanup(); | 2834 | fib6_gc_cleanup(); |
| 2834 | unregister_pernet_subsys(&ip6_route_net_ops); | 2835 | unregister_pernet_subsys(&ip6_route_net_ops); |
| 2836 | dst_entries_destroy(&ip6_dst_blackhole_ops); | ||
| 2835 | kmem_cache_destroy(ip6_dst_ops_template.kmem_cachep); | 2837 | kmem_cache_destroy(ip6_dst_ops_template.kmem_cachep); |
| 2836 | } | 2838 | } |
diff --git a/net/l2tp/l2tp_debugfs.c b/net/l2tp/l2tp_debugfs.c index 104ec3b283d4..b8dbae82fab8 100644 --- a/net/l2tp/l2tp_debugfs.c +++ b/net/l2tp/l2tp_debugfs.c | |||
| @@ -249,7 +249,7 @@ static int l2tp_dfs_seq_open(struct inode *inode, struct file *file) | |||
| 249 | struct seq_file *seq; | 249 | struct seq_file *seq; |
| 250 | int rc = -ENOMEM; | 250 | int rc = -ENOMEM; |
| 251 | 251 | ||
| 252 | pd = kzalloc(GFP_KERNEL, sizeof(*pd)); | 252 | pd = kzalloc(sizeof(*pd), GFP_KERNEL); |
| 253 | if (pd == NULL) | 253 | if (pd == NULL) |
| 254 | goto out; | 254 | goto out; |
| 255 | 255 | ||
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c index 1eacf8d9966a..27a5ea6b6a0f 100644 --- a/net/netfilter/nf_conntrack_core.c +++ b/net/netfilter/nf_conntrack_core.c | |||
| @@ -1312,7 +1312,8 @@ void *nf_ct_alloc_hashtable(unsigned int *sizep, int *vmalloced, int nulls) | |||
| 1312 | if (!hash) { | 1312 | if (!hash) { |
| 1313 | *vmalloced = 1; | 1313 | *vmalloced = 1; |
| 1314 | printk(KERN_WARNING "nf_conntrack: falling back to vmalloc.\n"); | 1314 | printk(KERN_WARNING "nf_conntrack: falling back to vmalloc.\n"); |
| 1315 | hash = __vmalloc(sz, GFP_KERNEL | __GFP_ZERO, PAGE_KERNEL); | 1315 | hash = __vmalloc(sz, GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO, |
| 1316 | PAGE_KERNEL); | ||
| 1316 | } | 1317 | } |
| 1317 | 1318 | ||
| 1318 | if (hash && nulls) | 1319 | if (hash && nulls) |
diff --git a/net/netfilter/nf_conntrack_proto.c b/net/netfilter/nf_conntrack_proto.c index ed6d92958023..dc7bb74110df 100644 --- a/net/netfilter/nf_conntrack_proto.c +++ b/net/netfilter/nf_conntrack_proto.c | |||
| @@ -292,6 +292,12 @@ int nf_conntrack_l4proto_register(struct nf_conntrack_l4proto *l4proto) | |||
| 292 | 292 | ||
| 293 | for (i = 0; i < MAX_NF_CT_PROTO; i++) | 293 | for (i = 0; i < MAX_NF_CT_PROTO; i++) |
| 294 | proto_array[i] = &nf_conntrack_l4proto_generic; | 294 | proto_array[i] = &nf_conntrack_l4proto_generic; |
| 295 | |||
| 296 | /* Before making proto_array visible to lockless readers, | ||
| 297 | * we must make sure its content is committed to memory. | ||
| 298 | */ | ||
| 299 | smp_wmb(); | ||
| 300 | |||
| 295 | nf_ct_protos[l4proto->l3proto] = proto_array; | 301 | nf_ct_protos[l4proto->l3proto] = proto_array; |
| 296 | } else if (nf_ct_protos[l4proto->l3proto][l4proto->l4proto] != | 302 | } else if (nf_ct_protos[l4proto->l3proto][l4proto->l4proto] != |
| 297 | &nf_conntrack_l4proto_generic) { | 303 | &nf_conntrack_l4proto_generic) { |
diff --git a/net/rds/loop.c b/net/rds/loop.c index c390156b426f..aeec1d483b17 100644 --- a/net/rds/loop.c +++ b/net/rds/loop.c | |||
| @@ -134,8 +134,12 @@ static int rds_loop_conn_alloc(struct rds_connection *conn, gfp_t gfp) | |||
| 134 | static void rds_loop_conn_free(void *arg) | 134 | static void rds_loop_conn_free(void *arg) |
| 135 | { | 135 | { |
| 136 | struct rds_loop_connection *lc = arg; | 136 | struct rds_loop_connection *lc = arg; |
| 137 | unsigned long flags; | ||
| 138 | |||
| 137 | rdsdebug("lc %p\n", lc); | 139 | rdsdebug("lc %p\n", lc); |
| 140 | spin_lock_irqsave(&loop_conns_lock, flags); | ||
| 138 | list_del(&lc->loop_node); | 141 | list_del(&lc->loop_node); |
| 142 | spin_unlock_irqrestore(&loop_conns_lock, flags); | ||
| 139 | kfree(lc); | 143 | kfree(lc); |
| 140 | } | 144 | } |
| 141 | 145 | ||
diff --git a/net/rds/tcp.c b/net/rds/tcp.c index 08a8c6cf2d10..8e0a32001c90 100644 --- a/net/rds/tcp.c +++ b/net/rds/tcp.c | |||
| @@ -221,7 +221,13 @@ static int rds_tcp_conn_alloc(struct rds_connection *conn, gfp_t gfp) | |||
| 221 | static void rds_tcp_conn_free(void *arg) | 221 | static void rds_tcp_conn_free(void *arg) |
| 222 | { | 222 | { |
| 223 | struct rds_tcp_connection *tc = arg; | 223 | struct rds_tcp_connection *tc = arg; |
| 224 | unsigned long flags; | ||
| 224 | rdsdebug("freeing tc %p\n", tc); | 225 | rdsdebug("freeing tc %p\n", tc); |
| 226 | |||
| 227 | spin_lock_irqsave(&rds_tcp_conn_lock, flags); | ||
| 228 | list_del(&tc->t_tcp_node); | ||
| 229 | spin_unlock_irqrestore(&rds_tcp_conn_lock, flags); | ||
| 230 | |||
| 225 | kmem_cache_free(rds_tcp_conn_slab, tc); | 231 | kmem_cache_free(rds_tcp_conn_slab, tc); |
| 226 | } | 232 | } |
| 227 | 233 | ||
diff --git a/net/sched/cls_cgroup.c b/net/sched/cls_cgroup.c index 37dff78e9cb1..d49c40fb7e09 100644 --- a/net/sched/cls_cgroup.c +++ b/net/sched/cls_cgroup.c | |||
| @@ -34,8 +34,6 @@ struct cgroup_subsys net_cls_subsys = { | |||
| 34 | .populate = cgrp_populate, | 34 | .populate = cgrp_populate, |
| 35 | #ifdef CONFIG_NET_CLS_CGROUP | 35 | #ifdef CONFIG_NET_CLS_CGROUP |
| 36 | .subsys_id = net_cls_subsys_id, | 36 | .subsys_id = net_cls_subsys_id, |
| 37 | #else | ||
| 38 | #define net_cls_subsys_id net_cls_subsys.subsys_id | ||
| 39 | #endif | 37 | #endif |
| 40 | .module = THIS_MODULE, | 38 | .module = THIS_MODULE, |
| 41 | }; | 39 | }; |
diff --git a/net/sched/em_text.c b/net/sched/em_text.c index 763253257411..ea8f566e720c 100644 --- a/net/sched/em_text.c +++ b/net/sched/em_text.c | |||
| @@ -103,7 +103,8 @@ retry: | |||
| 103 | 103 | ||
| 104 | static void em_text_destroy(struct tcf_proto *tp, struct tcf_ematch *m) | 104 | static void em_text_destroy(struct tcf_proto *tp, struct tcf_ematch *m) |
| 105 | { | 105 | { |
| 106 | textsearch_destroy(EM_TEXT_PRIV(m)->config); | 106 | if (EM_TEXT_PRIV(m) && EM_TEXT_PRIV(m)->config) |
| 107 | textsearch_destroy(EM_TEXT_PRIV(m)->config); | ||
| 107 | } | 108 | } |
| 108 | 109 | ||
| 109 | static int em_text_dump(struct sk_buff *skb, struct tcf_ematch *m) | 110 | static int em_text_dump(struct sk_buff *skb, struct tcf_ematch *m) |
diff --git a/net/x25/x25_facilities.c b/net/x25/x25_facilities.c index 771bab00754b..3a8c4c419cd4 100644 --- a/net/x25/x25_facilities.c +++ b/net/x25/x25_facilities.c | |||
| @@ -134,15 +134,15 @@ int x25_parse_facilities(struct sk_buff *skb, struct x25_facilities *facilities, | |||
| 134 | case X25_FAC_CLASS_D: | 134 | case X25_FAC_CLASS_D: |
| 135 | switch (*p) { | 135 | switch (*p) { |
| 136 | case X25_FAC_CALLING_AE: | 136 | case X25_FAC_CALLING_AE: |
| 137 | if (p[1] > X25_MAX_DTE_FACIL_LEN) | 137 | if (p[1] > X25_MAX_DTE_FACIL_LEN || p[1] <= 1) |
| 138 | break; | 138 | return 0; |
| 139 | dte_facs->calling_len = p[2]; | 139 | dte_facs->calling_len = p[2]; |
| 140 | memcpy(dte_facs->calling_ae, &p[3], p[1] - 1); | 140 | memcpy(dte_facs->calling_ae, &p[3], p[1] - 1); |
| 141 | *vc_fac_mask |= X25_MASK_CALLING_AE; | 141 | *vc_fac_mask |= X25_MASK_CALLING_AE; |
| 142 | break; | 142 | break; |
| 143 | case X25_FAC_CALLED_AE: | 143 | case X25_FAC_CALLED_AE: |
| 144 | if (p[1] > X25_MAX_DTE_FACIL_LEN) | 144 | if (p[1] > X25_MAX_DTE_FACIL_LEN || p[1] <= 1) |
| 145 | break; | 145 | return 0; |
| 146 | dte_facs->called_len = p[2]; | 146 | dte_facs->called_len = p[2]; |
| 147 | memcpy(dte_facs->called_ae, &p[3], p[1] - 1); | 147 | memcpy(dte_facs->called_ae, &p[3], p[1] - 1); |
| 148 | *vc_fac_mask |= X25_MASK_CALLED_AE; | 148 | *vc_fac_mask |= X25_MASK_CALLED_AE; |
diff --git a/net/x25/x25_in.c b/net/x25/x25_in.c index 63178961efac..f729f022be69 100644 --- a/net/x25/x25_in.c +++ b/net/x25/x25_in.c | |||
| @@ -119,6 +119,8 @@ static int x25_state1_machine(struct sock *sk, struct sk_buff *skb, int frametyp | |||
| 119 | &x25->vc_facil_mask); | 119 | &x25->vc_facil_mask); |
| 120 | if (len > 0) | 120 | if (len > 0) |
| 121 | skb_pull(skb, len); | 121 | skb_pull(skb, len); |
| 122 | else | ||
| 123 | return -1; | ||
| 122 | /* | 124 | /* |
| 123 | * Copy any Call User Data. | 125 | * Copy any Call User Data. |
| 124 | */ | 126 | */ |
