Merge rsync://rsync.kernel.org/pub/scm/linux/kernel/git/dtor/input.git manually

Some manual fixups required due to clashes with the PF_FREEZE cleanups.
This commit is contained in:
Linus Torvalds
2005-06-27 14:47:31 -07:00
79 changed files with 2783 additions and 1933 deletions
+1 -1
View File
@@ -1115,7 +1115,7 @@ running once the system is up.
See Documentation/ramdisk.txt.
psmouse.proto= [HW,MOUSE] Highest PS2 mouse protocol extension to
probe for (bare|imps|exps).
probe for (bare|imps|exps|lifebook|any).
psmouse.rate= [HW,MOUSE] Set desired mouse report rate, in reports
per second.
psmouse.resetafter=
+337 -90
View File
@@ -21,6 +21,7 @@
#include <linux/smp_lock.h>
#include <linux/device.h>
#include <linux/devfs_fs_kernel.h>
#include <linux/compat.h>
struct evdev {
int exist;
@@ -145,6 +146,41 @@ static int evdev_open(struct inode * inode, struct file * file)
return 0;
}
#ifdef CONFIG_COMPAT
struct input_event_compat {
struct compat_timeval time;
__u16 type;
__u16 code;
__s32 value;
};
#ifdef CONFIG_X86_64
# define COMPAT_TEST test_thread_flag(TIF_IA32)
#elif defined(CONFIG_IA64)
# define COMPAT_TEST IS_IA32_PROCESS(ia64_task_regs(current))
#elif defined(CONFIG_ARCH_S390)
# define COMPAT_TEST test_thread_flag(TIF_31BIT)
#else
# define COMPAT_TEST test_thread_flag(TIF_32BIT)
#endif
static ssize_t evdev_write_compat(struct file * file, const char __user * buffer, size_t count, loff_t *ppos)
{
struct evdev_list *list = file->private_data;
struct input_event_compat event;
int retval = 0;
while (retval < count) {
if (copy_from_user(&event, buffer + retval, sizeof(struct input_event_compat)))
return -EFAULT;
input_event(list->evdev->handle.dev, event.type, event.code, event.value);
retval += sizeof(struct input_event_compat);
}
return retval;
}
#endif
static ssize_t evdev_write(struct file * file, const char __user * buffer, size_t count, loff_t *ppos)
{
struct evdev_list *list = file->private_data;
@@ -153,6 +189,11 @@ static ssize_t evdev_write(struct file * file, const char __user * buffer, size_
if (!list->evdev->exist) return -ENODEV;
#ifdef CONFIG_COMPAT
if (COMPAT_TEST)
return evdev_write_compat(file, buffer, count, ppos);
#endif
while (retval < count) {
if (copy_from_user(&event, buffer + retval, sizeof(struct input_event)))
@@ -164,11 +205,56 @@ static ssize_t evdev_write(struct file * file, const char __user * buffer, size_
return retval;
}
#ifdef CONFIG_COMPAT
static ssize_t evdev_read_compat(struct file * file, char __user * buffer, size_t count, loff_t *ppos)
{
struct evdev_list *list = file->private_data;
int retval;
if (count < sizeof(struct input_event_compat))
return -EINVAL;
if (list->head == list->tail && list->evdev->exist && (file->f_flags & O_NONBLOCK))
return -EAGAIN;
retval = wait_event_interruptible(list->evdev->wait,
list->head != list->tail || (!list->evdev->exist));
if (retval)
return retval;
if (!list->evdev->exist)
return -ENODEV;
while (list->head != list->tail && retval + sizeof(struct input_event_compat) <= count) {
struct input_event *event = (struct input_event *) list->buffer + list->tail;
struct input_event_compat event_compat;
event_compat.time.tv_sec = event->time.tv_sec;
event_compat.time.tv_usec = event->time.tv_usec;
event_compat.type = event->type;
event_compat.code = event->code;
event_compat.value = event->value;
if (copy_to_user(buffer + retval, &event_compat,
sizeof(struct input_event_compat))) return -EFAULT;
list->tail = (list->tail + 1) & (EVDEV_BUFFER_SIZE - 1);
retval += sizeof(struct input_event_compat);
}
return retval;
}
#endif
static ssize_t evdev_read(struct file * file, char __user * buffer, size_t count, loff_t *ppos)
{
struct evdev_list *list = file->private_data;
int retval;
#ifdef CONFIG_COMPAT
if (COMPAT_TEST)
return evdev_read_compat(file, buffer, count, ppos);
#endif
if (count < sizeof(struct input_event))
return -EINVAL;
@@ -186,7 +272,7 @@ static ssize_t evdev_read(struct file * file, char __user * buffer, size_t count
while (list->head != list->tail && retval + sizeof(struct input_event) <= count) {
if (copy_to_user(buffer + retval, list->buffer + list->tail,
sizeof(struct input_event))) return -EFAULT;
sizeof(struct input_event))) return -EFAULT;
list->tail = (list->tail + 1) & (EVDEV_BUFFER_SIZE - 1);
retval += sizeof(struct input_event);
}
@@ -203,7 +289,7 @@ static unsigned int evdev_poll(struct file *file, poll_table *wait)
(list->evdev->exist ? 0 : (POLLHUP | POLLERR));
}
static int evdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
static long evdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
struct evdev_list *list = file->private_data;
struct evdev *evdev = list->evdev;
@@ -285,110 +371,268 @@ static int evdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
default:
if (_IOC_TYPE(cmd) != 'E' || _IOC_DIR(cmd) != _IOC_READ)
if (_IOC_TYPE(cmd) != 'E')
return -EINVAL;
if ((_IOC_NR(cmd) & ~EV_MAX) == _IOC_NR(EVIOCGBIT(0,0))) {
if (_IOC_DIR(cmd) == _IOC_READ) {
long *bits;
int len;
if ((_IOC_NR(cmd) & ~EV_MAX) == _IOC_NR(EVIOCGBIT(0,0))) {
switch (_IOC_NR(cmd) & EV_MAX) {
case 0: bits = dev->evbit; len = EV_MAX; break;
case EV_KEY: bits = dev->keybit; len = KEY_MAX; break;
case EV_REL: bits = dev->relbit; len = REL_MAX; break;
case EV_ABS: bits = dev->absbit; len = ABS_MAX; break;
case EV_MSC: bits = dev->mscbit; len = MSC_MAX; break;
case EV_LED: bits = dev->ledbit; len = LED_MAX; break;
case EV_SND: bits = dev->sndbit; len = SND_MAX; break;
case EV_FF: bits = dev->ffbit; len = FF_MAX; break;
default: return -EINVAL;
long *bits;
int len;
switch (_IOC_NR(cmd) & EV_MAX) {
case 0: bits = dev->evbit; len = EV_MAX; break;
case EV_KEY: bits = dev->keybit; len = KEY_MAX; break;
case EV_REL: bits = dev->relbit; len = REL_MAX; break;
case EV_ABS: bits = dev->absbit; len = ABS_MAX; break;
case EV_MSC: bits = dev->mscbit; len = MSC_MAX; break;
case EV_LED: bits = dev->ledbit; len = LED_MAX; break;
case EV_SND: bits = dev->sndbit; len = SND_MAX; break;
case EV_FF: bits = dev->ffbit; len = FF_MAX; break;
default: return -EINVAL;
}
len = NBITS(len) * sizeof(long);
if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
return copy_to_user(p, bits, len) ? -EFAULT : len;
}
len = NBITS(len) * sizeof(long);
if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
return copy_to_user(p, bits, len) ? -EFAULT : len;
if (_IOC_NR(cmd) == _IOC_NR(EVIOCGKEY(0))) {
int len;
len = NBITS(KEY_MAX) * sizeof(long);
if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
return copy_to_user(p, dev->key, len) ? -EFAULT : len;
}
if (_IOC_NR(cmd) == _IOC_NR(EVIOCGLED(0))) {
int len;
len = NBITS(LED_MAX) * sizeof(long);
if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
return copy_to_user(p, dev->led, len) ? -EFAULT : len;
}
if (_IOC_NR(cmd) == _IOC_NR(EVIOCGSND(0))) {
int len;
len = NBITS(SND_MAX) * sizeof(long);
if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
return copy_to_user(p, dev->snd, len) ? -EFAULT : len;
}
if (_IOC_NR(cmd) == _IOC_NR(EVIOCGNAME(0))) {
int len;
if (!dev->name) return -ENOENT;
len = strlen(dev->name) + 1;
if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
return copy_to_user(p, dev->name, len) ? -EFAULT : len;
}
if (_IOC_NR(cmd) == _IOC_NR(EVIOCGPHYS(0))) {
int len;
if (!dev->phys) return -ENOENT;
len = strlen(dev->phys) + 1;
if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
return copy_to_user(p, dev->phys, len) ? -EFAULT : len;
}
if (_IOC_NR(cmd) == _IOC_NR(EVIOCGUNIQ(0))) {
int len;
if (!dev->uniq) return -ENOENT;
len = strlen(dev->uniq) + 1;
if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
return copy_to_user(p, dev->uniq, len) ? -EFAULT : len;
}
if ((_IOC_NR(cmd) & ~ABS_MAX) == _IOC_NR(EVIOCGABS(0))) {
int t = _IOC_NR(cmd) & ABS_MAX;
abs.value = dev->abs[t];
abs.minimum = dev->absmin[t];
abs.maximum = dev->absmax[t];
abs.fuzz = dev->absfuzz[t];
abs.flat = dev->absflat[t];
if (copy_to_user(p, &abs, sizeof(struct input_absinfo)))
return -EFAULT;
return 0;
}
}
if (_IOC_NR(cmd) == _IOC_NR(EVIOCGKEY(0))) {
int len;
len = NBITS(KEY_MAX) * sizeof(long);
if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
return copy_to_user(p, dev->key, len) ? -EFAULT : len;
}
if (_IOC_DIR(cmd) == _IOC_WRITE) {
if (_IOC_NR(cmd) == _IOC_NR(EVIOCGLED(0))) {
int len;
len = NBITS(LED_MAX) * sizeof(long);
if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
return copy_to_user(p, dev->led, len) ? -EFAULT : len;
}
if ((_IOC_NR(cmd) & ~ABS_MAX) == _IOC_NR(EVIOCSABS(0))) {
if (_IOC_NR(cmd) == _IOC_NR(EVIOCGSND(0))) {
int len;
len = NBITS(SND_MAX) * sizeof(long);
if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
return copy_to_user(p, dev->snd, len) ? -EFAULT : len;
}
int t = _IOC_NR(cmd) & ABS_MAX;
if (_IOC_NR(cmd) == _IOC_NR(EVIOCGNAME(0))) {
int len;
if (!dev->name) return -ENOENT;
len = strlen(dev->name) + 1;
if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
return copy_to_user(p, dev->name, len) ? -EFAULT : len;
}
if (copy_from_user(&abs, p, sizeof(struct input_absinfo)))
return -EFAULT;
if (_IOC_NR(cmd) == _IOC_NR(EVIOCGPHYS(0))) {
int len;
if (!dev->phys) return -ENOENT;
len = strlen(dev->phys) + 1;
if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
return copy_to_user(p, dev->phys, len) ? -EFAULT : len;
}
dev->abs[t] = abs.value;
dev->absmin[t] = abs.minimum;
dev->absmax[t] = abs.maximum;
dev->absfuzz[t] = abs.fuzz;
dev->absflat[t] = abs.flat;
if (_IOC_NR(cmd) == _IOC_NR(EVIOCGUNIQ(0))) {
int len;
if (!dev->uniq) return -ENOENT;
len = strlen(dev->uniq) + 1;
if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
return copy_to_user(p, dev->uniq, len) ? -EFAULT : len;
}
if ((_IOC_NR(cmd) & ~ABS_MAX) == _IOC_NR(EVIOCGABS(0))) {
int t = _IOC_NR(cmd) & ABS_MAX;
abs.value = dev->abs[t];
abs.minimum = dev->absmin[t];
abs.maximum = dev->absmax[t];
abs.fuzz = dev->absfuzz[t];
abs.flat = dev->absflat[t];
if (copy_to_user(p, &abs, sizeof(struct input_absinfo)))
return -EFAULT;
return 0;
}
if ((_IOC_NR(cmd) & ~ABS_MAX) == _IOC_NR(EVIOCSABS(0))) {
int t = _IOC_NR(cmd) & ABS_MAX;
if (copy_from_user(&abs, p, sizeof(struct input_absinfo)))
return -EFAULT;
dev->abs[t] = abs.value;
dev->absmin[t] = abs.minimum;
dev->absmax[t] = abs.maximum;
dev->absfuzz[t] = abs.fuzz;
dev->absflat[t] = abs.flat;
return 0;
return 0;
}
}
}
return -EINVAL;
}
#ifdef CONFIG_COMPAT
#define BITS_PER_LONG_COMPAT (sizeof(compat_long_t) * 8)
#define NBITS_COMPAT(x) ((((x)-1)/BITS_PER_LONG_COMPAT)+1)
#define OFF_COMPAT(x) ((x)%BITS_PER_LONG_COMPAT)
#define BIT_COMPAT(x) (1UL<<OFF_COMPAT(x))
#define LONG_COMPAT(x) ((x)/BITS_PER_LONG_COMPAT)
#define test_bit_compat(bit, array) ((array[LONG_COMPAT(bit)] >> OFF_COMPAT(bit)) & 1)
#ifdef __BIG_ENDIAN
#define bit_to_user(bit, max) \
do { \
int i; \
int len = NBITS_COMPAT((max)) * sizeof(compat_long_t); \
if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd); \
for (i = 0; i < len / sizeof(compat_long_t); i++) \
if (copy_to_user((compat_long_t*) p + i, \
(compat_long_t*) (bit) + i + 1 - ((i % 2) << 1), \
sizeof(compat_long_t))) \
return -EFAULT; \
return len; \
} while (0)
#else
#define bit_to_user(bit, max) \
do { \
int len = NBITS_COMPAT((max)) * sizeof(compat_long_t); \
if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd); \
return copy_to_user(p, (bit), len) ? -EFAULT : len; \
} while (0)
#endif
static long evdev_ioctl_compat(struct file *file, unsigned int cmd, unsigned long arg)
{
struct evdev_list *list = file->private_data;
struct evdev *evdev = list->evdev;
struct input_dev *dev = evdev->handle.dev;
struct input_absinfo abs;
void __user *p = compat_ptr(arg);
if (!evdev->exist) return -ENODEV;
switch (cmd) {
case EVIOCGVERSION:
case EVIOCGID:
case EVIOCGKEYCODE:
case EVIOCSKEYCODE:
case EVIOCSFF:
case EVIOCRMFF:
case EVIOCGEFFECTS:
case EVIOCGRAB:
return evdev_ioctl(file, cmd, (unsigned long) p);
default:
if (_IOC_TYPE(cmd) != 'E')
return -EINVAL;
if (_IOC_DIR(cmd) == _IOC_READ) {
if ((_IOC_NR(cmd) & ~EV_MAX) == _IOC_NR(EVIOCGBIT(0,0))) {
long *bits;
int max;
switch (_IOC_NR(cmd) & EV_MAX) {
case 0: bits = dev->evbit; max = EV_MAX; break;
case EV_KEY: bits = dev->keybit; max = KEY_MAX; break;
case EV_REL: bits = dev->relbit; max = REL_MAX; break;
case EV_ABS: bits = dev->absbit; max = ABS_MAX; break;
case EV_MSC: bits = dev->mscbit; max = MSC_MAX; break;
case EV_LED: bits = dev->ledbit; max = LED_MAX; break;
case EV_SND: bits = dev->sndbit; max = SND_MAX; break;
case EV_FF: bits = dev->ffbit; max = FF_MAX; break;
default: return -EINVAL;
}
bit_to_user(bits, max);
}
if (_IOC_NR(cmd) == _IOC_NR(EVIOCGKEY(0)))
bit_to_user(dev->key, KEY_MAX);
if (_IOC_NR(cmd) == _IOC_NR(EVIOCGLED(0)))
bit_to_user(dev->led, LED_MAX);
if (_IOC_NR(cmd) == _IOC_NR(EVIOCGSND(0)))
bit_to_user(dev->snd, SND_MAX);
if (_IOC_NR(cmd) == _IOC_NR(EVIOCGNAME(0))) {
int len;
if (!dev->name) return -ENOENT;
len = strlen(dev->name) + 1;
if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
return copy_to_user(p, dev->name, len) ? -EFAULT : len;
}
if (_IOC_NR(cmd) == _IOC_NR(EVIOCGPHYS(0))) {
int len;
if (!dev->phys) return -ENOENT;
len = strlen(dev->phys) + 1;
if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
return copy_to_user(p, dev->phys, len) ? -EFAULT : len;
}
if (_IOC_NR(cmd) == _IOC_NR(EVIOCGUNIQ(0))) {
int len;
if (!dev->uniq) return -ENOENT;
len = strlen(dev->uniq) + 1;
if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd);
return copy_to_user(p, dev->uniq, len) ? -EFAULT : len;
}
if ((_IOC_NR(cmd) & ~ABS_MAX) == _IOC_NR(EVIOCGABS(0))) {
int t = _IOC_NR(cmd) & ABS_MAX;
abs.value = dev->abs[t];
abs.minimum = dev->absmin[t];
abs.maximum = dev->absmax[t];
abs.fuzz = dev->absfuzz[t];
abs.flat = dev->absflat[t];
if (copy_to_user(p, &abs, sizeof(struct input_absinfo)))
return -EFAULT;
return 0;
}
}
if (_IOC_DIR(cmd) == _IOC_WRITE) {
if ((_IOC_NR(cmd) & ~ABS_MAX) == _IOC_NR(EVIOCSABS(0))) {
int t = _IOC_NR(cmd) & ABS_MAX;
if (copy_from_user(&abs, p, sizeof(struct input_absinfo)))
return -EFAULT;
dev->abs[t] = abs.value;
dev->absmin[t] = abs.minimum;
dev->absmax[t] = abs.maximum;
dev->absfuzz[t] = abs.fuzz;
dev->absflat[t] = abs.flat;
return 0;
}
}
}
return -EINVAL;
}
#endif
static struct file_operations evdev_fops = {
.owner = THIS_MODULE,
.read = evdev_read,
@@ -396,7 +640,10 @@ static struct file_operations evdev_fops = {
.poll = evdev_poll,
.open = evdev_open,
.release = evdev_release,
.ioctl = evdev_ioctl,
.unlocked_ioctl = evdev_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = evdev_ioctl_compat,
#endif
.fasync = evdev_fasync,
.flush = evdev_flush
};
-14
View File
@@ -49,22 +49,8 @@ config GAMEPORT_EMU10K1
To compile this driver as a module, choose M here: the
module will be called emu10k1-gp.
config GAMEPORT_VORTEX
tristate "Aureal Vortex, Vortex 2 gameport support"
depends on PCI
help
Say Y here if you have an Aureal Vortex 1 or 2 card and want
to use its gameport.
To compile this driver as a module, choose M here: the
module will be called vortex.
config GAMEPORT_FM801
tristate "ForteMedia FM801 gameport support"
depends on PCI
config GAMEPORT_CS461X
tristate "Crystal SoundFusion gameport support"
depends on PCI
endif
-2
View File
@@ -5,9 +5,7 @@
# Each configuration option enables a list of files.
obj-$(CONFIG_GAMEPORT) += gameport.o
obj-$(CONFIG_GAMEPORT_CS461X) += cs461x.o
obj-$(CONFIG_GAMEPORT_EMU10K1) += emu10k1-gp.o
obj-$(CONFIG_GAMEPORT_FM801) += fm801-gp.o
obj-$(CONFIG_GAMEPORT_L4) += lightning.o
obj-$(CONFIG_GAMEPORT_NS558) += ns558.o
obj-$(CONFIG_GAMEPORT_VORTEX) += vortex.o
-322
View File
@@ -1,322 +0,0 @@
/*
The all defines and part of code (such as cs461x_*) are
contributed from ALSA 0.5.8 sources.
See http://www.alsa-project.org/ for sources
Tested on Linux 686 2.4.0-test9, ALSA 0.5.8a and CS4610
*/
#include <asm/io.h>
#include <linux/module.h>
#include <linux/ioport.h>
#include <linux/config.h>
#include <linux/init.h>
#include <linux/gameport.h>
#include <linux/slab.h>
#include <linux/pci.h>
MODULE_AUTHOR("Victor Krapivin");
MODULE_LICENSE("GPL");
/*
These options are experimental
#define CS461X_FULL_MAP
*/
#ifndef PCI_VENDOR_ID_CIRRUS
#define PCI_VENDOR_ID_CIRRUS 0x1013
#endif
#ifndef PCI_DEVICE_ID_CIRRUS_4610
#define PCI_DEVICE_ID_CIRRUS_4610 0x6001
#endif
#ifndef PCI_DEVICE_ID_CIRRUS_4612
#define PCI_DEVICE_ID_CIRRUS_4612 0x6003
#endif
#ifndef PCI_DEVICE_ID_CIRRUS_4615
#define PCI_DEVICE_ID_CIRRUS_4615 0x6004
#endif
/* Registers */
#define BA0_JSPT 0x00000480
#define BA0_JSCTL 0x00000484
#define BA0_JSC1 0x00000488
#define BA0_JSC2 0x0000048C
#define BA0_JSIO 0x000004A0
/* Bits for JSPT */
#define JSPT_CAX 0x00000001
#define JSPT_CAY 0x00000002
#define JSPT_CBX 0x00000004
#define JSPT_CBY 0x00000008
#define JSPT_BA1 0x00000010
#define JSPT_BA2 0x00000020
#define JSPT_BB1 0x00000040
#define JSPT_BB2 0x00000080
/* Bits for JSCTL */
#define JSCTL_SP_MASK 0x00000003
#define JSCTL_SP_SLOW 0x00000000
#define JSCTL_SP_MEDIUM_SLOW 0x00000001
#define JSCTL_SP_MEDIUM_FAST 0x00000002
#define JSCTL_SP_FAST 0x00000003
#define JSCTL_ARE 0x00000004
/* Data register pairs masks */
#define JSC1_Y1V_MASK 0x0000FFFF
#define JSC1_X1V_MASK 0xFFFF0000
#define JSC1_Y1V_SHIFT 0
#define JSC1_X1V_SHIFT 16
#define JSC2_Y2V_MASK 0x0000FFFF
#define JSC2_X2V_MASK 0xFFFF0000
#define JSC2_Y2V_SHIFT 0
#define JSC2_X2V_SHIFT 16
/* JS GPIO */
#define JSIO_DAX 0x00000001
#define JSIO_DAY 0x00000002
#define JSIO_DBX 0x00000004
#define JSIO_DBY 0x00000008
#define JSIO_AXOE 0x00000010
#define JSIO_AYOE 0x00000020
#define JSIO_BXOE 0x00000040
#define JSIO_BYOE 0x00000080
/*
The card initialization code is obfuscated; the module cs461x
need to be loaded after ALSA modules initialized and something
played on the CS 4610 chip (see sources for details of CS4610
initialization code from ALSA)
*/
/* Card specific definitions */
#define CS461X_BA0_SIZE 0x2000
#define CS461X_BA1_DATA0_SIZE 0x3000
#define CS461X_BA1_DATA1_SIZE 0x3800
#define CS461X_BA1_PRG_SIZE 0x7000
#define CS461X_BA1_REG_SIZE 0x0100
#define BA1_SP_DMEM0 0x00000000
#define BA1_SP_DMEM1 0x00010000
#define BA1_SP_PMEM 0x00020000
#define BA1_SP_REG 0x00030000
#define BA1_DWORD_SIZE (13 * 1024 + 512)
#define BA1_MEMORY_COUNT 3
/*
Only one CS461x card is still suppoted; the code requires
redesign to avoid this limitatuion.
*/
static unsigned long ba0_addr;
static unsigned int __iomem *ba0;
#ifdef CS461X_FULL_MAP
static unsigned long ba1_addr;
static union ba1_t {
struct {
unsigned int __iomem *data0;
unsigned int __iomem *data1;
unsigned int __iomem *pmem;
unsigned int __iomem *reg;
} name;
unsigned int __iomem *idx[4];
} ba1;
static void cs461x_poke(unsigned long reg, unsigned int val)
{
writel(val, &ba1.idx[(reg >> 16) & 3][(reg >> 2) & 0x3fff]);
}
static unsigned int cs461x_peek(unsigned long reg)
{
return readl(&ba1.idx[(reg >> 16) & 3][(reg >> 2) & 0x3fff]);
}
#endif
static void cs461x_pokeBA0(unsigned long reg, unsigned int val)
{
writel(val, &ba0[reg >> 2]);
}
static unsigned int cs461x_peekBA0(unsigned long reg)
{
return readl(&ba0[reg >> 2]);
}
static int cs461x_free(struct pci_dev *pdev)
{
struct gameport *port = pci_get_drvdata(pdev);
if (port)
gameport_unregister_port(port);
if (ba0) iounmap(ba0);
#ifdef CS461X_FULL_MAP
if (ba1.name.data0) iounmap(ba1.name.data0);
if (ba1.name.data1) iounmap(ba1.name.data1);
if (ba1.name.pmem) iounmap(ba1.name.pmem);
if (ba1.name.reg) iounmap(ba1.name.reg);
#endif
return 0;
}
static void cs461x_gameport_trigger(struct gameport *gameport)
{
cs461x_pokeBA0(BA0_JSPT, 0xFF); //outb(gameport->io, 0xFF);
}
static unsigned char cs461x_gameport_read(struct gameport *gameport)
{
return cs461x_peekBA0(BA0_JSPT); //inb(gameport->io);
}
static int cs461x_gameport_cooked_read(struct gameport *gameport, int *axes, int *buttons)
{
unsigned js1, js2, jst;
js1 = cs461x_peekBA0(BA0_JSC1);
js2 = cs461x_peekBA0(BA0_JSC2);
jst = cs461x_peekBA0(BA0_JSPT);
*buttons = (~jst >> 4) & 0x0F;
axes[0] = ((js1 & JSC1_Y1V_MASK) >> JSC1_Y1V_SHIFT) & 0xFFFF;
axes[1] = ((js1 & JSC1_X1V_MASK) >> JSC1_X1V_SHIFT) & 0xFFFF;
axes[2] = ((js2 & JSC2_Y2V_MASK) >> JSC2_Y2V_SHIFT) & 0xFFFF;
axes[3] = ((js2 & JSC2_X2V_MASK) >> JSC2_X2V_SHIFT) & 0xFFFF;
for(jst=0;jst<4;++jst)
if(axes[jst]==0xFFFF) axes[jst] = -1;
return 0;
}
static int cs461x_gameport_open(struct gameport *gameport, int mode)
{
switch (mode) {
case GAMEPORT_MODE_COOKED:
case GAMEPORT_MODE_RAW:
return 0;
default:
return -1;
}
return 0;
}
static struct pci_device_id cs461x_pci_tbl[] = {
{ PCI_VENDOR_ID_CIRRUS, 0x6001, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* Cirrus CS4610 */
{ PCI_VENDOR_ID_CIRRUS, 0x6003, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* Cirrus CS4612 */
{ PCI_VENDOR_ID_CIRRUS, 0x6005, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* Cirrus CS4615 */
{ 0, }
};
MODULE_DEVICE_TABLE(pci, cs461x_pci_tbl);
static int __devinit cs461x_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
int rc;
struct gameport* port;
rc = pci_enable_device(pdev);
if (rc) {
printk(KERN_ERR "cs461x: Cannot enable PCI gameport (bus %d, devfn %d) error=%d\n",
pdev->bus->number, pdev->devfn, rc);
return rc;
}
ba0_addr = pci_resource_start(pdev, 0);
#ifdef CS461X_FULL_MAP
ba1_addr = pci_resource_start(pdev, 1);
#endif
if (ba0_addr == 0 || ba0_addr == ~0
#ifdef CS461X_FULL_MAP
|| ba1_addr == 0 || ba1_addr == ~0
#endif
) {
printk(KERN_ERR "cs461x: wrong address - ba0 = 0x%lx\n", ba0_addr);
#ifdef CS461X_FULL_MAP
printk(KERN_ERR "cs461x: wrong address - ba1 = 0x%lx\n", ba1_addr);
#endif
cs461x_free(pdev);
return -ENOMEM;
}
ba0 = ioremap(ba0_addr, CS461X_BA0_SIZE);
#ifdef CS461X_FULL_MAP
ba1.name.data0 = ioremap(ba1_addr + BA1_SP_DMEM0, CS461X_BA1_DATA0_SIZE);
ba1.name.data1 = ioremap(ba1_addr + BA1_SP_DMEM1, CS461X_BA1_DATA1_SIZE);
ba1.name.pmem = ioremap(ba1_addr + BA1_SP_PMEM, CS461X_BA1_PRG_SIZE);
ba1.name.reg = ioremap(ba1_addr + BA1_SP_REG, CS461X_BA1_REG_SIZE);
if (ba0 == NULL || ba1.name.data0 == NULL ||
ba1.name.data1 == NULL || ba1.name.pmem == NULL ||
ba1.name.reg == NULL) {
cs461x_free(pdev);
return -ENOMEM;
}
#else
if (ba0 == NULL) {
cs461x_free(pdev);
return -ENOMEM;
}
#endif
if (!(port = gameport_allocate_port())) {
printk(KERN_ERR "cs461x: Memory allocation failed\n");
cs461x_free(pdev);
return -ENOMEM;
}
pci_set_drvdata(pdev, port);
port->open = cs461x_gameport_open;
port->trigger = cs461x_gameport_trigger;
port->read = cs461x_gameport_read;
port->cooked_read = cs461x_gameport_cooked_read;
gameport_set_name(port, "CS416x");
gameport_set_phys(port, "pci%s/gameport0", pci_name(pdev));
port->dev.parent = &pdev->dev;
cs461x_pokeBA0(BA0_JSIO, 0xFF); // ?
cs461x_pokeBA0(BA0_JSCTL, JSCTL_SP_MEDIUM_SLOW);
gameport_register_port(port);
return 0;
}
static void __devexit cs461x_pci_remove(struct pci_dev *pdev)
{
cs461x_free(pdev);
}
static struct pci_driver cs461x_pci_driver = {
.name = "CS461x_gameport",
.id_table = cs461x_pci_tbl,
.probe = cs461x_pci_probe,
.remove = __devexit_p(cs461x_pci_remove),
};
static int __init cs461x_init(void)
{
return pci_register_driver(&cs461x_pci_driver);
}
static void __exit cs461x_exit(void)
{
pci_unregister_driver(&cs461x_pci_driver);
}
module_init(cs461x_init);
module_exit(cs461x_exit);
+6 -6
View File
@@ -258,18 +258,18 @@ static int __init ns558_init(void)
{
int i = 0;
if (pnp_register_driver(&ns558_pnp_driver) >= 0)
pnp_registered = 1;
/*
* Probe ISA ports first so that PnP gets to choose free port addresses
* not occupied by the ISA ports.
* Probe ISA ports after PnP, so that PnP ports that are already
* enabled get detected as PnP. This may be suboptimal in multi-device
* configurations, but saves hassle with simple setups.
*/
while (ns558_isa_portlist[i])
ns558_isa_probe(ns558_isa_portlist[i++]);
if (pnp_register_driver(&ns558_pnp_driver) >= 0)
pnp_registered = 1;
return (list_empty(&ns558_list) && !pnp_registered) ? -ENODEV : 0;
}
-186
View File
@@ -1,186 +0,0 @@
/*
* $Id: vortex.c,v 1.5 2002/07/01 15:39:30 vojtech Exp $
*
* Copyright (c) 2000-2001 Vojtech Pavlik
*
* Based on the work of:
* Raymond Ingles
*/
/*
* Trident 4DWave and Aureal Vortex gameport driver for Linux
*/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Should you need to contact me, the author, you can do so either by
* e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
*/
#include <asm/io.h>
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/ioport.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/gameport.h>
MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
MODULE_DESCRIPTION("Aureal Vortex and Vortex2 gameport driver");
MODULE_LICENSE("GPL");
#define VORTEX_GCR 0x0c /* Gameport control register */
#define VORTEX_LEG 0x08 /* Legacy port location */
#define VORTEX_AXD 0x10 /* Axes start */
#define VORTEX_DATA_WAIT 20 /* 20 ms */
struct vortex {
struct gameport *gameport;
struct pci_dev *dev;
unsigned char __iomem *base;
unsigned char __iomem *io;
};
static unsigned char vortex_read(struct gameport *gameport)
{
struct vortex *vortex = gameport->port_data;
return readb(vortex->io + VORTEX_LEG);
}
static void vortex_trigger(struct gameport *gameport)
{
struct vortex *vortex = gameport->port_data;
writeb(0xff, vortex->io + VORTEX_LEG);
}
static int vortex_cooked_read(struct gameport *gameport, int *axes, int *buttons)
{
struct vortex *vortex = gameport->port_data;
int i;
*buttons = (~readb(vortex->base + VORTEX_LEG) >> 4) & 0xf;
for (i = 0; i < 4; i++) {
axes[i] = readw(vortex->io + VORTEX_AXD + i * sizeof(u32));
if (axes[i] == 0x1fff) axes[i] = -1;
}
return 0;
}
static int vortex_open(struct gameport *gameport, int mode)
{
struct vortex *vortex = gameport->port_data;
switch (mode) {
case GAMEPORT_MODE_COOKED:
writeb(0x40, vortex->io + VORTEX_GCR);
msleep(VORTEX_DATA_WAIT);
return 0;
case GAMEPORT_MODE_RAW:
writeb(0x00, vortex->io + VORTEX_GCR);
return 0;
default:
return -1;
}
return 0;
}
static int __devinit vortex_probe(struct pci_dev *dev, const struct pci_device_id *id)
{
struct vortex *vortex;
struct gameport *port;
int i;
vortex = kcalloc(1, sizeof(struct vortex), GFP_KERNEL);
port = gameport_allocate_port();
if (!vortex || !port) {
printk(KERN_ERR "vortex: Memory allocation failed.\n");
kfree(vortex);
gameport_free_port(port);
return -ENOMEM;
}
for (i = 0; i < 6; i++)
if (~pci_resource_flags(dev, i) & IORESOURCE_IO)
break;
pci_enable_device(dev);
vortex->dev = dev;
vortex->gameport = port;
vortex->base = ioremap(pci_resource_start(vortex->dev, i),
pci_resource_len(vortex->dev, i));
vortex->io = vortex->base + id->driver_data;
pci_set_drvdata(dev, vortex);
port->port_data = vortex;
port->fuzz = 64;
gameport_set_name(port, "AU88x0");
gameport_set_phys(port, "pci%s/gameport0", pci_name(dev));
port->dev.parent = &dev->dev;
port->read = vortex_read;
port->trigger = vortex_trigger;
port->cooked_read = vortex_cooked_read;
port->open = vortex_open;
gameport_register_port(port);
return 0;
}
static void __devexit vortex_remove(struct pci_dev *dev)
{
struct vortex *vortex = pci_get_drvdata(dev);
gameport_unregister_port(vortex->gameport);
iounmap(vortex->base);
kfree(vortex);
}
static struct pci_device_id vortex_id_table[] = {
{ 0x12eb, 0x0001, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0x11000 },
{ 0x12eb, 0x0002, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0x28800 },
{ 0 }
};
static struct pci_driver vortex_driver = {
.name = "vortex_gameport",
.id_table = vortex_id_table,
.probe = vortex_probe,
.remove = __devexit_p(vortex_remove),
};
static int __init vortex_init(void)
{
return pci_register_driver(&vortex_driver);
}
static void __exit vortex_exit(void)
{
pci_unregister_driver(&vortex_driver);
}
module_init(vortex_init);
module_exit(vortex_exit);
+32 -5
View File
@@ -219,10 +219,24 @@ void input_release_device(struct input_handle *handle)
int input_open_device(struct input_handle *handle)
{
struct input_dev *dev = handle->dev;
int err;
err = down_interruptible(&dev->sem);
if (err)
return err;
handle->open++;
if (handle->dev->open)
return handle->dev->open(handle->dev);
return 0;
if (!dev->users++ && dev->open)
err = dev->open(dev);
if (err)
handle->open--;
up(&dev->sem);
return err;
}
int input_flush_device(struct input_handle* handle, struct file* file)
@@ -235,10 +249,17 @@ int input_flush_device(struct input_handle* handle, struct file* file)
void input_close_device(struct input_handle *handle)
{
struct input_dev *dev = handle->dev;
input_release_device(handle);
if (handle->dev->close)
handle->dev->close(handle->dev);
down(&dev->sem);
if (!--dev->users && dev->close)
dev->close(dev);
handle->open--;
up(&dev->sem);
}
static void input_link_handle(struct input_handle *handle)
@@ -415,6 +436,8 @@ void input_register_device(struct input_dev *dev)
set_bit(EV_SYN, dev->evbit);
init_MUTEX(&dev->sem);
/*
* If delay and period are pre-set by the driver, then autorepeating
* is handled by the driver itself and we don't do it in input.c.
@@ -674,6 +697,8 @@ static int input_handlers_read(char *buf, char **start, off_t pos, int count, in
return (count > cnt) ? cnt : count;
}
static struct file_operations input_fileops;
static int __init input_proc_init(void)
{
struct proc_dir_entry *entry;
@@ -688,6 +713,8 @@ static int __init input_proc_init(void)
return -ENOMEM;
}
entry->owner = THIS_MODULE;
input_fileops = *entry->proc_fops;
entry->proc_fops = &input_fileops;
entry->proc_fops->poll = input_devices_poll;
entry = create_proc_read_entry("handlers", 0, proc_bus_input_dir, input_handlers_read, NULL);
if (entry == NULL) {
+91 -25
View File
@@ -285,48 +285,33 @@ static unsigned int joydev_poll(struct file *file, poll_table *wait)
(POLLIN | POLLRDNORM) : 0) | (list->joydev->exist ? 0 : (POLLHUP | POLLERR));
}
static int joydev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
static int joydev_ioctl_common(struct joydev *joydev, unsigned int cmd, void __user *argp)
{
struct joydev_list *list = file->private_data;
struct joydev *joydev = list->joydev;
struct input_dev *dev = joydev->handle.dev;
void __user *argp = (void __user *)arg;
int i, j;
if (!joydev->exist) return -ENODEV;
switch (cmd) {
case JS_SET_CAL:
return copy_from_user(&joydev->glue.JS_CORR, argp,
sizeof(struct JS_DATA_TYPE)) ? -EFAULT : 0;
sizeof(joydev->glue.JS_CORR)) ? -EFAULT : 0;
case JS_GET_CAL:
return copy_to_user(argp, &joydev->glue.JS_CORR,
sizeof(struct JS_DATA_TYPE)) ? -EFAULT : 0;
sizeof(joydev->glue.JS_CORR)) ? -EFAULT : 0;
case JS_SET_TIMEOUT:
return get_user(joydev->glue.JS_TIMEOUT, (int __user *) arg);
return get_user(joydev->glue.JS_TIMEOUT, (s32 __user *) argp);
case JS_GET_TIMEOUT:
return put_user(joydev->glue.JS_TIMEOUT, (int __user *) arg);
case JS_SET_TIMELIMIT:
return get_user(joydev->glue.JS_TIMELIMIT, (long __user *) arg);
case JS_GET_TIMELIMIT:
return put_user(joydev->glue.JS_TIMELIMIT, (long __user *) arg);
case JS_SET_ALL:
return copy_from_user(&joydev->glue, argp,
sizeof(struct JS_DATA_SAVE_TYPE)) ? -EFAULT : 0;
case JS_GET_ALL:
return copy_to_user(argp, &joydev->glue,
sizeof(struct JS_DATA_SAVE_TYPE)) ? -EFAULT : 0;
return put_user(joydev->glue.JS_TIMEOUT, (s32 __user *) argp);
case JSIOCGVERSION:
return put_user(JS_VERSION, (__u32 __user *) arg);
return put_user(JS_VERSION, (__u32 __user *) argp);
case JSIOCGAXES:
return put_user(joydev->nabs, (__u8 __user *) arg);
return put_user(joydev->nabs, (__u8 __user *) argp);
case JSIOCGBUTTONS:
return put_user(joydev->nkey, (__u8 __user *) arg);
return put_user(joydev->nkey, (__u8 __user *) argp);
case JSIOCSCORR:
if (copy_from_user(joydev->corr, argp,
sizeof(struct js_corr) * joydev->nabs))
sizeof(joydev->corr[0]) * joydev->nabs))
return -EFAULT;
for (i = 0; i < joydev->nabs; i++) {
j = joydev->abspam[i];
@@ -335,7 +320,7 @@ static int joydev_ioctl(struct inode *inode, struct file *file, unsigned int cmd
return 0;
case JSIOCGCORR:
return copy_to_user(argp, joydev->corr,
sizeof(struct js_corr) * joydev->nabs) ? -EFAULT : 0;
sizeof(joydev->corr[0]) * joydev->nabs) ? -EFAULT : 0;
case JSIOCSAXMAP:
if (copy_from_user(joydev->abspam, argp, sizeof(__u8) * (ABS_MAX + 1)))
return -EFAULT;
@@ -371,6 +356,84 @@ static int joydev_ioctl(struct inode *inode, struct file *file, unsigned int cmd
return -EINVAL;
}
#ifdef CONFIG_COMPAT
static long joydev_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
struct joydev_list *list = file->private_data;
struct joydev *joydev = list->joydev;
void __user *argp = (void __user *)arg;
s32 tmp32;
struct JS_DATA_SAVE_TYPE_32 ds32;
int err;
if (!joydev->exist) return -ENODEV;
switch(cmd) {
case JS_SET_TIMELIMIT:
err = get_user(tmp32, (s32 __user *) arg);
if (err == 0)
joydev->glue.JS_TIMELIMIT = tmp32;
break;
case JS_GET_TIMELIMIT:
tmp32 = joydev->glue.JS_TIMELIMIT;
err = put_user(tmp32, (s32 __user *) arg);
break;
case JS_SET_ALL:
err = copy_from_user(&ds32, argp,
sizeof(ds32)) ? -EFAULT : 0;
if (err == 0) {
joydev->glue.JS_TIMEOUT = ds32.JS_TIMEOUT;
joydev->glue.BUSY = ds32.BUSY;
joydev->glue.JS_EXPIRETIME = ds32.JS_EXPIRETIME;
joydev->glue.JS_TIMELIMIT = ds32.JS_TIMELIMIT;
joydev->glue.JS_SAVE = ds32.JS_SAVE;
joydev->glue.JS_CORR = ds32.JS_CORR;
}
break;
case JS_GET_ALL:
ds32.JS_TIMEOUT = joydev->glue.JS_TIMEOUT;
ds32.BUSY = joydev->glue.BUSY;
ds32.JS_EXPIRETIME = joydev->glue.JS_EXPIRETIME;
ds32.JS_TIMELIMIT = joydev->glue.JS_TIMELIMIT;
ds32.JS_SAVE = joydev->glue.JS_SAVE;
ds32.JS_CORR = joydev->glue.JS_CORR;
err = copy_to_user(argp, &ds32,
sizeof(ds32)) ? -EFAULT : 0;
break;
default:
err = joydev_ioctl_common(joydev, cmd, argp);
}
return err;
}
#endif /* CONFIG_COMPAT */
static int joydev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
struct joydev_list *list = file->private_data;
struct joydev *joydev = list->joydev;
void __user *argp = (void __user *)arg;
if (!joydev->exist) return -ENODEV;
switch(cmd) {
case JS_SET_TIMELIMIT:
return get_user(joydev->glue.JS_TIMELIMIT, (long __user *) arg);
case JS_GET_TIMELIMIT:
return put_user(joydev->glue.JS_TIMELIMIT, (long __user *) arg);
case JS_SET_ALL:
return copy_from_user(&joydev->glue, argp,
sizeof(joydev->glue)) ? -EFAULT : 0;
case JS_GET_ALL:
return copy_to_user(argp, &joydev->glue,
sizeof(joydev->glue)) ? -EFAULT : 0;
default:
return joydev_ioctl_common(joydev, cmd, argp);
}
}
static struct file_operations joydev_fops = {
.owner = THIS_MODULE,
.read = joydev_read,
@@ -379,6 +442,9 @@ static struct file_operations joydev_fops = {
.open = joydev_open,
.release = joydev_release,
.ioctl = joydev_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = joydev_compat_ioctl,
#endif
.fasync = joydev_fasync,
};
+1 -1
View File
@@ -185,7 +185,7 @@ static void a3d_poll(struct gameport *gameport)
a3d->reads++;
if (a3d_read_packet(a3d->gameport, a3d->length, data) != a3d->length ||
data[0] != a3d->mode || a3d_csum(data, a3d->length))
a3d->bads++;
a3d->bads++;
else
a3d_read(a3d, data);
}
+2 -2
View File
@@ -82,7 +82,7 @@ static char adi_cm2_abs[] = { ABS_X, ABS_Y, ABS_Z, ABS_RX, ABS_RY, ABS_RZ };
static char adi_wmf_abs[] = { ABS_WHEEL, ABS_GAS, ABS_BRAKE, ABS_HAT0X, ABS_HAT0Y, ABS_HAT1X, ABS_HAT1Y, ABS_HAT2X, ABS_HAT2Y };
static short adi_wmgpe_key[] = { BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, BTN_TL, BTN_TR, BTN_START, BTN_MODE, BTN_SELECT };
static short adi_wmi_key[] = { BTN_TRIGGER, BTN_TOP, BTN_THUMB, BTN_TOP2, BTN_BASE, BTN_BASE2, BTN_BASE3, BTN_BASE4, BTN_EXTRA };
static short adi_wmi_key[] = { BTN_TRIGGER, BTN_TOP, BTN_THUMB, BTN_TOP2, BTN_BASE, BTN_BASE2, BTN_BASE3, BTN_BASE4, BTN_EXTRA };
static short adi_wmed3d_key[] = { BTN_TRIGGER, BTN_THUMB, BTN_THUMB2, BTN_TOP, BTN_TOP2, BTN_BASE, BTN_BASE2 };
static short adi_cm2_key[] = { BTN_1, BTN_2, BTN_3, BTN_4, BTN_5, BTN_6, BTN_7, BTN_8 };
@@ -183,7 +183,7 @@ static void adi_move_bits(struct adi_port *port, int length)
int i;
struct adi *adi = port->adi;
adi[0].idx = adi[1].idx = 0;
adi[0].idx = adi[1].idx = 0;
if (adi[0].ret <= 0 || adi[1].ret <= 0) return;
if (adi[0].data[0] & 0x20 || ~adi[1].data[0] & 0x20) return;
+16 -13
View File
@@ -51,7 +51,8 @@ MODULE_PARM_DESC(map, "Map of attached joysticks in form of <a>,<b> (default is
__obsolete_setup("amijoy=");
static int amijoy_used[2] = { 0, 0 };
static int amijoy_used;
static DECLARE_MUTEX(amijoy_sem);
static struct input_dev amijoy_dev[2];
static char *amijoy_phys[2] = { "amijoy/input0", "amijoy/input1" };
@@ -84,26 +85,30 @@ static irqreturn_t amijoy_interrupt(int irq, void *dummy, struct pt_regs *fp)
static int amijoy_open(struct input_dev *dev)
{
int *used = dev->private;
int err;
if ((*used)++)
return 0;
err = down_interruptible(&amijoy_sem);
if (err)
return err;
if (request_irq(IRQ_AMIGA_VERTB, amijoy_interrupt, 0, "amijoy", amijoy_interrupt)) {
(*used)--;
if (!amijoy_used && request_irq(IRQ_AMIGA_VERTB, amijoy_interrupt, 0, "amijoy", amijoy_interrupt)) {
printk(KERN_ERR "amijoy.c: Can't allocate irq %d\n", IRQ_AMIGA_VERTB);
return -EBUSY;
err = -EBUSY;
goto out;
}
return 0;
amijoy_used++;
out:
up(&amijoy_sem);
return err;
}
static void amijoy_close(struct input_dev *dev)
{
int *used = dev->private;
if (!--(*used))
down(&amijoysem);
if (!--amijoy_used)
free_irq(IRQ_AMIGA_VERTB, amijoy_interrupt);
up(&amijoy_sem);
}
static int __init amijoy_init(void)
@@ -138,8 +143,6 @@ static int __init amijoy_init(void)
amijoy_dev[i].id.product = 0x0003;
amijoy_dev[i].id.version = 0x0100;
amijoy_dev[i].private = amijoy_used + i;
input_register_device(amijoy_dev + i);
printk(KERN_INFO "input: %s at joy%ddat\n", amijoy_name, i);
}
+13 -4
View File
@@ -87,7 +87,7 @@ __obsolete_setup("db9_3=");
#define DB9_NORMAL 0x0a
#define DB9_NOSELECT 0x08
#define DB9_MAX_DEVICES 2
#define DB9_MAX_DEVICES 2
#define DB9_GENESIS6_DELAY 14
#define DB9_REFRESH_TIME HZ/100
@@ -98,6 +98,7 @@ struct db9 {
struct pardevice *pd;
int mode;
int used;
struct semaphore sem;
char phys[2][32];
};
@@ -503,6 +504,11 @@ static int db9_open(struct input_dev *dev)
{
struct db9 *db9 = dev->private;
struct parport *port = db9->pd->port;
int err;
err = down_interruptible(&db9->sem);
if (err)
return err;
if (!db9->used++) {
parport_claim(db9->pd);
@@ -514,6 +520,7 @@ static int db9_open(struct input_dev *dev)
mod_timer(&db9->timer, jiffies + DB9_REFRESH_TIME);
}
up(&db9->sem);
return 0;
}
@@ -522,12 +529,14 @@ static void db9_close(struct input_dev *dev)
struct db9 *db9 = dev->private;
struct parport *port = db9->pd->port;
down(&db9->sem);
if (!--db9->used) {
del_timer(&db9->timer);
del_timer_sync(&db9->timer);
parport_write_control(port, 0x00);
parport_data_forward(port);
parport_release(db9->pd);
}
up(&db9->sem);
}
static struct db9 __init *db9_probe(int *config, int nargs)
@@ -563,12 +572,12 @@ static struct db9 __init *db9_probe(int *config, int nargs)
}
}
if (!(db9 = kmalloc(sizeof(struct db9), GFP_KERNEL))) {
if (!(db9 = kcalloc(1, sizeof(struct db9), GFP_KERNEL))) {
parport_put_port(pp);
return NULL;
}
memset(db9, 0, sizeof(struct db9));
init_MUTEX(&db9->sem);
db9->mode = config[1];
init_timer(&db9->timer);
db9->timer.data = (long) db9;
+21 -8
View File
@@ -1,12 +1,12 @@
/*
* NES, SNES, N64, MultiSystem, PSX gamepad driver for Linux
*
* Copyright (c) 1999-2004 Vojtech Pavlik <vojtech@suse.cz>
* Copyright (c) 2004 Peter Nelson <rufus-kernel@hackish.org>
* Copyright (c) 1999-2004 Vojtech Pavlik <vojtech@suse.cz>
* Copyright (c) 2004 Peter Nelson <rufus-kernel@hackish.org>
*
* Based on the work of:
* Andree Borrmann John Dahlstrom
* David Kuder Nathan Hand
* Andree Borrmann John Dahlstrom
* David Kuder Nathan Hand
*/
/*
@@ -81,6 +81,7 @@ struct gc {
struct timer_list timer;
unsigned char pads[GC_MAX + 1];
int used;
struct semaphore sem;
char phys[5][32];
};
@@ -433,7 +434,7 @@ static void gc_timer(unsigned long private)
gc_psx_read_packet(gc, data_psx, data);
for (i = 0; i < 5; i++) {
switch (data[i]) {
switch (data[i]) {
case GC_PSX_RUMBLE:
@@ -503,22 +504,33 @@ static void gc_timer(unsigned long private)
static int gc_open(struct input_dev *dev)
{
struct gc *gc = dev->private;
int err;
err = down_interruptible(&gc->sem);
if (err)
return err;
if (!gc->used++) {
parport_claim(gc->pd);
parport_write_control(gc->pd->port, 0x04);
mod_timer(&gc->timer, jiffies + GC_REFRESH_TIME);
}
up(&gc->sem);
return 0;
}
static void gc_close(struct input_dev *dev)
{
struct gc *gc = dev->private;
down(&gc->sem);
if (!--gc->used) {
del_timer(&gc->timer);
del_timer_sync(&gc->timer);
parport_write_control(gc->pd->port, 0x00);
parport_release(gc->pd);
}
up(&gc->sem);
}
static struct gc __init *gc_probe(int *config, int nargs)
@@ -542,11 +554,12 @@ static struct gc __init *gc_probe(int *config, int nargs)
return NULL;
}
if (!(gc = kmalloc(sizeof(struct gc), GFP_KERNEL))) {
if (!(gc = kcalloc(1, sizeof(struct gc), GFP_KERNEL))) {
parport_put_port(pp);
return NULL;
}
memset(gc, 0, sizeof(struct gc));
init_MUTEX(&gc->sem);
gc->pd = parport_register_device(pp, "gamecon", NULL, NULL, NULL, PARPORT_DEV_EXCL, NULL);
+1 -1
View File
@@ -329,7 +329,7 @@ static int gf2k_connect(struct gameport *gameport, struct gameport_driver *drv)
for (i = 0; i < gf2k_axes[gf2k->id]; i++) {
gf2k->dev.absmax[gf2k_abs[i]] = (i < 2) ? gf2k->dev.abs[gf2k_abs[i]] * 2 - 32 :
gf2k->dev.abs[gf2k_abs[0]] + gf2k->dev.abs[gf2k_abs[1]] - 32;
gf2k->dev.abs[gf2k_abs[0]] + gf2k->dev.abs[gf2k_abs[1]] - 32;
gf2k->dev.absmin[gf2k_abs[i]] = 32;
gf2k->dev.absfuzz[gf2k_abs[i]] = 8;
gf2k->dev.absflat[gf2k_abs[i]] = (i < 2) ? 24 : 0;
+1 -1
View File
@@ -171,7 +171,7 @@ static int mp_io(struct gameport* gameport, int sendflags, int sendcode, u32 *pa
*packet = 0;
raw_data = gameport_read(gameport);
if (raw_data & 1)
return IO_RETRY;
return IO_RETRY;
for (i = 0; i < 64; i++) {
raw_data = gameport_read(gameport);
@@ -78,6 +78,7 @@ static struct iforce_device iforce_device[] = {
{ 0x061c, 0xc0a4, "ACT LABS Force RS", btn_wheel, abs_wheel, ff_iforce }, //?
{ 0x06f8, 0x0001, "Guillemot Race Leader Force Feedback", btn_wheel, abs_wheel, ff_iforce }, //?
{ 0x06f8, 0x0004, "Guillemot Force Feedback Racing Wheel", btn_wheel, abs_wheel, ff_iforce }, //?
{ 0x06f8, 0x0004, "Gullemot Jet Leader 3D", btn_joystick, abs_joystick, ff_iforce }, //?
{ 0x0000, 0x0000, "Unknown I-Force Device [%04x:%04x]", btn_joystick, abs_joystick, ff_iforce }
};
@@ -229,6 +229,7 @@ static struct usb_device_id iforce_usb_ids [] = {
{ USB_DEVICE(0x061c, 0xc0a4) }, /* ACT LABS Force RS */
{ USB_DEVICE(0x06f8, 0x0001) }, /* Guillemot Race Leader Force Feedback */
{ USB_DEVICE(0x06f8, 0x0004) }, /* Guillemot Force Feedback Racing Wheel */
{ USB_DEVICE(0x06f8, 0xa302) }, /* Guillemot Jet Leader 3D */
{ } /* Terminating entry */
};
+2 -2
View File
@@ -4,8 +4,8 @@
* Copyright (c) 1999-2001 Vojtech Pavlik
*
* Based on the work of:
* David Thompson
* Joseph Krahn
* David Thompson
* Joseph Krahn
*/
/*
+1 -1
View File
@@ -4,7 +4,7 @@
* Copyright (c) 1999-2001 Vojtech Pavlik
*
* Based on the work of:
* David Thompson
* David Thompson
*/
/*

Some files were not shown because too many files have changed in this diff Show More