1 /*
2 * OS Specific settings for Linux
3 *
4 * Copyright by Hannu Savolainen 1993
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 *
27 */
28
29 #define ALLOW_SELECT
30
31 #include <linux/param.h>
32 #include <linux/types.h>
33 #include <linux/errno.h>
34 #include <linux/signal.h>
35 #include <linux/fcntl.h>
36 #include <linux/sched.h>
37 #include <linux/timer.h>
38 #include <linux/tty.h>
39 #include <linux/ctype.h>
40 #include <asm/io.h>
41 #include <asm/segment.h>
42 #include <asm/system.h>
43 #include <asm/dma.h>
44 #include <sys/kd.h>
45 #include <linux/wait.h>
46 #include <linux/malloc.h>
47 #include "soundcard.h"
48
49 typedef char snd_rw_buf;
50
51 #define FALSE 0
52 #define TRUE 1
53
54 #define COPY_FROM_USER(d, s, o, c) memcpy_fromfs((d), &((s)[o]), (c))
55 #define COPY_TO_USER(d, o, s, c) memcpy_tofs(&((d)[o]), (s), (c))
56 #define IOCTL_FROM_USER(d, s, o, c) memcpy_fromfs((d), &((s)[o]), (c))
57 #define IOCTL_TO_USER(d, o, s, c) memcpy_tofs(&((d)[o]), (s), (c))
58
59 #define GET_BYTE_FROM_USER(target, addr, offs) target = get_fs_byte(&((addr)[offs]))
60 #define GET_SHORT_FROM_USER(target, addr, offs) target = get_fs_word(&((addr)[offs]))
61 #define GET_WORD_FROM_USER(target, addr, offs) target = get_fs_long((long*)&((addr)[offs]))
62 #define PUT_WORD_TO_USER(addr, offs, data) put_fs_long(data, (long*)&((addr)[offs]))
63 #define IOCTL_IN(arg) get_fs_long((long *)(arg))
64 #define IOCTL_OUT(arg, ret) snd_ioctl_return((int *)arg, ret)
65
66 /*
67 #define DEFINE_WAIT_QUEUE(name, flag) static struct wait_queue *name = NULL; static int flag = 0
68 #define DEFINE_WAIT_QUEUES(name, flag) static struct wait_queue *name = {NULL}; static int flag = {0}
69 #define PROCESS_ABORTING(wqueue, flags) (current->signal & ~current->blocked)
70 #define REQUEST_TIMEOUT(nticks, wqueue) current->timeout = jiffies + (nticks);
71 #define INTERRUPTIBLE_SLEEP_ON(q, f) \
72 {f = 1;interruptible_sleep_on(&q);f=0;}
73 */
74
75 struct snd_wait {
76 int mode; int aborting;
77 };
78
79 #define DEFINE_WAIT_QUEUE(name, flag) static struct wait_queue *name = NULL; \
80 static volatile struct snd_wait flag = {0}
81 #define DEFINE_WAIT_QUEUES(name, flag) static struct wait_queue *name = {NULL}; \
82 static volatile struct snd_wait flag = {{0}}
83 #define RESET_WAIT_QUEUE(q, f) {f.aborting = 0;f.mode = WK_NONE;}
84 #define PROCESS_ABORTING(q, f) (f.aborting | (current->signal & ~current->blocked))
85 #define SET_ABORT_FLAG(q, f) f.aborting = 1
86 #define TIMED_OUT(q, f) (f.mode & WK_TIMEOUT)
87 #define DO_SLEEP(q, f, time_limit) \
88 { unsigned long tl;\
89 if (time_limit) tl = current->timeout = jiffies + (time_limit); \
90 else tl = 0xffffffff; \
91 f.mode = WK_SLEEP;interruptible_sleep_on(&q); \
92 if (!(f.mode & WK_WAKEUP)) \
93 { \
94 if (current->signal & ~current->blocked) \
95 f.aborting = 1; \
96 else \
97 if (jiffies >= tl) f.mode |= WK_TIMEOUT; \
98 } \
99 f.mode &= ~WK_SLEEP; \
100 }
101 #define SOMEONE_WAITING(f) (f.mode & WK_SLEEP)
102 #define WAKE_UP(q, f) {f.mode = WK_WAKEUP;wake_up(&q);}
103
104 #define ALLOC_DMA_CHN(chn) request_dma(chn)
105 #define RELEASE_DMA_CHN(chn) free_dma(chn)
106
107 #define GET_TIME() jiffies
108 #define RELEASE_IRQ free_irq
109 #define RET_ERROR(err) -err
110
111 /* DISABLE_INTR is used to disable interrupts.
112 These macros store the current flags to the (unsigned long) variable given
113 as a parameter. RESTORE_INTR returns the interrupt ebable bit to state
114 before DISABLE_INTR or ENABLE_INTR */
115
116 #define DISABLE_INTR(flags) __asm__ __volatile__("pushfl ; popl %0 ; cli":"=r" (flags));
117 #define RESTORE_INTR(flags) __asm__ __volatile__("pushl %0 ; popfl": \
118 :"r" (flags));
119 /*
120 KERNEL_MALLOC() allocates requested number of memory and
121 KERNEL_FREE is used to free it.
122 These macros are never called from interrupt, in addition the
123 nbytes will never be more than 4096 bytes. Generally the driver
124 will allocate memory in blocks of 4k. If the kernel has just a
125 page level memory allocation, 4K can be safely used as the size
126 (the nbytes parameter can be ignored).
127 */
128 #define KERNEL_MALLOC(nbytes) kmalloc(nbytes, GFP_KERNEL)
129 #define KERNEL_FREE(addr) kfree(addr)
130
131 /*
132 * The macro DEFINE_TIMER defines variables for the ACTIVATE_TIMER if
133 * required. The name is the variable/name to be used and the proc is
134 * the procedure to be called when the timer expires.
135 */
136
137 #define DEFINE_TIMER(name, proc) \
138 static struct timer_list name = \
139 {NULL, 0, 0, proc}
140
141 /*
142 * The ACTIVATE_TIMER requests system to call 'proc' after 'time' ticks.
143 */
144
145 #define ACTIVATE_TIMER(name, proc, time) \
146 {name.expires = time; \
147 add_timer (&name);}
148
149 #define INB inb
150 #define OUTB outb