Use copyin/copyout to get a colormap from/to user space.

Also, prepare for the case of a colormap maintained in kernel space.
This commit is contained in:
pk 2000-04-04 21:47:17 +00:00
parent 2d78be17d1
commit 99dbc425e9
8 changed files with 128 additions and 56 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: bt_subr.c,v 1.9 1999/08/26 22:53:41 thorpej Exp $ */
/* $NetBSD: bt_subr.c,v 1.10 2000/04/04 21:47:17 pk Exp $ */
/*
* Copyright (c) 1993
@ -48,6 +48,7 @@
#include <sys/systm.h>
#include <sys/buf.h>
#include <sys/errno.h>
#include <sys/malloc.h>
#include <vm/vm.h>
@ -68,56 +69,127 @@
* Implement an FBIOGETCMAP-like ioctl.
*/
int
bt_getcmap(p, cm, cmsize)
register struct fbcmap *p;
bt_getcmap(p, cm, cmsize, uspace)
struct fbcmap *p;
union bt_cmap *cm;
int cmsize;
int uspace;
{
register u_int i, start, count;
register u_char *cp;
u_int i, start, count;
int error = 0;
u_char *cp, *r, *g, *b;
u_char *cbuf = NULL;
start = p->index;
count = p->count;
if (start >= cmsize || start + count > cmsize)
return (EINVAL);
if (!uvm_useracc(p->red, count, B_WRITE) ||
!uvm_useracc(p->green, count, B_WRITE) ||
!uvm_useracc(p->blue, count, B_WRITE))
return (EFAULT);
for (cp = &cm->cm_map[start][0], i = 0; i < count; cp += 3, i++) {
p->red[i] = cp[0];
p->green[i] = cp[1];
p->blue[i] = cp[2];
if (uspace) {
/* Check user buffers for appropriate access */
if (!uvm_useracc(p->red, count, B_WRITE) ||
!uvm_useracc(p->green, count, B_WRITE) ||
!uvm_useracc(p->blue, count, B_WRITE))
return (EFAULT);
/* Allocate temporary buffer for color values */
cbuf = malloc(3*count*sizeof(char), M_TEMP, M_WAITOK);
r = cbuf;
g = r + count;
b = g + count;
} else {
/* Direct access in kernel space */
r = p->red;
g = p->green;
b = p->blue;
}
return (0);
/* Copy colors from BT map to fbcmap */
for (cp = &cm->cm_map[start][0], i = 0; i < count; cp += 3, i++) {
r[i] = cp[0];
g[i] = cp[1];
b[i] = cp[2];
}
if (uspace) {
error = copyout(r, p->red, count);
if (error)
goto out;
error = copyout(g, p->green, count);
if (error)
goto out;
error = copyout(b, p->blue, count);
if (error)
goto out;
}
out:
if (cbuf != NULL)
free(cbuf, M_TEMP);
return (error);
}
/*
* Implement the software portion of an FBIOPUTCMAP-like ioctl.
*/
int
bt_putcmap(p, cm, cmsize)
register struct fbcmap *p;
bt_putcmap(p, cm, cmsize, uspace)
struct fbcmap *p;
union bt_cmap *cm;
int cmsize;
int uspace;
{
register u_int i, start, count;
register u_char *cp;
u_int i, start, count;
int error = 0;
u_char *cp, *r, *g, *b;
u_char *cbuf = NULL;
start = p->index;
count = p->count;
if (start >= cmsize || start + count > cmsize)
return (EINVAL);
if (!uvm_useracc(p->red, count, B_READ) ||
!uvm_useracc(p->green, count, B_READ) ||
!uvm_useracc(p->blue, count, B_READ))
return (EFAULT);
for (cp = &cm->cm_map[start][0], i = 0; i < count; cp += 3, i++) {
cp[0] = p->red[i];
cp[1] = p->green[i];
cp[2] = p->blue[i];
if (uspace) {
/* Check user buffers for appropriate access */
if (!uvm_useracc(p->red, count, B_READ) ||
!uvm_useracc(p->green, count, B_READ) ||
!uvm_useracc(p->blue, count, B_READ))
return (EFAULT);
/* Allocate temporary buffer for color values */
cbuf = malloc(3*count*sizeof(char), M_TEMP, M_WAITOK);
r = cbuf;
g = r + count;
b = g + count;
error = copyin(p->red, r, count);
if (error)
goto out;
error = copyin(p->green, g, count);
if (error)
goto out;
error = copyin(p->blue, b, count);
if (error)
goto out;
} else {
/* Direct access in kernel space */
r = p->red;
g = p->green;
b = p->blue;
}
return (0);
/* Copy colors from fbcmap to BT map */
for (cp = &cm->cm_map[start][0], i = 0; i < count; cp += 3, i++) {
cp[0] = r[i];
cp[1] = g[i];
cp[2] = b[i];
}
out:
if (cbuf != NULL)
free(cbuf, M_TEMP);
return (error);
}
/*

View File

@ -1,4 +1,4 @@
/* $NetBSD: btvar.h,v 1.3 1999/08/26 22:53:42 thorpej Exp $ */
/* $NetBSD: btvar.h,v 1.4 2000/04/04 21:47:17 pk Exp $ */
/*
* Copyright (c) 1993
@ -61,8 +61,8 @@ union bt_cmap {
/*
* Routines in bt_subr.c.
*/
int bt_getcmap __P((struct fbcmap *, union bt_cmap *, int));
int bt_putcmap __P((struct fbcmap *, union bt_cmap *, int));
int bt_getcmap __P((struct fbcmap *, union bt_cmap *, int, int));
int bt_putcmap __P((struct fbcmap *, union bt_cmap *, int, int));
void bt_initcmap __P((union bt_cmap *, int));
/*

View File

@ -1,4 +1,4 @@
/* $NetBSD: cgeight.c,v 1.20 2000/03/19 15:38:45 pk Exp $ */
/* $NetBSD: cgeight.c,v 1.21 2000/04/04 21:47:17 pk Exp $ */
/*-
* Copyright (c) 1996, 1997 The NetBSD Foundation, Inc.
@ -369,12 +369,12 @@ cgeightioctl(dev, cmd, data, flags, p)
break;
case FBIOGETCMAP:
return (bt_getcmap((struct fbcmap *)data, &sc->sc_cmap, 256));
#define p ((struct fbcmap *)data)
return (bt_getcmap(p, &sc->sc_cmap, 256, 1));
case FBIOPUTCMAP:
/* copy to software map */
#define p ((struct fbcmap *)data)
error = bt_putcmap(p, &sc->sc_cmap, 256);
error = bt_putcmap(p, &sc->sc_cmap, 256, 1);
if (error)
return (error);
/* now blast them into the chip */

View File

@ -1,4 +1,4 @@
/* $NetBSD: cgfour.c,v 1.20 2000/03/19 15:38:45 pk Exp $ */
/* $NetBSD: cgfour.c,v 1.21 2000/04/04 21:47:17 pk Exp $ */
/*-
* Copyright (c) 1996, 1997 The NetBSD Foundation, Inc.
@ -367,12 +367,12 @@ cgfourioctl(dev, cmd, data, flags, p)
break;
case FBIOGETCMAP:
return (bt_getcmap((struct fbcmap *)data, &sc->sc_cmap, 256));
#define p ((struct fbcmap *)data)
return (bt_getcmap(p, &sc->sc_cmap, 256, 1));
case FBIOPUTCMAP:
/* copy to software map */
#define p ((struct fbcmap *)data)
error = bt_putcmap(p, &sc->sc_cmap, 256);
error = bt_putcmap(p, &sc->sc_cmap, 256, 1);
if (error)
return (error);
/* now blast them into the chip */

View File

@ -1,4 +1,4 @@
/* $NetBSD: cgsix.c,v 1.48 2000/03/31 12:58:54 pk Exp $ */
/* $NetBSD: cgsix.c,v 1.49 2000/04/04 21:47:17 pk Exp $ */
/*-
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@ -552,12 +552,12 @@ cgsixioctl(dev, cmd, data, flags, p)
break;
case FBIOGETCMAP:
return (bt_getcmap((struct fbcmap *)data, &sc->sc_cmap, 256));
#define p ((struct fbcmap *)data)
return (bt_getcmap(p, &sc->sc_cmap, 256, 1));
case FBIOPUTCMAP:
/* copy to software map */
#define p ((struct fbcmap *)data)
error = bt_putcmap(p, &sc->sc_cmap, 256);
error = bt_putcmap(p, &sc->sc_cmap, 256, 1);
if (error)
return (error);
/* now blast them into the chip */
@ -605,7 +605,7 @@ cgsixioctl(dev, cmd, data, flags, p)
}
if (p->cmap.red != NULL) {
error = bt_getcmap(&p->cmap,
(union bt_cmap *)&cc->cc_color, 2);
(union bt_cmap *)&cc->cc_color, 2, 1);
if (error)
return (error);
} else {
@ -629,7 +629,7 @@ cgsixioctl(dev, cmd, data, flags, p)
* copies are small (8 bytes)...
*/
tcm = cc->cc_color;
error = bt_putcmap(&p->cmap, (union bt_cmap *)&tcm, 2);
error = bt_putcmap(&p->cmap, (union bt_cmap *)&tcm, 2, 1);
if (error)
return (error);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: cgthree.c,v 1.42 2000/03/19 15:38:45 pk Exp $ */
/* $NetBSD: cgthree.c,v 1.43 2000/04/04 21:47:17 pk Exp $ */
/*-
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@ -447,12 +447,12 @@ cgthreeioctl(dev, cmd, data, flags, p)
break;
case FBIOGETCMAP:
return (bt_getcmap((struct fbcmap *)data, &sc->sc_cmap, 256));
#define p ((struct fbcmap *)data)
return (bt_getcmap(p, &sc->sc_cmap, 256, 1));
case FBIOPUTCMAP:
/* copy to software map */
#define p ((struct fbcmap *)data)
error = bt_putcmap(p, &sc->sc_cmap, 256);
error = bt_putcmap(p, &sc->sc_cmap, 256, 1);
if (error)
return (error);
/* now blast them into the chip */

View File

@ -1,4 +1,4 @@
/* $NetBSD: p9100.c,v 1.9 2000/03/19 15:38:45 pk Exp $ */
/* $NetBSD: p9100.c,v 1.10 2000/04/04 21:47:17 pk Exp $ */
/*-
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@ -357,12 +357,12 @@ p9100ioctl(dev_t dev, u_long cmd, caddr_t data, int flags, struct proc *p)
break;
case FBIOGETCMAP:
return (bt_getcmap((struct fbcmap *)data, &sc->sc_cmap, 256));
#define p ((struct fbcmap *)data)
return (bt_getcmap(p, &sc->sc_cmap, 256, 1));
case FBIOPUTCMAP:
/* copy to software map */
#define p ((struct fbcmap *)data)
error = bt_putcmap(p, &sc->sc_cmap, 256);
error = bt_putcmap(p, &sc->sc_cmap, 256, 1);
if (error)
return (error);
/* now blast them into the chip */

View File

@ -1,4 +1,4 @@
/* $NetBSD: tcx.c,v 1.16 2000/03/19 15:38:45 pk Exp $ */
/* $NetBSD: tcx.c,v 1.17 2000/04/04 21:47:17 pk Exp $ */
/*
* Copyright (c) 1996,1998 The NetBSD Foundation, Inc.
@ -289,12 +289,12 @@ tcxioctl(dev, cmd, data, flags, p)
break;
case FBIOGETCMAP:
return (bt_getcmap((struct fbcmap *)data, &sc->sc_cmap, 256));
#define p ((struct fbcmap *)data)
return (bt_getcmap(p, &sc->sc_cmap, 256, 1));
case FBIOPUTCMAP:
/* copy to software map */
#define p ((struct fbcmap *)data)
error = bt_putcmap(p, &sc->sc_cmap, 256);
error = bt_putcmap(p, &sc->sc_cmap, 256, 1);
if (error)
return (error);
/* now blast them into the chip */