Merge git://git.infradead.org/mtd-2.6
[linux-2.6] / arch / avr32 / lib / strncpy_from_user.S
1 /*
2  * Copy to/from userspace with optional address space checking.
3  *
4  * Copyright 2004-2006 Atmel Corporation
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation.
9  */
10 #include <linux/errno.h>
11
12 #include <asm/page.h>
13 #include <asm/thread_info.h>
14 #include <asm/asm.h>
15
16         /*
17          * long strncpy_from_user(char *dst, const char *src, long count)
18          *
19          * On success, returns the length of the string, not including
20          * the terminating NUL.
21          *
22          * If the string is longer than count, returns count
23          *
24          * If userspace access fails, returns -EFAULT
25          */
26         .text
27         .align  1
28         .global strncpy_from_user
29         .type   strncpy_from_user, "function"
30 strncpy_from_user:
31         mov     r9, -EFAULT
32         branch_if_kernel r8, __strncpy_from_user
33         ret_if_privileged r8, r11, r10, r9
34
35         .global __strncpy_from_user
36         .type   __strncpy_from_user, "function"
37 __strncpy_from_user:
38         cp.w    r10, 0
39         reteq   0
40
41         mov     r9, r10
42
43 1:      ld.ub   r8, r11++
44         st.b    r12++, r8
45         cp.w    r8, 0
46         breq    2f
47         sub     r9, 1
48         brne    1b
49
50 2:      sub     r10, r9
51         retal   r10
52
53         .section .fixup, "ax"
54         .align  1
55 3:      mov     r12, -EFAULT
56         retal   r12
57
58         .section __ex_table, "a"
59         .align  2
60         .long   1b, 3b