11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* sbuslib.c: Helper library for SBUS framebuffer drivers. 21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (C) 2003 David S. Miller (davem@redhat.com) 41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 69ffb83bcc5c5337f980dc0576bf13ac9bd4fd33dChristoph Hellwig#include <linux/compat.h> 71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/kernel.h> 81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/module.h> 91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/string.h> 101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/fb.h> 111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/mm.h> 12631a9dca60ddd7d84a08171a14828e9cfb667d48Robert Reif#include <linux/uaccess.h> 136cd5a86b56ec8fc8651c043bdb05ea0c662fb704Robert Reif#include <linux/of_device.h> 141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/fbio.h> 161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "sbuslib.h" 181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 196cd5a86b56ec8fc8651c043bdb05ea0c662fb704Robert Reifvoid sbusfb_fill_var(struct fb_var_screeninfo *var, struct device_node *dp, 206cd5a86b56ec8fc8651c043bdb05ea0c662fb704Robert Reif int bpp) 211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memset(var, 0, sizeof(*var)); 231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 246cd5a86b56ec8fc8651c043bdb05ea0c662fb704Robert Reif var->xres = of_getintprop_default(dp, "width", 1152); 256cd5a86b56ec8fc8651c043bdb05ea0c662fb704Robert Reif var->yres = of_getintprop_default(dp, "height", 900); 261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds var->xres_virtual = var->xres; 271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds var->yres_virtual = var->yres; 281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds var->bits_per_pixel = bpp; 291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(sbusfb_fill_var); 321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic unsigned long sbusfb_mmapsize(long size, unsigned long fbsize) 341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (size == SBUS_MMAP_EMPTY) return 0; 361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (size >= 0) return size; 371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return fbsize * (-size); 381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint sbusfb_mmap_helper(struct sbus_mmap_map *map, 411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long physbase, 421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long fbsize, 431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long iospace, 441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct vm_area_struct *vma) 451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int size, page, r, map_size; 471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long map_offset = 0; 481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long off; 491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 51e445ee65cbefaa19131c972ae7fe221c95cf4cc4David S. Miller if (!(vma->vm_flags & (VM_SHARED | VM_MAYSHARE))) 52e445ee65cbefaa19131c972ae7fe221c95cf4cc4David S. Miller return -EINVAL; 53e445ee65cbefaa19131c972ae7fe221c95cf4cc4David S. Miller 541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds size = vma->vm_end - vma->vm_start; 551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) 561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EINVAL; 571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds off = vma->vm_pgoff << PAGE_SHIFT; 591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 60314e51b9851b4f4e8ab302243ff5a6fc6147f379Konstantin Khlebnikov /* VM_IO | VM_DONTEXPAND | VM_DONTDUMP are set by remap_pfn_range() */ 61314e51b9851b4f4e8ab302243ff5a6fc6147f379Konstantin Khlebnikov 6214778d9072e53d2171f66ffd9657daff41acfaedDavid S. Miller vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); 6314778d9072e53d2171f66ffd9657daff41acfaedDavid S. Miller 641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Each page, see which map applies */ 651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (page = 0; page < size; ){ 661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds map_size = 0; 671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; map[i].size; i++) 681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (map[i].voff == off+page) { 691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds map_size = sbusfb_mmapsize(map[i].size, fbsize); 701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef __sparc_v9__ 711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define POFF_MASK (PAGE_MASK|0x1UL) 721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#else 731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define POFF_MASK (PAGE_MASK) 741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds map_offset = (physbase + map[i].poff) & POFF_MASK; 761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 782dfd7cf6ce581621c5c0103f96cca7a9924b5f94Zac Storer if (!map_size) { 791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds page += PAGE_SIZE; 801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds continue; 811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (page + map_size > size) 831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds map_size = size - page; 841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds r = io_remap_pfn_range(vma, 851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds vma->vm_start + page, 861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MK_IOSPACE_PFN(iospace, 871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds map_offset >> PAGE_SHIFT), 881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds map_size, 891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds vma->vm_page_prot); 901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (r) 911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EAGAIN; 921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds page += map_size; 931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(sbusfb_mmap_helper); 981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint sbusfb_ioctl_helper(unsigned long cmd, unsigned long arg, 1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct fb_info *info, 1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int type, int fb_depth, unsigned long fb_size) 1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch(cmd) { 1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case FBIOGTYPE: { 1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct fbtype __user *f = (struct fbtype __user *) arg; 1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (put_user(type, &f->fb_type) || 1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __put_user(info->var.yres, &f->fb_height) || 1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __put_user(info->var.xres, &f->fb_width) || 1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __put_user(fb_depth, &f->fb_depth) || 1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __put_user(0, &f->fb_cmsize) || 1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __put_user(fb_size, &f->fb_cmsize)) 1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EFAULT; 1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case FBIOPUTCMAP_SPARC: { 1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct fbcmap __user *c = (struct fbcmap __user *) arg; 1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct fb_cmap cmap; 1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u16 red, green, blue; 1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 red8, green8, blue8; 1211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned char __user *ured; 1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned char __user *ugreen; 1231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned char __user *ublue; 1241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int index, count, i; 1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (get_user(index, &c->index) || 1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __get_user(count, &c->count) || 1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __get_user(ured, &c->red) || 1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __get_user(ugreen, &c->green) || 1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __get_user(ublue, &c->blue)) 1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EFAULT; 1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cmap.len = 1; 1341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cmap.red = &red; 1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cmap.green = &green; 1361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cmap.blue = &blue; 1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cmap.transp = NULL; 1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < count; i++) { 1391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int err; 1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (get_user(red8, &ured[i]) || 1421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds get_user(green8, &ugreen[i]) || 1431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds get_user(blue8, &ublue[i])) 1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EFAULT; 1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds red = red8 << 8; 1471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds green = green8 << 8; 1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds blue = blue8 << 8; 1491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cmap.start = index + i; 1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = fb_set_cmap(&cmap, info); 1521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (err) 1531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return err; 1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case FBIOGETCMAP_SPARC: { 1581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct fbcmap __user *c = (struct fbcmap __user *) arg; 1591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned char __user *ured; 1601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned char __user *ugreen; 1611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned char __user *ublue; 1621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct fb_cmap *cmap = &info->cmap; 1631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int index, count, i; 1641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 red, green, blue; 1651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (get_user(index, &c->index) || 1671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __get_user(count, &c->count) || 1681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __get_user(ured, &c->red) || 1691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __get_user(ugreen, &c->green) || 1701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __get_user(ublue, &c->blue)) 1711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EFAULT; 1721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (index + count > cmap->len) 1741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EINVAL; 1751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < count; i++) { 1771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds red = cmap->red[index + i] >> 8; 1781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds green = cmap->green[index + i] >> 8; 1791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds blue = cmap->blue[index + i] >> 8; 1801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (put_user(red, &ured[i]) || 1811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds put_user(green, &ugreen[i]) || 1821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds put_user(blue, &ublue[i])) 1831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EFAULT; 1841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 1861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 1881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EINVAL; 189cf6ac4ce1bdf2d0718d5f33d62f695e105706a5dJoe Perches } 1901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(sbusfb_ioctl_helper); 1929ffb83bcc5c5337f980dc0576bf13ac9bd4fd33dChristoph Hellwig 1939ffb83bcc5c5337f980dc0576bf13ac9bd4fd33dChristoph Hellwig#ifdef CONFIG_COMPAT 194c7006638a50cbf16bb420fa91e5af2dd22d28621David S. Millerstatic int fbiogetputcmap(struct fb_info *info, unsigned int cmd, unsigned long arg) 1959ffb83bcc5c5337f980dc0576bf13ac9bd4fd33dChristoph Hellwig{ 1969ffb83bcc5c5337f980dc0576bf13ac9bd4fd33dChristoph Hellwig struct fbcmap32 __user *argp = (void __user *)arg; 1979ffb83bcc5c5337f980dc0576bf13ac9bd4fd33dChristoph Hellwig struct fbcmap __user *p = compat_alloc_user_space(sizeof(*p)); 1989ffb83bcc5c5337f980dc0576bf13ac9bd4fd33dChristoph Hellwig u32 addr; 1999ffb83bcc5c5337f980dc0576bf13ac9bd4fd33dChristoph Hellwig int ret; 2009ffb83bcc5c5337f980dc0576bf13ac9bd4fd33dChristoph Hellwig 2019ffb83bcc5c5337f980dc0576bf13ac9bd4fd33dChristoph Hellwig ret = copy_in_user(p, argp, 2 * sizeof(int)); 2029ffb83bcc5c5337f980dc0576bf13ac9bd4fd33dChristoph Hellwig ret |= get_user(addr, &argp->red); 2039ffb83bcc5c5337f980dc0576bf13ac9bd4fd33dChristoph Hellwig ret |= put_user(compat_ptr(addr), &p->red); 2049ffb83bcc5c5337f980dc0576bf13ac9bd4fd33dChristoph Hellwig ret |= get_user(addr, &argp->green); 2059ffb83bcc5c5337f980dc0576bf13ac9bd4fd33dChristoph Hellwig ret |= put_user(compat_ptr(addr), &p->green); 2069ffb83bcc5c5337f980dc0576bf13ac9bd4fd33dChristoph Hellwig ret |= get_user(addr, &argp->blue); 2079ffb83bcc5c5337f980dc0576bf13ac9bd4fd33dChristoph Hellwig ret |= put_user(compat_ptr(addr), &p->blue); 2089ffb83bcc5c5337f980dc0576bf13ac9bd4fd33dChristoph Hellwig if (ret) 2099ffb83bcc5c5337f980dc0576bf13ac9bd4fd33dChristoph Hellwig return -EFAULT; 2105ebdce726baf17eb66c5a1bf402ae6f161a082edChristoph Hellwig return info->fbops->fb_ioctl(info, 2119ffb83bcc5c5337f980dc0576bf13ac9bd4fd33dChristoph Hellwig (cmd == FBIOPUTCMAP32) ? 2129ffb83bcc5c5337f980dc0576bf13ac9bd4fd33dChristoph Hellwig FBIOPUTCMAP_SPARC : FBIOGETCMAP_SPARC, 2135ebdce726baf17eb66c5a1bf402ae6f161a082edChristoph Hellwig (unsigned long)p); 2149ffb83bcc5c5337f980dc0576bf13ac9bd4fd33dChristoph Hellwig} 2159ffb83bcc5c5337f980dc0576bf13ac9bd4fd33dChristoph Hellwig 216c7006638a50cbf16bb420fa91e5af2dd22d28621David S. Millerstatic int fbiogscursor(struct fb_info *info, unsigned long arg) 2179ffb83bcc5c5337f980dc0576bf13ac9bd4fd33dChristoph Hellwig{ 2189ffb83bcc5c5337f980dc0576bf13ac9bd4fd33dChristoph Hellwig struct fbcursor __user *p = compat_alloc_user_space(sizeof(*p)); 2199ffb83bcc5c5337f980dc0576bf13ac9bd4fd33dChristoph Hellwig struct fbcursor32 __user *argp = (void __user *)arg; 2209ffb83bcc5c5337f980dc0576bf13ac9bd4fd33dChristoph Hellwig compat_uptr_t addr; 2219ffb83bcc5c5337f980dc0576bf13ac9bd4fd33dChristoph Hellwig int ret; 2229ffb83bcc5c5337f980dc0576bf13ac9bd4fd33dChristoph Hellwig 2239ffb83bcc5c5337f980dc0576bf13ac9bd4fd33dChristoph Hellwig ret = copy_in_user(p, argp, 2249ffb83bcc5c5337f980dc0576bf13ac9bd4fd33dChristoph Hellwig 2 * sizeof (short) + 2 * sizeof(struct fbcurpos)); 2259ffb83bcc5c5337f980dc0576bf13ac9bd4fd33dChristoph Hellwig ret |= copy_in_user(&p->size, &argp->size, sizeof(struct fbcurpos)); 2269ffb83bcc5c5337f980dc0576bf13ac9bd4fd33dChristoph Hellwig ret |= copy_in_user(&p->cmap, &argp->cmap, 2 * sizeof(int)); 2279ffb83bcc5c5337f980dc0576bf13ac9bd4fd33dChristoph Hellwig ret |= get_user(addr, &argp->cmap.red); 2289ffb83bcc5c5337f980dc0576bf13ac9bd4fd33dChristoph Hellwig ret |= put_user(compat_ptr(addr), &p->cmap.red); 2299ffb83bcc5c5337f980dc0576bf13ac9bd4fd33dChristoph Hellwig ret |= get_user(addr, &argp->cmap.green); 2309ffb83bcc5c5337f980dc0576bf13ac9bd4fd33dChristoph Hellwig ret |= put_user(compat_ptr(addr), &p->cmap.green); 2319ffb83bcc5c5337f980dc0576bf13ac9bd4fd33dChristoph Hellwig ret |= get_user(addr, &argp->cmap.blue); 2329ffb83bcc5c5337f980dc0576bf13ac9bd4fd33dChristoph Hellwig ret |= put_user(compat_ptr(addr), &p->cmap.blue); 2339ffb83bcc5c5337f980dc0576bf13ac9bd4fd33dChristoph Hellwig ret |= get_user(addr, &argp->mask); 2349ffb83bcc5c5337f980dc0576bf13ac9bd4fd33dChristoph Hellwig ret |= put_user(compat_ptr(addr), &p->mask); 2359ffb83bcc5c5337f980dc0576bf13ac9bd4fd33dChristoph Hellwig ret |= get_user(addr, &argp->image); 2369ffb83bcc5c5337f980dc0576bf13ac9bd4fd33dChristoph Hellwig ret |= put_user(compat_ptr(addr), &p->image); 2379ffb83bcc5c5337f980dc0576bf13ac9bd4fd33dChristoph Hellwig if (ret) 2389ffb83bcc5c5337f980dc0576bf13ac9bd4fd33dChristoph Hellwig return -EFAULT; 2395ebdce726baf17eb66c5a1bf402ae6f161a082edChristoph Hellwig return info->fbops->fb_ioctl(info, FBIOSCURSOR, (unsigned long)p); 2409ffb83bcc5c5337f980dc0576bf13ac9bd4fd33dChristoph Hellwig} 2419ffb83bcc5c5337f980dc0576bf13ac9bd4fd33dChristoph Hellwig 242c7006638a50cbf16bb420fa91e5af2dd22d28621David S. Millerint sbusfb_compat_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg) 2439ffb83bcc5c5337f980dc0576bf13ac9bd4fd33dChristoph Hellwig{ 2449ffb83bcc5c5337f980dc0576bf13ac9bd4fd33dChristoph Hellwig switch (cmd) { 2459ffb83bcc5c5337f980dc0576bf13ac9bd4fd33dChristoph Hellwig case FBIOGTYPE: 2469ffb83bcc5c5337f980dc0576bf13ac9bd4fd33dChristoph Hellwig case FBIOSATTR: 2479ffb83bcc5c5337f980dc0576bf13ac9bd4fd33dChristoph Hellwig case FBIOGATTR: 2489ffb83bcc5c5337f980dc0576bf13ac9bd4fd33dChristoph Hellwig case FBIOSVIDEO: 2499ffb83bcc5c5337f980dc0576bf13ac9bd4fd33dChristoph Hellwig case FBIOGVIDEO: 2509ffb83bcc5c5337f980dc0576bf13ac9bd4fd33dChristoph Hellwig case FBIOGCURSOR32: /* This is not implemented yet. 2519ffb83bcc5c5337f980dc0576bf13ac9bd4fd33dChristoph Hellwig Later it should be converted... */ 2529ffb83bcc5c5337f980dc0576bf13ac9bd4fd33dChristoph Hellwig case FBIOSCURPOS: 2539ffb83bcc5c5337f980dc0576bf13ac9bd4fd33dChristoph Hellwig case FBIOGCURPOS: 2549ffb83bcc5c5337f980dc0576bf13ac9bd4fd33dChristoph Hellwig case FBIOGCURMAX: 2555ebdce726baf17eb66c5a1bf402ae6f161a082edChristoph Hellwig return info->fbops->fb_ioctl(info, cmd, arg); 2569ffb83bcc5c5337f980dc0576bf13ac9bd4fd33dChristoph Hellwig case FBIOPUTCMAP32: 2575ebdce726baf17eb66c5a1bf402ae6f161a082edChristoph Hellwig return fbiogetputcmap(info, cmd, arg); 2589ffb83bcc5c5337f980dc0576bf13ac9bd4fd33dChristoph Hellwig case FBIOGETCMAP32: 2595ebdce726baf17eb66c5a1bf402ae6f161a082edChristoph Hellwig return fbiogetputcmap(info, cmd, arg); 2609ffb83bcc5c5337f980dc0576bf13ac9bd4fd33dChristoph Hellwig case FBIOSCURSOR32: 2615ebdce726baf17eb66c5a1bf402ae6f161a082edChristoph Hellwig return fbiogscursor(info, arg); 2629ffb83bcc5c5337f980dc0576bf13ac9bd4fd33dChristoph Hellwig default: 2639ffb83bcc5c5337f980dc0576bf13ac9bd4fd33dChristoph Hellwig return -ENOIOCTLCMD; 2649ffb83bcc5c5337f980dc0576bf13ac9bd4fd33dChristoph Hellwig } 2659ffb83bcc5c5337f980dc0576bf13ac9bd4fd33dChristoph Hellwig} 2669ffb83bcc5c5337f980dc0576bf13ac9bd4fd33dChristoph HellwigEXPORT_SYMBOL(sbusfb_compat_ioctl); 2679ffb83bcc5c5337f980dc0576bf13ac9bd4fd33dChristoph Hellwig#endif 268