aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char')
-rw-r--r--drivers/char/Kconfig4
-rw-r--r--drivers/char/amiserial.c4
-rw-r--r--drivers/char/applicom.c2
-rw-r--r--drivers/char/drm/Kconfig2
-rw-r--r--drivers/char/drm/Makefile5
-rw-r--r--drivers/char/drm/drmP.h5
-rw-r--r--drivers/char/drm/drm_bufs.c25
-rw-r--r--drivers/char/drm/drm_context.c6
-rw-r--r--drivers/char/drm/drm_ioc32.c1069
-rw-r--r--drivers/char/drm/i915_dma.c24
-rw-r--r--drivers/char/drm/i915_drm.h27
-rw-r--r--drivers/char/drm/i915_drv.c25
-rw-r--r--drivers/char/drm/i915_drv.h24
-rw-r--r--drivers/char/drm/i915_irq.c24
-rw-r--r--drivers/char/drm/i915_mem.c24
-rw-r--r--drivers/char/drm/radeon_drv.c3
-rw-r--r--drivers/char/drm/radeon_drv.h3
-rw-r--r--drivers/char/drm/radeon_ioc32.c395
-rw-r--r--drivers/char/drm/radeon_irq.c27
-rw-r--r--drivers/char/ds1620.c3
-rw-r--r--drivers/char/ftape/compressor/zftape-compress.c4
-rw-r--r--drivers/char/hpet.c2
-rw-r--r--drivers/char/i8k.c909
-rw-r--r--drivers/char/ip2/i2cmd.c6
-rw-r--r--drivers/char/ip2/i2cmd.h12
-rw-r--r--drivers/char/ip2main.c10
-rw-r--r--drivers/char/isicom.c12
-rw-r--r--drivers/char/istallion.c3
-rw-r--r--drivers/char/mem.c53
-rw-r--r--drivers/char/misc.c8
-rw-r--r--drivers/char/mwave/3780i.c6
-rw-r--r--drivers/char/mwave/3780i.h4
-rw-r--r--drivers/char/mwave/tp3780i.c14
-rw-r--r--drivers/char/nvram.c6
-rw-r--r--drivers/char/rio/func.h1
-rw-r--r--drivers/char/rio/rio_linux.c5
-rw-r--r--drivers/char/rio/rioinit.c7
-rw-r--r--drivers/char/rio/riotty.c15
-rw-r--r--drivers/char/rocket.c226
-rw-r--r--drivers/char/rocket_int.h40
-rw-r--r--drivers/char/sysrq.c24
-rw-r--r--drivers/char/toshiba.c60
-rw-r--r--drivers/char/tpm/tpm.c12
-rw-r--r--drivers/char/tpm/tpm.h14
-rw-r--r--drivers/char/tpm/tpm_atmel.c16
-rw-r--r--drivers/char/tpm/tpm_nsc.c93
-rw-r--r--drivers/char/tty_io.c10
47 files changed, 2302 insertions, 971 deletions
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index 7ccf871d3c9d..43d0cb19ef6a 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -940,8 +940,8 @@ config RAW_DRIVER
940 Once bound, I/O against /dev/raw/rawN uses efficient zero-copy I/O. 940 Once bound, I/O against /dev/raw/rawN uses efficient zero-copy I/O.
941 See the raw(8) manpage for more details. 941 See the raw(8) manpage for more details.
942 942
943 The raw driver is deprecated and may be removed from 2.7 943 The raw driver is deprecated and will be removed soon.
944 kernels. Applications should simply open the device (eg /dev/hda1) 944 Applications should simply open the device (eg /dev/hda1)
945 with the O_DIRECT flag. 945 with the O_DIRECT flag.
946 946
947config HPET 947config HPET
diff --git a/drivers/char/amiserial.c b/drivers/char/amiserial.c
index 777bc499bbbd..2a36561eec68 100644
--- a/drivers/char/amiserial.c
+++ b/drivers/char/amiserial.c
@@ -1973,10 +1973,6 @@ static _INLINE_ void show_serial_version(void)
1973} 1973}
1974 1974
1975 1975
1976int register_serial(struct serial_struct *req);
1977void unregister_serial(int line);
1978
1979
1980static struct tty_operations serial_ops = { 1976static struct tty_operations serial_ops = {
1981 .open = rs_open, 1977 .open = rs_open,
1982 .close = rs_close, 1978 .close = rs_close,
diff --git a/drivers/char/applicom.c b/drivers/char/applicom.c
index 6bf2e27dc23a..11f9ee581124 100644
--- a/drivers/char/applicom.c
+++ b/drivers/char/applicom.c
@@ -599,7 +599,7 @@ static ssize_t ac_read (struct file *filp, char __user *buf, size_t count, loff_
599 599
600#ifdef DEBUG 600#ifdef DEBUG
601 if (loopcount++ > 2) { 601 if (loopcount++ > 2) {
602 printk("Looping in ac_read. loopcount %d\n", loopcount); 602 printk(KERN_DEBUG "Looping in ac_read. loopcount %d\n", loopcount);
603 } 603 }
604#endif 604#endif
605 } 605 }
diff --git a/drivers/char/drm/Kconfig b/drivers/char/drm/Kconfig
index d9a029934678..c2b12eab67c9 100644
--- a/drivers/char/drm/Kconfig
+++ b/drivers/char/drm/Kconfig
@@ -6,7 +6,7 @@
6# 6#
7config DRM 7config DRM
8 tristate "Direct Rendering Manager (XFree86 4.1.0 and higher DRI support)" 8 tristate "Direct Rendering Manager (XFree86 4.1.0 and higher DRI support)"
9 depends on AGP || AGP=n 9 depends on (AGP || AGP=n) && PCI
10 help 10 help
11 Kernel-level support for the Direct Rendering Infrastructure (DRI) 11 Kernel-level support for the Direct Rendering Infrastructure (DRI)
12 introduced in XFree86 4.0. If you say Y here, you need to select 12 introduced in XFree86 4.0. If you say Y here, you need to select
diff --git a/drivers/char/drm/Makefile b/drivers/char/drm/Makefile
index 23ab26321e9a..7444dec40b94 100644
--- a/drivers/char/drm/Makefile
+++ b/drivers/char/drm/Makefile
@@ -19,6 +19,11 @@ radeon-objs := radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o radeon_irq.o
19ffb-objs := ffb_drv.o ffb_context.o 19ffb-objs := ffb_drv.o ffb_context.o
20sis-objs := sis_drv.o sis_ds.o sis_mm.o 20sis-objs := sis_drv.o sis_ds.o sis_mm.o
21 21
22ifeq ($(CONFIG_COMPAT),y)
23drm-objs += drm_ioc32.o
24radeon-objs += radeon_ioc32.o
25endif
26
22obj-$(CONFIG_DRM) += drm.o 27obj-$(CONFIG_DRM) += drm.o
23obj-$(CONFIG_DRM_GAMMA) += gamma.o 28obj-$(CONFIG_DRM_GAMMA) += gamma.o
24obj-$(CONFIG_DRM_TDFX) += tdfx.o 29obj-$(CONFIG_DRM_TDFX) += tdfx.o
diff --git a/drivers/char/drm/drmP.h b/drivers/char/drm/drmP.h
index 21f4c54e1a8d..b04ddf12a0ff 100644
--- a/drivers/char/drm/drmP.h
+++ b/drivers/char/drm/drmP.h
@@ -316,6 +316,9 @@ do { \
316typedef int drm_ioctl_t( struct inode *inode, struct file *filp, 316typedef int drm_ioctl_t( struct inode *inode, struct file *filp,
317 unsigned int cmd, unsigned long arg ); 317 unsigned int cmd, unsigned long arg );
318 318
319typedef int drm_ioctl_compat_t(struct file *filp, unsigned int cmd,
320 unsigned long arg);
321
319typedef struct drm_ioctl_desc { 322typedef struct drm_ioctl_desc {
320 drm_ioctl_t *func; 323 drm_ioctl_t *func;
321 int auth_needed; 324 int auth_needed;
@@ -775,6 +778,8 @@ extern int drm_version(struct inode *inode, struct file *filp,
775 unsigned int cmd, unsigned long arg); 778 unsigned int cmd, unsigned long arg);
776extern int drm_ioctl(struct inode *inode, struct file *filp, 779extern int drm_ioctl(struct inode *inode, struct file *filp,
777 unsigned int cmd, unsigned long arg); 780 unsigned int cmd, unsigned long arg);
781extern long drm_compat_ioctl(struct file *filp,
782 unsigned int cmd, unsigned long arg);
778extern int drm_takedown(drm_device_t * dev); 783extern int drm_takedown(drm_device_t * dev);
779 784
780 /* Device support (drm_fops.h) */ 785 /* Device support (drm_fops.h) */
diff --git a/drivers/char/drm/drm_bufs.c b/drivers/char/drm/drm_bufs.c
index 4113bcba67fe..3407380b865a 100644
--- a/drivers/char/drm/drm_bufs.c
+++ b/drivers/char/drm/drm_bufs.c
@@ -60,6 +60,15 @@ int drm_order( unsigned long size )
60} 60}
61EXPORT_SYMBOL(drm_order); 61EXPORT_SYMBOL(drm_order);
62 62
63#ifdef CONFIG_COMPAT
64/*
65 * Used to allocate 32-bit handles for _DRM_SHM regions
66 * The 0x10000000 value is chosen to be out of the way of
67 * FB/register and GART physical addresses.
68 */
69static unsigned int map32_handle = 0x10000000;
70#endif
71
63/** 72/**
64 * Ioctl to specify a range of memory that is available for mapping by a non-root process. 73 * Ioctl to specify a range of memory that is available for mapping by a non-root process.
65 * 74 *
@@ -187,16 +196,18 @@ int drm_addmap( struct inode *inode, struct file *filp,
187 196
188 down(&dev->struct_sem); 197 down(&dev->struct_sem);
189 list_add(&list->head, &dev->maplist->head); 198 list_add(&list->head, &dev->maplist->head);
199#ifdef CONFIG_COMPAT
200 /* Assign a 32-bit handle for _DRM_SHM mappings */
201 /* We do it here so that dev->struct_sem protects the increment */
202 if (map->type == _DRM_SHM)
203 map->offset = map32_handle += PAGE_SIZE;
204#endif
190 up(&dev->struct_sem); 205 up(&dev->struct_sem);
191 206
192 if ( copy_to_user( argp, map, sizeof(*map) ) ) 207 if ( copy_to_user( argp, map, sizeof(*map) ) )
193 return -EFAULT; 208 return -EFAULT;
194 if ( map->type != _DRM_SHM ) { 209 if (copy_to_user(&argp->handle, &map->offset, sizeof(map->offset)))
195 if ( copy_to_user( &argp->handle, 210 return -EFAULT;
196 &map->offset,
197 sizeof(map->offset) ) )
198 return -EFAULT;
199 }
200 return 0; 211 return 0;
201} 212}
202 213
@@ -240,7 +251,7 @@ int drm_rmmap(struct inode *inode, struct file *filp,
240 r_list = list_entry(list, drm_map_list_t, head); 251 r_list = list_entry(list, drm_map_list_t, head);
241 252
242 if(r_list->map && 253 if(r_list->map &&
243 r_list->map->handle == request.handle && 254 r_list->map->offset == (unsigned long) request.handle &&
244 r_list->map->flags & _DRM_REMOVABLE) break; 255 r_list->map->flags & _DRM_REMOVABLE) break;
245 } 256 }
246 257
diff --git a/drivers/char/drm/drm_context.c b/drivers/char/drm/drm_context.c
index f15c86c57875..fdf661f234ed 100644
--- a/drivers/char/drm/drm_context.c
+++ b/drivers/char/drm/drm_context.c
@@ -225,7 +225,7 @@ int drm_getsareactx(struct inode *inode, struct file *filp,
225 map = dev->context_sareas[request.ctx_id]; 225 map = dev->context_sareas[request.ctx_id];
226 up(&dev->struct_sem); 226 up(&dev->struct_sem);
227 227
228 request.handle = map->handle; 228 request.handle = (void *) map->offset;
229 if (copy_to_user(argp, &request, sizeof(request))) 229 if (copy_to_user(argp, &request, sizeof(request)))
230 return -EFAULT; 230 return -EFAULT;
231 return 0; 231 return 0;
@@ -261,8 +261,8 @@ int drm_setsareactx(struct inode *inode, struct file *filp,
261 down(&dev->struct_sem); 261 down(&dev->struct_sem);
262 list_for_each(list, &dev->maplist->head) { 262 list_for_each(list, &dev->maplist->head) {
263 r_list = list_entry(list, drm_map_list_t, head); 263 r_list = list_entry(list, drm_map_list_t, head);
264 if(r_list->map && 264 if (r_list->map
265 r_list->map->handle == request.handle) 265 && r_list->map->offset == (unsigned long) request.handle)
266 goto found; 266 goto found;
267 } 267 }
268bad: 268bad:
diff --git a/drivers/char/drm/drm_ioc32.c b/drivers/char/drm/drm_ioc32.c
new file mode 100644
index 000000000000..8087a9636399
--- /dev/null
+++ b/drivers/char/drm/drm_ioc32.c
@@ -0,0 +1,1069 @@
1/**
2 * \file drm_ioc32.c
3 *
4 * 32-bit ioctl compatibility routines for the DRM.
5 *
6 * \author Paul Mackerras <paulus@samba.org>
7 *
8 * Copyright (C) Paul Mackerras 2005.
9 * All Rights Reserved.
10 *
11 * Permission is hereby granted, free of charge, to any person obtaining a
12 * copy of this software and associated documentation files (the "Software"),
13 * to deal in the Software without restriction, including without limitation
14 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
15 * and/or sell copies of the Software, and to permit persons to whom the
16 * Software is furnished to do so, subject to the following conditions:
17 *
18 * The above copyright notice and this permission notice (including the next
19 * paragraph) shall be included in all copies or substantial portions of the
20 * Software.
21 *
22 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
25 * THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
26 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
28 * IN THE SOFTWARE.
29 */
30#include <linux/compat.h>
31#include <linux/ioctl32.h>
32
33#include "drmP.h"
34#include "drm_core.h"
35
36#define DRM_IOCTL_VERSION32 DRM_IOWR(0x00, drm_version32_t)
37#define DRM_IOCTL_GET_UNIQUE32 DRM_IOWR(0x01, drm_unique32_t)
38#define DRM_IOCTL_GET_MAP32 DRM_IOWR(0x04, drm_map32_t)
39#define DRM_IOCTL_GET_CLIENT32 DRM_IOWR(0x05, drm_client32_t)
40#define DRM_IOCTL_GET_STATS32 DRM_IOR( 0x06, drm_stats32_t)
41
42#define DRM_IOCTL_SET_UNIQUE32 DRM_IOW( 0x10, drm_unique32_t)
43#define DRM_IOCTL_ADD_MAP32 DRM_IOWR(0x15, drm_map32_t)
44#define DRM_IOCTL_ADD_BUFS32 DRM_IOWR(0x16, drm_buf_desc32_t)
45#define DRM_IOCTL_MARK_BUFS32 DRM_IOW( 0x17, drm_buf_desc32_t)
46#define DRM_IOCTL_INFO_BUFS32 DRM_IOWR(0x18, drm_buf_info32_t)
47#define DRM_IOCTL_MAP_BUFS32 DRM_IOWR(0x19, drm_buf_map32_t)
48#define DRM_IOCTL_FREE_BUFS32 DRM_IOW( 0x1a, drm_buf_free32_t)
49
50#define DRM_IOCTL_RM_MAP32 DRM_IOW( 0x1b, drm_map32_t)
51
52#define DRM_IOCTL_SET_SAREA_CTX32 DRM_IOW( 0x1c, drm_ctx_priv_map32_t)
53#define DRM_IOCTL_GET_SAREA_CTX32 DRM_IOWR(0x1d, drm_ctx_priv_map32_t)
54
55#define DRM_IOCTL_RES_CTX32 DRM_IOWR(0x26, drm_ctx_res32_t)
56#define DRM_IOCTL_DMA32 DRM_IOWR(0x29, drm_dma32_t)
57
58#define DRM_IOCTL_AGP_ENABLE32 DRM_IOW( 0x32, drm_agp_mode32_t)
59#define DRM_IOCTL_AGP_INFO32 DRM_IOR( 0x33, drm_agp_info32_t)
60#define DRM_IOCTL_AGP_ALLOC32 DRM_IOWR(0x34, drm_agp_buffer32_t)
61#define DRM_IOCTL_AGP_FREE32 DRM_IOW( 0x35, drm_agp_buffer32_t)
62#define DRM_IOCTL_AGP_BIND32 DRM_IOW( 0x36, drm_agp_binding32_t)
63#define DRM_IOCTL_AGP_UNBIND32 DRM_IOW( 0x37, drm_agp_binding32_t)
64
65#define DRM_IOCTL_SG_ALLOC32 DRM_IOW( 0x38, drm_scatter_gather32_t)
66#define DRM_IOCTL_SG_FREE32 DRM_IOW( 0x39, drm_scatter_gather32_t)
67
68#define DRM_IOCTL_WAIT_VBLANK32 DRM_IOWR(0x3a, drm_wait_vblank32_t)
69
70typedef struct drm_version_32 {
71 int version_major; /**< Major version */
72 int version_minor; /**< Minor version */
73 int version_patchlevel;/**< Patch level */
74 u32 name_len; /**< Length of name buffer */
75 u32 name; /**< Name of driver */
76 u32 date_len; /**< Length of date buffer */
77 u32 date; /**< User-space buffer to hold date */
78 u32 desc_len; /**< Length of desc buffer */
79 u32 desc; /**< User-space buffer to hold desc */
80} drm_version32_t;
81
82static int compat_drm_version(struct file *file, unsigned int cmd,
83 unsigned long arg)
84{
85 drm_version32_t v32;
86 drm_version_t __user *version;
87 int err;
88
89 if (copy_from_user(&v32, (void __user *) arg, sizeof(v32)))
90 return -EFAULT;
91
92 version = compat_alloc_user_space(sizeof(*version));
93 if (!access_ok(VERIFY_WRITE, version, sizeof(*version)))
94 return -EFAULT;
95 if (__put_user(v32.name_len, &version->name_len)
96 || __put_user((void __user *)(unsigned long)v32.name,
97 &version->name)
98 || __put_user(v32.date_len, &version->date_len)
99 || __put_user((void __user *)(unsigned long)v32.date,
100 &version->date)
101 || __put_user(v32.desc_len, &version->desc_len)
102 || __put_user((void __user *)(unsigned long)v32.desc,
103 &version->desc))
104 return -EFAULT;
105
106 err = drm_ioctl(file->f_dentry->d_inode, file,
107 DRM_IOCTL_VERSION, (unsigned long) version);
108 if (err)
109 return err;
110
111 if (__get_user(v32.version_major, &version->version_major)
112 || __get_user(v32.version_minor, &version->version_minor)
113 || __get_user(v32.version_patchlevel, &version->version_patchlevel)
114 || __get_user(v32.name_len, &version->name_len)
115 || __get_user(v32.date_len, &version->date_len)
116 || __get_user(v32.desc_len, &version->desc_len))
117 return -EFAULT;
118
119 if (copy_to_user((void __user *) arg, &v32, sizeof(v32)))
120 return -EFAULT;
121 return 0;
122}
123
124typedef struct drm_unique32 {
125 u32 unique_len; /**< Length of unique */
126 u32 unique; /**< Unique name for driver instantiation */
127} drm_unique32_t;
128
129static int compat_drm_getunique(struct file *file, unsigned int cmd,
130 unsigned long arg)
131{
132 drm_unique32_t uq32;
133 drm_unique_t __user *u;
134 int err;
135
136 if (copy_from_user(&uq32, (void __user *) arg, sizeof(uq32)))
137 return -EFAULT;
138
139 u = compat_alloc_user_space(sizeof(*u));
140 if (!access_ok(VERIFY_WRITE, u, sizeof(*u)))
141 return -EFAULT;
142 if (__put_user(uq32.unique_len, &u->unique_len)
143 || __put_user((void __user *)(unsigned long) uq32.unique,
144 &u->unique))
145 return -EFAULT;
146
147 err = drm_ioctl(file->f_dentry->d_inode, file,
148 DRM_IOCTL_GET_UNIQUE, (unsigned long) u);
149 if (err)
150 return err;
151
152 if (__get_user(uq32.unique_len, &u->unique_len))
153 return -EFAULT;
154 if (copy_to_user((void __user *) arg, &uq32, sizeof(uq32)))
155 return -EFAULT;
156 return 0;
157}
158
159static int compat_drm_setunique(struct file *file, unsigned int cmd,
160 unsigned long arg)
161{
162 drm_unique32_t uq32;
163 drm_unique_t __user *u;
164
165 if (copy_from_user(&uq32, (void __user *) arg, sizeof(uq32)))
166 return -EFAULT;
167
168 u = compat_alloc_user_space(sizeof(*u));
169 if (!access_ok(VERIFY_WRITE, u, sizeof(*u)))
170 return -EFAULT;
171 if (__put_user(uq32.unique_len, &u->unique_len)
172 || __put_user((void __user *)(unsigned long) uq32.unique,
173 &u->unique))
174 return -EFAULT;
175
176 return drm_ioctl(file->f_dentry->d_inode, file,
177 DRM_IOCTL_SET_UNIQUE, (unsigned long) u);
178}
179
180typedef struct drm_map32 {
181 u32 offset; /**< Requested physical address (0 for SAREA)*/
182 u32 size; /**< Requested physical size (bytes) */
183 drm_map_type_t type; /**< Type of memory to map */
184 drm_map_flags_t flags; /**< Flags */
185 u32 handle; /**< User-space: "Handle" to pass to mmap() */
186 int mtrr; /**< MTRR slot used */
187} drm_map32_t;
188
189static int compat_drm_getmap(struct file *file, unsigned int cmd,
190 unsigned long arg)
191{
192 drm_map32_t __user *argp = (void __user *)arg;
193 drm_map32_t m32;
194 drm_map_t __user *map;
195 int idx, err;
196 void *handle;
197
198 if (get_user(idx, &argp->offset))
199 return -EFAULT;
200
201 map = compat_alloc_user_space(sizeof(*map));
202 if (!access_ok(VERIFY_WRITE, map, sizeof(*map)))
203 return -EFAULT;
204 if (__put_user(idx, &map->offset))
205 return -EFAULT;
206
207 err = drm_ioctl(file->f_dentry->d_inode, file,
208 DRM_IOCTL_GET_MAP, (unsigned long) map);
209 if (err)
210 return err;
211
212 if (__get_user(m32.offset, &map->offset)
213 || __get_user(m32.size, &map->size)
214 || __get_user(m32.type, &map->type)
215 || __get_user(m32.flags, &map->flags)
216 || __get_user(handle, &map->handle)
217 || __get_user(m32.mtrr, &map->mtrr))
218 return -EFAULT;
219
220 m32.handle = (unsigned long) handle;
221 if (copy_to_user(argp, &m32, sizeof(m32)))
222 return -EFAULT;
223 return 0;
224
225}
226
227static int compat_drm_addmap(struct file *file, unsigned int cmd,
228 unsigned long arg)
229{
230 drm_map32_t __user *argp = (void __user *)arg;
231 drm_map32_t m32;
232 drm_map_t __user *map;
233 int err;
234 void *handle;
235
236 if (copy_from_user(&m32, argp, sizeof(m32)))
237 return -EFAULT;
238
239 map = compat_alloc_user_space(sizeof(*map));
240 if (!access_ok(VERIFY_WRITE, map, sizeof(*map)))
241 return -EFAULT;
242 if (__put_user(m32.offset, &map->offset)
243 || __put_user(m32.size, &map->size)
244 || __put_user(m32.type, &map->type)
245 || __put_user(m32.flags, &map->flags))
246 return -EFAULT;
247
248 err = drm_ioctl(file->f_dentry->d_inode, file,
249 DRM_IOCTL_ADD_MAP, (unsigned long) map);
250 if (err)
251 return err;
252
253 if (__get_user(m32.offset, &map->offset)
254 || __get_user(m32.mtrr, &map->mtrr)
255 || __get_user(handle, &map->handle))
256 return -EFAULT;
257
258 m32.handle = (unsigned long) handle;
259 if (m32.handle != (unsigned long) handle && printk_ratelimit())
260 printk(KERN_ERR "compat_drm_addmap truncated handle"
261 " %p for type %d offset %x\n",
262 handle, m32.type, m32.offset);
263
264 if (copy_to_user(argp, &m32, sizeof(m32)))
265 return -EFAULT;
266
267 return 0;
268}
269
270static int compat_drm_rmmap(struct file *file, unsigned int cmd,
271 unsigned long arg)
272{
273 drm_map32_t __user *argp = (void __user *)arg;
274 drm_map_t __user *map;
275 u32 handle;
276
277 if (get_user(handle, &argp->handle))
278 return -EFAULT;
279
280 map = compat_alloc_user_space(sizeof(*map));
281 if (!access_ok(VERIFY_WRITE, map, sizeof(*map)))
282 return -EFAULT;
283 if (__put_user((void *)(unsigned long) handle, &map->handle))
284 return -EFAULT;
285
286 return drm_ioctl(file->f_dentry->d_inode, file,
287 DRM_IOCTL_RM_MAP, (unsigned long) map);
288}
289
290typedef struct drm_client32 {
291 int idx; /**< Which client desired? */
292 int auth; /**< Is client authenticated? */
293 u32 pid; /**< Process ID */
294 u32 uid; /**< User ID */
295 u32 magic; /**< Magic */
296 u32 iocs; /**< Ioctl count */
297} drm_client32_t;
298
299static int compat_drm_getclient(struct file *file, unsigned int cmd,
300 unsigned long arg)
301{
302 drm_client32_t c32;
303 drm_client32_t __user *argp = (void __user *)arg;
304 drm_client_t __user *client;
305 int idx, err;
306
307 if (get_user(idx, &argp->idx))
308 return -EFAULT;
309
310 client = compat_alloc_user_space(sizeof(*client));
311 if (!access_ok(VERIFY_WRITE, client, sizeof(*client)))
312 return -EFAULT;
313 if (__put_user(idx, &client->idx))
314 return -EFAULT;
315
316 err = drm_ioctl(file->f_dentry->d_inode, file,
317 DRM_IOCTL_GET_CLIENT, (unsigned long) client);
318 if (err)
319 return err;
320
321 if (__get_user(c32.auth, &client->auth)
322 || __get_user(c32.pid, &client->pid)
323 || __get_user(c32.uid, &client->uid)
324 || __get_user(c32.magic, &client->magic)
325 || __get_user(c32.iocs, &client->iocs))
326 return -EFAULT;
327
328 if (copy_to_user(argp, &c32, sizeof(c32)))
329 return -EFAULT;
330 return 0;
331}
332
333typedef struct drm_stats32 {
334 u32 count;
335 struct {
336 u32 value;
337 drm_stat_type_t type;
338 } data[15];
339} drm_stats32_t;
340
341static int compat_drm_getstats(struct file *file, unsigned int cmd,
342 unsigned long arg)
343{
344 drm_stats32_t s32;
345 drm_stats32_t __user *argp = (void __user *)arg;
346 drm_stats_t __user *stats;
347 int i, err;
348
349 stats = compat_alloc_user_space(sizeof(*stats));
350 if (!access_ok(VERIFY_WRITE, stats, sizeof(*stats)))
351 return -EFAULT;
352
353 err = drm_ioctl(file->f_dentry->d_inode, file,
354 DRM_IOCTL_GET_STATS, (unsigned long) stats);
355 if (err)
356 return err;
357
358 if (__get_user(s32.count, &stats->count))
359 return -EFAULT;
360 for (i = 0; i < 15; ++i)
361 if (__get_user(s32.data[i].value, &stats->data[i].value)
362 || __get_user(s32.data[i].type, &stats->data[i].type))
363 return -EFAULT;
364
365 if (copy_to_user(argp, &s32, sizeof(s32)))
366 return -EFAULT;
367 return 0;
368}
369
370typedef struct drm_buf_desc32 {
371 int count; /**< Number of buffers of this size */
372 int size; /**< Size in bytes */
373 int low_mark; /**< Low water mark */
374 int high_mark; /**< High water mark */
375 int flags;
376 u32 agp_start; /**< Start address in the AGP aperture */
377} drm_buf_desc32_t;
378
379static int compat_drm_addbufs(struct file *file, unsigned int cmd,
380 unsigned long arg)
381{
382 drm_buf_desc32_t __user *argp = (void __user *)arg;
383 drm_buf_desc_t __user *buf;
384 int err;
385 unsigned long agp_start;
386
387 buf = compat_alloc_user_space(sizeof(*buf));
388 if (!access_ok(VERIFY_WRITE, buf, sizeof(*buf))
389 || !access_ok(VERIFY_WRITE, argp, sizeof(*argp)))
390 return -EFAULT;
391
392 if (__copy_in_user(buf, argp, offsetof(drm_buf_desc32_t, agp_start))
393 || __get_user(agp_start, &argp->agp_start)
394 || __put_user(agp_start, &buf->agp_start))
395 return -EFAULT;
396
397 err = drm_ioctl(file->f_dentry->d_inode, file,
398 DRM_IOCTL_ADD_BUFS, (unsigned long) buf);
399 if (err)
400 return err;
401
402 if (__copy_in_user(argp, buf, offsetof(drm_buf_desc32_t, agp_start))
403 || __get_user(agp_start, &buf->agp_start)
404 || __put_user(agp_start, &argp->agp_start))
405 return -EFAULT;
406
407 return 0;
408}
409
410static int compat_drm_markbufs(struct file *file, unsigned int cmd,
411 unsigned long arg)
412{
413 drm_buf_desc32_t b32;
414 drm_buf_desc32_t __user *argp = (void __user *)arg;
415 drm_buf_desc_t __user *buf;
416
417 if (copy_from_user(&b32, argp, sizeof(b32)))
418 return -EFAULT;
419
420 buf = compat_alloc_user_space(sizeof(*buf));
421 if (!access_ok(VERIFY_WRITE, buf, sizeof(*buf)))
422 return -EFAULT;
423
424 if (__put_user(b32.size, &buf->size)
425 || __put_user(b32.low_mark, &buf->low_mark)
426 || __put_user(b32.high_mark, &buf->high_mark))
427 return -EFAULT;
428
429 return drm_ioctl(file->f_dentry->d_inode, file,
430 DRM_IOCTL_MARK_BUFS, (unsigned long) buf);
431}
432
433typedef struct drm_buf_info32 {
434 int count; /**< Entries in list */
435 u32 list;
436} drm_buf_info32_t;
437
438static int compat_drm_infobufs(struct file *file, unsigned int cmd,
439 unsigned long arg)
440{
441 drm_buf_info32_t req32;
442 drm_buf_info32_t __user *argp = (void __user *)arg;
443 drm_buf_desc32_t __user *to;
444 drm_buf_info_t __user *request;
445 drm_buf_desc_t __user *list;
446 size_t nbytes;
447 int i, err;
448 int count, actual;
449
450 if (copy_from_user(&req32, argp, sizeof(req32)))
451 return -EFAULT;
452
453 count = req32.count;
454 to = (drm_buf_desc32_t __user *)(unsigned long) req32.list;
455 if (count < 0)
456 count = 0;
457 if (count > 0
458 && !access_ok(VERIFY_WRITE, to, count * sizeof(drm_buf_desc32_t)))
459 return -EFAULT;
460
461 nbytes = sizeof(*request) + count * sizeof(drm_buf_desc_t);
462 request = compat_alloc_user_space(nbytes);
463 if (!access_ok(VERIFY_WRITE, request, nbytes))
464 return -EFAULT;
465 list = (drm_buf_desc_t *) (request + 1);
466
467 if (__put_user(count, &request->count)
468 || __put_user(list, &request->list))
469 return -EFAULT;
470
471 err = drm_ioctl(file->f_dentry->d_inode, file,
472 DRM_IOCTL_INFO_BUFS, (unsigned long) request);
473 if (err)
474 return err;
475
476 if (__get_user(actual, &request->count))
477 return -EFAULT;
478 if (count >= actual)
479 for (i = 0; i < actual; ++i)
480 if (__copy_in_user(&to[i], &list[i],
481 offsetof(drm_buf_desc_t, flags)))
482 return -EFAULT;
483
484 if (__put_user(actual, &argp->count))
485 return -EFAULT;
486
487 return 0;
488}
489
490typedef struct drm_buf_pub32 {
491 int idx; /**< Index into the master buffer list */
492 int total; /**< Buffer size */
493 int used; /**< Amount of buffer in use (for DMA) */
494 u32 address; /**< Address of buffer */
495} drm_buf_pub32_t;
496
497typedef struct drm_buf_map32 {
498 int count; /**< Length of the buffer list */
499 u32 virtual; /**< Mmap'd area in user-virtual */
500 u32 list; /**< Buffer information */
501} drm_buf_map32_t;
502
503static int compat_drm_mapbufs(struct file *file, unsigned int cmd,
504 unsigned long arg)
505{
506 drm_buf_map32_t __user *argp = (void __user *)arg;
507 drm_buf_map32_t req32;
508 drm_buf_pub32_t __user *list32;
509 drm_buf_map_t __user *request;
510 drm_buf_pub_t __user *list;
511 int i, err;
512 int count, actual;
513 size_t nbytes;
514 void __user *addr;
515
516 if (copy_from_user(&req32, argp, sizeof(req32)))
517 return -EFAULT;
518 count = req32.count;
519 list32 = (void __user *)(unsigned long)req32.list;
520
521 if (count < 0)
522 return -EINVAL;
523 nbytes = sizeof(*request) + count * sizeof(drm_buf_pub_t);
524 request = compat_alloc_user_space(nbytes);
525 if (!access_ok(VERIFY_WRITE, request, nbytes))
526 return -EFAULT;
527 list = (drm_buf_pub_t *) (request + 1);
528
529 if (__put_user(count, &request->count)
530 || __put_user(list, &request->list))
531 return -EFAULT;
532
533 err = drm_ioctl(file->f_dentry->d_inode, file,
534 DRM_IOCTL_MAP_BUFS, (unsigned long) request);
535 if (err)
536 return err;
537
538 if (__get_user(actual, &request->count))
539 return -EFAULT;
540 if (count >= actual)
541 for (i = 0; i < actual; ++i)
542 if (__copy_in_user(&list32[i], &list[i],
543 offsetof(drm_buf_pub_t, address))
544 || __get_user(addr, &list[i].address)
545 || __put_user((unsigned long) addr,
546 &list32[i].address))
547 return -EFAULT;
548
549 if (__put_user(actual, &argp->count)
550 || __get_user(addr, &request->virtual)
551 || __put_user((unsigned long) addr, &argp->virtual))
552 return -EFAULT;
553
554 return 0;
555}
556
557typedef struct drm_buf_free32 {
558 int count;
559 u32 list;
560} drm_buf_free32_t;
561
562static int compat_drm_freebufs(struct file *file, unsigned int cmd,
563 unsigned long arg)
564{
565 drm_buf_free32_t req32;
566 drm_buf_free_t __user *request;
567 drm_buf_free32_t __user *argp = (void __user *)arg;
568
569 if (copy_from_user(&req32, argp, sizeof(req32)))
570 return -EFAULT;
571
572 request = compat_alloc_user_space(sizeof(*request));
573 if (!access_ok(VERIFY_WRITE, request, sizeof(*request)))
574 return -EFAULT;
575 if (__put_user(req32.count, &request->count)
576 || __put_user((int __user *)(unsigned long) req32.list,
577 &request->list))
578 return -EFAULT;
579
580 return drm_ioctl(file->f_dentry->d_inode, file,
581 DRM_IOCTL_FREE_BUFS, (unsigned long) request);
582}
583
584typedef struct drm_ctx_priv_map32 {
585 unsigned int ctx_id; /**< Context requesting private mapping */
586 u32 handle; /**< Handle of map */
587} drm_ctx_priv_map32_t;
588
589static int compat_drm_setsareactx(struct file *file, unsigned int cmd,
590 unsigned long arg)
591{
592 drm_ctx_priv_map32_t req32;
593 drm_ctx_priv_map_t __user *request;
594 drm_ctx_priv_map32_t __user *argp = (void __user *)arg;
595
596 if (copy_from_user(&req32, argp, sizeof(req32)))
597 return -EFAULT;
598
599 request = compat_alloc_user_space(sizeof(*request));
600 if (!access_ok(VERIFY_WRITE, request, sizeof(*request)))
601 return -EFAULT;
602 if (__put_user(req32.ctx_id, &request->ctx_id)
603 || __put_user((void *)(unsigned long) req32.handle,
604 &request->handle))
605 return -EFAULT;
606
607 return drm_ioctl(file->f_dentry->d_inode, file,
608 DRM_IOCTL_SET_SAREA_CTX, (unsigned long) request);
609}
610
611static int compat_drm_getsareactx(struct file *file, unsigned int cmd,
612 unsigned long arg)
613{
614 drm_ctx_priv_map_t __user *request;
615 drm_ctx_priv_map32_t __user *argp = (void __user *)arg;
616 int err;
617 unsigned int ctx_id;
618 void *handle;
619
620 if (!access_ok(VERIFY_WRITE, argp, sizeof(*argp))
621 || __get_user(ctx_id, &argp->ctx_id))
622 return -EFAULT;
623
624 request = compat_alloc_user_space(sizeof(*request));
625 if (!access_ok(VERIFY_WRITE, request, sizeof(*request)))
626 return -EFAULT;
627 if (__put_user(ctx_id, &request->ctx_id))
628 return -EFAULT;
629
630 err = drm_ioctl(file->f_dentry->d_inode, file,
631 DRM_IOCTL_GET_SAREA_CTX, (unsigned long) request);
632 if (err)
633 return err;
634
635 if (__get_user(handle, &request->handle)
636 || __put_user((unsigned long) handle, &argp->handle))
637 return -EFAULT;
638
639 return 0;
640}
641
642typedef struct drm_ctx_res32 {
643 int count;
644 u32 contexts;
645} drm_ctx_res32_t;
646
647static int compat_drm_resctx(struct file *file, unsigned int cmd,
648 unsigned long arg)
649{
650 drm_ctx_res32_t __user *argp = (void __user *)arg;
651 drm_ctx_res32_t res32;
652 drm_ctx_res_t __user *res;
653 int err;
654
655 if (copy_from_user(&res32, argp, sizeof(res32)))
656 return -EFAULT;
657
658 res = compat_alloc_user_space(sizeof(*res));
659 if (!access_ok(VERIFY_WRITE, res, sizeof(*res)))
660 return -EFAULT;
661 if (__put_user(res32.count, &res->count)
662 || __put_user((drm_ctx_t __user *)(unsigned long) res32.contexts,
663 &res->contexts))
664 return -EFAULT;
665
666 err = drm_ioctl(file->f_dentry->d_inode, file,
667 DRM_IOCTL_RES_CTX, (unsigned long) res);
668 if (err)
669 return err;
670
671 if (__get_user(res32.count, &res->count)
672 || __put_user(res32.count, &argp->count))
673 return -EFAULT;
674
675 return 0;
676}
677
678typedef struct drm_dma32 {
679 int context; /**< Context handle */
680 int send_count; /**< Number of buffers to send */
681 u32 send_indices; /**< List of handles to buffers */
682 u32 send_sizes; /**< Lengths of data to send */
683 drm_dma_flags_t flags; /**< Flags */
684 int request_count; /**< Number of buffers requested */
685 int request_size; /**< Desired size for buffers */
686 u32 request_indices; /**< Buffer information */
687 u32 request_sizes;
688 int granted_count; /**< Number of buffers granted */
689} drm_dma32_t;
690
691static int compat_drm_dma(struct file *file, unsigned int cmd,
692 unsigned long arg)
693{
694 drm_dma32_t d32;
695 drm_dma32_t __user *argp = (void __user *) arg;
696 drm_dma_t __user *d;
697 int err;
698
699 if (copy_from_user(&d32, argp, sizeof(d32)))
700 return -EFAULT;
701
702 d = compat_alloc_user_space(sizeof(*d));
703 if (!access_ok(VERIFY_WRITE, d, sizeof(*d)))
704 return -EFAULT;
705
706 if (__put_user(d32.context, &d->context)
707 || __put_user(d32.send_count, &d->send_count)
708 || __put_user((int __user *)(unsigned long) d32.send_indices,
709 &d->send_indices)
710 || __put_user((int __user *)(unsigned long) d32.send_sizes,
711 &d->send_sizes)
712 || __put_user(d32.flags, &d->flags)
713 || __put_user(d32.request_count, &d->request_count)
714 || __put_user((int __user *)(unsigned long) d32.request_indices,
715 &d->request_indices)
716 || __put_user((int __user *)(unsigned long) d32.request_sizes,
717 &d->request_sizes))
718 return -EFAULT;
719
720 err = drm_ioctl(file->f_dentry->d_inode, file,
721 DRM_IOCTL_DMA, (unsigned long) d);
722 if (err)
723 return err;
724
725 if (__get_user(d32.request_size, &d->request_size)
726 || __get_user(d32.granted_count, &d->granted_count)
727 || __put_user(d32.request_size, &argp->request_size)
728 || __put_user(d32.granted_count, &argp->granted_count))
729 return -EFAULT;
730
731 return 0;
732}
733
734#if __OS_HAS_AGP
735typedef struct drm_agp_mode32 {
736 u32 mode; /**< AGP mode */
737} drm_agp_mode32_t;
738
739static int compat_drm_agp_enable(struct file *file, unsigned int cmd,
740 unsigned long arg)
741{
742 drm_agp_mode32_t __user *argp = (void __user *)arg;
743 drm_agp_mode32_t m32;
744 drm_agp_mode_t __user *mode;
745
746 if (get_user(m32.mode, &argp->mode))
747 return -EFAULT;
748
749 mode = compat_alloc_user_space(sizeof(*mode));
750 if (put_user(m32.mode, &mode->mode))
751 return -EFAULT;
752
753 return drm_ioctl(file->f_dentry->d_inode, file,
754 DRM_IOCTL_AGP_ENABLE, (unsigned long) mode);
755}
756
757typedef struct drm_agp_info32 {
758 int agp_version_major;
759 int agp_version_minor;
760 u32 mode;
761 u32 aperture_base; /* physical address */
762 u32 aperture_size; /* bytes */
763 u32 memory_allowed; /* bytes */
764 u32 memory_used;
765
766 /* PCI information */
767 unsigned short id_vendor;
768 unsigned short id_device;
769} drm_agp_info32_t;
770
771static int compat_drm_agp_info(struct file *file, unsigned int cmd,
772 unsigned long arg)
773{
774 drm_agp_info32_t __user *argp = (void __user *)arg;
775 drm_agp_info32_t i32;
776 drm_agp_info_t __user *info;
777 int err;
778
779 info = compat_alloc_user_space(sizeof(*info));
780 if (!access_ok(VERIFY_WRITE, info, sizeof(*info)))
781 return -EFAULT;
782
783 err = drm_ioctl(file->f_dentry->d_inode, file,
784 DRM_IOCTL_AGP_INFO, (unsigned long) info);
785 if (err)
786 return err;
787
788 if (__get_user(i32.agp_version_major, &info->agp_version_major)
789 || __get_user(i32.agp_version_minor, &info->agp_version_minor)
790 || __get_user(i32.mode, &info->mode)
791 || __get_user(i32.aperture_base, &info->aperture_base)
792 || __get_user(i32.aperture_size, &info->aperture_size)
793 || __get_user(i32.memory_allowed, &info->memory_allowed)
794 || __get_user(i32.memory_used, &info->memory_used)
795 || __get_user(i32.id_vendor, &info->id_vendor)
796 || __get_user(i32.id_device, &info->id_device))
797 return -EFAULT;
798
799 if (copy_to_user(argp, &i32, sizeof(i32)))
800 return -EFAULT;
801
802 return 0;
803}
804
805typedef struct drm_agp_buffer32 {
806 u32 size; /**< In bytes -- will round to page boundary */
807 u32 handle; /**< Used for binding / unbinding */
808 u32 type; /**< Type of memory to allocate */
809 u32 physical; /**< Physical used by i810 */
810} drm_agp_buffer32_t;
811
812static int compat_drm_agp_alloc(struct file *file, unsigned int cmd,
813 unsigned long arg)
814{
815 drm_agp_buffer32_t __user *argp = (void __user *)arg;
816 drm_agp_buffer32_t req32;
817 drm_agp_buffer_t __user *request;
818 int err;
819
820 if (copy_from_user(&req32, argp, sizeof(req32)))
821 return -EFAULT;
822
823 request = compat_alloc_user_space(sizeof(*request));
824 if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
825 || __put_user(req32.size, &request->size)
826 || __put_user(req32.type, &request->type))
827 return -EFAULT;
828
829 err = drm_ioctl(file->f_dentry->d_inode, file,
830 DRM_IOCTL_AGP_ALLOC, (unsigned long) request);
831 if (err)
832 return err;
833
834 if (__get_user(req32.handle, &request->handle)
835 || __get_user(req32.physical, &request->physical)
836 || copy_to_user(argp, &req32, sizeof(req32))) {
837 drm_ioctl(file->f_dentry->d_inode, file,
838 DRM_IOCTL_AGP_FREE, (unsigned long) request);
839 return -EFAULT;
840 }
841
842 return 0;
843}
844
845static int compat_drm_agp_free(struct file *file, unsigned int cmd,
846 unsigned long arg)
847{
848 drm_agp_buffer32_t __user *argp = (void __user *)arg;
849 drm_agp_buffer_t __user *request;
850 u32 handle;
851
852 request = compat_alloc_user_space(sizeof(*request));
853 if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
854 || get_user(handle, &argp->handle)
855 || __put_user(handle, &request->handle))
856 return -EFAULT;
857
858 return drm_ioctl(file->f_dentry->d_inode, file,
859 DRM_IOCTL_AGP_FREE, (unsigned long) request);
860}
861
862typedef struct drm_agp_binding32 {
863 u32 handle; /**< From drm_agp_buffer */
864 u32 offset; /**< In bytes -- will round to page boundary */
865} drm_agp_binding32_t;
866
867static int compat_drm_agp_bind(struct file *file, unsigned int cmd,
868 unsigned long arg)
869{
870 drm_agp_binding32_t __user *argp = (void __user *)arg;
871 drm_agp_binding32_t req32;
872 drm_agp_binding_t __user *request;
873
874 if (copy_from_user(&req32, argp, sizeof(req32)))
875 return -EFAULT;
876
877 request = compat_alloc_user_space(sizeof(*request));
878 if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
879 || __put_user(req32.handle, &request->handle)
880 || __put_user(req32.offset, &request->offset))
881 return -EFAULT;
882
883 return drm_ioctl(file->f_dentry->d_inode, file,
884 DRM_IOCTL_AGP_BIND, (unsigned long) request);
885}
886
887static int compat_drm_agp_unbind(struct file *file, unsigned int cmd,
888 unsigned long arg)
889{
890 drm_agp_binding32_t __user *argp = (void __user *)arg;
891 drm_agp_binding_t __user *request;
892 u32 handle;
893
894 request = compat_alloc_user_space(sizeof(*request));
895 if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
896 || get_user(handle, &argp->handle)
897 || __put_user(handle, &request->handle))
898 return -EFAULT;
899
900 return drm_ioctl(file->f_dentry->d_inode, file,
901 DRM_IOCTL_AGP_UNBIND, (unsigned long) request);
902}
903#endif /* __OS_HAS_AGP */
904
905typedef struct drm_scatter_gather32 {
906 u32 size; /**< In bytes -- will round to page boundary */
907 u32 handle; /**< Used for mapping / unmapping */
908} drm_scatter_gather32_t;
909
910static int compat_drm_sg_alloc(struct file *file, unsigned int cmd,
911 unsigned long arg)
912{
913 drm_scatter_gather32_t __user *argp = (void __user *)arg;
914 drm_scatter_gather_t __user *request;
915 int err;
916 unsigned long x;
917
918 request = compat_alloc_user_space(sizeof(*request));
919 if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
920 || !access_ok(VERIFY_WRITE, argp, sizeof(*argp))
921 || __get_user(x, &argp->size)
922 || __put_user(x, &request->size))
923 return -EFAULT;
924
925 err = drm_ioctl(file->f_dentry->d_inode, file,
926 DRM_IOCTL_SG_ALLOC, (unsigned long) request);
927 if (err)
928 return err;
929
930 /* XXX not sure about the handle conversion here... */
931 if (__get_user(x, &request->handle)
932 || __put_user(x >> PAGE_SHIFT, &argp->handle))
933 return -EFAULT;
934
935 return 0;
936}
937
938static int compat_drm_sg_free(struct file *file, unsigned int cmd,
939 unsigned long arg)
940{
941 drm_scatter_gather32_t __user *argp = (void __user *)arg;
942 drm_scatter_gather_t __user *request;
943 unsigned long x;
944
945 request = compat_alloc_user_space(sizeof(*request));
946 if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
947 || !access_ok(VERIFY_WRITE, argp, sizeof(*argp))
948 || __get_user(x, &argp->handle)
949 || __put_user(x << PAGE_SHIFT, &request->handle))
950 return -EFAULT;
951
952 return drm_ioctl(file->f_dentry->d_inode, file,
953 DRM_IOCTL_SG_FREE, (unsigned long) request);
954}
955
956struct drm_wait_vblank_request32 {
957 drm_vblank_seq_type_t type;
958 unsigned int sequence;
959 u32 signal;
960};
961
962struct drm_wait_vblank_reply32 {
963 drm_vblank_seq_type_t type;
964 unsigned int sequence;
965 s32 tval_sec;
966 s32 tval_usec;
967};
968
969typedef union drm_wait_vblank32 {
970 struct drm_wait_vblank_request32 request;
971 struct drm_wait_vblank_reply32 reply;
972} drm_wait_vblank32_t;
973
974static int compat_drm_wait_vblank(struct file *file, unsigned int cmd,
975 unsigned long arg)
976{
977 drm_wait_vblank32_t __user *argp = (void __user *)arg;
978 drm_wait_vblank32_t req32;
979 drm_wait_vblank_t __user *request;
980 int err;
981
982 if (copy_from_user(&req32, argp, sizeof(req32)))
983 return -EFAULT;
984
985 request = compat_alloc_user_space(sizeof(*request));
986 if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
987 || __put_user(req32.request.type, &request->request.type)
988 || __put_user(req32.request.sequence, &request->request.sequence)
989 || __put_user(req32.request.signal, &request->request.signal))
990 return -EFAULT;
991
992 err = drm_ioctl(file->f_dentry->d_inode, file,
993 DRM_IOCTL_WAIT_VBLANK, (unsigned long) request);
994 if (err)
995 return err;
996
997 if (__get_user(req32.reply.type, &request->reply.type)
998 || __get_user(req32.reply.sequence, &request->reply.sequence)
999 || __get_user(req32.reply.tval_sec, &request->reply.tval_sec)
1000 || __get_user(req32.reply.tval_usec, &request->reply.tval_usec))
1001 return -EFAULT;
1002
1003 if (copy_to_user(argp, &req32, sizeof(req32)))
1004 return -EFAULT;
1005
1006 return 0;
1007}
1008
1009drm_ioctl_compat_t *drm_compat_ioctls[] = {
1010 [DRM_IOCTL_NR(DRM_IOCTL_VERSION32)] = compat_drm_version,
1011 [DRM_IOCTL_NR(DRM_IOCTL_GET_UNIQUE32)] = compat_drm_getunique,
1012 [DRM_IOCTL_NR(DRM_IOCTL_GET_MAP32)] = compat_drm_getmap,
1013 [DRM_IOCTL_NR(DRM_IOCTL_GET_CLIENT32)] = compat_drm_getclient,
1014 [DRM_IOCTL_NR(DRM_IOCTL_GET_STATS32)] = compat_drm_getstats,
1015 [DRM_IOCTL_NR(DRM_IOCTL_SET_UNIQUE32)] = compat_drm_setunique,
1016 [DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP32)] = compat_drm_addmap,
1017 [DRM_IOCTL_NR(DRM_IOCTL_ADD_BUFS32)] = compat_drm_addbufs,
1018 [DRM_IOCTL_NR(DRM_IOCTL_MARK_BUFS32)] = compat_drm_markbufs,
1019 [DRM_IOCTL_NR(DRM_IOCTL_INFO_BUFS32)] = compat_drm_infobufs,
1020 [DRM_IOCTL_NR(DRM_IOCTL_MAP_BUFS32)] = compat_drm_mapbufs,
1021 [DRM_IOCTL_NR(DRM_IOCTL_FREE_BUFS32)] = compat_drm_freebufs,
1022 [DRM_IOCTL_NR(DRM_IOCTL_RM_MAP32)] = compat_drm_rmmap,
1023 [DRM_IOCTL_NR(DRM_IOCTL_SET_SAREA_CTX32)] = compat_drm_setsareactx,
1024 [DRM_IOCTL_NR(DRM_IOCTL_GET_SAREA_CTX32)] = compat_drm_getsareactx,
1025 [DRM_IOCTL_NR(DRM_IOCTL_RES_CTX32)] = compat_drm_resctx,
1026 [DRM_IOCTL_NR(DRM_IOCTL_DMA32)] = compat_drm_dma,
1027#if __OS_HAS_AGP
1028 [DRM_IOCTL_NR(DRM_IOCTL_AGP_ENABLE32)] = compat_drm_agp_enable,
1029 [DRM_IOCTL_NR(DRM_IOCTL_AGP_INFO32)] = compat_drm_agp_info,
1030 [DRM_IOCTL_NR(DRM_IOCTL_AGP_ALLOC32)] = compat_drm_agp_alloc,
1031 [DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE32)] = compat_drm_agp_free,
1032 [DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND32)] = compat_drm_agp_bind,
1033 [DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND32)] = compat_drm_agp_unbind,
1034#endif
1035 [DRM_IOCTL_NR(DRM_IOCTL_SG_ALLOC32)] = compat_drm_sg_alloc,
1036 [DRM_IOCTL_NR(DRM_IOCTL_SG_FREE32)] = compat_drm_sg_free,
1037 [DRM_IOCTL_NR(DRM_IOCTL_WAIT_VBLANK32)] = compat_drm_wait_vblank,
1038};
1039
1040/**
1041 * Called whenever a 32-bit process running under a 64-bit kernel
1042 * performs an ioctl on /dev/drm.
1043 *
1044 * \param filp file pointer.
1045 * \param cmd command.
1046 * \param arg user argument.
1047 * \return zero on success or negative number on failure.
1048 */
1049long drm_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
1050{
1051 unsigned int nr = DRM_IOCTL_NR(cmd);
1052 drm_ioctl_compat_t *fn;
1053 int ret;
1054
1055 if (nr >= DRM_ARRAY_SIZE(drm_compat_ioctls))
1056 return -ENOTTY;
1057
1058 fn = drm_compat_ioctls[nr];
1059
1060 lock_kernel(); /* XXX for now */
1061 if (fn != NULL)
1062 ret = (*fn)(filp, cmd, arg);
1063 else
1064 ret = drm_ioctl(filp->f_dentry->d_inode, filp, cmd, arg);
1065 unlock_kernel();
1066
1067 return ret;
1068}
1069EXPORT_SYMBOL(drm_compat_ioctl);
diff --git a/drivers/char/drm/i915_dma.c b/drivers/char/drm/i915_dma.c
index 7300a09dbd5c..b5903f9f1423 100644
--- a/drivers/char/drm/i915_dma.c
+++ b/drivers/char/drm/i915_dma.c
@@ -1,10 +1,30 @@
1/* i915_dma.c -- DMA support for the I915 -*- linux-c -*- 1/* i915_dma.c -- DMA support for the I915 -*- linux-c -*-
2 */ 2 */
3/************************************************************************** 3/**************************************************************************
4 * 4 *
5 * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. 5 * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
6 * All Rights Reserved. 6 * All Rights Reserved.
7 * 7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the
10 * "Software"), to deal in the Software without restriction, including
11 * without limitation the rights to use, copy, modify, merge, publish,
12 * distribute, sub license, and/or sell copies of the Software, and to
13 * permit persons to whom the Software is furnished to do so, subject to
14 * the following conditions:
15 *
16 * The above copyright notice and this permission notice (including the
17 * next paragraph) shall be included in all copies or substantial portions
18 * of the Software.
19 *
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
23 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
24 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
25 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
26 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 *
8 **************************************************************************/ 28 **************************************************************************/
9 29
10#include "drmP.h" 30#include "drmP.h"
diff --git a/drivers/char/drm/i915_drm.h b/drivers/char/drm/i915_drm.h
index 7e55edf45c4f..23e027d29080 100644
--- a/drivers/char/drm/i915_drm.h
+++ b/drivers/char/drm/i915_drm.h
@@ -1,3 +1,30 @@
1/**************************************************************************
2 *
3 * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 **************************************************************************/
27
1#ifndef _I915_DRM_H_ 28#ifndef _I915_DRM_H_
2#define _I915_DRM_H_ 29#define _I915_DRM_H_
3 30
diff --git a/drivers/char/drm/i915_drv.c b/drivers/char/drm/i915_drv.c
index 002b7082e21b..e6a9e1d1d283 100644
--- a/drivers/char/drm/i915_drv.c
+++ b/drivers/char/drm/i915_drv.c
@@ -1,11 +1,30 @@
1/* i915_drv.c -- i830,i845,i855,i865,i915 driver -*- linux-c -*- 1/* i915_drv.c -- i830,i845,i855,i865,i915 driver -*- linux-c -*-
2 */ 2 */
3
4/************************************************************************** 3/**************************************************************************
5 * 4 *
6 * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. 5 * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
7 * All Rights Reserved. 6 * All Rights Reserved.
8 * 7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the
10 * "Software"), to deal in the Software without restriction, including
11 * without limitation the rights to use, copy, modify, merge, publish,
12 * distribute, sub license, and/or sell copies of the Software, and to
13 * permit persons to whom the Software is furnished to do so, subject to
14 * the following conditions:
15 *
16 * The above copyright notice and this permission notice (including the
17 * next paragraph) shall be included in all copies or substantial portions
18 * of the Software.
19 *
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
23 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
24 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
25 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
26 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 *
9 **************************************************************************/ 28 **************************************************************************/
10 29
11#include "drmP.h" 30#include "drmP.h"
diff --git a/drivers/char/drm/i915_drv.h b/drivers/char/drm/i915_drv.h
index f6ca92a565db..fa940d64b85d 100644
--- a/drivers/char/drm/i915_drv.h
+++ b/drivers/char/drm/i915_drv.h
@@ -1,10 +1,30 @@
1/* i915_drv.h -- Private header for the I915 driver -*- linux-c -*- 1/* i915_drv.h -- Private header for the I915 driver -*- linux-c -*-
2 */ 2 */
3/************************************************************************** 3/**************************************************************************
4 * 4 *
5 * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. 5 * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
6 * All Rights Reserved. 6 * All Rights Reserved.
7 * 7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the
10 * "Software"), to deal in the Software without restriction, including
11 * without limitation the rights to use, copy, modify, merge, publish,
12 * distribute, sub license, and/or sell copies of the Software, and to
13 * permit persons to whom the Software is furnished to do so, subject to
14 * the following conditions:
15 *
16 * The above copyright notice and this permission notice (including the
17 * next paragraph) shall be included in all copies or substantial portions
18 * of the Software.
19 *
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
23 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
24 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
25 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
26 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 *
8 **************************************************************************/ 28 **************************************************************************/
9 29
10#ifndef _I915_DRV_H_ 30#ifndef _I915_DRV_H_
diff --git a/drivers/char/drm/i915_irq.c b/drivers/char/drm/i915_irq.c
index b0239262a84a..a101cc9cfd7e 100644
--- a/drivers/char/drm/i915_irq.c
+++ b/drivers/char/drm/i915_irq.c
@@ -1,10 +1,30 @@
1/* i915_dma.c -- DMA support for the I915 -*- linux-c -*- 1/* i915_dma.c -- DMA support for the I915 -*- linux-c -*-
2 */ 2 */
3/************************************************************************** 3/**************************************************************************
4 * 4 *
5 * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. 5 * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
6 * All Rights Reserved. 6 * All Rights Reserved.
7 * 7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the
10 * "Software"), to deal in the Software without restriction, including
11 * without limitation the rights to use, copy, modify, merge, publish,
12 * distribute, sub license, and/or sell copies of the Software, and to
13 * permit persons to whom the Software is furnished to do so, subject to
14 * the following conditions:
15 *
16 * The above copyright notice and this permission notice (including the
17 * next paragraph) shall be included in all copies or substantial portions
18 * of the Software.
19 *
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
23 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
24 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
25 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
26 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 *
8 **************************************************************************/ 28 **************************************************************************/
9 29
10#include "drmP.h" 30#include "drmP.h"
diff --git a/drivers/char/drm/i915_mem.c b/drivers/char/drm/i915_mem.c
index d54a3005946b..9b1698f521be 100644
--- a/drivers/char/drm/i915_mem.c
+++ b/drivers/char/drm/i915_mem.c
@@ -1,10 +1,30 @@
1/* i915_mem.c -- Simple agp/fb memory manager for i915 -*- linux-c -*- 1/* i915_mem.c -- Simple agp/fb memory manager for i915 -*- linux-c -*-
2 */ 2 */
3/************************************************************************** 3/**************************************************************************
4 * 4 *
5 * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. 5 * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
6 * All Rights Reserved. 6 * All Rights Reserved.
7 * 7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the
10 * "Software"), to deal in the Software without restriction, including
11 * without limitation the rights to use, copy, modify, merge, publish,
12 * distribute, sub license, and/or sell copies of the Software, and to
13 * permit persons to whom the Software is furnished to do so, subject to
14 * the following conditions:
15 *
16 * The above copyright notice and this permission notice (including the
17 * next paragraph) shall be included in all copies or substantial portions
18 * of the Software.
19 *
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
23 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
24 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
25 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
26 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 *
8 **************************************************************************/ 28 **************************************************************************/
9 29
10#include "drmP.h" 30#include "drmP.h"
diff --git a/drivers/char/drm/radeon_drv.c b/drivers/char/drm/radeon_drv.c
index 7b983d96e53b..18e4e5b0952f 100644
--- a/drivers/char/drm/radeon_drv.c
+++ b/drivers/char/drm/radeon_drv.c
@@ -101,6 +101,9 @@ static struct drm_driver driver = {
101 .mmap = drm_mmap, 101 .mmap = drm_mmap,
102 .poll = drm_poll, 102 .poll = drm_poll,
103 .fasync = drm_fasync, 103 .fasync = drm_fasync,
104#ifdef CONFIG_COMPAT
105 .compat_ioctl = radeon_compat_ioctl,
106#endif
104 }, 107 },
105 .pci_driver = { 108 .pci_driver = {
106 .name = DRIVER_NAME, 109 .name = DRIVER_NAME,
diff --git a/drivers/char/drm/radeon_drv.h b/drivers/char/drm/radeon_drv.h
index 5837098afae8..771aa80a5e8c 100644
--- a/drivers/char/drm/radeon_drv.h
+++ b/drivers/char/drm/radeon_drv.h
@@ -317,6 +317,9 @@ extern int radeon_preinit( struct drm_device *dev, unsigned long flags );
317extern int radeon_postinit( struct drm_device *dev, unsigned long flags ); 317extern int radeon_postinit( struct drm_device *dev, unsigned long flags );
318extern int radeon_postcleanup( struct drm_device *dev ); 318extern int radeon_postcleanup( struct drm_device *dev );
319 319
320extern long radeon_compat_ioctl(struct file *filp, unsigned int cmd,
321 unsigned long arg);
322
320/* Flags for stats.boxes 323/* Flags for stats.boxes
321 */ 324 */
322#define RADEON_BOX_DMA_IDLE 0x1 325#define RADEON_BOX_DMA_IDLE 0x1
diff --git a/drivers/char/drm/radeon_ioc32.c b/drivers/char/drm/radeon_ioc32.c
new file mode 100644
index 000000000000..bfe612215fb3
--- /dev/null
+++ b/drivers/char/drm/radeon_ioc32.c
@@ -0,0 +1,395 @@
1/**
2 * \file radeon_ioc32.c
3 *
4 * 32-bit ioctl compatibility routines for the Radeon DRM.
5 *
6 * \author Paul Mackerras <paulus@samba.org>
7 *
8 * Copyright (C) Paul Mackerras 2005
9 * All Rights Reserved.
10 *
11 * Permission is hereby granted, free of charge, to any person obtaining a
12 * copy of this software and associated documentation files (the "Software"),
13 * to deal in the Software without restriction, including without limitation
14 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
15 * and/or sell copies of the Software, and to permit persons to whom the
16 * Software is furnished to do so, subject to the following conditions:
17 *
18 * The above copyright notice and this permission notice (including the next
19 * paragraph) shall be included in all copies or substantial portions of the
20 * Software.
21 *
22 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
25 * THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
26 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
28 * IN THE SOFTWARE.
29 */
30#include <linux/compat.h>
31#include <linux/ioctl32.h>
32
33#include "drmP.h"
34#include "drm.h"
35#include "radeon_drm.h"
36#include "radeon_drv.h"
37
38typedef struct drm_radeon_init32 {
39 int func;
40 u32 sarea_priv_offset;
41 int is_pci;
42 int cp_mode;
43 int gart_size;
44 int ring_size;
45 int usec_timeout;
46
47 unsigned int fb_bpp;
48 unsigned int front_offset, front_pitch;
49 unsigned int back_offset, back_pitch;
50 unsigned int depth_bpp;
51 unsigned int depth_offset, depth_pitch;
52
53 u32 fb_offset;
54 u32 mmio_offset;
55 u32 ring_offset;
56 u32 ring_rptr_offset;
57 u32 buffers_offset;
58 u32 gart_textures_offset;
59} drm_radeon_init32_t;
60
61static int compat_radeon_cp_init(struct file *file, unsigned int cmd,
62 unsigned long arg)
63{
64 drm_radeon_init32_t init32;
65 drm_radeon_init_t __user *init;
66
67 if (copy_from_user(&init32, (void __user *)arg, sizeof(init32)))
68 return -EFAULT;
69
70 init = compat_alloc_user_space(sizeof(*init));
71 if (!access_ok(VERIFY_WRITE, init, sizeof(*init))
72 || __put_user(init32.func, &init->func)
73 || __put_user(init32.sarea_priv_offset, &init->sarea_priv_offset)
74 || __put_user(init32.is_pci, &init->is_pci)
75 || __put_user(init32.cp_mode, &init->cp_mode)
76 || __put_user(init32.gart_size, &init->gart_size)
77 || __put_user(init32.ring_size, &init->ring_size)
78 || __put_user(init32.usec_timeout, &init->usec_timeout)
79 || __put_user(init32.fb_bpp, &init->fb_bpp)
80 || __put_user(init32.front_offset, &init->front_offset)
81 || __put_user(init32.front_pitch, &init->front_pitch)
82 || __put_user(init32.back_offset, &init->back_offset)
83 || __put_user(init32.back_pitch, &init->back_pitch)
84 || __put_user(init32.depth_bpp, &init->depth_bpp)
85 || __put_user(init32.depth_offset, &init->depth_offset)
86 || __put_user(init32.depth_pitch, &init->depth_pitch)
87 || __put_user(init32.fb_offset, &init->fb_offset)
88 || __put_user(init32.mmio_offset, &init->mmio_offset)
89 || __put_user(init32.ring_offset, &init->ring_offset)
90 || __put_user(init32.ring_rptr_offset, &init->ring_rptr_offset)
91 || __put_user(init32.buffers_offset, &init->buffers_offset)
92 || __put_user(init32.gart_textures_offset,
93 &init->gart_textures_offset))
94 return -EFAULT;
95
96 return drm_ioctl(file->f_dentry->d_inode, file,
97 DRM_IOCTL_RADEON_CP_INIT, (unsigned long) init);
98}
99
100typedef struct drm_radeon_clear32 {
101 unsigned int flags;
102 unsigned int clear_color;
103 unsigned int clear_depth;
104 unsigned int color_mask;
105 unsigned int depth_mask; /* misnamed field: should be stencil */
106 u32 depth_boxes;
107} drm_radeon_clear32_t;
108
109static int compat_radeon_cp_clear(struct file *file, unsigned int cmd,
110 unsigned long arg)
111{
112 drm_radeon_clear32_t clr32;
113 drm_radeon_clear_t __user *clr;
114
115 if (copy_from_user(&clr32, (void __user *)arg, sizeof(clr32)))
116 return -EFAULT;
117
118 clr = compat_alloc_user_space(sizeof(*clr));
119 if (!access_ok(VERIFY_WRITE, clr, sizeof(*clr))
120 || __put_user(clr32.flags, &clr->flags)
121 || __put_user(clr32.clear_color, &clr->clear_color)
122 || __put_user(clr32.clear_depth, &clr->clear_depth)
123 || __put_user(clr32.color_mask, &clr->color_mask)
124 || __put_user(clr32.depth_mask, &clr->depth_mask)
125 || __put_user((void __user *)(unsigned long)clr32.depth_boxes,
126 &clr->depth_boxes))
127 return -EFAULT;
128
129 return drm_ioctl(file->f_dentry->d_inode, file,
130 DRM_IOCTL_RADEON_CLEAR, (unsigned long) clr);
131}
132
133typedef struct drm_radeon_stipple32 {
134 u32 mask;
135} drm_radeon_stipple32_t;
136
137static int compat_radeon_cp_stipple(struct file *file, unsigned int cmd,
138 unsigned long arg)
139{
140 drm_radeon_stipple32_t __user *argp = (void __user *) arg;
141 drm_radeon_stipple_t __user *request;
142 u32 mask;
143
144 if (get_user(mask, &argp->mask))
145 return -EFAULT;
146
147 request = compat_alloc_user_space(sizeof(*request));
148 if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
149 || __put_user((unsigned int __user *)(unsigned long) mask,
150 &request->mask))
151 return -EFAULT;
152
153 return drm_ioctl(file->f_dentry->d_inode, file,
154 DRM_IOCTL_RADEON_STIPPLE, (unsigned long) request);
155}
156
157typedef struct drm_radeon_tex_image32 {
158 unsigned int x, y; /* Blit coordinates */
159 unsigned int width, height;
160 u32 data;
161} drm_radeon_tex_image32_t;
162
163typedef struct drm_radeon_texture32 {
164 unsigned int offset;
165 int pitch;
166 int format;
167 int width; /* Texture image coordinates */
168 int height;
169 u32 image;
170} drm_radeon_texture32_t;
171
172static int compat_radeon_cp_texture(struct file *file, unsigned int cmd,
173 unsigned long arg)
174{
175 drm_radeon_texture32_t req32;
176 drm_radeon_texture_t __user *request;
177 drm_radeon_tex_image32_t img32;
178 drm_radeon_tex_image_t __user *image;
179
180 if (copy_from_user(&req32, (void __user *) arg, sizeof(req32)))
181 return -EFAULT;
182 if (req32.image == 0)
183 return -EINVAL;
184 if (copy_from_user(&img32, (void __user *)(unsigned long)req32.image,
185 sizeof(img32)))
186 return -EFAULT;
187
188 request = compat_alloc_user_space(sizeof(*request) + sizeof(*image));
189 if (!access_ok(VERIFY_WRITE, request,
190 sizeof(*request) + sizeof(*image)))
191 return -EFAULT;
192 image = (drm_radeon_tex_image_t __user *) (request + 1);
193
194 if (__put_user(req32.offset, &request->offset)
195 || __put_user(req32.pitch, &request->pitch)
196 || __put_user(req32.format, &request->format)
197 || __put_user(req32.width, &request->width)
198 || __put_user(req32.height, &request->height)
199 || __put_user(image, &request->image)
200 || __put_user(img32.x, &image->x)
201 || __put_user(img32.y, &image->y)
202 || __put_user(img32.width, &image->width)
203 || __put_user(img32.height, &image->height)
204 || __put_user((const void __user *)(unsigned long)img32.data,
205 &image->data))
206 return -EFAULT;
207
208 return drm_ioctl(file->f_dentry->d_inode, file,
209 DRM_IOCTL_RADEON_TEXTURE, (unsigned long) request);
210}
211
212typedef struct drm_radeon_vertex2_32 {
213 int idx; /* Index of vertex buffer */
214 int discard; /* Client finished with buffer? */
215 int nr_states;
216 u32 state;
217 int nr_prims;
218 u32 prim;
219} drm_radeon_vertex2_32_t;
220
221static int compat_radeon_cp_vertex2(struct file *file, unsigned int cmd,
222 unsigned long arg)
223{
224 drm_radeon_vertex2_32_t req32;
225 drm_radeon_vertex2_t __user *request;
226
227 if (copy_from_user(&req32, (void __user *) arg, sizeof(req32)))
228 return -EFAULT;
229
230 request = compat_alloc_user_space(sizeof(*request));
231 if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
232 || __put_user(req32.idx, &request->idx)
233 || __put_user(req32.discard, &request->discard)
234 || __put_user(req32.nr_states, &request->nr_states)
235 || __put_user((void __user *)(unsigned long)req32.state,
236 &request->state)
237 || __put_user(req32.nr_prims, &request->nr_prims)
238 || __put_user((void __user *)(unsigned long)req32.prim,
239 &request->prim))
240 return -EFAULT;
241
242 return drm_ioctl(file->f_dentry->d_inode, file,
243 DRM_IOCTL_RADEON_VERTEX2, (unsigned long) request);
244}
245
246typedef struct drm_radeon_cmd_buffer32 {
247 int bufsz;
248 u32 buf;
249 int nbox;
250 u32 boxes;
251} drm_radeon_cmd_buffer32_t;
252
253static int compat_radeon_cp_cmdbuf(struct file *file, unsigned int cmd,
254 unsigned long arg)
255{
256 drm_radeon_cmd_buffer32_t req32;
257 drm_radeon_cmd_buffer_t __user *request;
258
259 if (copy_from_user(&req32, (void __user *) arg, sizeof(req32)))
260 return -EFAULT;
261
262 request = compat_alloc_user_space(sizeof(*request));
263 if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
264 || __put_user(req32.bufsz, &request->bufsz)
265 || __put_user((void __user *)(unsigned long)req32.buf,
266 &request->buf)
267 || __put_user(req32.nbox, &request->nbox)
268 || __put_user((void __user *)(unsigned long)req32.boxes,
269 &request->boxes))
270 return -EFAULT;
271
272 return drm_ioctl(file->f_dentry->d_inode, file,
273 DRM_IOCTL_RADEON_CMDBUF, (unsigned long) request);
274}
275
276typedef struct drm_radeon_getparam32 {
277 int param;
278 u32 value;
279} drm_radeon_getparam32_t;
280
281static int compat_radeon_cp_getparam(struct file *file, unsigned int cmd,
282 unsigned long arg)
283{
284 drm_radeon_getparam32_t req32;
285 drm_radeon_getparam_t __user *request;
286
287 if (copy_from_user(&req32, (void __user *) arg, sizeof(req32)))
288 return -EFAULT;
289
290 request = compat_alloc_user_space(sizeof(*request));
291 if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
292 || __put_user(req32.param, &request->param)
293 || __put_user((void __user *)(unsigned long)req32.value,
294 &request->value))
295 return -EFAULT;
296
297 return drm_ioctl(file->f_dentry->d_inode, file,
298 DRM_IOCTL_RADEON_GETPARAM, (unsigned long) request);
299}
300
301typedef struct drm_radeon_mem_alloc32 {
302 int region;
303 int alignment;
304 int size;
305 u32 region_offset; /* offset from start of fb or GART */
306} drm_radeon_mem_alloc32_t;
307
308static int compat_radeon_mem_alloc(struct file *file, unsigned int cmd,
309 unsigned long arg)
310{
311 drm_radeon_mem_alloc32_t req32;
312 drm_radeon_mem_alloc_t __user *request;
313
314 if (copy_from_user(&req32, (void __user *) arg, sizeof(req32)))
315 return -EFAULT;
316
317 request = compat_alloc_user_space(sizeof(*request));
318 if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
319 || __put_user(req32.region, &request->region)
320 || __put_user(req32.alignment, &request->alignment)
321 || __put_user(req32.size, &request->size)
322 || __put_user((int __user *)(unsigned long)req32.region_offset,
323 &request->region_offset))
324 return -EFAULT;
325
326 return drm_ioctl(file->f_dentry->d_inode, file,
327 DRM_IOCTL_RADEON_ALLOC, (unsigned long) request);
328}
329
330typedef struct drm_radeon_irq_emit32 {
331 u32 irq_seq;
332} drm_radeon_irq_emit32_t;
333
334static int compat_radeon_irq_emit(struct file *file, unsigned int cmd,
335 unsigned long arg)
336{
337 drm_radeon_irq_emit32_t req32;
338 drm_radeon_irq_emit_t __user *request;
339
340 if (copy_from_user(&req32, (void __user *) arg, sizeof(req32)))
341 return -EFAULT;
342
343 request = compat_alloc_user_space(sizeof(*request));
344 if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
345 || __put_user((int __user *)(unsigned long)req32.irq_seq,
346 &request->irq_seq))
347 return -EFAULT;
348
349 return drm_ioctl(file->f_dentry->d_inode, file,
350 DRM_IOCTL_RADEON_IRQ_EMIT, (unsigned long) request);
351}
352
353drm_ioctl_compat_t *radeon_compat_ioctls[] = {
354 [DRM_RADEON_CP_INIT] = compat_radeon_cp_init,
355 [DRM_RADEON_CLEAR] = compat_radeon_cp_clear,
356 [DRM_RADEON_STIPPLE] = compat_radeon_cp_stipple,
357 [DRM_RADEON_TEXTURE] = compat_radeon_cp_texture,
358 [DRM_RADEON_VERTEX2] = compat_radeon_cp_vertex2,
359 [DRM_RADEON_CMDBUF] = compat_radeon_cp_cmdbuf,
360 [DRM_RADEON_GETPARAM] = compat_radeon_cp_getparam,
361 [DRM_RADEON_ALLOC] = compat_radeon_mem_alloc,
362 [DRM_RADEON_IRQ_EMIT] = compat_radeon_irq_emit,
363};
364
365/**
366 * Called whenever a 32-bit process running under a 64-bit kernel
367 * performs an ioctl on /dev/dri/card<n>.
368 *
369 * \param filp file pointer.
370 * \param cmd command.
371 * \param arg user argument.
372 * \return zero on success or negative number on failure.
373 */
374long radeon_compat_ioctl(struct file *filp, unsigned int cmd,
375 unsigned long arg)
376{
377 unsigned int nr = DRM_IOCTL_NR(cmd);
378 drm_ioctl_compat_t *fn = NULL;
379 int ret;
380
381 if (nr < DRM_COMMAND_BASE)
382 return drm_compat_ioctl(filp, cmd, arg);
383
384 if (nr < DRM_COMMAND_BASE + DRM_ARRAY_SIZE(radeon_compat_ioctls))
385 fn = radeon_compat_ioctls[nr - DRM_COMMAND_BASE];
386
387 lock_kernel(); /* XXX for now */
388 if (fn != NULL)
389 ret = (*fn)(filp, cmd, arg);
390 else
391 ret = drm_ioctl(filp->f_dentry->d_inode, filp, cmd, arg);
392 unlock_kernel();
393
394 return ret;
395}
diff --git a/drivers/char/drm/radeon_irq.c b/drivers/char/drm/radeon_irq.c
index cd25f28e26a3..40474a65f56d 100644
--- a/drivers/char/drm/radeon_irq.c
+++ b/drivers/char/drm/radeon_irq.c
@@ -35,6 +35,14 @@
35#include "radeon_drm.h" 35#include "radeon_drm.h"
36#include "radeon_drv.h" 36#include "radeon_drv.h"
37 37
38static __inline__ u32 radeon_acknowledge_irqs(drm_radeon_private_t *dev_priv, u32 mask)
39{
40 u32 irqs = RADEON_READ(RADEON_GEN_INT_STATUS) & mask;
41 if (irqs)
42 RADEON_WRITE(RADEON_GEN_INT_STATUS, irqs);
43 return irqs;
44}
45
38/* Interrupts - Used for device synchronization and flushing in the 46/* Interrupts - Used for device synchronization and flushing in the
39 * following circumstances: 47 * following circumstances:
40 * 48 *
@@ -63,8 +71,8 @@ irqreturn_t radeon_driver_irq_handler( DRM_IRQ_ARGS )
63 /* Only consider the bits we're interested in - others could be used 71 /* Only consider the bits we're interested in - others could be used
64 * outside the DRM 72 * outside the DRM
65 */ 73 */
66 stat = RADEON_READ(RADEON_GEN_INT_STATUS) 74 stat = radeon_acknowledge_irqs(dev_priv, (RADEON_SW_INT_TEST_ACK |
67 & (RADEON_SW_INT_TEST | RADEON_CRTC_VBLANK_STAT); 75 RADEON_CRTC_VBLANK_STAT));
68 if (!stat) 76 if (!stat)
69 return IRQ_NONE; 77 return IRQ_NONE;
70 78
@@ -80,19 +88,9 @@ irqreturn_t radeon_driver_irq_handler( DRM_IRQ_ARGS )
80 drm_vbl_send_signals( dev ); 88 drm_vbl_send_signals( dev );
81 } 89 }
82 90
83 /* Acknowledge interrupts we handle */
84 RADEON_WRITE(RADEON_GEN_INT_STATUS, stat);
85 return IRQ_HANDLED; 91 return IRQ_HANDLED;
86} 92}
87 93
88static __inline__ void radeon_acknowledge_irqs(drm_radeon_private_t *dev_priv)
89{
90 u32 tmp = RADEON_READ( RADEON_GEN_INT_STATUS )
91 & (RADEON_SW_INT_TEST_ACK | RADEON_CRTC_VBLANK_STAT);
92 if (tmp)
93 RADEON_WRITE( RADEON_GEN_INT_STATUS, tmp );
94}
95
96static int radeon_emit_irq(drm_device_t *dev) 94static int radeon_emit_irq(drm_device_t *dev)
97{ 95{
98 drm_radeon_private_t *dev_priv = dev->dev_private; 96 drm_radeon_private_t *dev_priv = dev->dev_private;
@@ -141,7 +139,7 @@ int radeon_driver_vblank_wait(drm_device_t *dev, unsigned int *sequence)
141 return DRM_ERR(EINVAL); 139 return DRM_ERR(EINVAL);
142 } 140 }
143 141
144 radeon_acknowledge_irqs( dev_priv ); 142 radeon_acknowledge_irqs(dev_priv, RADEON_CRTC_VBLANK_STAT);
145 143
146 dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; 144 dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE;
147 145
@@ -219,7 +217,8 @@ void radeon_driver_irq_preinstall( drm_device_t *dev ) {
219 RADEON_WRITE( RADEON_GEN_INT_CNTL, 0 ); 217 RADEON_WRITE( RADEON_GEN_INT_CNTL, 0 );
220 218
221 /* Clear bits if they're already high */ 219 /* Clear bits if they're already high */
222 radeon_acknowledge_irqs( dev_priv ); 220 radeon_acknowledge_irqs(dev_priv, (RADEON_SW_INT_TEST_ACK |
221 RADEON_CRTC_VBLANK_STAT));
223} 222}
224 223
225void radeon_driver_irq_postinstall( drm_device_t *dev ) { 224void radeon_driver_irq_postinstall( drm_device_t *dev ) {
diff --git a/drivers/char/ds1620.c b/drivers/char/ds1620.c
index 7def6ad51798..62cda25724e3 100644
--- a/drivers/char/ds1620.c
+++ b/drivers/char/ds1620.c
@@ -163,8 +163,7 @@ static void ds1620_out(int cmd, int bits, int value)
163 netwinder_ds1620_reset(); 163 netwinder_ds1620_reset();
164 netwinder_unlock(&flags); 164 netwinder_unlock(&flags);
165 165
166 set_current_state(TASK_INTERRUPTIBLE); 166 msleep(20);
167 schedule_timeout(2);
168} 167}
169 168
170static unsigned int ds1620_in(int cmd, int bits) 169static unsigned int ds1620_in(int cmd, int bits)
diff --git a/drivers/char/ftape/compressor/zftape-compress.c b/drivers/char/ftape/compressor/zftape-compress.c
index 220a227e6061..65ffc0be3df9 100644
--- a/drivers/char/ftape/compressor/zftape-compress.c
+++ b/drivers/char/ftape/compressor/zftape-compress.c
@@ -1176,8 +1176,8 @@ KERN_INFO "Compressor for zftape (lzrw3 algorithm)\n");
1176 } 1176 }
1177#else /* !MODULE */ 1177#else /* !MODULE */
1178 /* print a short no-nonsense boot message */ 1178 /* print a short no-nonsense boot message */
1179 printk("zftape compressor v1.00a 970514\n"); 1179 printk(KERN_INFO "zftape compressor v1.00a 970514\n");
1180 printk("For use with " FTAPE_VERSION "\n"); 1180 printk(KERN_INFO "For use with " FTAPE_VERSION "\n");
1181#endif /* MODULE */ 1181#endif /* MODULE */
1182 TRACE(ft_t_info, "zft_compressor_init @ 0x%p", zft_compressor_init); 1182 TRACE(ft_t_info, "zft_compressor_init @ 0x%p", zft_compressor_init);
1183 TRACE(ft_t_info, "installing compressor for zftape ..."); 1183 TRACE(ft_t_info, "installing compressor for zftape ...");
diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c
index 5ec732e6ca92..762fa430fb5b 100644
--- a/drivers/char/hpet.c
+++ b/drivers/char/hpet.c
@@ -834,7 +834,7 @@ int hpet_alloc(struct hpet_data *hdp)
834 printk("\n"); 834 printk("\n");
835 835
836 ns = hpetp->hp_period; /* femptoseconds, 10^-15 */ 836 ns = hpetp->hp_period; /* femptoseconds, 10^-15 */
837 do_div(ns, 1000000); /* convert to nanoseconds, 10^-9 */ 837 ns /= 1000000; /* convert to nanoseconds, 10^-9 */
838 printk(KERN_INFO "hpet%d: %ldns tick, %d %d-bit timers\n", 838 printk(KERN_INFO "hpet%d: %ldns tick, %d %d-bit timers\n",
839 hpetp->hp_which, ns, hpetp->hp_ntimer, 839 hpetp->hp_which, ns, hpetp->hp_ntimer,
840 cap & HPET_COUNTER_SIZE_MASK ? 64 : 32); 840 cap & HPET_COUNTER_SIZE_MASK ? 64 : 32);
diff --git a/drivers/char/i8k.c b/drivers/char/i8k.c
index a81197640283..6c4b3f986d0c 100644
--- a/drivers/char/i8k.c
+++ b/drivers/char/i8k.c
@@ -20,13 +20,14 @@
20#include <linux/types.h> 20#include <linux/types.h>
21#include <linux/init.h> 21#include <linux/init.h>
22#include <linux/proc_fs.h> 22#include <linux/proc_fs.h>
23#include <linux/apm_bios.h> 23#include <linux/seq_file.h>
24#include <linux/dmi.h>
24#include <asm/uaccess.h> 25#include <asm/uaccess.h>
25#include <asm/io.h> 26#include <asm/io.h>
26 27
27#include <linux/i8k.h> 28#include <linux/i8k.h>
28 29
29#define I8K_VERSION "1.13 14/05/2002" 30#define I8K_VERSION "1.14 21/02/2005"
30 31
31#define I8K_SMM_FN_STATUS 0x0025 32#define I8K_SMM_FN_STATUS 0x0025
32#define I8K_SMM_POWER_STATUS 0x0069 33#define I8K_SMM_POWER_STATUS 0x0069
@@ -34,7 +35,8 @@
34#define I8K_SMM_GET_FAN 0x00a3 35#define I8K_SMM_GET_FAN 0x00a3
35#define I8K_SMM_GET_SPEED 0x02a3 36#define I8K_SMM_GET_SPEED 0x02a3
36#define I8K_SMM_GET_TEMP 0x10a3 37#define I8K_SMM_GET_TEMP 0x10a3
37#define I8K_SMM_GET_DELL_SIG 0xffa3 38#define I8K_SMM_GET_DELL_SIG1 0xfea3
39#define I8K_SMM_GET_DELL_SIG2 0xffa3
38#define I8K_SMM_BIOS_VERSION 0x00a6 40#define I8K_SMM_BIOS_VERSION 0x00a6
39 41
40#define I8K_FAN_MULT 30 42#define I8K_FAN_MULT 30
@@ -52,18 +54,7 @@
52 54
53#define I8K_TEMPERATURE_BUG 1 55#define I8K_TEMPERATURE_BUG 1
54 56
55#define DELL_SIGNATURE "Dell Computer" 57static char bios_version[4];
56
57static char *supported_models[] = {
58 "Inspiron",
59 "Latitude",
60 NULL
61};
62
63static char system_vendor[48] = "?";
64static char product_name [48] = "?";
65static char bios_version [4] = "?";
66static char serial_number[16] = "?";
67 58
68MODULE_AUTHOR("Massimo Dal Zotto (dz@debian.org)"); 59MODULE_AUTHOR("Massimo Dal Zotto (dz@debian.org)");
69MODULE_DESCRIPTION("Driver for accessing SMM BIOS on Dell laptops"); 60MODULE_DESCRIPTION("Driver for accessing SMM BIOS on Dell laptops");
@@ -73,6 +64,10 @@ static int force;
73module_param(force, bool, 0); 64module_param(force, bool, 0);
74MODULE_PARM_DESC(force, "Force loading without checking for supported models"); 65MODULE_PARM_DESC(force, "Force loading without checking for supported models");
75 66
67static int ignore_dmi;
68module_param(ignore_dmi, bool, 0);
69MODULE_PARM_DESC(ignore_dmi, "Continue probing hardware even if DMI data does not match");
70
76static int restricted; 71static int restricted;
77module_param(restricted, bool, 0); 72module_param(restricted, bool, 0);
78MODULE_PARM_DESC(restricted, "Allow fan control if SYS_ADMIN capability set"); 73MODULE_PARM_DESC(restricted, "Allow fan control if SYS_ADMIN capability set");
@@ -81,69 +76,69 @@ static int power_status;
81module_param(power_status, bool, 0600); 76module_param(power_status, bool, 0600);
82MODULE_PARM_DESC(power_status, "Report power status in /proc/i8k"); 77MODULE_PARM_DESC(power_status, "Report power status in /proc/i8k");
83 78
84static ssize_t i8k_read(struct file *, char __user *, size_t, loff_t *); 79static int i8k_open_fs(struct inode *inode, struct file *file);
85static int i8k_ioctl(struct inode *, struct file *, unsigned int, 80static int i8k_ioctl(struct inode *, struct file *, unsigned int,
86 unsigned long); 81 unsigned long);
87 82
88static struct file_operations i8k_fops = { 83static struct file_operations i8k_fops = {
89 .read = i8k_read, 84 .open = i8k_open_fs,
90 .ioctl = i8k_ioctl, 85 .read = seq_read,
86 .llseek = seq_lseek,
87 .release = single_release,
88 .ioctl = i8k_ioctl,
89};
90
91struct smm_regs {
92 unsigned int eax;
93 unsigned int ebx __attribute__ ((packed));
94 unsigned int ecx __attribute__ ((packed));
95 unsigned int edx __attribute__ ((packed));
96 unsigned int esi __attribute__ ((packed));
97 unsigned int edi __attribute__ ((packed));
91}; 98};
92 99
93typedef struct { 100static inline char *i8k_get_dmi_data(int field)
94 unsigned int eax; 101{
95 unsigned int ebx __attribute__ ((packed)); 102 return dmi_get_system_info(field) ? : "N/A";
96 unsigned int ecx __attribute__ ((packed)); 103}
97 unsigned int edx __attribute__ ((packed));
98 unsigned int esi __attribute__ ((packed));
99 unsigned int edi __attribute__ ((packed));
100} SMMRegisters;
101
102typedef struct {
103 u8 type;
104 u8 length;
105 u16 handle;
106} DMIHeader;
107 104
108/* 105/*
109 * Call the System Management Mode BIOS. Code provided by Jonathan Buzzard. 106 * Call the System Management Mode BIOS. Code provided by Jonathan Buzzard.
110 */ 107 */
111static int i8k_smm(SMMRegisters *regs) 108static int i8k_smm(struct smm_regs *regs)
112{ 109{
113 int rc; 110 int rc;
114 int eax = regs->eax; 111 int eax = regs->eax;
115 112
116 asm("pushl %%eax\n\t" \ 113 asm("pushl %%eax\n\t"
117 "movl 0(%%eax),%%edx\n\t" \ 114 "movl 0(%%eax),%%edx\n\t"
118 "push %%edx\n\t" \ 115 "push %%edx\n\t"
119 "movl 4(%%eax),%%ebx\n\t" \ 116 "movl 4(%%eax),%%ebx\n\t"
120 "movl 8(%%eax),%%ecx\n\t" \ 117 "movl 8(%%eax),%%ecx\n\t"
121 "movl 12(%%eax),%%edx\n\t" \ 118 "movl 12(%%eax),%%edx\n\t"
122 "movl 16(%%eax),%%esi\n\t" \ 119 "movl 16(%%eax),%%esi\n\t"
123 "movl 20(%%eax),%%edi\n\t" \ 120 "movl 20(%%eax),%%edi\n\t"
124 "popl %%eax\n\t" \ 121 "popl %%eax\n\t"
125 "out %%al,$0xb2\n\t" \ 122 "out %%al,$0xb2\n\t"
126 "out %%al,$0x84\n\t" \ 123 "out %%al,$0x84\n\t"
127 "xchgl %%eax,(%%esp)\n\t" 124 "xchgl %%eax,(%%esp)\n\t"
128 "movl %%ebx,4(%%eax)\n\t" \ 125 "movl %%ebx,4(%%eax)\n\t"
129 "movl %%ecx,8(%%eax)\n\t" \ 126 "movl %%ecx,8(%%eax)\n\t"
130 "movl %%edx,12(%%eax)\n\t" \ 127 "movl %%edx,12(%%eax)\n\t"
131 "movl %%esi,16(%%eax)\n\t" \ 128 "movl %%esi,16(%%eax)\n\t"
132 "movl %%edi,20(%%eax)\n\t" \ 129 "movl %%edi,20(%%eax)\n\t"
133 "popl %%edx\n\t" \ 130 "popl %%edx\n\t"
134 "movl %%edx,0(%%eax)\n\t" \ 131 "movl %%edx,0(%%eax)\n\t"
135 "lahf\n\t" \ 132 "lahf\n\t"
136 "shrl $8,%%eax\n\t" \ 133 "shrl $8,%%eax\n\t"
137 "andl $1,%%eax\n" \ 134 "andl $1,%%eax\n":"=a"(rc)
138 : "=a" (rc) 135 : "a"(regs)
139 : "a" (regs) 136 : "%ebx", "%ecx", "%edx", "%esi", "%edi", "memory");
140 : "%ebx", "%ecx", "%edx", "%esi", "%edi", "memory"); 137
141 138 if (rc != 0 || (regs->eax & 0xffff) == 0xffff || regs->eax == eax)
142 if ((rc != 0) || ((regs->eax & 0xffff) == 0xffff) || (regs->eax == eax)) { 139 return -EINVAL;
143 return -EINVAL; 140
144 } 141 return 0;
145
146 return 0;
147} 142}
148 143
149/* 144/*
@@ -152,24 +147,9 @@ static int i8k_smm(SMMRegisters *regs)
152 */ 147 */
153static int i8k_get_bios_version(void) 148static int i8k_get_bios_version(void)
154{ 149{
155 SMMRegisters regs = { 0, 0, 0, 0, 0, 0 }; 150 struct smm_regs regs = { .eax = I8K_SMM_BIOS_VERSION, };
156 int rc;
157
158 regs.eax = I8K_SMM_BIOS_VERSION;
159 if ((rc=i8k_smm(&regs)) < 0) {
160 return rc;
161 }
162
163 return regs.eax;
164}
165 151
166/* 152 return i8k_smm(&regs) ? : regs.eax;
167 * Read the machine id.
168 */
169static int i8k_get_serial_number(unsigned char *buff)
170{
171 strlcpy(buff, serial_number, sizeof(serial_number));
172 return 0;
173} 153}
174 154
175/* 155/*
@@ -177,24 +157,22 @@ static int i8k_get_serial_number(unsigned char *buff)
177 */ 157 */
178static int i8k_get_fn_status(void) 158static int i8k_get_fn_status(void)
179{ 159{
180 SMMRegisters regs = { 0, 0, 0, 0, 0, 0 }; 160 struct smm_regs regs = { .eax = I8K_SMM_FN_STATUS, };
181 int rc; 161 int rc;
182 162
183 regs.eax = I8K_SMM_FN_STATUS; 163 if ((rc = i8k_smm(&regs)) < 0)
184 if ((rc=i8k_smm(&regs)) < 0) { 164 return rc;
185 return rc; 165
186 } 166 switch ((regs.eax >> I8K_FN_SHIFT) & I8K_FN_MASK) {
187 167 case I8K_FN_UP:
188 switch ((regs.eax >> I8K_FN_SHIFT) & I8K_FN_MASK) { 168 return I8K_VOL_UP;
189 case I8K_FN_UP: 169 case I8K_FN_DOWN:
190 return I8K_VOL_UP; 170 return I8K_VOL_DOWN;
191 case I8K_FN_DOWN: 171 case I8K_FN_MUTE:
192 return I8K_VOL_DOWN; 172 return I8K_VOL_MUTE;
193 case I8K_FN_MUTE: 173 default:
194 return I8K_VOL_MUTE; 174 return 0;
195 default: 175 }
196 return 0;
197 }
198} 176}
199 177
200/* 178/*
@@ -202,20 +180,13 @@ static int i8k_get_fn_status(void)
202 */ 180 */
203static int i8k_get_power_status(void) 181static int i8k_get_power_status(void)
204{ 182{
205 SMMRegisters regs = { 0, 0, 0, 0, 0, 0 }; 183 struct smm_regs regs = { .eax = I8K_SMM_POWER_STATUS, };
206 int rc; 184 int rc;
207 185
208 regs.eax = I8K_SMM_POWER_STATUS; 186 if ((rc = i8k_smm(&regs)) < 0)
209 if ((rc=i8k_smm(&regs)) < 0) { 187 return rc;
210 return rc; 188
211 } 189 return (regs.eax & 0xff) == I8K_POWER_AC ? I8K_AC : I8K_BATTERY;
212
213 switch (regs.eax & 0xff) {
214 case I8K_POWER_AC:
215 return I8K_AC;
216 default:
217 return I8K_BATTERY;
218 }
219} 190}
220 191
221/* 192/*
@@ -223,16 +194,10 @@ static int i8k_get_power_status(void)
223 */ 194 */
224static int i8k_get_fan_status(int fan) 195static int i8k_get_fan_status(int fan)
225{ 196{
226 SMMRegisters regs = { 0, 0, 0, 0, 0, 0 }; 197 struct smm_regs regs = { .eax = I8K_SMM_GET_FAN, };
227 int rc;
228
229 regs.eax = I8K_SMM_GET_FAN;
230 regs.ebx = fan & 0xff;
231 if ((rc=i8k_smm(&regs)) < 0) {
232 return rc;
233 }
234 198
235 return (regs.eax & 0xff); 199 regs.ebx = fan & 0xff;
200 return i8k_smm(&regs) ? : regs.eax & 0xff;
236} 201}
237 202
238/* 203/*
@@ -240,16 +205,10 @@ static int i8k_get_fan_status(int fan)
240 */ 205 */
241static int i8k_get_fan_speed(int fan) 206static int i8k_get_fan_speed(int fan)
242{ 207{
243 SMMRegisters regs = { 0, 0, 0, 0, 0, 0 }; 208 struct smm_regs regs = { .eax = I8K_SMM_GET_SPEED, };
244 int rc;
245 209
246 regs.eax = I8K_SMM_GET_SPEED; 210 regs.ebx = fan & 0xff;
247 regs.ebx = fan & 0xff; 211 return i8k_smm(&regs) ? : (regs.eax & 0xffff) * I8K_FAN_MULT;
248 if ((rc=i8k_smm(&regs)) < 0) {
249 return rc;
250 }
251
252 return (regs.eax & 0xffff) * I8K_FAN_MULT;
253} 212}
254 213
255/* 214/*
@@ -257,532 +216,318 @@ static int i8k_get_fan_speed(int fan)
257 */ 216 */
258static int i8k_set_fan(int fan, int speed) 217static int i8k_set_fan(int fan, int speed)
259{ 218{
260 SMMRegisters regs = { 0, 0, 0, 0, 0, 0 }; 219 struct smm_regs regs = { .eax = I8K_SMM_SET_FAN, };
261 int rc;
262
263 speed = (speed < 0) ? 0 : ((speed > I8K_FAN_MAX) ? I8K_FAN_MAX : speed);
264 220
265 regs.eax = I8K_SMM_SET_FAN; 221 speed = (speed < 0) ? 0 : ((speed > I8K_FAN_MAX) ? I8K_FAN_MAX : speed);
266 regs.ebx = (fan & 0xff) | (speed << 8); 222 regs.ebx = (fan & 0xff) | (speed << 8);
267 if ((rc=i8k_smm(&regs)) < 0) {
268 return rc;
269 }
270 223
271 return (i8k_get_fan_status(fan)); 224 return i8k_smm(&regs) ? : i8k_get_fan_status(fan);
272} 225}
273 226
274/* 227/*
275 * Read the cpu temperature. 228 * Read the cpu temperature.
276 */ 229 */
277static int i8k_get_cpu_temp(void) 230static int i8k_get_temp(int sensor)
278{ 231{
279 SMMRegisters regs = { 0, 0, 0, 0, 0, 0 }; 232 struct smm_regs regs = { .eax = I8K_SMM_GET_TEMP, };
280 int rc; 233 int rc;
281 int temp; 234 int temp;
282 235
283#ifdef I8K_TEMPERATURE_BUG 236#ifdef I8K_TEMPERATURE_BUG
284 static int prev = 0; 237 static int prev;
285#endif 238#endif
239 regs.ebx = sensor & 0xff;
240 if ((rc = i8k_smm(&regs)) < 0)
241 return rc;
286 242
287 regs.eax = I8K_SMM_GET_TEMP; 243 temp = regs.eax & 0xff;
288 if ((rc=i8k_smm(&regs)) < 0) {
289 return rc;
290 }
291 temp = regs.eax & 0xff;
292 244
293#ifdef I8K_TEMPERATURE_BUG 245#ifdef I8K_TEMPERATURE_BUG
294 /* 246 /*
295 * Sometimes the temperature sensor returns 0x99, which is out of range. 247 * Sometimes the temperature sensor returns 0x99, which is out of range.
296 * In this case we return (once) the previous cached value. For example: 248 * In this case we return (once) the previous cached value. For example:
297 # 1003655137 00000058 00005a4b 249 # 1003655137 00000058 00005a4b
298 # 1003655138 00000099 00003a80 <--- 0x99 = 153 degrees 250 # 1003655138 00000099 00003a80 <--- 0x99 = 153 degrees
299 # 1003655139 00000054 00005c52 251 # 1003655139 00000054 00005c52
300 */ 252 */
301 if (temp > I8K_MAX_TEMP) { 253 if (temp > I8K_MAX_TEMP) {
302 temp = prev; 254 temp = prev;
303 prev = I8K_MAX_TEMP; 255 prev = I8K_MAX_TEMP;
304 } else { 256 } else {
305 prev = temp; 257 prev = temp;
306 } 258 }
307#endif 259#endif
308 260
309 return temp; 261 return temp;
310} 262}
311 263
312static int i8k_get_dell_signature(void) 264static int i8k_get_dell_signature(int req_fn)
313{ 265{
314 SMMRegisters regs = { 0, 0, 0, 0, 0, 0 }; 266 struct smm_regs regs = { .eax = req_fn, };
315 int rc; 267 int rc;
316 268
317 regs.eax = I8K_SMM_GET_DELL_SIG; 269 if ((rc = i8k_smm(&regs)) < 0)
318 if ((rc=i8k_smm(&regs)) < 0) { 270 return rc;
319 return rc;
320 }
321 271
322 if ((regs.eax == 1145651527) && (regs.edx == 1145392204)) { 272 return regs.eax == 1145651527 && regs.edx == 1145392204 ? 0 : -1;
323 return 0;
324 } else {
325 return -1;
326 }
327} 273}
328 274
329static int i8k_ioctl(struct inode *ip, struct file *fp, unsigned int cmd, 275static int i8k_ioctl(struct inode *ip, struct file *fp, unsigned int cmd,
330 unsigned long arg) 276 unsigned long arg)
331{ 277{
332 int val; 278 int val = 0;
333 int speed; 279 int speed;
334 unsigned char buff[16]; 280 unsigned char buff[16];
335 int __user *argp = (int __user *)arg; 281 int __user *argp = (int __user *)arg;
336
337 if (!argp)
338 return -EINVAL;
339
340 switch (cmd) {
341 case I8K_BIOS_VERSION:
342 val = i8k_get_bios_version();
343 break;
344
345 case I8K_MACHINE_ID:
346 memset(buff, 0, 16);
347 val = i8k_get_serial_number(buff);
348 break;
349
350 case I8K_FN_STATUS:
351 val = i8k_get_fn_status();
352 break;
353
354 case I8K_POWER_STATUS:
355 val = i8k_get_power_status();
356 break;
357
358 case I8K_GET_TEMP:
359 val = i8k_get_cpu_temp();
360 break;
361
362 case I8K_GET_SPEED:
363 if (copy_from_user(&val, argp, sizeof(int))) {
364 return -EFAULT;
365 }
366 val = i8k_get_fan_speed(val);
367 break;
368
369 case I8K_GET_FAN:
370 if (copy_from_user(&val, argp, sizeof(int))) {
371 return -EFAULT;
372 }
373 val = i8k_get_fan_status(val);
374 break;
375 282
376 case I8K_SET_FAN: 283 if (!argp)
377 if (restricted && !capable(CAP_SYS_ADMIN)) { 284 return -EINVAL;
378 return -EPERM;
379 }
380 if (copy_from_user(&val, argp, sizeof(int))) {
381 return -EFAULT;
382 }
383 if (copy_from_user(&speed, argp+1, sizeof(int))) {
384 return -EFAULT;
385 }
386 val = i8k_set_fan(val, speed);
387 break;
388 285
389 default: 286 switch (cmd) {
390 return -EINVAL; 287 case I8K_BIOS_VERSION:
391 } 288 val = i8k_get_bios_version();
289 break;
392 290
393 if (val < 0) { 291 case I8K_MACHINE_ID:
394 return val; 292 memset(buff, 0, 16);
395 } 293 strlcpy(buff, i8k_get_dmi_data(DMI_PRODUCT_SERIAL), sizeof(buff));
294 break;
396 295
397 switch (cmd) { 296 case I8K_FN_STATUS:
398 case I8K_BIOS_VERSION: 297 val = i8k_get_fn_status();
399 if (copy_to_user(argp, &val, 4)) { 298 break;
400 return -EFAULT;
401 }
402 break;
403 case I8K_MACHINE_ID:
404 if (copy_to_user(argp, buff, 16)) {
405 return -EFAULT;
406 }
407 break;
408 default:
409 if (copy_to_user(argp, &val, sizeof(int))) {
410 return -EFAULT;
411 }
412 break;
413 }
414 299
415 return 0; 300 case I8K_POWER_STATUS:
416} 301 val = i8k_get_power_status();
302 break;
417 303
418/* 304 case I8K_GET_TEMP:
419 * Print the information for /proc/i8k. 305 val = i8k_get_temp(0);
420 */ 306 break;
421static int i8k_get_info(char *buffer, char **start, off_t fpos, int length)
422{
423 int n, fn_key, cpu_temp, ac_power;
424 int left_fan, right_fan, left_speed, right_speed;
425
426 cpu_temp = i8k_get_cpu_temp(); /* 11100 µs */
427 left_fan = i8k_get_fan_status(I8K_FAN_LEFT); /* 580 µs */
428 right_fan = i8k_get_fan_status(I8K_FAN_RIGHT); /* 580 µs */
429 left_speed = i8k_get_fan_speed(I8K_FAN_LEFT); /* 580 µs */
430 right_speed = i8k_get_fan_speed(I8K_FAN_RIGHT); /* 580 µs */
431 fn_key = i8k_get_fn_status(); /* 750 µs */
432 if (power_status) {
433 ac_power = i8k_get_power_status(); /* 14700 µs */
434 } else {
435 ac_power = -1;
436 }
437
438 /*
439 * Info:
440 *
441 * 1) Format version (this will change if format changes)
442 * 2) BIOS version
443 * 3) BIOS machine ID
444 * 4) Cpu temperature
445 * 5) Left fan status
446 * 6) Right fan status
447 * 7) Left fan speed
448 * 8) Right fan speed
449 * 9) AC power
450 * 10) Fn Key status
451 */
452 n = sprintf(buffer, "%s %s %s %d %d %d %d %d %d %d\n",
453 I8K_PROC_FMT,
454 bios_version,
455 serial_number,
456 cpu_temp,
457 left_fan,
458 right_fan,
459 left_speed,
460 right_speed,
461 ac_power,
462 fn_key);
463
464 return n;
465}
466 307
467static ssize_t i8k_read(struct file *f, char __user *buffer, size_t len, loff_t *fpos) 308 case I8K_GET_SPEED:
468{ 309 if (copy_from_user(&val, argp, sizeof(int)))
469 int n; 310 return -EFAULT;
470 char info[128];
471 311
472 n = i8k_get_info(info, NULL, 0, 128); 312 val = i8k_get_fan_speed(val);
473 if (n <= 0) { 313 break;
474 return n;
475 }
476 314
477 if (*fpos >= n) { 315 case I8K_GET_FAN:
478 return 0; 316 if (copy_from_user(&val, argp, sizeof(int)))
479 } 317 return -EFAULT;
480 318
481 if ((*fpos + len) >= n) { 319 val = i8k_get_fan_status(val);
482 len = n - *fpos; 320 break;
483 }
484 321
485 if (copy_to_user(buffer, info, len) != 0) { 322 case I8K_SET_FAN:
486 return -EFAULT; 323 if (restricted && !capable(CAP_SYS_ADMIN))
487 } 324 return -EPERM;
488 325
489 *fpos += len; 326 if (copy_from_user(&val, argp, sizeof(int)))
490 return len; 327 return -EFAULT;
491}
492 328
493static char* __init string_trim(char *s, int size) 329 if (copy_from_user(&speed, argp + 1, sizeof(int)))
494{ 330 return -EFAULT;
495 int len;
496 char *p;
497 331
498 if ((len = strlen(s)) > size) { 332 val = i8k_set_fan(val, speed);
499 len = size; 333 break;
500 }
501 334
502 for (p=s+len-1; len && (*p==' '); len--,p--) { 335 default:
503 *p = '\0'; 336 return -EINVAL;
504 } 337 }
505 338
506 return s; 339 if (val < 0)
507} 340 return val;
508 341
509/* DMI code, stolen from arch/i386/kernel/dmi_scan.c */ 342 switch (cmd) {
343 case I8K_BIOS_VERSION:
344 if (copy_to_user(argp, &val, 4))
345 return -EFAULT;
510 346
511/* 347 break;
512 * |<-- dmi->length -->| 348 case I8K_MACHINE_ID:
513 * | | 349 if (copy_to_user(argp, buff, 16))
514 * |dmi header s=N | string1,\0, ..., stringN,\0, ..., \0 350 return -EFAULT;
515 * | |
516 * +-----------------------+
517 */
518static char* __init dmi_string(DMIHeader *dmi, u8 s)
519{
520 u8 *p;
521 351
522 if (!s) { 352 break;
523 return ""; 353 default:
524 } 354 if (copy_to_user(argp, &val, sizeof(int)))
525 s--; 355 return -EFAULT;
526 356
527 p = (u8 *)dmi + dmi->length; 357 break;
528 while (s > 0) { 358 }
529 p += strlen(p);
530 p++;
531 s--;
532 }
533 359
534 return p; 360 return 0;
535} 361}
536 362
537static void __init dmi_decode(DMIHeader *dmi) 363/*
364 * Print the information for /proc/i8k.
365 */
366static int i8k_proc_show(struct seq_file *seq, void *offset)
538{ 367{
539 u8 *data = (u8 *) dmi; 368 int fn_key, cpu_temp, ac_power;
540 char *p; 369 int left_fan, right_fan, left_speed, right_speed;
541 370
542#ifdef I8K_DEBUG 371 cpu_temp = i8k_get_temp(0); /* 11100 µs */
543 int i; 372 left_fan = i8k_get_fan_status(I8K_FAN_LEFT); /* 580 µs */
544 printk("%08x ", (int)data); 373 right_fan = i8k_get_fan_status(I8K_FAN_RIGHT); /* 580 µs */
545 for (i=0; i<data[1] && i<64; i++) { 374 left_speed = i8k_get_fan_speed(I8K_FAN_LEFT); /* 580 µs */
546 printk("%02x ", data[i]); 375 right_speed = i8k_get_fan_speed(I8K_FAN_RIGHT); /* 580 µs */
547 } 376 fn_key = i8k_get_fn_status(); /* 750 µs */
548 printk("\n"); 377 if (power_status)
549#endif 378 ac_power = i8k_get_power_status(); /* 14700 µs */
550 379 else
551 switch (dmi->type) { 380 ac_power = -1;
552 case 0: /* BIOS Information */
553 p = dmi_string(dmi,data[5]);
554 if (*p) {
555 strlcpy(bios_version, p, sizeof(bios_version));
556 string_trim(bios_version, sizeof(bios_version));
557 }
558 break;
559 case 1: /* System Information */
560 p = dmi_string(dmi,data[4]);
561 if (*p) {
562 strlcpy(system_vendor, p, sizeof(system_vendor));
563 string_trim(system_vendor, sizeof(system_vendor));
564 }
565 p = dmi_string(dmi,data[5]);
566 if (*p) {
567 strlcpy(product_name, p, sizeof(product_name));
568 string_trim(product_name, sizeof(product_name));
569 }
570 p = dmi_string(dmi,data[7]);
571 if (*p) {
572 strlcpy(serial_number, p, sizeof(serial_number));
573 string_trim(serial_number, sizeof(serial_number));
574 }
575 break;
576 }
577}
578 381
579static int __init dmi_table(u32 base, int len, int num, void (*fn)(DMIHeader*))
580{
581 u8 *buf;
582 u8 *data;
583 DMIHeader *dmi;
584 int i = 1;
585
586 buf = ioremap(base, len);
587 if (buf == NULL) {
588 return -1;
589 }
590 data = buf;
591
592 /*
593 * Stop when we see al the items the table claimed to have
594 * or we run off the end of the table (also happens)
595 */
596 while ((i<num) && ((data-buf) < len)) {
597 dmi = (DMIHeader *)data;
598 /*
599 * Avoid misparsing crud if the length of the last
600 * record is crap
601 */
602 if ((data-buf+dmi->length) >= len) {
603 break;
604 }
605 fn(dmi);
606 data += dmi->length;
607 /* 382 /*
608 * Don't go off the end of the data if there is 383 * Info:
609 * stuff looking like string fill past the end 384 *
385 * 1) Format version (this will change if format changes)
386 * 2) BIOS version
387 * 3) BIOS machine ID
388 * 4) Cpu temperature
389 * 5) Left fan status
390 * 6) Right fan status
391 * 7) Left fan speed
392 * 8) Right fan speed
393 * 9) AC power
394 * 10) Fn Key status
610 */ 395 */
611 while (((data-buf) < len) && (*data || data[1])) { 396 return seq_printf(seq, "%s %s %s %d %d %d %d %d %d %d\n",
612 data++; 397 I8K_PROC_FMT,
613 } 398 bios_version,
614 data += 2; 399 dmi_get_system_info(DMI_PRODUCT_SERIAL) ? : "N/A",
615 i++; 400 cpu_temp,
616 } 401 left_fan, right_fan, left_speed, right_speed,
617 iounmap(buf); 402 ac_power, fn_key);
618
619 return 0;
620} 403}
621 404
622static int __init dmi_iterate(void (*decode)(DMIHeader *)) 405static int i8k_open_fs(struct inode *inode, struct file *file)
623{ 406{
624 unsigned char buf[20]; 407 return single_open(file, i8k_proc_show, NULL);
625 void __iomem *p = ioremap(0xe0000, 0x20000), *q;
626
627 if (!p)
628 return -1;
629
630 for (q = p; q < p + 0x20000; q += 16) {
631 memcpy_fromio(buf, q, 20);
632 if (memcmp(buf, "_DMI_", 5)==0) {
633 u16 num = buf[13]<<8 | buf[12];
634 u16 len = buf [7]<<8 | buf [6];
635 u32 base = buf[11]<<24 | buf[10]<<16 | buf[9]<<8 | buf[8];
636#ifdef I8K_DEBUG
637 printk(KERN_INFO "DMI %d.%d present.\n",
638 buf[14]>>4, buf[14]&0x0F);
639 printk(KERN_INFO "%d structures occupying %d bytes.\n",
640 buf[13]<<8 | buf[12],
641 buf [7]<<8 | buf[6]);
642 printk(KERN_INFO "DMI table at 0x%08X.\n",
643 buf[11]<<24 | buf[10]<<16 | buf[9]<<8 | buf[8]);
644#endif
645 if (dmi_table(base, len, num, decode)==0) {
646 iounmap(p);
647 return 0;
648 }
649 }
650 }
651 iounmap(p);
652 return -1;
653} 408}
654/* end of DMI code */
655
656/*
657 * Get DMI information.
658 */
659static int __init i8k_dmi_probe(void)
660{
661 char **p;
662
663 if (dmi_iterate(dmi_decode) != 0) {
664 printk(KERN_INFO "i8k: unable to get DMI information\n");
665 return -ENODEV;
666 }
667
668 if (strncmp(system_vendor,DELL_SIGNATURE,strlen(DELL_SIGNATURE)) != 0) {
669 printk(KERN_INFO "i8k: not running on a Dell system\n");
670 return -ENODEV;
671 }
672
673 for (p=supported_models; ; p++) {
674 if (!*p) {
675 printk(KERN_INFO "i8k: unsupported model: %s\n", product_name);
676 return -ENODEV;
677 }
678 if (strncmp(product_name,*p,strlen(*p)) == 0) {
679 break;
680 }
681 }
682 409
683 return 0; 410static struct dmi_system_id __initdata i8k_dmi_table[] = {
684} 411 {
412 .ident = "Dell Inspiron",
413 .matches = {
414 DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer"),
415 DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron"),
416 },
417 },
418 {
419 .ident = "Dell Latitude",
420 .matches = {
421 DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer"),
422 DMI_MATCH(DMI_PRODUCT_NAME, "Latitude"),
423 },
424 },
425 {
426 .ident = "Dell Inspiron 2",
427 .matches = {
428 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
429 DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron"),
430 },
431 },
432 {
433 .ident = "Dell Latitude 2",
434 .matches = {
435 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
436 DMI_MATCH(DMI_PRODUCT_NAME, "Latitude"),
437 },
438 },
439 { }
440};
685 441
686/* 442/*
687 * Probe for the presence of a supported laptop. 443 * Probe for the presence of a supported laptop.
688 */ 444 */
689static int __init i8k_probe(void) 445static int __init i8k_probe(void)
690{ 446{
691 char buff[4]; 447 char buff[4];
692 int version; 448 int version;
693 int smm_found = 0; 449
694
695 /*
696 * Get DMI information
697 */
698 if (i8k_dmi_probe() != 0) {
699 printk(KERN_INFO "i8k: vendor=%s, model=%s, version=%s\n",
700 system_vendor, product_name, bios_version);
701 }
702
703 /*
704 * Get SMM Dell signature
705 */
706 if (i8k_get_dell_signature() != 0) {
707 printk(KERN_INFO "i8k: unable to get SMM Dell signature\n");
708 } else {
709 smm_found = 1;
710 }
711
712 /*
713 * Get SMM BIOS version.
714 */
715 version = i8k_get_bios_version();
716 if (version <= 0) {
717 printk(KERN_INFO "i8k: unable to get SMM BIOS version\n");
718 } else {
719 smm_found = 1;
720 buff[0] = (version >> 16) & 0xff;
721 buff[1] = (version >> 8) & 0xff;
722 buff[2] = (version) & 0xff;
723 buff[3] = '\0';
724 /* 450 /*
725 * If DMI BIOS version is unknown use SMM BIOS version. 451 * Get DMI information
726 */ 452 */
727 if (bios_version[0] == '?') { 453 if (!dmi_check_system(i8k_dmi_table)) {
728 strcpy(bios_version, buff); 454 if (!ignore_dmi && !force)
455 return -ENODEV;
456
457 printk(KERN_INFO "i8k: not running on a supported Dell system.\n");
458 printk(KERN_INFO "i8k: vendor=%s, model=%s, version=%s\n",
459 i8k_get_dmi_data(DMI_SYS_VENDOR),
460 i8k_get_dmi_data(DMI_PRODUCT_NAME),
461 i8k_get_dmi_data(DMI_BIOS_VERSION));
729 } 462 }
463
464 strlcpy(bios_version, i8k_get_dmi_data(DMI_BIOS_VERSION), sizeof(bios_version));
465
730 /* 466 /*
731 * Check if the two versions match. 467 * Get SMM Dell signature
732 */ 468 */
733 if (strncmp(buff,bios_version,sizeof(bios_version)) != 0) { 469 if (i8k_get_dell_signature(I8K_SMM_GET_DELL_SIG1) &&
734 printk(KERN_INFO "i8k: BIOS version mismatch: %s != %s\n", 470 i8k_get_dell_signature(I8K_SMM_GET_DELL_SIG2)) {
735 buff, bios_version); 471 printk(KERN_ERR "i8k: unable to get SMM Dell signature\n");
472 if (!force)
473 return -ENODEV;
736 } 474 }
737 }
738 475
739 if (!smm_found && !force) { 476 /*
740 return -ENODEV; 477 * Get SMM BIOS version.
741 } 478 */
479 version = i8k_get_bios_version();
480 if (version <= 0) {
481 printk(KERN_WARNING "i8k: unable to get SMM BIOS version\n");
482 } else {
483 buff[0] = (version >> 16) & 0xff;
484 buff[1] = (version >> 8) & 0xff;
485 buff[2] = (version) & 0xff;
486 buff[3] = '\0';
487 /*
488 * If DMI BIOS version is unknown use SMM BIOS version.
489 */
490 if (!dmi_get_system_info(DMI_BIOS_VERSION))
491 strlcpy(bios_version, buff, sizeof(bios_version));
492
493 /*
494 * Check if the two versions match.
495 */
496 if (strncmp(buff, bios_version, sizeof(bios_version)) != 0)
497 printk(KERN_WARNING "i8k: BIOS version mismatch: %s != %s\n",
498 buff, bios_version);
499 }
742 500
743 return 0; 501 return 0;
744} 502}
745 503
746#ifdef MODULE 504static int __init i8k_init(void)
747static
748#endif
749int __init i8k_init(void)
750{ 505{
751 struct proc_dir_entry *proc_i8k; 506 struct proc_dir_entry *proc_i8k;
752
753 /* Are we running on an supported laptop? */
754 if (i8k_probe() != 0) {
755 return -ENODEV;
756 }
757
758 /* Register the proc entry */
759 proc_i8k = create_proc_info_entry("i8k", 0, NULL, i8k_get_info);
760 if (!proc_i8k) {
761 return -ENOENT;
762 }
763 proc_i8k->proc_fops = &i8k_fops;
764 proc_i8k->owner = THIS_MODULE;
765
766 printk(KERN_INFO
767 "Dell laptop SMM driver v%s Massimo Dal Zotto (dz@debian.org)\n",
768 I8K_VERSION);
769
770 return 0;
771}
772 507
773#ifdef MODULE 508 /* Are we running on an supported laptop? */
774int init_module(void) 509 if (i8k_probe())
775{ 510 return -ENODEV;
776 return i8k_init(); 511
512 /* Register the proc entry */
513 proc_i8k = create_proc_entry("i8k", 0, NULL);
514 if (!proc_i8k)
515 return -ENOENT;
516
517 proc_i8k->proc_fops = &i8k_fops;
518 proc_i8k->owner = THIS_MODULE;
519
520 printk(KERN_INFO
521 "Dell laptop SMM driver v%s Massimo Dal Zotto (dz@debian.org)\n",
522 I8K_VERSION);
523
524 return 0;
777} 525}
778 526
779void cleanup_module(void) 527static void __exit i8k_exit(void)
780{ 528{
781 /* Remove the proc entry */ 529 remove_proc_entry("i8k", NULL);
782 remove_proc_entry("i8k", NULL);
783
784 printk(KERN_INFO "i8k: module unloaded\n");
785} 530}
786#endif
787 531
788/* end of file */ 532module_init(i8k_init);
533module_exit(i8k_exit);
diff --git a/drivers/char/ip2/i2cmd.c b/drivers/char/ip2/i2cmd.c
index fd299d6c42ac..cb8f4198e9a3 100644
--- a/drivers/char/ip2/i2cmd.c
+++ b/drivers/char/ip2/i2cmd.c
@@ -97,7 +97,7 @@ static UCHAR ct41[] = { 1, BYP, 0x29 }; // RESUME
97//static UCHAR ct44[]={ 2, BTH, 0x2C,0 }; // MS PING 97//static UCHAR ct44[]={ 2, BTH, 0x2C,0 }; // MS PING
98//static UCHAR ct45[]={ 1, BTH, 0x2D }; // HOTENAB 98//static UCHAR ct45[]={ 1, BTH, 0x2D }; // HOTENAB
99//static UCHAR ct46[]={ 1, BTH, 0x2E }; // HOTDSAB 99//static UCHAR ct46[]={ 1, BTH, 0x2E }; // HOTDSAB
100static UCHAR ct47[] = { 7, BTH, 0x2F,0,0,0,0,0,0 }; // UNIX FLAGS 100//static UCHAR ct47[]={ 7, BTH, 0x2F,0,0,0,0,0,0 }; // UNIX FLAGS
101//static UCHAR ct48[]={ 1, BTH, 0x30 }; // DSRFLOWENAB 101//static UCHAR ct48[]={ 1, BTH, 0x30 }; // DSRFLOWENAB
102//static UCHAR ct49[]={ 1, BTH, 0x31 }; // DSRFLOWDSAB 102//static UCHAR ct49[]={ 1, BTH, 0x31 }; // DSRFLOWDSAB
103//static UCHAR ct50[]={ 1, BTH, 0x32 }; // DTRFLOWENAB 103//static UCHAR ct50[]={ 1, BTH, 0x32 }; // DTRFLOWENAB
@@ -162,6 +162,7 @@ static UCHAR ct89[]={ 1, BYP, 0x59 }; // DSS_NOW
162// This routine sets the parameters of command 47 and returns a pointer to the 162// This routine sets the parameters of command 47 and returns a pointer to the
163// appropriate structure. 163// appropriate structure.
164//****************************************************************************** 164//******************************************************************************
165#if 0
165cmdSyntaxPtr 166cmdSyntaxPtr
166i2cmdUnixFlags(unsigned short iflag,unsigned short cflag,unsigned short lflag) 167i2cmdUnixFlags(unsigned short iflag,unsigned short cflag,unsigned short lflag)
167{ 168{
@@ -175,6 +176,7 @@ i2cmdUnixFlags(unsigned short iflag,unsigned short cflag,unsigned short lflag)
175 pCM->cmd[6] = (unsigned char) (lflag >> 8); 176 pCM->cmd[6] = (unsigned char) (lflag >> 8);
176 return pCM; 177 return pCM;
177} 178}
179#endif /* 0 */
178 180
179//****************************************************************************** 181//******************************************************************************
180// Function: i2cmdBaudDef(which, rate) 182// Function: i2cmdBaudDef(which, rate)
@@ -187,7 +189,7 @@ i2cmdUnixFlags(unsigned short iflag,unsigned short cflag,unsigned short lflag)
187// This routine sets the parameters of commands 54 or 55 (according to the 189// This routine sets the parameters of commands 54 or 55 (according to the
188// argument which), and returns a pointer to the appropriate structure. 190// argument which), and returns a pointer to the appropriate structure.
189//****************************************************************************** 191//******************************************************************************
190cmdSyntaxPtr 192static cmdSyntaxPtr
191i2cmdBaudDef(int which, unsigned short rate) 193i2cmdBaudDef(int which, unsigned short rate)
192{ 194{
193 cmdSyntaxPtr pCM; 195 cmdSyntaxPtr pCM;
diff --git a/drivers/char/ip2/i2cmd.h b/drivers/char/ip2/i2cmd.h
index c41728a85710..baa4e721b758 100644
--- a/drivers/char/ip2/i2cmd.h
+++ b/drivers/char/ip2/i2cmd.h
@@ -64,16 +64,6 @@ typedef struct _cmdSyntax
64 // directly from user-level 64 // directly from user-level
65#define VAR 0x10 // This command is of variable length! 65#define VAR 0x10 // This command is of variable length!
66 66
67//-----------------------------------
68// External declarations for i2cmd.c
69//-----------------------------------
70// Routine to set up parameters for the "define hot-key sequence" command. Since
71// there is more than one parameter to assign, we must use a function rather
72// than a macro (used usually).
73//
74extern cmdSyntaxPtr i2cmdUnixFlags(USHORT iflag,USHORT cflag,USHORT lflag);
75extern cmdSyntaxPtr i2cmdBaudDef(int which, USHORT rate);
76
77// Declarations for the global arrays used to bear the commands and their 67// Declarations for the global arrays used to bear the commands and their
78// arguments. 68// arguments.
79// 69//
@@ -433,6 +423,7 @@ static UCHAR cc02[];
433#define CMD_HOT_ENAB (cmdSyntaxPtr)(ct45) // Enable Hot-key checking 423#define CMD_HOT_ENAB (cmdSyntaxPtr)(ct45) // Enable Hot-key checking
434#define CMD_HOT_DSAB (cmdSyntaxPtr)(ct46) // Disable Hot-key checking 424#define CMD_HOT_DSAB (cmdSyntaxPtr)(ct46) // Disable Hot-key checking
435 425
426#if 0
436// COMMAND 47: Send Protocol info via Unix flags: 427// COMMAND 47: Send Protocol info via Unix flags:
437// iflag = Unix tty t_iflag 428// iflag = Unix tty t_iflag
438// cflag = Unix tty t_cflag 429// cflag = Unix tty t_cflag
@@ -441,6 +432,7 @@ static UCHAR cc02[];
441// within these flags 432// within these flags
442// 433//
443#define CMD_UNIX_FLAGS(iflag,cflag,lflag) i2cmdUnixFlags(iflag,cflag,lflag) 434#define CMD_UNIX_FLAGS(iflag,cflag,lflag) i2cmdUnixFlags(iflag,cflag,lflag)
435#endif /* 0 */
444 436
445#define CMD_DSRFL_ENAB (cmdSyntaxPtr)(ct48) // Enable DSR receiver ctrl 437#define CMD_DSRFL_ENAB (cmdSyntaxPtr)(ct48) // Enable DSR receiver ctrl
446#define CMD_DSRFL_DSAB (cmdSyntaxPtr)(ct49) // Disable DSR receiver ctrl 438#define CMD_DSRFL_DSAB (cmdSyntaxPtr)(ct49) // Disable DSR receiver ctrl
diff --git a/drivers/char/ip2main.c b/drivers/char/ip2main.c
index 3b8314b4249a..cf0cd58d6305 100644
--- a/drivers/char/ip2main.c
+++ b/drivers/char/ip2main.c
@@ -2691,16 +2691,6 @@ no_xon:
2691 pCh->flags |= ASYNC_CHECK_CD; 2691 pCh->flags |= ASYNC_CHECK_CD;
2692 } 2692 }
2693 2693
2694#ifdef XXX
2695do_flags_thing: // This is a test, we don't do the flags thing
2696
2697 if ( (cflag & CRTSCTS) ) {
2698 cflag |= 014000000000;
2699 }
2700 i2QueueCommands(PTYPE_BYPASS, pCh, 100, 1,
2701 CMD_UNIX_FLAGS(iflag,cflag,lflag));
2702#endif
2703
2704service_it: 2694service_it:
2705 i2DrainOutput( pCh, 100 ); 2695 i2DrainOutput( pCh, 100 );
2706} 2696}
diff --git a/drivers/char/isicom.c b/drivers/char/isicom.c
index 601c7fccb4cf..1bbf507adda5 100644
--- a/drivers/char/isicom.c
+++ b/drivers/char/isicom.c
@@ -1756,7 +1756,7 @@ static void isicom_flush_buffer(struct tty_struct * tty)
1756} 1756}
1757 1757
1758 1758
1759static int __init register_ioregion(void) 1759static int __devinit register_ioregion(void)
1760{ 1760{
1761 int count, done=0; 1761 int count, done=0;
1762 for (count=0; count < BOARD_COUNT; count++ ) { 1762 for (count=0; count < BOARD_COUNT; count++ ) {
@@ -1771,7 +1771,7 @@ static int __init register_ioregion(void)
1771 return done; 1771 return done;
1772} 1772}
1773 1773
1774static void __exit unregister_ioregion(void) 1774static void unregister_ioregion(void)
1775{ 1775{
1776 int count; 1776 int count;
1777 for (count=0; count < BOARD_COUNT; count++ ) 1777 for (count=0; count < BOARD_COUNT; count++ )
@@ -1803,7 +1803,7 @@ static struct tty_operations isicom_ops = {
1803 .tiocmset = isicom_tiocmset, 1803 .tiocmset = isicom_tiocmset,
1804}; 1804};
1805 1805
1806static int __init register_drivers(void) 1806static int __devinit register_drivers(void)
1807{ 1807{
1808 int error; 1808 int error;
1809 1809
@@ -1834,7 +1834,7 @@ static int __init register_drivers(void)
1834 return 0; 1834 return 0;
1835} 1835}
1836 1836
1837static void __exit unregister_drivers(void) 1837static void unregister_drivers(void)
1838{ 1838{
1839 int error = tty_unregister_driver(isicom_normal); 1839 int error = tty_unregister_driver(isicom_normal);
1840 if (error) 1840 if (error)
@@ -1842,7 +1842,7 @@ static void __exit unregister_drivers(void)
1842 put_tty_driver(isicom_normal); 1842 put_tty_driver(isicom_normal);
1843} 1843}
1844 1844
1845static int __init register_isr(void) 1845static int __devinit register_isr(void)
1846{ 1846{
1847 int count, done=0; 1847 int count, done=0;
1848 unsigned long irqflags; 1848 unsigned long irqflags;
@@ -1883,7 +1883,7 @@ static void __exit unregister_isr(void)
1883 } 1883 }
1884} 1884}
1885 1885
1886static int __init isicom_init(void) 1886static int __devinit isicom_init(void)
1887{ 1887{
1888 int card, channel, base; 1888 int card, channel, base;
1889 struct isi_port * port; 1889 struct isi_port * port;
diff --git a/drivers/char/istallion.c b/drivers/char/istallion.c
index c02a21dbad5d..52a073eee201 100644
--- a/drivers/char/istallion.c
+++ b/drivers/char/istallion.c
@@ -407,7 +407,6 @@ static unsigned long stli_eisamemprobeaddrs[] = {
407}; 407};
408 408
409static int stli_eisamempsize = sizeof(stli_eisamemprobeaddrs) / sizeof(unsigned long); 409static int stli_eisamempsize = sizeof(stli_eisamemprobeaddrs) / sizeof(unsigned long);
410int stli_eisaprobe = STLI_EISAPROBE;
411 410
412/* 411/*
413 * Define the Stallion PCI vendor and device IDs. 412 * Define the Stallion PCI vendor and device IDs.
@@ -4685,7 +4684,7 @@ static int stli_initbrds(void)
4685#ifdef MODULE 4684#ifdef MODULE
4686 stli_argbrds(); 4685 stli_argbrds();
4687#endif 4686#endif
4688 if (stli_eisaprobe) 4687 if (STLI_EISAPROBE)
4689 stli_findeisabrds(); 4688 stli_findeisabrds();
4690#ifdef CONFIG_PCI 4689#ifdef CONFIG_PCI
4691 stli_findpcibrds(); 4690 stli_findpcibrds();
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
index e3085b22a365..42187381506b 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -23,7 +23,10 @@
23#include <linux/devfs_fs_kernel.h> 23#include <linux/devfs_fs_kernel.h>
24#include <linux/ptrace.h> 24#include <linux/ptrace.h>
25#include <linux/device.h> 25#include <linux/device.h>
26#include <linux/highmem.h>
27#include <linux/crash_dump.h>
26#include <linux/backing-dev.h> 28#include <linux/backing-dev.h>
29#include <linux/bootmem.h>
27 30
28#include <asm/uaccess.h> 31#include <asm/uaccess.h>
29#include <asm/io.h> 32#include <asm/io.h>
@@ -273,6 +276,40 @@ static int mmap_kmem(struct file * file, struct vm_area_struct * vma)
273 return mmap_mem(file, vma); 276 return mmap_mem(file, vma);
274} 277}
275 278
279#ifdef CONFIG_CRASH_DUMP
280/*
281 * Read memory corresponding to the old kernel.
282 */
283static ssize_t read_oldmem(struct file *file, char __user *buf,
284 size_t count, loff_t *ppos)
285{
286 unsigned long pfn, offset;
287 size_t read = 0, csize;
288 int rc = 0;
289
290 while (count) {
291 pfn = *ppos / PAGE_SIZE;
292 if (pfn > saved_max_pfn)
293 return read;
294
295 offset = (unsigned long)(*ppos % PAGE_SIZE);
296 if (count > PAGE_SIZE - offset)
297 csize = PAGE_SIZE - offset;
298 else
299 csize = count;
300
301 rc = copy_oldmem_page(pfn, buf, csize, offset, 1);
302 if (rc < 0)
303 return rc;
304 buf += csize;
305 *ppos += csize;
306 read += csize;
307 count -= csize;
308 }
309 return read;
310}
311#endif
312
276extern long vread(char *buf, char *addr, unsigned long count); 313extern long vread(char *buf, char *addr, unsigned long count);
277extern long vwrite(char *buf, char *addr, unsigned long count); 314extern long vwrite(char *buf, char *addr, unsigned long count);
278 315
@@ -721,6 +758,7 @@ static int open_port(struct inode * inode, struct file * filp)
721#define read_full read_zero 758#define read_full read_zero
722#define open_mem open_port 759#define open_mem open_port
723#define open_kmem open_mem 760#define open_kmem open_mem
761#define open_oldmem open_mem
724 762
725static struct file_operations mem_fops = { 763static struct file_operations mem_fops = {
726 .llseek = memory_lseek, 764 .llseek = memory_lseek,
@@ -770,6 +808,13 @@ static struct file_operations full_fops = {
770 .write = write_full, 808 .write = write_full,
771}; 809};
772 810
811#ifdef CONFIG_CRASH_DUMP
812static struct file_operations oldmem_fops = {
813 .read = read_oldmem,
814 .open = open_oldmem,
815};
816#endif
817
773static ssize_t kmsg_write(struct file * file, const char __user * buf, 818static ssize_t kmsg_write(struct file * file, const char __user * buf,
774 size_t count, loff_t *ppos) 819 size_t count, loff_t *ppos)
775{ 820{
@@ -825,6 +870,11 @@ static int memory_open(struct inode * inode, struct file * filp)
825 case 11: 870 case 11:
826 filp->f_op = &kmsg_fops; 871 filp->f_op = &kmsg_fops;
827 break; 872 break;
873#ifdef CONFIG_CRASH_DUMP
874 case 12:
875 filp->f_op = &oldmem_fops;
876 break;
877#endif
828 default: 878 default:
829 return -ENXIO; 879 return -ENXIO;
830 } 880 }
@@ -854,6 +904,9 @@ static const struct {
854 {8, "random", S_IRUGO | S_IWUSR, &random_fops}, 904 {8, "random", S_IRUGO | S_IWUSR, &random_fops},
855 {9, "urandom", S_IRUGO | S_IWUSR, &urandom_fops}, 905 {9, "urandom", S_IRUGO | S_IWUSR, &urandom_fops},
856 {11,"kmsg", S_IRUGO | S_IWUSR, &kmsg_fops}, 906 {11,"kmsg", S_IRUGO | S_IWUSR, &kmsg_fops},
907#ifdef CONFIG_CRASH_DUMP
908 {12,"oldmem", S_IRUSR | S_IWUSR | S_IRGRP, &oldmem_fops},
909#endif
857}; 910};
858 911
859static struct class *mem_class; 912static struct class *mem_class;
diff --git a/drivers/char/misc.c b/drivers/char/misc.c
index 3115d318b997..31cf84d69026 100644
--- a/drivers/char/misc.c
+++ b/drivers/char/misc.c
@@ -66,8 +66,6 @@ static unsigned char misc_minors[DYNAMIC_MINORS / 8];
66extern int rtc_DP8570A_init(void); 66extern int rtc_DP8570A_init(void);
67extern int rtc_MK48T08_init(void); 67extern int rtc_MK48T08_init(void);
68extern int pmu_device_init(void); 68extern int pmu_device_init(void);
69extern int tosh_init(void);
70extern int i8k_init(void);
71 69
72#ifdef CONFIG_PROC_FS 70#ifdef CONFIG_PROC_FS
73static void *misc_seq_start(struct seq_file *seq, loff_t *pos) 71static void *misc_seq_start(struct seq_file *seq, loff_t *pos)
@@ -314,12 +312,6 @@ static int __init misc_init(void)
314#ifdef CONFIG_PMAC_PBOOK 312#ifdef CONFIG_PMAC_PBOOK
315 pmu_device_init(); 313 pmu_device_init();
316#endif 314#endif
317#ifdef CONFIG_TOSHIBA
318 tosh_init();
319#endif
320#ifdef CONFIG_I8K
321 i8k_init();
322#endif
323 if (register_chrdev(MISC_MAJOR,"misc",&misc_fops)) { 315 if (register_chrdev(MISC_MAJOR,"misc",&misc_fops)) {
324 printk("unable to get major %d for misc devices\n", 316 printk("unable to get major %d for misc devices\n",
325 MISC_MAJOR); 317 MISC_MAJOR);
diff --git a/drivers/char/mwave/3780i.c b/drivers/char/mwave/3780i.c
index ab00f51475df..613aed9e1840 100644
--- a/drivers/char/mwave/3780i.c
+++ b/drivers/char/mwave/3780i.c
@@ -107,8 +107,8 @@ void dsp3780I_WriteMsaCfg(unsigned short usDspBaseIO,
107 spin_unlock_irqrestore(&dsp_lock, flags); 107 spin_unlock_irqrestore(&dsp_lock, flags);
108} 108}
109 109
110void dsp3780I_WriteGenCfg(unsigned short usDspBaseIO, unsigned uIndex, 110static void dsp3780I_WriteGenCfg(unsigned short usDspBaseIO, unsigned uIndex,
111 unsigned char ucValue) 111 unsigned char ucValue)
112{ 112{
113 DSP_ISA_SLAVE_CONTROL rSlaveControl; 113 DSP_ISA_SLAVE_CONTROL rSlaveControl;
114 DSP_ISA_SLAVE_CONTROL rSlaveControl_Save; 114 DSP_ISA_SLAVE_CONTROL rSlaveControl_Save;
@@ -141,6 +141,7 @@ void dsp3780I_WriteGenCfg(unsigned short usDspBaseIO, unsigned uIndex,
141 141
142} 142}
143 143
144#if 0
144unsigned char dsp3780I_ReadGenCfg(unsigned short usDspBaseIO, 145unsigned char dsp3780I_ReadGenCfg(unsigned short usDspBaseIO,
145 unsigned uIndex) 146 unsigned uIndex)
146{ 147{
@@ -167,6 +168,7 @@ unsigned char dsp3780I_ReadGenCfg(unsigned short usDspBaseIO,
167 168
168 return ucValue; 169 return ucValue;
169} 170}
171#endif /* 0 */
170 172
171int dsp3780I_EnableDSP(DSP_3780I_CONFIG_SETTINGS * pSettings, 173int dsp3780I_EnableDSP(DSP_3780I_CONFIG_SETTINGS * pSettings,
172 unsigned short *pIrqMap, 174 unsigned short *pIrqMap,
diff --git a/drivers/char/mwave/3780i.h b/drivers/char/mwave/3780i.h
index 3e7d020d1bf4..270431ca7dae 100644
--- a/drivers/char/mwave/3780i.h
+++ b/drivers/char/mwave/3780i.h
@@ -338,10 +338,6 @@ unsigned short dsp3780I_ReadMsaCfg(unsigned short usDspBaseIO,
338 unsigned long ulMsaAddr); 338 unsigned long ulMsaAddr);
339void dsp3780I_WriteMsaCfg(unsigned short usDspBaseIO, 339void dsp3780I_WriteMsaCfg(unsigned short usDspBaseIO,
340 unsigned long ulMsaAddr, unsigned short usValue); 340 unsigned long ulMsaAddr, unsigned short usValue);
341void dsp3780I_WriteGenCfg(unsigned short usDspBaseIO, unsigned uIndex,
342 unsigned char ucValue);
343unsigned char dsp3780I_ReadGenCfg(unsigned short usDspBaseIO,
344 unsigned uIndex);
345int dsp3780I_GetIPCSource(unsigned short usDspBaseIO, 341int dsp3780I_GetIPCSource(unsigned short usDspBaseIO,
346 unsigned short *pusIPCSource); 342 unsigned short *pusIPCSource);
347 343
diff --git a/drivers/char/mwave/tp3780i.c b/drivers/char/mwave/tp3780i.c
index ab650cd6efc0..d6c72e0934e2 100644
--- a/drivers/char/mwave/tp3780i.c
+++ b/drivers/char/mwave/tp3780i.c
@@ -242,20 +242,14 @@ int tp3780I_ClaimResources(THINKPAD_BD_DATA * pBDData)
242{ 242{
243 int retval = 0; 243 int retval = 0;
244 DSP_3780I_CONFIG_SETTINGS *pSettings = &pBDData->rDspSettings; 244 DSP_3780I_CONFIG_SETTINGS *pSettings = &pBDData->rDspSettings;
245#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
246 struct resource *pres; 245 struct resource *pres;
247#endif
248 246
249 PRINTK_2(TRACE_TP3780I, 247 PRINTK_2(TRACE_TP3780I,
250 "tp3780i::tp3780I_ClaimResources entry pBDData %p\n", pBDData); 248 "tp3780i::tp3780I_ClaimResources entry pBDData %p\n", pBDData);
251 249
252#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
253 pres = request_region(pSettings->usDspBaseIO, 16, "mwave_3780i"); 250 pres = request_region(pSettings->usDspBaseIO, 16, "mwave_3780i");
254 if ( pres == NULL ) retval = -EIO; 251 if ( pres == NULL ) retval = -EIO;
255#else 252
256 retval = check_region(pSettings->usDspBaseIO, 16);
257 if (!retval) request_region(pSettings->usDspBaseIO, 16, "mwave_3780i");
258#endif
259 if (retval) { 253 if (retval) {
260 PRINTK_ERROR(KERN_ERR_MWAVE "tp3780i::tp3780I_ClaimResources: Error: Could not claim I/O region starting at %x\n", pSettings->usDspBaseIO); 254 PRINTK_ERROR(KERN_ERR_MWAVE "tp3780i::tp3780I_ClaimResources: Error: Could not claim I/O region starting at %x\n", pSettings->usDspBaseIO);
261 retval = -EIO; 255 retval = -EIO;
@@ -292,7 +286,7 @@ int tp3780I_ReleaseResources(THINKPAD_BD_DATA * pBDData)
292int tp3780I_EnableDSP(THINKPAD_BD_DATA * pBDData) 286int tp3780I_EnableDSP(THINKPAD_BD_DATA * pBDData)
293{ 287{
294 DSP_3780I_CONFIG_SETTINGS *pSettings = &pBDData->rDspSettings; 288 DSP_3780I_CONFIG_SETTINGS *pSettings = &pBDData->rDspSettings;
295 BOOLEAN bDSPPoweredUp = FALSE, bDSPEnabled = FALSE, bInterruptAllocated = FALSE; 289 BOOLEAN bDSPPoweredUp = FALSE, bInterruptAllocated = FALSE;
296 290
297 PRINTK_2(TRACE_TP3780I, "tp3780i::tp3780I_EnableDSP entry pBDData %p\n", pBDData); 291 PRINTK_2(TRACE_TP3780I, "tp3780i::tp3780I_EnableDSP entry pBDData %p\n", pBDData);
298 292
@@ -397,8 +391,6 @@ int tp3780I_EnableDSP(THINKPAD_BD_DATA * pBDData)
397 if (dsp3780I_EnableDSP(pSettings, s_ausThinkpadIrqToField, s_ausThinkpadDmaToField)) { 391 if (dsp3780I_EnableDSP(pSettings, s_ausThinkpadIrqToField, s_ausThinkpadDmaToField)) {
398 PRINTK_ERROR("tp3780i::tp3780I_EnableDSP: Error: dsp7880I_EnableDSP() failed\n"); 392 PRINTK_ERROR("tp3780i::tp3780I_EnableDSP: Error: dsp7880I_EnableDSP() failed\n");
399 goto exit_cleanup; 393 goto exit_cleanup;
400 } else {
401 bDSPEnabled = TRUE;
402 } 394 }
403 395
404 EnableSRAM(pBDData); 396 EnableSRAM(pBDData);
@@ -411,8 +403,6 @@ int tp3780I_EnableDSP(THINKPAD_BD_DATA * pBDData)
411 403
412exit_cleanup: 404exit_cleanup:
413 PRINTK_ERROR("tp3780i::tp3780I_EnableDSP: Cleaning up\n"); 405 PRINTK_ERROR("tp3780i::tp3780I_EnableDSP: Cleaning up\n");
414 if (bDSPEnabled)
415 dsp3780I_DisableDSP(pSettings);
416 if (bDSPPoweredUp) 406 if (bDSPPoweredUp)
417 smapi_set_DSP_power_state(FALSE); 407 smapi_set_DSP_power_state(FALSE);
418 if (bInterruptAllocated) { 408 if (bInterruptAllocated) {
diff --git a/drivers/char/nvram.c b/drivers/char/nvram.c
index f63a3fd7ca6f..1af733d07321 100644
--- a/drivers/char/nvram.c
+++ b/drivers/char/nvram.c
@@ -211,12 +211,13 @@ nvram_check_checksum(void)
211 return rv; 211 return rv;
212} 212}
213 213
214void 214static void
215__nvram_set_checksum(void) 215__nvram_set_checksum(void)
216{ 216{
217 mach_set_checksum(); 217 mach_set_checksum();
218} 218}
219 219
220#if 0
220void 221void
221nvram_set_checksum(void) 222nvram_set_checksum(void)
222{ 223{
@@ -226,6 +227,7 @@ nvram_set_checksum(void)
226 __nvram_set_checksum(); 227 __nvram_set_checksum();
227 spin_unlock_irqrestore(&rtc_lock, flags); 228 spin_unlock_irqrestore(&rtc_lock, flags);
228} 229}
230#endif /* 0 */
229 231
230/* 232/*
231 * The are the file operation function for user access to /dev/nvram 233 * The are the file operation function for user access to /dev/nvram
@@ -921,6 +923,4 @@ EXPORT_SYMBOL(__nvram_write_byte);
921EXPORT_SYMBOL(nvram_write_byte); 923EXPORT_SYMBOL(nvram_write_byte);
922EXPORT_SYMBOL(__nvram_check_checksum); 924EXPORT_SYMBOL(__nvram_check_checksum);
923EXPORT_SYMBOL(nvram_check_checksum); 925EXPORT_SYMBOL(nvram_check_checksum);
924EXPORT_SYMBOL(__nvram_set_checksum);
925EXPORT_SYMBOL(nvram_set_checksum);
926MODULE_ALIAS_MISCDEV(NVRAM_MINOR); 926MODULE_ALIAS_MISCDEV(NVRAM_MINOR);
diff --git a/drivers/char/rio/func.h b/drivers/char/rio/func.h
index e8f3860f4726..01987c6dc398 100644
--- a/drivers/char/rio/func.h
+++ b/drivers/char/rio/func.h
@@ -147,7 +147,6 @@ struct rio_info * rio_info_store( int cmd, struct rio_info * p);
147extern int rio_pcicopy(char *src, char *dst, int n); 147extern int rio_pcicopy(char *src, char *dst, int n);
148extern int rio_minor (struct tty_struct *tty); 148extern int rio_minor (struct tty_struct *tty);
149extern int rio_ismodem (struct tty_struct *tty); 149extern int rio_ismodem (struct tty_struct *tty);
150extern void rio_udelay (int usecs);
151 150
152extern void rio_start_card_running (struct Host * HostP); 151extern void rio_start_card_running (struct Host * HostP);
153 152
diff --git a/drivers/char/rio/rio_linux.c b/drivers/char/rio/rio_linux.c
index 763893e289b3..7db3370f4972 100644
--- a/drivers/char/rio/rio_linux.c
+++ b/drivers/char/rio/rio_linux.c
@@ -354,11 +354,6 @@ int rio_ismodem(struct tty_struct *tty)
354} 354}
355 355
356 356
357void rio_udelay (int usecs)
358{
359 udelay (usecs);
360}
361
362static int rio_set_real_termios (void *ptr) 357static int rio_set_real_termios (void *ptr)
363{ 358{
364 int rv, modem; 359 int rv, modem;
diff --git a/drivers/char/rio/rioinit.c b/drivers/char/rio/rioinit.c
index dca941ed10cf..898a126ae3e6 100644
--- a/drivers/char/rio/rioinit.c
+++ b/drivers/char/rio/rioinit.c
@@ -37,6 +37,7 @@ static char *_rioinit_c_sccs_ = "@(#)rioinit.c 1.3";
37#include <linux/module.h> 37#include <linux/module.h>
38#include <linux/slab.h> 38#include <linux/slab.h>
39#include <linux/errno.h> 39#include <linux/errno.h>
40#include <linux/delay.h>
40#include <asm/io.h> 41#include <asm/io.h>
41#include <asm/system.h> 42#include <asm/system.h>
42#include <asm/string.h> 43#include <asm/string.h>
@@ -1560,14 +1561,14 @@ uint Slot;
1560 INTERRUPT_DISABLE | BYTE_OPERATION | 1561 INTERRUPT_DISABLE | BYTE_OPERATION |
1561 SLOW_LINKS | SLOW_AT_BUS); 1562 SLOW_LINKS | SLOW_AT_BUS);
1562 WBYTE(DpRamP->DpResetTpu, 0xFF); 1563 WBYTE(DpRamP->DpResetTpu, 0xFF);
1563 rio_udelay (3); 1564 udelay(3);
1564 1565
1565 rio_dprintk (RIO_DEBUG_INIT, "RIOHostReset: Don't know if it worked. Try reset again\n"); 1566 rio_dprintk (RIO_DEBUG_INIT, "RIOHostReset: Don't know if it worked. Try reset again\n");
1566 WBYTE(DpRamP->DpControl, BOOT_FROM_RAM | EXTERNAL_BUS_OFF | 1567 WBYTE(DpRamP->DpControl, BOOT_FROM_RAM | EXTERNAL_BUS_OFF |
1567 INTERRUPT_DISABLE | BYTE_OPERATION | 1568 INTERRUPT_DISABLE | BYTE_OPERATION |
1568 SLOW_LINKS | SLOW_AT_BUS); 1569 SLOW_LINKS | SLOW_AT_BUS);
1569 WBYTE(DpRamP->DpResetTpu, 0xFF); 1570 WBYTE(DpRamP->DpResetTpu, 0xFF);
1570 rio_udelay (3); 1571 udelay(3);
1571 break; 1572 break;
1572#ifdef FUTURE_RELEASE 1573#ifdef FUTURE_RELEASE
1573 case RIO_EISA: 1574 case RIO_EISA:
@@ -1599,7 +1600,7 @@ uint Slot;
1599 DpRamP->DpControl = RIO_PCI_BOOT_FROM_RAM; 1600 DpRamP->DpControl = RIO_PCI_BOOT_FROM_RAM;
1600 DpRamP->DpResetInt = 0xFF; 1601 DpRamP->DpResetInt = 0xFF;
1601 DpRamP->DpResetTpu = 0xFF; 1602 DpRamP->DpResetTpu = 0xFF;
1602 rio_udelay (100); 1603 udelay(100);
1603 /* for (i=0; i<6000; i++); */ 1604 /* for (i=0; i<6000; i++); */
1604 /* suspend( 3 ); */ 1605 /* suspend( 3 ); */
1605 break; 1606 break;
diff --git a/drivers/char/rio/riotty.c b/drivers/char/rio/riotty.c
index db655002671f..78a321afdf4f 100644
--- a/drivers/char/rio/riotty.c
+++ b/drivers/char/rio/riotty.c
@@ -524,16 +524,16 @@ riotclose(void *ptr)
524 register uint SysPort = dev; 524 register uint SysPort = dev;
525 struct ttystatics *tp; /* pointer to our ttystruct */ 525 struct ttystatics *tp; /* pointer to our ttystruct */
526#endif 526#endif
527 struct Port *PortP =ptr; /* pointer to the port structure */ 527 struct Port *PortP = ptr; /* pointer to the port structure */
528 int deleted = 0; 528 int deleted = 0;
529 int try = -1; /* Disable the timeouts by setting them to -1 */ 529 int try = -1; /* Disable the timeouts by setting them to -1 */
530 int repeat_this = -1; /* Congrats to those having 15 years of 530 int repeat_this = -1; /* Congrats to those having 15 years of
531 uptime! (You get to break the driver.) */ 531 uptime! (You get to break the driver.) */
532 long end_time; 532 unsigned long end_time;
533 struct tty_struct * tty; 533 struct tty_struct * tty;
534 unsigned long flags; 534 unsigned long flags;
535 int Modem; 535 int Modem;
536 int rv =0; 536 int rv = 0;
537 537
538 rio_dprintk (RIO_DEBUG_TTY, "port close SysPort %d\n",PortP->PortNum); 538 rio_dprintk (RIO_DEBUG_TTY, "port close SysPort %d\n",PortP->PortNum);
539 539
@@ -620,7 +620,7 @@ riotclose(void *ptr)
620 if (repeat_this -- <= 0) { 620 if (repeat_this -- <= 0) {
621 rv = -EINTR; 621 rv = -EINTR;
622 rio_dprintk (RIO_DEBUG_TTY, "Waiting for not idle closed broken by signal\n"); 622 rio_dprintk (RIO_DEBUG_TTY, "Waiting for not idle closed broken by signal\n");
623 RIOPreemptiveCmd(p, PortP, FCLOSE ); 623 RIOPreemptiveCmd(p, PortP, FCLOSE);
624 goto close_end; 624 goto close_end;
625 } 625 }
626 rio_dprintk (RIO_DEBUG_TTY, "Calling timeout to flush in closing\n"); 626 rio_dprintk (RIO_DEBUG_TTY, "Calling timeout to flush in closing\n");
@@ -656,14 +656,12 @@ riotclose(void *ptr)
656 goto close_end; 656 goto close_end;
657 } 657 }
658 658
659
660
661 /* Can't call RIOShortCommand with the port locked. */ 659 /* Can't call RIOShortCommand with the port locked. */
662 rio_spin_unlock_irqrestore(&PortP->portSem, flags); 660 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
663 661
664 if (RIOShortCommand(p, PortP, CLOSE, 1, 0) == RIO_FAIL) { 662 if (RIOShortCommand(p, PortP, CLOSE, 1, 0) == RIO_FAIL) {
665 RIOPreemptiveCmd(p, PortP,FCLOSE); 663 RIOPreemptiveCmd(p, PortP, FCLOSE);
666 goto close_end; 664 goto close_end;
667 } 665 }
668 666
669 if (!deleted) 667 if (!deleted)
@@ -698,7 +696,6 @@ riotclose(void *ptr)
698*/ 696*/
699 PortP->Config &= ~(RIO_CTSFLOW|RIO_RTSFLOW); 697 PortP->Config &= ~(RIO_CTSFLOW|RIO_RTSFLOW);
700 698
701
702#ifdef STATS 699#ifdef STATS
703 PortP->Stat.CloseCnt++; 700 PortP->Stat.CloseCnt++;
704#endif 701#endif
diff --git a/drivers/char/rocket.c b/drivers/char/rocket.c
index 5bcbeb0cb9ae..f463d6baa685 100644
--- a/drivers/char/rocket.c
+++ b/drivers/char/rocket.c
@@ -161,6 +161,64 @@ static Word_t upci_aiop_intr_bits[AIOP_CTL_SIZE] = {
161 UPCI_AIOP_INTR_BIT_3 161 UPCI_AIOP_INTR_BIT_3
162}; 162};
163 163
164static Byte_t RData[RDATASIZE] = {
165 0x00, 0x09, 0xf6, 0x82,
166 0x02, 0x09, 0x86, 0xfb,
167 0x04, 0x09, 0x00, 0x0a,
168 0x06, 0x09, 0x01, 0x0a,
169 0x08, 0x09, 0x8a, 0x13,
170 0x0a, 0x09, 0xc5, 0x11,
171 0x0c, 0x09, 0x86, 0x85,
172 0x0e, 0x09, 0x20, 0x0a,
173 0x10, 0x09, 0x21, 0x0a,
174 0x12, 0x09, 0x41, 0xff,
175 0x14, 0x09, 0x82, 0x00,
176 0x16, 0x09, 0x82, 0x7b,
177 0x18, 0x09, 0x8a, 0x7d,
178 0x1a, 0x09, 0x88, 0x81,
179 0x1c, 0x09, 0x86, 0x7a,
180 0x1e, 0x09, 0x84, 0x81,
181 0x20, 0x09, 0x82, 0x7c,
182 0x22, 0x09, 0x0a, 0x0a
183};
184
185static Byte_t RRegData[RREGDATASIZE] = {
186 0x00, 0x09, 0xf6, 0x82, /* 00: Stop Rx processor */
187 0x08, 0x09, 0x8a, 0x13, /* 04: Tx software flow control */
188 0x0a, 0x09, 0xc5, 0x11, /* 08: XON char */
189 0x0c, 0x09, 0x86, 0x85, /* 0c: XANY */
190 0x12, 0x09, 0x41, 0xff, /* 10: Rx mask char */
191 0x14, 0x09, 0x82, 0x00, /* 14: Compare/Ignore #0 */
192 0x16, 0x09, 0x82, 0x7b, /* 18: Compare #1 */
193 0x18, 0x09, 0x8a, 0x7d, /* 1c: Compare #2 */
194 0x1a, 0x09, 0x88, 0x81, /* 20: Interrupt #1 */
195 0x1c, 0x09, 0x86, 0x7a, /* 24: Ignore/Replace #1 */
196 0x1e, 0x09, 0x84, 0x81, /* 28: Interrupt #2 */
197 0x20, 0x09, 0x82, 0x7c, /* 2c: Ignore/Replace #2 */
198 0x22, 0x09, 0x0a, 0x0a /* 30: Rx FIFO Enable */
199};
200
201static CONTROLLER_T sController[CTL_SIZE] = {
202 {-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0},
203 {0, 0, 0, 0}, {-1, -1, -1, -1}, {0, 0, 0, 0}},
204 {-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0},
205 {0, 0, 0, 0}, {-1, -1, -1, -1}, {0, 0, 0, 0}},
206 {-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0},
207 {0, 0, 0, 0}, {-1, -1, -1, -1}, {0, 0, 0, 0}},
208 {-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0},
209 {0, 0, 0, 0}, {-1, -1, -1, -1}, {0, 0, 0, 0}}
210};
211
212static Byte_t sBitMapClrTbl[8] = {
213 0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f
214};
215
216static Byte_t sBitMapSetTbl[8] = {
217 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80
218};
219
220static int sClockPrescale = 0x14;
221
164/* 222/*
165 * Line number is the ttySIx number (x), the Minor number. We 223 * Line number is the ttySIx number (x), the Minor number. We
166 * assign them sequentially, starting at zero. The following 224 * assign them sequentially, starting at zero. The following
@@ -177,6 +235,26 @@ static void rmSpeakerReset(CONTROLLER_T * CtlP, unsigned long model);
177static unsigned char GetLineNumber(int ctrl, int aiop, int ch); 235static unsigned char GetLineNumber(int ctrl, int aiop, int ch);
178static unsigned char SetLineNumber(int ctrl, int aiop, int ch); 236static unsigned char SetLineNumber(int ctrl, int aiop, int ch);
179static void rp_start(struct tty_struct *tty); 237static void rp_start(struct tty_struct *tty);
238static int sInitChan(CONTROLLER_T * CtlP, CHANNEL_T * ChP, int AiopNum,
239 int ChanNum);
240static void sSetInterfaceMode(CHANNEL_T * ChP, Byte_t mode);
241static void sFlushRxFIFO(CHANNEL_T * ChP);
242static void sFlushTxFIFO(CHANNEL_T * ChP);
243static void sEnInterrupts(CHANNEL_T * ChP, Word_t Flags);
244static void sDisInterrupts(CHANNEL_T * ChP, Word_t Flags);
245static void sModemReset(CONTROLLER_T * CtlP, int chan, int on);
246static void sPCIModemReset(CONTROLLER_T * CtlP, int chan, int on);
247static int sWriteTxPrioByte(CHANNEL_T * ChP, Byte_t Data);
248static int sPCIInitController(CONTROLLER_T * CtlP, int CtlNum,
249 ByteIO_t * AiopIOList, int AiopIOListSize,
250 WordIO_t ConfigIO, int IRQNum, Byte_t Frequency,
251 int PeriodicOnly, int altChanRingIndicator,
252 int UPCIRingInd);
253static int sInitController(CONTROLLER_T * CtlP, int CtlNum, ByteIO_t MudbacIO,
254 ByteIO_t * AiopIOList, int AiopIOListSize,
255 int IRQNum, Byte_t Frequency, int PeriodicOnly);
256static int sReadAiopID(ByteIO_t io);
257static int sReadAiopNumChan(WordIO_t io);
180 258
181#ifdef MODULE 259#ifdef MODULE
182MODULE_AUTHOR("Theodore Ts'o"); 260MODULE_AUTHOR("Theodore Ts'o");
@@ -1798,7 +1876,7 @@ static void rp_flush_buffer(struct tty_struct *tty)
1798 * init's aiopic and serial port hardware. 1876 * init's aiopic and serial port hardware.
1799 * Inputs: i is the board number (0-n) 1877 * Inputs: i is the board number (0-n)
1800 */ 1878 */
1801__init int register_PCI(int i, struct pci_dev *dev) 1879static __init int register_PCI(int i, struct pci_dev *dev)
1802{ 1880{
1803 int num_aiops, aiop, max_num_aiops, num_chan, chan; 1881 int num_aiops, aiop, max_num_aiops, num_chan, chan;
1804 unsigned int aiopio[MAX_AIOPS_PER_BOARD]; 1882 unsigned int aiopio[MAX_AIOPS_PER_BOARD];
@@ -2453,72 +2531,6 @@ static void rp_cleanup_module(void)
2453} 2531}
2454#endif 2532#endif
2455 2533
2456#ifndef TRUE
2457#define TRUE 1
2458#endif
2459
2460#ifndef FALSE
2461#define FALSE 0
2462#endif
2463
2464static Byte_t RData[RDATASIZE] = {
2465 0x00, 0x09, 0xf6, 0x82,
2466 0x02, 0x09, 0x86, 0xfb,
2467 0x04, 0x09, 0x00, 0x0a,
2468 0x06, 0x09, 0x01, 0x0a,
2469 0x08, 0x09, 0x8a, 0x13,
2470 0x0a, 0x09, 0xc5, 0x11,
2471 0x0c, 0x09, 0x86, 0x85,
2472 0x0e, 0x09, 0x20, 0x0a,
2473 0x10, 0x09, 0x21, 0x0a,
2474 0x12, 0x09, 0x41, 0xff,
2475 0x14, 0x09, 0x82, 0x00,
2476 0x16, 0x09, 0x82, 0x7b,
2477 0x18, 0x09, 0x8a, 0x7d,
2478 0x1a, 0x09, 0x88, 0x81,
2479 0x1c, 0x09, 0x86, 0x7a,
2480 0x1e, 0x09, 0x84, 0x81,
2481 0x20, 0x09, 0x82, 0x7c,
2482 0x22, 0x09, 0x0a, 0x0a
2483};
2484
2485static Byte_t RRegData[RREGDATASIZE] = {
2486 0x00, 0x09, 0xf6, 0x82, /* 00: Stop Rx processor */
2487 0x08, 0x09, 0x8a, 0x13, /* 04: Tx software flow control */
2488 0x0a, 0x09, 0xc5, 0x11, /* 08: XON char */
2489 0x0c, 0x09, 0x86, 0x85, /* 0c: XANY */
2490 0x12, 0x09, 0x41, 0xff, /* 10: Rx mask char */
2491 0x14, 0x09, 0x82, 0x00, /* 14: Compare/Ignore #0 */
2492 0x16, 0x09, 0x82, 0x7b, /* 18: Compare #1 */
2493 0x18, 0x09, 0x8a, 0x7d, /* 1c: Compare #2 */
2494 0x1a, 0x09, 0x88, 0x81, /* 20: Interrupt #1 */
2495 0x1c, 0x09, 0x86, 0x7a, /* 24: Ignore/Replace #1 */
2496 0x1e, 0x09, 0x84, 0x81, /* 28: Interrupt #2 */
2497 0x20, 0x09, 0x82, 0x7c, /* 2c: Ignore/Replace #2 */
2498 0x22, 0x09, 0x0a, 0x0a /* 30: Rx FIFO Enable */
2499};
2500
2501CONTROLLER_T sController[CTL_SIZE] = {
2502 {-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0},
2503 {0, 0, 0, 0}, {-1, -1, -1, -1}, {0, 0, 0, 0}},
2504 {-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0},
2505 {0, 0, 0, 0}, {-1, -1, -1, -1}, {0, 0, 0, 0}},
2506 {-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0},
2507 {0, 0, 0, 0}, {-1, -1, -1, -1}, {0, 0, 0, 0}},
2508 {-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0},
2509 {0, 0, 0, 0}, {-1, -1, -1, -1}, {0, 0, 0, 0}}
2510};
2511
2512Byte_t sBitMapClrTbl[8] = {
2513 0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f
2514};
2515
2516Byte_t sBitMapSetTbl[8] = {
2517 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80
2518};
2519
2520int sClockPrescale = 0x14;
2521
2522/*************************************************************************** 2534/***************************************************************************
2523Function: sInitController 2535Function: sInitController
2524Purpose: Initialization of controller global registers and controller 2536Purpose: Initialization of controller global registers and controller
@@ -2554,22 +2566,22 @@ Call: sInitController(CtlP,CtlNum,MudbacIO,AiopIOList,AiopIOListSize,
2554 FREQ_4HZ - 4 Hertz 2566 FREQ_4HZ - 4 Hertz
2555 If IRQNum is set to 0 the Frequency parameter is 2567 If IRQNum is set to 0 the Frequency parameter is
2556 overidden, it is forced to a value of FREQ_DIS. 2568 overidden, it is forced to a value of FREQ_DIS.
2557 int PeriodicOnly: TRUE if all interrupts except the periodic 2569 int PeriodicOnly: 1 if all interrupts except the periodic
2558 interrupt are to be blocked. 2570 interrupt are to be blocked.
2559 FALSE is both the periodic interrupt and 2571 0 is both the periodic interrupt and
2560 other channel interrupts are allowed. 2572 other channel interrupts are allowed.
2561 If IRQNum is set to 0 the PeriodicOnly parameter is 2573 If IRQNum is set to 0 the PeriodicOnly parameter is
2562 overidden, it is forced to a value of FALSE. 2574 overidden, it is forced to a value of 0.
2563Return: int: Number of AIOPs on the controller, or CTLID_NULL if controller 2575Return: int: Number of AIOPs on the controller, or CTLID_NULL if controller
2564 initialization failed. 2576 initialization failed.
2565 2577
2566Comments: 2578Comments:
2567 If periodic interrupts are to be disabled but AIOP interrupts 2579 If periodic interrupts are to be disabled but AIOP interrupts
2568 are allowed, set Frequency to FREQ_DIS and PeriodicOnly to FALSE. 2580 are allowed, set Frequency to FREQ_DIS and PeriodicOnly to 0.
2569 2581
2570 If interrupts are to be completely disabled set IRQNum to 0. 2582 If interrupts are to be completely disabled set IRQNum to 0.
2571 2583
2572 Setting Frequency to FREQ_DIS and PeriodicOnly to TRUE is an 2584 Setting Frequency to FREQ_DIS and PeriodicOnly to 1 is an
2573 invalid combination. 2585 invalid combination.
2574 2586
2575 This function performs initialization of global interrupt modes, 2587 This function performs initialization of global interrupt modes,
@@ -2589,9 +2601,9 @@ Warnings: No range checking on any of the parameters is done.
2589 After this function all AIOPs on the controller are disabled, 2601 After this function all AIOPs on the controller are disabled,
2590 they can be enabled with sEnAiop(). 2602 they can be enabled with sEnAiop().
2591*/ 2603*/
2592int sInitController(CONTROLLER_T * CtlP, int CtlNum, ByteIO_t MudbacIO, 2604static int sInitController(CONTROLLER_T * CtlP, int CtlNum, ByteIO_t MudbacIO,
2593 ByteIO_t * AiopIOList, int AiopIOListSize, int IRQNum, 2605 ByteIO_t * AiopIOList, int AiopIOListSize,
2594 Byte_t Frequency, int PeriodicOnly) 2606 int IRQNum, Byte_t Frequency, int PeriodicOnly)
2595{ 2607{
2596 int i; 2608 int i;
2597 ByteIO_t io; 2609 ByteIO_t io;
@@ -2687,22 +2699,22 @@ Call: sPCIInitController(CtlP,CtlNum,AiopIOList,AiopIOListSize,
2687 FREQ_4HZ - 4 Hertz 2699 FREQ_4HZ - 4 Hertz
2688 If IRQNum is set to 0 the Frequency parameter is 2700 If IRQNum is set to 0 the Frequency parameter is
2689 overidden, it is forced to a value of FREQ_DIS. 2701 overidden, it is forced to a value of FREQ_DIS.
2690 int PeriodicOnly: TRUE if all interrupts except the periodic 2702 int PeriodicOnly: 1 if all interrupts except the periodic
2691 interrupt are to be blocked. 2703 interrupt are to be blocked.
2692 FALSE is both the periodic interrupt and 2704 0 is both the periodic interrupt and
2693 other channel interrupts are allowed. 2705 other channel interrupts are allowed.
2694 If IRQNum is set to 0 the PeriodicOnly parameter is 2706 If IRQNum is set to 0 the PeriodicOnly parameter is
2695 overidden, it is forced to a value of FALSE. 2707 overidden, it is forced to a value of 0.
2696Return: int: Number of AIOPs on the controller, or CTLID_NULL if controller 2708Return: int: Number of AIOPs on the controller, or CTLID_NULL if controller
2697 initialization failed. 2709 initialization failed.
2698 2710
2699Comments: 2711Comments:
2700 If periodic interrupts are to be disabled but AIOP interrupts 2712 If periodic interrupts are to be disabled but AIOP interrupts
2701 are allowed, set Frequency to FREQ_DIS and PeriodicOnly to FALSE. 2713 are allowed, set Frequency to FREQ_DIS and PeriodicOnly to 0.
2702 2714
2703 If interrupts are to be completely disabled set IRQNum to 0. 2715 If interrupts are to be completely disabled set IRQNum to 0.
2704 2716
2705 Setting Frequency to FREQ_DIS and PeriodicOnly to TRUE is an 2717 Setting Frequency to FREQ_DIS and PeriodicOnly to 1 is an
2706 invalid combination. 2718 invalid combination.
2707 2719
2708 This function performs initialization of global interrupt modes, 2720 This function performs initialization of global interrupt modes,
@@ -2722,11 +2734,11 @@ Warnings: No range checking on any of the parameters is done.
2722 After this function all AIOPs on the controller are disabled, 2734 After this function all AIOPs on the controller are disabled,
2723 they can be enabled with sEnAiop(). 2735 they can be enabled with sEnAiop().
2724*/ 2736*/
2725int sPCIInitController(CONTROLLER_T * CtlP, int CtlNum, 2737static int sPCIInitController(CONTROLLER_T * CtlP, int CtlNum,
2726 ByteIO_t * AiopIOList, int AiopIOListSize, 2738 ByteIO_t * AiopIOList, int AiopIOListSize,
2727 WordIO_t ConfigIO, int IRQNum, Byte_t Frequency, 2739 WordIO_t ConfigIO, int IRQNum, Byte_t Frequency,
2728 int PeriodicOnly, int altChanRingIndicator, 2740 int PeriodicOnly, int altChanRingIndicator,
2729 int UPCIRingInd) 2741 int UPCIRingInd)
2730{ 2742{
2731 int i; 2743 int i;
2732 ByteIO_t io; 2744 ByteIO_t io;
@@ -2784,7 +2796,7 @@ Return: int: Flag AIOPID_XXXX if a valid AIOP is found, where X
2784Warnings: No context switches are allowed while executing this function. 2796Warnings: No context switches are allowed while executing this function.
2785 2797
2786*/ 2798*/
2787int sReadAiopID(ByteIO_t io) 2799static int sReadAiopID(ByteIO_t io)
2788{ 2800{
2789 Byte_t AiopID; /* ID byte from AIOP */ 2801 Byte_t AiopID; /* ID byte from AIOP */
2790 2802
@@ -2810,7 +2822,7 @@ Comments: The number of channels is determined by write/reads from identical
2810 AIOP, otherwise it is an 8 channel. 2822 AIOP, otherwise it is an 8 channel.
2811Warnings: No context switches are allowed while executing this function. 2823Warnings: No context switches are allowed while executing this function.
2812*/ 2824*/
2813int sReadAiopNumChan(WordIO_t io) 2825static int sReadAiopNumChan(WordIO_t io)
2814{ 2826{
2815 Word_t x; 2827 Word_t x;
2816 static Byte_t R[4] = { 0x00, 0x00, 0x34, 0x12 }; 2828 static Byte_t R[4] = { 0x00, 0x00, 0x34, 0x12 };
@@ -2834,15 +2846,15 @@ Call: sInitChan(CtlP,ChP,AiopNum,ChanNum)
2834 CHANNEL_T *ChP; Ptr to channel structure 2846 CHANNEL_T *ChP; Ptr to channel structure
2835 int AiopNum; AIOP number within controller 2847 int AiopNum; AIOP number within controller
2836 int ChanNum; Channel number within AIOP 2848 int ChanNum; Channel number within AIOP
2837Return: int: TRUE if initialization succeeded, FALSE if it fails because channel 2849Return: int: 1 if initialization succeeded, 0 if it fails because channel
2838 number exceeds number of channels available in AIOP. 2850 number exceeds number of channels available in AIOP.
2839Comments: This function must be called before a channel can be used. 2851Comments: This function must be called before a channel can be used.
2840Warnings: No range checking on any of the parameters is done. 2852Warnings: No range checking on any of the parameters is done.
2841 2853
2842 No context switches are allowed while executing this function. 2854 No context switches are allowed while executing this function.
2843*/ 2855*/
2844int sInitChan(CONTROLLER_T * CtlP, CHANNEL_T * ChP, int AiopNum, 2856static int sInitChan(CONTROLLER_T * CtlP, CHANNEL_T * ChP, int AiopNum,
2845 int ChanNum) 2857 int ChanNum)
2846{ 2858{
2847 int i; 2859 int i;
2848 WordIO_t AiopIO; 2860 WordIO_t AiopIO;
@@ -2853,7 +2865,7 @@ int sInitChan(CONTROLLER_T * CtlP, CHANNEL_T * ChP, int AiopNum,
2853 int brd9600; 2865 int brd9600;
2854 2866
2855 if (ChanNum >= CtlP->AiopNumChan[AiopNum]) 2867 if (ChanNum >= CtlP->AiopNumChan[AiopNum])
2856 return (FALSE); /* exceeds num chans in AIOP */ 2868 return 0; /* exceeds num chans in AIOP */
2857 2869
2858 /* Channel, AIOP, and controller identifiers */ 2870 /* Channel, AIOP, and controller identifiers */
2859 ChP->CtlP = CtlP; 2871 ChP->CtlP = CtlP;
@@ -2968,7 +2980,7 @@ int sInitChan(CONTROLLER_T * CtlP, CHANNEL_T * ChP, int AiopNum,
2968 ChP->TxPrioBuf = ChOff + _TXP_BUF; 2980 ChP->TxPrioBuf = ChOff + _TXP_BUF;
2969 sEnRxProcessor(ChP); /* start the Rx processor */ 2981 sEnRxProcessor(ChP); /* start the Rx processor */
2970 2982
2971 return (TRUE); 2983 return 1;
2972} 2984}
2973 2985
2974/*************************************************************************** 2986/***************************************************************************
@@ -2989,7 +3001,7 @@ Warnings: No context switches are allowed while executing this function.
2989 After calling this function a delay of 4 uS is required to ensure 3001 After calling this function a delay of 4 uS is required to ensure
2990 that the receive processor is no longer processing this channel. 3002 that the receive processor is no longer processing this channel.
2991*/ 3003*/
2992void sStopRxProcessor(CHANNEL_T * ChP) 3004static void sStopRxProcessor(CHANNEL_T * ChP)
2993{ 3005{
2994 Byte_t R[4]; 3006 Byte_t R[4];
2995 3007
@@ -3014,18 +3026,18 @@ Comments: To prevent data from being enqueued or dequeued in the Tx FIFO
3014 this function. 3026 this function.
3015Warnings: No context switches are allowed while executing this function. 3027Warnings: No context switches are allowed while executing this function.
3016*/ 3028*/
3017void sFlushRxFIFO(CHANNEL_T * ChP) 3029static void sFlushRxFIFO(CHANNEL_T * ChP)
3018{ 3030{
3019 int i; 3031 int i;
3020 Byte_t Ch; /* channel number within AIOP */ 3032 Byte_t Ch; /* channel number within AIOP */
3021 int RxFIFOEnabled; /* TRUE if Rx FIFO enabled */ 3033 int RxFIFOEnabled; /* 1 if Rx FIFO enabled */
3022 3034
3023 if (sGetRxCnt(ChP) == 0) /* Rx FIFO empty */ 3035 if (sGetRxCnt(ChP) == 0) /* Rx FIFO empty */
3024 return; /* don't need to flush */ 3036 return; /* don't need to flush */
3025 3037
3026 RxFIFOEnabled = FALSE; 3038 RxFIFOEnabled = 0;
3027 if (ChP->R[0x32] == 0x08) { /* Rx FIFO is enabled */ 3039 if (ChP->R[0x32] == 0x08) { /* Rx FIFO is enabled */
3028 RxFIFOEnabled = TRUE; 3040 RxFIFOEnabled = 1;
3029 sDisRxFIFO(ChP); /* disable it */ 3041 sDisRxFIFO(ChP); /* disable it */
3030 for (i = 0; i < 2000 / 200; i++) /* delay 2 uS to allow proc to disable FIFO */ 3042 for (i = 0; i < 2000 / 200; i++) /* delay 2 uS to allow proc to disable FIFO */
3031 sInB(ChP->IntChan); /* depends on bus i/o timing */ 3043 sInB(ChP->IntChan); /* depends on bus i/o timing */
@@ -3056,18 +3068,18 @@ Comments: To prevent data from being enqueued or dequeued in the Tx FIFO
3056 this function. 3068 this function.
3057Warnings: No context switches are allowed while executing this function. 3069Warnings: No context switches are allowed while executing this function.
3058*/ 3070*/
3059void sFlushTxFIFO(CHANNEL_T * ChP) 3071static void sFlushTxFIFO(CHANNEL_T * ChP)
3060{ 3072{
3061 int i; 3073 int i;
3062 Byte_t Ch; /* channel number within AIOP */ 3074 Byte_t Ch; /* channel number within AIOP */
3063 int TxEnabled; /* TRUE if transmitter enabled */ 3075 int TxEnabled; /* 1 if transmitter enabled */
3064 3076
3065 if (sGetTxCnt(ChP) == 0) /* Tx FIFO empty */ 3077 if (sGetTxCnt(ChP) == 0) /* Tx FIFO empty */
3066 return; /* don't need to flush */ 3078 return; /* don't need to flush */
3067 3079
3068 TxEnabled = FALSE; 3080 TxEnabled = 0;
3069 if (ChP->TxControl[3] & TX_ENABLE) { 3081 if (ChP->TxControl[3] & TX_ENABLE) {
3070 TxEnabled = TRUE; 3082 TxEnabled = 1;
3071 sDisTransmit(ChP); /* disable transmitter */ 3083 sDisTransmit(ChP); /* disable transmitter */
3072 } 3084 }
3073 sStopRxProcessor(ChP); /* stop Rx processor */ 3085 sStopRxProcessor(ChP); /* stop Rx processor */
@@ -3096,7 +3108,7 @@ Comments: The priority byte is transmitted before any data in the Tx FIFO.
3096 3108
3097Warnings: No context switches are allowed while executing this function. 3109Warnings: No context switches are allowed while executing this function.
3098*/ 3110*/
3099int sWriteTxPrioByte(CHANNEL_T * ChP, Byte_t Data) 3111static int sWriteTxPrioByte(CHANNEL_T * ChP, Byte_t Data)
3100{ 3112{
3101 Byte_t DWBuf[4]; /* buffer for double word writes */ 3113 Byte_t DWBuf[4]; /* buffer for double word writes */
3102 Word_t *WordPtr; /* must be far because Win SS != DS */ 3114 Word_t *WordPtr; /* must be far because Win SS != DS */
@@ -3158,7 +3170,7 @@ Comments: If an interrupt enable flag is set in Flags, that interrupt will be
3158 enable channel interrupts. This would allow the global interrupt 3170 enable channel interrupts. This would allow the global interrupt
3159 status register to be used to determine which AIOPs need service. 3171 status register to be used to determine which AIOPs need service.
3160*/ 3172*/
3161void sEnInterrupts(CHANNEL_T * ChP, Word_t Flags) 3173static void sEnInterrupts(CHANNEL_T * ChP, Word_t Flags)
3162{ 3174{
3163 Byte_t Mask; /* Interrupt Mask Register */ 3175 Byte_t Mask; /* Interrupt Mask Register */
3164 3176
@@ -3202,7 +3214,7 @@ Comments: If an interrupt flag is set in Flags, that interrupt will be
3202 this channel's bit from being set in the AIOP's Interrupt Channel 3214 this channel's bit from being set in the AIOP's Interrupt Channel
3203 Register. 3215 Register.
3204*/ 3216*/
3205void sDisInterrupts(CHANNEL_T * ChP, Word_t Flags) 3217static void sDisInterrupts(CHANNEL_T * ChP, Word_t Flags)
3206{ 3218{
3207 Byte_t Mask; /* Interrupt Mask Register */ 3219 Byte_t Mask; /* Interrupt Mask Register */
3208 3220
@@ -3218,7 +3230,7 @@ void sDisInterrupts(CHANNEL_T * ChP, Word_t Flags)
3218 } 3230 }
3219} 3231}
3220 3232
3221void sSetInterfaceMode(CHANNEL_T * ChP, Byte_t mode) 3233static void sSetInterfaceMode(CHANNEL_T * ChP, Byte_t mode)
3222{ 3234{
3223 sOutB(ChP->CtlP->AiopIO[2], (mode & 0x18) | ChP->ChanNum); 3235 sOutB(ChP->CtlP->AiopIO[2], (mode & 0x18) | ChP->ChanNum);
3224} 3236}
@@ -3227,7 +3239,7 @@ void sSetInterfaceMode(CHANNEL_T * ChP, Byte_t mode)
3227 * Not an official SSCI function, but how to reset RocketModems. 3239 * Not an official SSCI function, but how to reset RocketModems.
3228 * ISA bus version 3240 * ISA bus version
3229 */ 3241 */
3230void sModemReset(CONTROLLER_T * CtlP, int chan, int on) 3242static void sModemReset(CONTROLLER_T * CtlP, int chan, int on)
3231{ 3243{
3232 ByteIO_t addr; 3244 ByteIO_t addr;
3233 Byte_t val; 3245 Byte_t val;
@@ -3252,7 +3264,7 @@ void sModemReset(CONTROLLER_T * CtlP, int chan, int on)
3252 * Not an official SSCI function, but how to reset RocketModems. 3264 * Not an official SSCI function, but how to reset RocketModems.
3253 * PCI bus version 3265 * PCI bus version
3254 */ 3266 */
3255void sPCIModemReset(CONTROLLER_T * CtlP, int chan, int on) 3267static void sPCIModemReset(CONTROLLER_T * CtlP, int chan, int on)
3256{ 3268{
3257 ByteIO_t addr; 3269 ByteIO_t addr;
3258 3270
diff --git a/drivers/char/rocket_int.h b/drivers/char/rocket_int.h
index 802687290ee1..3a8bcc85bc14 100644
--- a/drivers/char/rocket_int.h
+++ b/drivers/char/rocket_int.h
@@ -1130,46 +1130,6 @@ Warnings: This function writes the data byte without checking to see if
1130*/ 1130*/
1131#define sWriteTxByte(IO,DATA) sOutB(IO,DATA) 1131#define sWriteTxByte(IO,DATA) sOutB(IO,DATA)
1132 1132
1133int sInitController(CONTROLLER_T * CtlP,
1134 int CtlNum,
1135 ByteIO_t MudbacIO,
1136 ByteIO_t * AiopIOList,
1137 int AiopIOListSize,
1138 int IRQNum, Byte_t Frequency, int PeriodicOnly);
1139
1140int sPCIInitController(CONTROLLER_T * CtlP,
1141 int CtlNum,
1142 ByteIO_t * AiopIOList,
1143 int AiopIOListSize,
1144 WordIO_t ConfigIO,
1145 int IRQNum,
1146 Byte_t Frequency,
1147 int PeriodicOnly,
1148 int altChanRingIndicator, int UPCIRingInd);
1149
1150int sReadAiopID(ByteIO_t io);
1151int sReadAiopNumChan(WordIO_t io);
1152int sInitChan(CONTROLLER_T * CtlP,
1153 CHANNEL_T * ChP, int AiopNum, int ChanNum);
1154Byte_t sGetRxErrStatus(CHANNEL_T * ChP);
1155void sStopRxProcessor(CHANNEL_T * ChP);
1156void sStopSWInFlowCtl(CHANNEL_T * ChP);
1157void sFlushRxFIFO(CHANNEL_T * ChP);
1158void sFlushTxFIFO(CHANNEL_T * ChP);
1159int sWriteTxPrioByte(CHANNEL_T * ChP, Byte_t Data);
1160void sEnInterrupts(CHANNEL_T * ChP, Word_t Flags);
1161void sDisInterrupts(CHANNEL_T * ChP, Word_t Flags);
1162void sModemReset(CONTROLLER_T * CtlP, int chan, int on);
1163void sPCIModemReset(CONTROLLER_T * CtlP, int chan, int on);
1164void sSetInterfaceMode(CHANNEL_T * ChP, Byte_t mode);
1165
1166extern Byte_t R[RDATASIZE];
1167extern CONTROLLER_T sController[CTL_SIZE];
1168extern Byte_t sIRQMap[16];
1169extern Byte_t sBitMapClrTbl[8];
1170extern Byte_t sBitMapSetTbl[8];
1171extern int sClockPrescale;
1172
1173/* 1133/*
1174 * Begin Linux specific definitions for the Rocketport driver 1134 * Begin Linux specific definitions for the Rocketport driver
1175 * 1135 *
diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c
index f59f7cbd525b..af79805b5576 100644
--- a/drivers/char/sysrq.c
+++ b/drivers/char/sysrq.c
@@ -35,6 +35,7 @@
35#include <linux/spinlock.h> 35#include <linux/spinlock.h>
36#include <linux/vt_kern.h> 36#include <linux/vt_kern.h>
37#include <linux/workqueue.h> 37#include <linux/workqueue.h>
38#include <linux/kexec.h>
38 39
39#include <asm/ptrace.h> 40#include <asm/ptrace.h>
40 41
@@ -94,6 +95,21 @@ static struct sysrq_key_op sysrq_unraw_op = {
94}; 95};
95#endif /* CONFIG_VT */ 96#endif /* CONFIG_VT */
96 97
98#ifdef CONFIG_KEXEC
99/* crashdump sysrq handler */
100static void sysrq_handle_crashdump(int key, struct pt_regs *pt_regs,
101 struct tty_struct *tty)
102{
103 crash_kexec(pt_regs);
104}
105static struct sysrq_key_op sysrq_crashdump_op = {
106 .handler = sysrq_handle_crashdump,
107 .help_msg = "Crashdump",
108 .action_msg = "Trigger a crashdump",
109 .enable_mask = SYSRQ_ENABLE_DUMP,
110};
111#endif
112
97/* reboot sysrq handler */ 113/* reboot sysrq handler */
98static void sysrq_handle_reboot(int key, struct pt_regs *pt_regs, 114static void sysrq_handle_reboot(int key, struct pt_regs *pt_regs,
99 struct tty_struct *tty) 115 struct tty_struct *tty)
@@ -273,8 +289,12 @@ static struct sysrq_key_op *sysrq_key_table[SYSRQ_KEY_TABLE_LENGTH] = {
273 it is handled specially on the sparc 289 it is handled specially on the sparc
274 and will never arrive */ 290 and will never arrive */
275/* b */ &sysrq_reboot_op, 291/* b */ &sysrq_reboot_op,
276/* c */ NULL, 292#ifdef CONFIG_KEXEC
277/* d */ NULL, 293/* c */ &sysrq_crashdump_op,
294#else
295/* c */ NULL,
296#endif
297/* d */ NULL,
278/* e */ &sysrq_term_op, 298/* e */ &sysrq_term_op,
279/* f */ &sysrq_moom_op, 299/* f */ &sysrq_moom_op,
280/* g */ NULL, 300/* g */ NULL,
diff --git a/drivers/char/toshiba.c b/drivers/char/toshiba.c
index 58e21fe44262..0c6f521abd0e 100644
--- a/drivers/char/toshiba.c
+++ b/drivers/char/toshiba.c
@@ -73,16 +73,20 @@
73 73
74#define TOSH_MINOR_DEV 181 74#define TOSH_MINOR_DEV 181
75 75
76static int tosh_id = 0x0000; 76MODULE_LICENSE("GPL");
77static int tosh_bios = 0x0000; 77MODULE_AUTHOR("Jonathan Buzzard <jonathan@buzzard.org.uk>");
78static int tosh_date = 0x0000; 78MODULE_DESCRIPTION("Toshiba laptop SMM driver");
79static int tosh_sci = 0x0000; 79MODULE_SUPPORTED_DEVICE("toshiba");
80static int tosh_fan = 0;
81
82static int tosh_fn = 0;
83 80
84module_param(tosh_fn, int, 0); 81static int tosh_fn;
82module_param_named(fn, tosh_fn, int, 0);
83MODULE_PARM_DESC(fn, "User specified Fn key detection port");
85 84
85static int tosh_id;
86static int tosh_bios;
87static int tosh_date;
88static int tosh_sci;
89static int tosh_fan;
86 90
87static int tosh_ioctl(struct inode *, struct file *, unsigned int, 91static int tosh_ioctl(struct inode *, struct file *, unsigned int,
88 unsigned long); 92 unsigned long);
@@ -359,7 +363,7 @@ static int tosh_get_machine_id(void)
359 unsigned long address; 363 unsigned long address;
360 364
361 id = (0x100*(int) isa_readb(0xffffe))+((int) isa_readb(0xffffa)); 365 id = (0x100*(int) isa_readb(0xffffe))+((int) isa_readb(0xffffa));
362 366
363 /* do we have a SCTTable machine identication number on our hands */ 367 /* do we have a SCTTable machine identication number on our hands */
364 368
365 if (id==0xfc2f) { 369 if (id==0xfc2f) {
@@ -424,7 +428,7 @@ static int tosh_probe(void)
424 } 428 }
425 429
426 /* call the Toshiba SCI support check routine */ 430 /* call the Toshiba SCI support check routine */
427 431
428 regs.eax = 0xf0f0; 432 regs.eax = 0xf0f0;
429 regs.ebx = 0x0000; 433 regs.ebx = 0x0000;
430 regs.ecx = 0x0000; 434 regs.ecx = 0x0000;
@@ -440,7 +444,7 @@ static int tosh_probe(void)
440 /* if we get this far then we are running on a Toshiba (probably)! */ 444 /* if we get this far then we are running on a Toshiba (probably)! */
441 445
442 tosh_sci = regs.edx & 0xffff; 446 tosh_sci = regs.edx & 0xffff;
443 447
444 /* next get the machine ID of the current laptop */ 448 /* next get the machine ID of the current laptop */
445 449
446 tosh_id = tosh_get_machine_id(); 450 tosh_id = tosh_get_machine_id();
@@ -475,16 +479,15 @@ static int tosh_probe(void)
475 return 0; 479 return 0;
476} 480}
477 481
478int __init tosh_init(void) 482static int __init toshiba_init(void)
479{ 483{
480 int retval; 484 int retval;
481 /* are we running on a Toshiba laptop */ 485 /* are we running on a Toshiba laptop */
482 486
483 if (tosh_probe()!=0) 487 if (tosh_probe())
484 return -EIO; 488 return -ENODEV;
485 489
486 printk(KERN_INFO "Toshiba System Managment Mode driver v" 490 printk(KERN_INFO "Toshiba System Managment Mode driver v" TOSH_VERSION "\n");
487 TOSH_VERSION"\n");
488 491
489 /* set the port to use for Fn status if not specified as a parameter */ 492 /* set the port to use for Fn status if not specified as a parameter */
490 if (tosh_fn==0x00) 493 if (tosh_fn==0x00)
@@ -492,12 +495,12 @@ int __init tosh_init(void)
492 495
493 /* register the device file */ 496 /* register the device file */
494 retval = misc_register(&tosh_device); 497 retval = misc_register(&tosh_device);
495 if(retval < 0) 498 if (retval < 0)
496 return retval; 499 return retval;
497 500
498#ifdef CONFIG_PROC_FS 501#ifdef CONFIG_PROC_FS
499 /* register the proc entry */ 502 /* register the proc entry */
500 if(create_proc_info_entry("toshiba", 0, NULL, tosh_get_info) == NULL){ 503 if (create_proc_info_entry("toshiba", 0, NULL, tosh_get_info) == NULL) {
501 misc_deregister(&tosh_device); 504 misc_deregister(&tosh_device);
502 return -ENOMEM; 505 return -ENOMEM;
503 } 506 }
@@ -506,27 +509,12 @@ int __init tosh_init(void)
506 return 0; 509 return 0;
507} 510}
508 511
509#ifdef MODULE 512static void __exit toshiba_exit(void)
510int init_module(void)
511{
512 return tosh_init();
513}
514
515void cleanup_module(void)
516{ 513{
517 /* remove the proc entry */
518
519 remove_proc_entry("toshiba", NULL); 514 remove_proc_entry("toshiba", NULL);
520
521 /* unregister the device file */
522
523 misc_deregister(&tosh_device); 515 misc_deregister(&tosh_device);
524} 516}
525#endif
526 517
527MODULE_LICENSE("GPL"); 518module_init(toshiba_init);
528MODULE_PARM_DESC(tosh_fn, "User specified Fn key detection port"); 519module_exit(toshiba_exit);
529MODULE_AUTHOR("Jonathan Buzzard <jonathan@buzzard.org.uk>");
530MODULE_DESCRIPTION("Toshiba laptop SMM driver");
531MODULE_SUPPORTED_DEVICE("toshiba");
532 520
diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c
index 5c843c9bf819..854475c54f0e 100644
--- a/drivers/char/tpm/tpm.c
+++ b/drivers/char/tpm/tpm.c
@@ -233,10 +233,10 @@ ssize_t tpm_show_pubek(struct device *dev, struct device_attribute *attr,
233 data[15], data[16], data[17], data[22], data[23], 233 data[15], data[16], data[17], data[22], data[23],
234 data[24], data[25], data[26], data[27], data[28], 234 data[24], data[25], data[26], data[27], data[28],
235 data[29], data[30], data[31], data[32], data[33], 235 data[29], data[30], data[31], data[32], data[33],
236 be32_to_cpu(*((__be32 *) (data + 32)))); 236 be32_to_cpu(*((__be32 *) (data + 34))));
237 237
238 for (i = 0; i < 256; i++) { 238 for (i = 0; i < 256; i++) {
239 str += sprintf(str, "%02X ", data[i + 39]); 239 str += sprintf(str, "%02X ", data[i + 38]);
240 if ((i + 1) % 16 == 0) 240 if ((i + 1) % 16 == 0)
241 str += sprintf(str, "\n"); 241 str += sprintf(str, "\n");
242 } 242 }
@@ -464,6 +464,7 @@ void __devexit tpm_remove(struct pci_dev *pci_dev)
464 464
465 pci_set_drvdata(pci_dev, NULL); 465 pci_set_drvdata(pci_dev, NULL);
466 misc_deregister(&chip->vendor->miscdev); 466 misc_deregister(&chip->vendor->miscdev);
467 kfree(&chip->vendor->miscdev.name);
467 468
468 sysfs_remove_group(&pci_dev->dev.kobj, chip->vendor->attr_group); 469 sysfs_remove_group(&pci_dev->dev.kobj, chip->vendor->attr_group);
469 470
@@ -526,7 +527,9 @@ EXPORT_SYMBOL_GPL(tpm_pm_resume);
526int tpm_register_hardware(struct pci_dev *pci_dev, 527int tpm_register_hardware(struct pci_dev *pci_dev,
527 struct tpm_vendor_specific *entry) 528 struct tpm_vendor_specific *entry)
528{ 529{
529 char devname[7]; 530#define DEVNAME_SIZE 7
531
532 char *devname;
530 struct tpm_chip *chip; 533 struct tpm_chip *chip;
531 int i, j; 534 int i, j;
532 535
@@ -569,7 +572,8 @@ dev_num_search_complete:
569 else 572 else
570 chip->vendor->miscdev.minor = MISC_DYNAMIC_MINOR; 573 chip->vendor->miscdev.minor = MISC_DYNAMIC_MINOR;
571 574
572 snprintf(devname, sizeof(devname), "%s%d", "tpm", chip->dev_num); 575 devname = kmalloc(DEVNAME_SIZE, GFP_KERNEL);
576 scnprintf(devname, DEVNAME_SIZE, "%s%d", "tpm", chip->dev_num);
573 chip->vendor->miscdev.name = devname; 577 chip->vendor->miscdev.name = devname;
574 578
575 chip->vendor->miscdev.dev = &(pci_dev->dev); 579 chip->vendor->miscdev.dev = &(pci_dev->dev);
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index 10cb450191a6..373b41f6b460 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -31,8 +31,8 @@ enum tpm_timeout {
31 31
32/* TPM addresses */ 32/* TPM addresses */
33enum tpm_addr { 33enum tpm_addr {
34 TPM_SUPERIO_ADDR = 0x2E,
34 TPM_ADDR = 0x4E, 35 TPM_ADDR = 0x4E,
35 TPM_DATA = 0x4F
36}; 36};
37 37
38extern ssize_t tpm_show_pubek(struct device *, struct device_attribute *attr, 38extern ssize_t tpm_show_pubek(struct device *, struct device_attribute *attr,
@@ -79,16 +79,16 @@ struct tpm_chip {
79 struct list_head list; 79 struct list_head list;
80}; 80};
81 81
82static inline int tpm_read_index(int index) 82static inline int tpm_read_index(int base, int index)
83{ 83{
84 outb(index, TPM_ADDR); 84 outb(index, base);
85 return inb(TPM_DATA) & 0xFF; 85 return inb(base+1) & 0xFF;
86} 86}
87 87
88static inline void tpm_write_index(int index, int value) 88static inline void tpm_write_index(int base, int index, int value)
89{ 89{
90 outb(index, TPM_ADDR); 90 outb(index, base);
91 outb(value & 0xFF, TPM_DATA); 91 outb(value & 0xFF, base+1);
92} 92}
93 93
94extern int tpm_register_hardware(struct pci_dev *, 94extern int tpm_register_hardware(struct pci_dev *,
diff --git a/drivers/char/tpm/tpm_atmel.c b/drivers/char/tpm/tpm_atmel.c
index 61fe14a77124..cc2cc77fd174 100644
--- a/drivers/char/tpm/tpm_atmel.c
+++ b/drivers/char/tpm/tpm_atmel.c
@@ -163,24 +163,24 @@ static int __devinit tpm_atml_init(struct pci_dev *pci_dev,
163 if (pci_enable_device(pci_dev)) 163 if (pci_enable_device(pci_dev))
164 return -EIO; 164 return -EIO;
165 165
166 lo = tpm_read_index( TPM_ATMEL_BASE_ADDR_LO ); 166 lo = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_LO);
167 hi = tpm_read_index( TPM_ATMEL_BASE_ADDR_HI ); 167 hi = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_HI);
168 168
169 tpm_atmel.base = (hi<<8)|lo; 169 tpm_atmel.base = (hi<<8)|lo;
170 dev_dbg( &pci_dev->dev, "Operating with base: 0x%x\n", tpm_atmel.base); 170 dev_dbg( &pci_dev->dev, "Operating with base: 0x%x\n", tpm_atmel.base);
171 171
172 /* verify that it is an Atmel part */ 172 /* verify that it is an Atmel part */
173 if (tpm_read_index(4) != 'A' || tpm_read_index(5) != 'T' 173 if (tpm_read_index(TPM_ADDR, 4) != 'A' || tpm_read_index(TPM_ADDR, 5) != 'T'
174 || tpm_read_index(6) != 'M' || tpm_read_index(7) != 'L') { 174 || tpm_read_index(TPM_ADDR, 6) != 'M' || tpm_read_index(TPM_ADDR, 7) != 'L') {
175 rc = -ENODEV; 175 rc = -ENODEV;
176 goto out_err; 176 goto out_err;
177 } 177 }
178 178
179 /* query chip for its version number */ 179 /* query chip for its version number */
180 if ((version[0] = tpm_read_index(0x00)) != 0xFF) { 180 if ((version[0] = tpm_read_index(TPM_ADDR, 0x00)) != 0xFF) {
181 version[1] = tpm_read_index(0x01); 181 version[1] = tpm_read_index(TPM_ADDR, 0x01);
182 version[2] = tpm_read_index(0x02); 182 version[2] = tpm_read_index(TPM_ADDR, 0x02);
183 version[3] = tpm_read_index(0x03); 183 version[3] = tpm_read_index(TPM_ADDR, 0x03);
184 } else { 184 } else {
185 dev_info(&pci_dev->dev, "version query failed\n"); 185 dev_info(&pci_dev->dev, "version query failed\n");
186 rc = -ENODEV; 186 rc = -ENODEV;
diff --git a/drivers/char/tpm/tpm_nsc.c b/drivers/char/tpm/tpm_nsc.c
index 1a45e7dfc13b..b4127348c063 100644
--- a/drivers/char/tpm/tpm_nsc.c
+++ b/drivers/char/tpm/tpm_nsc.c
@@ -23,7 +23,6 @@
23 23
24/* National definitions */ 24/* National definitions */
25enum tpm_nsc_addr{ 25enum tpm_nsc_addr{
26 TPM_NSC_BASE = 0x360,
27 TPM_NSC_IRQ = 0x07, 26 TPM_NSC_IRQ = 0x07,
28 TPM_NSC_BASE0_HI = 0x60, 27 TPM_NSC_BASE0_HI = 0x60,
29 TPM_NSC_BASE0_LO = 0x61, 28 TPM_NSC_BASE0_LO = 0x61,
@@ -56,6 +55,7 @@ enum tpm_nsc_status {
56 NSC_STATUS_RDY = 0x10, /* ready to receive command */ 55 NSC_STATUS_RDY = 0x10, /* ready to receive command */
57 NSC_STATUS_IBR = 0x20 /* ready to receive data */ 56 NSC_STATUS_IBR = 0x20 /* ready to receive data */
58}; 57};
58
59/* command bits */ 59/* command bits */
60enum tpm_nsc_cmd_mode { 60enum tpm_nsc_cmd_mode {
61 NSC_COMMAND_NORMAL = 0x01, /* normal mode */ 61 NSC_COMMAND_NORMAL = 0x01, /* normal mode */
@@ -150,7 +150,8 @@ static int tpm_nsc_recv(struct tpm_chip *chip, u8 * buf, size_t count)
150 *p = inb(chip->vendor->base + NSC_DATA); 150 *p = inb(chip->vendor->base + NSC_DATA);
151 } 151 }
152 152
153 if ((data & NSC_STATUS_F0) == 0) { 153 if ((data & NSC_STATUS_F0) == 0 &&
154 (wait_for_stat(chip, NSC_STATUS_F0, NSC_STATUS_F0, &data) < 0)) {
154 dev_err(&chip->pci_dev->dev, "F0 not set\n"); 155 dev_err(&chip->pci_dev->dev, "F0 not set\n");
155 return -EIO; 156 return -EIO;
156 } 157 }
@@ -259,85 +260,64 @@ static int __devinit tpm_nsc_init(struct pci_dev *pci_dev,
259{ 260{
260 int rc = 0; 261 int rc = 0;
261 int lo, hi; 262 int lo, hi;
263 int nscAddrBase = TPM_ADDR;
262 264
263 hi = tpm_read_index(TPM_NSC_BASE0_HI);
264 lo = tpm_read_index(TPM_NSC_BASE0_LO);
265
266 tpm_nsc.base = (hi<<8) | lo;
267 265
268 if (pci_enable_device(pci_dev)) 266 if (pci_enable_device(pci_dev))
269 return -EIO; 267 return -EIO;
270 268
269 /* select PM channel 1 */
270 tpm_write_index(nscAddrBase,NSC_LDN_INDEX, 0x12);
271
271 /* verify that it is a National part (SID) */ 272 /* verify that it is a National part (SID) */
272 if (tpm_read_index(NSC_SID_INDEX) != 0xEF) { 273 if (tpm_read_index(TPM_ADDR, NSC_SID_INDEX) != 0xEF) {
273 rc = -ENODEV; 274 nscAddrBase = (tpm_read_index(TPM_SUPERIO_ADDR, 0x2C)<<8)|
274 goto out_err; 275 (tpm_read_index(TPM_SUPERIO_ADDR, 0x2B)&0xFE);
276 if (tpm_read_index(nscAddrBase, NSC_SID_INDEX) != 0xF6) {
277 rc = -ENODEV;
278 goto out_err;
279 }
275 } 280 }
276 281
282 hi = tpm_read_index(nscAddrBase, TPM_NSC_BASE0_HI);
283 lo = tpm_read_index(nscAddrBase, TPM_NSC_BASE0_LO);
284 tpm_nsc.base = (hi<<8) | lo;
285
277 dev_dbg(&pci_dev->dev, "NSC TPM detected\n"); 286 dev_dbg(&pci_dev->dev, "NSC TPM detected\n");
278 dev_dbg(&pci_dev->dev, 287 dev_dbg(&pci_dev->dev,
279 "NSC LDN 0x%x, SID 0x%x, SRID 0x%x\n", 288 "NSC LDN 0x%x, SID 0x%x, SRID 0x%x\n",
280 tpm_read_index(0x07), tpm_read_index(0x20), 289 tpm_read_index(nscAddrBase,0x07), tpm_read_index(nscAddrBase,0x20),
281 tpm_read_index(0x27)); 290 tpm_read_index(nscAddrBase,0x27));
282 dev_dbg(&pci_dev->dev, 291 dev_dbg(&pci_dev->dev,
283 "NSC SIOCF1 0x%x SIOCF5 0x%x SIOCF6 0x%x SIOCF8 0x%x\n", 292 "NSC SIOCF1 0x%x SIOCF5 0x%x SIOCF6 0x%x SIOCF8 0x%x\n",
284 tpm_read_index(0x21), tpm_read_index(0x25), 293 tpm_read_index(nscAddrBase,0x21), tpm_read_index(nscAddrBase,0x25),
285 tpm_read_index(0x26), tpm_read_index(0x28)); 294 tpm_read_index(nscAddrBase,0x26), tpm_read_index(nscAddrBase,0x28));
286 dev_dbg(&pci_dev->dev, "NSC IO Base0 0x%x\n", 295 dev_dbg(&pci_dev->dev, "NSC IO Base0 0x%x\n",
287 (tpm_read_index(0x60) << 8) | tpm_read_index(0x61)); 296 (tpm_read_index(nscAddrBase,0x60) << 8) | tpm_read_index(nscAddrBase,0x61));
288 dev_dbg(&pci_dev->dev, "NSC IO Base1 0x%x\n", 297 dev_dbg(&pci_dev->dev, "NSC IO Base1 0x%x\n",
289 (tpm_read_index(0x62) << 8) | tpm_read_index(0x63)); 298 (tpm_read_index(nscAddrBase,0x62) << 8) | tpm_read_index(nscAddrBase,0x63));
290 dev_dbg(&pci_dev->dev, "NSC Interrupt number and wakeup 0x%x\n", 299 dev_dbg(&pci_dev->dev, "NSC Interrupt number and wakeup 0x%x\n",
291 tpm_read_index(0x70)); 300 tpm_read_index(nscAddrBase,0x70));
292 dev_dbg(&pci_dev->dev, "NSC IRQ type select 0x%x\n", 301 dev_dbg(&pci_dev->dev, "NSC IRQ type select 0x%x\n",
293 tpm_read_index(0x71)); 302 tpm_read_index(nscAddrBase,0x71));
294 dev_dbg(&pci_dev->dev, 303 dev_dbg(&pci_dev->dev,
295 "NSC DMA channel select0 0x%x, select1 0x%x\n", 304 "NSC DMA channel select0 0x%x, select1 0x%x\n",
296 tpm_read_index(0x74), tpm_read_index(0x75)); 305 tpm_read_index(nscAddrBase,0x74), tpm_read_index(nscAddrBase,0x75));
297 dev_dbg(&pci_dev->dev, 306 dev_dbg(&pci_dev->dev,
298 "NSC Config " 307 "NSC Config "
299 "0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", 308 "0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
300 tpm_read_index(0xF0), tpm_read_index(0xF1), 309 tpm_read_index(nscAddrBase,0xF0), tpm_read_index(nscAddrBase,0xF1),
301 tpm_read_index(0xF2), tpm_read_index(0xF3), 310 tpm_read_index(nscAddrBase,0xF2), tpm_read_index(nscAddrBase,0xF3),
302 tpm_read_index(0xF4), tpm_read_index(0xF5), 311 tpm_read_index(nscAddrBase,0xF4), tpm_read_index(nscAddrBase,0xF5),
303 tpm_read_index(0xF6), tpm_read_index(0xF7), 312 tpm_read_index(nscAddrBase,0xF6), tpm_read_index(nscAddrBase,0xF7),
304 tpm_read_index(0xF8), tpm_read_index(0xF9)); 313 tpm_read_index(nscAddrBase,0xF8), tpm_read_index(nscAddrBase,0xF9));
305 314
306 dev_info(&pci_dev->dev, 315 dev_info(&pci_dev->dev,
307 "NSC PC21100 TPM revision %d\n", 316 "NSC TPM revision %d\n",
308 tpm_read_index(0x27) & 0x1F); 317 tpm_read_index(nscAddrBase, 0x27) & 0x1F);
309
310 if (tpm_read_index(NSC_LDC_INDEX) == 0)
311 dev_info(&pci_dev->dev, ": NSC TPM not active\n");
312
313 /* select PM channel 1 */
314 tpm_write_index(NSC_LDN_INDEX, 0x12);
315 tpm_read_index(NSC_LDN_INDEX);
316
317 /* disable the DPM module */
318 tpm_write_index(NSC_LDC_INDEX, 0);
319 tpm_read_index(NSC_LDC_INDEX);
320
321 /* set the data register base addresses */
322 tpm_write_index(NSC_DIO_INDEX, TPM_NSC_BASE >> 8);
323 tpm_write_index(NSC_DIO_INDEX + 1, TPM_NSC_BASE);
324 tpm_read_index(NSC_DIO_INDEX);
325 tpm_read_index(NSC_DIO_INDEX + 1);
326
327 /* set the command register base addresses */
328 tpm_write_index(NSC_CIO_INDEX, (TPM_NSC_BASE + 1) >> 8);
329 tpm_write_index(NSC_CIO_INDEX + 1, (TPM_NSC_BASE + 1));
330 tpm_read_index(NSC_DIO_INDEX);
331 tpm_read_index(NSC_DIO_INDEX + 1);
332
333 /* set the interrupt number to be used for the host interface */
334 tpm_write_index(NSC_IRQ_INDEX, TPM_NSC_IRQ);
335 tpm_write_index(NSC_ITS_INDEX, 0x00);
336 tpm_read_index(NSC_IRQ_INDEX);
337 318
338 /* enable the DPM module */ 319 /* enable the DPM module */
339 tpm_write_index(NSC_LDC_INDEX, 0x01); 320 tpm_write_index(nscAddrBase, NSC_LDC_INDEX, 0x01);
340 tpm_read_index(NSC_LDC_INDEX);
341 321
342 if ((rc = tpm_register_hardware(pci_dev, &tpm_nsc)) < 0) 322 if ((rc = tpm_register_hardware(pci_dev, &tpm_nsc)) < 0)
343 goto out_err; 323 goto out_err;
@@ -355,6 +335,9 @@ static struct pci_device_id tpm_pci_tbl[] __devinitdata = {
355 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0)}, 335 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0)},
356 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12)}, 336 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12)},
357 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0)}, 337 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0)},
338 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_0)},
339 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1)},
340 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_0)},
358 {PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_LPC)}, 341 {PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_LPC)},
359 {0,} 342 {0,}
360}; 343};
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index cc4b43bad703..6e4be3bb2d89 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -94,6 +94,7 @@
94#include <linux/idr.h> 94#include <linux/idr.h>
95#include <linux/wait.h> 95#include <linux/wait.h>
96#include <linux/bitops.h> 96#include <linux/bitops.h>
97#include <linux/delay.h>
97 98
98#include <asm/uaccess.h> 99#include <asm/uaccess.h>
99#include <asm/system.h> 100#include <asm/system.h>
@@ -2180,12 +2181,11 @@ static int tiocsetd(struct tty_struct *tty, int __user *p)
2180 return tty_set_ldisc(tty, ldisc); 2181 return tty_set_ldisc(tty, ldisc);
2181} 2182}
2182 2183
2183static int send_break(struct tty_struct *tty, int duration) 2184static int send_break(struct tty_struct *tty, unsigned int duration)
2184{ 2185{
2185 tty->driver->break_ctl(tty, -1); 2186 tty->driver->break_ctl(tty, -1);
2186 if (!signal_pending(current)) { 2187 if (!signal_pending(current)) {
2187 set_current_state(TASK_INTERRUPTIBLE); 2188 msleep_interruptible(duration);
2188 schedule_timeout(duration);
2189 } 2189 }
2190 tty->driver->break_ctl(tty, 0); 2190 tty->driver->break_ctl(tty, 0);
2191 if (signal_pending(current)) 2191 if (signal_pending(current))
@@ -2366,10 +2366,10 @@ int tty_ioctl(struct inode * inode, struct file * file,
2366 * all by anyone? 2366 * all by anyone?
2367 */ 2367 */
2368 if (!arg) 2368 if (!arg)
2369 return send_break(tty, HZ/4); 2369 return send_break(tty, 250);
2370 return 0; 2370 return 0;
2371 case TCSBRKP: /* support for POSIX tcsendbreak() */ 2371 case TCSBRKP: /* support for POSIX tcsendbreak() */
2372 return send_break(tty, arg ? arg*(HZ/10) : HZ/4); 2372 return send_break(tty, arg ? arg*100 : 250);
2373 2373
2374 case TIOCMGET: 2374 case TIOCMGET:
2375 return tty_tiocmget(tty, file, p); 2375 return tty_tiocmget(tty, file, p);