Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 366557
b: refs/heads/master
c: b0a1f2a
h: refs/heads/master
i:
  366555: 74bd6ce
v: v3
  • Loading branch information
Sakari Ailus authored and Mauro Carvalho Chehab committed Mar 18, 2013
1 parent c22f911 commit 3d1c9b0
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 14 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: c6c1d50b51e76b57fbf0651d38a7ae0c3fb9d5cc
refs/heads/master: b0a1f2a8420782ccb83fb4f68df37af642790560
102 changes: 89 additions & 13 deletions trunk/drivers/media/media-device.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,11 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/

#include <linux/types.h>
#include <linux/compat.h>
#include <linux/export.h>
#include <linux/ioctl.h>
#include <linux/media.h>
#include <linux/export.h>
#include <linux/types.h>

#include <media/media-device.h>
#include <media/media-devnode.h>
Expand Down Expand Up @@ -124,35 +125,31 @@ static void media_device_kpad_to_upad(const struct media_pad *kpad,
upad->flags = kpad->flags;
}

static long media_device_enum_links(struct media_device *mdev,
struct media_links_enum __user *ulinks)
static long __media_device_enum_links(struct media_device *mdev,
struct media_links_enum *links)
{
struct media_entity *entity;
struct media_links_enum links;

if (copy_from_user(&links, ulinks, sizeof(links)))
return -EFAULT;

entity = find_entity(mdev, links.entity);
entity = find_entity(mdev, links->entity);
if (entity == NULL)
return -EINVAL;

if (links.pads) {
if (links->pads) {
unsigned int p;

for (p = 0; p < entity->num_pads; p++) {
struct media_pad_desc pad;
media_device_kpad_to_upad(&entity->pads[p], &pad);
if (copy_to_user(&links.pads[p], &pad, sizeof(pad)))
if (copy_to_user(&links->pads[p], &pad, sizeof(pad)))
return -EFAULT;
}
}

if (links.links) {
if (links->links) {
struct media_link_desc __user *ulink;
unsigned int l;

for (l = 0, ulink = links.links; l < entity->num_links; l++) {
for (l = 0, ulink = links->links; l < entity->num_links; l++) {
struct media_link_desc link;

/* Ignore backlinks. */
Expand All @@ -169,8 +166,26 @@ static long media_device_enum_links(struct media_device *mdev,
ulink++;
}
}

return 0;
}

static long media_device_enum_links(struct media_device *mdev,
struct media_links_enum __user *ulinks)
{
struct media_links_enum links;
int rval;

if (copy_from_user(&links, ulinks, sizeof(links)))
return -EFAULT;

rval = __media_device_enum_links(mdev, &links);
if (rval < 0)
return rval;

if (copy_to_user(ulinks, &links, sizeof(*ulinks)))
return -EFAULT;

return 0;
}

Expand Down Expand Up @@ -251,10 +266,71 @@ static long media_device_ioctl(struct file *filp, unsigned int cmd,
return ret;
}

#ifdef CONFIG_COMPAT

struct media_links_enum32 {
__u32 entity;
compat_uptr_t pads; /* struct media_pad_desc * */
compat_uptr_t links; /* struct media_link_desc * */
__u32 reserved[4];
};

static long media_device_enum_links32(struct media_device *mdev,
struct media_links_enum32 __user *ulinks)
{
struct media_links_enum links;
compat_uptr_t pads_ptr, links_ptr;

memset(&links, 0, sizeof(links));

if (get_user(links.entity, &ulinks->entity)
|| get_user(pads_ptr, &ulinks->pads)
|| get_user(links_ptr, &ulinks->links))
return -EFAULT;

links.pads = compat_ptr(pads_ptr);
links.links = compat_ptr(links_ptr);

return __media_device_enum_links(mdev, &links);
}

#define MEDIA_IOC_ENUM_LINKS32 _IOWR('|', 0x02, struct media_links_enum32)

static long media_device_compat_ioctl(struct file *filp, unsigned int cmd,
unsigned long arg)
{
struct media_devnode *devnode = media_devnode_data(filp);
struct media_device *dev = to_media_device(devnode);
long ret;

switch (cmd) {
case MEDIA_IOC_DEVICE_INFO:
case MEDIA_IOC_ENUM_ENTITIES:
case MEDIA_IOC_SETUP_LINK:
return media_device_ioctl(filp, cmd, arg);

case MEDIA_IOC_ENUM_LINKS32:
mutex_lock(&dev->graph_mutex);
ret = media_device_enum_links32(dev,
(struct media_links_enum32 __user *)arg);
mutex_unlock(&dev->graph_mutex);
break;

default:
ret = -ENOIOCTLCMD;
}

return ret;
}
#endif /* CONFIG_COMPAT */

static const struct media_file_operations media_device_fops = {
.owner = THIS_MODULE,
.open = media_device_open,
.ioctl = media_device_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = media_device_compat_ioctl,
#endif /* CONFIG_COMPAT */
.release = media_device_close,
};

Expand Down

0 comments on commit 3d1c9b0

Please sign in to comment.