Received: by 2002:ac0:a594:0:0:0:0:0 with SMTP id m20-v6csp3934821imm; Sun, 13 May 2018 23:30:27 -0700 (PDT) X-Google-Smtp-Source: AB8JxZqK1+Kc3NCmzqOnDreH7cslfbnNPWiLaM4d1IMCMJtqpid4xwAjGb9aysWH2WkCYmeRs0Dq X-Received: by 2002:a63:788b:: with SMTP id t133-v6mr517428pgc.20.1526279427313; Sun, 13 May 2018 23:30:27 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1526279427; cv=none; d=google.com; s=arc-20160816; b=WZbtOGwwtR1jR8cUGImIpr+voKI2kJNTK9SMXs0MSvv05n8ph1Pev0DUivRNz/ptKd 7kL7GjAlGzATgllSqJH9UxMqGgASjB03BpxjY5vlkKtbGZMHNvzMR47uxwNSr6QXljzT pePFGGHj5a+bDCSWhRY4KrjZYBGbCElJgjOzABu3Hi8bETSb03usv9vQb1o4pWttRLRL CfntJKfmvtWUlt4lrTsjsp3kDSAeFflWwusNIe9RD6HqQyN6ZbDtRut2ctJuXVM3fdY0 TZZ1RjM5IjJNdubujtyXLRoWtL3/JrVHe+4LybGLPIfay/OKq+y0lO01kZMp+KySIz0y +EaQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:arc-authentication-results; bh=nuTIhfGmUApi2iZozoNKRW9yicbHorWEMOVD5lHkNss=; b=0s2P0WLtn41mRdVyvWKYlbVn5yC5uP6vYtYlievv2/5P4FWiEDnaY3fortKSikra4w A8PCok2Lg/QoVJ17z+saOzEVCzNuAbzpRsKcFiH58YXC51SsmWbjj61Yj7qpYp0WjZhD 7lT4DeU4H+m5U6KMwDiysf8OGaZdhmp81+LAuiJtsYe5Nmlb+yLtLJuzah1aQ/t+VK7k GaaFHVjftnP21b05URWZBVuLeY7u/6JKTfy39YC/6KRc8aCmRIZayWoCSbKnhwm0rUKO MtLpsAY1KJ3wxk3saUYG2PGqvryAcWG3j3XCnJ76woFQiFBly3tND+XE9mJIEjtaHRKN FaRw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=vW+0iwVu; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id m2-v6si8851651pfb.259.2018.05.13.23.30.04; Sun, 13 May 2018 23:30:27 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=vW+0iwVu; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752037AbeENG15 (ORCPT + 99 others); Mon, 14 May 2018 02:27:57 -0400 Received: from mail-lf0-f66.google.com ([209.85.215.66]:40495 "EHLO mail-lf0-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751871AbeENG1y (ORCPT ); Mon, 14 May 2018 02:27:54 -0400 Received: by mail-lf0-f66.google.com with SMTP id p85-v6so16162975lfg.7 for ; Sun, 13 May 2018 23:27:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=nuTIhfGmUApi2iZozoNKRW9yicbHorWEMOVD5lHkNss=; b=vW+0iwVuXREJz/XtJg66LJuY2boV89nWI5TMkqg2P8PnVIhy2tWWZOWJR9EUI8LAc3 hVp6hH8INwgCNUY/netcpggvZCKhyUSMeuQtUDzEWj5j+K/aeKQhBz9ZcUO0ILKK8Rue i/jE61/lWCk9sLYsLNI3nBuRNb0J3RJ2afgSausMpD0Y5t0OnjIurjpxJLOuxytXKyuA PeE+LzJ55bnLE0Hm2HlFFETRVatU6E0/Ne/Rp3NQbcUnnL1RmDCggyNFrqvt2u4TeO6L 6Yyjmfk44flfE5cQ4Xn9bn628cQ647uRclU4f3o6cyUpW3WyYSEUoUqvcl4obMyGV4ao Hq4A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=nuTIhfGmUApi2iZozoNKRW9yicbHorWEMOVD5lHkNss=; b=a+VkhrC4vNCzD84Egje6eznU+GqmWN2CU02hChHf69wofAfFOx6VKWeKsw/mF9fFF5 u124rXKab4CWCsHGMbQEQP4X4fj2cHAdetgJ2zxcT4NzWjPbk5kF/l9kMSVLsYPLQT11 E64JN53t0gK+AhOX8FspGzk33058G3ji5s0tVn0QhI4SQBhZ8BbQ4TQzKV4xQycdYDZ8 HGG6TOT4a4oLp0FpRjjX+S25DNqugNg6eryDL/S/EMBiTpCNCnO52iU5sYKmJqXFIIkz 5uwsuhci90UJ20L/g7+jgkKO4N8yZaHsYJVE/mHTlKjAR78E1QNfVXu3H3NkXGl0Od8U 1Jnw== X-Gm-Message-State: ALKqPwdnccKnXaKMfOPbjocfI7rMwVD0Hj/Dc+WmRiYifOHHF1ajhQhR HIQbLz3Hrqu/r+xuxiaVWKU= X-Received: by 2002:a19:a84f:: with SMTP id r76-v6mr7981173lfe.68.1526279272346; Sun, 13 May 2018 23:27:52 -0700 (PDT) Received: from a2k-HP-ProDesk-600-G2-SFF.kyiv.epam.com (ll-54.209.223.85.sovam.net.ua. [85.223.209.54]) by smtp.gmail.com with ESMTPSA id k127-v6sm2187860lfe.21.2018.05.13.23.27.50 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sun, 13 May 2018 23:27:51 -0700 (PDT) From: Oleksandr Andrushchenko To: xen-devel@lists.xenproject.org, linux-kernel@vger.kernel.org, alsa-devel@alsa-project.org, jgross@suse.com, boris.ostrovsky@oracle.com, konrad.wilk@oracle.com, perex@perex.cz, tiwai@suse.com Cc: andr2000@gmail.com, Oleksandr Andrushchenko Subject: [PATCH v3 1/6] ALSA: xen-front: Introduce Xen para-virtualized sound frontend driver Date: Mon, 14 May 2018 09:27:37 +0300 Message-Id: <20180514062742.25879-2-andr2000@gmail.com> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20180514062742.25879-1-andr2000@gmail.com> References: <20180514062742.25879-1-andr2000@gmail.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Oleksandr Andrushchenko Introduce skeleton of the para-virtualized Xen sound frontend driver. Initial handling for Xen bus states: implement Xen bus state machine for the frontend driver according to the state diagram and recovery flow from sound para-virtualized protocol: xen/interface/io/sndif.h. Signed-off-by: Oleksandr Andrushchenko Reviewed-by: Juergen Gross --- sound/Kconfig | 2 + sound/Makefile | 2 +- sound/xen/Kconfig | 10 ++ sound/xen/Makefile | 5 + sound/xen/xen_snd_front.c | 196 ++++++++++++++++++++++++++++++++++++++ sound/xen/xen_snd_front.h | 18 ++++ 6 files changed, 232 insertions(+), 1 deletion(-) create mode 100644 sound/xen/Kconfig create mode 100644 sound/xen/Makefile create mode 100644 sound/xen/xen_snd_front.c create mode 100644 sound/xen/xen_snd_front.h diff --git a/sound/Kconfig b/sound/Kconfig index 6833db9002ec..1140e9988fc5 100644 --- a/sound/Kconfig +++ b/sound/Kconfig @@ -96,6 +96,8 @@ source "sound/x86/Kconfig" source "sound/synth/Kconfig" +source "sound/xen/Kconfig" + endif # SND endif # !UML diff --git a/sound/Makefile b/sound/Makefile index 99d8c31262c8..797ecdcd35e2 100644 --- a/sound/Makefile +++ b/sound/Makefile @@ -5,7 +5,7 @@ obj-$(CONFIG_SOUND) += soundcore.o obj-$(CONFIG_DMASOUND) += oss/dmasound/ obj-$(CONFIG_SND) += core/ i2c/ drivers/ isa/ pci/ ppc/ arm/ sh/ synth/ usb/ \ - firewire/ sparc/ spi/ parisc/ pcmcia/ mips/ soc/ atmel/ hda/ x86/ + firewire/ sparc/ spi/ parisc/ pcmcia/ mips/ soc/ atmel/ hda/ x86/ xen/ obj-$(CONFIG_SND_AOA) += aoa/ # This one must be compilable even if sound is configured out diff --git a/sound/xen/Kconfig b/sound/xen/Kconfig new file mode 100644 index 000000000000..4f1fceea82d2 --- /dev/null +++ b/sound/xen/Kconfig @@ -0,0 +1,10 @@ +# ALSA Xen drivers + +config SND_XEN_FRONTEND + tristate "Xen para-virtualized sound frontend driver" + depends on XEN + select SND_PCM + select XEN_XENBUS_FRONTEND + help + Choose this option if you want to enable a para-virtualized + frontend sound driver for Xen guest OSes. diff --git a/sound/xen/Makefile b/sound/xen/Makefile new file mode 100644 index 000000000000..4507ef3c27fd --- /dev/null +++ b/sound/xen/Makefile @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0 OR MIT + +snd_xen_front-objs := xen_snd_front.o + +obj-$(CONFIG_SND_XEN_FRONTEND) += snd_xen_front.o diff --git a/sound/xen/xen_snd_front.c b/sound/xen/xen_snd_front.c new file mode 100644 index 000000000000..bbbe2767b565 --- /dev/null +++ b/sound/xen/xen_snd_front.c @@ -0,0 +1,196 @@ +// SPDX-License-Identifier: GPL-2.0 OR MIT + +/* + * Xen para-virtual sound device + * + * Copyright (C) 2016-2018 EPAM Systems Inc. + * + * Author: Oleksandr Andrushchenko + */ + +#include +#include + +#include +#include +#include + +#include + +#include "xen_snd_front.h" + +static void xen_snd_drv_fini(struct xen_snd_front_info *front_info) +{ +} + +static int sndback_initwait(struct xen_snd_front_info *front_info) +{ + return 0; +} + +static int sndback_connect(struct xen_snd_front_info *front_info) +{ + return 0; +} + +static void sndback_disconnect(struct xen_snd_front_info *front_info) +{ + xen_snd_drv_fini(front_info); + xenbus_switch_state(front_info->xb_dev, XenbusStateInitialising); +} + +static void sndback_changed(struct xenbus_device *xb_dev, + enum xenbus_state backend_state) +{ + struct xen_snd_front_info *front_info = dev_get_drvdata(&xb_dev->dev); + int ret; + + dev_dbg(&xb_dev->dev, "Backend state is %s, front is %s\n", + xenbus_strstate(backend_state), + xenbus_strstate(xb_dev->state)); + + switch (backend_state) { + case XenbusStateReconfiguring: + /* fall through */ + case XenbusStateReconfigured: + /* fall through */ + case XenbusStateInitialised: + /* fall through */ + break; + + case XenbusStateInitialising: + /* Recovering after backend unexpected closure. */ + sndback_disconnect(front_info); + break; + + case XenbusStateInitWait: + /* Recovering after backend unexpected closure. */ + sndback_disconnect(front_info); + + ret = sndback_initwait(front_info); + if (ret < 0) + xenbus_dev_fatal(xb_dev, ret, "initializing frontend"); + else + xenbus_switch_state(xb_dev, XenbusStateInitialised); + break; + + case XenbusStateConnected: + if (xb_dev->state != XenbusStateInitialised) + break; + + ret = sndback_connect(front_info); + if (ret < 0) + xenbus_dev_fatal(xb_dev, ret, "initializing frontend"); + else + xenbus_switch_state(xb_dev, XenbusStateConnected); + break; + + case XenbusStateClosing: + /* + * In this state backend starts freeing resources, + * so let it go into closed state first, so we can also + * remove ours. + */ + break; + + case XenbusStateUnknown: + /* fall through */ + case XenbusStateClosed: + if (xb_dev->state == XenbusStateClosed) + break; + + sndback_disconnect(front_info); + break; + } +} + +static int xen_drv_probe(struct xenbus_device *xb_dev, + const struct xenbus_device_id *id) +{ + struct xen_snd_front_info *front_info; + + front_info = devm_kzalloc(&xb_dev->dev, + sizeof(*front_info), GFP_KERNEL); + if (!front_info) + return -ENOMEM; + + front_info->xb_dev = xb_dev; + dev_set_drvdata(&xb_dev->dev, front_info); + + return xenbus_switch_state(xb_dev, XenbusStateInitialising); +} + +static int xen_drv_remove(struct xenbus_device *dev) +{ + struct xen_snd_front_info *front_info = dev_get_drvdata(&dev->dev); + int to = 100; + + xenbus_switch_state(dev, XenbusStateClosing); + + /* + * On driver removal it is disconnected from XenBus, + * so no backend state change events come via .otherend_changed + * callback. This prevents us from exiting gracefully, e.g. + * signaling the backend to free event channels, waiting for its + * state to change to XenbusStateClosed and cleaning at our end. + * Normally when front driver removed backend will finally go into + * XenbusStateInitWait state. + * + * Workaround: read backend's state manually and wait with time-out. + */ + while ((xenbus_read_unsigned(front_info->xb_dev->otherend, "state", + XenbusStateUnknown) != XenbusStateInitWait) && + to--) + msleep(10); + + if (!to) { + unsigned int state; + + state = xenbus_read_unsigned(front_info->xb_dev->otherend, + "state", XenbusStateUnknown); + pr_err("Backend state is %s while removing driver\n", + xenbus_strstate(state)); + } + + xen_snd_drv_fini(front_info); + xenbus_frontend_closed(dev); + return 0; +} + +static const struct xenbus_device_id xen_drv_ids[] = { + { XENSND_DRIVER_NAME }, + { "" } +}; + +static struct xenbus_driver xen_driver = { + .ids = xen_drv_ids, + .probe = xen_drv_probe, + .remove = xen_drv_remove, + .otherend_changed = sndback_changed, +}; + +static int __init xen_drv_init(void) +{ + if (!xen_domain()) + return -ENODEV; + + if (!xen_has_pv_devices()) + return -ENODEV; + + pr_info("Initialising Xen " XENSND_DRIVER_NAME " frontend driver\n"); + return xenbus_register_frontend(&xen_driver); +} + +static void __exit xen_drv_fini(void) +{ + pr_info("Unregistering Xen " XENSND_DRIVER_NAME " frontend driver\n"); + xenbus_unregister_driver(&xen_driver); +} + +module_init(xen_drv_init); +module_exit(xen_drv_fini); + +MODULE_DESCRIPTION("Xen virtual sound device frontend"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("xen:" XENSND_DRIVER_NAME); +MODULE_SUPPORTED_DEVICE("{{ALSA,Virtual soundcard}}"); diff --git a/sound/xen/xen_snd_front.h b/sound/xen/xen_snd_front.h new file mode 100644 index 000000000000..4ae204b23d32 --- /dev/null +++ b/sound/xen/xen_snd_front.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0 OR MIT */ + +/* + * Xen para-virtual sound device + * + * Copyright (C) 2016-2018 EPAM Systems Inc. + * + * Author: Oleksandr Andrushchenko + */ + +#ifndef __XEN_SND_FRONT_H +#define __XEN_SND_FRONT_H + +struct xen_snd_front_info { + struct xenbus_device *xb_dev; +}; + +#endif /* __XEN_SND_FRONT_H */ -- 2.17.0