Commit Graph

85 Commits

Author SHA1 Message Date
Sakari Ailus 20b8522736 [media] media: Rename graph and pipeline structs and functions
The media_entity_pipeline_start() and media_entity_pipeline_stop()
functions are renamed as media_pipeline_start() and media_pipeline_stop(),
respectively. The reason is two-fold: the pipeline struct is, rightly,
already called media_pipeline (rather than media_entity_pipeline) and what
this really is about is a pipeline. A pipeline consists of entities ---
and, well, other objects embedded in these entities.

As the pipeline object will be in the future moved from entities to pads
in order to support multiple pipelines through a single entity, do the
renaming now.

Similarly, functions operating on struct media_entity_graph as well as the
struct itself are renamed by dropping the "entity_" part from the prefix
of the function family and the data structure. The graph traversal which
is what the functions are about is not specifically about entities only
and will operate on pads for the same reason as the media pipeline.

The patch has been generated using the following command:

git grep -l media_entity |xargs perl -i -pe '
	s/media_entity_pipeline/media_pipeline/g;
	s/media_entity_graph/media_graph/g'

And a few manual edits related to line start alignment and line wrapping.

Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
2017-01-27 16:13:24 -02:00
Sakari Ailus bcb63314e2 [media] media: Drop FSF's postal address from the source code files
Drop the FSF's postal address from the source code files that typically
contain mostly the license text. Of the 628 removed instances, 578 are
outdated.

The patch has been created with the following command without manual edits:

git grep -l "675 Mass Ave\|59 Temple Place\|51 Franklin St" -- \
	drivers/media/ include/media|while read i; do i=$i perl -e '
open(F,"< $ENV{i}");
$a=join("", <F>);
$a =~ s/[ \t]*\*\n.*You should.*\n.*along with.*\n.*(\n.*USA.*$)?\n//m
	&& $a =~ s/(^.*)Or, (point your browser to) /$1To obtain the license, $2\n$1/m;
close(F);
open(F, "> $ENV{i}");
print F $a;
close(F);'; done

Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
2017-01-27 11:38:09 -02:00
Sakari Ailus 98d85f3cb9 [media] media: Properly pass through media entity types in entity enumeration
When the functions replaced media entity types, the range which was
allowed for the types was incorrect. This meant that media entity types
for specific devices were not passed correctly to the userspace through
MEDIA_IOC_ENUM_ENTITIES. Fix it.

Fixes: commit b2cd27448b ("[media] media-device: map new functions into old types for legacy API")
Reported-and-tested-by: Antti Laakso <antti.laakso@intel.com>

Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Cc: stable@vger.kernel.org # For v4.5 and up
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
2017-01-27 11:20:33 -02:00
Shuah Khan 8c2ebcf103 [media] media: remove obsolete Media Device Managed resource interfaces
Remove obsolete media_device_get_devres(), media_device_find_devres(),
and media_device_release_devres() interfaces. These interfaces are now
obsolete.

Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
2016-11-25 07:40:40 -02:00
Max Kellermann e7cd17a29d [media] drivers/media/media-device: fix double free bug in _unregister()
While removing all interfaces in media_device_unregister(), all
media_interface pointers are freed.  This is illegal and results in
double kfree() if any media_interface is still linked at this point;
maybe because a userspace process still has a file handle.  Once the
process closes the file handle, dvb_media_device_free() gets called,
which frees the dvb_device.intf_devnode again.

This patch removes the unnecessary kfree() call, and documents who's
responsible for really freeing it.

Signed-off-by: Max Kellermann <max.kellermann@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
2016-11-18 15:29:27 -02:00
Sakari Ailus 7d4b64028c [media] media: Add flags to tell whether to take graph mutex for an IOCTL
New IOCTLs (especially for the request API) do not necessarily need the
graph mutex acquired. Leave this up to the drivers.

Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
2016-09-22 10:28:40 -03:00
Sakari Ailus bcd5081b05 [media] media: Refactor copying IOCTL arguments from and to user space
Refactor copying the IOCTL argument structs from the user space and back,
in order to reduce code copied around and make the implementation more
robust.

As a result, the copying is done while not holding the graph mutex.

Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
2016-09-22 10:25:55 -03:00
Sakari Ailus 6975264c4c [media] media: Unify IOCTL handler calling
Each IOCTL handler can be listed in an array instead of using a large and
cumbersome switch. Do that.

Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
2016-09-22 10:23:04 -03:00
Sakari Ailus cf439d5f4d [media] media: Determine early whether an IOCTL is supported
Preparation for refactoring media IOCTL handling to unify common parts.

Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
2016-09-22 10:22:15 -03:00
Shuah Khan 6f0dd24a08 [media] media: fix media devnode ioctl/syscall and unregister race
Media devnode open/ioctl could be in progress when media device unregister
is initiated. System calls and ioctls check media device registered status
at the beginning, however, there is a window where unregister could be in
progress without changing the media devnode status to unregistered.

process 1				process 2
fd = open(/dev/media0)
media_devnode_is_registered()
	(returns true here)

					media_device_unregister()
						(unregister is in progress
						and devnode isn't
						unregistered yet)
					...
ioctl(fd, ...)
__media_ioctl()
media_devnode_is_registered()
	(returns true here)
					...
					media_devnode_unregister()
					...
					(driver releases the media device
					memory)

