Commit 726978f5 authored by Ralf Bächle's avatar Ralf Bächle Committed by Linus Torvalds

[PATCH] drivers/sgi update

This updates drivers/sgi by removing it :-)  With all the conceptually
wrong code which has was rewritten or should be rewritten or better
live elsewhere there just was no point in keeping this directory around
any longer.
parent 98ebe7d3
#
# Character device configuration
#
menu "SGI devices"
depends on SGI_IP22
config SGI_SERIAL
bool "SGI Zilog85C30 serial support"
help
If you want to use your SGI's built-in serial ports under Linux,
answer Y.
config SERIAL_CONSOLE
bool "Support for console on serial port"
depends on SGI_SERIAL
---help---
If you say Y here, it will be possible to use a serial port as the
system console (the system console is the device which receives all
kernel messages and warnings and which allows logins in single user
mode). This could be useful if some terminal or printer is connected
to that serial port.
Even if you say Y here, the currently visible virtual console
(/dev/tty0) will still be used as the system console by default, but
you can alter that using a kernel command line option such as
"console=ttyS1". (Try "man bootparam" or see the documentation of
your boot loader (lilo or loadlin) about how to pass options to the
kernel at boot time.)
If you don't have a VGA card installed and you say Y here, the
kernel will automatically use the first serial line, /dev/ttyS0, as
system console.
If unsure, say N.
config SGI_DS1286
bool "SGI DS1286 RTC support"
help
If you say Y here and create a character special file /dev/rtc with
major number 10 and minor number 135 using mknod ("man mknod"), you
will get access to the real time clock built into your computer.
Every SGI has such a clock built in. It reports status information
via the file /proc/rtc and its behaviour is set by various ioctls on
/dev/rtc.
config SGI_NEWPORT_GFX
tristate "SGI Newport Graphics support (EXPERIMENTAL)"
depends on EXPERIMENTAL
help
If you have an SGI machine and you want to compile the graphics
drivers, say Y here. This will include the code for the
/dev/graphics and /dev/gfx drivers into the kernel for supporting
virtualized access to your graphics hardware.
endmenu
#
# Makefile for the linux kernel.
#
#
# Character and Audio devices for SGI machines.
#
subdir-m += char
obj-y += char/
#
# Makefile for the linux kernel.
#
obj-y := newport.o shmiq.o sgicons.o usema.o streamable.o
obj-$(CONFIG_SGI_SERIAL) += sgiserial.o
obj-$(CONFIG_SGI_DS1286) += ds1286.o
obj-$(CONFIG_SGI_NEWPORT_GFX) += graphics.o rrm.o
This diff is collapsed.
/*
* This is a temporary measure, we should eventually migrate to
* Gert's generic graphic console code.
*/
#define cmapsz 8192
#define CHAR_HEIGHT 16
struct console_ops {
void (*set_origin)(unsigned short offset);
void (*hide_cursor)(void);
void (*set_cursor)(int currcons);
void (*get_scrmem)(int currcons);
void (*set_scrmem)(int currcons, long offset);
int (*set_get_cmap)(unsigned char *arg, int set);
void (*blitc)(unsigned short charattr, unsigned long addr);
void (*memsetw)(void *s, unsigned short c, unsigned int count);
void (*memcpyw)(unsigned short *to, unsigned short *from, unsigned int count);
};
void register_gconsole (struct console_ops *);
/* This points to the system console */
extern struct console_ops *gconsole;
extern void gfx_init (const char **name);
extern void __set_origin (unsigned short offset);
extern void hide_cursor (void);
extern unsigned char vga_font[];
extern void disable_gconsole (void);
extern void enable_gconsole (void);
/*
* gfx.c: support for SGI's /dev/graphics, /dev/opengl
*
* Author: Miguel de Icaza (miguel@nuclecu.unam.mx)
* Ralf Baechle (ralf@gnu.org)
* Ulf Carlsson (ulfc@bun.falkenberg.se)
*
* 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.
*
* The reason that the original SGI programmer had to use only one
* device for all the graphic cards on the system will remain a
* mistery for the rest of our lives. Why some ioctls take a board
* number and some others not? Mistery. Why do they map the hardware
* registers into the user address space with an ioctl instead of
* mmap? Mistery too. Why they did not use the standard way of
* making ioctl constants and instead sticked a random constant?
* Mistery too.
*
* We implement those misterious things, and tried not to think about
* the reasons behind them.
*/
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/miscdevice.h>
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/mman.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/smp_lock.h>
#include <asm/uaccess.h>
#include "gconsole.h"
#include "graphics.h"
#include "usema.h"
#include <asm/gfx.h>
#include <asm/rrm.h>
#include <asm/page.h>
#include <asm/pgtable.h>
#include <video/newport.h>
#define DEBUG
/* The boards */
extern struct graphics_ops *newport_probe (int, const char **);
static struct graphics_ops cards [MAXCARDS];
static int boards;
#define GRAPHICS_CARD(inode) 0
/*
void enable_gconsole(void) {};
void disable_gconsole(void) {};
*/
int
sgi_graphics_open (struct inode *inode, struct file *file)
{
struct newport_regs *nregs =
(struct newport_regs *) KSEG1ADDR(cards[0].g_regs);
newport_wait();
nregs->set.wrmask = 0xffffffff;
nregs->set.drawmode0 = (NPORT_DMODE0_DRAW | NPORT_DMODE0_BLOCK |
NPORT_DMODE0_DOSETUP | NPORT_DMODE0_STOPX |
NPORT_DMODE0_STOPY);
nregs->set.colori = 1;
nregs->set.xystarti = (0 << 16) | 0;
nregs->go.xyendi = (1280 << 16) | 1024;
return 0;
}
int
sgi_graphics_ioctl (struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
unsigned int board;
unsigned int devnum = GRAPHICS_CARD (inode->i_rdev);
int i;
if ((cmd >= RRM_BASE) && (cmd <= RRM_CMD_LIMIT))
return rrm_command (cmd-RRM_BASE, (void *) arg);
switch (cmd){
case GFX_GETNUM_BOARDS:
return boards;
case GFX_GETBOARD_INFO: {
struct gfx_getboardinfo_args *bia = (void *) arg;
void *dest_buf;
int max_len;
i = verify_area (VERIFY_READ, (void *) arg, sizeof (struct gfx_getboardinfo_args));
if (i) return i;
if (__get_user (board, &bia->board) ||
__get_user (dest_buf, &bia->buf) ||
__get_user (max_len, &bia->len))
return -EFAULT;
if (board >= boards)
return -EINVAL;
if (max_len < sizeof (struct gfx_getboardinfo_args))
return -EINVAL;
if (max_len > cards [board].g_board_info_len)
max_len = cards [boards].g_board_info_len;
i = verify_area (VERIFY_WRITE, dest_buf, max_len);
if (i) return i;
if (copy_to_user (dest_buf, cards [board].g_board_info, max_len))
return -EFAULT;
return max_len;
}
case GFX_ATTACH_BOARD: {
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;
if (__get_user (board, &att->board) ||
__get_user (vaddr, &att->vaddr))
return -EFAULT;
/* Ok for now we are assuming /dev/graphicsN -> head N even
* if the ioctl api suggests that this is not quite the case.
*
* Otherwise we fail, we use this assumption in the mmap code
* below to find our board information.
*/
if (board != devnum){
printk ("Parameter board does not match the current board\n");
return -EINVAL;
}
if (board >= boards)
return -EINVAL;
/* If it is the first opening it, then make it the board owner */
if (!cards [board].g_owner)
cards [board].g_owner = current;
/*
* Ok, we now call mmap on this file, which will end up calling
* sgi_graphics_mmap
*/
disable_gconsole ();
down_write(&current->mm->mmap_sem);
r = do_mmap (file, (unsigned long)vaddr,
cards[board].g_regs_size, PROT_READ|PROT_WRITE,
MAP_FIXED|MAP_PRIVATE, 0);
up_write(&current->mm->mmap_sem);
if (r)
return r;
}
/* Strange, the real mapping seems to be done at GFX_ATTACH_BOARD,
* GFX_MAPALL is not even used by IRIX X server
*/
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 (devnum > boards)
return -EINVAL;
return (cards [devnum].g_owner != 0);
default:
if (cards [devnum].g_ioctl)
return (*cards [devnum].g_ioctl)(devnum, cmd, arg);
}
return -EINVAL;
}
int
sgi_graphics_close (struct inode *inode, struct file *file)
{
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 [board].g_owner){
cards [board].g_owner = 0;
if (cards [board].g_reset_console)
(*cards [board].g_reset_console)();
enable_gconsole ();
}
return 0;
}
/*
* This is the core of the direct rendering engine.
*/
struct page *
sgi_graphics_nopage (struct vm_area_struct *vma, unsigned long address, int
no_share)
{
pgd_t *pgd; pmd_t *pmd; pte_t *pte;
int board = GRAPHICS_CARD (vma->vm_dentry->d_inode->i_rdev);
unsigned long virt_add, phys_add;
struct page * page;
#ifdef DEBUG
printk ("Got a page fault for board %d address=%lx guser=%lx\n", board,
address, (unsigned long) cards[board].g_user);
#endif
/* Figure out if another process has this mapped, and revoke the mapping
* in that case. */
if (cards[board].g_user && cards[board].g_user != current) {
/* FIXME: save graphics context here, dump it to rendering
* node? */
remove_mapping(vma, cards[board].g_user, vma->vm_start, vma->vm_end);
}
cards [board].g_user = current;
/* Map the physical address of the newport registers into the address
* space of this process */
virt_add = address & PAGE_MASK;
phys_add = cards[board].g_regs + virt_add - vma->vm_start;
remap_page_range(vma, virt_add, phys_add, PAGE_SIZE, vma->vm_page_prot);
pgd = pgd_offset(current->mm, address);
pmd = pmd_offset(pgd, address);
pte = pte_kmap_offset(pmd, address);
page = pte_page(*pte);
pte_kunmap(pte);
return page;
}
/*
* We convert a GFX ioctl for mapping hardware registers, in a nice sys_mmap
* call, which takes care of everything that must be taken care of.
*
*/
static struct vm_operations_struct graphics_mmap = {
.nopage = sgi_graphics_nopage, /* our magic no-page fault handler */
};
int
sgi_graphics_mmap (struct file *file, struct vm_area_struct *vma)
{
uint size;
size = vma->vm_end - vma->vm_start;
/* 1. Set our special graphic virtualizer */
vma->vm_ops = &graphics_mmap;
/* 2. Set the special tlb permission bits */
vma->vm_page_prot = PAGE_USERIO;
/* final setup */
vma->vm_file = file;
return 0;
}
#if 0
/* Do any post card-detection setup on graphics_ops */
static void
graphics_ops_post_init (int slot)
{
/* There is no owner for the card initially */
cards [slot].g_owner = (struct task_struct *) 0;
cards [slot].g_user = (struct task_struct *) 0;
}
#endif
struct file_operations sgi_graphics_fops = {
.ioctl = sgi_graphics_ioctl,
.mmap = sgi_graphics_mmap,
.open = sgi_graphics_open,
.release = sgi_graphics_close,
};
/* /dev/graphics */
static struct miscdevice dev_graphics = {
SGI_GRAPHICS_MINOR, "sgi-graphics", &sgi_graphics_fops
};
/* /dev/opengl */
static struct miscdevice dev_opengl = {
SGI_OPENGL_MINOR, "sgi-opengl", &sgi_graphics_fops
};
/* This is called later from the misc-init routine */
void __init gfx_register (void)
{
misc_register (&dev_graphics);
misc_register (&dev_opengl);
}
void __init gfx_init (const char **name)
{
#if 0
struct console_ops *console;
struct graphics_ops *g;
#endif
printk ("GFX INIT: ");
shmiq_init ();
usema_init ();
boards++;
#if 0
if ((g = newport_probe (boards, name)) != 0) {
cards [boards] = *g;
graphics_ops_post_init (boards);
boards++;
console = 0;
}
/* Add more graphic drivers here */
/* Keep passing console around */
#endif
if (boards > MAXCARDS)
printk (KERN_WARNING "Too many cards found on the system\n");
}
#ifdef MODULE
MODULE_LICENSE("GPL");
int init_module(void) {
static int initiated = 0;
printk("SGI Newport Graphics version %i.%i.%i\n",42,54,69);
if (!initiated++) {
shmiq_init();
usema_init();
printk("Adding first board\n");
boards++;
cards[0].g_regs = 0x1f0f0000;
cards[0].g_regs_size = sizeof (struct newport_regs);
}
printk("Boards: %d\n", boards);
misc_register (&dev_graphics);
misc_register (&dev_opengl);
return 0;
}
void cleanup_module(void) {
printk("Shutting down SGI Newport Graphics\n");
misc_deregister (&dev_graphics);
misc_deregister (&dev_opengl);
}
#endif
#define MAXCARDS 4
struct graphics_ops {
/* SGIism: Board owner, gets the shmiq requests from the kernel */
struct task_struct *g_owner;
/* Last process that got the graphics registers mapped */
struct task_struct *g_user;
/* Board info */
void *g_board_info;
int g_board_info_len;
/* These point to hardware registers that should be mapped with
* GFX_ATTACH_BOARD and the size of the information pointed to
*/
unsigned long g_regs;
int g_regs_size;
void (*g_save_context)(void *);
void (*g_restore_context)(void *);
void (*g_reset_console)(void);
int (*g_ioctl)(int device, int cmd, unsigned long arg);
};
void shmiq_init (void);
void streamable_init (void);
/*
* newport.c: context switching the newport graphics card and
* newport graphics support.
*
* Author: Miguel de Icaza
*/
#include <linux/errno.h>
#include <linux/sched.h>
#include <asm/types.h>
#include <asm/gfx.h>
#include <asm/ng1.h>
#include <asm/uaccess.h>
#include <video/newport.h>
#include <linux/module.h>
struct newport_regs *npregs;
EXPORT_SYMBOL(npregs);
/* Kernel routines for supporting graphics context switching */
void newport_save (void *y)
{
newport_ctx *x = y;
newport_wait ();
#define LOAD(val) x->val = npregs->set.val;
#define LOADI(val) x->val = npregs->set.val.word;
#define LOADC(val) x->val = npregs->cset.val;
LOAD(drawmode1);
LOAD(drawmode0);
LOAD(lsmode);
LOAD(lspattern);
LOAD(lspatsave);
LOAD(zpattern);
LOAD(colorback);
LOAD(colorvram);
LOAD(alpharef);
LOAD(smask0x);
LOAD(smask0y);
LOADI(_xstart);
LOADI(_ystart);
LOADI(_xend);
LOADI(_yend);
LOAD(xsave);
LOAD(xymove);
LOADI(bresd);
LOADI(bress1);
LOAD(bresoctinc1);
LOAD(bresrndinc2);
LOAD(brese1);
LOAD(bress2);
LOAD(aweight0);
LOAD(aweight1);
LOADI(colorred);
LOADI(coloralpha);
LOADI(colorgrn);
LOADI(colorblue);
LOADI(slopered);
LOADI(slopealpha);
LOADI(slopegrn);
LOADI(slopeblue);
LOAD(wrmask);
LOAD(hostrw0);
LOAD(hostrw1);
/* configregs */
LOADC(smask1x);
LOADC(smask1y);
LOADC(smask2x);
LOADC(smask2y);
LOADC(smask3x);
LOADC(smask3y);
LOADC(smask4x);
LOADC(smask4y);
LOADC(topscan);
LOADC(xywin);
LOADC(clipmode);
LOADC(config);
/* Mhm, maybe I am missing something, but it seems that
* saving/restoring the DCB is only a matter of saving these
* registers
*/
newport_bfwait ();
LOAD (dcbmode);
newport_bfwait ();
x->dcbdata0 = npregs->set.dcbdata0.byword;
newport_bfwait ();
LOAD(dcbdata1);
}
/*
* Importat things to keep in mind when restoring the newport context:
*
* 1. slopered register is stored as a 2's complete (s12.11);
* needs to be converted to a signed magnitude (s(8)12.11).
*
* 2. xsave should be stored after xstart.
*
* 3. None of the registers should be written with the GO address.
* (read the docs for more details on this).
*/
void newport_restore (void *y)
{
newport_ctx *x = y;
#define STORE(val) npregs->set.val = x->val
#define STOREI(val) npregs->set.val.word = x->val
#define STOREC(val) npregs->cset.val = x->val
newport_wait ();
STORE(drawmode1);
STORE(drawmode0);
STORE(lsmode);
STORE(lspattern);
STORE(lspatsave);
STORE(zpattern);
STORE(colorback);
STORE(colorvram);
STORE(alpharef);
STORE(smask0x);
STORE(smask0y);
STOREI(_xstart);
STOREI(_ystart);
STOREI(_xend);
STOREI(_yend);
STORE(xsave);
STORE(xymove);
STOREI(bresd);
STOREI(bress1);
STORE(bresoctinc1);
STORE(bresrndinc2);
STORE(brese1);
STORE(bress2);
STORE(aweight0);
STORE(aweight1);
STOREI(colorred);
STOREI(coloralpha);
STOREI(colorgrn);
STOREI(colorblue);
STOREI(slopered);
STOREI(slopealpha);
STOREI(slopegrn);
STOREI(slopeblue);
STORE(wrmask);
STORE(hostrw0);
STORE(hostrw1);
/* configregs */
STOREC(smask1x);
STOREC(smask1y);
STOREC(smask2x);
STOREC(smask2y);
STOREC(smask3x);
STOREC(smask3y);
STOREC(smask4x);
STOREC(smask4y);
STOREC(topscan);
STOREC(xywin);
STOREC(clipmode);
STOREC(config);
/* FIXME: restore dcb thingies */
}
int
newport_ioctl (int card, int cmd, unsigned long arg)
{
switch (cmd){
case NG1_SETDISPLAYMODE: {
struct ng1_setdisplaymode_args request;
if (copy_from_user (&request, (void *) arg, sizeof (request)))
return -EFAULT;
newport_wait ();
newport_bfwait ();
npregs->set.dcbmode = DCB_XMAP0 | XM9_CRS_FIFO_AVAIL |
DCB_DATAWIDTH_1 | R_DCB_XMAP9_PROTOCOL;
xmap9FIFOWait (npregs);
/* FIXME: timing is wrong, just be extracted from
* the per-board timing table. I still have to figure
* out where this comes from
*
* This is used to select the protocol used to talk to
* the xmap9. For now I am using 60, selecting the
* WSLOW_DCB_XMAP9_PROTOCOL.
*
* Robert Tray comments on this issue:
*
* cfreq refers to the frequency of the monitor
* (ie. the refresh rate). Our monitors run typically
* between 60 Hz and 76 Hz. But it will be as low as
* 50 Hz if you're displaying NTSC/PAL and as high as
* 120 Hz if you are runining in stereo mode. You
* might want to try the WSLOW values.
*/
xmap9SetModeReg (npregs, request.wid, request.mode, 60);
return 0;
}
case NG1_SET_CURSOR_HOTSPOT: {
struct ng1_set_cursor_hotspot request;
if (copy_from_user (&request, (void *) arg, sizeof (request)))
return -EFAULT;
/* FIXME: make request.xhot, request.yhot the hot spot */
return 0;
}
case NG1_SETGAMMARAMP0:
/* FIXME: load the gamma ramps :-) */
return 0;
}
return -EINVAL;
}
/*
* Linux Rendering Resource Manager
*
* Implements the SGI-compatible rendering resource manager.
* This takes care of implementing the virtualized video hardware
* access required for OpenGL direct rendering.
*
* Author: Miguel de Icaza (miguel@nuclecu.unam.mx)
*
* Fixes:
*/
#include <linux/module.h>
#include <asm/uaccess.h>
#include <asm/rrm.h>
int
rrm_open_rn (int rnid, void *arg)
{
return 0;
}
int
rrm_close_rn (int rnid, void *arg)
{
return 0;
}
int
rrm_bind_proc_to_rn (int rnid, void *arg)
{
return 0;
}
typedef int (*rrm_function )(void *arg);
struct {
int (*r_fn)(int rnid, void *arg);
int arg_size;
} rrm_functions [] = {
{ rrm_open_rn, sizeof (struct RRM_OpenRN) },
{ rrm_close_rn, sizeof (struct RRM_CloseRN) },
{ rrm_bind_proc_to_rn, sizeof (struct RRM_BindProcToRN) }
};
#define RRM_FUNCTIONS (sizeof (rrm_functions)/sizeof (rrm_functions [0]))
/* cmd is a number in the range [0..RRM_CMD_LIMIT-RRM_BASE] */
int
rrm_command (unsigned int cmd, void *arg)
{
int i, rnid;
if (cmd > RRM_FUNCTIONS){
printk ("Called unimplemented rrm ioctl: %d\n", cmd + RRM_BASE);
return -EINVAL;
}
i = verify_area (VERIFY_READ, arg, rrm_functions [cmd].arg_size);
if (i) return i;
if (__get_user (rnid, (int *) arg))
return -EFAULT;
return (*(rrm_functions [cmd].r_fn))(rnid, arg);
}
int
rrm_close (struct inode *inode, struct file *file)
{
/* This routine is invoked when the device is closed */
return 0;
}
EXPORT_SYMBOL(rrm_command);
EXPORT_SYMBOL(rrm_close);
/*
* sgicons.c: Setting up and registering console I/O on the SGI.
*
* Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
* Copyright (C) 1997 Miguel de Icaza (miguel@nuclecu.unam.mx)
*
* This implement a virtual console interface.
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/module.h>
#include <asm/uaccess.h>
#include "gconsole.h"
/* This is the system graphics console (the first adapter found) */
struct console_ops *gconsole = 0;
struct console_ops *real_gconsole = 0;
void
enable_gconsole (void)
{
if (!gconsole)
gconsole = real_gconsole;
}
void
disable_gconsole (void)
{
if (gconsole){
real_gconsole = gconsole;
gconsole = 0;
}
}
EXPORT_SYMBOL(disable_gconsole);
EXPORT_SYMBOL(enable_gconsole);
void
register_gconsole (struct console_ops *gc)
{
if (gconsole)
return;
gconsole = gc;
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/* $Id: streamable.c,v 1.10 2000/02/05 06:47:30 ralf Exp $
*
* streamable.c: streamable devices. /dev/gfx
* (C) 1997 Miguel de Icaza (miguel@nuclecu.unam.mx)
*
* Major 10 is the streams clone device. The IRIX Xsgi server just
* opens /dev/gfx and closes it inmediately.
*
*/
#include <linux/fs.h>
#include <linux/miscdevice.h>
#include <linux/sched.h>
#include <linux/kbd_kern.h>
#include <linux/vt_kern.h>
#include <linux/smp_lock.h>
#include <asm/uaccess.h>
#include <asm/shmiq.h>
#include <asm/keyboard.h>
#include "graphics.h"
extern struct kbd_struct kbd_table [MAX_NR_CONSOLES];
/* console number where forwarding is enabled */
int forward_chars;
/* To which shmiq this keyboard is assigned */
int kbd_assigned_device;
/* previous kbd_mode for the forward_chars terminal */
int kbd_prev_mode;
/* Fetchs the strioctl information from user space for I_STR ioctls */
int
get_sioc (struct strioctl *sioc, unsigned long arg)
{
int v;
v = verify_area (VERIFY_WRITE, (void *) arg, sizeof (struct strioctl));
if (v)
return v;
if (copy_from_user (sioc, (void *) arg, sizeof (struct strioctl)))
return -EFAULT;
v = verify_area (VERIFY_WRITE, (void *) sioc->ic_dp, sioc->ic_len);
if (v)
return v;
return 0;
}
/* /dev/gfx device */
static int
sgi_gfx_ioctl (struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
printk ("GFX: ioctl 0x%x %ld called\n", cmd, arg);
return 0;
return -EINVAL;
}
struct file_operations sgi_gfx_fops = {
.ioctl = sgi_gfx_ioctl,
};
static struct miscdevice dev_gfx = {
SGI_GFX_MINOR, "sgi-gfx", &sgi_gfx_fops
};
/* /dev/input/keyboard streams device */
static idevDesc sgi_kbd_desc = {
"keyboard", /* devName */
"KEYBOARD", /* devType */
240, /* nButtons */
0, /* nValuators */
0, /* nLEDs */
0, /* nStrDpys */
0, /* nIntDpys */
0, /* nBells */
IDEV_HAS_KEYMAP | IDEV_HAS_PCKBD
};
static int
sgi_kbd_sioc (idevInfo *dinfo, int cmd, int size, char *data, int *found)
{
*found = 1;
switch (cmd){
case IDEVINITDEVICE:
return 0;
case IDEVGETDEVICEDESC:
if (size >= sizeof (idevDesc)){
if (copy_to_user (data, &sgi_kbd_desc, sizeof (sgi_kbd_desc)))
return -EFAULT;
return 0;
}
return -EINVAL;
case IDEVGETKEYMAPDESC:
if (size >= sizeof (idevKeymapDesc)){
if (copy_to_user (data, "US", 3))
return -EFAULT;
return 0;
}
return -EINVAL;
}
*found = 0;
return -EINVAL;
}
static int
sgi_keyb_ioctl (struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
struct strioctl sioc;
int f, v;
/* IRIX calls I_PUSH on the opened device, go figure */
if (cmd == I_PUSH)
return 0;
if (cmd == I_STR){
v = get_sioc (&sioc, arg);
if (v)
return v;
/* Why like this? Because this is a sample piece of code
* that can be copied into other drivers and shows how to
* call a stock IRIX xxx_wioctl routine
*
* The NULL is supposed to be a idevInfo, right now we
* do not support this in our kernel.
*/
return sgi_kbd_sioc (NULL, sioc.ic_cmd, sioc.ic_len, sioc.ic_dp, &f);
}
if (cmd == SHMIQ_ON){
kbd_assigned_device = arg;
forward_chars = fg_console + 1;
kbd_prev_mode = kbd_table [fg_console].kbdmode;
kbd_table [fg_console].kbdmode = VC_RAW;
} else if (cmd == SHMIQ_OFF && forward_chars){
kbd_table [forward_chars-1].kbdmode = kbd_prev_mode;
forward_chars = 0;
} else
return -EINVAL;
return 0;
}
void
kbd_forward_char (int ch)
{
static struct shmqevent ev;
ev.data.flags = (ch & 0200) ? 0 : 1;
ev.data.which = ch;
ev.data.device = kbd_assigned_device + 0x11;
shmiq_push_event (&ev);
}
static int
sgi_keyb_open (struct inode *inode, struct file *file)
{
/* Nothing, but required by the misc driver */
return 0;
}
struct file_operations sgi_keyb_fops = {
.ioctl = sgi_keyb_ioctl,
.open = sgi_keyb_open,
};
static struct miscdevice dev_input_keyboard = {
SGI_STREAMS_KEYBOARD, "streams-keyboard", &sgi_keyb_fops
};
/* /dev/input/mouse streams device */
#define MOUSE_VALUATORS 2
static idevDesc sgi_mouse_desc = {
"mouse", /* devName */
"MOUSE", /* devType */
3, /* nButtons */
MOUSE_VALUATORS, /* nValuators */
0, /* nLEDs */
0, /* nStrDpys */
0, /* nIntDpys */
0, /* nBells */
0 /* flags */
};
static idevValuatorDesc mouse_default_valuator = {
200, /* hwMinRes */
200, /* hwMaxRes */
0, /* hwMinVal */
65000, /* hwMaxVal */
IDEV_EITHER, /* possibleModes */
IDEV_ABSOLUTE, /* default mode */
200, /* resolution */
0, /* minVal */
65000 /* maxVal */
};
static int mouse_opened;
static idevValuatorDesc mouse_valuators [MOUSE_VALUATORS];
int
sgi_mouse_open (struct inode *inode, struct file *file)
{
int i;
if (mouse_opened)
return -EBUSY;
mouse_opened = 1;
for (i = 0; i < MOUSE_VALUATORS; i++)
mouse_valuators [i] = mouse_default_valuator;
return 0;
}
static int
sgi_mouse_close (struct inode *inode, struct file *filp)
{
mouse_opened = 0;
return 0;
}
static int
sgi_mouse_sioc (idevInfo *dinfo, int cmd, int size, char *data, int *found)
{
*found = 1;
switch (cmd){
case IDEVINITDEVICE:
return 0;
case IDEVGETDEVICEDESC:
if (size >= sizeof (idevDesc)){
if (copy_to_user (data, &sgi_mouse_desc, sizeof (sgi_mouse_desc)))
return -EFAULT;
return 0;
}
return -EINVAL;
case IDEVGETVALUATORDESC: {
idevGetSetValDesc request, *ureq = (idevGetSetValDesc *) data;
if (size < sizeof (idevGetSetValDesc))
return -EINVAL;
if (copy_from_user (&request, data, sizeof (request)))
return -EFAULT;
if (request.valNum >= MOUSE_VALUATORS)
return -EINVAL;
if (copy_to_user ((void *)&ureq->desc,
(void *)&mouse_valuators [request.valNum],
sizeof (idevValuatorDesc)))
return -EFAULT;
return 0;
}
}
*found = 0;
return -EINVAL;
}
static int
sgi_mouse_ioctl (struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
struct strioctl sioc;
int f, v;
/* IRIX calls I_PUSH on the opened device, go figure */
switch (cmd){
case I_PUSH:
return 0;
case I_STR:
v = get_sioc (&sioc, arg);
if (v)
return v;
/* Why like this? Because this is a sample piece of code
* that can be copied into other drivers and shows how to
* call a stock IRIX xxx_wioctl routine
*
* The NULL is supposed to be a idevInfo, right now we
* do not support this in our kernel.
*/
return sgi_mouse_sioc (NULL, sioc.ic_cmd, sioc.ic_len, sioc.ic_dp, &f);
case SHMIQ_ON:
case SHMIQ_OFF:
return 0;
}
return 0;
}
struct file_operations sgi_mouse_fops = {
.ioctl = sgi_mouse_ioctl,
.open = sgi_mouse_open,
.release = sgi_mouse_close,
};
/* /dev/input/mouse */
static struct miscdevice dev_input_mouse = {
SGI_STREAMS_KEYBOARD, "streams-mouse", &sgi_mouse_fops
};
void
streamable_init (void)
{
if (misc_register (&dev_gfx) < 0) {
printk(KERN_ERR
"streamable: cannot register gfx misc device.\n");
return;
}
if (misc_register (&dev_input_keyboard) < 0) {
printk(KERN_ERR
"streamable: cannot register keyboard misc device.\n");
misc_deregister(&dev_gfx);
return;
}
if (misc_register (&dev_input_mouse) < 0) {
printk(KERN_ERR
"streamable: cannot register mouse misc device.\n");
misc_deregister(&dev_input_keyboard);
misc_deregister(&dev_gfx);
return;
}
printk ("streamable: misc devices registered (keyb:%d, gfx:%d)\n",
SGI_STREAMS_KEYBOARD, SGI_GFX_MINOR);
}
This diff is collapsed.
/* usema.h
*
* Copyright (C) 1996 Alex deVries <puffin@redhat.com>
*/
#ifndef _SGI_USEMA_H
#define _SGI_USEMA_H
void usema_init (void);
#endif
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