diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1997-07-20 14:56:40 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 1997-07-20 14:56:40 +0000 |
commit | e308faf24f68e262d92d294a01ddca7a17e76762 (patch) | |
tree | 22c47cb315811834861f013067878ff664e95abd /drivers/sbus/char | |
parent | 30c6397ce63178fcb3e7963ac247f0a03132aca9 (diff) |
Sync with Linux 2.1.46.
Diffstat (limited to 'drivers/sbus/char')
-rw-r--r-- | drivers/sbus/char/bwtwo.c | 12 | ||||
-rw-r--r-- | drivers/sbus/char/cgfourteen.c | 11 | ||||
-rw-r--r-- | drivers/sbus/char/cgsix.c | 65 | ||||
-rw-r--r-- | drivers/sbus/char/cgthree.c | 11 | ||||
-rw-r--r-- | drivers/sbus/char/creator.c | 604 | ||||
-rw-r--r-- | drivers/sbus/char/fb.h | 15 | ||||
-rw-r--r-- | drivers/sbus/char/leo.c | 41 | ||||
-rw-r--r-- | drivers/sbus/char/openprom.c | 10 | ||||
-rw-r--r-- | drivers/sbus/char/suncons.c | 89 | ||||
-rw-r--r-- | drivers/sbus/char/sunfb.c | 20 | ||||
-rw-r--r-- | drivers/sbus/char/sunkbd.c | 20 | ||||
-rw-r--r-- | drivers/sbus/char/sunmouse.c | 2 | ||||
-rw-r--r-- | drivers/sbus/char/sunserial.c | 11 | ||||
-rw-r--r-- | drivers/sbus/char/sunserial.h | 2 | ||||
-rw-r--r-- | drivers/sbus/char/tcx.c | 12 | ||||
-rw-r--r-- | drivers/sbus/char/vfc_dev.c | 11 | ||||
-rw-r--r-- | drivers/sbus/char/weitek.c | 11 |
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 |