Commit f82e5610 authored by Linus Torvalds's avatar Linus Torvalds

Import 2.3.31pre1

parent 9c2dd1d4
This diff is collapsed.
......@@ -74,10 +74,9 @@ is, you have both an axis 0 and a button 0). Generally,
2nd Axis Y 3
...and so on
Hats vary from one joystick type to another. Some can be moved in 8
directions, some only in 4. The driver, however, always reports a hat
as two independent axis, even if the hardware doesn't allow independent
movement.
Hats vary from one joystick type to another. Some can be moved in 8
directions, some only in 4, The driver, however, always reports a hat as two
independent axis, even if the hardware doesn't allow independent movement.
2.3 js_event.value
......@@ -300,7 +299,7 @@ fixed range for reporting the values, 1 being the minimum, 128 the
center, and 255 maximum value.
The v0.8.0.2 driver also had an interface for 'digital joysticks', (now
called Multisystem joystick in this driver), under /dev/djsX. This driver
called Multisystem joysticks in this driver), under /dev/djsX. This driver
doesn't try to be compatible with that interface.
......
Linux Joystick parport drivers v1.2 BETA
(c) 1998 Vojtech Pavlik <vojtech@suse.cz>
(c) 1998-1999 Vojtech Pavlik <vojtech@suse.cz>
(c) 1998 Andree Borrmann <a.borrmann@tu-bs.de>
Sponsored by SuSE
----------------------------------------------------------------------------
0. Disclaimer
......@@ -44,7 +45,8 @@ you'll use for NES and SNES gamepads.
The main problem with PC parallel ports is that they don't have +5V power
source on any of their pins. So, if you want a reliable source of power
for your pads, use either keyboard or joystick port, and make a pass-through
cable.
cable. You can also pull the power directly from the power supply (the red
wire is +5V).
If you want to use the parallel port only, you can take the power is from
some data pin. For most gamepad and parport implementations only one pin is
......@@ -298,27 +300,29 @@ work for most people. If you like adventure, you can try yourself.
The PSX controller is supported by the joy-console.c.
Pinout of the PSX controller:
Pinout of the PSX controller (compatible with DirectPadPro):
+---------+---------+---------+
9 | o o o | o o o | o o o | 1 parallel
\________|_________|________/ port pins
| | | | | |
| | | | | +--------> Clock --- (1)
| | | | +------------> Select --- (17)
| | | +---------------> Power --- (16)
| | | | | +--------> Clock --- (4)
| | | | +------------> Select --- (3)
| | | +---------------> Power --- (5-9)
| | +------------------> Ground --- (18-25)
| +-------------------------> Command --- (14)
| +-------------------------> Command --- (2)
+----------------------------> Data --- (10,11,12,13,15) one only...
You may have to add pull up/down resistors. Maybe your pad also won't like
the 5V (PSX uses 3.7V).
Currently the driver supports only ONE psx pad and only one type of
controller: The normal PSX controller. NEGCON support is planned for the
next release. ANALOG controller may be too (I do not recommend to connect
the "force feedback"/"rumble pack" version... it (may) use too much
power...)
Currently the driver supports only one psx pad per parallel port, and these
controllers:
* Standard PSX Pad
* NegCon PSX Pad
* Analog PSX Pad (red mode)
* Analog PSX Pad (green mode)
2.4 Sega
~~~~~~~~
......@@ -437,13 +441,15 @@ Linux kernels, the number of the parport interface (eg. 0 for parport0).
4 | Multisystem 1-button joystick
5 | Multisystem 2-button joystick
6 | Sony PSX controller
7 | N64 pad
8 | N64 pad with direction pad as buttons (DirectPadPro style)
The exact type of the PSX controller type is autoprobed, so you must have
your controller plugged in before initializing.
Should you want to use more than one of parallel ports at once, you can
use js_console_2 and js_db9_3 as additional command line parameters for two
more parallel ports.
use js_console_2 and js_console_3 as additional command line parameters for
two more parallel ports.
Changes:
v0.1 : First version (SNES only)
......@@ -463,6 +469,9 @@ more parallel ports.
v0.10 : Fixed PSX buttons 8 and 9
v0.11V: Switched to EXCL mode
Removed wakeup
v0.12V: Added N64 support
v0.13V: Updated N64 support
v0.14V: Fixed N64 axis/button counts
3.2 joy-db9.c
~~~~~~~~~~~~~
......@@ -475,6 +484,10 @@ joy-db9.c driver. It uses the following kernel/module command line:
is connected to (eg. 0x378), or, if you are using the parport driver of 2.1+
Linux kernels, the number of the parport interface (eg. 0 for parport0).
Caveat here: This driver only works on bidirectional parallel ports. If
your parallel port is recent enough, you should have no trouble with this.
Old parallel ports may not have this feature.
'Type' is the type of joystick or pad attached:
Type | Joystick/Pad
......@@ -484,9 +497,10 @@ Linux kernels, the number of the parport interface (eg. 0 for parport0).
2 | Multisystem 2-button joystick
3 | Genesis pad (3+1 buttons)
5 | Genesis pad (5+1 buttons)
6 | Genesis pad (6+1 buttons)
7 | Saturn pad
6 | Genesis pad (6+2 buttons)
7 | Saturn pad (8 buttons)
8 | Multisystem 1-button joystick (v0.8.0.2 pin-out)
9 | Two Multiststem 1-button joysticks (v0.8.0.2 pin-out)
Should you want to use more than one of these joysticks/pads at once, you
can use js_db9_2 and js_db9_3 as additional command line parameters for two
......@@ -501,6 +515,8 @@ more joysticks/pads.
v0.4V: Switched to EXCL mode
Removed wakeup
v0.5V: Added 0.8.0.2 HW compatibility for Multi sticks
v0.6V: Better timing for Genesis 6
v0.7V: Added 0.8.0.2 second joystick support
3.3 joy-turbografx.c
~~~~~~~~~~~~~~~~~~~~
......@@ -519,6 +535,27 @@ interface ports 1-7 have. For a standard multisystem joystick, this is 1.
use js_tg_2 and js_tg_3 as additional command line parameters for two more
interfaces.
3.4 End
3.4 PC parallel port pinout
~~~~~~~~~~~~~~~~~~~~~~~~~~~
.----------------------------------------.
At the PC: \ 13 12 11 10 9 8 7 6 5 4 3 2 1 /
\ 25 24 23 22 21 20 19 18 17 16 15 14 /
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Pin | Name | Description
~~~~~~|~~~~~~~~~|~~~~~~~~~~
1 | /STROBE | Strobe
2-9 | D0-D7 | Data Bit 0-7
10 | /ACK | Acknowledge
11 | BUSY | Busy
12 | PE | Paper End
13 | SELIN | Select In
14 | /AUTOFD | Autofeed
15 | /ERROR | Error
16 | /INIT | Initialize
17 | /SEL | Select
18-25 | GND | Signal Ground
3.5 End
~~~~~~~
That's all, folks! Have fun!
This diff is collapsed.
VERSION = 2
PATCHLEVEL = 3
SUBLEVEL = 30
SUBLEVEL = 31
EXTRAVERSION =
ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/)
......@@ -117,6 +117,10 @@ DRIVERS =drivers/block/block.a \
LIBS =$(TOPDIR)/lib/lib.a
SUBDIRS =kernel drivers mm fs net ipc lib
ifdef CONFIG_DRM
DRIVERS += drivers/char/drm/drm.o
endif
ifdef CONFIG_NUBUS
DRIVERS := $(DRIVERS) drivers/nubus/nubus.a
endif
......
......@@ -49,6 +49,36 @@ asmlinkage int sys_pipe(unsigned long * fildes)
return error;
}
/* common code for old and new mmaps */
static inline long do_mmap2(
unsigned long addr, unsigned long len,
unsigned long prot, unsigned long flags,
unsigned long fd, unsigned long pgoff)
{
int error = -EBADF;
struct file * file = NULL;
flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
if (!(flags & MAP_ANONYMOUS)) {
file = fget(fd);
if (!file)
goto out;
}
down(&current->mm->mmap_sem);
lock_kernel();
error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
unlock_kernel();
up(&current->mm->mmap_sem);
if (file)
fput(file);
out:
return error;
}
/*
* Perform the select(nd, in, out, ex, tv) and mmap() system
* calls. ARM Linux didn't use to be able to handle more than
......@@ -68,30 +98,20 @@ struct mmap_arg_struct {
asmlinkage int old_mmap(struct mmap_arg_struct *arg)
{
int error = -EFAULT;
struct file * file = NULL;
struct mmap_arg_struct a;
down(&current->mm->mmap_sem);
lock_kernel();
if (copy_from_user(&a, arg, sizeof(a)))
goto out;;
error = -EINVAL;
if (a.offset & ~PAGE_MASK)
goto out;
if (!(a.flags & MAP_ANONYMOUS)) {
error = -EBADF;
file = fget(a.fd);
if (!file)
goto out;
}
a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
error = do_mmap(file, a.addr, a.len, a.prot, a.flags, a.offset);
if (file)
fput(file);
error = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);
out:
unlock_kernel();
up(&current->mm->mmap_sem);
return error;
}
extern asmlinkage int sys_select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
struct sel_arg_struct {
......
......@@ -592,6 +592,7 @@ ENTRY(sys_call_table)
.long SYMBOL_NAME(sys_ni_syscall) /* streams2 */
.long SYMBOL_NAME(sys_vfork) /* 190 */
.long SYMBOL_NAME(sys_getrlimit)
.long SYMBOL_NAME(sys_mmap2)
/*
* NOTE!! This doesn't have to be exact - we just have
......@@ -599,6 +600,6 @@ ENTRY(sys_call_table)
* entries. Don't panic if you notice that this hasn't
* been shrunk every time we add a new system call.
*/
.rept NR_syscalls-191
.rept NR_syscalls-192
.long SYMBOL_NAME(sys_ni_syscall)
.endr
......@@ -575,7 +575,7 @@ asmlinkage void smp_spurious_interrupt(void)
* This interrupt should never happen with our APIC/SMP architecture
*/
static spinlock_t err_lock;
static spinlock_t err_lock = SPIN_LOCK_UNLOCKED;
asmlinkage void smp_error_interrupt(void)
{
......
......@@ -41,6 +41,43 @@ asmlinkage int sys_pipe(unsigned long * fildes)
return error;
}
/* common code for old and new mmaps */
static inline long do_mmap2(
unsigned long addr, unsigned long len,
unsigned long prot, unsigned long flags,
unsigned long fd, unsigned long pgoff)
{
int error = -EBADF;
struct file * file = NULL;
flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
if (!(flags & MAP_ANONYMOUS)) {
file = fget(fd);
if (!file)
goto out;
}
down(&current->mm->mmap_sem);
lock_kernel();
error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
unlock_kernel();
up(&current->mm->mmap_sem);
if (file)
fput(file);
out:
return error;
}
asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
unsigned long prot, unsigned long flags,
unsigned long fd, unsigned long pgoff)
{
return do_mmap2(addr, len, prot, flags, fd, pgoff);
}
/*
* Perform the select(nd, in, out, ex, tv) and mmap() system
* calls. Linux/i386 didn't use to be able to handle more than
......@@ -59,32 +96,22 @@ struct mmap_arg_struct {
asmlinkage int old_mmap(struct mmap_arg_struct *arg)
{
int error = -EFAULT;
struct file * file = NULL;
struct mmap_arg_struct a;
int err = -EFAULT;
if (copy_from_user(&a, arg, sizeof(a)))
return -EFAULT;
goto out;
down(&current->mm->mmap_sem);
lock_kernel();
if (!(a.flags & MAP_ANONYMOUS)) {
error = -EBADF;
file = fget(a.fd);
if (!file)
goto out;
}
a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
err = -EINVAL;
if (a.offset & ~PAGE_MASK)
goto out;
error = do_mmap(file, a.addr, a.len, a.prot, a.flags, a.offset);
if (file)
fput(file);
err = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);
out:
unlock_kernel();
up(&current->mm->mmap_sem);
return error;
return err;
}
extern asmlinkage int sys_select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
struct sel_arg_struct {
......
......@@ -80,8 +80,7 @@ extern rwlock_t xtime_lock;
static inline unsigned long do_fast_gettimeoffset(void)
{
register unsigned long eax asm("ax");
register unsigned long edx asm("dx");
register unsigned long eax, edx;
/* Read the Time Stamp Counter */
......
......@@ -44,6 +44,43 @@ asmlinkage int sys_pipe(unsigned long * fildes)
return error;
}
/* common code for old and new mmaps */
static inline long do_mmap2(
unsigned long addr, unsigned long len,
unsigned long prot, unsigned long flags,
unsigned long fd, unsigned long pgoff)
{
int error = -EBADF;
struct file * file = NULL;
flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
if (!(flags & MAP_ANONYMOUS)) {
file = fget(fd);
if (!file)
goto out;
}
down(&current->mm->mmap_sem);
lock_kernel();
error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
unlock_kernel();
up(&current->mm->mmap_sem);
if (file)
fput(file);
out:
return error;
}
asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
unsigned long prot, unsigned long flags,
unsigned long fd, unsigned long pgoff)
{
return do_mmap2(addr, len, prot, flags, fd, pgoff);
}
/*
* Perform the select(nd, in, out, ex, tv) and mmap() system
* calls. Linux/m68k cloned Linux/i386, which didn't use to be able to
......@@ -62,13 +99,49 @@ struct mmap_arg_struct {
asmlinkage int old_mmap(struct mmap_arg_struct *arg)
{
int error;
struct file * file = NULL;
struct mmap_arg_struct a;
int error = -EFAULT;
if (copy_from_user(&a, arg, sizeof(a)))
goto out;
error = -EINVAL;
if (a.offset & ~PAGE_MASK)
goto out;
a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
error = do_mmap2(file, a.addr, a.len, a.prot, a.flags, a.offset >> PAGE_SHIFT);
out:
return error;
}
struct mmap_arg_struct64 {
__u32 addr;
__u32 len;
__u32 prot;
__u32 flags;
__u64 offset; /* 64 bits */
__u32 fd;
};
asmlinkage long sys_mmap64(struct mmap_arg_struct64 *arg)
{
int error = -EFAULT;
struct file * file = NULL;
struct mmap_arg_struct64 a;
unsigned long pgoff;
if (copy_from_user(&a, arg, sizeof(a)))
return -EFAULT;
if ((long)a.offset & ~PAGE_MASK)
return -EINVAL;
pgoff = a.offset >> PAGE_SHIFT;
if ((a.offset >> PAGE_SHIFT) != pgoff)
return -EINVAL;
down(&current->mm->mmap_sem);
lock_kernel();
if (!(a.flags & MAP_ANONYMOUS)) {
......@@ -79,7 +152,7 @@ asmlinkage int old_mmap(struct mmap_arg_struct *arg)
}
a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
error = do_mmap(file, a.addr, a.len, a.prot, a.flags, a.offset);
error = do_mmap_pgoff(file, a.addr, a.len, a.prot, a.flags, pgoff);
if (file)
fput(file);
out:
......@@ -88,7 +161,6 @@ asmlinkage int old_mmap(struct mmap_arg_struct *arg)
return error;
}
extern asmlinkage int sys_select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
struct sel_arg_struct {
......@@ -103,7 +175,7 @@ asmlinkage int old_select(struct sel_arg_struct *arg)
if (copy_from_user(&a, arg, sizeof(a)))
return -EFAULT;
/* sys_select() does the appropriate kernel locking */
/* sys_select() does the appropriate kernel locking */
return sys_select(a.n, a.inp, a.outp, a.exp, a.tvp);
}
......
......@@ -82,6 +82,8 @@ if [ "$CONFIG_MOUSE" != "n" ]; then
fi
endmenu
source drivers/char/joystick/Config.in
tristate 'QIC-02 tape support' CONFIG_QIC02_TAPE
if [ "$CONFIG_QIC02_TAPE" != "n" ]; then
bool ' Do you want runtime configuration for QIC-02' CONFIG_QIC02_DYNCONF
......@@ -141,7 +143,6 @@ if [ "$CONFIG_VIDEO_DEV" != "n" ]; then
fi
if [ "$CONFIG_PCI" != "n" ]; then
dep_tristate ' BT848 Video For Linux' CONFIG_VIDEO_BT848 $CONFIG_VIDEO_DEV
dep_tristate 'Zoran ZR36120/36125 support' CONFIG_VIDEO_ZR36120 $CONFIG_VIDEO_DEV
fi
dep_tristate ' GemTek Radio Card support' CONFIG_RADIO_GEMTEK $CONFIG_VIDEO_DEV
if [ "$CONFIG_RADIO_GEMTEK" = "y" ]; then
......@@ -200,15 +201,6 @@ fi
endmenu
mainmenu_option next_comment
comment 'Joystick support'
tristate 'Joystick support' CONFIG_JOYSTICK
if [ "$CONFIG_JOYSTICK" != "n" ]; then
source drivers/char/joystick/Config.in
fi
endmenu
tristate 'Double Talk PC internal speech card support' CONFIG_DTLK
tristate 'Siemens R3964 line discipline' CONFIG_R3964
......@@ -224,6 +216,7 @@ endmenu
if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
bool 'Direct Rendering Manager (XFree86 DRI support) (EXPERIMENTAL)' CONFIG_DRM
dep_tristate ' 3dfx Banshee/Voodoo3' CONFIG_DRM_TDFX $CONFIG_DRM
if [ "$CONFIG_DRM" = "y" ]; then
dep_tristate ' 3dlabs GMX 2000' CONFIG_DRM_GAMMA m
fi
......
......@@ -622,6 +622,7 @@ else
endif
ifeq ($(CONFIG_DRM),y)
SUB_DIRS += drm
ALL_SUB_DIRS += drm
MOD_SUB_DIRS += drm
endif
......
......@@ -11,17 +11,33 @@
#
L_TARGET := libdrm.a
O_TARGET := drm.o
L_OBJS := init.o memory.o proc.o auth.o context.o drawable.o bufs.o \
lists.o lock.o ioctl.o fops.o vm.o dma.o
M_OBJS :=
ifdef CONFIG_DRM_GAMMA
M_OBJS += gamma.o
ifeq ($(CONFIG_DRM_GAMMA),y)
O_OBJS += gamma.o
else
ifeq ($(CONFIG_DRM_GAMMA),m)
M_OBJS += gamma.o
endif
endif
ifeq ($(CONFIG_DRM_TDFX),y)
O_OBJS += tdfx.o
else
ifeq ($(CONFIG_DRM_TDFX),m)
M_OBJS += tdfx.o
endif
endif
include $(TOPDIR)/Rules.make
gamma.o: gamma_drv.o gamma_dma.o $(L_TARGET)
$(LD) $(LD_RFLAG) -r -o $@ gamma_drv.o gamma_dma.o -L. -ldrm
tdfx.o: tdfx_drv.o tdfx_context.o $(L_TARGET)
$(LD) $(LD_RFLAG) -r -o $@ tdfx_drv.o tdfx_context.o -L. -ldrm
......@@ -37,3 +37,5 @@ For specific information about kernel-level support, see:
http://precisioninsight.com/dr/security.html
$XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/README.drm,v 1.2 1999/09/27 14:59:24 dawes Exp $
......@@ -24,8 +24,8 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/auth.c,v 1.4 1999/08/30 13:05:00 faith Exp $
* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/gen_ioctl.c,v 1.2 1999/06/27 14:08:27 dawes Exp $
* $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/auth.c,v 1.4 1999/08/30 13:05:00 faith Exp $
* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/auth.c,v 1.1 1999/09/25 14:37:57 dawes Exp $
*
*/
......
/* bufs.c -- IOCTLs to manage buffers -*- linux-c -*-
* Created: Tue Feb 2 08:37:54 1999 by faith@precisioninsight.com
* Revised: Fri Aug 20 22:48:10 1999 by faith@precisioninsight.com
* Revised: Fri Dec 3 12:11:11 1999 by faith@precisioninsight.com
*
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
* All Rights Reserved.
......@@ -24,13 +24,12 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/bufs.c,v 1.8 1999/08/30 13:05:00 faith Exp $
* $XFree86$
* $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/bufs.c,v 1.8 1999/08/30 13:05:00 faith Exp $
* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/bufs.c,v 1.1 1999/09/25 14:37:57 dawes Exp $
*
*/
#define __NO_VERSION__
#include <linux/config.h>
#include "drmP.h"
#include "linux/un.h"
......@@ -90,10 +89,11 @@ int drm_addmap(struct inode *inode, struct file *filp, unsigned int cmd,
case _DRM_SHM:
DRM_DEBUG("%ld %d\n", map->size, drm_order(map->size));
map->handle = (void *)drm_alloc_pages(drm_order(map->size)
- PAGE_SHIFT,
DRM_MEM_SAREA);
DRM_DEBUG("%ld %d %p\n", map->size, drm_order(map->size),
map->handle);
if (!map->handle) {
drm_free(map, sizeof(*map), DRM_MEM_MAPS);
return -ENOMEM;
......
......@@ -24,8 +24,8 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/context.c,v 1.5 1999/08/30 13:05:00 faith Exp $
* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/gen_ioctl.c,v 1.2 1999/06/27 14:08:27 dawes Exp $
* $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/context.c,v 1.5 1999/08/30 13:05:00 faith Exp $
* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/context.c,v 1.1 1999/09/25 14:37:58 dawes Exp $
*
*/
......
/* dma.c -- DMA IOCTL and function support -*- linux-c -*-
* Created: Fri Mar 19 14:30:16 1999 by faith@precisioninsight.com
* Revised: Fri Aug 20 13:06:51 1999 by faith@precisioninsight.com
* Revised: Thu Sep 16 12:55:39 1999 by faith@precisioninsight.com
*
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
* All Rights Reserved.
......@@ -24,8 +24,8 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/dma.c,v 1.6 1999/08/20 20:00:53 faith Exp $
* $XFree86$
* $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/dma.c,v 1.7 1999/09/16 16:56:18 faith Exp $
* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/dma.c,v 1.1 1999/09/25 14:37:58 dawes Exp $
*
*/
......@@ -176,6 +176,7 @@ void drm_reclaim_buffers(drm_device_t *dev, pid_t pid)
drm_device_dma_t *dma = dev->dma;
int i;
if (!dma) return;
for (i = 0; i < dma->buf_count; i++) {
if (dma->buflist[i]->pid == pid) {
switch (dma->buflist[i]->list) {
......
......@@ -24,8 +24,8 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/drawable.c,v 1.3 1999/08/30 13:05:00 faith Exp $
* $XFree86$
* $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drawable.c,v 1.3 1999/08/30 13:05:00 faith Exp $
* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drawable.c,v 1.1 1999/09/25 14:37:58 dawes Exp $
*
*/
......
/* drm.h -- Header for Direct Rendering Manager -*- linux-c -*-
* Created: Mon Jan 4 10:05:05 1999 by faith@precisioninsight.com
* Revised: Fri Aug 20 13:08:18 1999 by faith@precisioninsight.com
* Revised: Mon Dec 6 17:11:19 1999 by faith@precisioninsight.com
*
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
* All rights reserved.
......@@ -24,9 +24,12 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/drm.h,v 1.46 1999/08/20 20:00:53 faith Exp $
* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/drm.h,v 1.2 1999/06/27 14:08:21 dawes Exp $
*
* $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm.h,v 1.46 1999/08/20 20:00:53 faith Exp $
* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm.h,v 1.1 1999/09/25 14:37:58 dawes Exp $
*
* Acknowledgements:
* Dec 1999, Richard Henderson <rth@twiddle.net>, move to generic cmpxchg.
*
*/
#ifndef _DRM_H_
......
/* drmP.h -- Private header for Direct Rendering Manager -*- linux-c -*-
* Created: Mon Jan 4 10:05:05 1999 by faith@precisioninsight.com
* Revised: Fri Aug 20 13:04:33 1999 by faith@precisioninsight.com
* Revised: Mon Dec 6 16:06:49 1999 by faith@precisioninsight.com
*
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
* All rights reserved.
......@@ -24,8 +24,8 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/drmP.h,v 1.58 1999/08/30 13:05:00 faith Exp $
* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/drmP.h,v 1.2 1999/06/27 14:08:24 dawes Exp $
* $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drmP.h,v 1.58 1999/08/30 13:05:00 faith Exp $
* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drmP.h,v 1.1 1999/09/25 14:37:59 dawes Exp $
*
*/
......@@ -33,7 +33,6 @@
#define _DRM_P_H_
#ifdef __KERNEL__
#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/miscdevice.h>
......@@ -84,33 +83,77 @@
#define DRM_MEM_BUFLISTS 14
/* Backward compatibility section */
/* _PAGE_WT changed to _PAGE_PWT in 2.2.6 */
#ifndef _PAGE_PWT
/* The name of _PAGE_WT was changed to
_PAGE_PWT in Linux 2.2.6 */
#define _PAGE_PWT _PAGE_WT
#endif
/* Wait queue declarations changes in 2.3.1 */
/* Wait queue declarations changed in 2.3.1 */
#ifndef DECLARE_WAITQUEUE
#define DECLARE_WAITQUEUE(w,c) struct wait_queue w = { c, NULL }
typedef struct wait_queue *wait_queue_head_t;
#define init_waitqueue_head(q) *q = NULL;
#endif
#define __drm_dummy_lock(lock) (*(__volatile__ unsigned int *)lock)
#define _DRM_CAS(lock,old,new,__ret) \
do { \
int __dummy; /* Can't mark eax as clobbered */ \
__asm__ __volatile__( \
"lock ; cmpxchg %4,%1\n\t" \
"setnz %0" \
: "=d" (__ret), \
"=m" (__drm_dummy_lock(lock)), \
"=a" (__dummy) \
: "2" (old), \
"r" (new)); \
} while (0)
/* _PAGE_4M changed to _PAGE_PSE in 2.3.23 */
#ifndef _PAGE_PSE
#define _PAGE_PSE _PAGE_4M
#endif
/* vm_offset changed to vm_pgoff in 2.3.25 */
#if LINUX_VERSION_CODE < 0x020319
#define VM_OFFSET(vma) ((vma)->vm_offset)
#else
#define VM_OFFSET(vma) ((vma)->vm_pgoff << PAGE_SHIFT)
#endif
/* *_nopage return values defined in 2.3.26 */
#ifndef NOPAGE_SIGBUS
#define NOPAGE_SIGBUS 0
#endif
#ifndef NOPAGE_OOM
#define NOPAGE_OOM 0
#endif
/* Generic cmpxchg added in 2.3.x */
#if CPU != 386
#ifndef __HAVE_ARCH_CMPXCHG
/* Include this here so that driver can be
used with older kernels. */
static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
unsigned long new, int size)
{
unsigned long prev;
switch (size) {
case 1:
__asm__ __volatile__(LOCK_PREFIX "cmpxchgb %b1,%2"
: "=a"(prev)
: "q"(new), "m"(*__xg(ptr)), "0"(old)
: "memory");
return prev;
case 2:
__asm__ __volatile__(LOCK_PREFIX "cmpxchgw %w1,%2"
: "=a"(prev)
: "q"(new), "m"(*__xg(ptr)), "0"(old)
: "memory");
return prev;
case 4:
__asm__ __volatile__(LOCK_PREFIX "cmpxchgl %1,%2"
: "=a"(prev)
: "q"(new), "m"(*__xg(ptr)), "0"(old)
: "memory");
return prev;
}
return old;
}
#define cmpxchg(ptr,o,n) \
((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o), \
(unsigned long)(n),sizeof(*(ptr))))
#endif
#else
/* Compiling for a 386 proper... */
#error DRI not supported on Intel 80386
#endif
/* Macros to make printk easier */
#define DRM_ERROR(fmt, arg...) \
......@@ -437,6 +480,7 @@ extern ssize_t drm_read(struct file *filp, char *buf, size_t count,
extern int drm_write_string(drm_device_t *dev, const char *s);
/* Mapping support (vm.c) */
#if LINUX_VERSION_CODE < 0x020317
extern unsigned long drm_vm_nopage(struct vm_area_struct *vma,
unsigned long address,
int write_access);
......@@ -446,6 +490,18 @@ extern unsigned long drm_vm_shm_nopage(struct vm_area_struct *vma,
extern unsigned long drm_vm_dma_nopage(struct vm_area_struct *vma,
unsigned long address,
int write_access);
#else
/* Return type changed in 2.3.23 */
extern struct page *drm_vm_nopage(struct vm_area_struct *vma,
unsigned long address,
int write_access);
extern struct page *drm_vm_shm_nopage(struct vm_area_struct *vma,
unsigned long address,
int write_access);
extern struct page *drm_vm_dma_nopage(struct vm_area_struct *vma,
unsigned long address,
int write_access);
#endif
extern void drm_vm_open(struct vm_area_struct *vma);
extern void drm_vm_close(struct vm_area_struct *vma);
extern int drm_mmap_dma(struct file *filp,
......@@ -570,7 +626,8 @@ extern int drm_unblock(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
extern int drm_lock_take(__volatile__ unsigned int *lock,
unsigned int context);
extern int drm_lock_transfer(__volatile__ unsigned int *lock,
extern int drm_lock_transfer(drm_device_t *dev,
__volatile__ unsigned int *lock,
unsigned int context);
extern int drm_lock_free(drm_device_t *dev,
__volatile__ unsigned int *lock,
......
/* fops.c -- File operations for DRM -*- linux-c -*-
* Created: Mon Jan 4 08:58:31 1999 by faith@precisioninsight.com
* Revised: Fri Aug 20 11:31:46 1999 by faith@precisioninsight.com
* Revised: Fri Dec 3 10:26:26 1999 by faith@precisioninsight.com
*
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
* All Rights Reserved.
......@@ -24,8 +24,8 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/fops.c,v 1.3 1999/08/20 15:36:45 faith Exp $
* $XFree86$
* $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/fops.c,v 1.3 1999/08/20 15:36:45 faith Exp $
* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/fops.c,v 1.1 1999/09/25 14:37:59 dawes Exp $
*
*/
......@@ -75,8 +75,8 @@ int drm_flush(struct file *filp)
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
DRM_DEBUG("pid = %d, device = 0x%x, open_count = %d, f_count = %d\n",
current->pid, dev->device, dev->open_count, atomic_read(&filp->f_count));
DRM_DEBUG("pid = %d, device = 0x%x, open_count = %d\n",
current->pid, dev->device, dev->open_count);
return 0;
}
......@@ -91,6 +91,20 @@ int drm_release(struct inode *inode, struct file *filp)
DRM_DEBUG("pid = %d, device = 0x%x, open_count = %d\n",
current->pid, dev->device, dev->open_count);
if (_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)
&& dev->lock.pid == current->pid) {
DRM_ERROR("Process %d dead, freeing lock for context %d\n",
current->pid,
_DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock));
drm_lock_free(dev,
&dev->lock.hw_lock->lock,
_DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock));
/* FIXME: may require heavy-handed reset of
hardware at this point, possibly
processed via a callback to the X
server. */
}
drm_reclaim_buffers(dev, priv->pid);
drm_fasync(-1, filp, 0);
......@@ -197,7 +211,12 @@ int drm_write_string(drm_device_t *dev, const char *s)
send -= count;
}
if (dev->buf_async) kill_fasync(dev->buf_async, SIGIO, POLL_OUT);
#if LINUX_VERSION_CODE < 0x020315
if (dev->buf_async) kill_fasync(dev->buf_async, SIGIO);
#else
/* Parameter added in 2.3.21 */
if (dev->buf_async) kill_fasync(dev->buf_async, SIGIO, POLL_IN);
#endif
DRM_DEBUG("waking\n");
wake_up_interruptible(&dev->buf_readers);
return 0;
......
/* gamma_dma.c -- DMA support for GMX 2000 -*- linux-c -*-
* Created: Fri Mar 19 14:30:16 1999 by faith@precisioninsight.com
* Revised: Fri Aug 20 11:31:45 1999 by faith@precisioninsight.com
* Revised: Thu Sep 16 12:55:37 1999 by faith@precisioninsight.com
*
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
* All Rights Reserved.
......@@ -24,8 +24,8 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/gamma_dma.c,v 1.8 1999/08/30 13:05:00 faith Exp $
* $XFree86$
* $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma_dma.c,v 1.9 1999/09/16 16:56:18 faith Exp $
* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma_dma.c,v 1.1 1999/09/25 14:38:00 dawes Exp $
*
*/
......
/* gamma.c -- 3dlabs GMX 2000 driver -*- linux-c -*-
* Created: Mon Jan 4 08:58:31 1999 by faith@precisioninsight.com
* Revised: Fri Aug 20 22:48:11 1999 by faith@precisioninsight.com
* Revised: Tue Oct 12 08:51:36 1999 by faith@precisioninsight.com
*
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
* All Rights Reserved.
......@@ -24,13 +24,12 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/gamma_drv.c,v 1.17 1999/08/30 13:05:00 faith Exp $
* $XFree86$
* $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma_drv.c,v 1.17 1999/08/30 13:05:00 faith Exp $
* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma_drv.c,v 1.1 1999/09/25 14:38:00 dawes Exp $
*
*/
#define EXPORT_SYMTAB
#include <linux/config.h>
#include "drmP.h"
#include "gamma_drv.h"
EXPORT_SYMBOL(gamma_init);
......@@ -509,7 +508,7 @@ int gamma_unlock(struct inode *inode, struct file *filp, unsigned int cmd,
atomic_inc(&dev->total_unlocks);
if (_DRM_LOCK_IS_CONT(dev->lock.hw_lock->lock))
atomic_inc(&dev->total_contends);
drm_lock_transfer(&dev->lock.hw_lock->lock, DRM_KERNEL_CONTEXT);
drm_lock_transfer(dev, &dev->lock.hw_lock->lock, DRM_KERNEL_CONTEXT);
gamma_dma_schedule(dev, 1);
if (!dev->context_flag) {
if (drm_lock_free(dev, &dev->lock.hw_lock->lock,
......
......@@ -24,8 +24,8 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/gamma_drv.h,v 1.4 1999/08/30 13:05:00 faith Exp $
* $XFree86$
* $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma_drv.h,v 1.4 1999/08/30 13:05:00 faith Exp $
* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/gamma_drv.h,v 1.1 1999/09/25 14:38:00 dawes Exp $
*
*/
......
......@@ -24,8 +24,8 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/init.c,v 1.3 1999/08/20 15:07:01 faith Exp $
* $XFree86$
* $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/init.c,v 1.3 1999/08/20 15:07:01 faith Exp $
* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/init.c,v 1.1 1999/09/25 14:38:01 dawes Exp $
*
*/
......
......@@ -24,8 +24,8 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/ioctl.c,v 1.3 1999/08/30 13:05:00 faith Exp $
* $XFree86$
* $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/ioctl.c,v 1.3 1999/08/30 13:05:00 faith Exp $
* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/ioctl.c,v 1.1 1999/09/25 14:38:01 dawes Exp $
*
*/
......
/* lists.c -- Buffer list handling routines -*- linux-c -*-
* Created: Mon Apr 19 20:54:22 1999 by faith@precisioninsight.com
* Revised: Fri Aug 20 09:27:01 1999 by faith@precisioninsight.com
* Revised: Mon Dec 6 16:04:44 1999 by faith@precisioninsight.com
*
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
* All Rights Reserved.
......@@ -24,8 +24,8 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/lists.c,v 1.3 1999/08/20 15:07:02 faith Exp $
* $XFree86$
* $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/lists.c,v 1.3 1999/08/20 15:07:02 faith Exp $
* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/lists.c,v 1.1 1999/09/25 14:38:01 dawes Exp $
*
*/
......@@ -130,11 +130,9 @@ int drm_freelist_destroy(drm_freelist_t *bl)
int drm_freelist_put(drm_device_t *dev, drm_freelist_t *bl, drm_buf_t *buf)
{
unsigned int old;
unsigned int new;
char failed;
drm_buf_t *old, *prev;
int count = 0;
drm_device_dma_t *dma = dev->dma;
drm_device_dma_t *dma = dev->dma;
if (!dma) {
DRM_ERROR("No DMA support\n");
......@@ -155,15 +153,14 @@ int drm_freelist_put(drm_device_t *dev, drm_freelist_t *bl, drm_buf_t *buf)
#endif
buf->list = DRM_LIST_FREE;
do {
old = (unsigned long)bl->next;
buf->next = (void *)old;
new = (unsigned long)buf;
_DRM_CAS(&bl->next, old, new, failed);
old = bl->next;
bl->next = old;
prev = cmpxchg(&bl->next, old, buf);
if (++count > DRM_LOOPING_LIMIT) {
DRM_ERROR("Looping\n");
return 1;
}
} while (failed);
} while (prev != old);
atomic_inc(&bl->count);
if (atomic_read(&bl->count) > dma->buf_count) {
DRM_ERROR("%d of %d buffers free after addition of %d\n",
......@@ -180,9 +177,7 @@ int drm_freelist_put(drm_device_t *dev, drm_freelist_t *bl, drm_buf_t *buf)
static drm_buf_t *drm_freelist_try(drm_freelist_t *bl)
{
unsigned int old;
unsigned int new;
char failed;
drm_buf_t *old, *new, *prev;
drm_buf_t *buf;
int count = 0;
......@@ -190,20 +185,18 @@ static drm_buf_t *drm_freelist_try(drm_freelist_t *bl)
/* Get buffer */
do {
old = (unsigned int)bl->next;
if (!old) {
return NULL;
}
new = (unsigned long)bl->next->next;
_DRM_CAS(&bl->next, old, new, failed);
old = bl->next;
if (!old) return NULL;
new = bl->next->next;
prev = cmpxchg(&bl->next, old, new);
if (++count > DRM_LOOPING_LIMIT) {
DRM_ERROR("Looping\n");
return NULL;
}
} while (failed);
} while (prev != old);
atomic_dec(&bl->count);
buf = (drm_buf_t *)old;
buf = old;
buf->next = NULL;
buf->list = DRM_LIST_NONE;
DRM_DEBUG("%d, count = %d, wfh = %d, w%d, p%d\n",
......
/* lock.c -- IOCTLs for locking -*- linux-c -*-
* Created: Tue Feb 2 08:37:54 1999 by faith@precisioninsight.com
* Revised: Fri Aug 20 09:27:01 1999 by faith@precisioninsight.com
* Revised: Mon Dec 6 16:04:44 1999 by faith@precisioninsight.com
*
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
* All Rights Reserved.
......@@ -24,8 +24,8 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/lock.c,v 1.5 1999/08/30 13:05:00 faith Exp $
* $XFree86$
* $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/lock.c,v 1.5 1999/08/30 13:05:00 faith Exp $
* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/lock.c,v 1.1 1999/09/25 14:38:01 dawes Exp $
*
*/
......@@ -48,17 +48,15 @@ int drm_unblock(struct inode *inode, struct file *filp, unsigned int cmd,
int drm_lock_take(__volatile__ unsigned int *lock, unsigned int context)
{
unsigned int old;
unsigned int new;
char failed;
unsigned int old, new, prev;
DRM_DEBUG("%d attempts\n", context);
do {
old = *lock;
if (old & _DRM_LOCK_HELD) new = old | _DRM_LOCK_CONT;
else new = context | _DRM_LOCK_HELD;
_DRM_CAS(lock, old, new, failed);
} while (failed);
prev = cmpxchg(lock, old, new);
} while (prev != old);
if (_DRM_LOCKING_CONTEXT(old) == context) {
if (old & _DRM_LOCK_HELD) {
if (context != DRM_KERNEL_CONTEXT) {
......@@ -80,17 +78,17 @@ int drm_lock_take(__volatile__ unsigned int *lock, unsigned int context)
/* This takes a lock forcibly and hands it to context. Should ONLY be used
inside *_unlock to give lock to kernel before calling *_dma_schedule. */
int drm_lock_transfer(__volatile__ unsigned int *lock, unsigned int context)
int drm_lock_transfer(drm_device_t *dev,
__volatile__ unsigned int *lock, unsigned int context)
{
unsigned int old;
unsigned int new;
char failed;
unsigned int old, new, prev;
dev->lock.pid = 0;
do {
old = *lock;
new = context | _DRM_LOCK_HELD;
_DRM_CAS(lock, old, new, failed);
} while (failed);
old = *lock;
new = context | _DRM_LOCK_HELD;
prev = cmpxchg(lock, old, new);
} while (prev != old);
DRM_DEBUG("%d => %d\n", _DRM_LOCKING_CONTEXT(old), context);
return 1;
}
......@@ -98,23 +96,23 @@ int drm_lock_transfer(__volatile__ unsigned int *lock, unsigned int context)
int drm_lock_free(drm_device_t *dev,
__volatile__ unsigned int *lock, unsigned int context)
{
unsigned int old;
unsigned int new;
char failed;
unsigned int old, new, prev;
pid_t pid = dev->lock.pid;
DRM_DEBUG("%d\n", context);
dev->lock.pid = 0;
do {
old = *lock;
new = 0;
_DRM_CAS(lock, old, new, failed);
} while (failed);
old = *lock;
new = 0;
prev = cmpxchg(lock, old, new);
} while (prev != old);
if (_DRM_LOCK_IS_HELD(old) && _DRM_LOCKING_CONTEXT(old) != context) {
DRM_ERROR("%d freed heavyweight lock held by %d\n",
DRM_ERROR("%d freed heavyweight lock held by %d (pid %d)\n",
context,
_DRM_LOCKING_CONTEXT(old));
_DRM_LOCKING_CONTEXT(old),
pid);
return 1;
}
dev->lock.pid = 0;
wake_up_interruptible(&dev->lock.lock_queue);
return 0;
}
......
/* memory.c -- Memory management wrappers for DRM -*- linux-c -*-
* Created: Thu Feb 4 14:00:34 1999 by faith@precisioninsight.com
* Revised: Fri Aug 20 13:04:33 1999 by faith@precisioninsight.com
* Revised: Mon Dec 6 10:28:18 1999 by faith@precisioninsight.com
*
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
* All Rights Reserved.
......@@ -24,8 +24,8 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/memory.c,v 1.4 1999/08/20 20:00:53 faith Exp $
* $XFree86$
* $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/memory.c,v 1.4 1999/08/20 20:00:53 faith Exp $
* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/memory.c,v 1.1 1999/09/25 14:38:02 dawes Exp $
*
*/
......@@ -42,7 +42,7 @@ typedef struct drm_mem_stats {
} drm_mem_stats_t;
static spinlock_t drm_mem_lock = SPIN_LOCK_UNLOCKED;
static unsigned long drm_ram_available = 0;
static unsigned long drm_ram_available = 0; /* In pages */
static unsigned long drm_ram_used = 0;
static drm_mem_stats_t drm_mem_stats[] = {
[DRM_MEM_DMA] = { "dmabufs" },
......@@ -77,7 +77,12 @@ void drm_mem_init(void)
}
si_meminfo(&si);
#if LINUX_VERSION_CODE < 0x020317
/* Changed to page count in 2.3.23 */
drm_ram_available = si.totalram >> PAGE_SHIFT;
#else
drm_ram_available = si.totalram;
#endif
drm_ram_used = 0;
}
......@@ -95,10 +100,11 @@ static int _drm_mem_info(char *buf, char **start, off_t offset, int len,
" | outstanding \n");
DRM_PROC_PRINT("type alloc freed fail bytes freed"
" | allocs bytes\n\n");
DRM_PROC_PRINT("%-9.9s %5d %5d %4d %10lu |\n",
"system", 0, 0, 0, drm_ram_available);
DRM_PROC_PRINT("%-9.9s %5d %5d %4d %10lu |\n",
"locked", 0, 0, 0, drm_ram_used);
DRM_PROC_PRINT("%-9.9s %5d %5d %4d %10lu kB |\n",
"system", 0, 0, 0,
drm_ram_available << (PAGE_SHIFT - 10));
DRM_PROC_PRINT("%-9.9s %5d %5d %4d %10lu kB |\n",
"locked", 0, 0, 0, drm_ram_used >> 10);
DRM_PROC_PRINT("\n");
for (pt = drm_mem_stats; pt->name; pt++) {
DRM_PROC_PRINT("%-9.9s %5d %5d %4d %10lu %10lu | %6d %10ld\n",
......@@ -207,7 +213,8 @@ unsigned long drm_alloc_pages(int order, int area)
unsigned int sz;
spin_lock(&drm_mem_lock);
if (drm_ram_used > +(DRM_RAM_PERCENT * drm_ram_available) / 100) {
if ((drm_ram_used >> PAGE_SHIFT)
> (DRM_RAM_PERCENT * drm_ram_available) / 100) {
spin_unlock(&drm_mem_lock);
return 0;
}
......
/* proc.c -- /proc support for DRM -*- linux-c -*-
* Created: Mon Jan 11 09:48:47 1999 by faith@precisioninsight.com
* Revised: Fri Aug 20 11:31:48 1999 by faith@precisioninsight.com
* Revised: Fri Dec 3 09:44:16 1999 by faith@precisioninsight.com
*
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
* All Rights Reserved.
......@@ -24,8 +24,8 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/proc.c,v 1.4 1999/08/20 15:36:46 faith Exp $
* $XFree86$
* $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/proc.c,v 1.4 1999/08/20 15:36:46 faith Exp $
* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/proc.c,v 1.1 1999/09/25 14:38:02 dawes Exp $
*
*/
......@@ -79,41 +79,44 @@ int drm_proc_init(drm_device_t *dev)
struct proc_dir_entry *ent;
int i, j;
drm_root = proc_mkdir("video", NULL);
drm_root = create_proc_entry("graphics", S_IFDIR, NULL);
if (!drm_root) {
DRM_ERROR("Cannot create /proc/video\n");
DRM_ERROR("Cannot create /proc/graphics\n");
return -1;
}
/* Instead of doing this search, we should
add some global support for /proc/video. */
add some global support for /proc/graphics. */
for (i = 0; i < 8; i++) {
sprintf(drm_slot_name, "video/%d", i);
drm_dev_root = proc_mkdir(drm_slot_name, NULL);
sprintf(drm_slot_name, "graphics/%d", i);
drm_dev_root = create_proc_entry(drm_slot_name, S_IFDIR, NULL);
if (!drm_dev_root) {
DRM_ERROR("Cannot create /proc/%s\n", drm_slot_name);
remove_proc_entry("video", NULL);
remove_proc_entry("graphics", NULL);
}
if (drm_dev_root->nlink == 2) break;
drm_dev_root = NULL;
}
if (!drm_dev_root) {
DRM_ERROR("Cannot find slot in /proc/video\n");
DRM_ERROR("Cannot find slot in /proc/graphics\n");
return -1;
}
for (i = 0; i < DRM_PROC_ENTRIES; i++) {
if (create_proc_read_entry(drm_proc_list[i].name,0,drm_dev_root,
drm_proc_list[i].f, dev))
continue;
DRM_ERROR("Cannot create /proc/%s/%s\n",
drm_slot_name, drm_proc_list[i].name);
for (j = 0; j < i; j++)
remove_proc_entry(drm_proc_list[i].name, drm_dev_root);
remove_proc_entry(drm_slot_name, NULL);
remove_proc_entry("video", NULL);
return -1;
ent = create_proc_entry(drm_proc_list[i].name,
S_IFREG|S_IRUGO, drm_dev_root);
if (!ent) {
DRM_ERROR("Cannot create /proc/%s/%s\n",
drm_slot_name, drm_proc_list[i].name);
for (j = 0; j < i; j++)
remove_proc_entry(drm_proc_list[i].name,
drm_dev_root);
remove_proc_entry(drm_slot_name, NULL);
remove_proc_entry("graphics", NULL);
return -1;
}
ent->read_proc = drm_proc_list[i].f;
ent->data = dev;
}
return 0;
......@@ -132,7 +135,7 @@ int drm_proc_cleanup(void)
}
remove_proc_entry(drm_slot_name, NULL);
}
remove_proc_entry("video", NULL);
remove_proc_entry("graphics", NULL);
remove_proc_entry(DRM_NAME, NULL);
}
drm_root = drm_dev_root = NULL;
......@@ -379,7 +382,8 @@ static int _drm_vma_info(char *buf, char **start, off_t offset, int len,
vma->vm_flags & VM_MAYSHARE ? 's' : 'p',
vma->vm_flags & VM_LOCKED ? 'l' : '-',
vma->vm_flags & VM_IO ? 'i' : '-',
vma->vm_pgoff << PAGE_SHIFT );
VM_OFFSET(vma));
#if defined(__i386__)
pgprot = pgprot_val(vma->vm_page_prot);
DRM_PROC_PRINT(" %c%c%c%c%c%c%c%c%c",
......
/* tdfx_context.c -- IOCTLs for tdfx contexts -*- linux-c -*-
* Created: Thu Oct 7 10:50:22 1999 by faith@precisioninsight.com
* Revised: Sat Oct 9 23:39:56 1999 by faith@precisioninsight.com
*
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* $PI$
* $XFree86$
*
*/
#include <linux/sched.h>
#define __NO_VERSION__
#include "drmP.h"
#include "tdfx_drv.h"
extern drm_ctx_t tdfx_res_ctx;
static int tdfx_alloc_queue(drm_device_t *dev)
{
static int context = 0;
return ++context; /* Should this reuse contexts in the future? */
}
int tdfx_context_switch(drm_device_t *dev, int old, int new)
{
char buf[64];
atomic_inc(&dev->total_ctx);
if (test_and_set_bit(0, &dev->context_flag)) {
DRM_ERROR("Reentering -- FIXME\n");
return -EBUSY;
}
#if DRM_DMA_HISTOGRAM
dev->ctx_start = get_cycles();
#endif
DRM_DEBUG("Context switch from %d to %d\n", old, new);
if (new == dev->last_context) {
clear_bit(0, &dev->context_flag);
return 0;
}
if (drm_flags & DRM_FLAG_NOCTX) {
tdfx_context_switch_complete(dev, new);
} else {
sprintf(buf, "C %d %d\n", old, new);
drm_write_string(dev, buf);
}
return 0;
}
int tdfx_context_switch_complete(drm_device_t *dev, int new)
{
dev->last_context = new; /* PRE/POST: This is the _only_ writer. */
dev->last_switch = jiffies;
if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
DRM_ERROR("Lock isn't held after context switch\n");
}
/* If a context switch is ever initiated
when the kernel holds the lock, release
that lock here. */
#if DRM_DMA_HISTOGRAM
atomic_inc(&dev->histo.ctx[drm_histogram_slot(get_cycles()
- dev->ctx_start)]);
#endif
clear_bit(0, &dev->context_flag);
wake_up(&dev->context_wait);
return 0;
}
int tdfx_resctx(struct inode *inode, struct file *filp, unsigned int cmd,
unsigned long arg)
{
drm_ctx_res_t res;
drm_ctx_t ctx;
int i;
DRM_DEBUG("%d\n", DRM_RESERVED_CONTEXTS);
copy_from_user_ret(&res, (drm_ctx_res_t *)arg, sizeof(res), -EFAULT);
if (res.count >= DRM_RESERVED_CONTEXTS) {
memset(&ctx, 0, sizeof(ctx));
for (i = 0; i < DRM_RESERVED_CONTEXTS; i++) {
ctx.handle = i;
copy_to_user_ret(&res.contexts[i],
&i,
sizeof(i),
-EFAULT);
}
}
res.count = DRM_RESERVED_CONTEXTS;
copy_to_user_ret((drm_ctx_res_t *)arg, &res, sizeof(res), -EFAULT);
return 0;
}
int tdfx_addctx(struct inode *inode, struct file *filp, unsigned int cmd,
unsigned long arg)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
drm_ctx_t ctx;
copy_from_user_ret(&ctx, (drm_ctx_t *)arg, sizeof(ctx), -EFAULT);
if ((ctx.handle = tdfx_alloc_queue(dev)) == DRM_KERNEL_CONTEXT) {
/* Skip kernel's context and get a new one. */
ctx.handle = tdfx_alloc_queue(dev);
}
DRM_DEBUG("%d\n", ctx.handle);
copy_to_user_ret((drm_ctx_t *)arg, &ctx, sizeof(ctx), -EFAULT);
return 0;
}
int tdfx_modctx(struct inode *inode, struct file *filp, unsigned int cmd,
unsigned long arg)
{
drm_ctx_t ctx;
copy_from_user_ret(&ctx, (drm_ctx_t*)arg, sizeof(ctx), -EFAULT);
if (ctx.flags==_DRM_CONTEXT_PRESERVED)
tdfx_res_ctx.handle=ctx.handle;
return 0;
}
int tdfx_getctx(struct inode *inode, struct file *filp, unsigned int cmd,
unsigned long arg)
{
drm_ctx_t ctx;
copy_from_user_ret(&ctx, (drm_ctx_t*)arg, sizeof(ctx), -EFAULT);
/* This is 0, because we don't hanlde any context flags */
ctx.flags = 0;
copy_to_user_ret((drm_ctx_t*)arg, &ctx, sizeof(ctx), -EFAULT);
return 0;
}
int tdfx_switchctx(struct inode *inode, struct file *filp, unsigned int cmd,
unsigned long arg)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
drm_ctx_t ctx;
copy_from_user_ret(&ctx, (drm_ctx_t *)arg, sizeof(ctx), -EFAULT);
DRM_DEBUG("%d\n", ctx.handle);
return tdfx_context_switch(dev, dev->last_context, ctx.handle);
}
int tdfx_newctx(struct inode *inode, struct file *filp, unsigned int cmd,
unsigned long arg)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
drm_ctx_t ctx;
copy_from_user_ret(&ctx, (drm_ctx_t *)arg, sizeof(ctx), -EFAULT);
DRM_DEBUG("%d\n", ctx.handle);
tdfx_context_switch_complete(dev, ctx.handle);
return 0;
}
int tdfx_rmctx(struct inode *inode, struct file *filp, unsigned int cmd,
unsigned long arg)
{
drm_ctx_t ctx;
copy_from_user_ret(&ctx, (drm_ctx_t *)arg, sizeof(ctx), -EFAULT);
DRM_DEBUG("%d\n", ctx.handle);
/* This is currently a noop because we
don't reuse context values. Perhaps we
should? */
return 0;
}
This diff is collapsed.
/* sigio.c -- Support for SIGIO handler -*- linux-c -*-
* Created: Thu Jun 3 15:39:18 1999 by faith@precisioninsight.com
* Revised: Thu Jun 3 16:16:35 1999 by faith@precisioninsight.com
/* tdfx_drv.h -- Private header for tdfx driver -*- linux-c -*-
* Created: Thu Oct 7 10:40:04 1999 by faith@precisioninsight.com
* Revised: Sat Oct 9 23:38:19 1999 by faith@precisioninsight.com
*
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
* All Rights Reserved.
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
......@@ -24,58 +24,45 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* $PI: xc/programs/Xserver/hw/xfree86/os-support/shared/sigio.c,v 1.2 1999/06/14 21:11:29 faith Exp $
* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/shared/sigio.c,v 1.2 1999/06/14 12:02:11 dawes Exp $
* $PI$
* $XFree86$
*
*/
#ifndef _TDFX_DRV_H_
#define _TDFX_DRV_H_
#ifdef XFree86Server
# include "X.h"
# include "xf86.h"
# include "xf86drm.h"
# include "xf86_OSlib.h"
#else
# include <unistd.h>
# include <signal.h>
# include <fcntl.h>
#endif
/*
* Linux libc5 defines FASYNC, but not O_ASYNC. Don't know if it is
* functional or not.
*/
#if defined(FASYNC) && !defined(O_ASYNC)
# define O_ASYNC FASYNC
#endif
int
xf86InstallSIGIOHandler(int fd, void (*f)(int))
{
struct sigaction sa;
struct sigaction osa;
/* tdfx_drv.c */
extern int tdfx_init(void);
extern void tdfx_cleanup(void);
extern int tdfx_version(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
extern int tdfx_open(struct inode *inode, struct file *filp);
extern int tdfx_release(struct inode *inode, struct file *filp);
extern int tdfx_ioctl(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
extern int tdfx_lock(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
extern int tdfx_unlock(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
sigemptyset(&sa.sa_mask);
sigaddset(&sa.sa_mask, SIGIO);
sa.sa_flags = 0;
sa.sa_handler = f;
sigaction(SIGIO, &sa, &osa);
fcntl(fd, F_SETOWN, getpid());
fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_ASYNC);
return 0;
}
/* tdfx_context.c */
int
xf86RemoveSIGIOHandler(int fd)
{
struct sigaction sa;
struct sigaction osa;
extern int tdfx_resctx(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
extern int tdfx_addctx(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
extern int tdfx_modctx(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
extern int tdfx_getctx(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
extern int tdfx_switchctx(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
extern int tdfx_newctx(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
extern int tdfx_rmctx(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
sigemptyset(&sa.sa_mask);
sigaddset(&sa.sa_mask, SIGIO);
sa.sa_flags = 0;
sa.sa_handler = SIG_DFL;
fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) & ~O_ASYNC);
sigaction(SIGIO, &sa, &osa);
return 0;
}
extern int tdfx_context_switch(drm_device_t *dev, int old, int new);
extern int tdfx_context_switch_complete(drm_device_t *dev, int new);
#endif
/* vm.c -- Memory mapping for DRM -*- linux-c -*-
* Created: Mon Jan 4 08:58:31 1999 by faith@precisioninsight.com
* Revised: Fri Aug 20 22:48:11 1999 by faith@precisioninsight.com
* Revised: Mon Dec 6 16:54:35 1999 by faith@precisioninsight.com
*
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
* All Rights Reserved.
......@@ -24,8 +24,8 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/generic/vm.c,v 1.7 1999/08/21 02:48:34 faith Exp $
* $XFree86$
* $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/vm.c,v 1.7 1999/08/21 02:48:34 faith Exp $
* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/vm.c,v 1.1 1999/09/25 14:38:02 dawes Exp $
*
*/
......@@ -50,18 +50,32 @@ struct vm_operations_struct drm_vm_dma_ops = {
close: drm_vm_close,
};
#if LINUX_VERSION_CODE < 0x020317
unsigned long drm_vm_nopage(struct vm_area_struct *vma,
unsigned long address,
int write_access)
#else
/* Return type changed in 2.3.23 */
struct page *drm_vm_nopage(struct vm_area_struct *vma,
unsigned long address,
int write_access)
#endif
{
DRM_DEBUG("0x%08lx, %d\n", address, write_access);
return 0; /* Disallow mremap */
return NOPAGE_SIGBUS; /* Disallow mremap */
}
#if LINUX_VERSION_CODE < 0x020317
unsigned long drm_vm_shm_nopage(struct vm_area_struct *vma,
unsigned long address,
int write_access)
#else
/* Return type changed in 2.3.23 */
struct page *drm_vm_shm_nopage(struct vm_area_struct *vma,
unsigned long address,
int write_access)
#endif
{
drm_file_t *priv = vma->vm_file->private_data;
drm_device_t *dev = priv->dev;
......@@ -69,8 +83,8 @@ unsigned long drm_vm_shm_nopage(struct vm_area_struct *vma,
unsigned long offset;
unsigned long page;
if (address > vma->vm_end) return 0; /* Disallow mremap */
if (!dev->lock.hw_lock) return 0; /* Nothing allocated */
if (address > vma->vm_end) return NOPAGE_SIGBUS; /* Disallow mremap */
if (!dev->lock.hw_lock) return NOPAGE_OOM; /* Nothing allocated */
offset = address - vma->vm_start;
page = offset >> PAGE_SHIFT;
......@@ -78,12 +92,23 @@ unsigned long drm_vm_shm_nopage(struct vm_area_struct *vma,
atomic_inc(&mem_map[MAP_NR(physical)].count); /* Dec. by kernel */
DRM_DEBUG("0x%08lx (page %lu) => 0x%08lx\n", address, page, physical);
#if LINUX_VERSION_CODE < 0x020317
return physical;
#else
return mem_map + MAP_NR(physical);
#endif
}
#if LINUX_VERSION_CODE < 0x020317
unsigned long drm_vm_dma_nopage(struct vm_area_struct *vma,
unsigned long address,
int write_access)
#else
/* Return type changed in 2.3.23 */
struct page *drm_vm_dma_nopage(struct vm_area_struct *vma,
unsigned long address,
int write_access)
#endif
{
drm_file_t *priv = vma->vm_file->private_data;
drm_device_t *dev = priv->dev;
......@@ -92,17 +117,21 @@ unsigned long drm_vm_dma_nopage(struct vm_area_struct *vma,
unsigned long offset;
unsigned long page;
if (!dma) return 0; /* Error */
if (address > vma->vm_end) return 0; /* Disallow mremap */
if (!dma->pagelist) return 0; /* Nothing allocated */
if (!dma) return NOPAGE_SIGBUS; /* Error */
if (address > vma->vm_end) return NOPAGE_SIGBUS; /* Disallow mremap */
if (!dma->pagelist) return NOPAGE_OOM ; /* Nothing allocated */
offset = address - vma->vm_start; /* vm_pgoff should be 0 */
offset = address - vma->vm_start; /* vm_[pg]off[set] should be 0 */
page = offset >> PAGE_SHIFT;
physical = dma->pagelist[page] + (offset & (~PAGE_MASK));
atomic_inc(&mem_map[MAP_NR(physical)].count); /* Dec. by kernel */
DRM_DEBUG("0x%08lx (page %lu) => 0x%08lx\n", address, page, physical);
#if LINUX_VERSION_CODE < 0x020317
return physical;
#else
return mem_map + MAP_NR(physical);
#endif
}
void drm_vm_open(struct vm_area_struct *vma)
......@@ -168,8 +197,8 @@ int drm_mmap_dma(struct file *filp, struct vm_area_struct *vma)
drm_device_dma_t *dma = dev->dma;
unsigned long length = vma->vm_end - vma->vm_start;
DRM_DEBUG("start = 0x%lx, end = 0x%lx, pgoff = 0x%lx\n",
vma->vm_start, vma->vm_end, vma->vm_pgoff);
DRM_DEBUG("start = 0x%lx, end = 0x%lx, offset = 0x%lx\n",
vma->vm_start, vma->vm_end, VM_OFFSET(vma));
/* Length must match exact page count */
if ((length >> PAGE_SHIFT) != dma->page_count) return -EINVAL;
......@@ -192,17 +221,13 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma)
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
drm_map_t *map = NULL;
unsigned long off;
int i;
DRM_DEBUG("start = 0x%lx, end = 0x%lx, offset = 0x%lx\n",
vma->vm_start, vma->vm_end, vma->vm_pgoff);
vma->vm_start, vma->vm_end, VM_OFFSET(vma));
if (!vma->vm_pgoff) return drm_mmap_dma(filp, vma);
if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) /* overflow? */
return -EINVAL;
if (!VM_OFFSET(vma)) return drm_mmap_dma(filp, vma);
off = vma->vm_pgoff << PAGE_SHIFT;
/* A sequential search of a linked list is
fine here because: 1) there will only be
about 5-10 entries in the list and, 2) a
......@@ -212,7 +237,7 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma)
bit longer. */
for (i = 0; i < dev->map_count; i++) {
map = dev->maplist[i];
if (map->offset == off) break;
if (map->offset == VM_OFFSET(vma)) break;
}
if (i >= dev->map_count) return -EINVAL;
......@@ -226,7 +251,7 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma)
switch (map->type) {
case _DRM_FRAME_BUFFER:
case _DRM_REGISTERS:
if (off >= __pa(high_memory)) {
if (VM_OFFSET(vma) >= __pa(high_memory)) {
#if defined(__i386__)
if (boot_cpu_data.x86 > 3) {
pgprot_val(vma->vm_page_prot) |= _PAGE_PCD;
......@@ -236,7 +261,7 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma)
vma->vm_flags |= VM_IO; /* not in core dump */
}
if (remap_page_range(vma->vm_start,
off,
VM_OFFSET(vma),
vma->vm_end - vma->vm_start,
vma->vm_page_prot))
return -EAGAIN;
......@@ -253,7 +278,15 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma)
}
vma->vm_flags |= VM_LOCKED | VM_SHM; /* Don't swap */
if (map->flags & _DRM_READ_ONLY) {
#if defined(__i386__)
pgprot_val(vma->vm_page_prot) &= ~_PAGE_RW;
#else
/* Ye gads this is ugly. With more thought
we could move this up higher and use
`protection_map' instead. */
vma->vm_page_prot = __pgprot(pte_val(pte_wrprotect(
__pte(pgprot_val(vma->vm_page_prot)))));
#endif
}
......
#
# Joystick lowlevel driver configuration
# Joystick driver
#
dep_tristate ' Classic PC analog joysticks and gamepads' CONFIG_JOY_ANALOG $CONFIG_JOYSTICK
dep_tristate ' FPGaming and MadCatz A3D controllers' CONFIG_JOY_ASSASIN $CONFIG_JOYSTICK
dep_tristate ' Gravis GrIP joysticks and gamepads' CONFIG_JOY_GRAVIS $CONFIG_JOYSTICK
dep_tristate ' Logitech Digital joysticks and gamepads' CONFIG_JOY_LOGITECH $CONFIG_JOYSTICK
dep_tristate ' Microsoft SideWinder, Genius Digital joysticks and gamepads' CONFIG_JOY_SIDEWINDER $CONFIG_JOYSTICK
dep_tristate ' ThrustMaster DirectConnect joysticks and gamepads' CONFIG_JOY_THRUSTMASTER $CONFIG_JOYSTICK
dep_tristate ' PDPI Lightning 4 gamecards' CONFIG_JOY_LIGHTNING $CONFIG_JOYSTICK
if [ "$CONFIG_PARPORT" != "n" ]; then
dep_tristate ' NES, SNES, PSX, Multisystem joysticks and gamepads' CONFIG_JOY_CONSOLE $CONFIG_JOYSTICK $CONFIG_PARPORT
dep_tristate ' Sega, Multisystem joysticks and gamepads' CONFIG_JOY_DB9 $CONFIG_JOYSTICK $CONFIG_PARPORT
dep_tristate ' TurboGraFX Multisystem joystick interface' CONFIG_JOY_TURBOGRAFX $CONFIG_JOYSTICK $CONFIG_PARPORT
fi
if [ "$CONFIG_AMIGA" = "y" ]; then
dep_tristate ' Amiga joysticks' CONFIG_JOY_AMIGA $CONFIG_JOYSTICK
mainmenu_option next_comment
comment 'Joysticks'
tristate 'Joystick support' CONFIG_JOYSTICK
if [ "$CONFIG_JOYSTICK" != "n" ]; then
dep_tristate ' Classic PC analog' CONFIG_JOY_ANALOG $CONFIG_JOYSTICK
dep_tristate ' FPGaming and MadCatz A3D' CONFIG_JOY_ASSASSIN $CONFIG_JOYSTICK
dep_tristate ' Gravis GrIP' CONFIG_JOY_GRAVIS $CONFIG_JOYSTICK
dep_tristate ' Logitech ADI' CONFIG_JOY_LOGITECH $CONFIG_JOYSTICK
dep_tristate ' Microsoft SideWinder' CONFIG_JOY_SIDEWINDER $CONFIG_JOYSTICK
dep_tristate ' ThrustMaster DirectConnect' CONFIG_JOY_THRUSTMASTER $CONFIG_JOYSTICK
dep_tristate ' Creative Labs Blaster' CONFIG_JOY_CREATIVE $CONFIG_JOYSTICK
dep_tristate ' PDPI Lightning 4 card' CONFIG_JOY_LIGHTNING $CONFIG_JOYSTICK
dep_tristate ' Trident 4DWave and Aureal Vortex gameport' CONFIG_JOY_PCI $CONFIG_JOYSTICK
dep_tristate ' Magellan and Space Mouse' CONFIG_JOY_MAGELLAN $CONFIG_JOYSTICK
dep_tristate ' SpaceTec SpaceOrb 360 and SpaceBall Avenger' CONFIG_JOY_SPACEORB $CONFIG_JOYSTICK
dep_tristate ' SpaceTec SpaceBall 4000 FLX' CONFIG_JOY_SPACEBALL $CONFIG_JOYSTICK
dep_tristate ' Logitech WingMan Warrior' CONFIG_JOY_WARRIOR $CONFIG_JOYSTICK
if [ "$CONFIG_PARPORT" != "n" ]; then
dep_tristate ' NES, SNES, PSX, N64, Multi' CONFIG_JOY_CONSOLE $CONFIG_JOYSTICK $CONFIG_PARPORT
dep_tristate ' Sega, Multi' CONFIG_JOY_DB9 $CONFIG_JOYSTICK $CONFIG_PARPORT
dep_tristate ' TurboGraFX interface' CONFIG_JOY_TURBOGRAFX $CONFIG_JOYSTICK $CONFIG_PARPORT
fi
if [ "$CONFIG_AMIGA" = "y" ]; then
dep_tristate ' Amiga joysticks' CONFIG_JOY_AMIGA $CONFIG_JOYSTICK
fi
fi
endmenu
#
# Makefile for the joystick drivers.
#
# Note! Dependencies are done automagically by 'make dep', which also
# removes any old dependencies. DON'T put your own dependencies here
# unless it's something special (ie not a .c file).
#
# Note 2! The CFLAGS definitions are now inherited from the
# parent makes..
#
O_TARGET := js.o
OX_OBJS :=
O_OBJS :=
MX_OBJS :=
M_OBJS :=
ifeq ($(CONFIG_JOYSTICK),y)
O_OBJS += joystick.o
OX_OBJS += joystick.o
else
ifeq ($(CONFIG_JOYSTICK),m)
M_OBJS += joystick.o
MX_OBJS += joystick.o
endif
endif
......@@ -37,11 +32,11 @@ else
endif
endif
ifeq ($(CONFIG_JOY_ASSASIN),y)
O_OBJS += joy-assasin.o
ifeq ($(CONFIG_JOY_ASSASSIN),y)
O_OBJS += joy-assassin.o
else
ifeq ($(CONFIG_JOY_ASSASIN),m)
M_OBJS += joy-assasin.o
ifeq ($(CONFIG_JOY_ASSASSIN),m)
M_OBJS += joy-assassin.o
endif
endif
......@@ -53,6 +48,14 @@ else
endif
endif
ifeq ($(CONFIG_JOY_CREATIVE),y)
O_OBJS += joy-creative.o
else
ifeq ($(CONFIG_JOY_CREATIVE),m)
M_OBJS += joy-creative.o
endif
endif
ifeq ($(CONFIG_JOY_DB9),y)
O_OBJS += joy-db9.o
else
......@@ -85,6 +88,22 @@ else
endif
endif
ifeq ($(CONFIG_JOY_MAGELLAN),y)
O_OBJS += joy-magellan.o
else
ifeq ($(CONFIG_JOY_MAGELLAN),m)
M_OBJS += joy-magellan.o
endif
endif
ifeq ($(CONFIG_JOY_PCI),y)
O_OBJS += joy-pci.o
else
ifeq ($(CONFIG_JOY_PCI),m)
M_OBJS += joy-pci.o
endif
endif
ifeq ($(CONFIG_JOY_SIDEWINDER),y)
O_OBJS += joy-sidewinder.o
else
......@@ -93,6 +112,22 @@ else
endif
endif
ifeq ($(CONFIG_JOY_SPACEORB),y)
O_OBJS += joy-spaceorb.o
else
ifeq ($(CONFIG_JOY_SPACEORB),m)
M_OBJS += joy-spaceorb.o
endif
endif
ifeq ($(CONFIG_JOY_SPACEBALL),y)
O_OBJS += joy-spaceball.o
else
ifeq ($(CONFIG_JOY_SPACEBALL),m)
M_OBJS += joy-spaceball.o
endif
endif
ifeq ($(CONFIG_JOY_THRUSTMASTER),y)
O_OBJS += joy-thrustmaster.o
else
......@@ -109,4 +144,12 @@ else
endif
endif
ifeq ($(CONFIG_JOY_WARRIOR),y)
O_OBJS += joy-warrior.o
else
ifeq ($(CONFIG_JOY_WARRIOR),m)
M_OBJS += joy-warrior.o
endif
endif
include $(TOPDIR)/Rules.make
/*
* joy-amiga.c Version 1.2
*
* Copyright (c) 1998 Vojtech Pavlik
* Copyright (c) 1998-1999 Vojtech Pavlik
*
* Sponsored by SuSE
*/
/*
......@@ -36,13 +38,14 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <asm/amigahw.h>
#include <linux/init.h>
static struct js_port* js_am_port __initdata = NULL;
MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
MODULE_PARM(js_am, "1-2i");
static int js_am[]={0,0};
static int __initdata js_am[] = { 0, 0 };
/*
* js_am_read() reads and Amiga joystick data.
......@@ -69,7 +72,7 @@ static int js_am_read(void *info, int **axes, int **buttons)
axes[0][0] = ((data >> 1) & 1) - ((data >> 9) & 1);
data = ~(data ^ (data << 1));
axes[0][0] = ((data >> 1) & 1) - ((data >> 9) & 1);
axes[0][1] = ((data >> 1) & 1) - ((data >> 9) & 1);
return 0;
}
......@@ -114,11 +117,14 @@ static void __init js_am_init_corr(struct js_corr **corr)
}
#ifndef MODULE
void __init js_am_setup(char *str, int *ints)
int __init js_am_setup(SETUP_PARAM)
{
int i;
SETUP_PARSE(2);
for (i = 0; i <= ints[0] && i < 2; i++) js_am[i] = ints[i+1];
return 1;
}
__setup("js_am=", js_am_setup);
#endif
#ifdef MODULE
......@@ -148,8 +154,8 @@ int __init js_am_init(void)
#ifdef MODULE
void cleanup_module(void)
{
while (js_am_port != NULL) {
if (js_am_port->devs[0] != NULL)
while (js_am_port) {
if (js_am_port->devs[0])
js_unregister_device(js_am_port->devs[0]);
js_am_port = js_unregister_port(js_am_port);
}
......
/*
* joy-analog.c Version 1.2
*
* Copyright (c) 1996-1998 Vojtech Pavlik
* Copyright (c) 1996-1999 Vojtech Pavlik
*
* Sponsored by SuSE
*/
/*
......@@ -30,15 +32,21 @@
*/
#include <asm/io.h>
#include <asm/param.h>
#include <asm/system.h>
#include <linux/config.h>
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/ioport.h>
#include <linux/joystick.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/string.h>
#include <linux/init.h>
#define JS_AN_MAX_TIME 3000
#define JS_AN_MAX_TIME 3000 /* 3 ms */
#define JS_AN_LOOP_TIME 2000 /* 2 t */
static int js_an_port_list[] __initdata = {0x201, 0};
static struct js_port* js_an_port __initdata = NULL;
......@@ -46,53 +54,102 @@ static struct js_port* js_an_port __initdata = NULL;
MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
MODULE_PARM(js_an, "2-24i");
static int js_an[]={-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0};
static int __initdata js_an[] = { -1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0 };
#include "joy-analog.h"
struct js_ax_info {
int io;
int speed;
int loop;
int timeout;
struct js_an_info an;
};
/*
* Time macros.
*/
#ifdef __i386__
#ifdef CONFIG_X86_TSC
#define GET_TIME(x) __asm__ __volatile__ ( "rdtsc" : "=a" (x) : : "dx" )
#define DELTA(x,y) ((x)-(y))
#define TIME_NAME "TSC"
#else
#define GET_TIME(x) do { outb(0, 0x43); x = inb(0x40); x |= inb(0x40) << 8; } while (0)
#define DELTA(x,y) ((y)-(x)+((y)<(x)?1193180L/HZ:0))
#define TIME_NAME "PIT"
#endif
#elif __alpha__
#define GET_TIME(x) __asm__ __volatile__ ( "rpcc %0" : "=r" (x) )
#define DELTA(x,y) ((x)-(y))
#define TIME_NAME "PCC"
#endif
#ifndef GET_TIME
#define FAKE_TIME
static unsigned long js_an_faketime = 0;
#define GET_TIME(x) do { x = js_an_faketime++; } while(0)
#define DELTA(x,y) ((x)-(y))
#define TIME_NAME "Unreliable"
#endif
/*
* js_an_read() reads analog joystick data.
*/
static int js_an_read(void *xinfo, int **axes, int **buttons)
{
struct js_an_info *info = xinfo;
struct js_ax_info *info = xinfo;
struct js_an_info *an = &info->an;
int io = info->io;
unsigned long flags;
unsigned char buf[4];
int time[4];
unsigned char u, v, a;
unsigned int t, t1;
unsigned int time[4];
unsigned char u, v, w;
unsigned int p, q, r, s, t;
int i, j;
int timeout;
int io = info->io;
timeout = (JS_AN_MAX_TIME * js_time_speed_a) >> 10;
info->buttons = (~inb(io) & JS_AN_BUTTONS_STD) >> 4;
an->buttons = ~inb(io) >> 4;
i = 0;
u = a = ((info->mask[0] | info->mask[1]) & JS_AN_AXES_STD) | (info->extensions & JS_AN_HAT_FCS)
| ((info->extensions & JS_AN_BUTTONS_PXY_XY) >> 2) | ((info->extensions & JS_AN_BUTTONS_PXY_UV) >> 4);
w = ((an->mask[0] | an->mask[1]) & JS_AN_AXES_STD) | (an->extensions & JS_AN_HAT_FCS)
| ((an->extensions & JS_AN_BUTTONS_PXY_XY) >> 2) | ((an->extensions & JS_AN_BUTTONS_PXY_UV) >> 4);
p = info->loop;
q = info->timeout;
__save_flags(flags);
__cli();
outb(0xff,io);
t = js_get_time_a();
GET_TIME(r);
__restore_flags(flags);
t = r;
v = w;
do {
v = inb(io) & a;
t1 = js_get_time_a();
if (u ^ v) {
time[i] = js_delta_a(t1,t);
s = t;
u = v;
__cli();
v = inb(io) & w;
GET_TIME(t);
__restore_flags(flags);
if ((u ^ v) && (DELTA(t,s) < p)) {
time[i] = t;
buf[i] = u ^ v;
u = v;
i++;
}
} while (v && js_delta_a(t1,t) < timeout);
} while (v && (i < 4) && (DELTA(t,r) < q));
for (--i; i >= 0; i--)
v <<= 4;
for (--i; i >= 0; i--) {
v |= buf[i];
for (j = 0; j < 4; j++)
if (buf[i] & (1 << j)) info->axes[j] = (time[i] << 10) / js_time_speed_a;
if (buf[i] & (1 << j)) an->axes[j] = (DELTA(time[i],r) << 10) / info->speed;
}
js_an_decode(info, axes, buttons);
js_an_decode(an, axes, buttons);
return 0;
return -(v != w);
}
/*
......@@ -115,13 +172,54 @@ static int js_an_close(struct js_dev *jd)
return 0;
}
/*
* js_an_calibrate_timer() calibrates the timer and computes loop
* and timeout values for a joystick port.
*/
static void __init js_an_calibrate_timer(struct js_ax_info *info)
{
unsigned int i, t, tx, t1, t2, t3;
unsigned long flags;
int io = info->io;
save_flags(flags);
cli();
GET_TIME(t1);
#ifdef FAKE_TIME
js_an_faketime += 830;
#endif
udelay(1000);
GET_TIME(t2);
GET_TIME(t3);
restore_flags(flags);
info->speed = DELTA(t2, t1) - DELTA(t3, t2);
tx = 1 << 30;
for(i = 0; i < 50; i++) {
save_flags(flags);
cli();
GET_TIME(t1);
for(t = 0; t < 50; t++) { inb(io); GET_TIME(t2); }
GET_TIME(t3);
restore_flags(flags);
udelay(i);
if ((t = DELTA(t2,t1) - DELTA(t3,t2)) < tx) tx = t;
}
info->loop = (JS_AN_LOOP_TIME * t) / 50000;
info->timeout = (JS_AN_MAX_TIME * info->speed) / 1000;
}
/*
* js_an_probe() probes for analog joysticks.
*/
static struct js_port __init *js_an_probe(int io, int mask0, int mask1, struct js_port *port)
{
struct js_an_info info;
struct js_ax_info info, *ax;
int i, numdev;
unsigned char u;
......@@ -129,7 +227,6 @@ static struct js_port __init *js_an_probe(int io, int mask0, int mask1, struct j
if (check_region(io, 1)) return port;
if (((u = inb(io)) & 3) == 3) return port;
outb(0xff,io);
u = inb(io);
udelay(JS_AN_MAX_TIME);
......@@ -138,31 +235,41 @@ static struct js_port __init *js_an_probe(int io, int mask0, int mask1, struct j
if (!u) return port;
if (u & 0xf0) return port;
if ((numdev = js_an_probe_devs(&info, u, mask0, mask1, port)) <= 0)
if ((numdev = js_an_probe_devs(&info.an, u, mask0, mask1, port)) <= 0)
return port;
info.io = io;
js_an_calibrate_timer(&info);
request_region(info.io, 1, "joystick (analog)");
port = js_register_port(port, &info, numdev, sizeof(struct js_an_info), js_an_read);
port = js_register_port(port, &info, numdev, sizeof(struct js_ax_info), js_an_read);
ax = port->info;
for (i = 0; i < numdev; i++)
printk(KERN_INFO "js%d: %s at %#x\n",
js_register_device(port, i, js_an_axes(i, &info), js_an_buttons(i, &info),
js_an_name(i, &info), js_an_open, js_an_close),
js_an_name(i, &info), info.io);
js_an_read(port->info, port->axes, port->buttons);
js_an_init_corr(port->info, port->axes, port->corr, 8);
printk(KERN_INFO "js%d: %s at %#x ["TIME_NAME" timer, %d %sHz clock, %d ns res]\n",
js_register_device(port, i, js_an_axes(i, &ax->an), js_an_buttons(i, &ax->an),
js_an_name(i, &ax->an), js_an_open, js_an_close),
js_an_name(i, &ax->an),
ax->io,
ax->speed > 10000 ? (ax->speed + 800) / 1000 : ax->speed,
ax->speed > 10000 ? "M" : "k",
ax->loop * 1000000000 / JS_AN_LOOP_TIME / ax->speed);
js_an_read(ax, port->axes, port->buttons);
js_an_init_corr(&ax->an, port->axes, port->corr, 8);
return port;
}
#ifndef MODULE
void __init js_an_setup(char *str, int *ints)
int __init js_an_setup(SETUP_PARAM)
{
int i;
SETUP_PARSE(24);
for (i = 0; i <= ints[0] && i < 24; i++) js_an[i] = ints[i+1];
return 1;
}
__setup("js_an=", js_an_setup);
#endif
#ifdef MODULE
......@@ -193,11 +300,11 @@ int __init js_an_init(void)
void cleanup_module(void)
{
int i;
struct js_an_info *info;
struct js_ax_info *info;
while (js_an_port != NULL) {
while (js_an_port) {
for (i = 0; i < js_an_port->ndevs; i++)
if (js_an_port->devs[i] != NULL)
if (js_an_port->devs[i])
js_unregister_device(js_an_port->devs[i]);
info = js_an_port->info;
release_region(info->io, 1);
......
/*
* joy-analog.h Version 1.2
*
* Copyright (c) 1996-1998 Vojtech Pavlik
* Copyright (c) 1996-1999 Vojtech Pavlik
*
* Sponsored by SuSE
*/
/*
* This file is designed to be included in any joystick driver
* that communicates with standard analog joysticks. This currently
* is: joy-analog.c, joy-assasin.c, and joy-lightning.c
* is: joy-analog.c, joy-assassin.c, and joy-lightning.c
*/
/*
......@@ -30,6 +32,8 @@
* Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic
*/
#include <linux/bitops.h>
#define JS_AN_AXES_STD 0x0f
#define JS_AN_BUTTONS_STD 0xf0
......@@ -53,7 +57,6 @@ static struct {
} js_an_hat_to_axis[] = {{ 0, 0}, { 0,-1}, { 1, 0}, { 0, 1}, {-1, 0}};
struct js_an_info {
int io;
unsigned char mask[2];
unsigned int extensions;
int axes[4];
......@@ -75,7 +78,7 @@ static void js_an_decode(struct js_an_info *info, int **axes, int **buttons)
if (info->mask[1] & JS_AN_BUTTONS_STD) buttons[1][0] = 0;
if (info->extensions & JS_AN_ANY_CHF) {
switch (info->buttons) {
switch (info->buttons & 0xf) {
case 0x1: buttons[0][0] = 0x01; break;
case 0x2: buttons[0][0] = 0x02; break;
case 0x4: buttons[0][0] = 0x04; break;
......@@ -134,19 +137,6 @@ static void js_an_decode(struct js_an_info *info, int **axes, int **buttons)
}
}
/*
* js_an_count_bits() counts set bits in a byte.
*/
static inline int js_an_count_bits(unsigned long c)
{
int i = 0;
while (c) {
i += c & 1;
c >>= 1;
}
return i;
}
/*
* js_an_init_corr() initializes the correction values for
......@@ -158,7 +148,7 @@ static void __init js_an_init_corr(struct js_an_info *info, int **axes, struct j
int i, j, t;
for (i = 0; i < 2; i++)
for (j = 0; j < js_an_count_bits(info->mask[i] & 0xf); j++) {
for (j = 0; j < hweight8(info->mask[i] & 0xf); j++) {
if ((j == 2 && (info->mask[i] & 0xb) == 0xb) ||
(j == 3 && (info->mask[i] & 0xf) == 0xf)) {
......@@ -175,9 +165,9 @@ static void __init js_an_init_corr(struct js_an_info *info, int **axes, struct j
corr[i][j].coef[3] = (1 << 29) / (t - (t >> 2) + 1);
}
i = js_an_count_bits(info->mask[0] & 0xf);
i = hweight8(info->mask[0] & 0xf);
for (j = i; j < i + (js_an_count_bits(info->extensions & JS_AN_HATS_ALL) << 1); j++) {
for (j = i; j < i + (hweight8(info->extensions & JS_AN_HATS_ALL) << 1); j++) {
corr[0][j].type = JS_CORR_BROKEN;
corr[0][j].prec = 0;
corr[0][j].coef[0] = 0;
......@@ -204,6 +194,7 @@ static int __init js_an_probe_devs(struct js_an_info *info, int exist, int mask0
info->mask[1] = mask1 & (exist | 0xf0) & ~info->mask[0];
info->extensions = (mask0 >> 8) & ((exist & JS_AN_HAT_FCS) | ((exist << 2) & JS_AN_BUTTONS_PXY_XY) |
((exist << 4) & JS_AN_BUTTONS_PXY_UV) | JS_AN_ANY_CHF);
if (info->extensions & JS_AN_BUTTONS_PXY) {
info->mask[0] &= ~((info->extensions & JS_AN_BUTTONS_PXY_XY) >> 2);
info->mask[0] &= ~((info->extensions & JS_AN_BUTTONS_PXY_UV) >> 4);
......@@ -212,7 +203,7 @@ static int __init js_an_probe_devs(struct js_an_info *info, int exist, int mask0
if (info->extensions & JS_AN_HAT_FCS) {
info->mask[0] &= ~JS_AN_HAT_FCS;
info->mask[1] = 0;
info->extensions &= ~(JS_AN_BUTTON_PXY_Y | JS_AN_BUTTON_PXY_U);
info->extensions &= ~(JS_AN_BUTTON_PXY_Y | JS_AN_BUTTON_PXY_V);
}
if (info->extensions & JS_AN_ANY_CHF) {
info->mask[0] |= 0xf0;
......@@ -233,8 +224,7 @@ static int __init js_an_probe_devs(struct js_an_info *info, int exist, int mask0
info->mask[0] = 0xcc; /* joystick 1 */
break;
case 0xf:
info->mask[0] = 0x33; /* joysticks 0 and 1 */
info->mask[1] = 0xcc;
info->mask[0] = 0xff; /* 4-axis 4-button joystick */
break;
default:
printk(KERN_WARNING "joy-analog: Unknown joystick device detected "
......@@ -252,7 +242,7 @@ static int __init js_an_probe_devs(struct js_an_info *info, int exist, int mask0
static inline int js_an_axes(int i, struct js_an_info *info)
{
return js_an_count_bits(info->mask[i] & 0x0f) + js_an_count_bits(info->extensions & JS_AN_HATS_ALL) * 2;
return hweight8(info->mask[i] & 0x0f) + hweight8(info->extensions & JS_AN_HATS_ALL) * 2;
}
/*
......@@ -261,9 +251,9 @@ static inline int js_an_axes(int i, struct js_an_info *info)
static inline int js_an_buttons(int i, struct js_an_info *info)
{
return js_an_count_bits(info->mask[i] & 0xf0) +
return hweight8(info->mask[i] & 0xf0) +
(info->extensions & JS_AN_BUTTONS_CHF) * 2 +
js_an_count_bits(info->extensions & JS_AN_BUTTONS_PXY);
hweight8(info->extensions & JS_AN_BUTTONS_PXY);
}
/*
......@@ -276,13 +266,13 @@ static char __init *js_an_name(int i, struct js_an_info *info)
{
sprintf(js_an_name_buf, "Analog %d-axis %d-button",
js_an_count_bits(info->mask[i] & 0x0f),
hweight8(info->mask[i] & 0x0f),
js_an_buttons(i, info));
if (info->extensions & JS_AN_HATS_ALL)
sprintf(js_an_name_buf, "%s %d-hat",
js_an_name_buf,
js_an_count_bits(info->extensions & JS_AN_HATS_ALL));
hweight8(info->extensions & JS_AN_HATS_ALL));
strcat(js_an_name_buf, " joystick");
......@@ -291,7 +281,7 @@ static char __init *js_an_name(int i, struct js_an_info *info)
js_an_name_buf,
info->extensions & JS_AN_ANY_CHF ? " CHF" : "",
info->extensions & JS_AN_HAT_FCS ? " FCS" : "",
info->extensions & JS_AN_BUTTONS_PXY ? " XY-button" : "");
info->extensions & JS_AN_BUTTONS_PXY ? " XY/UV" : "");
return js_an_name_buf;
}
/*
* joy-assasin.c Version 1.2
* joy-assassin.c Version 1.2
*
* Copyright (c) 1998 Vojtech Pavlik
* Copyright (c) 1998-1999 Vojtech Pavlik
*
* Sponsored by SuSE
*/
/*
* This is a module for the Linux joystick driver, supporting
* joysticks using FP-Gaming's Assasin 3D protocol.
* joysticks using FP-Gaming's Assassin 3D protocol.
*/
/*
......@@ -38,13 +40,13 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/string.h>
#include <linux/init.h>
#define JS_AS_MAX_START 250
#define JS_AS_MAX_STROBE 50
#define JS_AS_MAX_TIME 2400
#define JS_AS_MAX_START 1000
#define JS_AS_DELAY_READ 3000
#define JS_AS_MAX_LENGTH 40
#define JS_AS_MODE_A3D 1 /* Assasin 3D */
#define JS_AS_MODE_A3D 1 /* Assassin 3D */
#define JS_AS_MODE_PAN 2 /* Panther */
#define JS_AS_MODE_OEM 3 /* Panther OEM version */
#define JS_AS_MODE_PXL 4 /* Panther XL */
......@@ -52,7 +54,7 @@
MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
MODULE_PARM(js_as, "2-24i");
static int js_as[]={-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0};
static int __initdata js_as[] = { -1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0 };
static int js_as_port_list[] __initdata = {0x201, 0};
static struct js_port* js_as_port __initdata = NULL;
......@@ -67,44 +69,33 @@ struct js_as_info {
};
/*
* js_as_read_packet() reads an Assasin 3D packet.
* js_as_read_packet() reads an Assassin 3D packet.
*/
static int js_as_read_packet(int io, int length, char *data)
{
unsigned char u, v;
int i;
unsigned int t, t1;
unsigned int t, p;
unsigned long flags;
int start = (js_time_speed * JS_AS_MAX_START) >> 10;
int strobe = (js_time_speed * JS_AS_MAX_STROBE) >> 10;
i = 0;
__save_flags(flags);
__cli();
outb(0xff,io);
u = inb(io);
t = js_get_time();
do {
v = inb(io);
t1 = js_get_time();
} while (u == v && js_delta(t1, t) < start);
t = t1;
outb(0xff,io);
v = inb(io);
t = p = JS_AS_MAX_START;
do {
v = inb(io);
t1 = js_get_time();
if ((u ^ v) & u & 0x10) {
while (t > 0 && i < length) {
t--;
u = v; v = inb(io);
if (~v & u & 0x10) {
data[i++] = v >> 5;
t = t1;
p = t = (p - t) << 3;
}
u = v;
} while (i < length && js_delta(t1,t) < strobe);
}
__restore_flags(flags);
......@@ -181,11 +172,8 @@ static int js_as_read(void *xinfo, int **axes, int **buttons)
if (info->rudder) axes[1][0] = info->an.axes[0];
return 0;
default:
printk("Error.\n");
return -1;
}
return -1;
}
/*
......@@ -254,7 +242,7 @@ static void __init js_as_pxl_init_corr(struct js_corr **corr, int **axes)
/*
* js_as_as_init_corr() initializes the correction values for
* the Panther and Assasin.
* the Panther and Assassin.
*/
static void __init js_as_as_init_corr(struct js_corr **corr)
......@@ -305,25 +293,27 @@ static struct js_port __init *js_as_probe(int io, int mask0, int mask1, struct j
if (io < 0) return port;
if (check_region(io, 1)) return port;
if (((u = inb(io)) & 3) == 3) return port;
outb(0xff,io);
if (!((inb(io) ^ u) & ~u & 0xf)) return port;
if (js_as_read_packet(io, 1, data) != 1) return port;
i = js_as_read_packet(io, JS_AS_MAX_LENGTH, data);
printk("%d\n", i);
if (!i) return port;
if (js_as_csum(data, i)) return port;
if (data[0] && data[0] <= 4) {
info->mode = data[0];
info->io = io;
request_region(io, 1, "joystick (assasin)");
request_region(io, 1, "joystick (assassin)");
port = js_register_port(port, info, 3, sizeof(struct js_as_info), js_as_read);
info = port->info;
} else {
printk(KERN_WARNING "joy-assasin: unknown joystick device detected "
printk(KERN_WARNING "joy-assassin: unknown joystick device detected "
"(io=%#x, id=%d), contact <vojtech@suse.cz>\n", io, data[0]);
return port;
}
udelay(JS_AS_MAX_TIME);
udelay(JS_AS_DELAY_READ);
if (info->mode == JS_AS_MODE_PXL) {
printk(KERN_INFO "js%d: MadCatz Panther XL at %#x\n",
......@@ -342,9 +332,9 @@ static struct js_port __init *js_as_probe(int io, int mask0, int mask1, struct j
}
switch (info->mode) {
case JS_AS_MODE_A3D: name = "FP-Gaming Assasin 3D"; break;
case JS_AS_MODE_A3D: name = "FP-Gaming Assassin 3D"; break;
case JS_AS_MODE_PAN: name = "MadCatz Panther"; break;
case JS_AS_MODE_OEM: name = "OEM Assasin 3D"; break;
case JS_AS_MODE_OEM: name = "OEM Assassin 3D"; break;
default: name = "This cannot happen"; break;
}
......@@ -374,11 +364,14 @@ static struct js_port __init *js_as_probe(int io, int mask0, int mask1, struct j
}
#ifndef MODULE
void __init js_as_setup(char *str, int *ints)
int __init js_as_setup(SETUP_PARAM)
{
int i;
SETUP_PARSE(24);
for (i = 0; i <= ints[0] && i < 24; i++) js_as[i] = ints[i+1];
return 1;
}
__setup("js_as=", js_as_setup);
#endif
#ifdef MODULE
......@@ -398,7 +391,7 @@ int __init js_as_init(void)
if (js_as_port) return 0;
#ifdef MODULE
printk(KERN_WARNING "joy-assasin: no joysticks found\n");
printk(KERN_WARNING "joy-assassin: no joysticks found\n");
#endif
return -ENODEV;
......@@ -410,9 +403,9 @@ void cleanup_module(void)
int i;
struct js_as_info *info;
while (js_as_port != NULL) {
while (js_as_port) {
for (i = 0; i < js_as_port->ndevs; i++)
if (js_as_port->devs[i] != NULL)
if (js_as_port->devs[i])
js_unregister_device(js_as_port->devs[i]);
info = js_as_port->info;
release_region(info->io, 1);
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -247,7 +247,18 @@ if [ "$CONFIG_NET_RADIO" = "y" ]; then
dep_tristate ' STRIP (Metricom starmode radio IP)' CONFIG_STRIP $CONFIG_INET
tristate ' AT&T WaveLAN & DEC RoamAbout DS support' CONFIG_WAVELAN
tristate ' Aironet Arlan 655 & IC2200 DS support' CONFIG_ARLAN
tristate ' Aironet 4500/4800 series adapters' CONFIG_AIRONET4500
if [ ! "$CONFIG_AIRONET4500" = "n" ]; then
dep_tristate ' Aironet 4500/4800 ISA/PCI/PNP/365 support ' CONFIG_AIRONET4500_NONCS $CONFIG_AIRONET4500
if [ ! "$CONFIG_AIRONET4500_NONCS" = "n" ]; then
bool ' Aironet 4500/4800 PNP support ' CONFIG_AIRONET4500_PNP $CONFIG_AIRONET4500_NONCS $CONFIG_AIRONET4500
bool ' Aironet 4500/4800 PCI support ' CONFIG_AIRONET4500_PCI $CONFIG_AIRONET4500_NONCS $CONFIG_AIRONET4500
bool ' Aironet 4500/4800 ISA broken support ' CONFIG_AIRONET4500_ISA $CONFIG_AIRONET4500_NONCS $CONFIG_AIRONET4500 $CONFIG_EXPERIMENTAL
bool ' Aironet 4500/4800 I365 broken support ' CONFIG_AIRONET4500_I365 $CONFIG_AIRONET4500_NONCS $CONFIG_AIRONET4500 $CONFIG_EXPERIMENTAL
fi
dep_tristate ' Aironet 4500/4800 PCMCIA support ' CONFIG_AIRONET4500_CS $CONFIG_AIRONET4500 $CONFIG_PCMCIA
dep_tristate ' Aironet 4500/4800 PROC interface ' CONFIG_AIRONET4500_PROC $CONFIG_AIRONET4500 m
fi
fi
endmenu
......
......@@ -27,7 +27,7 @@ MOD_LIST_NAME := NET_MODULES
# All of the (potential) objects that export symbols.
# This list comes from 'grep -l EXPORT_SYMBOL *.[hc]'.
export-objs := 8390.o arcnet.o arlan.o ppp_async.o \
export-objs := 8390.o arcnet.o arlan.o aironet4500_core.o aironet4500_card.o ppp_async.o \
ppp_generic.o slhc.o
ifeq ($(CONFIG_PCMCIA),y)
......@@ -97,6 +97,12 @@ else
endif
endif
obj-$(CONFIG_AIRONET4500) += aironet4500_core.o
obj-$(CONFIG_AIRONET4500_NONCS) += aironet4500_card.o
obj-$(CONFIG_AIRONET4500_PROC) += aironet4500_proc.o
obj-$(CONFIG_NET) += Space.o setup.o net_init.o loopback.o
obj-$(CONFIG_SEEQ8005) += seeq8005.o
obj-$(CONFIG_ETHERTAP) += ethertap.o
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -14,6 +14,7 @@ if [ "$CONFIG_NET_PCMCIA" = "y" ]; then
dep_tristate ' New Media PCMCIA support' CONFIG_PCMCIA_NMCLAN $CONFIG_PCMCIA
dep_tristate ' SMC 91Cxx PCMCIA support' CONFIG_PCMCIA_SMC91C92 $CONFIG_PCMCIA
dep_tristate ' Xircom 16-bit PCMCIA support' CONFIG_PCMCIA_XIRC2PS $CONFIG_PCMCIA
dep_tristate ' Aironet 4500/4800 PCMCIA support ' CONFIG_AIRONET4500_CS $CONFIG_AIRONET4500 $CONFIG_PCMCIA
if [ "$CONFIG_CARDBUS" = "y" ]; then
dep_tristate ' 3Com 3c575 CardBus support' CONFIG_PCMCIA_3C575 m
......
......@@ -35,6 +35,7 @@ obj-$(CONFIG_PCMCIA_XIRC2PS) += xirc2ps_cs.o
obj-$(CONFIG_PCMCIA_RAYCS) += ray_cs.o
obj-$(CONFIG_PCMCIA_NETWAVE) += netwave_cs.o
obj-$(CONFIG_PCMCIA_WAVELAN) += wavelan_cs.o
obj-$(CONFIG_AIRONET4500_CS) += aironet4500_cs.o
# Cardbus client drivers
obj-$(CONFIG_PCMCIA_3C575) += 3c575_cb.o
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -553,8 +553,7 @@ struct dentry * d_lookup(struct dentry * parent, struct qstr * name)
/*
* An insecure source has sent us a dentry, here we verify it.
*
* This is just to make knfsd able to have the dentry pointer
* in the NFS file handle.
* This is used by ncpfs in its readdir implementation.
*
* NOTE! Do _not_ dereference the pointers before we have
* validated them. We can test the pointer values, but we
......
......@@ -42,7 +42,8 @@ void ext2_put_inode (struct inode * inode)
*/
void ext2_delete_inode (struct inode * inode)
{
if (inode->i_ino == EXT2_ACL_IDX_INO ||
if (is_bad_inode(inode) ||
inode->i_ino == EXT2_ACL_IDX_INO ||
inode->i_ino == EXT2_ACL_DATA_INO)
return;
inode->u.ext2_i.i_dtime = CURRENT_TIME;
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment