[SCSI] ibmmca: fix a NULL pointer dereference
[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 <asm/hardware.h>
12
13 #if (IO_BASE == (PCIO_BASE & 0xff000000))
14 #define ADDR(off,reg)                                           \
15                 tst     off, $0x80000000                        ;\
16                 mov     reg, $IO_BASE                           ;\
17                 orreq   reg, reg, $(PCIO_BASE & 0x00ff0000)
18 #else
19 #define ADDR(off,reg)                                           \
20                 tst     off, $0x80000000                        ;\
21                 movne   reg, $IO_BASE                           ;\
22                 moveq   reg, $(PCIO_BASE & 0xff000000)          ;\
23                 orreq   reg, reg, $(PCIO_BASE & 0x00ff0000)
24 #endif
25
26 @ Purpose: transfer a block of data from the acorn scsi card to memory
27 @ Proto  : void acornscsi_in(unsigned int addr_start, char *buffer, int length)
28 @ Returns: nothing
29
30                 .align
31 ENTRY(__acornscsi_in)
32                 stmfd   sp!, {r4 - r7, lr}
33                 bic     r0, r0, #3
34                 mov     lr, #0xff
35                 orr     lr, lr, #0xff00
36 acornscsi_in16lp:
37                 subs    r2, r2, #16
38                 bmi     acornscsi_in8
39                 ldmia   r0!, {r3, r4, r5, r6}
40                 and     r3, r3, lr
41                 orr     r3, r3, r4, lsl #16
42                 and     r4, r5, lr
43                 orr     r4, r4, r6, lsl #16
44                 ldmia   r0!, {r5, r6, r7, ip}
45                 and     r5, r5, lr
46                 orr     r5, r5, r6, lsl #16
47                 and     r6, r7, lr
48                 orr     r6, r6, ip, lsl #16
49                 stmia   r1!, {r3 - r6}
50                 bne     acornscsi_in16lp
51                 LOADREGS(fd, sp!, {r4 - r7, pc})
52
53 acornscsi_in8:  adds    r2, r2, #8
54                 bmi     acornscsi_in4
55                 ldmia   r0!, {r3, r4, r5, r6}
56                 and     r3, r3, lr
57                 orr     r3, r3, r4, lsl #16
58                 and     r4, r5, lr
59                 orr     r4, r4, r6, lsl #16
60                 stmia   r1!, {r3 - r4}
61                 LOADREGS(eqfd, sp!, {r4 - r7, pc})
62                 sub     r2, r2, #8
63
64 acornscsi_in4:  adds    r2, r2, #4
65                 bmi     acornscsi_in2
66                 ldmia   r0!, {r3, r4}
67                 and     r3, r3, lr
68                 orr     r3, r3, r4, lsl #16
69                 str     r3, [r1], #4
70                 LOADREGS(eqfd, sp!, {r4 - r7, pc})
71                 sub     r2, r2, #4
72
73 acornscsi_in2:  adds    r2, r2, #2
74                 ldr     r3, [r0], #4
75                 and     r3, r3, lr
76                 strb    r3, [r1], #1
77                 mov     r3, r3, lsr #8
78                 strplb  r3, [r1], #1
79                 LOADREGS(fd, sp!, {r4 - r7, pc})
80
81 @ Purpose: transfer a block of data from memory to the acorn scsi card
82 @ Proto  : void acornscsi_in(unsigned int addr_start, char *buffer, int length)
83 @ Returns: nothing
84
85 ENTRY(__acornscsi_out)
86                 stmfd   sp!, {r4 - r6, lr}
87                 bic     r0, r0, #3
88 acornscsi_out16lp:
89                 subs    r2, r2, #16
90                 bmi     acornscsi_out8
91                 ldmia   r1!, {r4, r6, ip, lr}
92                 mov     r3, r4, lsl #16
93                 orr     r3, r3, r3, lsr #16
94                 mov     r4, r4, lsr #16
95                 orr     r4, r4, r4, lsl #16
96                 mov     r5, r6, lsl #16
97                 orr     r5, r5, r5, lsr #16
98                 mov     r6, r6, lsr #16
99                 orr     r6, r6, r6, lsl #16
100                 stmia   r0!, {r3, r4, r5, r6}
101                 mov     r3, ip, lsl #16
102                 orr     r3, r3, r3, lsr #16
103                 mov     r4, ip, lsr #16
104                 orr     r4, r4, r4, lsl #16
105                 mov     ip, lr, lsl #16
106                 orr     ip, ip, ip, lsr #16
107                 mov     lr, lr, lsr #16
108                 orr     lr, lr, lr, lsl #16
109                 stmia   r0!, {r3, r4, ip, lr}
110                 bne     acornscsi_out16lp
111                 LOADREGS(fd, sp!, {r4 - r6, pc})
112
113 acornscsi_out8: adds    r2, r2, #8
114                 bmi     acornscsi_out4
115                 ldmia   r1!, {r4, r6}
116                 mov     r3, r4, lsl #16
117                 orr     r3, r3, r3, lsr #16
118                 mov     r4, r4, lsr #16
119                 orr     r4, r4, r4, lsl #16
120                 mov     r5, r6, lsl #16
121                 orr     r5, r5, r5, lsr #16
122                 mov     r6, r6, lsr #16
123                 orr     r6, r6, r6, lsl #16
124                 stmia   r0!, {r3, r4, r5, r6}
125                 LOADREGS(eqfd, sp!, {r4 - r6, pc})
126
127                 sub     r2, r2, #8
128 acornscsi_out4: adds    r2, r2, #4
129                 bmi     acornscsi_out2
130                 ldr     r4, [r1], #4
131                 mov     r3, r4, lsl #16
132                 orr     r3, r3, r3, lsr #16
133                 mov     r4, r4, lsr #16
134                 orr     r4, r4, r4, lsl #16
135                 stmia   r0!, {r3, r4}
136                 LOADREGS(eqfd, sp!, {r4 - r6, pc})
137
138                 sub     r2, r2, #4
139 acornscsi_out2: adds    r2, r2, #2
140                 ldr     r3, [r1], #2
141                 strb    r3, [r0], #1
142                 mov     r3, r3, lsr #8
143                 strplb  r3, [r0], #1
144                 LOADREGS(fd, sp!, {r4 - r6, pc})
145