PERFORCE change 209637 for review
Robert Watson
rwatson at FreeBSD.org
Sun Apr 15 18:41:37 UTC 2012
http://p4web.freebsd.org/@@209637?ac=10
Change 209637 by rwatson at rwatson_svr_ctsrd_mipsbuild on 2012/04/15 18:40:34
Implement d_read and d_write methods, not just d_mmap method, for
the Terasic Multi-touch LCD display driver. I/O must be 32-bit
aligned and a multiple of 32 bits in size in order to meet the
requirements of the underlying bus (in most cases), so this is
enforced by the driver. This should allow tools such as dd to be
used to set screen contents easily, even though the preferred
usage pattern will be for frame buffer libraries to memory map
the buffer and perform I/O directly (without kernel intervention).
While here, fix two issues in the d_mmap method: properly include
the requested mapping offset when calculating the physical
address, and use ENODEV rather than EINVAL to be consistent with
the read and write methods.
Affected files ...
.. //depot/projects/ctsrd/beribsd/src/sys/dev/terasic/mtllcd/terasic_mtllcd.c#4 edit
.. //depot/projects/ctsrd/beribsd/src/sys/dev/terasic/mtllcd/terasic_mtllcd_nexus.c#3 edit
Differences ...
==== //depot/projects/ctsrd/beribsd/src/sys/dev/terasic/mtllcd/terasic_mtllcd.c#4 (text+ko) ====
@@ -37,6 +37,7 @@
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/rman.h>
+#include <sys/uio.h>
#include <machine/bus.h>
#include <machine/resource.h>
@@ -44,16 +45,82 @@
#include <dev/terasic/mtllcd/terasic_mtllcd.h>
-static d_mmap_t mtllcd_mmap;
+static d_mmap_t terasic_mtllcd_mmap;
+static d_read_t terasic_mtllcd_read;
+static d_write_t terasic_mtllcd_write;
static struct cdevsw mtllcd_cdevsw = {
.d_version = D_VERSION,
- .d_mmap = mtllcd_mmap,
+ .d_mmap = terasic_mtllcd_mmap,
+ .d_read = terasic_mtllcd_read,
+ .d_write = terasic_mtllcd_write,
.d_name = "terasic_mtllcd",
};
+/*
+ * All I/O to/from the mtllcd device must be 32-bit, and aligned to 32-bit.
+ */
static int
-mtllcd_mmap(struct cdev *dev, vm_ooffset_t offset, vm_paddr_t *paddr,
+terasic_mtllcd_read(struct cdev *dev, struct uio *uio, int flag)
+{
+ struct terasic_mtllcd_softc *sc;
+ u_long offset, size;
+ uint32_t v;
+ int error;
+
+ if (uio->uio_offset < 0 || uio->uio_offset % 4 != 0 ||
+ uio->uio_resid % 4 != 0)
+ return (ENODEV);
+ sc = dev->si_drv1;
+ TERASIC_MTLLCD_LOCK(sc);
+ size = rman_get_size(sc->mtl_res);
+ TERASIC_MTLLCD_UNLOCK(sc);
+ error = 0;
+ if ((uio->uio_offset + uio->uio_resid < 0) ||
+ (uio->uio_offset + uio->uio_resid > size))
+ return (ENODEV);
+ while (uio->uio_resid > 0) {
+ offset = uio->uio_offset;
+ if (offset + sizeof(v) > size)
+ return (ENODEV);
+ v = bus_read_4(sc->mtl_res, offset);
+ error = uiomove(&v, sizeof(v), uio);
+ if (error)
+ return (error);
+ }
+ return (error);
+}
+
+static int
+terasic_mtllcd_write(struct cdev *dev, struct uio *uio, int flag)
+{
+ struct terasic_mtllcd_softc *sc;
+ u_long offset, size;
+ uint32_t v;
+ int error;
+
+ if (uio->uio_offset < 0 || uio->uio_offset % 4 != 0 ||
+ uio->uio_resid % 4 != 0)
+ return (ENODEV);
+ sc = dev->si_drv1;
+ TERASIC_MTLLCD_LOCK(sc);
+ size = rman_get_size(sc->mtl_res);
+ TERASIC_MTLLCD_UNLOCK(sc);
+ error = 0;
+ while (uio->uio_resid > 0) {
+ error = uiomove(&v, sizeof(v), uio);
+ if (error)
+ return (error);
+ offset = uio->uio_offset;
+ if (offset + sizeof(v) > size)
+ return (ENODEV);
+ bus_write_4(sc->mtl_res, offset, v);
+ }
+ return (error);
+}
+
+static int
+terasic_mtllcd_mmap(struct cdev *dev, vm_ooffset_t offset, vm_paddr_t *paddr,
int nprot, vm_memattr_t *memattr)
{
struct terasic_mtllcd_softc *sc;
@@ -64,10 +131,10 @@
error = 0;
if (trunc_page(offset) == offset &&
rman_get_size(sc->mtl_res) >= offset + PAGE_SIZE) {
- *paddr = rman_get_start(sc->mtl_res);
+ *paddr = rman_get_start(sc->mtl_res) + offset;
*memattr = VM_MEMATTR_UNCACHED;
} else
- error = EINVAL;
+ error = ENODEV;
TERASIC_MTLLCD_UNLOCK(sc);
return (error);
}
==== //depot/projects/ctsrd/beribsd/src/sys/dev/terasic/mtllcd/terasic_mtllcd_nexus.c#3 (text+ko) ====
@@ -56,10 +56,6 @@
*
* TODO:
*
- * 1. Allow read(2) and write(2) to work on MTL frame buffer / input memory so
- * that dd(1), etc, can be used to paint the touch screen conveniently
- * when there is no windowing system running.
- *
* 2. Allow different portions of the MTL memory space to be exported via
* different device nodes -- text frame buffer, graphics frame buffer,
* touch screen input.
More information about the p4-projects
mailing list