blob: 5230b89b45b5bb563eb045971a5a6ebff3afcc97 [file] [log] [blame]
David Kiliani3fedd142008-11-01 00:39:12 +01001/**
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
35int 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
54int 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
65int 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
122void me_slock_deinit(struct me_slock *slock)
123{
124 PDEBUG_LOCKS("executed.\n");
125}
126
127int 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}