media_device_ioctl()
	(By this point
	devnode->media_dev does not
	point to allocated memory.
	use-after free in in mutex_lock_nested)

BUG: KASAN: use-after-free in mutex_lock_nested+0x79c/0x800 at addr
ffff8801ebe914f0

Fix it by clearing register bit when unregister starts to avoid the race.

process 1                               process 2
fd = open(/dev/media0)
media_devnode_is_registered()
        (could return true here)

                                        media_device_unregister()
                                                (clear the register bit,
						 then start unregister.)
                                        ...
ioctl(fd, ...)
__media_ioctl()
media_devnode_is_registered()
        (return false here, ioctl
	 returns I/O error, and
	 will not access media
	 device memory)
                                        ...
                                        media_devnode_unregister()
                                        ...
                                        (driver releases the media device
					 memory)

Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
Suggested-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Reported-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
Tested-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
2016-06-15 17:59:28 -03:00
Shuah Khan 5b28dde51d [media] media: fix use-after-free in cdev_put() when app exits after driver unbind
When driver unbinds while media_ioctl is in progress, cdev_put() fails with
when app exits after driver unbinds.

Add devnode struct device kobj as the cdev parent kobject. cdev_add() gets
a reference to it and releases it in cdev_del() ensuring that the devnode
is not deallocated as long as the application has the device file open.

media_devnode_register() initializes the struct device kobj before calling
cdev_add(). media_devnode_unregister() does cdev_del() and then deletes the
device. devnode is released when the last reference to the struct device is
gone.

This problem is found on uvcvideo, em28xx, and au0828 drivers and fix has
been tested on all three.

kernel: [  193.599736] BUG: KASAN: use-after-free in cdev_put+0x4e/0x50
kernel: [  193.599745] Read of size 8 by task media_device_te/1851
kernel: [  193.599792] INFO: Allocated in __media_device_register+0x54
kernel: [  193.599951] INFO: Freed in media_devnode_release+0xa4/0xc0

kernel: [  193.601083] Call Trace:
kernel: [  193.601093]  [<ffffffff81aecac3>] dump_stack+0x67/0x94
kernel: [  193.601102]  [<ffffffff815359b2>] print_trailer+0x112/0x1a0
kernel: [  193.601111]  [<ffffffff8153b5e4>] object_err+0x34/0x40
kernel: [  193.601119]  [<ffffffff8153d9d4>] kasan_report_error+0x224/0x530
kernel: [  193.601128]  [<ffffffff814a2c3d>] ? kzfree+0x2d/0x40
kernel: [  193.601137]  [<ffffffff81539d72>] ? kfree+0x1d2/0x1f0
kernel: [  193.601154]  [<ffffffff8157ca7e>] ? cdev_put+0x4e/0x50
kernel: [  193.601162]  [<ffffffff8157ca7e>] cdev_put+0x4e/0x50
kernel: [  193.601170]  [<ffffffff815767eb>] __fput+0x52b/0x6c0
kernel: [  193.601179]  [<ffffffff8117743a>] ? switch_task_namespaces+0x2a
kernel: [  193.601188]  [<ffffffff815769ee>] ____fput+0xe/0x10
kernel: [  193.601196]  [<ffffffff81170023>] task_work_run+0x133/0x1f0
kernel: [  193.601204]  [<ffffffff8117746e>] ? switch_task_namespaces+0x5e
kernel: [  193.601213]  [<ffffffff8111b50c>] do_exit+0x72c/0x2c20
kernel: [  193.601224]  [<ffffffff8111ade0>] ? release_task+0x1250/0x1250
-
-
-
kernel: [  193.601360]  [<ffffffff81003587>] ? exit_to_usermode_loop+0xe7
kernel: [  193.601368]  [<ffffffff810035c0>] exit_to_usermode_loop+0x120
kernel: [  193.601376]  [<ffffffff810061da>] syscall_return_slowpath+0x16a
kernel: [  193.601386]  [<ffffffff82848b33>] entry_SYSCALL_64_fastpath+0xa6

Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
Tested-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
2016-06-15 17:58:06 -03:00
Mauro Carvalho Chehab a087ce704b [media] media-device: dynamically allocate struct media_devnode
struct media_devnode is currently embedded at struct media_device.

While this works fine during normal usage, it leads to a race
condition during devnode unregister. the problem is that drivers
assume that, after calling media_device_unregister(), the struct
that contains media_device can be freed. This is not true, as it
can't be freed until userspace closes all opened /dev/media devnodes.

In other words, if the media devnode is still open, and media_device
gets freed, any call to an ioctl will make the core to try to access
struct media_device, with will cause an use-after-free and even GPF.

Fix this by dynamically allocating the struct media_devnode and only
freeing it when it is safe.

Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
2016-06-15 17:57:24 -03:00
Mauro Carvalho Chehab a022f9347a Linux 4.6-rc7
-----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1
 
 iQEcBAABAgAGBQJXL7HfAAoJEHm+PkMAQRiGYe8IAJBGaPUq38EJh2YOV+AQf9v6
 t/alhwB3DUE1E0zjLy7I7JJ+xDXtKjZh9fS6OFuIS8Q3RIrBteIJ/oH8TPpt7yZ/
 SnP6rYPvYD6CImTyrh7+ORL/udEwJX8+YqFYAgUAq167gvpDjYj8r26VzdIaIN4/
 oBbL8NrQNWfODieywYyhUoitVhwMz09zmBfLtGVks4vd2jUJk2Fdd9cOtGV5tRfk
 DPndPgyQtbr8W0mKovV8sT9WkQeV5TsUr4MLgf7hjnAGYQ8+0KamkzzVVLBeBiiw
 uazyrOCFkddZp+N7KbmbOmazV/yULRuLGgDjVKazoCsOaKOvoGCzrCk7daOPy6Q=
 =CegX
 -----END PGP SIGNATURE-----

