aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarek Szyprowski <m.szyprowski@samsung.com>2010-12-06 03:56:55 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2011-03-21 19:31:34 -0400
commitb25748fe612626d6c9e344482bb028d76c1e11f2 (patch)
treedc4b9029f15af23d2d2648274b0fddc8afe60e96
parent5ba3f757f0592ca001266b4a6214d0332349909c (diff)
[media] v4l: videobuf2: add read() and write() emulator
Add a generic file io (read and write) emulator for videobuf2. It uses MMAP memory type buffers and generic vb2 calls: req_bufs, qbuf and dqbuf. Video date is being copied from mmap buffers to userspace with standard copy_to_user() function. To add support for file io the driver needs to provide an additional callback - read_setup or write_setup. It should provide the default number of buffers used by emulator and flags. With these flags one can detemine the style of read() or write() emulation. By default 'streaming' style is used. With VB2_FILEIO_READ_ONCE flag one can select 'one shot' mode for read() emulator. With VB2_FILEIO_WRITE_IMMEDIATE flag one can select immediate conversion of write calls to qbuf for write() emulator, so the vb2 will not wait until each buffer is filled completely before queueing it to the driver. Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com> CC: Pawel Osciak <pawel@osciak.com> Reviewed-by: Hans Verkuil <hverkuil@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r--drivers/media/video/videobuf2-core.c399
-rw-r--r--include/media/videobuf2-core.h9
2 files changed, 408 insertions, 0 deletions
diff --git a/drivers/media/video/videobuf2-core.c b/drivers/media/video/videobuf2-core.c
index b856bd105d77..73f3b220b34a 100644
--- a/drivers/media/video/videobuf2-core.c
+++ b/drivers/media/video/videobuf2-core.c
@@ -453,6 +453,11 @@ int vb2_reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req)
453 unsigned long plane_sizes[VIDEO_MAX_PLANES]; 453 unsigned long plane_sizes[VIDEO_MAX_PLANES];
454 int ret = 0; 454 int ret = 0;
455 455
456 if (q->fileio) {
457 dprintk(1, "reqbufs: file io in progress\n");
458 return -EBUSY;
459 }
460
456 if (req->memory != V4L2_MEMORY_MMAP 461 if (req->memory != V4L2_MEMORY_MMAP
457 && req->memory != V4L2_MEMORY_USERPTR) { 462 && req->memory != V4L2_MEMORY_USERPTR) {
458 dprintk(1, "reqbufs: unsupported memory type\n"); 463 dprintk(1, "reqbufs: unsupported memory type\n");
@@ -824,6 +829,11 @@ int vb2_qbuf(struct vb2_queue *q, struct v4l2_buffer *b)
824 struct vb2_buffer *vb; 829 struct vb2_buffer *vb;
825 int ret = 0; 830 int ret = 0;
826 831
832 if (q->fileio) {
833 dprintk(1, "qbuf: file io in progress\n");
834 return -EBUSY;
835 }
836
827 if (b->type != q->type) { 837 if (b->type != q->type) {
828 dprintk(1, "qbuf: invalid buffer type\n"); 838 dprintk(1, "qbuf: invalid buffer type\n");
829 return -EINVAL; 839 return -EINVAL;
@@ -1028,6 +1038,11 @@ int vb2_dqbuf(struct vb2_queue *q, struct v4l2_buffer *b, bool nonblocking)
1028 struct vb2_buffer *vb = NULL; 1038 struct vb2_buffer *vb = NULL;
1029 int ret; 1039 int ret;
1030 1040
1041 if (q->fileio) {
1042 dprintk(1, "dqbuf: file io in progress\n");
1043 return -EBUSY;
1044 }
1045
1031 if (b->type != q->type) { 1046 if (b->type != q->type) {
1032 dprintk(1, "dqbuf: invalid buffer type\n"); 1047 dprintk(1, "dqbuf: invalid buffer type\n");
1033 return -EINVAL; 1048 return -EINVAL;
@@ -1087,6 +1102,11 @@ int vb2_streamon(struct vb2_queue *q, enum v4l2_buf_type type)
1087{ 1102{
1088 struct vb2_buffer *vb; 1103 struct vb2_buffer *vb;
1089 1104
1105 if (q->fileio) {
1106 dprintk(1, "streamon: file io in progress\n");
1107 return -EBUSY;
1108 }
1109
1090 if (type != q->type) { 1110 if (type != q->type) {
1091 dprintk(1, "streamon: invalid stream type\n"); 1111 dprintk(1, "streamon: invalid stream type\n");
1092 return -EINVAL; 1112 return -EINVAL;
@@ -1180,6 +1200,11 @@ static void __vb2_queue_cancel(struct vb2_queue *q)
1180 */ 1200 */
1181int vb2_streamoff(struct vb2_queue *q, enum v4l2_buf_type type) 1201int vb2_streamoff(struct vb2_queue *q, enum v4l2_buf_type type)
1182{ 1202{
1203 if (q->fileio) {
1204 dprintk(1, "streamoff: file io in progress\n");
1205 return -EBUSY;
1206 }
1207
1183 if (type != q->type) { 1208 if (type != q->type) {
1184 dprintk(1, "streamoff: invalid stream type\n"); 1209 dprintk(1, "streamoff: invalid stream type\n");
1185 return -EINVAL; 1210 return -EINVAL;
@@ -1303,6 +1328,8 @@ int vb2_mmap(struct vb2_queue *q, struct vm_area_struct *vma)
1303} 1328}
1304EXPORT_SYMBOL_GPL(vb2_mmap); 1329EXPORT_SYMBOL_GPL(vb2_mmap);
1305 1330
1331static int __vb2_init_fileio(struct vb2_queue *q, int read);
1332static int __vb2_cleanup_fileio(struct vb2_queue *q);
1306 1333
1307/** 1334/**
1308 * vb2_poll() - implements poll userspace operation 1335 * vb2_poll() - implements poll userspace operation
@@ -1323,9 +1350,30 @@ EXPORT_SYMBOL_GPL(vb2_mmap);
1323unsigned int vb2_poll(struct vb2_queue *q, struct file *file, poll_table *wait) 1350unsigned int vb2_poll(struct vb2_queue *q, struct file *file, poll_table *wait)
1324{ 1351{
1325 unsigned long flags; 1352 unsigned long flags;
1353 unsigned int ret;
1326 struct vb2_buffer *vb = NULL; 1354 struct vb2_buffer *vb = NULL;
1327 1355
1328 /* 1356 /*
1357 * Start file io emulator if streaming api has not been used yet.
1358 */
1359 if (q->num_buffers == 0 && q->fileio == NULL) {
1360 if (!V4L2_TYPE_IS_OUTPUT(q->type) && (q->io_modes & VB2_READ)) {
1361 ret = __vb2_init_fileio(q, 1);
1362 if (ret)
1363 return ret;
1364 }
1365 if (V4L2_TYPE_IS_OUTPUT(q->type) && (q->io_modes & VB2_WRITE)) {
1366 ret = __vb2_init_fileio(q, 0);
1367 if (ret)
1368 return ret;
1369 /*
1370 * Write to OUTPUT queue can be done immediately.
1371 */
1372 return POLLOUT | POLLWRNORM;
1373 }
1374 }
1375
1376 /*
1329 * There is nothing to wait for if no buffers have already been queued. 1377 * There is nothing to wait for if no buffers have already been queued.
1330 */ 1378 */
1331 if (list_empty(&q->queued_list)) 1379 if (list_empty(&q->queued_list))
@@ -1395,11 +1443,362 @@ EXPORT_SYMBOL_GPL(vb2_queue_init);
1395 */ 1443 */
1396void vb2_queue_release(struct vb2_queue *q) 1444void vb2_queue_release(struct vb2_queue *q)
1397{ 1445{
1446 __vb2_cleanup_fileio(q);
1398 __vb2_queue_cancel(q); 1447 __vb2_queue_cancel(q);
1399 __vb2_queue_free(q); 1448 __vb2_queue_free(q);
1400} 1449}
1401EXPORT_SYMBOL_GPL(vb2_queue_release); 1450EXPORT_SYMBOL_GPL(vb2_queue_release);
1402 1451
1452/**
1453 * struct vb2_fileio_buf - buffer context used by file io emulator
1454 *
1455 * vb2 provides a compatibility layer and emulator of file io (read and
1456 * write) calls on top of streaming API. This structure is used for
1457 * tracking context related to the buffers.
1458 */
1459struct vb2_fileio_buf {
1460 void *vaddr;
1461 unsigned int size;
1462 unsigned int pos;
1463 unsigned int queued:1;
1464};
1465
1466/**
1467 * struct vb2_fileio_data - queue context used by file io emulator
1468 *
1469 * vb2 provides a compatibility layer and emulator of file io (read and
1470 * write) calls on top of streaming API. For proper operation it required
1471 * this structure to save the driver state between each call of the read
1472 * or write function.
1473 */
1474struct vb2_fileio_data {
1475 struct v4l2_requestbuffers req;
1476 struct v4l2_buffer b;
1477 struct vb2_fileio_buf bufs[VIDEO_MAX_FRAME];
1478 unsigned int index;
1479 unsigned int q_count;
1480 unsigned int dq_count;
1481 unsigned int flags;
1482};
1483
1484/**
1485 * __vb2_init_fileio() - initialize file io emulator
1486 * @q: videobuf2 queue
1487 * @read: mode selector (1 means read, 0 means write)
1488 */
1489static int __vb2_init_fileio(struct vb2_queue *q, int read)
1490{
1491 struct vb2_fileio_data *fileio;
1492 int i, ret;
1493 unsigned int count = 0;
1494
1495 /*
1496 * Sanity check
1497 */
1498 if ((read && !(q->io_modes & VB2_READ)) ||
1499 (!read && !(q->io_modes & VB2_WRITE)))
1500 BUG();
1501
1502 /*
1503 * Check if device supports mapping buffers to kernel virtual space.
1504 */
1505 if (!q->mem_ops->vaddr)
1506 return -EBUSY;
1507
1508 /*
1509 * Check if streaming api has not been already activated.
1510 */
1511 if (q->streaming || q->num_buffers > 0)
1512 return -EBUSY;
1513
1514 /*
1515 * Start with count 1, driver can increase it in queue_setup()
1516 */
1517 count = 1;
1518
1519 dprintk(3, "setting up file io: mode %s, count %d, flags %08x\n",
1520 (read) ? "read" : "write", count, q->io_flags);
1521
1522 fileio = kzalloc(sizeof(struct vb2_fileio_data), GFP_KERNEL);
1523 if (fileio == NULL)
1524 return -ENOMEM;
1525
1526 fileio->flags = q->io_flags;
1527
1528 /*
1529 * Request buffers and use MMAP type to force driver
1530 * to allocate buffers by itself.
1531 */
1532 fileio->req.count = count;
1533 fileio->req.memory = V4L2_MEMORY_MMAP;
1534 fileio->req.type = q->type;
1535 ret = vb2_reqbufs(q, &fileio->req);
1536 if (ret)
1537 goto err_kfree;
1538
1539 /*
1540 * Check if plane_count is correct
1541 * (multiplane buffers are not supported).
1542 */
1543 if (q->bufs[0]->num_planes != 1) {
1544 fileio->req.count = 0;
1545 ret = -EBUSY;
1546 goto err_reqbufs;
1547 }
1548
1549 /*
1550 * Get kernel address of each buffer.
1551 */
1552 for (i = 0; i < q->num_buffers; i++) {
1553 fileio->bufs[i].vaddr = vb2_plane_vaddr(q->bufs[i], 0);
1554 if (fileio->bufs[i].vaddr == NULL)
1555 goto err_reqbufs;
1556 fileio->bufs[i].size = vb2_plane_size(q->bufs[i], 0);
1557 }
1558
1559 /*
1560 * Read mode requires pre queuing of all buffers.
1561 */
1562 if (read) {
1563 /*
1564 * Queue all buffers.
1565 */
1566 for (i = 0; i < q->num_buffers; i++) {
1567 struct v4l2_buffer *b = &fileio->b;
1568 memset(b, 0, sizeof(*b));
1569 b->type = q->type;
1570 b->memory = q->memory;
1571 b->index = i;
1572 ret = vb2_qbuf(q, b);
1573 if (ret)
1574 goto err_reqbufs;
1575 fileio->bufs[i].queued = 1;
1576 }
1577
1578 /*
1579 * Start streaming.
1580 */
1581 ret = vb2_streamon(q, q->type);
1582 if (ret)
1583 goto err_reqbufs;
1584 }
1585
1586 q->fileio = fileio;
1587
1588 return ret;
1589
1590err_reqbufs:
1591 vb2_reqbufs(q, &fileio->req);
1592
1593err_kfree:
1594 kfree(fileio);
1595 return ret;
1596}
1597
1598/**
1599 * __vb2_cleanup_fileio() - free resourced used by file io emulator
1600 * @q: videobuf2 queue
1601 */
1602static int __vb2_cleanup_fileio(struct vb2_queue *q)
1603{
1604 struct vb2_fileio_data *fileio = q->fileio;
1605
1606 if (fileio) {
1607 /*
1608 * Hack fileio context to enable direct calls to vb2 ioctl
1609 * interface.
1610 */
1611 q->fileio = NULL;
1612
1613 vb2_streamoff(q, q->type);
1614 fileio->req.count = 0;
1615 vb2_reqbufs(q, &fileio->req);
1616 kfree(fileio);
1617 dprintk(3, "file io emulator closed\n");
1618 }
1619 return 0;
1620}
1621
1622/**
1623 * __vb2_perform_fileio() - perform a single file io (read or write) operation
1624 * @q: videobuf2 queue
1625 * @data: pointed to target userspace buffer
1626 * @count: number of bytes to read or write
1627 * @ppos: file handle position tracking pointer
1628 * @nonblock: mode selector (1 means blocking calls, 0 means nonblocking)
1629 * @read: access mode selector (1 means read, 0 means write)
1630 */
1631static size_t __vb2_perform_fileio(struct vb2_queue *q, char __user *data, size_t count,
1632 loff_t *ppos, int nonblock, int read)
1633{
1634 struct vb2_fileio_data *fileio;
1635 struct vb2_fileio_buf *buf;
1636 int ret, index;
1637
1638 dprintk(3, "file io: mode %s, offset %ld, count %ld, %sblocking\n",
1639 read ? "read" : "write", (long)*ppos, count,
1640 nonblock ? "non" : "");
1641
1642 if (!data)
1643 return -EINVAL;
1644
1645 /*
1646 * Initialize emulator on first call.
1647 */
1648 if (!q->fileio) {
1649 ret = __vb2_init_fileio(q, read);
1650 dprintk(3, "file io: vb2_init_fileio result: %d\n", ret);
1651 if (ret)
1652 return ret;
1653 }
1654 fileio = q->fileio;
1655
1656 /*
1657 * Hack fileio context to enable direct calls to vb2 ioctl interface.
1658 * The pointer will be restored before returning from this function.
1659 */
1660 q->fileio = NULL;
1661
1662 index = fileio->index;
1663 buf = &fileio->bufs[index];
1664
1665 /*
1666 * Check if we need to dequeue the buffer.
1667 */
1668 if (buf->queued) {
1669 struct vb2_buffer *vb;
1670
1671 /*
1672 * Call vb2_dqbuf to get buffer back.
1673 */
1674 memset(&fileio->b, 0, sizeof(fileio->b));
1675 fileio->b.type = q->type;
1676 fileio->b.memory = q->memory;
1677 fileio->b.index = index;
1678 ret = vb2_dqbuf(q, &fileio->b, nonblock);
1679 dprintk(5, "file io: vb2_dqbuf result: %d\n", ret);
1680 if (ret)
1681 goto end;
1682 fileio->dq_count += 1;
1683
1684 /*
1685 * Get number of bytes filled by the driver
1686 */
1687 vb = q->bufs[index];
1688 buf->size = vb2_get_plane_payload(vb, 0);
1689 buf->queued = 0;
1690 }
1691
1692 /*
1693 * Limit count on last few bytes of the buffer.
1694 */
1695 if (buf->pos + count > buf->size) {
1696 count = buf->size - buf->pos;
1697 dprintk(5, "reducing read count: %ld\n", count);
1698 }
1699
1700 /*
1701 * Transfer data to userspace.
1702 */
1703 dprintk(3, "file io: copying %ld bytes - buffer %d, offset %u\n",
1704 count, index, buf->pos);
1705 if (read)
1706 ret = copy_to_user(data, buf->vaddr + buf->pos, count);
1707 else
1708 ret = copy_from_user(buf->vaddr + buf->pos, data, count);
1709 if (ret) {
1710 dprintk(3, "file io: error copying data\n");
1711 ret = -EFAULT;
1712 goto end;
1713 }
1714
1715 /*
1716 * Update counters.
1717 */
1718 buf->pos += count;
1719 *ppos += count;
1720
1721 /*
1722 * Queue next buffer if required.
1723 */
1724 if (buf->pos == buf->size ||
1725 (!read && (fileio->flags & VB2_FILEIO_WRITE_IMMEDIATELY))) {
1726 /*
1727 * Check if this is the last buffer to read.
1728 */
1729 if (read && (fileio->flags & VB2_FILEIO_READ_ONCE) &&
1730 fileio->dq_count == 1) {
1731 dprintk(3, "file io: read limit reached\n");
1732 /*
1733 * Restore fileio pointer and release the context.
1734 */
1735 q->fileio = fileio;
1736 return __vb2_cleanup_fileio(q);
1737 }
1738
1739 /*
1740 * Call vb2_qbuf and give buffer to the driver.
1741 */
1742 memset(&fileio->b, 0, sizeof(fileio->b));
1743 fileio->b.type = q->type;
1744 fileio->b.memory = q->memory;
1745 fileio->b.index = index;
1746 fileio->b.bytesused = buf->pos;
1747 ret = vb2_qbuf(q, &fileio->b);
1748 dprintk(5, "file io: vb2_dbuf result: %d\n", ret);
1749 if (ret)
1750 goto end;
1751
1752 /*
1753 * Buffer has been queued, update the status
1754 */
1755 buf->pos = 0;
1756 buf->queued = 1;
1757 buf->size = q->bufs[0]->v4l2_planes[0].length;
1758 fileio->q_count += 1;
1759
1760 /*
1761 * Switch to the next buffer
1762 */
1763 fileio->index = (index + 1) % q->num_buffers;
1764
1765 /*
1766 * Start streaming if required.
1767 */
1768 if (!read && !q->streaming) {
1769 ret = vb2_streamon(q, q->type);
1770 if (ret)
1771 goto end;
1772 }
1773 }
1774
1775 /*
1776 * Return proper number of bytes processed.
1777 */
1778 if (ret == 0)
1779 ret = count;
1780end:
1781 /*
1782 * Restore the fileio context and block vb2 ioctl interface.
1783 */
1784 q->fileio = fileio;
1785 return ret;
1786}
1787
1788size_t vb2_read(struct vb2_queue *q, char __user *data, size_t count,
1789 loff_t *ppos, int nonblocking)
1790{
1791 return __vb2_perform_fileio(q, data, count, ppos, nonblocking, 1);
1792}
1793EXPORT_SYMBOL_GPL(vb2_read);
1794
1795size_t vb2_write(struct vb2_queue *q, char __user *data, size_t count,
1796 loff_t *ppos, int nonblocking)
1797{
1798 return __vb2_perform_fileio(q, data, count, ppos, nonblocking, 0);
1799}
1800EXPORT_SYMBOL_GPL(vb2_write);
1801
1403MODULE_DESCRIPTION("Driver helper framework for Video for Linux 2"); 1802MODULE_DESCRIPTION("Driver helper framework for Video for Linux 2");
1404MODULE_AUTHOR("Pawel Osciak, Marek Szyprowski"); 1803MODULE_AUTHOR("Pawel Osciak, Marek Szyprowski");
1405MODULE_LICENSE("GPL"); 1804MODULE_LICENSE("GPL");
diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h
index 1dafac05ce1a..0d71fc5efc46 100644
--- a/include/media/videobuf2-core.h
+++ b/include/media/videobuf2-core.h
@@ -18,6 +18,7 @@
18#include <linux/videodev2.h> 18#include <linux/videodev2.h>
19 19
20struct vb2_alloc_ctx; 20struct vb2_alloc_ctx;
21struct vb2_fileio_data;
21 22
22/** 23/**
23 * struct vb2_mem_ops - memory handling/memory allocator operations 24 * struct vb2_mem_ops - memory handling/memory allocator operations
@@ -54,6 +55,7 @@ struct vb2_alloc_ctx;
54 * 55 *
55 * Required ops for USERPTR types: get_userptr, put_userptr. 56 * Required ops for USERPTR types: get_userptr, put_userptr.
56 * Required ops for MMAP types: alloc, put, num_users, mmap. 57 * Required ops for MMAP types: alloc, put, num_users, mmap.
58 * Required ops for read/write access types: alloc, put, num_users, vaddr
57 */ 59 */
58struct vb2_mem_ops { 60struct vb2_mem_ops {
59 void *(*alloc)(void *alloc_ctx, unsigned long size); 61 void *(*alloc)(void *alloc_ctx, unsigned long size);
@@ -249,6 +251,7 @@ struct vb2_ops {
249 * @done_wq: waitqueue for processes waiting for buffers ready to be dequeued 251 * @done_wq: waitqueue for processes waiting for buffers ready to be dequeued
250 * @alloc_ctx: memory type/allocator-specific contexts for each plane 252 * @alloc_ctx: memory type/allocator-specific contexts for each plane
251 * @streaming: current streaming state 253 * @streaming: current streaming state
254 * @fileio: file io emulator internal data, used only if emulator is active
252 */ 255 */
253struct vb2_queue { 256struct vb2_queue {
254 enum v4l2_buf_type type; 257 enum v4l2_buf_type type;
@@ -275,6 +278,8 @@ struct vb2_queue {
275 void *alloc_ctx[VIDEO_MAX_PLANES]; 278 void *alloc_ctx[VIDEO_MAX_PLANES];
276 279
277 unsigned int streaming:1; 280 unsigned int streaming:1;
281
282 struct vb2_fileio_data *fileio;
278}; 283};
279 284
280void *vb2_plane_vaddr(struct vb2_buffer *vb, unsigned int plane_no); 285void *vb2_plane_vaddr(struct vb2_buffer *vb, unsigned int plane_no);
@@ -298,6 +303,10 @@ int vb2_streamoff(struct vb2_queue *q, enum v4l2_buf_type type);
298 303
299int vb2_mmap(struct vb2_queue *q, struct vm_area_struct *vma); 304int vb2_mmap(struct vb2_queue *q, struct vm_area_struct *vma);
300unsigned int vb2_poll(struct vb2_queue *q, struct file *file, poll_table *wait); 305unsigned int vb2_poll(struct vb2_queue *q, struct file *file, poll_table *wait);
306size_t vb2_read(struct vb2_queue *q, char __user *data, size_t count,
307 loff_t *ppos, int nonblock);
308size_t vb2_write(struct vb2_queue *q, char __user *data, size_t count,
309 loff_t *ppos, int nonblock);
301 310
302/** 311/**
303 * vb2_is_streaming() - return streaming status of the queue 312 * vb2_is_streaming() - return streaming status of the queue