• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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