Merge tag 'v4.6-rc7' into patchwork

Linux 4.6-rc7

* tag 'v4.6-rc7': (185 commits)
  Linux 4.6-rc7
  parisc: fix a bug when syscall number of tracee is __NR_Linux_syscalls
  x86/tsc: Read all ratio bits from MSR_PLATFORM_INFO
  mailmap: add John Paul Adrian Glaubitz
  byteswap: try to avoid __builtin_constant_p gcc bug
  lib/stackdepot: avoid to return 0 handle
  mm: fix kcompactd hang during memory offlining
  modpost: fix module autoloading for OF devices with generic compatible property
  proc: prevent accessing /proc/<PID>/environ until it's ready
  mm/zswap: provide unique zpool name
  mm: thp: kvm: fix memory corruption in KVM with THP enabled
  MAINTAINERS: fix Rajendra Nayak's address
  mm, cma: prevent nr_isolated_* counters from going negative
  mm: update min_free_kbytes from khugepaged after core initialization
  huge pagecache: mmap_sem is unlocked when truncation splits pmd
  rapidio/mport_cdev: fix uapi type definitions
  mm: memcontrol: let v2 cgroups follow changes in system swappiness
  mm: thp: correct split_huge_pages file permission
  maintainers: update rmk's email address(es)
  writeback: Fix performance regression in wb_over_bg_thresh()
  ...
2016-05-09 12:21:49 -03:00
Mauro Carvalho Chehab f73696275e [media] media-device: Simplify compat32 logic
Only MEDIA_IOC_ENUM_LINKS32 require an special logic when
userspace is 32 bits and Kernel is 64 bits.

For the rest, media_device_ioctl() will do the right thing,
and will return -ENOIOCTLCMD if the ioctl is unknown.

Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2016-05-07 11:52:11 -03:00
Max Kellermann c56d34a73e [media] drivers/media/media-device: move debug log before _devnode_unregister()
After media_devnode_unregister(), the struct media_device may be freed
already, and dereferencing it may crash.

Signed-off-by: Max Kellermann <max@duempel.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2016-05-07 11:24:02 -03:00
Mauro Carvalho Chehab b34ecd5aa3 [media] media-device: fix builds when USB or PCI is compiled as module
Just checking ifdef CONFIG_USB is not enough, if the USB is compiled
as module. The same applies to PCI.

Tested with the following .config alternatives:

CONFIG_USB=m
CONFIG_MEDIA_CONTROLLER=y
CONFIG_MEDIA_SUPPORT=m
CONFIG_VIDEO_AU0828=m

CONFIG_USB=m
CONFIG_MEDIA_CONTROLLER=y
CONFIG_MEDIA_SUPPORT=y
CONFIG_VIDEO_AU0828=m

CONFIG_USB=y
CONFIG_MEDIA_CONTROLLER=y
CONFIG_MEDIA_SUPPORT=y
CONFIG_VIDEO_AU0828=m

CONFIG_USB=y
CONFIG_MEDIA_CONTROLLER=y
CONFIG_MEDIA_SUPPORT=y
CONFIG_VIDEO_AU0828=y

Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2016-05-05 08:01:34 -03:00
Mauro Carvalho Chehab e2c91d4d78 [media] media-device: get rid of the spinlock
Right now, the lock schema for media_device struct is messy,
since sometimes, it is protected via a spin lock, while, for
media graph traversal, it is protected by a mutex.

Solve this conflict by always using a mutex.

As a side effect, this prevents a bug when the media notifiers
is called at atomic context, while running the notifier callback:

 BUG: sleeping function called from invalid context at mm/slub.c:1289
 in_atomic(): 1, irqs_disabled(): 0, pid: 3479, name: modprobe
 4 locks held by modprobe/3479:
 #0:  (&dev->mutex){......}, at: [<ffffffff81ce8933>] __driver_attach+0xa3/0x160
 #1:  (&dev->mutex){......}, at: [<ffffffff81ce8941>] __driver_attach+0xb1/0x160
 #2:  (register_mutex#5){+.+.+.}, at: [<ffffffffa10596c7>] usb_audio_probe+0x257/0x1c90 [snd_usb_audio]
 #3:  (&(&mdev->lock)->rlock){+.+.+.}, at: [<ffffffffa0e6051b>] media_device_register_entity+0x1cb/0x700 [media]
 CPU: 2 PID: 3479 Comm: modprobe Not tainted 4.5.0-rc3+ #49
 Hardware name:                  /NUC5i7RYB, BIOS RYBDWi35.86A.0350.2015.0812.1722 08/12/2015
 0000000000000000 ffff8803b3f6f288 ffffffff81933901 ffff8803c4bae000
 ffff8803c4bae5c8 ffff8803b3f6f2b0 ffffffff811c6af5 ffff8803c4bae000
 ffffffff8285d7f6 0000000000000509 ffff8803b3f6f2f0 ffffffff811c6ce5
 Call Trace:
 [<ffffffff81933901>] dump_stack+0x85/0xc4
 [<ffffffff811c6af5>] ___might_sleep+0x245/0x3a0
 [<ffffffff811c6ce5>] __might_sleep+0x95/0x1a0
 [<ffffffff8155aade>] kmem_cache_alloc_trace+0x20e/0x300
 [<ffffffffa0e66e3d>] ? media_add_link+0x4d/0x140 [media]
 [<ffffffffa0e66e3d>] media_add_link+0x4d/0x140 [media]
 [<ffffffffa0e69931>] media_create_pad_link+0xa1/0x600 [media]
 [<ffffffffa0fe11b3>] au0828_media_graph_notify+0x173/0x360 [au0828]
 [<ffffffffa0e68a6a>] ? media_gobj_create+0x1ba/0x480 [media]
 [<ffffffffa0e606fb>] media_device_register_entity+0x3ab/0x700 [media]

