Merge git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs-unstable
[linux-2.6] / drivers / scsi / arm / acornscsi-io.S
1 /*
2  *  linux/drivers/acorn/scsi/acornscsi-io.S: Acorn SCSI card IO
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation.
7  */
8 #include <linux/linkage.h>
9
10 #include <asm/assembler.h>
11 #include <mach/hardware.h>
12
13 #if defined(__APCS_32__)
14 #define LOADREGS(t,r,l...)      ldm##t  r, l
15 #elif defined(__APCS_26__)
16 #define LOADREGS(t,r,l...)      ldm##t  r, l##^
17 #endif
18
19 @ Purpose: transfer a block of data from the acorn scsi card to memory
20 @ Proto  : void acornscsi_in(unsigned int addr_start, char *buffer, int length)
21 @ Returns: nothing
22
23                 .align
24 ENTRY(__acornscsi_in)
25                 stmfd   sp!, {r4 - r7, lr}
26                 bic     r0, r0, #3
27                 mov     lr, #0xff
28                 orr     lr, lr, #0xff00
29 acornscsi_in16lp:
30                 subs    r2, r2, #16
31                 bmi     acornscsi_in8
32                 ldmia   r0!, {r3, r4, r5, r6}
33                 and     r3, r3, lr
34                 orr     r3, r3, r4, lsl #16
35                 and     r4, r5, lr
36                 orr     r4, r4, r6, lsl #16
37                 ldmia   r0!, {r5, r6, r7, ip}
38                 and     r5, r5, lr
39                 orr     r5, r5, r6, lsl #16
40                 and     r6, r7, lr
41                 orr     r6, r6, ip, lsl #16
42                 stmia   r1!, {r3 - r6}
43                 bne     acornscsi_in16lp
44                 LOADREGS(fd, sp!, {r4 - r7, pc})
45
46 acornscsi_in8:  adds    r2, r2, #8
47                 bmi     acornscsi_in4
48                 ldmia   r0!, {r3, r4, r5, r6}
49                 and     r3, r3, lr
50                 orr     r3, r3, r4, lsl #16
51                 and     r4, r5, lr
52                 orr     r4, r4, r6, lsl #16
53                 stmia   r1!, {r3 - r4}
54                 LOADREGS(eqfd, sp!, {r4 - r7, pc})
55                 sub     r2, r2, #8
56
57 acornscsi_in4:  adds    r2, r2, #4
58                 bmi     acornscsi_in2
59                 ldmia   r0!, {r3, r4}
60                 and     r3, r3, lr
61                 orr     r3, r3, r4, lsl #16
62                 str     r3, [r1], #4
63                 LOADREGS(eqfd, sp!, {r4 - r7, pc})
64                 sub     r2, r2, #4
65
66 acornscsi_in2:  adds    r2, r2, #2
67                 ldr     r3, [r0], #4
68                 and     r3, r3, lr
69                 strb    r3, [r1], #1
70                 mov     r3, r3, lsr #8
71                 strplb  r3, [r1], #1
72                 LOADREGS(fd, sp!, {r4 - r7, pc})
73
74 @ Purpose: transfer a block of data from memory to the acorn scsi card
75 @ Proto  : void acornscsi_in(unsigned int addr_start, char *buffer, int length)
76 @ Returns: nothing
77
78 ENTRY(__acornscsi_out)
79                 stmfd   sp!, {r4 - r6, lr}
80                 bic     r0, r0, #3
81 acornscsi_out16lp:
82                 subs    r2, r2, #16
83                 bmi     acornscsi_out8
84                 ldmia   r1!, {r4, r6, ip, lr}
85                 mov     r3, r4, lsl #16
86                 orr     r3, r3, r3, lsr #16
87                 mov     r4, r4, lsr #16
88                 orr     r4, r4, r4, lsl #16
89                 mov     r5, r6, lsl #16
90                 orr     r5, r5, r5, lsr #16
91                 mov     r6, r6, lsr #16
92                 orr     r6, r6, r6, lsl #16
93                 stmia   r0!, {r3, r4, r5, r6}
94                 mov     r3, ip, lsl #16
95                 orr     r3, r3, r3, lsr #16
96                 mov     r4, ip, lsr #16
97                 orr     r4, r4, r4, lsl #16
98                 mov     ip, lr, lsl #16
99                 orr     ip, ip, ip, lsr #16
100                 mov     lr, lr, lsr #16
101                 orr     lr, lr, lr, lsl #16
102                 stmia   r0!, {r3, r4, ip, lr}
103                 bne     acornscsi_out16lp
104                 LOADREGS(fd, sp!, {r4 - r6, pc})
105
106 acornscsi_out8: adds    r2, r2, #8
107                 bmi     acornscsi_out4
108                 ldmia   r1!, {r4, r6}
109                 mov     r3, r4, lsl #16
110                 orr     r3, r3, r3, lsr #16
111                 mov     r4, r4, lsr #16
112                 orr     r4, r4, r4, lsl #16
113                 mov     r5, r6, lsl #16
114                 orr     r5, r5, r5, lsr #16
115                 mov     r6, r6, lsr #16
116                 orr     r6, r6, r6, lsl #16
117                 stmia   r0!, {r3, r4, r5, r6}
118                 LOADREGS(eqfd, sp!, {r4 - r6, pc})
119
120                 sub     r2, r2, #8
121 acornscsi_out4: adds    r2, r2, #4
122                 bmi     acornscsi_out2
123                 ldr     r4, [r1], #4
124                 mov     r3, r4, lsl #16
125                 orr     r3, r3, r3, lsr #16
126                 mov     r4, r4, lsr #16
127                 orr     r4, r4, r4, lsl #16
128                 stmia   r0!, {r3, r4}
129                 LOADREGS(eqfd, sp!, {r4 - r6, pc})
130
131                 sub     r2, r2, #4
132 acornscsi_out2: adds    r2, r2, #2
133                 ldr     r3, [r1], #2
134                 strb    r3, [r0], #1
135                 mov     r3, r3, lsr #8
136                 strplb  r3, [r0], #1
137                 LOADREGS(fd, sp!, {r4 - r6, pc})
138