1 /**
2 * @file meslock.c
3 *
4 * @brief Implements the subdevice lock class.
5 * @note Copyright (C) 2006 Meilhaus Electronic GmbH (support@meilhaus.de)
6 * @author Guenter Gebhardt
7 */
8
9 /*
10 * Copyright (C) 2006 Meilhaus Electronic GmbH (support@meilhaus.de)
11 *
12 * This file is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 */
26
27 #include <linux/spinlock.h>
28
29 #include "medefines.h"
30 #include "meerror.h"
31
32 #include "medebug.h"
33 #include "meslock.h"
34
me_slock_enter(struct me_slock * slock,struct file * filep)35 int me_slock_enter(struct me_slock *slock, struct file *filep)
36 {
37 PDEBUG_LOCKS("executed.\n");
38
39 spin_lock(&slock->spin_lock);
40
41 if ((slock->filep) != NULL && (slock->filep != filep)) {
42 PERROR("Subdevice is locked by another process.\n");
43 spin_unlock(&slock->spin_lock);
44 return ME_ERRNO_LOCKED;
45 }
46
47 slock->count++;
48
49 spin_unlock(&slock->spin_lock);
50
51 return ME_ERRNO_SUCCESS;
52 }
53
me_slock_exit(struct me_slock * slock,struct file * filep)54 int me_slock_exit(struct me_slock *slock, struct file *filep)
55 {
56 PDEBUG_LOCKS("executed.\n");
57
58 spin_lock(&slock->spin_lock);
59 slock->count--;
60 spin_unlock(&slock->spin_lock);
61
62 return ME_ERRNO_SUCCESS;
63 }
64
me_slock_lock(struct me_slock * slock,struct file * filep,int lock)65 int me_slock_lock(struct me_slock *slock, struct file *filep, int lock)
66 {
67 PDEBUG_LOCKS("executed.\n");
68
69 switch (lock) {
70
71 case ME_LOCK_RELEASE:
72 spin_lock(&slock->spin_lock);
73
74 if (slock->filep == filep)
75 slock->filep = NULL;
76
77 spin_unlock(&slock->spin_lock);
78
79 break;
80
81 case ME_LOCK_SET:
82 spin_lock(&slock->spin_lock);
83
84 if (slock->count) {
85 spin_unlock(&slock->spin_lock);
86 PERROR("Subdevice is used by another process.\n");
87 return ME_ERRNO_USED;
88 } else if (slock->filep == NULL)
89 slock->filep = filep;
90 else if (slock->filep != filep) {
91 spin_unlock(&slock->spin_lock);
92 PERROR("Subdevice is locked by another process.\n");
93 return ME_ERRNO_LOCKED;
94 }
95
96 spin_unlock(&slock->spin_lock);
97
98 break;
99
100 case ME_LOCK_CHECK:
101 spin_lock(&slock->spin_lock);
102
103 if (slock->count) {
104 spin_unlock(&slock->spin_lock);
105 return ME_ERRNO_USED;
106 } else if ((slock->filep != NULL) && (slock->filep != filep)) {
107 spin_unlock(&slock->spin_lock);
108 return ME_ERRNO_LOCKED;
109 }
110
111 spin_unlock(&slock->spin_lock);
112
113 break;
114
115 default:
116 break;
117 }
118
119 return ME_ERRNO_SUCCESS;
120 }
121
me_slock_deinit(struct me_slock * slock)122 void me_slock_deinit(struct me_slock *slock)
123 {
124 PDEBUG_LOCKS("executed.\n");
125 }
126
me_slock_init(me_slock_t * slock)127 int me_slock_init(me_slock_t * slock)
128 {
129 PDEBUG_LOCKS("executed.\n");
130
131 slock->filep = NULL;
132 slock->count = 0;
133 spin_lock_init(&slock->spin_lock);
134
135 return 0;
136 }
137