Reviewed-by: Javier Martinez Canillas <javier@osg.samsung.com>
Acked-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2016-04-20 13:12:02 -03:00
Mauro Carvalho Chehab 8331c055b2 Merge commit '840f5b0572ea' into v4l_for_linus
* commit '840f5b0572ea': (381 commits)
  media: au0828 disable tuner to demod link in au0828_media_device_register()
  [media] touptek: cast char types on %x printk
  [media] touptek: don't DMA at the stack
  [media] mceusb: use %*ph for small buffer dumps
  [media] v4l: exynos4-is: Drop unneeded check when setting up fimc-lite links
  [media] v4l: vsp1: Check if an entity is a subdev with the right function
  [media] hide unused functions for !MEDIA_CONTROLLER
  [media] em28xx: fix Terratec Grabby AC97 codec detection
  [media] media: add prefixes to interface types
  [media] media: rc: nuvoton: switch attribute wakeup_data to text
  [media] v4l2-ioctl: fix YUV422P pixel format description
  [media] media: fix null pointer dereference in v4l_vb2q_enable_media_source()
  [media] v4l2-mc.h: fix yet more compiler errors
  [media] staging/media: add missing TODO files
  [media] media.h: always start with 1 for the audio entities
  [media] sound/usb: Use meaninful names for goto labels
  [media] v4l2-mc.h: fix compiler warnings
  [media] media: au0828 audio mixer isn't connected to decoder
  [media] sound/usb: Use Media Controller API to share media resources
  [media] dw2102: add support for TeVii S662
  ...
2016-03-15 07:48:28 -03:00
Mauro Carvalho Chehab b2cd27448b [media] media-device: map new functions into old types for legacy API
The legacy media controller userspace API exposes entity types that
carry both type and function information. The new API replaces the type
with a function. It preserves backward compatibility by defining legacy
functions for the existing types and using them in drivers.

This works fine, as long as newer entity functions won't be added.

Unfortunately, some tools, like media-ctl with --print-dot argument
rely on the now legacy MEDIA_ENT_T_V4L2_SUBDEV and MEDIA_ENT_T_DEVNODE
numeric ranges to identify what entities will be shown.

Also, if the entity doesn't match those ranges, it will ignore the
major/minor information on devnodes, and won't be getting the devnode
name via udev or sysfs.

As we're now adding devices outside the old range, the legacy ioctl
needs to map the new entity functions into a type at the old range,
or otherwise we'll have a regression.

Detected on all released media-ctl versions (e. g. versions <= 1.10).

Fix this by deriving the type from the function to emulate the legacy
API if the function isn't in the legacy functions range.

Reported-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2016-03-10 15:10:59 -03:00
Sakari Ailus d37410c272 [media] media: Properly handle user pointers
Mark pointers containing user pointers as such.

Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2016-03-03 13:03:06 -03:00
Sakari Ailus 0629e991a2 [media] media: Move media_get_uptr() macro out of the media.h user space header
The media_get_uptr() macro is mostly useful only for the IOCTL handling
code in media-device.c so move it there.

Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2016-03-03 13:02:44 -03:00
Sakari Ailus 0c426c472b [media] media: Always keep a graph walk large enough around
Re-create the graph walk object as needed in order to have one large enough
available for all entities in the graph.

This enumeration is used for pipeline power management in the future.

[mchehab@osg.samsung.com: fix documentation bug:
 " warning: bad line: graph_mutex"]

Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2016-03-03 12:17:28 -03:00
Shuah Khan afcbdb5589 [media] media: Media Controller register/unregister entity_notify API
Add new interfaces to register and unregister entity_notify
hook to media device. These interfaces allow drivers to add
hooks to take appropriate actions when new entities get added
to a shared media device. For example, au0828 bridge driver
registers an entity_notify hook to create links as needed
between media graph nodes.

