3 * Copyright (C) 2010 - 2013 UNISYS CORPORATION
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or (at
9 * your option) any later version.
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
14 * NON INFRINGEMENT. See the GNU General Public License for more
18 #ifndef __TIMSKMOD_H__
19 #define __TIMSKMOD_H__
21 #include <linux/version.h>
22 #include <linux/init.h>
23 #include <linux/kernel.h>
24 #include <linux/device.h>
25 #include <linux/kobject.h>
26 #include <linux/sysfs.h>
28 #include <linux/string.h>
29 #include <linux/sched.h>
30 #include <linux/spinlock.h>
31 #include <linux/slab.h>
32 #include <linux/errno.h>
33 #include <linux/interrupt.h>
34 #include <linux/sched.h>
35 #include <linux/wait.h>
36 #include <linux/vmalloc.h>
37 #include <linux/proc_fs.h>
38 #include <linux/cdev.h>
39 #include <linux/types.h>
43 #include <linux/uaccess.h>
44 #include <linux/list.h>
45 #include <linux/poll.h>
46 /* #define EXPORT_SYMTAB */
47 #include <linux/module.h>
48 #include <linux/moduleparam.h>
49 #include <linux/fcntl.h>
50 #include <linux/aio.h>
51 #include <linux/workqueue.h>
52 #include <linux/kthread.h>
53 #include <linux/seq_file.h>
66 #define DRIVERNAMEMAX 50
67 #define MIN(a, b) (((a) < (b)) ? (a) : (b))
68 #define MAX(a, b) (((a) > (b)) ? (a) : (b))
69 #define STRUCTSEQUAL(x, y) (memcmp(&x, &y, sizeof(x)) == 0)
71 #define HOSTADDRESS unsigned long long
74 #define LOCKSEM(sem) down_interruptible(sem)
75 #define LOCKSEM_UNINTERRUPTIBLE(sem) down(sem)
76 #define UNLOCKSEM(sem) up(sem)
78 /** lock read/write semaphore for reading.
79 Note that all read/write semaphores are of the "uninterruptible" variety.
80 @param sem (rw_semaphore *) points to semaphore to lock
82 #define LOCKREADSEM(sem) down_read(sem)
84 /** unlock read/write semaphore for reading.
85 Note that all read/write semaphores are of the "uninterruptible" variety.
86 @param sem (rw_semaphore *) points to semaphore to unlock
88 #define UNLOCKREADSEM(sem) up_read(sem)
90 /** lock read/write semaphore for writing.
91 Note that all read/write semaphores are of the "uninterruptible" variety.
92 @param sem (rw_semaphore *) points to semaphore to lock
94 #define LOCKWRITESEM(sem) down_write(sem)
96 /** unlock read/write semaphore for writing.
97 Note that all read/write semaphores are of the "uninterruptible" variety.
98 @param sem (rw_semaphore *) points to semaphore to unlock
100 #define UNLOCKWRITESEM(sem) up_write(sem)
102 #ifdef ENABLE_RETURN_TRACE
103 #define RETTRACE(x) \
106 INFODRV("RET 0x%lx in %s", \
107 (ulong)(x), __func__); \
114 /** Try to evaulate the provided expression, and do a RETINT(x) iff
115 * the expression evaluates to < 0.
116 * @param x the expression to try
118 #define ASSERT(cond) \
120 HUHDRV("ASSERT failed - %s", \
121 __stringify(cond)); \
124 #define sizeofmember(TYPE, MEMBER) (sizeof(((TYPE *)0)->MEMBER))
125 /** "Covered quotient" function */
126 #define COVQ(v, d) (((v) + (d) - 1) / (d))
127 #define SWAPPOINTERS(p1, p2) \
129 void *SWAPPOINTERS_TEMP = (void *)p1; \
130 (void *)(p1) = (void *)(p2); \
131 (void *)(p2) = SWAPPOINTERS_TEMP; \
135 * @addtogroup driverlogging
139 #define PRINTKDRV(fmt, args...) LOGINF(fmt, ## args)
140 #define TBDDRV(fmt, args...) LOGERR(fmt, ## args)
141 #define HUHDRV(fmt, args...) LOGERR(fmt, ## args)
142 #define ERRDRV(fmt, args...) LOGERR(fmt, ## args)
143 #define WARNDRV(fmt, args...) LOGWRN(fmt, ## args)
144 #define SECUREDRV(fmt, args...) LOGWRN(fmt, ## args)
145 #define INFODRV(fmt, args...) LOGINF(fmt, ## args)
146 #define DEBUGDRV(fmt, args...) DBGINF(fmt, ## args)
148 #define PRINTKDEV(devname, fmt, args...) LOGINFDEV(devname, fmt, ## args)
149 #define TBDDEV(devname, fmt, args...) LOGERRDEV(devname, fmt, ## args)
150 #define HUHDEV(devname, fmt, args...) LOGERRDEV(devname, fmt, ## args)
151 #define ERRDEV(devname, fmt, args...) LOGERRDEV(devname, fmt, ## args)
152 #define ERRDEVX(devno, fmt, args...) LOGERRDEVX(devno, fmt, ## args)
153 #define WARNDEV(devname, fmt, args...) LOGWRNDEV(devname, fmt, ## args)
154 #define SECUREDEV(devname, fmt, args...) LOGWRNDEV(devname, fmt, ## args)
155 #define INFODEV(devname, fmt, args...) LOGINFDEV(devname, fmt, ## args)
156 #define INFODEVX(devno, fmt, args...) LOGINFDEVX(devno, fmt, ## args)
157 #define DEBUGDEV(devname, fmt, args...) DBGINFDEV(devname, fmt, ## args)
162 /** Verifies the consistency of your PRIVATEDEVICEDATA structure using
163 * conventional "signature" fields:
165 * - sig1 should contain the size of the structure
166 * - sig2 should contain a pointer to the beginning of the structure
168 #define DDLOOKSVALID(dd) \
170 ((dd)->sig1 == sizeof(PRIVATEDEVICEDATA)) && \
173 /** Verifies the consistency of your PRIVATEFILEDATA structure using
174 * conventional "signature" fields:
176 * - sig1 should contain the size of the structure
177 * - sig2 should contain a pointer to the beginning of the structure
179 #define FDLOOKSVALID(fd) \
181 ((fd)->sig1 == sizeof(PRIVATEFILEDATA)) && \
184 /** Locks dd->lockDev if you havn't already locked it */
185 #define LOCKDEV(dd) \
188 spin_lock(&dd->lockDev); \
193 /** Unlocks dd->lockDev if you previously locked it */
194 #define UNLOCKDEV(dd) \
197 spin_unlock(&dd->lockDev); \
202 /** Locks dd->lockDevISR if you havn't already locked it */
203 #define LOCKDEVISR(dd) \
205 if (!lockedDevISR) { \
206 spin_lock_irqsave(&dd->lockDevISR, flags); \
207 lockedDevISR = TRUE; \
211 /** Unlocks dd->lockDevISR if you previously locked it */
212 #define UNLOCKDEVISR(dd) \
214 if (lockedDevISR) { \
215 spin_unlock_irqrestore(&dd->lockDevISR, flags); \
216 lockedDevISR = FALSE; \
220 /** Locks LockGlobalISR if you havn't already locked it */
221 #define LOCKGLOBALISR \
223 if (!lockedGlobalISR) { \
224 spin_lock_irqsave(&LockGlobalISR, flags); \
225 lockedGlobalISR = TRUE; \
229 /** Unlocks LockGlobalISR if you previously locked it */
230 #define UNLOCKGLOBALISR \
232 if (lockedGlobalISR) { \
233 spin_unlock_irqrestore(&LockGlobalISR, flags); \
234 lockedGlobalISR = FALSE; \
238 /** Locks LockGlobal if you havn't already locked it */
241 if (!lockedGlobal) { \
242 spin_lock(&LockGlobal); \
243 lockedGlobal = TRUE; \
247 /** Unlocks LockGlobal if you previously locked it */
248 #define UNLOCKGLOBAL \
250 if (lockedGlobal) { \
251 spin_unlock(&LockGlobal); \
252 lockedGlobal = FALSE; \
256 /** Use this at the beginning of functions where you intend to
257 * use #LOCKDEV/#UNLOCKDEV, #LOCKDEVISR/#UNLOCKDEVISR,
258 * #LOCKGLOBAL/#UNLOCKGLOBAL, #LOCKGLOBALISR/#UNLOCKGLOBALISR.
260 * Note that __attribute__((unused)) is how you tell GNU C to suppress
261 * any warning messages about the variable being unused.
263 #define LOCKPREAMBLE \
264 ulong flags __attribute__((unused)) = 0; \
265 BOOL lockedDev __attribute__((unused)) = FALSE; \
266 BOOL lockedDevISR __attribute__((unused)) = FALSE; \
267 BOOL lockedGlobal __attribute__((unused)) = FALSE; \
268 BOOL lockedGlobalISR __attribute__((unused)) = FALSE
272 /** Sleep for an indicated number of seconds (for use in kernel mode).
273 * @param x the number of seconds to sleep.
276 do { current->state = TASK_INTERRUPTIBLE; \
277 schedule_timeout((x)*HZ); \
280 /** Sleep for an indicated number of jiffies (for use in kernel mode).
281 * @param x the number of jiffies to sleep.
283 #define SLEEPJIFFIES(x) \
284 do { current->state = TASK_INTERRUPTIBLE; \
285 schedule_timeout(x); \
289 #define max(a, b) (((a) > (b)) ? (a):(b))
292 static inline struct cdev *cdev_alloc_init(struct module *owner,
293 const struct file_operations *fops)
295 struct cdev *cdev = NULL;
303 /* Note that the memory allocated for cdev will be deallocated
304 * when the usage count drops to 0, because it is controlled
305 * by a kobject of type ktype_cdev_dynamic. (This
306 * deallocation could very well happen outside of our kernel
307 * module, like via the cdev_put in __fput() for example.)
312 #include "timskmodutils.h"