summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcus Glocker <mglocker@cvs.openbsd.org>2008-06-09 20:51:32 +0000
committerMarcus Glocker <mglocker@cvs.openbsd.org>2008-06-09 20:51:32 +0000
commit92caf5c32eb1689e8b63a490f6069fbac91cd8e4 (patch)
tree9f7db9cddb877b6f1a4984fe28d7bfd22accf689
parent6620a808afa94330b2446a2cfcc555474ac8a184 (diff)
Let the driver switch between read() and mmap() depending on what
the userland application wants. OK robert@
-rw-r--r--sys/dev/usb/uvideo.c54
-rw-r--r--sys/dev/usb/uvideo.h3
-rw-r--r--sys/dev/video.c10
-rw-r--r--sys/dev/video_if.h3
-rw-r--r--sys/dev/videovar.h3
5 files changed, 56 insertions, 17 deletions
diff --git a/sys/dev/usb/uvideo.c b/sys/dev/usb/uvideo.c
index 9c01f93b83a..69546b43d76 100644
--- a/sys/dev/usb/uvideo.c
+++ b/sys/dev/usb/uvideo.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uvideo.c,v 1.28 2008/06/09 05:49:10 robert Exp $ */
+/* $OpenBSD: uvideo.c,v 1.29 2008/06/09 20:51:31 mglocker Exp $ */
/*
* Copyright (c) 2008 Robert Nagy <robert@openbsd.org>
@@ -101,6 +101,7 @@ void uvideo_vs_cb(usbd_xfer_handle, usbd_private_handle,
int uvideo_vs_decode_stream_header(struct uvideo_softc *,
uint8_t *, int);
int uvideo_mmap_queue(struct uvideo_softc *, uint8_t *, int);
+int uvideo_read(struct uvideo_softc *, uint8_t *, int);
#ifdef UVIDEO_DEBUG
void uvideo_dump_desc_all(struct uvideo_softc *);
void uvideo_dump_desc_vc_header(struct uvideo_softc *,
@@ -151,6 +152,7 @@ caddr_t uvideo_mappage(void *, off_t, int);
* Other hardware interface related functions
*/
int uvideo_get_bufsize(void *);
+void uvideo_start_read(void *);
#define DEVNAME(_s) ((_s)->sc_dev.dv_xname)
@@ -188,7 +190,8 @@ struct video_hw_if uvideo_hw_if = {
uvideo_streamon, /* VIDIOC_STREAMON */
uvideo_try_fmt, /* VIDIOC_TRY_FMT */
uvideo_mappage, /* mmap */
- uvideo_get_bufsize /* read */
+ uvideo_get_bufsize, /* read */
+ uvideo_start_read /* start stream for read */
};
int
@@ -261,7 +264,7 @@ uvideo_open(void *addr, int flags, int *size, uint8_t *buffer,
return(EIO);
usb_init_task(&sc->sc_task_write, uvideo_debug_file_write_sample, sc);
#endif
- //uvideo_vs_start(sc);
+ sc->sc_mmap_flag = 0;
return (0);
}
@@ -1214,16 +1217,13 @@ uvideo_vs_decode_stream_header(struct uvideo_softc *sc, uint8_t *frame,
usb_rem_task(sc->sc_udev, &sc->sc_task_write);
usb_add_task(sc->sc_udev, &sc->sc_task_write);
#endif
-#if 0
- /*
- * Copy video frame to upper layer buffer and call
- * upper layer interrupt.
- */
- *sc->sc_uplayer_fsize = fb->offset;
- bcopy(fb->buf, sc->sc_uplayer_fbuffer, fb->offset);
- sc->sc_uplayer_intr(sc->sc_uplayer_arg);
-#endif
- uvideo_mmap_queue(sc, fb->buf, fb->offset);
+ if (sc->sc_mmap_flag) {
+ /* mmap */
+ uvideo_mmap_queue(sc, fb->buf, fb->offset);
+ } else {
+ /* read */
+ uvideo_read(sc, fb->buf, fb->offset);
+ }
} else {
DPRINTF(1, "%s: %s: sample too large, skipped!\n",
DEVNAME(sc), __func__);
@@ -1272,6 +1272,20 @@ uvideo_mmap_queue(struct uvideo_softc *sc, uint8_t *buf, int len)
return (0);
}
+int
+uvideo_read(struct uvideo_softc *sc, uint8_t *buf, int len)
+{
+ /*
+ * Copy video frame to upper layer buffer and call
+ * upper layer interrupt.
+ */
+ *sc->sc_uplayer_fsize = len;
+ bcopy(buf, sc->sc_uplayer_fbuffer, len);
+ sc->sc_uplayer_intr(sc->sc_uplayer_arg);
+
+ return (0);
+}
+
#ifdef UVIDEO_DEBUG
void
uvideo_dump_desc_all(struct uvideo_softc *sc)
@@ -1939,12 +1953,26 @@ uvideo_get_bufsize(void *v)
return (sc->sc_video_buf_size);
}
+void
+uvideo_start_read(void *v)
+{
+ struct uvideo_softc *sc = v;
+
+ if (sc->sc_mmap_flag)
+ sc->sc_mmap_flag = 0;
+
+ uvideo_vs_start(sc);
+}
+
caddr_t
uvideo_mappage(void *v, off_t off, int prot)
{
struct uvideo_softc *sc = v;
caddr_t p;
+ if (!sc->sc_mmap_flag)
+ sc->sc_mmap_flag = 1;
+
p = sc->sc_mmap_buffer + off;
return (p);
diff --git a/sys/dev/usb/uvideo.h b/sys/dev/usb/uvideo.h
index 2f7fc14187e..c9a9e449b94 100644
--- a/sys/dev/usb/uvideo.h
+++ b/sys/dev/usb/uvideo.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: uvideo.h,v 1.13 2008/06/09 19:57:45 robert Exp $ */
+/* $OpenBSD: uvideo.h,v 1.14 2008/06/09 20:51:31 mglocker Exp $ */
/*
* Copyright (c) 2007 Robert Nagy <robert@openbsd.org>
@@ -401,6 +401,7 @@ struct uvideo_softc {
q_mmap sc_mmap_q;
int sc_mmap_count;
int sc_mmap_cur;
+ int sc_mmap_flag;
struct vnode *sc_vp;
struct usb_task sc_task_write;
diff --git a/sys/dev/video.c b/sys/dev/video.c
index 019a75cebd8..5eaf008d9c4 100644
--- a/sys/dev/video.c
+++ b/sys/dev/video.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: video.c,v 1.9 2008/06/09 17:13:35 robert Exp $ */
+/* $OpenBSD: video.c,v 1.10 2008/06/09 20:51:31 mglocker Exp $ */
/*
* Copyright (c) 2008 Robert Nagy <robert@openbsd.org>
*
@@ -92,6 +92,8 @@ videoopen(dev_t dev, int flags, int fmt, struct proc *p)
sc->hw_if == NULL)
return (ENXIO);
+ sc->sc_start_read = 0;
+
if (sc->hw_if->open != NULL)
return (sc->hw_if->open(sc->hw_hdl, flags, &sc->sc_fsize,
sc->sc_fbuffer, video_intr, sc));
@@ -126,6 +128,12 @@ videoread(dev_t dev, struct uio *uio, int ioflag)
if (sc->sc_dying)
return (EIO);
+ /* start the stream */
+ if (sc->hw_if->start_read && !sc->sc_start_read) {
+ sc->sc_start_read = 1;
+ sc->hw_if->start_read(sc->hw_hdl);
+ }
+
DPRINTF(("resid=%d\n", uio->uio_resid));
/* block userland read until a frame is ready */
diff --git a/sys/dev/video_if.h b/sys/dev/video_if.h
index b54c9f89ee9..c843ce09edd 100644
--- a/sys/dev/video_if.h
+++ b/sys/dev/video_if.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: video_if.h,v 1.9 2008/06/09 05:49:10 robert Exp $ */
+/* $OpenBSD: video_if.h,v 1.10 2008/06/09 20:51:31 mglocker Exp $ */
/*
* Copyright (c) 2008 Robert Nagy <robert@openbsd.org>
*
@@ -49,6 +49,7 @@ struct video_hw_if {
/* other functions */
int (*get_bufsize)(void *);
+ void (*start_read)(void *);
};
struct video_attach_args {
diff --git a/sys/dev/videovar.h b/sys/dev/videovar.h
index c8fdcb00a87..16f6d7a1730 100644
--- a/sys/dev/videovar.h
+++ b/sys/dev/videovar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: videovar.h,v 1.3 2008/05/25 07:47:47 mglocker Exp $ */
+/* $OpenBSD: videovar.h,v 1.4 2008/06/09 20:51:31 mglocker Exp $ */
/*
* Copyright (c) 2008 Robert Nagy <robert@openbsd.org>
*
@@ -27,6 +27,7 @@ struct video_softc {
int sc_fsize;
uint8_t *sc_fbuffer;
+ int sc_start_read;
};
#endif /* _SYS_DEV_VIDEOVAR_H */