From patchwork Mon Jan 16 19:26:50 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lyude Paul X-Patchwork-Id: 9519349 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 5EE536020B for ; Mon, 16 Jan 2017 19:27:11 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4EE3C282DC for ; Mon, 16 Jan 2017 19:27:11 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 434C9283F9; Mon, 16 Jan 2017 19:27:11 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id A9C9F282DC for ; Mon, 16 Jan 2017 19:27:10 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id C29F26E4D1; Mon, 16 Jan 2017 19:27:09 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by gabe.freedesktop.org (Postfix) with ESMTPS id 223896E4CF for ; Mon, 16 Jan 2017 19:27:09 +0000 (UTC) Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id BFF3A81229 for ; Mon, 16 Jan 2017 19:27:09 +0000 (UTC) Received: from meerkat.lyude.net (dhcp-25-222.bos.redhat.com [10.18.25.222]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id v0GJR8nJ006234; Mon, 16 Jan 2017 14:27:09 -0500 From: Lyude To: intel-gfx@lists.freedesktop.org Date: Mon, 16 Jan 2017 14:26:50 -0500 Message-Id: <20170116192653.4740-3-lyude@redhat.com> In-Reply-To: <20170116192653.4740-1-lyude@redhat.com> References: <20170116192653.4740-1-lyude@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.25]); Mon, 16 Jan 2017 19:27:09 +0000 (UTC) Subject: [Intel-gfx] [PATCH i-g-t v3 2/5] igt_kms: Add helpers for watching for sysfs hotplug events X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Virus-Scanned: ClamAV using ClamSMTP This adds some basic helpers for connecting to udev and watching for sysfs hotplug events. Cc: Tomeu Vizoso Signed-off-by: Lyude Changes since v1: - Remove unused arg from documentation Changes since v2: - Make udev_monitor explicit so that we can use this for detecting FSMs from the Chamelium in rpc calls --- lib/igt_kms.c | 111 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ lib/igt_kms.h | 7 ++++ 2 files changed, 118 insertions(+) diff --git a/lib/igt_kms.c b/lib/igt_kms.c index 2c5a6e8..df50451 100644 --- a/lib/igt_kms.c +++ b/lib/igt_kms.c @@ -38,6 +38,10 @@ #elif HAVE_SYS_KD_H #include #endif +#ifdef HAVE_UDEV +#include +#include +#endif #include #include @@ -2917,6 +2921,113 @@ void igt_reset_connectors(void) "detect"); } +#ifdef HAVE_UDEV + +/** + * igt_watch_hotplug: + * + * Begin monitoring udev for sysfs hotplug events. + * + * Returns: a udev monitor for detecting hotplugs on + */ +struct udev_monitor *igt_watch_hotplug(void) +{ + struct udev *udev; + struct udev_monitor *mon; + int ret, flags, fd; + + udev = udev_new(); + igt_assert(udev != NULL); + + mon = udev_monitor_new_from_netlink(udev, "udev"); + igt_assert(mon != NULL); + + ret = udev_monitor_filter_add_match_subsystem_devtype(mon, + "drm", + "drm_minor"); + igt_assert_eq(ret, 0); + ret = udev_monitor_filter_update(mon); + igt_assert_eq(ret, 0); + ret = udev_monitor_enable_receiving(mon); + igt_assert_eq(ret, 0); + + /* Set the fd for udev as non blocking */ + fd = udev_monitor_get_fd(mon); + flags = fcntl(fd, F_GETFL, 0); + igt_assert(flags); + + flags |= O_NONBLOCK; + igt_assert_neq(fcntl(fd, F_SETFL, flags), -1); + + return mon; +} + +/** + * igt_hotplug_detected: + * @mon: A udev monitor initialized with #igt_watch_hotplug + * @timeout_secs: How long to wait for a hotplug event to occur. + * + * Assert that a hotplug event was received since we last checked the monitor. + * + * Returns: true if a sysfs hotplug event was received, false if we timed out + */ +bool igt_hotplug_detected(struct udev_monitor *mon, int timeout_secs) +{ + struct udev_device *dev; + const char *hotplug_val; + struct pollfd fd = { + .fd = udev_monitor_get_fd(mon), + .events = POLLIN + }; + bool hotplug_received = false; + + /* Go through all of the events pending on the udev monitor. Once we + * receive a hotplug, we continue going through the rest of the events + * so that redundant hotplug events don't change the results of future + * checks + */ + while (!hotplug_received && poll(&fd, 1, timeout_secs * 1000)) { + dev = udev_monitor_receive_device(mon); + + hotplug_val = udev_device_get_property_value(dev, "HOTPLUG"); + if (hotplug_val && atoi(hotplug_val) == 1) + hotplug_received = true; + + udev_device_unref(dev); + } + + return hotplug_received; +} + +/** + * igt_flush_hotplugs: + * @mon: A udev monitor initialized with #igt_watch_hotplug + * + * Get rid of any pending hotplug events + */ +void igt_flush_hotplugs(struct udev_monitor *mon) +{ + struct udev_device *dev; + + while ((dev = udev_monitor_receive_device(mon))) + udev_device_unref(dev); +} + +/** + * igt_cleanup_hotplug: + * + * Cleanup the resources allocated by #igt_watch_hotplug + */ +void igt_cleanup_hotplug(struct udev_monitor *mon) +{ + struct udev *udev = udev_monitor_get_udev(mon); + + udev_monitor_unref(mon); + mon = NULL; + udev_unref(udev); +} +#endif + /** * kmstest_get_vbl_flag: * @pipe_id: Pipe to convert to flag representation. diff --git a/lib/igt_kms.h b/lib/igt_kms.h index 81be77f..72ed6a3 100644 --- a/lib/igt_kms.h +++ b/lib/igt_kms.h @@ -502,5 +502,12 @@ uint32_t kmstest_get_vbl_flag(uint32_t pipe_id); const unsigned char* igt_kms_get_base_edid(void); const unsigned char* igt_kms_get_alt_edid(void); +#ifdef HAVE_UDEV +struct udev_monitor *igt_watch_hotplug(void); +bool igt_hotplug_detected(struct udev_monitor *mon, + int timeout_secs); +void igt_flush_hotplugs(struct udev_monitor *mon); +void igt_cleanup_hotplug(struct udev_monitor *mon); +#endif #endif /* __IGT_KMS_H__ */