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:
parent
2d78be17d1
commit
99dbc425e9
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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));
|
||||
|
||||
/*
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user