Merge git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-rc-fixes-2.6
[linux-2.6] / arch / sparc / lib / locks.S
1 /*
2  * locks.S: SMP low-level lock primitives on Sparc.
3  *
4  * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
5  * Copyright (C) 1998 Anton Blanchard (anton@progsoc.uts.edu.au)
6  * Copyright (C) 1998 Jakub Jelinek   (jj@ultra.linux.cz)
7  */
8
9 #include <asm/ptrace.h>
10 #include <asm/psr.h>
11 #include <asm/smp.h>
12 #include <asm/spinlock.h>
13
14         .text
15         .align  4
16
17         /* Read/writer locks, as usual this is overly clever to make it
18          * as fast as possible.
19          */
20
21         /* caches... */
22 ___rw_read_enter_spin_on_wlock:
23         orcc    %g2, 0x0, %g0
24         be,a    ___rw_read_enter
25          ldstub [%g1 + 3], %g2
26         b       ___rw_read_enter_spin_on_wlock
27          ldub   [%g1 + 3], %g2
28 ___rw_read_try_spin_on_wlock:
29         andcc   %g2, 0xff, %g0
30         be,a    ___rw_read_try
31          ldstub [%g1 + 3], %g2
32         xnorcc  %g2, 0x0, %o0   /* if g2 is ~0, set o0 to 0 and bugger off */
33         bne,a   ___rw_read_enter_spin_on_wlock
34          ld     [%g1], %g2
35         retl
36          mov    %g4, %o7
37 ___rw_read_exit_spin_on_wlock:
38         orcc    %g2, 0x0, %g0
39         be,a    ___rw_read_exit
40          ldstub [%g1 + 3], %g2
41         b       ___rw_read_exit_spin_on_wlock
42          ldub   [%g1 + 3], %g2
43 ___rw_write_enter_spin_on_wlock:
44         orcc    %g2, 0x0, %g0
45         be,a    ___rw_write_enter
46          ldstub [%g1 + 3], %g2
47         b       ___rw_write_enter_spin_on_wlock
48          ld     [%g1], %g2
49
50         .globl  ___rw_read_enter
51 ___rw_read_enter:
52         orcc    %g2, 0x0, %g0
53         bne,a   ___rw_read_enter_spin_on_wlock
54          ldub   [%g1 + 3], %g2
55         ld      [%g1], %g2
56         add     %g2, 1, %g2
57         st      %g2, [%g1]
58         retl
59          mov    %g4, %o7
60
61         .globl  ___rw_read_exit
62 ___rw_read_exit:
63         orcc    %g2, 0x0, %g0
64         bne,a   ___rw_read_exit_spin_on_wlock
65          ldub   [%g1 + 3], %g2
66         ld      [%g1], %g2
67         sub     %g2, 0x1ff, %g2
68         st      %g2, [%g1]
69         retl
70          mov    %g4, %o7
71
72         .globl  ___rw_read_try
73 ___rw_read_try:
74         orcc    %g2, 0x0, %g0
75         bne     ___rw_read_try_spin_on_wlock
76          ld     [%g1], %g2
77         add     %g2, 1, %g2
78         st      %g2, [%g1]
79         set     1, %o1
80         retl
81          mov    %g4, %o7
82
83         .globl  ___rw_write_enter
84 ___rw_write_enter:
85         orcc    %g2, 0x0, %g0
86         bne     ___rw_write_enter_spin_on_wlock
87          ld     [%g1], %g2
88         andncc  %g2, 0xff, %g0
89         bne,a   ___rw_write_enter_spin_on_wlock
90          stb    %g0, [%g1 + 3]
91         retl
92          mov    %g4, %o7