diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/asm-blackfin/page.h | 1 | ||||
-rw-r--r-- | include/asm-h8300/page.h | 1 | ||||
-rw-r--r-- | include/asm-m68knommu/page.h | 1 | ||||
-rw-r--r-- | include/asm-s390/a.out.h | 32 | ||||
-rw-r--r-- | include/asm-s390/bitops.h | 4 | ||||
-rw-r--r-- | include/asm-s390/elf.h | 22 | ||||
-rw-r--r-- | include/asm-s390/mmu.h | 9 | ||||
-rw-r--r-- | include/asm-s390/mmu_context.h | 20 | ||||
-rw-r--r-- | include/asm-s390/page.h | 36 | ||||
-rw-r--r-- | include/asm-s390/pgalloc.h | 116 | ||||
-rw-r--r-- | include/asm-s390/pgtable.h | 191 | ||||
-rw-r--r-- | include/asm-s390/processor.h | 45 | ||||
-rw-r--r-- | include/asm-s390/tlb.h | 49 | ||||
-rw-r--r-- | include/asm-s390/tlbflush.h | 11 | ||||
-rw-r--r-- | include/asm-s390/unistd.h | 5 | ||||
-rw-r--r-- | include/asm-v850/page.h | 1 | ||||
-rw-r--r-- | include/linux/ext4_fs.h | 7 | ||||
-rw-r--r-- | include/linux/memcontrol.h | 10 | ||||
-rw-r--r-- | include/linux/memstick.h | 299 | ||||
-rw-r--r-- | include/linux/swapops.h | 2 | ||||
-rw-r--r-- | include/linux/thermal.h | 23 | ||||
-rw-r--r-- | include/linux/tifm.h | 4 |
22 files changed, 615 insertions, 274 deletions
diff --git a/include/asm-blackfin/page.h b/include/asm-blackfin/page.h index d5c9d143378..c7db0220fbd 100644 --- a/include/asm-blackfin/page.h +++ b/include/asm-blackfin/page.h @@ -39,6 +39,7 @@ typedef struct { typedef struct { unsigned long pgprot; } pgprot_t; +typedef struct page *pgtable_t; #define pte_val(x) ((x).pte) #define pmd_val(x) ((&x)->pmd[0]) diff --git a/include/asm-h8300/page.h b/include/asm-h8300/page.h index a8349244913..d6a3eaf3b27 100644 --- a/include/asm-h8300/page.h +++ b/include/asm-h8300/page.h @@ -31,6 +31,7 @@ typedef struct { unsigned long pte; } pte_t; typedef struct { unsigned long pmd[16]; } pmd_t; typedef struct { unsigned long pgd; } pgd_t; typedef struct { unsigned long pgprot; } pgprot_t; +typedef struct page *pgtable_t; #define pte_val(x) ((x).pte) #define pmd_val(x) ((&x)->pmd[0]) diff --git a/include/asm-m68knommu/page.h b/include/asm-m68knommu/page.h index 6af480c7f29..1e82ebb7d64 100644 --- a/include/asm-m68knommu/page.h +++ b/include/asm-m68knommu/page.h @@ -31,6 +31,7 @@ typedef struct { unsigned long pte; } pte_t; typedef struct { unsigned long pmd[16]; } pmd_t; typedef struct { unsigned long pgd; } pgd_t; typedef struct { unsigned long pgprot; } pgprot_t; +typedef struct page *pgtable_t; #define pte_val(x) ((x).pte) #define pmd_val(x) ((&x)->pmd[0]) diff --git a/include/asm-s390/a.out.h b/include/asm-s390/a.out.h deleted file mode 100644 index 8d6bd9c2952..00000000000 --- a/include/asm-s390/a.out.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * include/asm-s390/a.out.h - * - * S390 version - * Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation - * - * Derived from "include/asm-i386/a.out.h" - * Copyright (C) 1992, Linus Torvalds - * - * I don't think we'll ever need a.out ... - */ - -#ifndef __S390_A_OUT_H__ -#define __S390_A_OUT_H__ - -struct exec -{ - unsigned long a_info; /* Use macros N_MAGIC, etc for access */ - unsigned a_text; /* length of text, in bytes */ - unsigned a_data; /* length of data, in bytes */ - unsigned a_bss; /* length of uninitialized data area for file, in bytes */ - unsigned a_syms; /* length of symbol table data in file, in bytes */ - unsigned a_entry; /* start address */ - unsigned a_trsize; /* length of relocation info for text, in bytes */ - unsigned a_drsize; /* length of relocation info for data, in bytes */ -}; - -#define N_TRSIZE(a) ((a).a_trsize) -#define N_DRSIZE(a) ((a).a_drsize) -#define N_SYMSIZE(a) ((a).a_syms) - -#endif /* __A_OUT_GNU_H__ */ diff --git a/include/asm-s390/bitops.h b/include/asm-s390/bitops.h index 882db054110..ab83c844d04 100644 --- a/include/asm-s390/bitops.h +++ b/include/asm-s390/bitops.h @@ -472,7 +472,7 @@ static inline unsigned long __ffz_word_loop(const unsigned long *addr, " brct %1,0b\n" "1:\n" #endif - : "+a" (bytes), "+d" (size) + : "+&a" (bytes), "+&d" (size) : "d" (-1UL), "a" (addr), "m" (*(addrtype *) addr) : "cc" ); return bytes; @@ -507,7 +507,7 @@ static inline unsigned long __ffs_word_loop(const unsigned long *addr, " brct %1,0b\n" "1:\n" #endif - : "+a" (bytes), "+a" (size) + : "+&a" (bytes), "+&a" (size) : "d" (0UL), "a" (addr), "m" (*(addrtype *) addr) : "cc" ); return bytes; diff --git a/include/asm-s390/elf.h b/include/asm-s390/elf.h index b73a424d0f9..b3ac262c458 100644 --- a/include/asm-s390/elf.h +++ b/include/asm-s390/elf.h @@ -115,6 +115,7 @@ typedef s390_regs elf_gregset_t; #include <linux/sched.h> /* for task_struct */ #include <asm/system.h> /* for save_access_regs */ +#include <asm/mmu_context.h> /* * This is used to ensure we don't load something for the wrong architecture. @@ -137,14 +138,7 @@ typedef s390_regs elf_gregset_t; use of this is to invoke "./ld.so someprog" to test out a new version of the loader. We need to make sure that it is out of the way of the program that it will "exec", and that there is sufficient room for the brk. */ - -#ifndef __s390x__ -#define ELF_ET_DYN_BASE ((TASK_SIZE & 0x80000000) \ - ? TASK_SIZE / 3 * 2 \ - : 2 * TASK_SIZE / 3) -#else /* __s390x__ */ -#define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2) -#endif /* __s390x__ */ +#define ELF_ET_DYN_BASE (STACK_TOP / 3 * 2) /* Wow, the "main" arch needs arch dependent functions too.. :) */ @@ -214,4 +208,16 @@ do { \ } while (0) #endif /* __s390x__ */ +/* + * An executable for which elf_read_implies_exec() returns TRUE will + * have the READ_IMPLIES_EXEC personality flag set automatically. + */ +#define elf_read_implies_exec(ex, executable_stack) \ +({ \ + if (current->mm->context.noexec && \ + executable_stack != EXSTACK_DISABLE_X) \ + disable_noexec(current->mm, current); \ + current->mm->context.noexec == 0; \ +}) + #endif diff --git a/include/asm-s390/mmu.h b/include/asm-s390/mmu.h index ccd36d26615..1698e29c5b2 100644 --- a/include/asm-s390/mmu.h +++ b/include/asm-s390/mmu.h @@ -1,7 +1,12 @@ #ifndef __MMU_H #define __MMU_H -/* Default "unsigned long" context */ -typedef unsigned long mm_context_t; +typedef struct { + struct list_head crst_list; + struct list_head pgtable_list; + unsigned long asce_bits; + unsigned long asce_limit; + int noexec; +} mm_context_t; #endif diff --git a/include/asm-s390/mmu_context.h b/include/asm-s390/mmu_context.h index a77d4ba3c8e..b5a34c6f91a 100644 --- a/include/asm-s390/mmu_context.h +++ b/include/asm-s390/mmu_context.h @@ -10,15 +10,19 @@ #define __S390_MMU_CONTEXT_H #include <asm/pgalloc.h> +#include <asm/uaccess.h> #include <asm-generic/mm_hooks.h> static inline int init_new_context(struct task_struct *tsk, struct mm_struct *mm) { - mm->context = _ASCE_TABLE_LENGTH | _ASCE_USER_BITS; + mm->context.asce_bits = _ASCE_TABLE_LENGTH | _ASCE_USER_BITS; #ifdef CONFIG_64BIT - mm->context |= _ASCE_TYPE_REGION3; + mm->context.asce_bits |= _ASCE_TYPE_REGION3; #endif + mm->context.noexec = s390_noexec; + mm->context.asce_limit = STACK_TOP_MAX; + crst_table_init((unsigned long *) mm->pgd, pgd_entry_type(mm)); return 0; } @@ -32,24 +36,25 @@ static inline int init_new_context(struct task_struct *tsk, static inline void update_mm(struct mm_struct *mm, struct task_struct *tsk) { - S390_lowcore.user_asce = mm->context | __pa(mm->pgd); + pgd_t *pgd = mm->pgd; + + S390_lowcore.user_asce = mm->context.asce_bits | __pa(pgd); if (switch_amode) { /* Load primary space page table origin. */ - pgd_t *shadow_pgd = get_shadow_table(mm->pgd) ? : mm->pgd; - S390_lowcore.user_exec_asce = mm->context | __pa(shadow_pgd); + pgd = mm->context.noexec ? get_shadow_table(pgd) : pgd; + S390_lowcore.user_exec_asce = mm->context.asce_bits | __pa(pgd); asm volatile(LCTL_OPCODE" 1,1,%0\n" : : "m" (S390_lowcore.user_exec_asce) ); } else /* Load home space page table origin. */ asm volatile(LCTL_OPCODE" 13,13,%0" : : "m" (S390_lowcore.user_asce) ); + set_fs(current->thread.mm_segment); } static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, struct task_struct *tsk) { - if (unlikely(prev == next)) - return; cpu_set(smp_processor_id(), next->cpu_vm_mask); update_mm(next, tsk); } @@ -61,7 +66,6 @@ static inline void activate_mm(struct mm_struct *prev, struct mm_struct *next) { switch_mm(prev, next, current); - set_fs(current->thread.mm_segment); } #endif /* __S390_MMU_CONTEXT_H */ diff --git a/include/asm-s390/page.h b/include/asm-s390/page.h index 7f29a981f48..fe7f92b6ae6 100644 --- a/include/asm-s390/page.h +++ b/include/asm-s390/page.h @@ -74,43 +74,17 @@ static inline void copy_page(void *to, void *from) typedef struct { unsigned long pgprot; } pgprot_t; typedef struct { unsigned long pte; } pte_t; - -#define pte_val(x) ((x).pte) -#define pgprot_val(x) ((x).pgprot) - -#ifndef __s390x__ - typedef struct { unsigned long pmd; } pmd_t; typedef struct { unsigned long pud; } pud_t; -typedef struct { - unsigned long pgd0; - unsigned long pgd1; - unsigned long pgd2; - unsigned long pgd3; - } pgd_t; - -#define pmd_val(x) ((x).pmd) -#define pud_val(x) ((x).pud) -#define pgd_val(x) ((x).pgd0) - -#else /* __s390x__ */ - -typedef struct { - unsigned long pmd0; - unsigned long pmd1; - } pmd_t; -typedef struct { unsigned long pud; } pud_t; typedef struct { unsigned long pgd; } pgd_t; +typedef pte_t *pgtable_t; -#define pmd_val(x) ((x).pmd0) -#define pmd_val1(x) ((x).pmd1) +#define pgprot_val(x) ((x).pgprot) +#define pte_val(x) ((x).pte) +#define pmd_val(x) ((x).pmd) #define pud_val(x) ((x).pud) #define pgd_val(x) ((x).pgd) -#endif /* __s390x__ */ - -typedef struct page *pgtable_t; - #define __pte(x) ((pte_t) { (x) } ) #define __pmd(x) ((pmd_t) { (x) } ) #define __pgd(x) ((pgd_t) { (x) } ) @@ -167,7 +141,7 @@ static inline int pfn_valid(unsigned long pfn) #define page_to_phys(page) (page_to_pfn(page) << PAGE_SHIFT) #define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT) -#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \ +#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | \ VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) #include <asm-generic/memory_model.h> diff --git a/include/asm-s390/pgalloc.h b/include/asm-s390/pgalloc.h index 900d44807e1..f5b2bf3d7c1 100644 --- a/include/asm-s390/pgalloc.h +++ b/include/asm-s390/pgalloc.h @@ -20,10 +20,11 @@ #define check_pgt_cache() do {} while (0) unsigned long *crst_table_alloc(struct mm_struct *, int); -void crst_table_free(unsigned long *); +void crst_table_free(struct mm_struct *, unsigned long *); -unsigned long *page_table_alloc(int); -void page_table_free(unsigned long *); +unsigned long *page_table_alloc(struct mm_struct *); +void page_table_free(struct mm_struct *, unsigned long *); +void disable_noexec(struct mm_struct *, struct task_struct *); static inline void clear_table(unsigned long *s, unsigned long val, size_t n) { @@ -72,23 +73,49 @@ static inline unsigned long pgd_entry_type(struct mm_struct *mm) static inline unsigned long pgd_entry_type(struct mm_struct *mm) { - return _REGION3_ENTRY_EMPTY; + if (mm->context.asce_limit <= (1UL << 31)) + return _SEGMENT_ENTRY_EMPTY; + if (mm->context.asce_limit <= (1UL << 42)) + return _REGION3_ENTRY_EMPTY; + return _REGION2_ENTRY_EMPTY; } -#define pud_alloc_one(mm,address) ({ BUG(); ((pud_t *)2); }) -#define pud_free(mm, x) do { } while (0) +int crst_table_upgrade(struct mm_struct *, unsigned long limit); +void crst_table_downgrade(struct mm_struct *, unsigned long limit); + +static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long address) +{ + unsigned long *table = crst_table_alloc(mm, mm->context.noexec); + if (table) + crst_table_init(table, _REGION3_ENTRY_EMPTY); + return (pud_t *) table; +} +#define pud_free(mm, pud) crst_table_free(mm, (unsigned long *) pud) static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long vmaddr) { - unsigned long *crst = crst_table_alloc(mm, s390_noexec); - if (crst) - crst_table_init(crst, _SEGMENT_ENTRY_EMPTY); - return (pmd_t *) crst; + unsigned long *table = crst_table_alloc(mm, mm->context.noexec); + if (table) + crst_table_init(table, _SEGMENT_ENTRY_EMPTY); + return (pmd_t *) table; } -#define pmd_free(mm, pmd) crst_table_free((unsigned long *)pmd) +#define pmd_free(mm, pmd) crst_table_free(mm, (unsigned long *) pmd) -#define pgd_populate(mm, pgd, pud) BUG() -#define pgd_populate_kernel(mm, pgd, pud) BUG() +static inline void pgd_populate_kernel(struct mm_struct *mm, + pgd_t *pgd, pud_t *pud) +{ + pgd_val(*pgd) = _REGION2_ENTRY | __pa(pud); +} + +static inline void pgd_populate(struct mm_struct *mm, pgd_t *pgd, pud_t *pud) +{ + pgd_populate_kernel(mm, pgd, pud); + if (mm->context.noexec) { + pgd = get_shadow_table(pgd); + pud = get_shadow_table(pud); + pgd_populate_kernel(mm, pgd, pud); + } +} static inline void pud_populate_kernel(struct mm_struct *mm, pud_t *pud, pmd_t *pmd) @@ -98,63 +125,50 @@ static inline void pud_populate_kernel(struct mm_struct *mm, static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd) { - pud_t *shadow_pud = get_shadow_table(pud); - pmd_t *shadow_pmd = get_shadow_table(pmd); - - if (shadow_pud && shadow_pmd) - pud_populate_kernel(mm, shadow_pud, shadow_pmd); pud_populate_kernel(mm, pud, pmd); + if (mm->context.noexec) { + pud = get_shadow_table(pud); + pmd = get_shadow_table(pmd); + pud_populate_kernel(mm, pud, pmd); + } } #endif /* __s390x__ */ static inline pgd_t *pgd_alloc(struct mm_struct *mm) { - unsigned long *crst = crst_table_alloc(mm, s390_noexec); - if (crst) - crst_table_init(crst, pgd_entry_type(mm)); - return (pgd_t *) crst; + INIT_LIST_HEAD(&mm->context.crst_list); + INIT_LIST_HEAD(&mm->context.pgtable_list); + return (pgd_t *) crst_table_alloc(mm, s390_noexec); } -#define pgd_free(mm, pgd) crst_table_free((unsigned long *) pgd) +#define pgd_free(mm, pgd) crst_table_free(mm, (unsigned long *) pgd) -static inline void -pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd, pte_t *pte) +static inline void pmd_populate_kernel(struct mm_struct *mm, + pmd_t *pmd, pte_t *pte) { -#ifndef __s390x__ - pmd_val(pmd[0]) = _SEGMENT_ENTRY + __pa(pte); - pmd_val(pmd[1]) = _SEGMENT_ENTRY + __pa(pte+256); - pmd_val(pmd[2]) = _SEGMENT_ENTRY + __pa(pte+512); - pmd_val(pmd[3]) = _SEGMENT_ENTRY + __pa(pte+768); -#else /* __s390x__ */ pmd_val(*pmd) = _SEGMENT_ENTRY + __pa(pte); - pmd_val1(*pmd) = _SEGMENT_ENTRY + __pa(pte+256); -#endif /* __s390x__ */ } -static inline void -pmd_populate(struct mm_struct *mm, pmd_t *pmd, pgtable_t page) +static inline void pmd_populate(struct mm_struct *mm, + pmd_t *pmd, pgtable_t pte) { - pte_t *pte = (pte_t *)page_to_phys(page); - pmd_t *shadow_pmd = get_shadow_table(pmd); - pte_t *shadow_pte = get_shadow_pte(pte); - pmd_populate_kernel(mm, pmd, pte); - if (shadow_pmd && shadow_pte) - pmd_populate_kernel(mm, shadow_pmd, shadow_pte); + if (mm->context.noexec) { + pmd = get_shadow_table(pmd); + pmd_populate_kernel(mm, pmd, pte + PTRS_PER_PTE); + } } -#define pmd_pgtable(pmd) pmd_page(pmd) + +#define pmd_pgtable(pmd) \ + (pgtable_t)(pmd_val(pmd) & -sizeof(pte_t)*PTRS_PER_PTE) /* * page table entry allocation/free routines. */ -#define pte_alloc_one_kernel(mm, vmaddr) \ - ((pte_t *) page_table_alloc(s390_noexec)) -#define pte_alloc_one(mm, vmaddr) \ - virt_to_page(page_table_alloc(s390_noexec)) - -#define pte_free_kernel(mm, pte) \ - page_table_free((unsigned long *) pte) -#define pte_free(mm, pte) \ - page_table_free((unsigned long *) page_to_phys((struct page *) pte)) +#define pte_alloc_one_kernel(mm, vmaddr) ((pte_t *) page_table_alloc(mm)) +#define pte_alloc_one(mm, vmaddr) ((pte_t *) page_table_alloc(mm)) + +#define pte_free_kernel(mm, pte) page_table_free(mm, (unsigned long *) pte) +#define pte_free(mm, pte) page_table_free(mm, (unsigned long *) pte) #endif /* _S390_PGALLOC_H */ diff --git a/include/asm-s390/pgtable.h b/include/asm-s390/pgtable.h index 3f520754e71..65154dc9a9e 100644 --- a/include/asm-s390/pgtable.h +++ b/include/asm-s390/pgtable.h @@ -57,21 +57,21 @@ extern char empty_zero_page[PAGE_SIZE]; * PGDIR_SHIFT determines what a third-level page table entry can map */ #ifndef __s390x__ -# define PMD_SHIFT 22 -# define PUD_SHIFT 22 -# define PGDIR_SHIFT 22 +# define PMD_SHIFT 20 +# define PUD_SHIFT 20 +# define PGDIR_SHIFT 20 #else /* __s390x__ */ -# define PMD_SHIFT 21 +# define PMD_SHIFT 20 # define PUD_SHIFT 31 -# define PGDIR_SHIFT 31 +# define PGDIR_SHIFT 42 #endif /* __s390x__ */ #define PMD_SIZE (1UL << PMD_SHIFT) #define PMD_MASK (~(PMD_SIZE-1)) #define PUD_SIZE (1UL << PUD_SHIFT) #define PUD_MASK (~(PUD_SIZE-1)) -#define PGDIR_SIZE (1UL << PGDIR_SHIFT) -#define PGDIR_MASK (~(PGDIR_SIZE-1)) +#define PGDIR_SIZE (1UL << PGDIR_SHIFT) +#define PGDIR_MASK (~(PGDIR_SIZE-1)) /* * entries per page directory level: the S390 is two-level, so @@ -79,17 +79,15 @@ extern char empty_zero_page[PAGE_SIZE]; * for S390 segment-table entries are combined to one PGD * that leads to 1024 pte per pgd */ +#define PTRS_PER_PTE 256 #ifndef __s390x__ -# define PTRS_PER_PTE 1024 -# define PTRS_PER_PMD 1 -# define PTRS_PER_PUD 1 -# define PTRS_PER_PGD 512 +#define PTRS_PER_PMD 1 +#define PTRS_PER_PUD 1 #else /* __s390x__ */ -# define PTRS_PER_PTE 512 -# define PTRS_PER_PMD 1024 -# define PTRS_PER_PUD 1 -# define PTRS_PER_PGD 2048 +#define PTRS_PER_PMD 2048 +#define PTRS_PER_PUD 2048 #endif /* __s390x__ */ +#define PTRS_PER_PGD 2048 #define FIRST_USER_ADDRESS 0 @@ -127,8 +125,9 @@ extern char empty_zero_page[PAGE_SIZE]; * mapping. This needs to be calculated at compile time since the size of the * VMEM_MAP is static but the size of struct page can change. */ -#define VMEM_MAX_PHYS min(VMALLOC_START, ((VMEM_MAP_END - VMALLOC_END) / \ - sizeof(struct page) * PAGE_SIZE) & ~((16 << 20) - 1)) +#define VMEM_MAX_PAGES ((VMEM_MAP_END - VMALLOC_END) / sizeof(struct page)) +#define VMEM_MAX_PFN min(VMALLOC_START >> PAGE_SHIFT, VMEM_MAX_PAGES) +#define VMEM_MAX_PHYS ((VMEM_MAX_PFN << PAGE_SHIFT) & ~((16 << 20) - 1)) #define VMEM_MAP ((struct page *) VMALLOC_END) /* @@ -375,24 +374,6 @@ extern char empty_zero_page[PAGE_SIZE]; # define PxD_SHADOW_SHIFT 2 #endif /* __s390x__ */ -static inline struct page *get_shadow_page(struct page *page) -{ - if (s390_noexec && page->index) - return virt_to_page((void *)(addr_t) page->index); - return NULL; -} - -static inline void *get_shadow_pte(void *table) -{ - unsigned long addr, offset; - struct page *page; - - addr = (unsigned long) table; - offset = addr & (PAGE_SIZE - 1); - page = virt_to_page((void *)(addr ^ offset)); - return (void *)(addr_t)(page->index ? (page->index | offset) : 0UL); -} - static inline void *get_shadow_table(void *table) { unsigned long addr, offset; @@ -410,17 +391,16 @@ static inline void *get_shadow_table(void *table) * hook is made available. */ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr, - pte_t *pteptr, pte_t pteval) + pte_t *ptep, pte_t entry) { - pte_t *shadow_pte = get_shadow_pte(pteptr); - - *pteptr = pteval; - if (shadow_pte) { - if (!(pte_val(pteval) & _PAGE_INVALID) && - (pte_val(pteval) & _PAGE_SWX)) - pte_val(*shadow_pte) = pte_val(pteval) | _PAGE_RO; + *ptep = entry; + if (mm->context.noexec) { + if (!(pte_val(entry) & _PAGE_INVALID) && + (pte_val(entry) & _PAGE_SWX)) + pte_val(entry) |= _PAGE_RO; else - pte_val(*shadow_pte) = _PAGE_TYPE_EMPTY; + pte_val(entry) = _PAGE_TYPE_EMPTY; + ptep[PTRS_PER_PTE] = entry; } } @@ -439,24 +419,58 @@ static inline int pud_bad(pud_t pud) { return 0; } #else /* __s390x__ */ -static inline int pgd_present(pgd_t pgd) { return 1; } -static inline int pgd_none(pgd_t pgd) { return 0; } -static inline int pgd_bad(pgd_t pgd) { return 0; } +static inline int pgd_present(pgd_t pgd) +{ + if ((pgd_val(pgd) & _REGION_ENTRY_TYPE_MASK) < _REGION_ENTRY_TYPE_R2) + return 1; + return (pgd_val(pgd) & _REGION_ENTRY_ORIGIN) != 0UL; +} + +static inline int pgd_none(pgd_t pgd) +{ + if ((pgd_val(pgd) & _REGION_ENTRY_TYPE_MASK) < _REGION_ENTRY_TYPE_R2) + return 0; + return (pgd_val(pgd) & _REGION_ENTRY_INV) != 0UL; +} + +static inline int pgd_bad(pgd_t pgd) +{ + /* + * With dynamic page table levels the pgd can be a region table + * entry or a segment table entry. Check for the bit that are + * invalid for either table entry. + */ + unsigned long mask = + ~_SEGMENT_ENTRY_ORIGIN & ~_REGION_ENTRY_INV & + ~_REGION_ENTRY_TYPE_MASK & ~_REGION_ENTRY_LENGTH; + return (pgd_val(pgd) & mask) != 0; +} static inline int pud_present(pud_t pud) { + if ((pud_val(pud) & _REGION_ENTRY_TYPE_MASK) < _REGION_ENTRY_TYPE_R3) + return 1; return (pud_val(pud) & _REGION_ENTRY_ORIGIN) != 0UL; } static inline int pud_none(pud_t pud) { + if ((pud_val(pud) & _REGION_ENTRY_TYPE_MASK) < _REGION_ENTRY_TYPE_R3) + return 0; return (pud_val(pud) & _REGION_ENTRY_INV) != 0UL; } static inline int pud_bad(pud_t pud) { - unsigned long mask = ~_REGION_ENTRY_ORIGIN & ~_REGION_ENTRY_INV; - return (pud_val(pud) & mask) != _REGION3_ENTRY; + /* + * With dynamic page table levels the pud can be a region table + * entry or a segment table entry. Check for the bit that are + * invalid for either table entry. + */ + unsigned long mask = + ~_SEGMENT_ENTRY_ORIGIN & ~_REGION_ENTRY_INV & + ~_REGION_ENTRY_TYPE_MASK & ~_REGION_ENTRY_LENGTH; + return (pud_val(pud) & mask) != 0; } #endif /* __s390x__ */ @@ -535,24 +549,30 @@ static inline int pte_young(pte_t pte) #define pgd_clear(pgd) do { } while (0) #define pud_clear(pud) do { } while (0) -static inline void pmd_clear_kernel(pmd_t * pmdp) +#else /* __s390x__ */ + +static inline void pgd_clear_kernel(pgd_t * pgd) { - pmd_val(pmdp[0]) = _SEGMENT_ENTRY_EMPTY; - pmd_val(pmdp[1]) = _SEGMENT_ENTRY_EMPTY; - pmd_val(pmdp[2]) = _SEGMENT_ENTRY_EMPTY; - pmd_val(pmdp[3]) = _SEGMENT_ENTRY_EMPTY; + if ((pgd_val(*pgd) & _REGION_ENTRY_TYPE_MASK) == _REGION_ENTRY_TYPE_R2) + pgd_val(*pgd) = _REGION2_ENTRY_EMPTY; } -#else /* __s390x__ */ +static inline void pgd_clear(pgd_t * pgd) +{ + pgd_t *shadow = get_shadow_table(pgd); -#define pgd_clear(pgd) do { } while (0) + pgd_clear_kernel(pgd); + if (shadow) + pgd_clear_kernel(shadow); +} static inline void pud_clear_kernel(pud_t *pud) { - pud_val(*pud) = _REGION3_ENTRY_EMPTY; + if ((pud_val(*pud) & _REGION_ENTRY_TYPE_MASK) == _REGION_ENTRY_TYPE_R3) + pud_val(*pud) = _REGION3_ENTRY_EMPTY; } -static inline void pud_clear(pud_t * pud) +static inline void pud_clear(pud_t *pud) { pud_t *shadow = get_shadow_table(pud); @@ -561,30 +581,27 @@ static inline void pud_clear(pud_t * pud) pud_clear_kernel(shadow); } +#endif /* __s390x__ */ + static inline void pmd_clear_kernel(pmd_t * pmdp) { pmd_val(*pmdp) = _SEGMENT_ENTRY_EMPTY; - pmd_val1(*pmdp) = _SEGMENT_ENTRY_EMPTY; } -#endif /* __s390x__ */ - -static inline void pmd_clear(pmd_t * pmdp) +static inline void pmd_clear(pmd_t *pmd) { - pmd_t *shadow_pmd = get_shadow_table(pmdp); + pmd_t *shadow = get_shadow_table(pmd); - pmd_clear_kernel(pmdp); - if (shadow_pmd) - pmd_clear_kernel(shadow_pmd); + pmd_clear_kernel(pmd); + if (shadow) + pmd_clear_kernel(shadow); } static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) { - pte_t *shadow_pte = get_shadow_pte(ptep); - pte_val(*ptep) = _PAGE_TYPE_EMPTY; - if (shadow_pte) - pte_val(*shadow_pte) = _PAGE_TYPE_EMPTY; + if (mm->context.noexec) + pte_val(ptep[PTRS_PER_PTE]) = _PAGE_TYPE_EMPTY; } /* @@ -665,7 +682,7 @@ static inline void __ptep_ipte(unsigned long address, pte_t *ptep) { if (!(pte_val(*ptep) & _PAGE_INVALID)) { #ifndef __s390x__ - /* S390 has 1mb segments, we are emulating 4MB segments */ + /* pto must point to the start of the segment table */ pte_t *pto = (pte_t *) (((unsigned long) ptep) & 0x7ffffc00); #else /* ipte in zarch mode can do the math */ @@ -679,12 +696,12 @@ static inline void __ptep_ipte(unsigned long address, pte_t *ptep) pte_val(*ptep) = _PAGE_TYPE_EMPTY; } -static inline void ptep_invalidate(unsigned long address, pte_t *ptep) +static inline void ptep_invalidate(struct mm_struct *mm, + unsigned long address, pte_t *ptep) { __ptep_ipte(address, ptep); - ptep = get_shadow_pte(ptep); - if (ptep) - __ptep_ipte(address, ptep); + if (mm->context.noexec) + __ptep_ipte(address, ptep + PTRS_PER_PTE); } /* @@ -706,7 +723,7 @@ static inline void ptep_invalidate(unsigned long address, pte_t *ptep) pte_t __pte = *(__ptep); \ if (atomic_read(&(__mm)->mm_users) > 1 || \ (__mm) != current->active_mm) \ - ptep_invalidate(__address, __ptep); \ + ptep_invalidate(__mm, __address, __ptep); \ else \ pte_clear((__mm), (__address), (__ptep)); \ __pte; \ @@ -717,7 +734,7 @@ static inline pte_t ptep_clear_flush(struct vm_area_struct *vma, unsigned long address, pte_t *ptep) { pte_t pte = *ptep; - ptep_invalidate(address, ptep); + ptep_invalidate(vma->vm_mm, address, ptep); return pte; } @@ -738,7 +755,7 @@ static inline pte_t ptep_get_and_clear_full(struct mm_struct *mm, if (full) pte_clear(mm, addr, ptep); else - ptep_invalidate(addr, ptep); + ptep_invalidate(mm, addr, ptep); return pte; } @@ -749,7 +766,7 @@ static inline pte_t ptep_get_and_clear_full(struct mm_struct *mm, if (pte_write(__pte)) { \ if (atomic_read(&(__mm)->mm_users) > 1 || \ (__mm) != current->active_mm) \ - ptep_invalidate(__addr, __ptep); \ + ptep_invalidate(__mm, __addr, __ptep); \ set_pte_at(__mm, __addr, __ptep, pte_wrprotect(__pte)); \ } \ }) @@ -759,7 +776,7 @@ static inline pte_t ptep_get_and_clear_full(struct mm_struct *mm, ({ \ int __changed = !pte_same(*(__ptep), __entry); \ if (__changed) { \ - ptep_invalidate(__addr, __ptep); \ + ptep_invalidate((__vma)->vm_mm, __addr, __ptep); \ set_pte_at((__vma)->vm_mm, __addr, __ptep, __entry); \ } \ __changed; \ @@ -840,13 +857,21 @@ static inline pte_t mk_pte(struct page *page, pgprot_t pgprot) #define pmd_deref(pmd) (pmd_val(pmd) & _SEGMENT_ENTRY_ORIGIN) #define pud_deref(pud) (pud_val(pud) & _REGION_ENTRY_ORIGIN) -#define pgd_deref(pgd) ({ BUG(); 0UL; }) +#define pgd_deref(pgd) (pgd_val(pgd) & _REGION_ENTRY_ORIGIN) -#define pud_offset(pgd, address) ((pud_t *) pgd) +static inline pud_t *pud_offset(pgd_t *pgd, unsigned long address) +{ + pud_t *pud = (pud_t *) pgd; + if ((pgd_val(*pgd) & _REGION_ENTRY_TYPE_MASK) == _REGION_ENTRY_TYPE_R2) + pud = (pud_t *) pgd_deref(*pgd); + return pud + pud_index(address); +} static inline pmd_t *pmd_offset(pud_t *pud, unsigned long address) { - pmd_t *pmd = (pmd_t *) pud_deref(*pud); + pmd_t *pmd = (pmd_t *) pud; + if ((pud_val(*pud) & _REGION_ENTRY_TYPE_MASK) == _REGION_ENTRY_TYPE_R3) + pmd = (pmd_t *) pud_deref(*pud); return pmd + pmd_index(address); } diff --git a/include/asm-s390/processor.h b/include/asm-s390/processor.h index e8785634cbd..51d88912aa2 100644 --- a/include/asm-s390/processor.h +++ b/include/asm-s390/processor.h @@ -64,24 +64,29 @@ extern int get_cpu_capability(unsigned int *); */ #ifndef __s390x__ -# define TASK_SIZE (0x80000000UL) -# define TASK_UNMAPPED_BASE (TASK_SIZE / 2) -# define DEFAULT_TASK_SIZE (0x80000000UL) +#define TASK_SIZE (1UL << 31) +#define TASK_UNMAPPED_BASE (1UL << 30) #else /* __s390x__ */ -# define TASK_SIZE_OF(tsk) (test_tsk_thread_flag(tsk, TIF_31BIT) ? \ - (0x80000000UL) : (0x40000000000UL)) -# define TASK_SIZE TASK_SIZE_OF(current) -# define TASK_UNMAPPED_BASE (TASK_SIZE / 2) -# define DEFAULT_TASK_SIZE (0x40000000000UL) +#define TASK_SIZE_OF(tsk) (test_tsk_thread_flag(tsk,TIF_31BIT) ? \ + (1UL << 31) : (1UL << 53)) +#define TASK_UNMAPPED_BASE (test_thread_flag(TIF_31BIT) ? \ + (1UL << 30) : (1UL << 41)) +#define TASK_SIZE TASK_SIZE_OF(current) #endif /* __s390x__ */ #ifdef __KERNEL__ -#define STACK_TOP TASK_SIZE -#define STACK_TOP_MAX DEFAULT_TASK_SIZE +#ifndef __s390x__ +#define STACK_TOP (1UL << 31) +#define STACK_TOP_MAX (1UL << 31) +#else /* __s390x__ */ +#define STACK_TOP (1UL << (test_thread_flag(TIF_31BIT) ? 31:42)) +#define STACK_TOP_MAX (1UL << 42) +#endif /* __s390x__ */ + #endif @@ -138,8 +143,6 @@ struct stack_frame { /* * Do necessary setup to start up a new thread. */ -#ifndef __s390x__ - #define start_thread(regs, new_psw, new_stackp) do { \ set_fs(USER_DS); \ regs->psw.mask = psw_user_bits; \ @@ -147,24 +150,6 @@ struct stack_frame { regs->gprs[15] = new_stackp ; \ } while (0) -#else /* __s390x__ */ - -#define start_thread(regs, new_psw, new_stackp) do { \ - set_fs(USER_DS); \ - regs->psw.mask = psw_user_bits; \ - regs->psw.addr = new_psw; \ - regs->gprs[15] = new_stackp; \ -} while (0) - -#define start_thread31(regs, new_psw, new_stackp) do { \ - set_fs(USER_DS); \ - regs->psw.mask = psw_user32_bits; \ - regs->psw.addr = new_psw; \ - regs->gprs[15] = new_stackp; \ -} while (0) - -#endif /* __s390x__ */ - /* Forward declaration, a strange C thing */ struct task_struct; struct mm_struct; diff --git a/include/asm-s390/tlb.h b/include/asm-s390/tlb.h index 3c8177fa9e0..3d8a96d39d9 100644 --- a/include/asm-s390/tlb.h +++ b/include/asm-s390/tlb.h @@ -38,7 +38,7 @@ struct mmu_gather { struct mm_struct *mm; unsigned int fullmm; unsigned int nr_ptes; - unsigned int nr_pmds; + unsigned int nr_pxds; void *array[TLB_NR_PTRS]; }; @@ -53,7 +53,7 @@ static inline struct mmu_gather *tlb_gather_mmu(struct mm_struct *mm, tlb->fullmm = full_mm_flush || (num_online_cpus() == 1) || (atomic_read(&mm->mm_users) <= 1 && mm == current->active_mm); tlb->nr_ptes = 0; - tlb->nr_pmds = TLB_NR_PTRS; + tlb->nr_pxds = TLB_NR_PTRS; if (tlb->fullmm) __tlb_flush_mm(mm); return tlb; @@ -62,12 +62,13 @@ static inline struct mmu_gather *tlb_gather_mmu(struct mm_struct *mm, static inline void tlb_flush_mmu(struct mmu_gather *tlb, unsigned long start, unsigned long end) { - if (!tlb->fullmm && (tlb->nr_ptes > 0 || tlb->nr_pmds < TLB_NR_PTRS)) + if (!tlb->fullmm && (tlb->nr_ptes > 0 || tlb->nr_pxds < TLB_NR_PTRS)) __tlb_flush_mm(tlb->mm); while (tlb->nr_ptes > 0) pte_free(tlb->mm, tlb->array[--tlb->nr_ptes]); - while (tlb->nr_pmds < TLB_NR_PTRS) - pmd_free(tlb->mm, (pmd_t *) tlb->array[tlb->nr_pmds++]); + while (tlb->nr_pxds < TLB_NR_PTRS) + /* pgd_free frees the pointer as region or segment table */ + pgd_free(tlb->mm, tlb->array[tlb->nr_pxds++]); } static inline void tlb_finish_mmu(struct mmu_gather *tlb, @@ -95,33 +96,57 @@ static inline void tlb_remove_page(struct mmu_gather *tlb, struct page *page) * pte_free_tlb frees a pte table and clears the CRSTE for the * page table from the tlb. */ -static inline void pte_free_tlb(struct mmu_gather *tlb, pgtable_t page) +static inline void pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte) { if (!tlb->fullmm) { - tlb->array[tlb->nr_ptes++] = page; - if (tlb->nr_ptes >= tlb->nr_pmds) + tlb->array[tlb->nr_ptes++] = pte; + if (tlb->nr_ptes >= tlb->nr_pxds) tlb_flush_mmu(tlb, 0, 0); } else - pte_free(tlb->mm, page); + pte_free(tlb->mm, pte); } /* * pmd_free_tlb frees a pmd table and clears the CRSTE for the * segment table entry from the tlb. + * If the mm uses a two level page table the single pmd is freed + * as the pgd. pmd_free_tlb checks the asce_limit against 2GB + * to avoid the double free of the pmd in this case. */ static inline void pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd) { #ifdef __s390x__ + if (tlb->mm->context.asce_limit <= (1UL << 31)) + return; if (!tlb->fullmm) { - tlb->array[--tlb->nr_pmds] = (struct page *) pmd; - if (tlb->nr_ptes >= tlb->nr_pmds) + tlb->array[--tlb->nr_pxds] = pmd; + if (tlb->nr_ptes >= tlb->nr_pxds) tlb_flush_mmu(tlb, 0, 0); } else pmd_free(tlb->mm, pmd); #endif } -#define pud_free_tlb(tlb, pud) do { } while (0) +/* + * pud_free_tlb frees a pud table and clears the CRSTE for the + * region third table entry from the tlb. + * If the mm uses a three level page table the single pud is freed + * as the pgd. pud_free_tlb checks the asce_limit against 4TB + * to avoid the double free of the pud in this case. + */ +static inline void pud_free_tlb(struct mmu_gather *tlb, pud_t *pud) +{ +#ifdef __s390x__ + if (tlb->mm->context.asce_limit <= (1UL << 42)) + return; + if (!tlb->fullmm) { + tlb->array[--tlb->nr_pxds] = pud; + if (tlb->nr_ptes >= tlb->nr_pxds) + tlb_flush_mmu(tlb, 0, 0); + } else + pud_free(tlb->mm, pud); +#endif +} #define tlb_start_vma(tlb, vma) do { } while (0) #define tlb_end_vma(tlb, vma) do { } while (0) diff --git a/include/asm-s390/tlbflush.h b/include/asm-s390/tlbflush.h index 70fa5ae5818..35fb4f9127b 100644 --- a/include/asm-s390/tlbflush.h +++ b/include/asm-s390/tlbflush.h @@ -61,11 +61,12 @@ static inline void __tlb_flush_mm(struct mm_struct * mm) * only ran on the local cpu. */ if (MACHINE_HAS_IDTE) { - pgd_t *shadow = get_shadow_table(mm->pgd); - - if (shadow) - __tlb_flush_idte((unsigned long) shadow | mm->context); - __tlb_flush_idte((unsigned long) mm->pgd | mm->context); + if (mm->context.noexec) + __tlb_flush_idte((unsigned long) + get_shadow_table(mm->pgd) | + mm->context.asce_bits); + __tlb_flush_idte((unsigned long) mm->pgd | + mm->context.asce_bits); return; } preempt_disable(); diff --git a/include/asm-s390/unistd.h b/include/asm-s390/unistd.h index f04acb2670a..583da807ea9 100644 --- a/include/asm-s390/unistd.h +++ b/include/asm-s390/unistd.h @@ -256,7 +256,10 @@ #define __NR_signalfd 316 #define __NR_timerfd 317 #define __NR_eventfd 318 -#define NR_syscalls 319 +#define __NR_timerfd_create 319 +#define __NR_timerfd_settime 320 +#define __NR_timerfd_gettime 321 +#define NR_syscalls 322 /* * There are some system calls that are not present on 64 bit, some diff --git a/include/asm-v850/page.h b/include/asm-v850/page.h index 661d8cd0883..74a539a9bd5 100644 --- a/include/asm-v850/page.h +++ b/include/asm-v850/page.h @@ -57,6 +57,7 @@ typedef struct { unsigned long pte; } pte_t; typedef struct { unsigned long pmd; } pmd_t; typedef struct { unsigned long pgd; } pgd_t; typedef struct { unsigned long pgprot; } pgprot_t; +typedef struct page *pgtable_t; #define pte_val(x) ((x).pte) #define pmd_val(x) ((x).pmd) diff --git a/include/linux/ext4_fs.h b/include/linux/ext4_fs.h index c4f635a4dd2..25003254859 100644 --- a/include/linux/ext4_fs.h +++ b/include/linux/ext4_fs.h @@ -490,6 +490,13 @@ do { \ #define EXT4_ORPHAN_FS 0x0004 /* Orphans being recovered */ /* + * Misc. filesystem flags + */ +#define EXT2_FLAGS_SIGNED_HASH 0x0001 /* Signed dirhash in use */ +#define EXT2_FLAGS_UNSIGNED_HASH 0x0002 /* Unsigned dirhash in use */ +#define EXT2_FLAGS_TEST_FILESYS 0x0004 /* to test development code */ + +/* * Mount flags */ #define EXT4_MOUNT_CHECK 0x00001 /* Do mount-time checks */ diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h index 9815951ec99..925d57b236a 100644 --- a/include/linux/memcontrol.h +++ b/include/linux/memcontrol.h @@ -51,10 +51,8 @@ extern int mem_cgroup_cache_charge(struct page *page, struct mm_struct *mm, gfp_t gfp_mask); int task_in_mem_cgroup(struct task_struct *task, const struct mem_cgroup *mem); -static inline struct mem_cgroup *mm_cgroup(const struct mm_struct *mm) -{ - return rcu_dereference(mm->mem_cgroup); -} +#define vm_match_cgroup(mm, cgroup) \ + ((cgroup) == rcu_dereference((mm)->mem_cgroup)) extern int mem_cgroup_prepare_migration(struct page *page); extern void mem_cgroup_end_migration(struct page *page); @@ -123,9 +121,9 @@ static inline int mem_cgroup_cache_charge(struct page *page, return 0; } -static inline struct mem_cgroup *mm_cgroup(const struct mm_struct *mm) +static inline int vm_match_cgroup(struct mm_struct *mm, struct mem_cgroup *mem) { - return NULL; + return 1; } static inline int task_in_mem_cgroup(struct task_struct *task, diff --git a/include/linux/memstick.h b/include/linux/memstick.h new file mode 100644 index 00000000000..334d059d679 --- /dev/null +++ b/include/linux/memstick.h @@ -0,0 +1,299 @@ +/* + * Sony MemoryStick support + * + * Copyright (C) 2007 Alex Dubov <oakad@yahoo.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#ifndef _MEMSTICK_H +#define _MEMSTICK_H + +#include <linux/workqueue.h> +#include <linux/scatterlist.h> +#include <linux/device.h> + +/*** Hardware based structures ***/ + +struct ms_status_register { + unsigned char reserved; + unsigned char interrupt; +#define MEMSTICK_INT_CMDNAK 0x0001 +#define MEMSTICK_INT_BREQ 0x0020 +#define MEMSTICK_INT_ERR 0x0040 +#define MEMSTICK_INT_CED 0x0080 + + unsigned char status0; +#define MEMSTICK_STATUS0_WP 0x0001 +#define MEMSTICK_STATUS0_SL 0x0002 +#define MEMSTICK_STATUS0_BF 0x0010 +#define MEMSTICK_STATUS0_BE 0x0020 +#define MEMSTICK_STATUS0_FB0 0x0040 +#define MEMSTICK_STATUS0_MB 0x0080 + + unsigned char status1; +#define MEMSTICK_STATUS1_UCFG 0x0001 +#define MEMSTICK_STATUS1_FGER 0x0002 +#define MEMSTICK_STATUS1_UCEX 0x0004 +#define MEMSTICK_STATUS1_EXER 0x0008 +#define MEMSTICK_STATUS1_UCDT 0x0010 +#define MEMSTICK_STATUS1_DTER 0x0020 +#define MEMSTICK_STATUS1_FBI 0x0040 +#define MEMSTICK_STATUS1_MB 0x0080 +} __attribute__((packed)); + +struct ms_id_register { + unsigned char type; + unsigned char reserved; + unsigned char category; + unsigned char class; +} __attribute__((packed)); + +struct ms_param_register { + unsigned char system; + unsigned char block_address_msb; + unsigned short block_address; + unsigned char cp; +#define MEMSTICK_CP_BLOCK 0x0000 +#define MEMSTICK_CP_PAGE 0x0020 +#define MEMSTICK_CP_EXTRA 0x0040 +#define MEMSTICK_CP_OVERWRITE 0x0080 + + unsigned char page_address; +} __attribute__((packed)); + +struct ms_extra_data_register { + unsigned char overwrite_flag; +#define MEMSTICK_OVERWRITE_UPDATA 0x0010 +#define MEMSTICK_OVERWRITE_PAGE 0x0060 +#define MEMSTICK_OVERWRITE_BLOCK 0x0080 + + unsigned char management_flag; +#define MEMSTICK_MANAGEMENT_SYSTEM 0x0004 +#define MEMSTICK_MANAGEMENT_TRANS_TABLE 0x0008 +#define MEMSTICK_MANAGEMENT_COPY 0x0010 +#define MEMSTICK_MANAGEMENT_ACCESS 0x0020 + + unsigned short logical_address; +} __attribute__((packed)); + +struct ms_register { + struct ms_status_register status; + struct ms_id_register id; + unsigned char reserved[8]; + struct ms_param_register param; + struct ms_extra_data_register extra_data; +} __attribute__((packed)); + +struct mspro_param_register { + unsigned char system; + unsigned short data_count; + unsigned int data_address; + unsigned char cmd_param; +} __attribute__((packed)); + +struct mspro_register { + struct ms_status_register status; + struct ms_id_register id; + unsigned char reserved[8]; + struct mspro_param_register param; +} __attribute__((packed)); + +struct ms_register_addr { + unsigned char r_offset; + unsigned char r_length; + unsigned char w_offset; + unsigned char w_length; +} __attribute__((packed)); + +enum { + MS_TPC_READ_LONG_DATA = 0x02, + MS_TPC_READ_SHORT_DATA = 0x03, + MS_TPC_READ_REG = 0x04, + MS_TPC_READ_IO_DATA = 0x05, /* unverified */ + MS_TPC_GET_INT = 0x07, + MS_TPC_SET_RW_REG_ADRS = 0x08, + MS_TPC_EX_SET_CMD = 0x09, + MS_TPC_WRITE_IO_DATA = 0x0a, /* unverified */ + MS_TPC_WRITE_REG = 0x0b, + MS_TPC_WRITE_SHORT_DATA = 0x0c, + MS_TPC_WRITE_LONG_DATA = 0x0d, + MS_TPC_SET_CMD = 0x0e +}; + +enum { + MS_CMD_BLOCK_END = 0x33, + MS_CMD_RESET = 0x3c, + MS_CMD_BLOCK_WRITE = 0x55, + MS_CMD_SLEEP = 0x5a, + MS_CMD_BLOCK_ERASE = 0x99, + MS_CMD_BLOCK_READ = 0xaa, + MS_CMD_CLEAR_BUF = 0xc3, + MS_CMD_FLASH_STOP = 0xcc, + MSPRO_CMD_FORMAT = 0x10, + MSPRO_CMD_SLEEP = 0x11, + MSPRO_CMD_READ_DATA = 0x20, + MSPRO_CMD_WRITE_DATA = 0x21, + MSPRO_CMD_READ_ATRB = 0x24, + MSPRO_CMD_STOP = 0x25, + MSPRO_CMD_ERASE = 0x26, + MSPRO_CMD_SET_IBA = 0x46, + MSPRO_CMD_SET_IBD = 0x47 +/* + MSPRO_CMD_RESET + MSPRO_CMD_WAKEUP + MSPRO_CMD_IN_IO_DATA + MSPRO_CMD_OUT_IO_DATA + MSPRO_CMD_READ_IO_ATRB + MSPRO_CMD_IN_IO_FIFO + MSPRO_CMD_OUT_IO_FIFO + MSPRO_CMD_IN_IOM + MSPRO_CMD_OUT_IOM +*/ +}; + +/*** Driver structures and functions ***/ + +#define MEMSTICK_PART_SHIFT 3 + +enum memstick_param { MEMSTICK_POWER = 1, MEMSTICK_INTERFACE }; + +#define MEMSTICK_POWER_OFF 0 +#define MEMSTICK_POWER_ON 1 + +#define MEMSTICK_SERIAL 0 +#define MEMSTICK_PARALLEL 1 + +struct memstick_host; +struct memstick_driver; + +#define MEMSTICK_MATCH_ALL 0x01 + +#define MEMSTICK_TYPE_LEGACY 0xff +#define MEMSTICK_TYPE_DUO 0x00 +#define MEMSTICK_TYPE_PRO 0x01 + +#define MEMSTICK_CATEGORY_STORAGE 0xff +#define MEMSTICK_CATEGORY_STORAGE_DUO 0x00 + +#define MEMSTICK_CLASS_GENERIC 0xff +#define MEMSTICK_CLASS_GENERIC_DUO 0x00 + + +struct memstick_device_id { + unsigned char match_flags; + unsigned char type; + unsigned char category; + unsigned char class; +}; + +struct memstick_request { + unsigned char tpc; + unsigned char data_dir:1, + need_card_int:1, + get_int_reg:1, + io_type:2; +#define MEMSTICK_IO_NONE 0 +#define MEMSTICK_IO_VAL 1 +#define MEMSTICK_IO_SG 2 + + unsigned char int_reg; + int error; + union { + struct scatterlist sg; + struct { + unsigned char data_len; + unsigned char data[15]; + }; + }; +}; + +struct memstick_dev { + struct memstick_device_id id; + struct memstick_host *host; + struct ms_register_addr reg_addr; + struct completion mrq_complete; + struct memstick_request current_mrq; + + /* Check that media driver is still willing to operate the device. */ + int (*check)(struct memstick_dev *card); + /* Get next request from the media driver. */ + int (*next_request)(struct memstick_dev *card, + struct memstick_request **mrq); + + struct device dev; +}; + +struct memstick_host { + struct mutex lock; + unsigned int id; + unsigned int caps; +#define MEMSTICK_CAP_PARALLEL 1 +#define MEMSTICK_CAP_AUTO_GET_INT 2 + + struct work_struct media_checker; + struct class_device cdev; + + struct memstick_dev *card; + unsigned int retries; + + /* Notify the host that some requests are pending. */ + void (*request)(struct memstick_host *host); + /* Set host IO parameters (power, clock, etc). */ + void (*set_param)(struct memstick_host *host, + enum memstick_param param, + int value); + unsigned long private[0] ____cacheline_aligned; +}; + +struct memstick_driver { + struct memstick_device_id *id_table; + int (*probe)(struct memstick_dev *card); + void (*remove)(struct memstick_dev *card); + int (*suspend)(struct memstick_dev *card, + pm_message_t state); + int (*resume)(struct memstick_dev *card); + + struct device_driver driver; +}; + +int memstick_register_driver(struct memstick_driver *drv); +void memstick_unregister_driver(struct memstick_driver *drv); + +struct memstick_host *memstick_alloc_host(unsigned int extra, + struct device *dev); + +int memstick_add_host(struct memstick_host *host); +void memstick_remove_host(struct memstick_host *host); +void memstick_free_host(struct memstick_host *host); +void memstick_detect_change(struct memstick_host *host); + +void memstick_init_req_sg(struct memstick_request *mrq, unsigned char tpc, + struct scatterlist *sg); +void memstick_init_req(struct memstick_request *mrq, unsigned char tpc, + void *buf, size_t length); +int memstick_next_req(struct memstick_host *host, + struct memstick_request **mrq); +void memstick_new_req(struct memstick_host *host); + +int memstick_set_rw_addr(struct memstick_dev *card); + +static inline void *memstick_priv(struct memstick_host *host) +{ + return (void *)host->private; +} + +static inline void *memstick_get_drvdata(struct memstick_dev *card) +{ + return dev_get_drvdata(&card->dev); +} + +static inline void memstick_set_drvdata(struct memstick_dev *card, void *data) +{ + dev_set_drvdata(&card->dev, data); +} + +#endif diff --git a/include/linux/swapops.h b/include/linux/swapops.h index 7bf2d149d20..6ec39ab27b4 100644 --- a/include/linux/swapops.h +++ b/include/linux/swapops.h @@ -42,11 +42,13 @@ static inline pgoff_t swp_offset(swp_entry_t entry) return entry.val & SWP_OFFSET_MASK(entry); } +#ifdef CONFIG_MMU /* check whether a pte points to a swap entry */ static inline int is_swap_pte(pte_t pte) { return !pte_none(pte) && !pte_present(pte) && !pte_file(pte); } +#endif /* * Convert the arch-dependent pte representation of a swp_entry_t into an diff --git a/include/linux/thermal.h b/include/linux/thermal.h index bba7712cadc..818ca1cf0b6 100644 --- a/include/linux/thermal.h +++ b/include/linux/thermal.h @@ -79,7 +79,9 @@ struct thermal_zone_device { }; struct thermal_zone_device *thermal_zone_device_register(char *, int, void *, - struct thermal_zone_device_ops *); + struct + thermal_zone_device_ops + *); void thermal_zone_device_unregister(struct thermal_zone_device *); int thermal_zone_bind_cooling_device(struct thermal_zone_device *, int, @@ -87,8 +89,23 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *, int, int thermal_zone_unbind_cooling_device(struct thermal_zone_device *, int, struct thermal_cooling_device *); +#ifdef CONFIG_THERMAL struct thermal_cooling_device *thermal_cooling_device_register(char *, void *, - struct thermal_cooling_device_ops *); + struct + thermal_cooling_device_ops + *); void thermal_cooling_device_unregister(struct thermal_cooling_device *); +#else +static inline struct thermal_cooling_device +*thermal_cooling_device_register(char *c, void *v, + struct thermal_cooling_device_ops *t) +{ + return NULL; +} +static inline + void thermal_cooling_device_unregister(struct thermal_cooling_device *t) +{ +}; +#endif -#endif /* __THERMAL_H__ */ +#endif /* __THERMAL_H__ */ diff --git a/include/linux/tifm.h b/include/linux/tifm.h index 2096b76d0ce..da76ed85f59 100644 --- a/include/linux/tifm.h +++ b/include/linux/tifm.h @@ -72,6 +72,7 @@ enum { #define TIFM_FIFO_READY 0x00000001 #define TIFM_FIFO_INT_SETALL 0x0000ffff #define TIFM_FIFO_INTMASK 0x00000005 +#define TIFM_FIFO_SIZE 0x00000200 #define TIFM_DMA_RESET 0x00000002 #define TIFM_DMA_TX 0x00008000 @@ -124,6 +125,8 @@ struct tifm_adapter { void (*eject)(struct tifm_adapter *fm, struct tifm_dev *sock); + int (*has_ms_pif)(struct tifm_adapter *fm, + struct tifm_dev *sock); struct tifm_dev *sockets[0]; }; @@ -141,6 +144,7 @@ struct tifm_dev *tifm_alloc_device(struct tifm_adapter *fm, unsigned int id, int tifm_register_driver(struct tifm_driver *drv); void tifm_unregister_driver(struct tifm_driver *drv); void tifm_eject(struct tifm_dev *sock); +int tifm_has_ms_pif(struct tifm_dev *sock); int tifm_map_sg(struct tifm_dev *sock, struct scatterlist *sg, int nents, int direction); void tifm_unmap_sg(struct tifm_dev *sock, struct scatterlist *sg, int nents, |