summaryrefslogtreecommitdiffstats
path: root/drivers/sbus/char
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1997-07-20 14:56:40 +0000
committerRalf Baechle <ralf@linux-mips.org>1997-07-20 14:56:40 +0000
commite308faf24f68e262d92d294a01ddca7a17e76762 (patch)
tree22c47cb315811834861f013067878ff664e95abd /drivers/sbus/char
parent30c6397ce63178fcb3e7963ac247f0a03132aca9 (diff)
Sync with Linux 2.1.46.
Diffstat (limited to 'drivers/sbus/char')
-rw-r--r--drivers/sbus/char/bwtwo.c12
-rw-r--r--drivers/sbus/char/cgfourteen.c11
-rw-r--r--drivers/sbus/char/cgsix.c65
-rw-r--r--drivers/sbus/char/cgthree.c11
-rw-r--r--drivers/sbus/char/creator.c604
-rw-r--r--drivers/sbus/char/fb.h15
-rw-r--r--drivers/sbus/char/leo.c41
-rw-r--r--drivers/sbus/char/openprom.c10
-rw-r--r--drivers/sbus/char/suncons.c89
-rw-r--r--drivers/sbus/char/sunfb.c20
-rw-r--r--drivers/sbus/char/sunkbd.c20
-rw-r--r--drivers/sbus/char/sunmouse.c2
-rw-r--r--drivers/sbus/char/sunserial.c11
-rw-r--r--drivers/sbus/char/sunserial.h2
-rw-r--r--drivers/sbus/char/tcx.c12
-rw-r--r--drivers/sbus/char/vfc_dev.c11
-rw-r--r--drivers/sbus/char/weitek.c11
17 files changed, 786 insertions, 161 deletions
diff --git a/drivers/sbus/char/bwtwo.c b/drivers/sbus/char/bwtwo.c
index ae81e1260..615fef33d 100644
--- a/drivers/sbus/char/bwtwo.c
+++ b/drivers/sbus/char/bwtwo.c
@@ -1,4 +1,4 @@
-/* $Id: bwtwo.c,v 1.16 1997/06/04 08:27:26 davem Exp $
+/* $Id: bwtwo.c,v 1.18 1997/07/17 02:21:43 davem Exp $
* bwtwo.c: bwtwo console driver
*
* Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx)
@@ -74,7 +74,8 @@ static int
bwtwo_mmap (struct inode *inode, struct file *file, struct vm_area_struct *vma,
long base, fbinfo_t *fb)
{
- uint size, map_offset, r;
+ uint size, r;
+ unsigned long map_offset;
int map_size;
map_size = size = vma->vm_end - vma->vm_start;
@@ -91,9 +92,10 @@ bwtwo_mmap (struct inode *inode, struct file *file, struct vm_area_struct *vma,
map_offset = get_phys ((unsigned long) fb->base);
r = io_remap_page_range (vma->vm_start, map_offset, map_size,
vma->vm_page_prot, fb->space);
- if (r) return -EAGAIN;
- vma->vm_inode = inode;
- atomic_inc(&inode->i_count);
+ if (r)
+ return -EAGAIN;
+
+ vma->vm_dentry = dget(file->f_dentry);
return 0;
}
diff --git a/drivers/sbus/char/cgfourteen.c b/drivers/sbus/char/cgfourteen.c
index 2cb4c21c9..40fb9fd70 100644
--- a/drivers/sbus/char/cgfourteen.c
+++ b/drivers/sbus/char/cgfourteen.c
@@ -1,4 +1,4 @@
-/* $Id: cgfourteen.c,v 1.22 1997/06/04 08:27:27 davem Exp $
+/* $Id: cgfourteen.c,v 1.24 1997/07/17 02:21:44 davem Exp $
* cgfourteen.c: Sun SparcStation console support.
*
* Copyright (C) 1995 Miguel de Icaza (miguel@nuclecu.unam.mx)
@@ -166,7 +166,7 @@ cg14_mmap (struct inode *inode, struct file *file,
struct vm_area_struct *vma, long base, fbinfo_t *fb)
{
uint size, page, r, map_size;
- uint map_offset = 0;
+ unsigned long map_offset = 0;
uint ram_size = fb->info.cg14.ramsize;
printk ("RAMSIZE=%d\n", ram_size);
@@ -269,11 +269,12 @@ cg14_mmap (struct inode *inode, struct file *file,
map_offset,
map_size, vma->vm_page_prot,
fb->space);
- if (r) return -EAGAIN;
+ if (r)
+ return -EAGAIN;
page += map_size;
}
- vma->vm_inode = inode;
- atomic_inc(&inode->i_count);
+
+ vma->vm_dentry = dget(file->f_dentry);
return 0;
}
diff --git a/drivers/sbus/char/cgsix.c b/drivers/sbus/char/cgsix.c
index e53fcf09e..825d49b4a 100644
--- a/drivers/sbus/char/cgsix.c
+++ b/drivers/sbus/char/cgsix.c
@@ -1,4 +1,4 @@
-/* $Id: cgsix.c,v 1.30 1997/06/04 08:27:28 davem Exp $
+/* $Id: cgsix.c,v 1.35 1997/07/17 02:21:45 davem Exp $
* cgsix.c: cgsix frame buffer driver
*
* Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx)
@@ -233,12 +233,33 @@ cg6_mmap (struct inode *inode, struct file *file, struct vm_area_struct *vma,
long base, fbinfo_t *fb)
{
uint size, page, r, map_size;
- uint map_offset = 0;
-
+ unsigned long map_offset = 0;
+
size = vma->vm_end - vma->vm_start;
if (vma->vm_offset & ~PAGE_MASK)
return -ENXIO;
+#ifdef __sparc_v9__
+ /* Try to align RAM */
+#define ALIGNMENT 0x80000
+ map_offset = vma->vm_offset + size;
+ if (vma->vm_offset <= CG6_RAM && map_offset >= CG6_RAM + fb->type.fb_size) {
+ struct vm_area_struct *vmm = find_vma(current->mm, vma->vm_start);
+ int alignment = ALIGNMENT - ((vma->vm_start + CG6_RAM - vma->vm_offset) & (ALIGNMENT - 1));
+ int sz = 0, fbsz;
+
+ if (alignment == ALIGNMENT) alignment = 0;
+ fbsz = ((fb->type.fb_size + ALIGNMENT - 1) & ~(ALIGNMENT - 1));
+ if (map_offset < CG6_RAM + fbsz)
+ sz = fbsz - map_offset + CG6_RAM;
+ if ((sz || alignment) && (!vmm || vmm->vm_start >= vma->vm_end + sz + alignment)) {
+ vma->vm_start += alignment;
+ vma->vm_end += alignment + sz;
+ }
+ }
+#undef ALIGNMENT
+#endif
+
/* To stop the swapper from even considering these pages */
vma->vm_flags |= FB_MMAP_VM_FLAGS;
@@ -247,7 +268,7 @@ cg6_mmap (struct inode *inode, struct file *file, struct vm_area_struct *vma,
switch (vma->vm_offset+page){
case CG6_TEC:
map_size = PAGE_SIZE;
- map_offset = get_phys ((unsigned long)fb->info.cg6.tec);
+ map_offset = get_phys ((unsigned long)fb->info.cg6.tec) & PAGE_MASK;
break;
case CG6_FBC:
map_size = PAGE_SIZE;
@@ -259,18 +280,25 @@ cg6_mmap (struct inode *inode, struct file *file, struct vm_area_struct *vma,
break;
case CG6_THC:
map_size = PAGE_SIZE;
- map_offset = get_phys ((unsigned long)fb->info.cg6.thc);
+ map_offset = get_phys ((unsigned long)fb->info.cg6.thc) & PAGE_MASK;
break;
case CG6_BTREGS:
map_size = PAGE_SIZE;
map_offset = get_phys ((unsigned long)fb->info.cg6.bt);
break;
+
+ /* For Ultra, make sure the following two are right.
+ * The above two happen to work out (for example FBC and
+ * TEC will get mapped by one I/O page mapping because
+ * of the 8192 byte page size, same for FHC/THC. -DaveM
+ */
+
case CG6_DHC:
- map_size = PAGE_SIZE * 40;
+ map_size = /* PAGE_SIZE * 40 */ (4096 * 40);
map_offset = get_phys ((unsigned long)fb->info.cg6.dhc);
break;
case CG6_ROM:
- map_size = PAGE_SIZE * 16;
+ map_size = /* PAGE_SIZE * 16 */ (4096 * 16);
map_offset = get_phys ((unsigned long)fb->info.cg6.rom);
break;
case CG6_RAM:
@@ -293,11 +321,12 @@ cg6_mmap (struct inode *inode, struct file *file, struct vm_area_struct *vma,
map_offset,
map_size, vma->vm_page_prot,
fb->space);
- if (r) return -EAGAIN;
+ if (r)
+ return -EAGAIN;
page += map_size;
}
- vma->vm_inode = inode;
- atomic_inc(&inode->i_count);
+
+ vma->vm_dentry = dget(file->f_dentry);
return 0;
}
@@ -449,14 +478,22 @@ __initfunc(void cg6_setup (fbinfo_t *fb, int slot, u32 cg6, int cg6_io))
sizeof (struct bt_regs), "cgsix_dac", cg6_io, 0);
cg6info->fhc = sparc_alloc_io (cg6+CG6_FHC_OFFSET, 0,
sizeof (int), "cgsix_fhc", cg6_io, 0);
+#if PAGE_SHIFT <= 12
cg6info->thc = sparc_alloc_io (cg6+CG6_THC_OFFSET, 0,
sizeof (struct cg6_thc), "cgsix_thc", cg6_io, 0);
+#else
+ cg6info->thc = (struct cg6_thc *)(((char *)cg6info->fhc)+0x1000);
+#endif
+ cg6info->fbc = sparc_alloc_io (cg6+CG6_FBC_OFFSET, 0,
+ 0x1000, "cgsix_fbc", cg6_io, 0);
+#if PAGE_SHIFT <= 12
cg6info->tec = sparc_alloc_io (cg6+CG6_TEC_OFFSET, 0,
sizeof (struct cg6_tec), "cgsix_tec", cg6_io, 0);
+#else
+ cg6info->tec = (struct cg6_tec *)(((char *)cg6info->fbc)+0x1000);
+#endif
cg6info->dhc = sparc_alloc_io (cg6+CG6_DHC_OFFSET, 0,
0x40000, "cgsix_dhc", cg6_io, 0);
- cg6info->fbc = sparc_alloc_io (cg6+CG6_FBC_OFFSET, 0,
- 0x1000, "cgsix_fbc", cg6_io, 0);
cg6info->rom = sparc_alloc_io (cg6+CG6_ROM_OFFSET, 0,
0x10000, "cgsix_rom", cg6_io, 0);
if (!fb->base) {
@@ -477,6 +514,10 @@ __initfunc(void cg6_setup (fbinfo_t *fb, int slot, u32 cg6, int cg6_io))
cg6info->bt->addr = 0x07 << 24;
cg6info->bt->control = 0x00 << 24;
+#ifdef __sparc_v9__
+ printk("VA %016lx ", fb->base);
+#endif
+
printk("TEC Rev %x ",
(cg6info->thc->thc_misc >> CG6_THC_MISC_REV_SHIFT) &
CG6_THC_MISC_REV_MASK);
diff --git a/drivers/sbus/char/cgthree.c b/drivers/sbus/char/cgthree.c
index 0e1446c0e..aea1bff32 100644
--- a/drivers/sbus/char/cgthree.c
+++ b/drivers/sbus/char/cgthree.c
@@ -1,4 +1,4 @@
-/* $Id: cgthree.c,v 1.21 1997/06/04 08:27:29 davem Exp $
+/* $Id: cgthree.c,v 1.23 1997/07/17 02:21:46 davem Exp $
* cgtree.c: cg3 frame buffer driver
*
* Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx)
@@ -96,7 +96,7 @@ cg3_mmap (struct inode *inode, struct file *file, struct vm_area_struct *vma,
long base, fbinfo_t *fb)
{
uint size, page, r, map_size;
- uint map_offset = 0;
+ unsigned long map_offset = 0;
size = vma->vm_end - vma->vm_start;
if (vma->vm_offset & ~PAGE_MASK)
@@ -128,11 +128,12 @@ cg3_mmap (struct inode *inode, struct file *file, struct vm_area_struct *vma,
map_offset,
map_size, vma->vm_page_prot,
fb->space);
- if (r) return -EAGAIN;
+ if (r)
+ return -EAGAIN;
page += map_size;
}
- vma->vm_inode = inode;
- atomic_inc(&inode->i_count);
+
+ vma->vm_dentry = dget(file->f_dentry);
return 0;
}
diff --git a/drivers/sbus/char/creator.c b/drivers/sbus/char/creator.c
index 4ff2caf31..086f9b40e 100644
--- a/drivers/sbus/char/creator.c
+++ b/drivers/sbus/char/creator.c
@@ -1,13 +1,13 @@
-/*
- * creator.c: Linux/Sun Ultra Creator console support.
- *
- * Copyright (C) 1997 MIguel de Icaza (miguel@nuclecu.unam.mx)
+/* $Id: creator.c,v 1.7 1997/07/17 02:21:47 davem Exp $
+ * creator.c: Creator/Creator3D frame buffer driver
*
+ * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
*/
#include <linux/kd.h>
#include <linux/tty.h>
#include <linux/malloc.h>
#include <linux/proc_fs.h>
+#include <linux/config.h>
#include <asm/sbus.h>
#include <asm/io.h>
@@ -20,31 +20,575 @@
#include <linux/selection.h>
#include <linux/console_struct.h>
#include "fb.h"
+#include "cg_common.h"
+
+#define FFB_SFB8R_VOFF 0x00000000
+#define FFB_SFB8G_VOFF 0x00400000
+#define FFB_SFB8B_VOFF 0x00800000
+#define FFB_SFB8X_VOFF 0x00c00000
+#define FFB_SFB32_VOFF 0x01000000
+#define FFB_SFB64_VOFF 0x02000000
+#define FFB_FBC_REGS_VOFF 0x04000000
+#define FFB_BM_FBC_REGS_VOFF 0x04002000
+#define FFB_DFB8R_VOFF 0x04004000
+#define FFB_DFB8G_VOFF 0x04404000
+#define FFB_DFB8B_VOFF 0x04804000
+#define FFB_DFB8X_VOFF 0x04c04000
+#define FFB_DFB24_VOFF 0x05004000
+#define FFB_DFB32_VOFF 0x06004000
+#define FFB_DFB422A_VOFF 0x07004000 /* DFB 422 mode write to A */
+#define FFB_DFB422AD_VOFF 0x07804000 /* DFB 422 mode with line doubling */
+#define FFB_DFB24B_VOFF 0x08004000 /* DFB 24bit mode write to B */
+#define FFB_DFB422B_VOFF 0x09004000 /* DFB 422 mode write to B */
+#define FFB_DFB422BD_VOFF 0x09804000 /* DFB 422 mode with line doubling */
+#define FFB_SFB16Z_VOFF 0x0a004000 /* 16bit mode Z planes */
+#define FFB_SFB8Z_VOFF 0x0a404000 /* 8bit mode Z planes */
+#define FFB_SFB422_VOFF 0x0ac04000 /* SFB 422 mode write to A/B */
+#define FFB_SFB422D_VOFF 0x0b404000 /* SFB 422 mode with line doubling */
+#define FFB_FBC_KREGS_VOFF 0x0bc04000
+#define FFB_DAC_VOFF 0x0bc06000
+#define FFB_PROM_VOFF 0x0bc08000
+#define FFB_EXP_VOFF 0x0bc18000
+
+#define FFB_SFB8R_POFF 0x04000000
+#define FFB_SFB8G_POFF 0x04400000
+#define FFB_SFB8B_POFF 0x04800000
+#define FFB_SFB8X_POFF 0x04c00000
+#define FFB_SFB32_POFF 0x05000000
+#define FFB_SFB64_POFF 0x06000000
+#define FFB_FBC_REGS_POFF 0x00600000
+#define FFB_BM_FBC_REGS_POFF 0x00600000
+#define FFB_DFB8R_POFF 0x01000000
+#define FFB_DFB8G_POFF 0x01400000
+#define FFB_DFB8B_POFF 0x01800000
+#define FFB_DFB8X_POFF 0x01c00000
+#define FFB_DFB24_POFF 0x02000000
+#define FFB_DFB32_POFF 0x03000000
+#define FFB_FBC_KREGS_POFF 0x00610000
+#define FFB_DAC_POFF 0x00400000
+#define FFB_PROM_POFF 0x00000000
+#define FFB_EXP_POFF 0x00200000
+
+#define FFB_Y_BYTE_ADDR_SHIFT 11
+#define FFB_Y_ADDR_SHIFT 13
+
+#define FFB_PPC_ACE_DISABLE 1
+#define FFB_PPC_ACE_AUX_ADD 3
+#define FFB_PPC_ACE_SHIFT 18
+#define FFB_PPC_DCE_DISABLE 2
+#define FFB_PPC_DCE_SHIFT 16
+#define FFB_PPC_ABE_DISABLE 2
+#define FFB_PPC_ABE_SHIFT 14
+#define FFB_PPC_VCE_DISABLE 1
+#define FFB_PPC_VCE_2D 2
+#define FFB_PPC_VCE_SHIFT 12
+#define FFB_PPC_APE_DISABLE 2
+#define FFB_PPC_APE_SHIFT 10
+#define FFB_PPC_CS_VARIABLE 2
+#define FFB_PPC_CS_SHIFT 0
+
+#define FFB_FBC_WB_A 1
+#define FFB_FBC_WB_SHIFT 29
+#define FFB_FBC_PGE_MASK 3
+#define FFB_FBC_BE_SHIFT 4
+#define FFB_FBC_GE_SHIFT 2
+#define FFB_FBC_RE_SHIFT 0
+
+#define FFB_ROP_NEW 0x83
+#define FFB_ROP_RGB_SHIFT 0
+
+#define FFB_UCSR_FIFO_MASK 0x00000fff
+#define FFB_UCSR_RP_BUSY 0x02000000
+
+struct ffb_fbc {
+ u8 xxx1[0x200];
+ volatile u32 ppc;
+ u8 xxx2[0x50];
+ volatile u32 fbc;
+ volatile u32 rop;
+ u8 xxx3[0x34];
+ volatile u32 pmask;
+ u8 xxx4[12];
+ volatile u32 clip0min;
+ volatile u32 clip0max;
+ volatile u32 clip1min;
+ volatile u32 clip1max;
+ volatile u32 clip2min;
+ volatile u32 clip2max;
+ volatile u32 clip3min;
+ volatile u32 clip3max;
+ u8 xxx5[0x3c];
+ volatile u32 unk1;
+ u8 xxx6[0x500];
+ volatile u32 unk2;
+ u8 xxx7[0xfc];
+ volatile u32 ucsr;
+};
+
+struct ffb_dac {
+ volatile u32 type;
+ volatile u32 value;
+ volatile u32 type2;
+ volatile u32 value2;
+};
+
+static void
+ffb_restore_palette (fbinfo_t *fbinfo)
+{
+}
+
+static void ffb_blitc(unsigned short, int, int);
+static void ffb_setw(int, int, unsigned short, int);
+static void ffb_cpyw(int, int, unsigned short *, int);
+static void ffb_fill(int, int, int *);
+
+static struct {
+ unsigned long voff;
+ unsigned long poff;
+ unsigned long size;
+} ffbmmap [] = {
+ { FFB_SFB8R_VOFF, FFB_SFB8R_POFF, 0x0400000 },
+ { FFB_SFB8G_VOFF, FFB_SFB8G_POFF, 0x0400000 },
+ { FFB_SFB8B_VOFF, FFB_SFB8B_POFF, 0x0400000 },
+ { FFB_SFB8X_VOFF, FFB_SFB8X_POFF, 0x0400000 },
+ { FFB_SFB32_VOFF, FFB_SFB32_POFF, 0x1000000 },
+ { FFB_SFB64_VOFF, FFB_SFB64_POFF, 0x2000000 },
+ { FFB_FBC_REGS_VOFF, FFB_FBC_REGS_POFF, 0x0002000 },
+ { FFB_BM_FBC_REGS_VOFF, FFB_BM_FBC_REGS_POFF, 0x0002000 },
+ { FFB_DFB8R_VOFF, FFB_DFB8R_POFF, 0x0400000 },
+ { FFB_DFB8G_VOFF, FFB_DFB8G_POFF, 0x0400000 },
+ { FFB_DFB8B_VOFF, FFB_DFB8B_POFF, 0x0400000 },
+ { FFB_DFB8X_VOFF, FFB_DFB8X_POFF, 0x0400000 },
+ { FFB_DFB24_VOFF, FFB_DFB24_POFF, 0x1000000 },
+ { FFB_DFB32_VOFF, FFB_DFB32_POFF, 0x1000000 },
+ { FFB_FBC_KREGS_VOFF, FFB_FBC_KREGS_POFF, 0x0002000 },
+ { FFB_DAC_VOFF, FFB_DAC_POFF, 0x0002000 },
+ { FFB_PROM_VOFF, FFB_PROM_POFF, 0x0010000 },
+ { FFB_EXP_VOFF, FFB_EXP_POFF, 0x0002000 }
+};
+
+/* Ugh: X wants to mmap a bunch of cute stuff at the same time :-( */
+/* So, we just mmap the things that are being asked for */
+static int
+ffb_mmap (struct inode *inode, struct file *file, struct vm_area_struct *vma,
+ long base, fbinfo_t *fb)
+{
+ uint size, page, r, map_size;
+ unsigned long map_offset = 0;
+ int i;
+
+ size = vma->vm_end - vma->vm_start;
+ if (vma->vm_offset & ~PAGE_MASK)
+ return -ENXIO;
+
+ /* Try to align RAM */
+#define ALIGNMENT 0x400000
+ map_offset = vma->vm_offset + size;
+ if (vma->vm_offset < FFB_FBC_REGS_VOFF) {
+ struct vm_area_struct *vmm = find_vma(current->mm, vma->vm_start);
+ int alignment = ALIGNMENT - ((vma->vm_start - vma->vm_offset) & (ALIGNMENT - 1));
+
+ if (alignment == ALIGNMENT) alignment = 0;
+ if (alignment && (!vmm || vmm->vm_start >= vma->vm_end + alignment)) {
+ vma->vm_start += alignment;
+ vma->vm_end += alignment;
+ }
+ }
+#undef ALIGNMENT
+
+ /* To stop the swapper from even considering these pages */
+ vma->vm_flags |= FB_MMAP_VM_FLAGS;
+
+ /* Each page, see which map applies */
+ for (page = 0; page < size; ){
+ map_size = 0;
+ for (i = 0; i < sizeof (ffbmmap) / sizeof (ffbmmap[0]); i++)
+ if (ffbmmap[i].voff == vma->vm_offset+page) {
+ map_size = ffbmmap[i].size;
+ map_offset = fb->info.ffb.physbase + ffbmmap[i].poff;
+ }
+
+ if (!map_size){
+ page += PAGE_SIZE;
+ continue;
+ }
+ if (page + map_size > size)
+ map_size = size - page;
+ r = io_remap_page_range (vma->vm_start+page,
+ map_offset,
+ map_size, vma->vm_page_prot, 0);
+ if (r)
+ return -EAGAIN;
+ page += map_size;
+ }
+
+ vma->vm_dentry = dget(file->f_dentry);
+ return 0;
+}
+
+/* XXX write body of these two... */
+static inline int
+ffb_wid_get (fbinfo_t *fb, struct fb_wid_list *wl)
+{
+ struct fb_wid_item *wi;
+ struct fb_wid_list wlt;
+ struct fb_wid_item wit[30];
+ char *km = NULL;
+ int i, j;
+ u32 l;
+ int err;
+
+#ifdef CONFIG_SPARC32_COMPAT
+ if (current->tss.flags & SPARC_FLAG_32BIT) {
+ if (copy_from_user (&wlt, wl, 2 * sizeof (__u32)) ||
+ __get_user ((long)wlt.wl_list, (((__u32 *)wl)+2)))
+ return -EFAULT;
+ } else
+#endif
+ if (copy_from_user (&wlt, wl, sizeof (wlt)))
+ return -EFAULT;
+ if (wlt.wl_count <= 30) {
+ if (copy_from_user (wit, wlt.wl_list, wlt.wl_count * sizeof(*wi)))
+ return -EFAULT;
+ wi = wit;
+ } else if (wlt.wl_count > 120)
+ return -EINVAL;
+ else {
+ wi = (struct fb_wid_item *) km = kmalloc (wlt.wl_count * sizeof (*wi), GFP_KERNEL);
+ if (!wi) return -ENOMEM;
+ if (copy_from_user (wi, wlt.wl_list, wlt.wl_count * sizeof(*wi))) {
+ kfree (wi);
+ return -EFAULT;
+ }
+ }
+ for (i = 0; i < wlt.wl_count; i++, wi++) {
+ switch (wi->wi_type) {
+ case FB_WID_DBL_8: j = (wi->wi_index & 0xf) + 0x40; break;
+ case FB_WID_DBL_24: j = wi->wi_index & 0x3f; break;
+ default: return -EINVAL;
+ }
+ wi->wi_attrs = 0xffff;
+ for (j = 0; j < 32; j++)
+ wi->wi_values [j] = 0;
+ }
+ err = 0;
+ if (copy_to_user (wlt.wl_list, km ? km : (char *)wit, wlt.wl_count * sizeof (*wi)))
+ err = -EFAULT;
+ if (km)
+ kfree (km);
+ return err;
+}
+
+static inline int
+ffb_wid_put (fbinfo_t *fb, struct fb_wid_list *wl)
+{
+ struct fb_wid_item *wi;
+ struct fb_wid_list wlt;
+ struct fb_wid_item wit[30];
+ char *km = NULL;
+ int i, j;
+ u32 l;
+
+#ifdef CONFIG_SPARC32_COMPAT
+ if (current->tss.flags & SPARC_FLAG_32BIT) {
+ if (copy_from_user (&wlt, wl, 2 * sizeof (__u32)) ||
+ __get_user ((long)wlt.wl_list, (((__u32 *)wl)+2)))
+ return -EFAULT;
+ } else
+#endif
+ if (copy_from_user (&wlt, wl, sizeof (wlt)))
+ return -EFAULT;
+ if (wlt.wl_count <= 30) {
+ if (copy_from_user (wit, wlt.wl_list, wlt.wl_count * sizeof(*wi)))
+ return -EFAULT;
+ wi = wit;
+ } else if (wlt.wl_count > 120)
+ return -EINVAL;
+ else {
+ wi = (struct fb_wid_item *) km = kmalloc (wlt.wl_count * sizeof (*wi), GFP_KERNEL);
+ if (!wi) return -ENOMEM;
+ if (copy_from_user (wi, wlt.wl_list, wlt.wl_count * sizeof(*wi))) {
+ kfree (wi);
+ return -EFAULT;
+ }
+ }
+ for (i = 0; i < wlt.wl_count; i++, wi++) {
+ switch (wi->wi_type) {
+ case FB_WID_DBL_8: j = (wi->wi_index & 0xf) + 0x40; break;
+ case FB_WID_DBL_24: j = wi->wi_index & 0x3f; break;
+ default: return -EINVAL;
+ }
+ /* x = wi->wi_values [j] */;
+ }
+ if (km)
+ kfree (km);
+ return 0;
+}
+
+static inline void
+ffb_curs_enable (fbinfo_t *fb, int enable)
+{
+ struct ffb_dac *dac = fb->info.ffb.dac;
+
+ dac->type2 = 0x100;
+ if (fb->info.ffb.dac_rev <= 2)
+ dac->value2 = enable ? 3 : 0;
+ else
+ dac->value2 = enable ? 0 : 3;
+}
-__initfunc(void creator_setup (fbinfo_t *fb, int slot, int con_node, unsigned long creator, int creator_io))
-{
- uint bases [2];
- unsigned long *p;
-
- if (!creator) {
- prom_getproperty (con_node, "address", (char *) &bases[0], 4);
- prom_printf ("Bases: %x %x\n", bases [0], bases [1]);
- p = (unsigned long *) creator = bases[0];
- fb->base = creator;
- fb->base = 0xff168000;
- }
-
- fb->type.fb_cmsize = 256;
- fb->mmap = 0;
- fb->loadcmap = 0;
- fb->setcursor = 0;
- fb->setcursormap = 0;
- fb->setcurshape = 0;
- fb->ioctl = 0;
- fb->switch_from_graph = 0;
- fb->postsetup = sun_cg_postsetup;
- fb->reset = 0;
- fb->blank = 0;
- fb->unblank = 0;
- fb->type.fb_depth = 8;
+static void
+ffb_setcursormap (fbinfo_t *fb, unsigned char *red,
+ unsigned char *green,
+ unsigned char *blue)
+{
+ struct ffb_dac *dac = fb->info.ffb.dac;
+
+ ffb_curs_enable (fb, 0);
+ dac->type2 = 0x102;
+ dac->value2 = (red[0] | (green[0]<<8) | (blue[0]<<16));
+ dac->value2 = (red[1] | (green[1]<<8) | (blue[1]<<16));
+}
+
+/* Set cursor shape */
+static void
+ffb_setcurshape (fbinfo_t *fb)
+{
+ struct ffb_dac *dac = fb->info.ffb.dac;
+ int i, j;
+
+ ffb_curs_enable (fb, 0);
+ for (j = 0; j < 2; j++) {
+ dac->type2 = j ? 0 : 0x80;
+ for (i = 0; i < 0x40; i++) {
+ if (fb->cursor.size.fbx <= 32) {
+ dac->value2 = fb->cursor.bits [j][i];
+ dac->value2 = 0;
+ } else {
+ dac->value2 = fb->cursor.bits [j][2*i];
+ dac->value2 = fb->cursor.bits [j][2*i+1];
+ }
+ }
+ }
+}
+
+/* Load cursor information */
+static void
+ffb_setcursor (fbinfo_t *fb)
+{
+ struct ffb_dac *dac = fb->info.ffb.dac;
+ struct cg_cursor *c = &fb->cursor;
+
+ dac->type2 = 0x104;
+/* Should this be just 0x7ff?? Should I do some margin handling and setcurshape
+ in that case? */
+ dac->value2 = (((c->cpos.fbx - c->chot.fbx) & 0xffff) << 16)
+ |((c->cpos.fby - c->chot.fby) & 0xffff);
+ ffb_curs_enable (fb, fb->cursor.enable);
+}
+
+static void
+ffb_blank (fbinfo_t *fb)
+{
+/* XXX Write this */
+}
+
+static void
+ffb_unblank (fbinfo_t *fb)
+{
+/* XXX Write this */
+}
+
+static int ffb_clutstore (fbinfo_t *fb, int offset, int count)
+{
+ int i;
+ u32 *clut = fb->info.ffb.clut + offset;
+ struct ffb_dac *dac = fb->info.ffb.dac;
+
+ dac->type = 0x2000 | offset;
+ for (i = 0; i < count; i++)
+ dac->value = *clut++; /* Feed the colors in :)) */
+ return 0;
+}
+
+static int ffb_clutpost (fbinfo_t *fb, struct fb_clut *fc)
+{
+ int i;
+ u32 *clut;
+ struct fb_clut fct;
+ u8 red[256], green[256], blue[256];
+
+#ifdef CONFIG_SPARC32_COMPAT
+ if (current->tss.flags & SPARC_FLAG_32BIT) {
+ if (copy_from_user (&fct, fc, 3 * sizeof (__u32)) ||
+ __get_user ((long)fct.red, &(((struct fb_clut32 *)fc)->red)) ||
+ __get_user ((long)fct.green, &(((struct fb_clut32 *)fc)->green)) ||
+ __get_user ((long)fct.blue, &(((struct fb_clut32 *)fc)->blue)))
+ return -EFAULT;
+ } else
+#endif
+ if (copy_from_user (&fct, fc, sizeof (struct fb_clut)))
+ return -EFAULT;
+ i = fct.offset + fct.count;
+ if (fct.clutid || i <= 0 || i > 256) return -EINVAL;
+ if (copy_from_user (red, fct.red, fct.count) ||
+ copy_from_user (green, fct.green, fct.count) ||
+ copy_from_user (blue, fct.blue, fct.count))
+ return -EFAULT;
+ clut = fb->info.ffb.clut + fct.offset;
+ for (i = 0; i < fct.count; i++)
+ *clut++ = ((red[i])|(green[i]<<8)|(blue[i]<<16));
+ return ffb_clutstore (fb, fct.offset, fct.count);
+}
+
+static int ffb_clutread (fbinfo_t *fb, struct fb_clut *fc)
+{
+/* XXX write this */
+ return 0;
+}
+
+static void
+ffb_loadcmap (fbinfo_t *fb, int index, int count)
+{
+ u32 *clut = fb->info.ffb.clut + index;
+ int i, j = count;
+
+ for (i = index; j--; i++)
+ *clut++ = ((fb->color_map CM(i,0))) |
+ ((fb->color_map CM(i,1)) << 8) |
+ ((fb->color_map CM(i,2)) << 16);
+ ffb_clutstore (fb, index, count);
+}
+
+/* Handle ffb-specific ioctls */
+static int
+ffb_ioctl (struct inode *inode, struct file *file, unsigned cmd, unsigned long arg, fbinfo_t *fb)
+{
+ int i;
+
+ switch (cmd) {
+ case FBIO_WID_GET:
+ return ffb_wid_get (fb, (struct fb_wid_list *)arg);
+ case FBIO_WID_PUT:
+ return ffb_wid_put (fb, (struct fb_wid_list *)arg);
+ case FFB_CLUTPOST:
+ return ffb_clutpost (fb, (struct fb_clut *)arg);
+ case FFB_CLUTREAD:
+ return ffb_clutread (fb, (struct fb_clut *)arg);
+
+ default:
+ return -ENOSYS;
+ }
+}
+
+void
+ffb_reset (fbinfo_t *fb)
+{
+ struct ffb_info *ffb = &(fb->info.ffb);
+ int fifo;
+
+ if (fb->setcursor)
+ sun_hw_hide_cursor ();
+
+ while ((fifo = (ffb->fbc->ucsr & FFB_UCSR_FIFO_MASK)) < 8);
+ ffb->fbc->ppc = (FFB_PPC_ACE_DISABLE << FFB_PPC_ACE_SHIFT) |
+ (FFB_PPC_DCE_DISABLE << FFB_PPC_DCE_SHIFT) |
+ (FFB_PPC_ABE_DISABLE << FFB_PPC_ABE_SHIFT) |
+ (FFB_PPC_VCE_DISABLE << FFB_PPC_VCE_SHIFT) |
+ (FFB_PPC_APE_DISABLE << FFB_PPC_APE_SHIFT) |
+ (FFB_PPC_CS_VARIABLE << FFB_PPC_CS_SHIFT);
+ ffb->fbc->fbc = (FFB_FBC_WB_A << FFB_FBC_WB_SHIFT) |
+ (FFB_FBC_PGE_MASK << FFB_FBC_BE_SHIFT) |
+ (FFB_FBC_PGE_MASK << FFB_FBC_GE_SHIFT) |
+ (FFB_FBC_PGE_MASK << FFB_FBC_RE_SHIFT);
+ ffb->fbc->rop = (FFB_ROP_NEW << FFB_ROP_RGB_SHIFT);
+ ffb->fbc->pmask = 0x00ffffff;
+ while (ffb->fbc->ucsr & FFB_UCSR_RP_BUSY);
+}
+
+__initfunc(static unsigned long ffb_postsetup (fbinfo_t *fb, unsigned long memory_start))
+{
+ fb->info.ffb.clut = (u32 *)(memory_start);
+ fb->color_map = (u8 *)(memory_start+256*4+256);
+ return memory_start + 256*4 + 256*3;
+}
+
+__initfunc(void creator_setup (fbinfo_t *fb, int slot, int ffb_node, unsigned long ffb, int ffb_io))
+{
+ struct ffb_info *ffbinfo;
+ struct linux_prom64_registers regs[2*PROMREG_MAX];
+
+ if (prom_getproperty(ffb_node, "reg", (void *) regs, sizeof(regs)) <= 0)
+ return;
+ ffb = regs[0].phys_addr;
+ printk ("creator%d at 0x%016lx ", slot, ffb);
+
+ fb->base = ffb; /* ??? */
+
+ /* Fill in parameters we left out */
+ fb->type.fb_cmsize = 256;
+ fb->mmap = ffb_mmap;
+ fb->loadcmap = ffb_loadcmap;
+ fb->reset = ffb_reset;
+ fb->blank = ffb_blank;
+ fb->unblank = ffb_unblank;
+ fb->setcursor = ffb_setcursor;
+ fb->setcursormap = ffb_setcursormap;
+ fb->setcurshape = ffb_setcurshape;
+ fb->postsetup = ffb_postsetup;
+ fb->blitc = ffb_blitc;
+ fb->setw = ffb_setw;
+ fb->cpyw = ffb_cpyw;
+ fb->fill = ffb_fill;
+ fb->ioctl = ffb_ioctl;
+ fb->cursor.hwsize.fbx = 64;
+ fb->cursor.hwsize.fby = 64;
+
+ ffbinfo = (struct ffb_info *) &fb->info.ffb;
+
+ ffbinfo->physbase = ffb;
+
+ ffbinfo->fbc = (struct ffb_fbc *)(ffb + FFB_FBC_REGS_POFF);
+ ffbinfo->dac = (struct ffb_dac *)(ffb + FFB_DAC_POFF);
+
+ ffbinfo->dac->type = 0x8000;
+ ffbinfo->dac_rev = (ffbinfo->dac->value >> 0x1c);
+
+ if (slot == sun_prom_console_id)
+ fb_restore_palette = ffb_restore_palette;
+
+ /* Initialize Brooktree DAC */
+
+ printk("DAC %d\n", ffbinfo->dac_rev);
+
+ if (slot && sun_prom_console_id == slot)
+ return;
+
+ /* Reset the ffb */
+ ffb_reset(fb);
+
+ if (!slot) {
+ /* Enable Video */
+ ffb_unblank(fb);
+ } else {
+ ffb_blank(fb);
+ }
+}
+
+extern unsigned char vga_font[];
+
+static void ffb_blitc(unsigned short charattr, int xoff, int yoff)
+{
+}
+
+static void ffb_setw(int xoff, int yoff, unsigned short c, int count)
+{
+}
+
+static void ffb_cpyw(int xoff, int yoff, unsigned short *p, int count)
+{
+}
+
+static void ffb_fill(int attrib, int count, int *boxes)
+{
}
diff --git a/drivers/sbus/char/fb.h b/drivers/sbus/char/fb.h
index 029eac81b..0aa9f2b48 100644
--- a/drivers/sbus/char/fb.h
+++ b/drivers/sbus/char/fb.h
@@ -1,4 +1,4 @@
-/* $Id: fb.h,v 1.26 1997/04/17 02:29:33 miguel Exp $
+/* $Id: fb.h,v 1.29 1997/07/15 09:48:48 jj Exp $
* fb.h: contains the definitions of the structures that various sun
* frame buffer can use to do console driver stuff.
*
@@ -33,7 +33,7 @@ struct cg_cursor {
struct fbcurpos chot; /* hot-spot */
struct fbcurpos size; /* size of mask & image fields */
struct fbcurpos hwsize; /* hw max size */
- int bits[2][32]; /* space for mask & image bits */
+ int bits[2][128]; /* space for mask & image bits */
char color [6]; /* cursor colors */
};
@@ -57,6 +57,14 @@ struct tcx_info {
int lowdepth;
};
+struct ffb_info {
+ unsigned long physbase;
+ struct ffb_fbc *fbc;
+ struct ffb_dac *dac;
+ int dac_rev;
+ u32 *clut;
+};
+
struct leo_info {
struct leo_cursor *cursor;
struct leo_lc_ss0_krn *lc_ss0_krn;
@@ -113,6 +121,7 @@ typedef struct fbinfo {
struct cg14_info cg14;
struct tcx_info tcx;
struct leo_info leo;
+ struct ffb_info ffb;
} info; /* per frame information */
int space; /* I/O space this card resides in */
int blanked; /* true if video blanked */
@@ -183,7 +192,7 @@ extern int con_height, con_linebytes;
extern int ints_per_line;
/* used in the mmap routines */
-extern unsigned int get_phys (unsigned long addr);
+extern unsigned long get_phys (unsigned long addr);
extern int get_iospace (unsigned long addr);
extern void render_screen(void);
diff --git a/drivers/sbus/char/leo.c b/drivers/sbus/char/leo.c
index 61e646e9f..1b5d06e4b 100644
--- a/drivers/sbus/char/leo.c
+++ b/drivers/sbus/char/leo.c
@@ -1,7 +1,7 @@
-/* $Id: leo.c,v 1.18 1997/06/04 08:27:30 davem Exp $
+/* $Id: leo.c,v 1.21 1997/07/17 02:21:48 davem Exp $
* leo.c: SUNW,leo 24/8bit frame buffer driver
*
- * Copyright (C) 1996 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
+ * Copyright (C) 1996,1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
* Copyright (C) 1997 Michal Rehacek (Michal.Rehacek@st.mff.cuni.cz)
*/
@@ -143,7 +143,7 @@ leo_mmap (struct inode *inode, struct file *file, struct vm_area_struct *vma,
long base, fbinfo_t *fb)
{
uint size, page, r, map_size = 0;
- uint map_offset = 0;
+ unsigned long map_offset = 0;
size = vma->vm_end - vma->vm_start;
if (vma->vm_offset & ~PAGE_MASK)
@@ -218,11 +218,12 @@ leo_mmap (struct inode *inode, struct file *file, struct vm_area_struct *vma,
map_offset,
map_size, vma->vm_page_prot,
fb->space);
- if (r) return -EAGAIN;
+ if (r)
+ return -EAGAIN;
page += map_size;
}
- vma->vm_inode = inode;
- atomic_inc(&inode->i_count);
+
+ vma->vm_dentry = dget(file->f_dentry);
return 0;
}
@@ -376,7 +377,7 @@ static int leo_clutstore (fbinfo_t *fb, int clutid)
return 0;
}
-static int leo_clutpost (fbinfo_t *fb, struct leo_clut *lc)
+static int leo_clutpost (fbinfo_t *fb, struct fb_clut *lc)
{
int xlate = 0, i;
u32 *clut;
@@ -398,7 +399,7 @@ static int leo_clutpost (fbinfo_t *fb, struct leo_clut *lc)
return leo_clutstore (fb, lc->clutid);
}
-static int leo_clutread (fbinfo_t *fb, struct leo_clut *lc)
+static int leo_clutread (fbinfo_t *fb, struct fb_clut *lc)
{
int i;
u32 u;
@@ -463,29 +464,29 @@ leo_ioctl (struct inode *inode, struct file *file, unsigned cmd, unsigned long a
if (i) return i;
return leo_wid_put (fb, (struct fb_wid_list *)arg);
case LEO_CLUTPOST:
- i = verify_area (VERIFY_READ, (void *)arg, sizeof (struct leo_clut));
+ i = verify_area (VERIFY_READ, (void *)arg, sizeof (struct fb_clut));
if (i) return i;
- i = ((struct leo_clut *)arg)->offset + ((struct leo_clut *)arg)->count;
+ i = ((struct fb_clut *)arg)->offset + ((struct fb_clut *)arg)->count;
if (i <= 0 || i > 256) return -EINVAL;
- i = verify_area (VERIFY_READ, ((struct leo_clut *)arg)->red, ((struct leo_clut *)arg)->count);
+ i = verify_area (VERIFY_READ, ((struct fb_clut *)arg)->red, ((struct fb_clut *)arg)->count);
if (i) return i;
- i = verify_area (VERIFY_READ, ((struct leo_clut *)arg)->green, ((struct leo_clut *)arg)->count);
+ i = verify_area (VERIFY_READ, ((struct fb_clut *)arg)->green, ((struct fb_clut *)arg)->count);
if (i) return i;
- i = verify_area (VERIFY_READ, ((struct leo_clut *)arg)->blue, ((struct leo_clut *)arg)->count);
+ i = verify_area (VERIFY_READ, ((struct fb_clut *)arg)->blue, ((struct fb_clut *)arg)->count);
if (i) return i;
- return leo_clutpost (fb, (struct leo_clut *)arg);
+ return leo_clutpost (fb, (struct fb_clut *)arg);
case LEO_CLUTREAD:
- i = verify_area (VERIFY_READ, (void *)arg, sizeof (struct leo_clut));
+ i = verify_area (VERIFY_READ, (void *)arg, sizeof (struct fb_clut));
if (i) return i;
- i = ((struct leo_clut *)arg)->offset + ((struct leo_clut *)arg)->count;
+ i = ((struct fb_clut *)arg)->offset + ((struct fb_clut *)arg)->count;
if (i <= 0 || i > 256) return -EINVAL;
- i = verify_area (VERIFY_WRITE, ((struct leo_clut *)arg)->red, ((struct leo_clut *)arg)->count);
+ i = verify_area (VERIFY_WRITE, ((struct fb_clut *)arg)->red, ((struct fb_clut *)arg)->count);
if (i) return i;
- i = verify_area (VERIFY_WRITE, ((struct leo_clut *)arg)->green, ((struct leo_clut *)arg)->count);
+ i = verify_area (VERIFY_WRITE, ((struct fb_clut *)arg)->green, ((struct fb_clut *)arg)->count);
if (i) return i;
- i = verify_area (VERIFY_WRITE, ((struct leo_clut *)arg)->blue, ((struct leo_clut *)arg)->count);
+ i = verify_area (VERIFY_WRITE, ((struct fb_clut *)arg)->blue, ((struct fb_clut *)arg)->count);
if (i) return i;
- return leo_clutread (fb, (struct leo_clut *)arg);
+ return leo_clutread (fb, (struct fb_clut *)arg);
default:
return -ENOSYS;
diff --git a/drivers/sbus/char/openprom.c b/drivers/sbus/char/openprom.c
index 548abb601..75b950071 100644
--- a/drivers/sbus/char/openprom.c
+++ b/drivers/sbus/char/openprom.c
@@ -137,6 +137,7 @@ static int openprom_sunos_ioctl(struct inode * inode, struct file * file,
struct openpromio *opp;
unsigned long flags;
int bufsize, len, error = 0;
+ extern char saved_command_line[];
if (cmd == OPROMSETOPT)
bufsize = getstrings((void *)arg, &opp);
@@ -172,7 +173,7 @@ static int openprom_sunos_ioctl(struct inode * inode, struct file * file,
case OPROMNXTOPT:
case OPROMNXTPROP:
save_and_cli(flags);
- buf = prom_nextprop(node, opp->oprom_array);
+ buf = prom_nextprop(node, opp->oprom_array, buffer);
restore_flags(flags);
len = strlen(buf);
@@ -229,9 +230,7 @@ static int openprom_sunos_ioctl(struct inode * inode, struct file * file,
break;
case OPROMGETBOOTARGS:
- save_and_cli(flags);
- buf = prom_getbootargs();
- restore_flags(flags);
+ buf = saved_command_line;
len = strlen(buf);
@@ -315,6 +314,7 @@ static int openprom_bsd_ioctl(struct inode * inode, struct file * file,
unsigned long flags;
int error, node, len;
char *str, *tmp;
+ char buffer[64];
switch (cmd) {
case OPIOCGET:
@@ -378,7 +378,7 @@ static int openprom_bsd_ioctl(struct inode * inode, struct file * file,
return error;
save_and_cli(flags);
- tmp = prom_nextprop(op.op_nodeid,str);
+ tmp = prom_nextprop(op.op_nodeid,str,buffer);
restore_flags(flags);
if (tmp) {
diff --git a/drivers/sbus/char/suncons.c b/drivers/sbus/char/suncons.c
index 1d3815dd3..cad446904 100644
--- a/drivers/sbus/char/suncons.c
+++ b/drivers/sbus/char/suncons.c
@@ -1,4 +1,4 @@
-/* $Id: suncons.c,v 1.63 1997/05/31 18:33:25 mj Exp $
+/* $Id: suncons.c,v 1.66 1997/07/15 09:48:47 jj Exp $
*
* suncons.c: Sun SparcStation console support.
*
@@ -759,7 +759,7 @@ console_restore_palette (void)
(*fb_restore_palette) (&fbinfo[0]);
}
-unsigned int
+unsigned long
get_phys (unsigned long addr)
{
return __get_phys(addr);
@@ -828,10 +828,14 @@ __initfunc(static int creator_present (void))
{
int root, n;
+#ifdef __sparc_v9__
root = prom_getchild (prom_root_node);
if ((n = prom_searchsiblings (root, "SUNW,ffb")) == 0)
return 0;
return n;
+#else
+ return 0;
+#endif
}
__initfunc(static void
@@ -1108,7 +1112,6 @@ __initfunc(static int sparc_console_probe(void))
if (!card_found)
card_found = cg14 = cg14_present ();
if (!card_found){
- prom_printf ("Searching for a creator\n");
card_found = creator = creator_present ();
}
if (!card_found){
@@ -1172,7 +1175,7 @@ __initfunc(static int sparc_console_probe(void))
if (creator){
sparc_framebuffer_setup (!sbdprom, creator, FBTYPE_CREATOR,
0, 0, 0, prom_console_node == creator,
- prom_getchild (prom_root_node));
+ prom_root_node);
}
break;
default:
@@ -1641,57 +1644,67 @@ void memcpyw(unsigned short *to, unsigned short *from, unsigned int count)
int
sun_hw_scursor (struct fbcursor *cursor, fbinfo_t *fb)
{
- int op = cursor->set;
+ int op;
int i, bytes = 0;
+ struct fbcursor f;
+ char red[2], green[2], blue[2];
+ if (copy_from_user (&f, cursor, sizeof(struct fbcursor)))
+ return -EFAULT;
+ op = f.set;
if (op & FB_CUR_SETSHAPE){
- if ((uint) cursor->size.fbx > fb->cursor.hwsize.fbx)
+ if ((uint) f.size.fbx > fb->cursor.hwsize.fbx)
return -EINVAL;
- if ((uint) cursor->size.fby > fb->cursor.hwsize.fby)
+ if ((uint) f.size.fby > fb->cursor.hwsize.fby)
return -EINVAL;
- bytes = (cursor->size.fby * 32)/8;
- i = verify_area (VERIFY_READ, cursor->image, bytes);
- if (i) return i;
- i = verify_area (VERIFY_READ, cursor->mask, bytes);
- if (i) return i;
+ if (f.size.fbx > 32)
+ bytes = f.size.fby << 3;
+ else
+ bytes = f.size.fby << 2;
}
if (op & FB_CUR_SETCMAP){
- if (cursor->cmap.index && cursor->cmap.count != 2)
+ if (f.cmap.index || f.cmap.count != 2)
return -EINVAL;
- i = verify_area (VERIFY_READ, cursor->cmap.red, 2);
- if (i) return i;
- i = verify_area (VERIFY_READ, cursor->cmap.green, 2);
- if (i) return i;
- i = verify_area (VERIFY_READ, cursor->cmap.blue, 2);
- if (i) return i;
- }
- if (op & (FB_CUR_SETCUR | FB_CUR_SETPOS | FB_CUR_SETHOT)){
- if (op & FB_CUR_SETCUR)
- fb->cursor.enable = cursor->enable;
- if (op & FB_CUR_SETPOS)
- fb->cursor.cpos = cursor->pos;
- if (op & FB_CUR_SETHOT)
- fb->cursor.chot = cursor->hot;
- (*fb->setcursor) (fb);
+ if (copy_from_user (red, f.cmap.red, 2) ||
+ copy_from_user (green, f.cmap.green, 2) ||
+ copy_from_user (blue, f.cmap.blue, 2))
+ return -EFAULT;
}
if (op & FB_CUR_SETCMAP)
- (*fb->setcursormap) (fb, cursor->cmap.red, cursor->cmap.green, cursor->cmap.blue);
+ (*fb->setcursormap) (fb, red, green, blue);
if (op & FB_CUR_SETSHAPE){
uint u;
- fb->cursor.size = cursor->size;
+ fb->cursor.size = f.size;
memset ((void *)&fb->cursor.bits, 0, sizeof (fb->cursor.bits));
- memcpy (fb->cursor.bits [0], cursor->mask, bytes);
- memcpy (fb->cursor.bits [1], cursor->image, bytes);
- u = ~0;
- if (cursor->size.fbx < fb->cursor.hwsize.fbx)
- u = ~(u >> cursor->size.fbx);
- for (i = fb->cursor.size.fby - 1; i >= 0; i--) {
- fb->cursor.bits [0][i] &= u;
- fb->cursor.bits [1][i] &= fb->cursor.bits [0][i];
+ if (copy_from_user (fb->cursor.bits [0], f.mask, bytes) ||
+ copy_from_user (fb->cursor.bits [1], f.image, bytes))
+ return -EFAULT;
+ if (f.size.fbx <= 32) {
+ u = ~(0xffffffff >> f.size.fbx);
+ for (i = fb->cursor.size.fby - 1; i >= 0; i--) {
+ fb->cursor.bits [0][i] &= u;
+ fb->cursor.bits [1][i] &= fb->cursor.bits [0][i];
+ }
+ } else {
+ u = ~(0xffffffff >> (f.size.fbx - 32));
+ for (i = fb->cursor.size.fby - 1; i >= 0; i--) {
+ fb->cursor.bits [0][2*i+1] &= u;
+ fb->cursor.bits [1][2*i] &= fb->cursor.bits [0][2*i];
+ fb->cursor.bits [1][2*i+1] &= fb->cursor.bits [0][2*i+1];
+ }
}
(*fb->setcurshape) (fb);
}
+ if (op & (FB_CUR_SETCUR | FB_CUR_SETPOS | FB_CUR_SETHOT)){
+ if (op & FB_CUR_SETCUR)
+ fb->cursor.enable = f.enable;
+ if (op & FB_CUR_SETPOS)
+ fb->cursor.cpos = f.pos;
+ if (op & FB_CUR_SETHOT)
+ fb->cursor.chot = f.hot;
+ (*fb->setcursor) (fb);
+ }
return 0;
}
diff --git a/drivers/sbus/char/sunfb.c b/drivers/sbus/char/sunfb.c
index 68856c9ee..885581975 100644
--- a/drivers/sbus/char/sunfb.c
+++ b/drivers/sbus/char/sunfb.c
@@ -1,4 +1,4 @@
-/* $Id: sunfb.c,v 1.23 1997/05/31 18:33:26 mj Exp $
+/* $Id: sunfb.c,v 1.26 1997/07/17 02:21:48 davem Exp $
* sunfb.c: Sun generic frame buffer support.
*
* Copyright (C) 1995, 1996 Miguel de Icaza (miguel@nuclecu.unam.mx)
@@ -132,7 +132,7 @@ fb_ioctl (struct inode *inode, struct file *file, uint cmd, unsigned long arg)
if ((index < 0) || (index > 255))
return -EINVAL;
if (index + count > 256)
- count = 256 - cmap->index;
+ count = 256 - index;
__get_user_ret(rp, &cmap->red, -EFAULT);
__get_user_ret(gp, &cmap->green, -EFAULT);
__get_user_ret(bp, &cmap->blue, -EFAULT);
@@ -146,7 +146,7 @@ fb_ioctl (struct inode *inode, struct file *file, uint cmd, unsigned long arg)
__put_user_ret(fb->color_map CM(i,2), bp, -EFAULT);
rp++; gp++; bp++;
}
- (*fb->loadcmap)(fb, cmap->index, count);
+ (*fb->loadcmap)(fb, index, count);
break;
}
@@ -164,13 +164,13 @@ fb_ioctl (struct inode *inode, struct file *file, uint cmd, unsigned long arg)
if ((index < 0) || (index > 255))
return -EINVAL;
if (index + count > 256)
- count = 256 - cmap->index;
+ count = 256 - index;
__get_user_ret(rp, &cmap->red, -EFAULT);
__get_user_ret(gp, &cmap->green, -EFAULT);
__get_user_ret(bp, &cmap->blue, -EFAULT);
- if(verify_area (VERIFY_READ, rp, cmap->count)) return -EFAULT;
- if(verify_area (VERIFY_READ, gp, cmap->count)) return -EFAULT;
- if(verify_area (VERIFY_READ, bp, cmap->count)) return -EFAULT;
+ if(verify_area (VERIFY_READ, rp, count)) return -EFAULT;
+ if(verify_area (VERIFY_READ, gp, count)) return -EFAULT;
+ if(verify_area (VERIFY_READ, bp, count)) return -EFAULT;
end = index + count;
for (i = index; i < end; i++){
@@ -179,7 +179,7 @@ fb_ioctl (struct inode *inode, struct file *file, uint cmd, unsigned long arg)
__get_user_ret(fb->color_map CM(i,2), bp, -EFAULT);
rp++; gp++; bp++;
}
- (*fb->loadcmap)(fb, cmap->index, count);
+ (*fb->loadcmap)(fb, index, count);
break;
}
@@ -275,7 +275,9 @@ fb_mmap (struct inode *inode, struct file *file, struct vm_area_struct *vma)
int v;
v = (*fb->mmap)(inode, file, vma, fb->base, fb);
- if (v) return v;
+ if (v)
+ return v;
+ vma->vm_flags |= VM_IO;
if (!fb->mmaped) {
fb->mmaped = 1;
if (!minor) {
diff --git a/drivers/sbus/char/sunkbd.c b/drivers/sbus/char/sunkbd.c
index 1ddaaecd4..54b09cd76 100644
--- a/drivers/sbus/char/sunkbd.c
+++ b/drivers/sbus/char/sunkbd.c
@@ -419,27 +419,27 @@ void sunkbd_inchar(unsigned char ch, struct pt_regs *regs)
if(ch == SKBD_RESET) {
kbd_reset_pending = 1;
- return;
+ goto out;
}
if(ch == SKBD_LYOUT) {
kbd_layout_pending = 1;
- return;
+ goto out;
}
if(kbd_reset_pending) {
sunkbd_type = ch;
kbd_reset_pending = 0;
if(ch == SUNKBD_TYPE4)
send_cmd(SKBDCMD_GLAYOUT);
- return;
+ goto out;
} else if(kbd_layout_pending) {
sunkbd_layout = ch;
kbd_layout_pending = 0;
- return;
+ goto out;
} else if(ch == SKBD_ALLUP) {
del_timer (&auto_repeat_timer);
memset(key_down, 0, sizeof(key_down));
compute_shiftstate();
- return;
+ goto out;
}
#ifdef SKBD_DEBUG
if(ch == 0x7f)
@@ -456,11 +456,11 @@ void sunkbd_inchar(unsigned char ch, struct pt_regs *regs)
} else {
keycode = ch;
}
- add_keyboard_randomness(keycode);
- mark_bh(KEYBOARD_BH);
do_poke_blanked_console = 1;
mark_bh(CONSOLE_BH);
+ add_keyboard_randomness(keycode);
+
kbd = kbd_table + fg_console;
tty = ttytab[fg_console];
if((raw_mode = (kbd->kbdmode == VC_RAW))) {
@@ -491,11 +491,11 @@ void sunkbd_inchar(unsigned char ch, struct pt_regs *regs)
}
if(raw_mode)
- return;
+ goto out;
if(kbd->kbdmode == VC_MEDIUMRAW) {
put_queue(keycode + up_flag);
- return;
+ goto out;
}
/*
@@ -545,6 +545,8 @@ void sunkbd_inchar(unsigned char ch, struct pt_regs *regs)
compute_shiftstate();
}
}
+out:
+ mark_bh(KEYBOARD_BH);
}
static void put_queue(int ch)
diff --git a/drivers/sbus/char/sunmouse.c b/drivers/sbus/char/sunmouse.c
index 371fb3004..789a332c0 100644
--- a/drivers/sbus/char/sunmouse.c
+++ b/drivers/sbus/char/sunmouse.c
@@ -171,7 +171,7 @@ void mouse_baud_detection(unsigned char c)
ctr = 0;
wait_for_synchron = 1;
if(mouse_baud_changing == 1) {
- printk("sunmouse: Successfully adjusted to %d baud.\n",
+ printk(KERN_DEBUG "sunmouse: Successfully adjusted to %d baud.\n",
mouse_baud);
mouse_baud_changing = 0;
}
diff --git a/drivers/sbus/char/sunserial.c b/drivers/sbus/char/sunserial.c
index e89384a3a..c0e6ab71d 100644
--- a/drivers/sbus/char/sunserial.c
+++ b/drivers/sbus/char/sunserial.c
@@ -1,4 +1,4 @@
-/* $Id: sunserial.c,v 1.42 1997/05/26 20:10:20 davem Exp $
+/* $Id: sunserial.c,v 1.43 1997/07/05 09:53:23 davem Exp $
* serial.c: Serial port driver for the Sparc.
*
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
@@ -348,10 +348,12 @@ static void batten_down_hatches(void)
*/
printk("\n");
flush_user_windows();
+#ifndef __sparc_v9__
if((((unsigned long)linux_dbvec)>=DEBUG_FIRSTVADDR) &&
(((unsigned long)linux_dbvec)<=DEBUG_LASTVADDR))
sp_enter_debugger();
else
+#endif
prom_cmdline();
/* XXX We want to notify the keyboard driver that all
@@ -396,7 +398,9 @@ static _INLINE_ void rs_sched_event(struct sun_serial *info,
mark_bh(SERIAL_BH);
}
+#ifndef __sparc_v9__
extern void breakpoint(void); /* For the KGDB frame character */
+#endif
static _INLINE_ void receive_chars(struct sun_serial *info, struct pt_regs *regs)
{
@@ -453,6 +457,7 @@ static _INLINE_ void receive_chars(struct sun_serial *info, struct pt_regs *regs
/* It is a 'keyboard interrupt' ;-) */
wake_up(&keypress_wait);
}
+#ifndef __sparc_v9__
/* Look for kgdb 'stop' character, consult the gdb
* documentation for remote target debugging and
* arch/sparc/kernel/sparc-stub.c to see how all this works.
@@ -461,7 +466,7 @@ static _INLINE_ void receive_chars(struct sun_serial *info, struct pt_regs *regs
breakpoint();
return;
}
-
+#endif
if(!tty)
return;
@@ -1867,7 +1872,7 @@ int rs_open(struct tty_struct *tty, struct file * filp)
static void show_serial_version(void)
{
- char *revision = "$Revision: 1.42 $";
+ char *revision = "$Revision: 1.2 $";
char *version, *p;
version = strchr(revision, ' ');
diff --git a/drivers/sbus/char/sunserial.h b/drivers/sbus/char/sunserial.h
index b8ae23305..ae4260cad 100644
--- a/drivers/sbus/char/sunserial.h
+++ b/drivers/sbus/char/sunserial.h
@@ -1,4 +1,4 @@
-/* $Id: sunserial.h,v 1.9 1997/04/12 23:33:12 ecd Exp $
+/* $Id: sunserial.h,v 1.11 1997/07/08 10:17:23 davem Exp $
* serial.h: Definitions for the Sparc Zilog serial driver.
*
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
diff --git a/drivers/sbus/char/tcx.c b/drivers/sbus/char/tcx.c
index db66383ac..20c14a687 100644
--- a/drivers/sbus/char/tcx.c
+++ b/drivers/sbus/char/tcx.c
@@ -1,4 +1,4 @@
-/* $Id: tcx.c,v 1.15 1997/06/04 08:27:32 davem Exp $
+/* $Id: tcx.c,v 1.17 1997/07/17 02:21:50 davem Exp $
* tcx.c: SUNW,tcx 24/8bit frame buffer driver
*
* Copyright (C) 1996 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
@@ -110,7 +110,8 @@ tcx_mmap (struct inode *inode, struct file *file, struct vm_area_struct *vma,
long base, fbinfo_t *fb)
{
uint size, page, r, map_size;
- uint map_offset = 0, i;
+ unsigned long map_offset = 0;
+ uint i;
long offsets[13] = { -1, TCX_RAM24BIT, TCX_UNK3, TCX_UNK4,
-1, TCX_UNK6, TCX_UNK7,
-1, -1, -1, TCX_UNK2, TCX_DHC, TCX_ALT };
@@ -168,11 +169,12 @@ tcx_mmap (struct inode *inode, struct file *file, struct vm_area_struct *vma,
map_offset,
map_size, vma->vm_page_prot,
fb->space);
- if (r) return -EAGAIN;
+ if (r)
+ return -EAGAIN;
page += map_size;
}
- vma->vm_inode = inode;
- atomic_inc(&inode->i_count);
+
+ vma->vm_dentry = dget(file->f_dentry);
return 0;
}
diff --git a/drivers/sbus/char/vfc_dev.c b/drivers/sbus/char/vfc_dev.c
index 00cdfe35c..007174a82 100644
--- a/drivers/sbus/char/vfc_dev.c
+++ b/drivers/sbus/char/vfc_dev.c
@@ -577,11 +577,12 @@ static int vfc_mmap(struct inode *inode, struct file *file,
if(vma->vm_offset & ~PAGE_MASK) return -ENXIO;
vma->vm_flags |= VM_SHM | VM_LOCKED | VM_IO | VM_MAYREAD | VM_MAYWRITE | VM_MAYSHARE;
map_offset=(unsigned int)dev->phys_regs;
- ret=io_remap_page_range(vma->vm_start,map_offset,map_size,
- vma->vm_page_prot, dev->which_io);
- if(ret) return -EAGAIN;
- vma->vm_inode=inode;
- atomic_inc(&inode->i_count);
+ ret = io_remap_page_range(vma->vm_start,map_offset,map_size,
+ vma->vm_page_prot, dev->which_io);
+ if(ret)
+ return -EAGAIN;
+
+ vma->vm_dentry = dget(file->f_dentry);
return 0;
}
diff --git a/drivers/sbus/char/weitek.c b/drivers/sbus/char/weitek.c
index d2ac4d135..7b7b1bd72 100644
--- a/drivers/sbus/char/weitek.c
+++ b/drivers/sbus/char/weitek.c
@@ -1,4 +1,4 @@
-/* $Id: weitek.c,v 1.12 1997/06/04 08:27:34 davem Exp $
+/* $Id: weitek.c,v 1.14 1997/07/17 02:21:53 davem Exp $
* weitek.c: Tadpole P9100/P9000 console driver
*
* Copyright (C) 1996 David Redman (djhr@tadpole.co.uk)
@@ -41,7 +41,7 @@ weitek_mmap(struct inode *inode, struct file *file, struct vm_area_struct *vma,
long base, fbinfo_t *fb)
{
unsigned int size, page, r, map_size;
- unsigned int map_offset = 0;
+ unsigned long map_offset = 0;
size = vma->vm_end - vma->vm_start;
if (vma->vm_offset & ~PAGE_MASK)
@@ -79,11 +79,12 @@ weitek_mmap(struct inode *inode, struct file *file, struct vm_area_struct *vma,
map_offset,
map_size, vma->vm_page_prot,
fb->space);
- if (r) return -EAGAIN;
+ if (r)
+ return -EAGAIN;
page += map_size;
}
- vma->vm_inode = inode;
- atomic_inc(&inode->i_count);
+
+ vma->vm_dentry = dget(file->f_dentry);
return 0;
}
#endif