summaryrefslogtreecommitdiffstats
path: root/drivers/sgi/char
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/sgi/char')
-rw-r--r--drivers/sgi/char/graphics.c81
1 files changed, 54 insertions, 27 deletions
diff --git a/drivers/sgi/char/graphics.c b/drivers/sgi/char/graphics.c
index 4ba6361b7..b7e69b243 100644
--- a/drivers/sgi/char/graphics.c
+++ b/drivers/sgi/char/graphics.c
@@ -3,8 +3,8 @@
*
* Author: Miguel de Icaza (miguel@nuclecu.unam.mx)
*
- * On IRIX, /dev/graphics is [57, 0]
- * /dev/opengl is [57, 1]
+ * On IRIX, /dev/graphics is [10, 146]
+ * /dev/opengl is [10, 147]
*
* From a mail with Mark J. Kilgard, /dev/opengl and /dev/graphics are
* the same thing, the use of /dev/graphics seems deprecated though.
@@ -37,9 +37,16 @@
/* The boards */
#include "newport.h"
+#ifdef PRODUCTION_DRIVER
+#define enable_gconsole()
+#define disable_gconsole()
+#endif
+
static struct graphics_ops cards [MAXCARDS];
static int boards;
+#define GRAPHICS_CARD(inode) 0
+
int
sgi_graphics_open (struct inode *inode, struct file *file)
{
@@ -50,7 +57,7 @@ int
sgi_graphics_ioctl (struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
unsigned int board;
- unsigned int minor = MINOR (inode->i_rdev);
+ unsigned int devnum = GRAPHICS_CARD (inode->i_rdev);
int i;
if ((cmd >= RRM_BASE) && (cmd <= RRM_CMD_LIMIT))
@@ -89,7 +96,7 @@ sgi_graphics_ioctl (struct inode *inode, struct file *file, unsigned int cmd, un
struct gfx_attach_board_args *att = (void *) arg;
void *vaddr;
int r;
-
+
i = verify_area (VERIFY_READ, (void *)arg, sizeof (struct gfx_attach_board_args));
if (i) return i;
@@ -102,8 +109,8 @@ sgi_graphics_ioctl (struct inode *inode, struct file *file, unsigned int cmd, un
* Otherwise we fail, we use this assumption in the mmap code
* below to find our board information.
*/
- if (board != minor){
- printk ("Parameter board does not match minor\n");
+ if (board != devnum){
+ printk ("Parameter board does not match the current board\n");
return -EINVAL;
}
@@ -123,6 +130,7 @@ sgi_graphics_ioctl (struct inode *inode, struct file *file, unsigned int cmd, un
PROT_READ|PROT_WRITE, MAP_FIXED|MAP_PRIVATE, 0);
if (r)
return r;
+
}
/* Strange, the real mapping seems to be done at GFX_ATTACH_BOARD,
@@ -131,29 +139,41 @@ sgi_graphics_ioctl (struct inode *inode, struct file *file, unsigned int cmd, un
case GFX_MAPALL:
return 0;
+ case GFX_LABEL:
+ return 0;
+
+ /* Version check
+ * for my IRIX 6.2 X server, this is what the kernel returns
+ */
+ case 1:
+ return 3;
+
/* Xsgi does not use this one, I assume minor is the board being queried */
case GFX_IS_MANAGED:
- if (minor > boards)
+ if (devnum > boards)
return -EINVAL;
- return (cards [minor].g_owner != 0);
+ return (cards [devnum].g_owner != 0);
+ default:
+ if (cards [devnum].g_ioctl)
+ return (*cards [devnum].g_ioctl)(devnum, cmd, arg);
- } /* ioctl switch (cmd) */
-
+ }
return -EINVAL;
}
int
sgi_graphics_close (struct inode *inode, struct file *file)
{
- int minor = MINOR (inode->i_rdev);
+ int board = GRAPHICS_CARD (inode->i_rdev);
/* Tell the rendering manager that one client is going away */
rrm_close (inode, file);
/* Was this file handle from the board owner?, clear it */
- if (current == cards [minor].g_owner){
- cards [minor].g_owner = 0;
+ if (current == cards [board].g_owner){
+ cards [board].g_owner = 0;
+ (*cards [board].g_reset_console)();
enable_gconsole ();
}
return 0;
@@ -167,26 +187,34 @@ unsigned long
sgi_graphics_nopage (struct vm_area_struct *vma, unsigned long address, int write_access)
{
unsigned long page;
- int board = MINOR (vma->vm_dentry->d_inode->i_rdev);
-
- printk ("Got a page fault for board %d\n", board);
-
- if (current == cards [board].g_user){
- printk ("Mhm, strange, graphics registers should be already mapped\n");
+ int board = GRAPHICS_CARD (vma->vm_dentry->d_inode->i_rdev);
- /* force a segfault */
- return 0;
- }
+#ifdef DEBUG_GRAPHICS
+ printk ("Got a page fault for board %d address=%lx guser=%lx\n", board, address,
+ cards [board].g_user);
+#endif
/* 1. figure out if another process has this mapped,
* and revoke the mapping in that case.
*/
- if (cards [board].g_user)
+ if (cards [board].g_user && cards [board].g_user != current){
+ /* FIXME: save graphics context here, dump it to rendering node? */
remove_mapping (cards [board].g_user, vma->vm_start, vma->vm_end);
-
+ }
+ cards [board].g_user = current;
+#if DEBUG_GRAPHICS
+ printk ("Registers: 0x%lx\n", cards [board].g_regs);
+ printk ("vm_start: 0x%lx\n", vma->vm_start);
+ printk ("address: 0x%lx\n", address);
+ printk ("diff: 0x%lx\n", (address - vma->vm_start));
+
+ printk ("page/pfn: 0x%lx\n", page);
+ printk ("TLB entry: %lx\n", pte_val (mk_pte (page + PAGE_OFFSET, PAGE_USERIO)));
+#endif
+
/* 2. Map this into the current process address space */
- page = ((cards [board].g_regs) + (vma->vm_start - address));
- return page >> PAGE_SHIFT;
+ page = ((cards [board].g_regs) + (address - vma->vm_start));
+ return page + PAGE_OFFSET;
}
/*
@@ -225,7 +253,6 @@ sgi_graphics_mmap (struct inode *inode, struct file *file, struct vm_area_struct
/* final setup */
vma->vm_dentry = dget (file->f_dentry);
- atomic_inc (&inode->i_count);
return 0;
}