[mchehab@osg.samsung.com: simple comments should be /* and not /**]

Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2016-02-27 08:33:25 -03:00
Mauro Carvalho Chehab 6cf5dad17e [media] media_device: move allocation out of media_device_*_init
Right now, media_device_pci_init and media_device_usb_init does
media_device allocation internaly. That preents its usage when
the media_device struct is embedded on some other structure.

Move memory allocation outside it, to make it more generic.

Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2016-02-23 07:19:39 -03:00
Mauro Carvalho Chehab 41b44e35ba [media] media-device: move PCI/USB helper functions from v4l2-mc
Those ancillary functions could be called even when compiled
without V4L2 support, as warned by ktest build robot:

All errors (new ones prefixed by >>):

>> ERROR: "__v4l2_mc_usb_media_device_init" [drivers/media/usb/dvb-usb/dvb-usb.ko] undefined!
>> ERROR: "__v4l2_mc_usb_media_device_init" [drivers/media/usb/dvb-usb-v2/dvb_usb_v2.ko] undefined!
>> ERROR: "__v4l2_mc_usb_media_device_init" [drivers/media/usb/au0828/au0828.ko] undefined!

Also, there's nothing there that are specific to V4L2. So, move
those ancillary functions to MC core.

No functional changes. Just function rename.

Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2016-02-23 07:18:45 -03:00
Mauro Carvalho Chehab bb07bd6b68 [media] allow overriding the driver name
On USB drivers, the dev struct is usually filled with the USB
device. That would mean that the name of the driver specified
by media_device.dev.driver.name would be "usb", instead of the
name of the actual driver that created the media entity.

Add an optional field at the internal struct to allow drivers
to override the driver name.

Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2016-02-16 08:41:10 -02:00
Mauro Carvalho Chehab 333a651534 Revert "[media] Postpone the addition of MEDIA_IOC_G_TOPOLOGY"
Enable MEDIA_IOC_G_TOPOLOGY ioctl for Kernel 4.6.

This reverts commit be0270ec89.

Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2016-01-25 07:29:43 -02:00
Mauro Carvalho Chehab be0270ec89 [media] Postpone the addition of MEDIA_IOC_G_TOPOLOGY
There are a few discussions left with regards to this ioctl:

1) the name of the new structs will contain _v2_ on it?
2) what's the best alternative to avoid compat32 issues?

Due to that, let's postpone the addition of this new ioctl to
the next Kernel version, to give people more time to discuss it.

Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2016-01-11 12:35:17 -02:00
Mauro Carvalho Chehab ba0dd729bf [media] media-entity: don't sleep at media_device_register_entity()
media_device_register_entity() is protected by a spin_lock.

Calling ida_pre_get() with GFP_KERNEL may put it to sleep,
with is a bad idea and causes this warning:

[ 8812.397195] BUG: sleeping function called from invalid context at mm/slub.c:1287
[ 8812.397203] in_atomic(): 1, irqs_disabled(): 0, pid: 15179, name: modprobe
[ 8812.397207] INFO: lockdep is turned off.
[ 8812.397213] CPU: 2 PID: 15179 Comm: modprobe Tainted: G    B           4.4.0-rc2+ #41
[ 8812.397218] Hardware name:                  /NUC5i7RYB, BIOS RYBDWi35.86A.0350.2015.0812.1722 08/12/2015
[ 8812.397222]  0000000000000000 ffff880314c77268 ffffffff818f8ba7 ffff8803b17dde00
[ 8812.397232]  ffff880314c77290 ffffffff811c2ee5 ffff8803b17dde00 ffffffff8284dbc9
[ 8812.397241]  0000000000000507 ffff880314c772d0 ffffffff811c30d5 0000000041b58ab3
[ 8812.397250] Call Trace:
[ 8812.397258]  [<ffffffff818f8ba7>] dump_stack+0x4b/0x64
[ 8812.397265]  [<ffffffff811c2ee5>] ___might_sleep+0x245/0x3a0
[ 8812.397270]  [<ffffffff811c30d5>] __might_sleep+0x95/0x1a0
[ 8812.397276]  [<ffffffff818fd083>] ? ida_pre_get+0x113/0x250
[ 8812.397282]  [<ffffffff8153bb77>] kmem_cache_alloc+0x197/0x250
[ 8812.397288]  [<ffffffff818fd083>] ida_pre_get+0x113/0x250
[ 8812.397293]  [<ffffffff818fd265>] ida_simple_get+0xa5/0x170
[ 8812.397298]  [<ffffffff818fd1c0>] ? ida_pre_get+0x250/0x250
[ 8812.397306]  [<ffffffffa07382d1>] media_device_register_entity+0x171/0x420 [media]
[ 8812.397318]  [<ffffffffa129e76f>] v4l2_device_register_subdev+0x34f/0x640 [videodev]
[ 8812.397324]  [<ffffffffa0768dea>] v4l2_i2c_new_subdev_board+0x12a/0x250 [v4l2_common]
[ 8812.397330]  [<ffffffffa0768fe7>] v4l2_i2c_new_subdev+0xd7/0x110 [v4l2_common]
[ 8812.397337]  [<ffffffffa0768f10>] ? v4l2_i2c_new_subdev_board+0x250/0x250 [v4l2_common]
[ 8812.397347]  [<ffffffffa13d2f76>] au0828_card_analog_fe_setup+0x2e6/0x3f0 [au0828]
[ 8812.397352]  [<ffffffff814450cc>] ? power_down+0xc4/0xc4
[ 8812.397361]  [<ffffffffa13d2c90>] ? au0828_tuner_callback+0x160/0x160 [au0828]
[ 8812.397370]  [<ffffffffa13d319f>] au0828_card_setup+0x11f/0x340 [au0828]
[ 8812.397378]  [<ffffffffa13d3080>] ? au0828_card_analog_fe_setup+0x3f0/0x3f0 [au0828]
[ 8812.397384]  [<ffffffff812a575b>] ? msleep+0x7b/0xc0
[ 8812.397393]  [<ffffffffa13d0d79>] au0828_usb_probe+0x679/0xcf0 [au0828]
[ 8812.397399]  [<ffffffff81d7619d>] usb_probe_interface+0x45d/0x940
[ 8812.397406]  [<ffffffff81ca7004>] driver_probe_device+0x454/0xd90
[ 8812.397411]  [<ffffffff81ca7940>] ? driver_probe_device+0xd90/0xd90
[ 8812.397417]  [<ffffffff81ca7940>] ? driver_probe_device+0xd90/0xd90
[ 8812.397422]  [<ffffffff81ca7a61>] __driver_attach+0x121/0x160
[ 8812.397427]  [<ffffffff81ca141f>] bus_for_each_dev+0x11f/0x1a0
[ 8812.397433]  [<ffffffff81ca1300>] ? subsys_dev_iter_exit+0x10/0x10
[ 8812.397439]  [<ffffffff822917d7>] ? _raw_spin_unlock+0x27/0x40
[ 8812.397445]  [<ffffffff81ca5d4d>] driver_attach+0x3d/0x50
[ 8812.397450]  [<ffffffff81ca5039>] bus_add_driver+0x4c9/0x770
[ 8812.397456]  [<ffffffff81ca944c>] driver_register+0x18c/0x3b0
[ 8812.397462]  [<ffffffff8124c952>] ? __raw_spin_lock_init+0x32/0x100
[ 8812.397468]  [<ffffffff81d71e58>] usb_register_driver+0x1f8/0x440
[ 8812.397473]  [<ffffffffa0208000>] ? 0xffffffffa0208000
[ 8812.397481]  [<ffffffffa02080b7>] au0828_init+0xb7/0x1000 [au0828]
[ 8812.397486]  [<ffffffff810021b1>] do_one_initcall+0x141/0x300
[ 8812.397492]  [<ffffffff81002070>] ? try_to_run_init_process+0x40/0x40
[ 8812.397497]  [<ffffffff8123bbf6>] ? trace_hardirqs_on_caller+0x16/0x590
[ 8812.397502]  [<ffffffff815406e6>] ? kasan_unpoison_shadow+0x36/0x50
[ 8812.397507]  [<ffffffff815406e6>] ? kasan_unpoison_shadow+0x36/0x50
[ 8812.397512]  [<ffffffff815406e6>] ? kasan_unpoison_shadow+0x36/0x50
[ 8812.397517]  [<ffffffff815407f7>] ? __asan_register_globals+0x87/0xa0
[ 8812.397524]  [<ffffffff814454e5>] do_init_module+0x1d0/0x5a4
[ 8812.397530]  [<ffffffff812ed7e8>] load_module+0x6648/0x9d70
[ 8812.397535]  [<ffffffff812e4b70>] ? symbol_put_addr+0x50/0x50
[ 8812.397546]  [<ffffffff812e71a0>] ? module_frob_arch_sections+0x20/0x20
[ 8812.397552]  [<ffffffff8158e950>] ? open_exec+0x50/0x50
[ 8812.397559]  [<ffffffff811648db>] ? ns_capable+0x5b/0xd0
[ 8812.397565]  [<ffffffff812f1208>] SyS_finit_module+0x108/0x130
[ 8812.397571]  [<ffffffff812f1100>] ? SyS_init_module+0x1f0/0x1f0
[ 8812.397576]  [<ffffffff81004044>] ? lockdep_sys_exit_thunk+0x12/0x14
[ 8812.397582]  [<ffffffff82292236>] entry_SYSCALL_64_fastpath+0x16/0x7a

Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2016-01-11 12:19:24 -02:00
Mauro Carvalho Chehab 92777994a5 [media] move documentation to the header files
Some exported functions were still documented at the .c file,
instead of documenting at the .h one.

Move the documentation to the right place, as we only use headers
at media device-drivers.xml DocBook.

Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2016-01-11 12:19:22 -02:00
Sakari Ailus 665faa971d [media] media: Introduce internal index for media entities
The internal index can be used internally by the framework in order to keep
track of entities for a purpose or another. The internal index is constant
while it's registered to a media device, but the same index may be re-used
once the entity having that index is unregistered.

Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2016-01-11 12:19:17 -02:00
Dan Carpenter a5c82e5622 [media] media-device: copy_to/from_user() returns positive
The copy_to/from_user() functions return the number of bytes *not*
copied.  They don't return error codes.

Fixes: 4f6b3f363475 ('media] media-device: add support for MEDIA_IOC_G_TOPOLOGY ioctl')

Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2016-01-11 12:19:16 -02:00
Javier Martinez Canillas 8a95079668 [media] media-device: set topology version 0 at media registration
The G_TOPOLOGY ioctl is used to get a graph topology and since in the
future a graph can be dynamically updated, there is a way to know the
topology version so userspace can be aware that the graph has changed.

The version 0 is reserved to indicate that the graph is static (i.e no
graphs updates since the media device was registered).

So, now that the media device initialization and registration has been
split and the media device node is not exposed to user-space until all
the entities have been registered and links created, it is safe to set
a topology version 0 in media_device_register().

Suggested-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Suggested-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
Signed-off-by: Javier Martinez Canillas <javier@osg.samsung.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2016-01-11 12:19:16 -02:00
Javier Martinez Canillas 9832e155f1 [media] media-device: split media initialization and registration
The media device node is registered and so made visible to user-space
before entities are registered and links created which means that the
media graph obtained by user-space could be only partially enumerated
if that happens too early before all the graph has been created.

To avoid this race condition, split the media init and registration
in separate functions and only register the media device node when
all the pending subdevices have been registered, either explicitly
by the driver or asynchronously using v4l2_async_register_subdev().

The media_device_register() had a check for drivers not filling dev
and model fields but all drivers in mainline set them and not doing
it will be a driver bug so change the function return to void and
add a BUG_ON() for dev being NULL instead.

Also, add a media_device_cleanup() function that will destroy the
graph_mutex that is initialized in media_device_init().

[mchehab@osg.samsung.com: Fix compilation if !CONFIG_MEDIA_CONTROLLER
 and remove two warnings added by this changeset]
Suggested-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: Javier Martinez Canillas <javier@osg.samsung.com>
Acked-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2016-01-11 12:19:15 -02:00
Mauro Carvalho Chehab 821ed36629 [media] media-device: better lock media_device_unregister()
If media_device_unregister() is called by two different
drivers, a race condition may happen, as the check if the
device is not registered is not protected.

Move the spin_lock() to happen earlier in the function, in order
to prevent such race condition.

Reported-by: Shuah Khan <shuahkh@osg.samsung.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2016-01-11 12:19:15 -02:00
Mauro Carvalho Chehab b2ed8af910 [media] media-device: move media entity register/unregister functions
media entity register and unregister functions are called by media
device register/unregister. Move them to occur earlier, as we'll need
an unlocked version of media_device_entity_unregister() and we don't
want to add a function prototype without needing it.

No functional changes.

Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2016-01-11 12:19:14 -02:00
Javier Martinez Canillas 223d19c566 [media] media-device: check before unregister if mdev was registered
Most media functions that unregister, check if the corresponding register
function succeed before. So these functions can safely be called even if a
registration was never made or the component as already been unregistered.

Add the same check to media_device_unregister() function for consistency.

This will also allow to split the media_device_register() function in an
initialization and registration functions without the need to change the
generic cleanup functions and error code paths for all the media drivers.

Suggested-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: Javier Martinez Canillas <javier@osg.samsung.com>
Acked-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2016-01-11 12:19:14 -02:00
Mauro Carvalho Chehab b6e4ca8129 [media] media-device.h: document the last functions
Add kernel-doc documentation for media_device_get_devres and
media_device_find_devres.

Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2016-01-11 12:19:13 -02:00
Mauro Carvalho Chehab 82ae2a5059 [media] media: move MEDIA_LNK_FL_INTERFACE_LINK logic to link creation
Instead of flagging an interface link as MEDIA_LNK_FL_INTERFACE_LINK
only when returning to userspace, do it at link creation time.

That would allow using such flag internally, and cleans up a
little bit the code for G_TOPOLOGY ioctl.

[mchehab@osg.samsung.com: folded with a fixup from Dan Carpenter,
 replacing & by &&]
Suggested-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2016-01-11 12:19:10 -02:00
Mauro Carvalho Chehab b3b7a9f138 [media] media-device: Use u64 ints for pointers
By using u64 integers and pointers, we can get rid of compat32
logic. So, let's do it!

Suggested-by: Arnd Bergmann <arnd@arndb.de>
Suggested-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2016-01-11 12:19:07 -02:00
Mauro Carvalho Chehab c350ef830f [media] media_entity: rename media_obj functions to *_create *_destroy
Those media_obj_* functions are actually creating/destroying
media graph objects. So, rename them to better represent
what they're actually doing.

No functional changes.

This was created via this small shell script:

	for i in $(git grep -l media_gobj_init); do sed s,media_gobj_init,media_gobj_create,g <$i >a && mv a $i; done
	for i in $(git grep -l media_gobj_remove); do sed s,media_gobj_remove,media_gobj_destroy,g <$i >a && mv a $i; done

Suggested-by: Sakari Ailus <sakari.ailus@iki.fi>
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2016-01-11 12:19:06 -02:00
Mauro Carvalho Chehab 8ed8c88c46 [media] media-entity.h: get rid of revision and group_id fields
Both revision and group_id fields were never used and were always
initialized to zero. Remove them.

Suggested-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2016-01-11 12:19:04 -02:00
Mauro Carvalho Chehab ab22e77cd3 [media] media framework: rename pads init function to media_entity_pads_init()
With the MC next gen rework, what's left for media_entity_init()
is to just initialize the PADs. However, certain devices, like
a FLASH led/light doesn't have any input or output PAD.

So, there's no reason why calling media_entity_init() would be
mandatory. Also, despite its name, what this function actually
does is to initialize the PADs data. So, rename it to
media_entity_pads_init() in order to reflect that.

The media entity actual init happens during entity register,
at media_device_register_entity(). We should move init of
num_links and num_backlinks to it.

Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2016-01-11 12:19:03 -02:00
Mauro Carvalho Chehab b83e250833 [media] media-device: better name Kernelspace/Userspace links
The __media_device_enum_links() copies links definitions from
Kernelspace to userspace. It has to work with 3 structs that
handle with links. Better name them to:
	link: Kernelspace internal link representation, of the
		type media_link;
	klink_desc:  struct media_link_desc pointer to the
		kernel memory where the data will be filled;
	ulink_desc:  struct media_link_desc pointer to the
		memory where the data will be copied to
		userspace.

Suggested-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2016-01-11 12:19:03 -02:00
Mauro Carvalho Chehab 497e80cdf9 [media] media-device: put headers in alphabetic order
It is better to keep the headers in alphabetic order.

Suggested-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2016-01-11 12:19:03 -02:00
Mauro Carvalho Chehab 9033b1a470 [media] media-device: use unsigned ints on some places
The entity->num_pads are defined as u16. So, better to use an
unsigned int, as this prevents additional warnings when W=2
(or W=1 on some architectures).

The "i" counter at __media_device_get_topology() is also a
monotonic counter that should never be below zero. So,
make it unsigned too.

Suggested-by: Sakari Ailus <sakari.ailus@iki.fi>

Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2016-01-11 12:19:02 -02:00
Mauro Carvalho Chehab 4ca72efaef [media] uapi/media.h: Rename entities types to functions
Rename the userspace types from MEDIA_ENT_T_ to MEDIA_ENT_F_
and add the backward compatibility bits.

The changes at the .c files was generated by the following
coccinelle script:

@@
@@
-MEDIA_ENT_T_UNKNOWN
+MEDIA_ENT_F_UNKNOWN
@@
@@
-MEDIA_ENT_T_DVB_BASE
+MEDIA_ENT_F_DVB_BASE
@@
@@
-MEDIA_ENT_T_V4L2_BASE
+MEDIA_ENT_F_V4L2_BASE
@@
@@
-MEDIA_ENT_T_V4L2_SUBDEV_BASE
+MEDIA_ENT_F_V4L2_SUBDEV_BASE
@@
@@
-MEDIA_ENT_T_CONNECTOR_BASE
+MEDIA_ENT_F_CONNECTOR_BASE
@@
@@
-MEDIA_ENT_T_V4L2_VIDEO
+MEDIA_ENT_F_IO_V4L
@@
@@
-MEDIA_ENT_T_V4L2_VBI
+MEDIA_ENT_F_IO_VBI
@@
@@
-MEDIA_ENT_T_V4L2_SWRADIO
+MEDIA_ENT_F_IO_SWRADIO
@@
@@
-MEDIA_ENT_T_V4L2_SUBDEV_UNKNOWN
+MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN
@@
@@
-MEDIA_ENT_T_CONN_RF
+MEDIA_ENT_F_CONN_RF
@@
@@
-MEDIA_ENT_T_CONN_SVIDEO
+MEDIA_ENT_F_CONN_SVIDEO
@@
@@
-MEDIA_ENT_T_CONN_COMPOSITE
+MEDIA_ENT_F_CONN_COMPOSITE
@@
@@
-MEDIA_ENT_T_CONN_TEST
+MEDIA_ENT_F_CONN_TEST
@@
@@
-MEDIA_ENT_T_V4L2_SUBDEV_SENSOR
+MEDIA_ENT_F_CAM_SENSOR
@@
@@
-MEDIA_ENT_T_V4L2_SUBDEV_FLASH
+MEDIA_ENT_F_FLASH
@@
@@
-MEDIA_ENT_T_V4L2_SUBDEV_LENS
+MEDIA_ENT_F_LENS
@@
@@
-MEDIA_ENT_T_V4L2_SUBDEV_DECODER
+MEDIA_ENT_F_ATV_DECODER
@@
@@
-MEDIA_ENT_T_V4L2_SUBDEV_TUNER
+MEDIA_ENT_F_TUNER
@@
@@
-MEDIA_ENT_T_DVB_DEMOD
+MEDIA_ENT_F_DTV_DEMOD
@@
@@
-MEDIA_ENT_T_DVB_DEMUX
+MEDIA_ENT_F_TS_DEMUX
@@
@@
-MEDIA_ENT_T_DVB_TSOUT
+MEDIA_ENT_F_IO_DTV
@@
@@
-MEDIA_ENT_T_DVB_CA
+MEDIA_ENT_F_DTV_CA
@@
@@
-MEDIA_ENT_T_DVB_NET_DECAP
+MEDIA_ENT_F_DTV_NET_DECAP

Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2016-01-11 12:19:01 -02:00
Mauro Carvalho Chehab d87cdb8844 [media] media-device: export the entity function via new ioctl
Now that entities have a main function, expose it via
MEDIA_IOC_G_TOPOLOGY ioctl.

Please notice that some entities may have secundary functions.
Such use case will be addressed later, when we add support for the
Media Controller properties.

Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2016-01-11 12:19:01 -02:00
Mauro Carvalho Chehab 0e576b76f5 [media] media-entity.h: rename entity.type to entity.function
Entities should have one or more functions. Calling it as a
type proofed to not be correct, as an entity could eventually
have more than one type.

So, rename the field as function.

Please notice that this patch doesn't extend support for
multiple function entities. Such change will happen when
we have real case drivers using it.

No functional changes.

Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2016-01-11 12:19:00 -02:00
Mauro Carvalho Chehab 39d1ebc609 [media] media-device: supress backlinks at G_TOPOLOGY ioctl
Due to the graph traversal algorithm currently in usage, we
need a copy of all data links. Those backlinks should not be
send to userspace, as otherwise, all links there will be
duplicated.

Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
2016-01-11 12:18:58 -02:00