diff options
| author | Anton Altaparmakov <aia21@cantab.net> | 2005-06-26 17:19:40 -0400 |
|---|---|---|
| committer | Anton Altaparmakov <aia21@cantab.net> | 2005-06-26 17:19:40 -0400 |
| commit | 2a322e4c08be4e7cb0c04b427ddaaa679fd88863 (patch) | |
| tree | ad8cc17bfd3b5e57e36f07a249028667d72f0b96 /drivers/char | |
| parent | ba6d2377c85c9b8a793f455d8c9b6cf31985d70f (diff) | |
| parent | 8678887e7fb43cd6c9be6c9807b05e77848e0920 (diff) | |
Automatic merge with /usr/src/ntfs-2.6.git.
Diffstat (limited to 'drivers/char')
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 | ||
| 947 | config HPET | 947 | config 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 | ||
| 1976 | int register_serial(struct serial_struct *req); | ||
| 1977 | void unregister_serial(int line); | ||
| 1978 | |||
| 1979 | |||
| 1980 | static struct tty_operations serial_ops = { | 1976 | static 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 | # |
| 7 | config DRM | 7 | config 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 | |||
| 19 | ffb-objs := ffb_drv.o ffb_context.o | 19 | ffb-objs := ffb_drv.o ffb_context.o |
| 20 | sis-objs := sis_drv.o sis_ds.o sis_mm.o | 20 | sis-objs := sis_drv.o sis_ds.o sis_mm.o |
| 21 | 21 | ||
| 22 | ifeq ($(CONFIG_COMPAT),y) | ||
| 23 | drm-objs += drm_ioc32.o | ||
| 24 | radeon-objs += radeon_ioc32.o | ||
| 25 | endif | ||
| 26 | |||
| 22 | obj-$(CONFIG_DRM) += drm.o | 27 | obj-$(CONFIG_DRM) += drm.o |
| 23 | obj-$(CONFIG_DRM_GAMMA) += gamma.o | 28 | obj-$(CONFIG_DRM_GAMMA) += gamma.o |
| 24 | obj-$(CONFIG_DRM_TDFX) += tdfx.o | 29 | obj-$(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 { \ | |||
| 316 | typedef int drm_ioctl_t( struct inode *inode, struct file *filp, | 316 | typedef 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 | ||
| 319 | typedef int drm_ioctl_compat_t(struct file *filp, unsigned int cmd, | ||
| 320 | unsigned long arg); | ||
| 321 | |||
| 319 | typedef struct drm_ioctl_desc { | 322 | typedef 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); |
| 776 | extern int drm_ioctl(struct inode *inode, struct file *filp, | 779 | extern int drm_ioctl(struct inode *inode, struct file *filp, |
| 777 | unsigned int cmd, unsigned long arg); | 780 | unsigned int cmd, unsigned long arg); |
| 781 | extern long drm_compat_ioctl(struct file *filp, | ||
| 782 | unsigned int cmd, unsigned long arg); | ||
| 778 | extern int drm_takedown(drm_device_t * dev); | 783 | extern 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 | } |
| 61 | EXPORT_SYMBOL(drm_order); | 61 | EXPORT_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 | */ | ||
| 69 | static 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 | } |
| 268 | bad: | 268 | bad: |
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 | |||
| 70 | typedef 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 | |||
| 82 | static 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 | |||
| 124 | typedef struct drm_unique32 { | ||
| 125 | u32 unique_len; /**< Length of unique */ | ||
| 126 | u32 unique; /**< Unique name for driver instantiation */ | ||
| 127 | } drm_unique32_t; | ||
| 128 | |||
| 129 | static 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 | |||
| 159 | static 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 | |||
| 180 | typedef 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 | |||
| 189 | static 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 | |||
| 227 | static 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 | |||
| 270 | static 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 | |||
| 290 | typedef 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 | |||
| 299 | static 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 | |||
| 333 | typedef 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 | |||
| 341 | static 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 | |||
| 370 | typedef 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 | |||
| 379 | static 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 | |||
| 410 | static 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 | |||
| 433 | typedef struct drm_buf_info32 { | ||
| 434 | int count; /**< Entries in list */ | ||
| 435 | u32 list; | ||
| 436 | } drm_buf_info32_t; | ||
| 437 | |||
| 438 | static 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 | |||
| 490 | typedef 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 | |||
| 497 | typedef 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 | |||
| 503 | static 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 | |||
| 557 | typedef struct drm_buf_free32 { | ||
| 558 | int count; | ||
| 559 | u32 list; | ||
| 560 | } drm_buf_free32_t; | ||
| 561 | |||
| 562 | static 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 | |||
| 584 | typedef 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 | |||
| 589 | static 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 | |||
| 611 | static 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 | |||
| 642 | typedef struct drm_ctx_res32 { | ||
| 643 | int count; | ||
| 644 | u32 contexts; | ||
| 645 | } drm_ctx_res32_t; | ||
| 646 | |||
| 647 | static 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 | |||
| 678 | typedef 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 | |||
| 691 | static 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 | ||
| 735 | typedef struct drm_agp_mode32 { | ||
| 736 | u32 mode; /**< AGP mode */ | ||
| 737 | } drm_agp_mode32_t; | ||
| 738 | |||
| 739 | static 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 | |||
| 757 | typedef 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 | |||
| 771 | static 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 | |||
| 805 | typedef 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 | |||
| 812 | static 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 | |||
| 845 | static 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 | |||
| 862 | typedef 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 | |||
| 867 | static 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 | |||
| 887 | static 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 | |||
| 905 | typedef 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 | |||
| 910 | static 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 | |||
| 938 | static 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 | |||
| 956 | struct drm_wait_vblank_request32 { | ||
| 957 | drm_vblank_seq_type_t type; | ||
| 958 | unsigned int sequence; | ||
| 959 | u32 signal; | ||
| 960 | }; | ||
| 961 | |||
| 962 | struct 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 | |||
| 969 | typedef union drm_wait_vblank32 { | ||
| 970 | struct drm_wait_vblank_request32 request; | ||
| 971 | struct drm_wait_vblank_reply32 reply; | ||
| 972 | } drm_wait_vblank32_t; | ||
| 973 | |||
| 974 | static 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 | |||
| 1009 | drm_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 | */ | ||
| 1049 | long 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 | } | ||
| 1069 | EXPORT_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 ); | |||
| 317 | extern int radeon_postinit( struct drm_device *dev, unsigned long flags ); | 317 | extern int radeon_postinit( struct drm_device *dev, unsigned long flags ); |
| 318 | extern int radeon_postcleanup( struct drm_device *dev ); | 318 | extern int radeon_postcleanup( struct drm_device *dev ); |
| 319 | 319 | ||
| 320 | extern 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 | |||
| 38 | typedef 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 | |||
| 61 | static 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 | |||
| 100 | typedef 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 | |||
| 109 | static 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 | |||
| 133 | typedef struct drm_radeon_stipple32 { | ||
| 134 | u32 mask; | ||
| 135 | } drm_radeon_stipple32_t; | ||
| 136 | |||
| 137 | static 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 | |||
| 157 | typedef 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 | |||
| 163 | typedef 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 | |||
| 172 | static 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 | |||
| 212 | typedef 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 | |||
| 221 | static 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 | |||
| 246 | typedef struct drm_radeon_cmd_buffer32 { | ||
| 247 | int bufsz; | ||
| 248 | u32 buf; | ||
| 249 | int nbox; | ||
| 250 | u32 boxes; | ||
| 251 | } drm_radeon_cmd_buffer32_t; | ||
| 252 | |||
| 253 | static 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 | |||
| 276 | typedef struct drm_radeon_getparam32 { | ||
| 277 | int param; | ||
| 278 | u32 value; | ||
| 279 | } drm_radeon_getparam32_t; | ||
| 280 | |||
| 281 | static 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 | |||
| 301 | typedef 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 | |||
| 308 | static 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 | |||
| 330 | typedef struct drm_radeon_irq_emit32 { | ||
| 331 | u32 irq_seq; | ||
| 332 | } drm_radeon_irq_emit32_t; | ||
| 333 | |||
| 334 | static 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 | |||
| 353 | drm_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 | */ | ||
| 374 | long 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 | ||
| 38 | static __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 | ||
| 88 | static __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 | |||
| 96 | static int radeon_emit_irq(drm_device_t *dev) | 94 | static 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 | ||
| 225 | void radeon_driver_irq_postinstall( drm_device_t *dev ) { | 224 | void 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 | ||
| 170 | static unsigned int ds1620_in(int cmd, int bits) | 169 | static 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" | 57 | static char bios_version[4]; |
| 56 | |||
| 57 | static char *supported_models[] = { | ||
| 58 | "Inspiron", | ||
| 59 | "Latitude", | ||
| 60 | NULL | ||
| 61 | }; | ||
| 62 | |||
| 63 | static char system_vendor[48] = "?"; | ||
| 64 | static char product_name [48] = "?"; | ||
| 65 | static char bios_version [4] = "?"; | ||
| 66 | static char serial_number[16] = "?"; | ||
| 67 | 58 | ||
| 68 | MODULE_AUTHOR("Massimo Dal Zotto (dz@debian.org)"); | 59 | MODULE_AUTHOR("Massimo Dal Zotto (dz@debian.org)"); |
| 69 | MODULE_DESCRIPTION("Driver for accessing SMM BIOS on Dell laptops"); | 60 | MODULE_DESCRIPTION("Driver for accessing SMM BIOS on Dell laptops"); |
| @@ -73,6 +64,10 @@ static int force; | |||
| 73 | module_param(force, bool, 0); | 64 | module_param(force, bool, 0); |
| 74 | MODULE_PARM_DESC(force, "Force loading without checking for supported models"); | 65 | MODULE_PARM_DESC(force, "Force loading without checking for supported models"); |
| 75 | 66 | ||
| 67 | static int ignore_dmi; | ||
| 68 | module_param(ignore_dmi, bool, 0); | ||
| 69 | MODULE_PARM_DESC(ignore_dmi, "Continue probing hardware even if DMI data does not match"); | ||
| 70 | |||
| 76 | static int restricted; | 71 | static int restricted; |
| 77 | module_param(restricted, bool, 0); | 72 | module_param(restricted, bool, 0); |
| 78 | MODULE_PARM_DESC(restricted, "Allow fan control if SYS_ADMIN capability set"); | 73 | MODULE_PARM_DESC(restricted, "Allow fan control if SYS_ADMIN capability set"); |
| @@ -81,69 +76,69 @@ static int power_status; | |||
| 81 | module_param(power_status, bool, 0600); | 76 | module_param(power_status, bool, 0600); |
| 82 | MODULE_PARM_DESC(power_status, "Report power status in /proc/i8k"); | 77 | MODULE_PARM_DESC(power_status, "Report power status in /proc/i8k"); |
| 83 | 78 | ||
| 84 | static ssize_t i8k_read(struct file *, char __user *, size_t, loff_t *); | 79 | static int i8k_open_fs(struct inode *inode, struct file *file); |
| 85 | static int i8k_ioctl(struct inode *, struct file *, unsigned int, | 80 | static int i8k_ioctl(struct inode *, struct file *, unsigned int, |
| 86 | unsigned long); | 81 | unsigned long); |
| 87 | 82 | ||
| 88 | static struct file_operations i8k_fops = { | 83 | static 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 | |||
| 91 | struct 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 | ||
| 93 | typedef struct { | 100 | static 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 | |||
| 102 | typedef 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 | */ |
| 111 | static int i8k_smm(SMMRegisters *regs) | 108 | static 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 | */ |
| 153 | static int i8k_get_bios_version(void) | 148 | static 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(®s)) < 0) { | ||
| 160 | return rc; | ||
| 161 | } | ||
| 162 | |||
| 163 | return regs.eax; | ||
| 164 | } | ||
| 165 | 151 | ||
| 166 | /* | 152 | return i8k_smm(®s) ? : regs.eax; |
| 167 | * Read the machine id. | ||
| 168 | */ | ||
| 169 | static 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 | */ |
| 178 | static int i8k_get_fn_status(void) | 158 | static 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(®s)) < 0) |
| 184 | if ((rc=i8k_smm(®s)) < 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 | */ |
| 203 | static int i8k_get_power_status(void) | 181 | static 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(®s)) < 0) |
| 209 | if ((rc=i8k_smm(®s)) < 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 | */ |
| 224 | static int i8k_get_fan_status(int fan) | 195 | static 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(®s)) < 0) { | ||
| 232 | return rc; | ||
| 233 | } | ||
| 234 | 198 | ||
| 235 | return (regs.eax & 0xff); | 199 | regs.ebx = fan & 0xff; |
| 200 | return i8k_smm(®s) ? : regs.eax & 0xff; | ||
| 236 | } | 201 | } |
| 237 | 202 | ||
| 238 | /* | 203 | /* |
| @@ -240,16 +205,10 @@ static int i8k_get_fan_status(int fan) | |||
| 240 | */ | 205 | */ |
| 241 | static int i8k_get_fan_speed(int fan) | 206 | static 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(®s) ? : (regs.eax & 0xffff) * I8K_FAN_MULT; |
| 248 | if ((rc=i8k_smm(®s)) < 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 | */ |
| 258 | static int i8k_set_fan(int fan, int speed) | 217 | static 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(®s)) < 0) { | ||
| 268 | return rc; | ||
| 269 | } | ||
| 270 | 223 | ||
| 271 | return (i8k_get_fan_status(fan)); | 224 | return i8k_smm(®s) ? : i8k_get_fan_status(fan); |
| 272 | } | 225 | } |
| 273 | 226 | ||
| 274 | /* | 227 | /* |
| 275 | * Read the cpu temperature. | 228 | * Read the cpu temperature. |
| 276 | */ | 229 | */ |
| 277 | static int i8k_get_cpu_temp(void) | 230 | static 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(®s)) < 0) | ||
| 241 | return rc; | ||
| 286 | 242 | ||
| 287 | regs.eax = I8K_SMM_GET_TEMP; | 243 | temp = regs.eax & 0xff; |
| 288 | if ((rc=i8k_smm(®s)) < 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 | ||
| 312 | static int i8k_get_dell_signature(void) | 264 | static 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(®s)) < 0) |
| 318 | if ((rc=i8k_smm(®s)) < 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 | ||
| 329 | static int i8k_ioctl(struct inode *ip, struct file *fp, unsigned int cmd, | 275 | static 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; |
| 421 | static 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 | ||
| 467 | static 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 | ||
| 493 | static 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 | */ | ||
| 518 | static 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 | ||
| 537 | static void __init dmi_decode(DMIHeader *dmi) | 363 | /* |
| 364 | * Print the information for /proc/i8k. | ||
| 365 | */ | ||
| 366 | static 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 | ||
| 579 | static 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 | ||
| 622 | static int __init dmi_iterate(void (*decode)(DMIHeader *)) | 405 | static 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 | */ | ||
| 659 | static 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; | 410 | static 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 | */ |
| 689 | static int __init i8k_probe(void) | 445 | static 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 | 504 | static int __init i8k_init(void) |
| 747 | static | ||
| 748 | #endif | ||
| 749 | int __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? */ |
| 774 | int 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 | ||
| 779 | void cleanup_module(void) | 527 | static 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 */ | 532 | module_init(i8k_init); |
| 533 | module_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 |
| 100 | static 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 | ||
| 165 | cmdSyntaxPtr | 166 | cmdSyntaxPtr |
| 166 | i2cmdUnixFlags(unsigned short iflag,unsigned short cflag,unsigned short lflag) | 167 | i2cmdUnixFlags(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 | //****************************************************************************** |
| 190 | cmdSyntaxPtr | 192 | static cmdSyntaxPtr |
| 191 | i2cmdBaudDef(int which, unsigned short rate) | 193 | i2cmdBaudDef(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 | // | ||
| 74 | extern cmdSyntaxPtr i2cmdUnixFlags(USHORT iflag,USHORT cflag,USHORT lflag); | ||
| 75 | extern 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 | ||
| 2695 | do_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 | |||
| 2704 | service_it: | 2694 | service_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 | ||
| 1759 | static int __init register_ioregion(void) | 1759 | static 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 | ||
| 1774 | static void __exit unregister_ioregion(void) | 1774 | static 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 | ||
| 1806 | static int __init register_drivers(void) | 1806 | static 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 | ||
| 1837 | static void __exit unregister_drivers(void) | 1837 | static 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 | ||
| 1845 | static int __init register_isr(void) | 1845 | static 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 | ||
| 1886 | static int __init isicom_init(void) | 1886 | static 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 | ||
| 409 | static int stli_eisamempsize = sizeof(stli_eisamemprobeaddrs) / sizeof(unsigned long); | 409 | static int stli_eisamempsize = sizeof(stli_eisamemprobeaddrs) / sizeof(unsigned long); |
| 410 | int 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 | */ | ||
| 283 | static 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 | |||
| 276 | extern long vread(char *buf, char *addr, unsigned long count); | 313 | extern long vread(char *buf, char *addr, unsigned long count); |
| 277 | extern long vwrite(char *buf, char *addr, unsigned long count); | 314 | extern 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 | ||
| 725 | static struct file_operations mem_fops = { | 763 | static 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 | ||
| 812 | static struct file_operations oldmem_fops = { | ||
| 813 | .read = read_oldmem, | ||
| 814 | .open = open_oldmem, | ||
| 815 | }; | ||
| 816 | #endif | ||
| 817 | |||
| 773 | static ssize_t kmsg_write(struct file * file, const char __user * buf, | 818 | static 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 | ||
| 859 | static struct class *mem_class; | 912 | static 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]; | |||
| 66 | extern int rtc_DP8570A_init(void); | 66 | extern int rtc_DP8570A_init(void); |
| 67 | extern int rtc_MK48T08_init(void); | 67 | extern int rtc_MK48T08_init(void); |
| 68 | extern int pmu_device_init(void); | 68 | extern int pmu_device_init(void); |
| 69 | extern int tosh_init(void); | ||
| 70 | extern int i8k_init(void); | ||
| 71 | 69 | ||
| 72 | #ifdef CONFIG_PROC_FS | 70 | #ifdef CONFIG_PROC_FS |
| 73 | static void *misc_seq_start(struct seq_file *seq, loff_t *pos) | 71 | static 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 | ||
| 110 | void dsp3780I_WriteGenCfg(unsigned short usDspBaseIO, unsigned uIndex, | 110 | static 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 | ||
| 144 | unsigned char dsp3780I_ReadGenCfg(unsigned short usDspBaseIO, | 145 | unsigned 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 | ||
| 171 | int dsp3780I_EnableDSP(DSP_3780I_CONFIG_SETTINGS * pSettings, | 173 | int 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); |
| 339 | void dsp3780I_WriteMsaCfg(unsigned short usDspBaseIO, | 339 | void dsp3780I_WriteMsaCfg(unsigned short usDspBaseIO, |
| 340 | unsigned long ulMsaAddr, unsigned short usValue); | 340 | unsigned long ulMsaAddr, unsigned short usValue); |
| 341 | void dsp3780I_WriteGenCfg(unsigned short usDspBaseIO, unsigned uIndex, | ||
| 342 | unsigned char ucValue); | ||
| 343 | unsigned char dsp3780I_ReadGenCfg(unsigned short usDspBaseIO, | ||
| 344 | unsigned uIndex); | ||
| 345 | int dsp3780I_GetIPCSource(unsigned short usDspBaseIO, | 341 | int 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) | |||
| 292 | int tp3780I_EnableDSP(THINKPAD_BD_DATA * pBDData) | 286 | int 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 | ||
| 412 | exit_cleanup: | 404 | exit_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 | ||
| 214 | void | 214 | static 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 | ||
| 220 | void | 221 | void |
| 221 | nvram_set_checksum(void) | 222 | nvram_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); | |||
| 921 | EXPORT_SYMBOL(nvram_write_byte); | 923 | EXPORT_SYMBOL(nvram_write_byte); |
| 922 | EXPORT_SYMBOL(__nvram_check_checksum); | 924 | EXPORT_SYMBOL(__nvram_check_checksum); |
| 923 | EXPORT_SYMBOL(nvram_check_checksum); | 925 | EXPORT_SYMBOL(nvram_check_checksum); |
| 924 | EXPORT_SYMBOL(__nvram_set_checksum); | ||
| 925 | EXPORT_SYMBOL(nvram_set_checksum); | ||
| 926 | MODULE_ALIAS_MISCDEV(NVRAM_MINOR); | 926 | MODULE_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); | |||
| 147 | extern int rio_pcicopy(char *src, char *dst, int n); | 147 | extern int rio_pcicopy(char *src, char *dst, int n); |
| 148 | extern int rio_minor (struct tty_struct *tty); | 148 | extern int rio_minor (struct tty_struct *tty); |
| 149 | extern int rio_ismodem (struct tty_struct *tty); | 149 | extern int rio_ismodem (struct tty_struct *tty); |
| 150 | extern void rio_udelay (int usecs); | ||
| 151 | 150 | ||
| 152 | extern void rio_start_card_running (struct Host * HostP); | 151 | extern 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 | ||
| 357 | void rio_udelay (int usecs) | ||
| 358 | { | ||
| 359 | udelay (usecs); | ||
| 360 | } | ||
| 361 | |||
| 362 | static int rio_set_real_termios (void *ptr) | 357 | static 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 | ||
| 164 | static 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 | |||
| 185 | static 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 | |||
| 201 | static 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 | |||
| 212 | static Byte_t sBitMapClrTbl[8] = { | ||
| 213 | 0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f | ||
| 214 | }; | ||
| 215 | |||
| 216 | static Byte_t sBitMapSetTbl[8] = { | ||
| 217 | 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 | ||
| 218 | }; | ||
| 219 | |||
| 220 | static 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); | |||
| 177 | static unsigned char GetLineNumber(int ctrl, int aiop, int ch); | 235 | static unsigned char GetLineNumber(int ctrl, int aiop, int ch); |
| 178 | static unsigned char SetLineNumber(int ctrl, int aiop, int ch); | 236 | static unsigned char SetLineNumber(int ctrl, int aiop, int ch); |
| 179 | static void rp_start(struct tty_struct *tty); | 237 | static void rp_start(struct tty_struct *tty); |
| 238 | static int sInitChan(CONTROLLER_T * CtlP, CHANNEL_T * ChP, int AiopNum, | ||
| 239 | int ChanNum); | ||
| 240 | static void sSetInterfaceMode(CHANNEL_T * ChP, Byte_t mode); | ||
| 241 | static void sFlushRxFIFO(CHANNEL_T * ChP); | ||
| 242 | static void sFlushTxFIFO(CHANNEL_T * ChP); | ||
| 243 | static void sEnInterrupts(CHANNEL_T * ChP, Word_t Flags); | ||
| 244 | static void sDisInterrupts(CHANNEL_T * ChP, Word_t Flags); | ||
| 245 | static void sModemReset(CONTROLLER_T * CtlP, int chan, int on); | ||
| 246 | static void sPCIModemReset(CONTROLLER_T * CtlP, int chan, int on); | ||
| 247 | static int sWriteTxPrioByte(CHANNEL_T * ChP, Byte_t Data); | ||
| 248 | static 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); | ||
| 253 | static int sInitController(CONTROLLER_T * CtlP, int CtlNum, ByteIO_t MudbacIO, | ||
| 254 | ByteIO_t * AiopIOList, int AiopIOListSize, | ||
| 255 | int IRQNum, Byte_t Frequency, int PeriodicOnly); | ||
| 256 | static int sReadAiopID(ByteIO_t io); | ||
| 257 | static int sReadAiopNumChan(WordIO_t io); | ||
| 180 | 258 | ||
| 181 | #ifdef MODULE | 259 | #ifdef MODULE |
| 182 | MODULE_AUTHOR("Theodore Ts'o"); | 260 | MODULE_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) | 1879 | static __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 | |||
| 2464 | static 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 | |||
| 2485 | static 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 | |||
| 2501 | CONTROLLER_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 | |||
| 2512 | Byte_t sBitMapClrTbl[8] = { | ||
| 2513 | 0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f | ||
| 2514 | }; | ||
| 2515 | |||
| 2516 | Byte_t sBitMapSetTbl[8] = { | ||
| 2517 | 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 | ||
| 2518 | }; | ||
| 2519 | |||
| 2520 | int sClockPrescale = 0x14; | ||
| 2521 | |||
| 2522 | /*************************************************************************** | 2534 | /*************************************************************************** |
| 2523 | Function: sInitController | 2535 | Function: sInitController |
| 2524 | Purpose: Initialization of controller global registers and controller | 2536 | Purpose: 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. |
| 2563 | Return: int: Number of AIOPs on the controller, or CTLID_NULL if controller | 2575 | Return: int: Number of AIOPs on the controller, or CTLID_NULL if controller |
| 2564 | initialization failed. | 2576 | initialization failed. |
| 2565 | 2577 | ||
| 2566 | Comments: | 2578 | Comments: |
| 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 | */ |
| 2592 | int sInitController(CONTROLLER_T * CtlP, int CtlNum, ByteIO_t MudbacIO, | 2604 | static 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. |
| 2696 | Return: int: Number of AIOPs on the controller, or CTLID_NULL if controller | 2708 | Return: int: Number of AIOPs on the controller, or CTLID_NULL if controller |
| 2697 | initialization failed. | 2709 | initialization failed. |
| 2698 | 2710 | ||
| 2699 | Comments: | 2711 | Comments: |
| 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 | */ |
| 2725 | int sPCIInitController(CONTROLLER_T * CtlP, int CtlNum, | 2737 | static 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 | |||
| 2784 | Warnings: No context switches are allowed while executing this function. | 2796 | Warnings: No context switches are allowed while executing this function. |
| 2785 | 2797 | ||
| 2786 | */ | 2798 | */ |
| 2787 | int sReadAiopID(ByteIO_t io) | 2799 | static 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. |
| 2811 | Warnings: No context switches are allowed while executing this function. | 2823 | Warnings: No context switches are allowed while executing this function. |
| 2812 | */ | 2824 | */ |
| 2813 | int sReadAiopNumChan(WordIO_t io) | 2825 | static 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 |
| 2837 | Return: int: TRUE if initialization succeeded, FALSE if it fails because channel | 2849 | Return: 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. |
| 2839 | Comments: This function must be called before a channel can be used. | 2851 | Comments: This function must be called before a channel can be used. |
| 2840 | Warnings: No range checking on any of the parameters is done. | 2852 | Warnings: 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 | */ |
| 2844 | int sInitChan(CONTROLLER_T * CtlP, CHANNEL_T * ChP, int AiopNum, | 2856 | static 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 | */ |
| 2992 | void sStopRxProcessor(CHANNEL_T * ChP) | 3004 | static 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. |
| 3015 | Warnings: No context switches are allowed while executing this function. | 3027 | Warnings: No context switches are allowed while executing this function. |
| 3016 | */ | 3028 | */ |
| 3017 | void sFlushRxFIFO(CHANNEL_T * ChP) | 3029 | static 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. |
| 3057 | Warnings: No context switches are allowed while executing this function. | 3069 | Warnings: No context switches are allowed while executing this function. |
| 3058 | */ | 3070 | */ |
| 3059 | void sFlushTxFIFO(CHANNEL_T * ChP) | 3071 | static 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 | ||
| 3097 | Warnings: No context switches are allowed while executing this function. | 3109 | Warnings: No context switches are allowed while executing this function. |
| 3098 | */ | 3110 | */ |
| 3099 | int sWriteTxPrioByte(CHANNEL_T * ChP, Byte_t Data) | 3111 | static 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 | */ |
| 3161 | void sEnInterrupts(CHANNEL_T * ChP, Word_t Flags) | 3173 | static 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 | */ |
| 3205 | void sDisInterrupts(CHANNEL_T * ChP, Word_t Flags) | 3217 | static 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 | ||
| 3221 | void sSetInterfaceMode(CHANNEL_T * ChP, Byte_t mode) | 3233 | static 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 | */ |
| 3230 | void sModemReset(CONTROLLER_T * CtlP, int chan, int on) | 3242 | static 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 | */ |
| 3255 | void sPCIModemReset(CONTROLLER_T * CtlP, int chan, int on) | 3267 | static 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 | ||
| 1133 | int 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 | |||
| 1140 | int 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 | |||
| 1150 | int sReadAiopID(ByteIO_t io); | ||
| 1151 | int sReadAiopNumChan(WordIO_t io); | ||
| 1152 | int sInitChan(CONTROLLER_T * CtlP, | ||
| 1153 | CHANNEL_T * ChP, int AiopNum, int ChanNum); | ||
| 1154 | Byte_t sGetRxErrStatus(CHANNEL_T * ChP); | ||
| 1155 | void sStopRxProcessor(CHANNEL_T * ChP); | ||
| 1156 | void sStopSWInFlowCtl(CHANNEL_T * ChP); | ||
| 1157 | void sFlushRxFIFO(CHANNEL_T * ChP); | ||
| 1158 | void sFlushTxFIFO(CHANNEL_T * ChP); | ||
| 1159 | int sWriteTxPrioByte(CHANNEL_T * ChP, Byte_t Data); | ||
| 1160 | void sEnInterrupts(CHANNEL_T * ChP, Word_t Flags); | ||
| 1161 | void sDisInterrupts(CHANNEL_T * ChP, Word_t Flags); | ||
| 1162 | void sModemReset(CONTROLLER_T * CtlP, int chan, int on); | ||
| 1163 | void sPCIModemReset(CONTROLLER_T * CtlP, int chan, int on); | ||
| 1164 | void sSetInterfaceMode(CHANNEL_T * ChP, Byte_t mode); | ||
| 1165 | |||
| 1166 | extern Byte_t R[RDATASIZE]; | ||
| 1167 | extern CONTROLLER_T sController[CTL_SIZE]; | ||
| 1168 | extern Byte_t sIRQMap[16]; | ||
| 1169 | extern Byte_t sBitMapClrTbl[8]; | ||
| 1170 | extern Byte_t sBitMapSetTbl[8]; | ||
| 1171 | extern 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 */ | ||
| 100 | static void sysrq_handle_crashdump(int key, struct pt_regs *pt_regs, | ||
| 101 | struct tty_struct *tty) | ||
| 102 | { | ||
| 103 | crash_kexec(pt_regs); | ||
| 104 | } | ||
| 105 | static 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 */ |
| 98 | static void sysrq_handle_reboot(int key, struct pt_regs *pt_regs, | 114 | static 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 | ||
| 76 | static int tosh_id = 0x0000; | 76 | MODULE_LICENSE("GPL"); |
| 77 | static int tosh_bios = 0x0000; | 77 | MODULE_AUTHOR("Jonathan Buzzard <jonathan@buzzard.org.uk>"); |
| 78 | static int tosh_date = 0x0000; | 78 | MODULE_DESCRIPTION("Toshiba laptop SMM driver"); |
| 79 | static int tosh_sci = 0x0000; | 79 | MODULE_SUPPORTED_DEVICE("toshiba"); |
| 80 | static int tosh_fan = 0; | ||
| 81 | |||
| 82 | static int tosh_fn = 0; | ||
| 83 | 80 | ||
| 84 | module_param(tosh_fn, int, 0); | 81 | static int tosh_fn; |
| 82 | module_param_named(fn, tosh_fn, int, 0); | ||
| 83 | MODULE_PARM_DESC(fn, "User specified Fn key detection port"); | ||
| 85 | 84 | ||
| 85 | static int tosh_id; | ||
| 86 | static int tosh_bios; | ||
| 87 | static int tosh_date; | ||
| 88 | static int tosh_sci; | ||
| 89 | static int tosh_fan; | ||
| 86 | 90 | ||
| 87 | static int tosh_ioctl(struct inode *, struct file *, unsigned int, | 91 | static 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 | ||
| 478 | int __init tosh_init(void) | 482 | static 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 | 512 | static void __exit toshiba_exit(void) |
| 510 | int init_module(void) | ||
| 511 | { | ||
| 512 | return tosh_init(); | ||
| 513 | } | ||
| 514 | |||
| 515 | void 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 | ||
| 527 | MODULE_LICENSE("GPL"); | 518 | module_init(toshiba_init); |
| 528 | MODULE_PARM_DESC(tosh_fn, "User specified Fn key detection port"); | 519 | module_exit(toshiba_exit); |
| 529 | MODULE_AUTHOR("Jonathan Buzzard <jonathan@buzzard.org.uk>"); | ||
| 530 | MODULE_DESCRIPTION("Toshiba laptop SMM driver"); | ||
| 531 | MODULE_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); | |||
| 526 | int tpm_register_hardware(struct pci_dev *pci_dev, | 527 | int 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 */ |
| 33 | enum tpm_addr { | 33 | enum tpm_addr { |
| 34 | TPM_SUPERIO_ADDR = 0x2E, | ||
| 34 | TPM_ADDR = 0x4E, | 35 | TPM_ADDR = 0x4E, |
| 35 | TPM_DATA = 0x4F | ||
| 36 | }; | 36 | }; |
| 37 | 37 | ||
| 38 | extern ssize_t tpm_show_pubek(struct device *, struct device_attribute *attr, | 38 | extern 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 | ||
| 82 | static inline int tpm_read_index(int index) | 82 | static 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 | ||
| 88 | static inline void tpm_write_index(int index, int value) | 88 | static 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 | ||
| 94 | extern int tpm_register_hardware(struct pci_dev *, | 94 | extern 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 */ |
| 25 | enum tpm_nsc_addr{ | 25 | enum 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 */ |
| 60 | enum tpm_nsc_cmd_mode { | 60 | enum 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 | ||
| 2183 | static int send_break(struct tty_struct *tty, int duration) | 2184 | static 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); |
