* Re: [PATCH 3/3] ARM: dts: gr-peach: Add ETHER pin group
From: Geert Uytterhoeven @ 2017-10-05 9:09 UTC (permalink / raw)
To: Jacopo Mondi
Cc: Simon Horman, Magnus Damm, Rob Herring, Mark Rutland,
Russell King, Linux-Renesas, devicetree@vger.kernel.org,
linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org
In-Reply-To: <1507193900-23801-4-git-send-email-jacopo+renesas@jmondi.org>
Hi Jacopo,
On Thu, Oct 5, 2017 at 10:58 AM, Jacopo Mondi <jacopo+renesas@jmondi.org> wrote:
> Add pin configuration subnode for ETHER pin group and enable the interface.
>
> Signed-off-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
> --- a/arch/arm/boot/dts/r7s72100-gr-peach.dts
> +++ b/arch/arm/boot/dts/r7s72100-gr-peach.dts
> @@ -88,3 +110,19 @@
>
> status = "okay";
> };
> +
> +ðer {
> + pinctrl-names = "default";
> + pinctrl-0 = <ðer_pins>;
> +
> + status = "okay";
> +
> + reset-gpios = <&port4 2 GPIO_ACTIVE_LOW>;
> + reset-delay-us = <5>;
I'm afraid the PHY people (not CCed ;-) will want you to move these reset
properties to the phy subnode these days, despite
Documentation/devicetree/bindings/net/mdio.txt...
> +
> + renesas,no-ether-link;
> + phy-handle = <&phy0>;
> + phy0: ethernet-phy@0 {
> + reg = <0>;
> + };
> +};
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply
* [PATCH 3/3] ARM: dts: gr-peach: Add ETHER pin group
From: Geert Uytterhoeven @ 2017-10-05 9:09 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1507193900-23801-4-git-send-email-jacopo+renesas@jmondi.org>
Hi Jacopo,
On Thu, Oct 5, 2017 at 10:58 AM, Jacopo Mondi <jacopo+renesas@jmondi.org> wrote:
> Add pin configuration subnode for ETHER pin group and enable the interface.
>
> Signed-off-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
> --- a/arch/arm/boot/dts/r7s72100-gr-peach.dts
> +++ b/arch/arm/boot/dts/r7s72100-gr-peach.dts
> @@ -88,3 +110,19 @@
>
> status = "okay";
> };
> +
> +ðer {
> + pinctrl-names = "default";
> + pinctrl-0 = <ðer_pins>;
> +
> + status = "okay";
> +
> + reset-gpios = <&port4 2 GPIO_ACTIVE_LOW>;
> + reset-delay-us = <5>;
I'm afraid the PHY people (not CCed ;-) will want you to move these reset
properties to the phy subnode these days, despite
Documentation/devicetree/bindings/net/mdio.txt...
> +
> + renesas,no-ether-link;
> + phy-handle = <&phy0>;
> + phy0: ethernet-phy at 0 {
> + reg = <0>;
> + };
> +};
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply
* Re: [PATCH v2 0/2] ethdev: add support for raw flow type for flow director
From: Rybalchenko, Kirill @ 2017-10-05 9:09 UTC (permalink / raw)
To: Yigit, Ferruh, Thomas Monjalon
Cc: dev@dpdk.org, Chilikin, Andrey, Xing, Beilei, Wu, Jingjing
In-Reply-To: <acd3ba0d-b813-9c8f-e957-81228abd4d12@intel.com>
Hi Thomas,
As Ferruh rightly said, this feature does not affect any
other drivers except i40e.
It was implemented as a temporary measure to accelerate
adoption of new protocols in DPDK.
It does not eliminate importance of rte_flow.
As you can see, we've already added GTP as a part of rte_flow.
(see Beilei Xing patch http://dpdk.org/ml/archives/dev/2017-October/077483.html)
Regards,
Kirill.
> -----Original Message-----
> From: Yigit, Ferruh
> Sent: Wednesday 4 October 2017 20:47
> To: Thomas Monjalon <thomas@monjalon.net>; Rybalchenko, Kirill
> <kirill.rybalchenko@intel.com>
> Cc: dev@dpdk.org; Chilikin, Andrey <andrey.chilikin@intel.com>; Xing, Beilei
> <beilei.xing@intel.com>; Wu, Jingjing <jingjing.wu@intel.com>
> Subject: Re: [dpdk-dev] [PATCH v2 0/2] ethdev: add support for raw flow
> type for flow director
>
> On 10/4/2017 6:56 PM, Thomas Monjalon wrote:
> > 04/10/2017 19:44, Ferruh Yigit:
> >> On 10/4/2017 5:57 PM, Thomas Monjalon wrote:
> >>> 03/10/2017 21:02, Ferruh Yigit:
> >>>> On 9/20/2017 9:42 AM, Kirill Rybalchenko wrote:
> >>>>> For complex packets use raw flow type with pre-constructed packet
> >>>>> buffer instead of creating a packet internally in PMD.
> >>>
> >>> Sorry for not catching this series before.
> >>>
> >>> As it has been said several times on this mailing list, the flow
> >>> director API is deprecated.
> >>> I think everybody here knows that it is going to be replaced by
> >>> rte_flow.
> >>>
> >>> That's why it does not make sense to extend flow director.
> >>> We are not going to update PMDs to support a new type of legacy flow
> >>> director.
> >>> Please focus your efforts on rte_flow.
> >>
> >> As far as I can see this is not to to extend flow director. But
> >> driver uses this struct and adding a new feature into driver requires
> >> update in this struct.
> >>
> >> I guess idea was for new filter functionalities PMD should use
> >> rte_flow, that is the new shiny method we have, I see the point here.
> >> But I don't see the point of making these structs under use completely
> immutable.
> >
> > I don't know what is RTE_ETH_FLOW_RAW.
> > Let's start by explaining it, how it is used by users, and why this
> > struct is needed.
>
> Let me answer as much as I get from patches, if something is missing or
> wrong Kirill needs to correct it.
>
> Driver (i40e) works with static pre-defined flow and pctypes. But new
> feature DDP lets loading custom profiles and work with custom and perhaps
> not yet defined flow and pctypes. So there are a few other patches to make
> driver more dynamic.
>
> For this case I40E_VALID_FLOW() fails with custom flow types, and
> RTE_ETH_FLOW_RAW used as kind of (void *) to be able to work with new
> dynamic types.
>
> > Thanks
> >
^ permalink raw reply
* Re: [PATCH 1/2] arm64: dts: renesas: r8a77995: add PWM device nodes
From: Simon Horman @ 2017-10-05 9:08 UTC (permalink / raw)
To: Geert Uytterhoeven
Cc: Yoshihiro Shimoda, Magnus Damm, Rob Herring, Mark Rutland,
devicetree@vger.kernel.org, Linux-Renesas
In-Reply-To: <CAMuHMdUDDZi86adiOQo0+5BMnTV9JHsRAQ=q6Hg9KjY-S3zFdw@mail.gmail.com>
On Wed, Oct 04, 2017 at 04:02:05PM +0200, Geert Uytterhoeven wrote:
> On Wed, Oct 4, 2017 at 12:27 PM, Yoshihiro Shimoda
> <yoshihiro.shimoda.uh@renesas.com> wrote:
> > This patch adds PWM device nodes for r8a77995.
> >
> > Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
>
> Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Thanks, applied.
^ permalink raw reply
* Re: [PATCH v2 08/13] fuzz/x86_emulate: Take multiple test files for inputs
From: Jan Beulich @ 2017-10-05 9:08 UTC (permalink / raw)
To: George Dunlap; +Cc: Andrew Cooper, Wei Liu, xen-devel, Ian Jackson
In-Reply-To: <c0c6c2b1-6403-6c7c-44b0-0cb4b9d1b5c1@citrix.com>
>>> On 04.10.17 at 18:58, <george.dunlap@citrix.com> wrote:
> On 10/04/2017 09:24 AM, Jan Beulich wrote:
>>>>> On 25.09.17 at 16:26, <george.dunlap@citrix.com> wrote:
>>> @@ -66,11 +70,14 @@ int main(int argc, char **argv)
>>> __AFL_INIT();
>>>
>>> while ( __AFL_LOOP(1000) )
>>> +#else
>>> + for( count = 0; count < max; count++ )
>>
>> Initially I've thought the initializer on count was pointless further
>> up because of the re-initialization here. Of course that's needed
>> because of the #if/#else this sits in. Hence I wonder whether omitting
>> the assignment here wouldn't be appropriate - it wouldn't really be
>> wromng for a compiler to warn about this redundancy.
>
> Could do that I suppose. The other option would be to change the other
> loop to `for ( count = 0; __AFL_LOOP(1000); )`
>
> Let me know if you have any preference.
No preference, your alternative is fine.
Jan
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel
^ permalink raw reply
* Re: [GIT PULL for-3.18 00/29] Commits for v3.18 LTS
From: gregkh @ 2017-10-05 9:08 UTC (permalink / raw)
To: Levin, Alexander (Sasha Levin); +Cc: stable@vger.kernel.org
In-Reply-To: <20170924184249.30330-1-alexander.levin@verizon.com>
On Sun, Sep 24, 2017 at 06:42:54PM +0000, Levin, Alexander (Sasha Levin) wrote:
> Hi Greg,
>
> The following commits were sent for review 7+ days ago, and comments were addressed.
>
> Please pull for v3.18 LTS.
>
> ===
>
> The following changes since commit 60a8261b1257b6ef226f572b34cffc7b5cb359c7:
>
> Linux 3.18.71 (2017-09-13 14:04:00 -0700)
>
> are available in the git repository at:
>
> git://git.kernel.org/pub/scm/linux/kernel/git/sashal/linux-stable.git for-greg-3.18
All now queued up, thanks.
greg k-h
^ permalink raw reply
* Re: [PATCH v2 14/17] phy: qcom-qusb2: Set vbus sw-override signal in device mode
From: Manu Gautam @ 2017-10-05 9:08 UTC (permalink / raw)
To: Jack Pham
Cc: Kishon Vijay Abraham I, Felipe Balbi, linux-arm-msm, linux-usb,
Vivek Gautam, Krzysztof Kozlowski,
open list:GENERIC PHY FRAMEWORK
In-Reply-To: <20170928165345.GD12812@usblab-sd-06.qualcomm.com>
Hi Jack,
On 9/28/2017 10:23 PM, Jack Pham wrote:
> Hi Manu,
>
> On Thu, Sep 28, 2017 at 09:30:38AM +0530, Manu Gautam wrote:
>> On 9/28/2017 12:46 AM, Jack Pham wrote:
>>> On Wed, Sep 27, 2017 at 10:57:41AM -0700, Jack Pham wrote:
>>>> On Wed, Sep 27, 2017 at 02:29:10PM +0530, Manu Gautam wrote:
>>>>> VBUS signal coming from PHY must be asserted in device for
>>>>> controller to start operation or assert pull-up. For some
>>>>> platforms where VBUS line is not connected to PHY there is
>>>>> HS_PHY_CTRL register in QSCRATCH wrapper that can be used
>>>>> by software to override VBUS signal going to controller.
>>>>>
>>>>> Signed-off-by: Manu Gautam <mgautam@codeaurora.org>
>>>>> ---
>>>>>
>>>>> +static int qusb2_phy_set_mode(struct phy *phy, enum phy_mode mode)
>>>>> +{
>>>>> + struct qusb2_phy *qphy = phy_get_drvdata(phy);
>>>>> +
>>>>> + qphy->mode = mode;
>>>>> +
>>>>> + /* Update VBUS override in qscratch register */
>>>>> + if (qphy->qscratch_base) {
>>>>> + if (mode == PHY_MODE_USB_DEVICE)
>>>>> + qusb2_setbits(qphy->qscratch_base, QSCRATCH_HS_PHY_CTRL,
>>>>> + UTMI_OTG_VBUS_VALID | SW_SESSVLD_SEL);
>>>>> + else
>>>>> + qusb2_clrbits(qphy->qscratch_base, QSCRATCH_HS_PHY_CTRL,
>>>>> + UTMI_OTG_VBUS_VALID | SW_SESSVLD_SEL);
>>>> Wouldn't this be better off handled in the controller glue driver? Two
>>>> reasons I think this patch is unattractive:
>>>>
>>>> - qscratch_base is part of the controller's register space. Your later
>>>> patch 16/17 ("phy: qcom-qmp: Override lane0_power_present signal in
>>>> device mode") does a similar thing and hence both drivers have to
>>>> ioremap() the same register resource while at the same time avoiding
>>>> request_mem_region() (called by devm_ioremap_resource) to allow it to
>>>> be mapped in both places.
>> Right. There is one more reason why qusb2 driver needs qscratch:
>> - During runtime suspend, it has to check linestate to set correct polarity for dp/dm
>> wakeup interrupt in order to detect disconnect/resume ion LS and FS/HS modes.
> Ugh, oh yeah. The way I understand we did it in our downstream driver
> is still to have the controller driver read the linestate but then pass
> the information via additional set_mode() flags which the PHY driver
> could use to correctly arm the interrupt trigger polarity.
>
> An alternative would be to access a couple of the debug QUSB2PHY
> registers that also provide a reading of the current UTMI linestate. The
> HPG mentions them vaguely, and I can't remember if we tested that
> interface or not. Assuming it works, would that be preferable to reading
> a non-PHY register here?
it looks like newer QUSB2 PHY doesn't have a register to read linestate.
QSCRATCH is the only option.
However, setting dp/dm wakeup interrupt polarity based on current linestate
isn't perfect either. It could race with any change in linestate while it was being
read, resulting in missed wakeup interrupt.
Same is the case with QMP PHY when trying to check for RX terminations on
suspend.
IMO PHY driver should get this info from platform glue or controller driver.
E.g. current speed -> SS, HS/FS, LS or NONE (if not in session).
Kishon,
What would you suggest here?
Should we add new calls e.g. phy_get/set_current_speed like::
diff --git a/include/linux/phy/phy.h b/include/linux/phy/phy.h
index 78bb0d7..41d9ec2 100644
--- a/include/linux/phy/phy.h
+++ b/include/linux/phy/phy.h
@@ -29,6 +29,14 @@ enum phy_mode {
PHY_MODE_USB_OTG,
};
+enum phy_speed {
+ PHY_SPEED_INVALID,
+ PHY_SPEED_USB_LS,
+ PHY_SPEED_USB_FS_HS,
+ PHY_SPEED_USB_SS,
+};
+
/**
* struct phy_ops - set of function pointers for performing phy operations
* @init: operation to be performed for initializing phy
@@ -45,6 +53,7 @@ struct phy_ops {
int (*power_on)(struct phy *phy);
int (*power_off)(struct phy *phy);
int (*set_mode)(struct phy *phy, enum phy_mode mode);
+ int (*set_speed)(struct phy *phy, enum phy_speed speed);
int (*reset)(struct phy *phy);
struct module *owner;
};
>>>> - VBUS override bit becomes asserted simply because the mode is changed
>>>> to device mode but this is irrespective of the actual VBUS state. This
>>>> could break some test setups which perform a logical disconnect by
>>>> switching off/on VBUS while leaving data lines connected. Controller
>>>> would go merrily along thinking it is still attached to the host.
>>>>
>>>> Instead maybe this could be tied to EXTCON_USB handling in the glue
>>>> driver; though it would need to be an additional notifier on top of
>>>> dwc3/drd.c which already handles extcon for host/device mode.
>> Yes, dwc3/drd.c currently deals with only EXTCON_USB_HOST. So, for platforms
>> where role swap happens using only Vbus or single GPIO this should take care of.
>>
>>
>>> That is to say, we'd probably need to split out dwc3-qcom from
>>> dwc3-of-simple.c into its own driver (again) in order to add this.
>>>
>>> Jack
>> However, I agree that more appropriate place for lane0-pwr-present and
>> vbus override update is dwc3 glue driver. Since we don't have one right now,
>>
>> IMO once we have dwc3-qcom driver in place, this handling can be moved from
>> PHY to glue driver. Until then we can use this approach to get USB device mode
>> working on qcom platforms which are using dwc3-of-simple.c e.g. sdm820
>> dragonboard.
> Could that be done in this series too? IMO better to get it right in one
> shot. Is this aimed for 4.15?
I was aiming 4.15 for PHY drivers at least.
This will be further simplified if dwc3 glue driver can pass current speed as well
to PHY drivers.
> Jack
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
^ permalink raw reply related
* Re: [PATCH v5 4/9] examples/vm_power_mgr: add scale to medium freq fn
From: santosh @ 2017-10-05 9:07 UTC (permalink / raw)
To: Hunt, David, dev
Cc: konstantin.ananyev, jingjing.wu, Nemanja Marjanovic, Rory Sexton
In-Reply-To: <6c97bd17-7a24-d1d0-f200-91d68f68c664@intel.com>
Hi David,
On Thursday 05 October 2017 02:17 PM, Hunt, David wrote:
> Hi Santosh,
>
>
> On 4/10/2017 5:04 PM, santosh wrote:
>> Hi David,
>>
>>
>> On Wednesday 04 October 2017 08:55 PM, David Hunt wrote:
>>> Signed-off-by: Nemanja Marjanovic <nemanja.marjanovic@intel.com>
>>> Signed-off-by: Rory Sexton <rory.sexton@intel.com>
>>> Signed-off-by: David Hunt <david.hunt@intel.com>
>>> ---
>>> examples/vm_power_manager/power_manager.c | 15 +++++++++++++++
>>> examples/vm_power_manager/power_manager.h | 13 +++++++++++++
>>> 2 files changed, 28 insertions(+)
>>>
>>> diff --git a/examples/vm_power_manager/power_manager.c b/examples/vm_power_manager/power_manager.c
>>> index 80705f9..c021c1d 100644
>>> --- a/examples/vm_power_manager/power_manager.c
>>> +++ b/examples/vm_power_manager/power_manager.c
>>> @@ -286,3 +286,18 @@ power_manager_disable_turbo_core(unsigned int core_num)
>>> POWER_SCALE_CORE(disable_turbo, core_num, ret);
>>> return ret;
>>> }
>>> +
>>> +int
>>> +power_manager_scale_core_med(unsigned int core_num)
>>> +{
>>> + int ret = 0;
>>> +
>>> + if (core_num >= POWER_MGR_MAX_CPUS)
>>> + return -1;
>>> + if (!(global_enabled_cpus & (1ULL << core_num)))
>>> + return -1;
>>> + rte_spinlock_lock(&global_core_freq_info[core_num].power_sl);
>>> + ret = rte_power_set_freq(core_num, 5);
>> nits:
>> what is 5? also should be enum or macro.
>>
>> Thanks.
>>
>
> This probably shouldn't be hard-coded. The intention is to select a middle frequency. I can add a helper function to get the value
> that is halfway between min and max, and use that instead.
>
I'm ok with your proposition.
Thanks.
> Thanks,
> Dave.
>
>
>
^ permalink raw reply
* [PATCH 1/6] libxl: move vkb device to libxl_vkb.c
From: Oleksandr Grytsov @ 2017-10-05 9:07 UTC (permalink / raw)
To: xen-devel; +Cc: ian.jackson, wei.liu2, Oleksandr Grytsov
In-Reply-To: <1507194431-17588-1-git-send-email-al1img@gmail.com>
From: Oleksandr Grytsov <oleksandr_grytsov@epam.com>
Logically it is better to move vkb to
separate file as vkb device used not only by vfb
and console.
Signed-off-by: Oleksandr Grytsov <oleksandr_grytsov@epam.com>
---
tools/libxl/Makefile | 1 +
tools/libxl/libxl_console.c | 53 ---------------------------------
tools/libxl/libxl_vkb.c | 72 +++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 73 insertions(+), 53 deletions(-)
create mode 100644 tools/libxl/libxl_vkb.c
diff --git a/tools/libxl/Makefile b/tools/libxl/Makefile
index 2d52435..df1b710 100644
--- a/tools/libxl/Makefile
+++ b/tools/libxl/Makefile
@@ -139,6 +139,7 @@ LIBXL_OBJS = flexarray.o libxl.o libxl_create.o libxl_dm.o libxl_pci.o \
libxl_vtpm.o libxl_nic.o libxl_disk.o libxl_console.o \
libxl_cpupool.o libxl_mem.o libxl_sched.o libxl_tmem.o \
libxl_9pfs.o libxl_domain.o libxl_vdispl.o libxl_vsnd.o \
+ libxl_vkb.o \
$(LIBXL_OBJS-y)
LIBXL_OBJS += libxl_genid.o
LIBXL_OBJS += _libxl_types.o libxl_flask.o _libxl_types_internal.o
diff --git a/tools/libxl/libxl_console.c b/tools/libxl/libxl_console.c
index 624bd01..09facaf 100644
--- a/tools/libxl/libxl_console.c
+++ b/tools/libxl/libxl_console.c
@@ -583,45 +583,6 @@ int libxl_device_channel_getinfo(libxl_ctx *ctx, uint32_t domid,
return rc;
}
-static int libxl__device_vkb_setdefault(libxl__gc *gc, uint32_t domid,
- libxl_device_vkb *vkb, bool hotplug)
-{
- return libxl__resolve_domid(gc, vkb->backend_domname, &vkb->backend_domid);
-}
-
-static int libxl__device_from_vkb(libxl__gc *gc, uint32_t domid,
- libxl_device_vkb *vkb,
- libxl__device *device)
-{
- device->backend_devid = vkb->devid;
- device->backend_domid = vkb->backend_domid;
- device->backend_kind = LIBXL__DEVICE_KIND_VKBD;
- device->devid = vkb->devid;
- device->domid = domid;
- device->kind = LIBXL__DEVICE_KIND_VKBD;
-
- return 0;
-}
-
-int libxl_device_vkb_add(libxl_ctx *ctx, uint32_t domid, libxl_device_vkb *vkb,
- const libxl_asyncop_how *ao_how)
-{
- AO_CREATE(ctx, domid, ao_how);
- int rc;
-
- rc = libxl__device_add(gc, domid, &libxl__vkb_devtype, vkb);
- if (rc) {
- LOGD(ERROR, domid, "Unable to add vkb device");
- goto out;
- }
-
-out:
- libxl__ao_complete(egc, ao, rc);
- return AO_INPROGRESS;
-}
-
-static LIBXL_DEFINE_UPDATE_DEVID(vkb, "vkb")
-
static int libxl__device_vfb_setdefault(libxl__gc *gc, uint32_t domid,
libxl_device_vfb *vfb, bool hotplug)
{
@@ -706,8 +667,6 @@ static int libxl__set_xenstore_vfb(libxl__gc *gc, uint32_t domid,
}
/* The following functions are defined:
- * libxl_device_vkb_remove
- * libxl_device_vkb_destroy
* libxl_device_vfb_remove
* libxl_device_vfb_destroy
*/
@@ -716,18 +675,6 @@ static int libxl__set_xenstore_vfb(libxl__gc *gc, uint32_t domid,
* 1. add support for secondary consoles to xenconsoled
* 2. dynamically add/remove qemu chardevs via qmp messages. */
-/* vkb */
-
-#define libxl__add_vkbs NULL
-#define libxl_device_vkb_list NULL
-#define libxl_device_vkb_compare NULL
-
-LIBXL_DEFINE_DEVICE_REMOVE(vkb)
-
-DEFINE_DEVICE_TYPE_STRUCT(vkb,
- .skip_attach = 1
-);
-
#define libxl__add_vfbs NULL
#define libxl_device_vfb_list NULL
#define libxl_device_vfb_compare NULL
diff --git a/tools/libxl/libxl_vkb.c b/tools/libxl/libxl_vkb.c
new file mode 100644
index 0000000..0d01262
--- /dev/null
+++ b/tools/libxl/libxl_vkb.c
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2016 EPAM Systems Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; version 2.1 only. with the special
+ * exception on linking described in file LICENSE.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ */
+
+#include "libxl_internal.h"
+
+static int libxl__device_vkb_setdefault(libxl__gc *gc, uint32_t domid,
+ libxl_device_vkb *vkb, bool hotplug)
+{
+ return libxl__resolve_domid(gc, vkb->backend_domname, &vkb->backend_domid);
+}
+
+static int libxl__device_from_vkb(libxl__gc *gc, uint32_t domid,
+ libxl_device_vkb *vkb,
+ libxl__device *device)
+{
+ device->backend_devid = vkb->devid;
+ device->backend_domid = vkb->backend_domid;
+ device->backend_kind = LIBXL__DEVICE_KIND_VKBD;
+ device->devid = vkb->devid;
+ device->domid = domid;
+ device->kind = LIBXL__DEVICE_KIND_VKBD;
+
+ return 0;
+}
+
+int libxl_device_vkb_add(libxl_ctx *ctx, uint32_t domid, libxl_device_vkb *vkb,
+ const libxl_asyncop_how *ao_how)
+{
+ AO_CREATE(ctx, domid, ao_how);
+ int rc;
+
+ rc = libxl__device_add(gc, domid, &libxl__vkb_devtype, vkb);
+ if (rc) {
+ LOGD(ERROR, domid, "Unable to add vkb device");
+ goto out;
+ }
+
+out:
+ libxl__ao_complete(egc, ao, rc);
+ return AO_INPROGRESS;
+}
+
+static LIBXL_DEFINE_UPDATE_DEVID(vkb, "vkb")
+
+#define libxl__add_vkbs NULL
+#define libxl_device_vkb_list NULL
+#define libxl_device_vkb_compare NULL
+
+LIBXL_DEFINE_DEVICE_REMOVE(vkb)
+
+DEFINE_DEVICE_TYPE_STRUCT(vkb,
+ .skip_attach = 1
+);
+
+/*
+ * Local variables:
+ * mode: C
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
--
2.7.4
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel
^ permalink raw reply related
* [PATCH 5/6] xl: add vkb config parser and CLI
From: Oleksandr Grytsov @ 2017-10-05 9:07 UTC (permalink / raw)
To: xen-devel; +Cc: ian.jackson, wei.liu2, Oleksandr Grytsov
In-Reply-To: <1507194431-17588-1-git-send-email-al1img@gmail.com>
From: Oleksandr Grytsov <oleksandr_grytsov@epam.com>
Signed-off-by: Oleksandr Grytsov <oleksandr_grytsov@epam.com>
---
tools/xl/Makefile | 2 +-
tools/xl/xl.h | 3 ++
tools/xl/xl_cmdtable.c | 15 ++++++
tools/xl/xl_parse.c | 77 +++++++++++++++++++++++++--
tools/xl/xl_parse.h | 2 +-
tools/xl/xl_vkb.c | 141 +++++++++++++++++++++++++++++++++++++++++++++++++
6 files changed, 235 insertions(+), 5 deletions(-)
create mode 100644 tools/xl/xl_vkb.c
diff --git a/tools/xl/Makefile b/tools/xl/Makefile
index 66bdbde..2769295 100644
--- a/tools/xl/Makefile
+++ b/tools/xl/Makefile
@@ -22,7 +22,7 @@ XL_OBJS += xl_vtpm.o xl_block.o xl_nic.o xl_usb.o
XL_OBJS += xl_sched.o xl_pci.o xl_vcpu.o xl_cdrom.o xl_mem.o
XL_OBJS += xl_info.o xl_console.o xl_misc.o
XL_OBJS += xl_vmcontrol.o xl_saverestore.o xl_migrate.o
-XL_OBJS += xl_vdispl.o xl_vsnd.o
+XL_OBJS += xl_vdispl.o xl_vsnd.o xl_vkb.o
$(XL_OBJS): CFLAGS += $(CFLAGS_libxentoollog)
$(XL_OBJS): CFLAGS += $(CFLAGS_XL)
diff --git a/tools/xl/xl.h b/tools/xl/xl.h
index 703caa6..826e9c1 100644
--- a/tools/xl/xl.h
+++ b/tools/xl/xl.h
@@ -170,6 +170,9 @@ int main_vtpmdetach(int argc, char **argv);
int main_vdisplattach(int argc, char **argv);
int main_vdispllist(int argc, char **argv);
int main_vdispldetach(int argc, char **argv);
+int main_vkbattach(int argc, char **argv);
+int main_vkblist(int argc, char **argv);
+int main_vkbdetach(int argc, char **argv);
int main_vsndattach(int argc, char **argv);
int main_vsndlist(int argc, char **argv);
int main_vsnddetach(int argc, char **argv);
diff --git a/tools/xl/xl_cmdtable.c b/tools/xl/xl_cmdtable.c
index 8e162ce..f495e55 100644
--- a/tools/xl/xl_cmdtable.c
+++ b/tools/xl/xl_cmdtable.c
@@ -378,6 +378,21 @@ struct cmd_spec cmd_table[] = {
"Destroy a domain's virtual TPM device",
"<Domain> <DevId|uuid>",
},
+ { "vkb-attach",
+ &main_vkbattach, 1, 1,
+ "Create a new virtual keyboard device",
+ "<Domain> [backend-type=<BackendType>] [backend=<BackDomain>]",
+ },
+ { "vkb-list",
+ &main_vkblist, 0, 0,
+ "List virtual keyboard devices for a domain",
+ "<Domain(s)>",
+ },
+ { "vkb-detach",
+ &main_vkbdetach, 0, 1,
+ "Destroy a domain's virtual keyboard device",
+ "<Domain> <DevId>",
+ },
{ "vdispl-attach",
&main_vdisplattach, 1, 1,
"Create a new virtual display device",
diff --git a/tools/xl/xl_parse.c b/tools/xl/xl_parse.c
index 7cfd7fd..5f90634 100644
--- a/tools/xl/xl_parse.c
+++ b/tools/xl/xl_parse.c
@@ -1099,6 +1099,75 @@ static void parse_vsnd_config(const XLU_Config *config,
}
}
+int parse_vkb_config(libxl_device_vkb *vkb, char *token)
+{
+ char *oparg;
+
+ if (MATCH_OPTION("backend", token, oparg)) {
+ vkb->backend_domname = strdup(oparg);
+ } else if (MATCH_OPTION("backend-type", token, oparg)) {
+ libxl_vkb_backend backend_type;
+ if (libxl_vkb_backend_from_string(oparg, &backend_type)) {
+ fprintf(stderr, "Unknown backend_type \"%s\" in vkb spec\n",
+ oparg);
+ return -1;
+ }
+ vkb->backend_type = backend_type;
+ } else {
+ fprintf(stderr, "Unknown string \"%s\" in vkb spec\n", token);
+ return -1;
+ }
+
+ return 0;
+}
+
+static void parse_vkb_list(const XLU_Config *config,
+ libxl_domain_config *d_config)
+{
+ XLU_ConfigList *vkbs;
+ const char *item;
+ char *buf = NULL;
+ int rc;
+
+ if (!xlu_cfg_get_list (config, "vkb", &vkbs, 0, 0)) {
+ int entry = 0;
+ while ((item = xlu_cfg_get_listitem(vkbs, entry)) != NULL) {
+ libxl_device_vkb *vkb;
+ char *p;
+
+ vkb = ARRAY_EXTEND_INIT(d_config->vkbs,
+ d_config->num_vkbs,
+ libxl_device_vkb_init);
+
+ buf = strdup(item);
+
+ p = strtok (buf, ",");
+ while (p != NULL)
+ {
+ while (*p == ' ') p++;
+
+ rc = parse_vkb_config(vkb, p);
+ if (rc) goto out;
+
+ p = strtok (NULL, ",");
+ }
+
+ if (vkb->backend_type == LIBXL_VKB_BACKEND_UNKNOWN) {
+ fprintf(stderr, "backend-type should be set in vkb spec\n");
+ rc = -1; goto out;
+ }
+
+ entry++;
+ }
+ }
+
+ rc = 0;
+
+out:
+ free(buf);
+ if (rc) exit(EXIT_FAILURE);
+}
+
void parse_config_data(const char *config_source,
const char *config_data,
int config_len,
@@ -1941,7 +2010,7 @@ skip_nic:
vkb = ARRAY_EXTEND_INIT(d_config->vkbs, d_config->num_vkbs,
libxl_device_vkb_init);
- vkb->backend_type = LIBXL_VKBD_BACKEND_QEMU;
+ vkb->backend_type = LIBXL_VKB_BACKEND_QEMU;
p = strtok(buf2, ",");
if (!p)
@@ -2274,7 +2343,7 @@ skip_usbdev:
vkb = ARRAY_EXTEND_INIT(d_config->vkbs, d_config->num_vkbs,
libxl_device_vkb_init);
- vkb->backend_type = LIBXL_VKBD_BACKEND_QEMU;
+ vkb->backend_type = LIBXL_VKB_BACKEND_QEMU;
parse_top_level_vnc_options(config, &vfb->vnc);
parse_top_level_sdl_options(config, &vfb->sdl);
@@ -2423,7 +2492,9 @@ skip_usbdev:
"Unknown gic_version \"%s\" specified\n", buf);
exit(-ERROR_FAIL);
}
- }
+ }
+
+ parse_vkb_list(config, d_config);
xlu_cfg_destroy(config);
}
diff --git a/tools/xl/xl_parse.h b/tools/xl/xl_parse.h
index 9a948ea..19f453a 100644
--- a/tools/xl/xl_parse.h
+++ b/tools/xl/xl_parse.h
@@ -35,7 +35,7 @@ int parse_cpurange(const char *cpu, libxl_bitmap *cpumap);
int parse_nic_config(libxl_device_nic *nic, XLU_Config **config, char *token);
int parse_vdispl_config(libxl_device_vdispl *vdispl, char *token);
int parse_vsnd_item(libxl_device_vsnd *vsnd, const char *spec);
-
+int parse_vkb_config(libxl_device_vkb *vkb, char *token);
int match_option_size(const char *prefix, size_t len,
char *arg, char **argopt);
#define MATCH_OPTION(prefix, arg, oparg) \
diff --git a/tools/xl/xl_vkb.c b/tools/xl/xl_vkb.c
new file mode 100644
index 0000000..6ec4b28
--- /dev/null
+++ b/tools/xl/xl_vkb.c
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2016 EPAM Systems Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; version 2.1 only. with the special
+ * exception on linking described in file LICENSE.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ */
+
+#include <stdlib.h>
+
+#include <libxl.h>
+#include <libxl_utils.h>
+#include <libxlutil.h>
+
+#include "xl.h"
+#include "xl_utils.h"
+#include "xl_parse.h"
+
+int main_vkbattach(int argc, char **argv)
+{
+ int opt;
+ int rc;
+ uint32_t domid;
+ libxl_device_vkb vkb;
+
+ SWITCH_FOREACH_OPT(opt, "", NULL, "vkb-attach", 2) {
+ /* No options */
+ }
+
+ libxl_device_vkb_init(&vkb);
+ domid = find_domain(argv[optind++]);
+
+ for (argv += optind, argc -= optind; argc > 0; ++argv, --argc) {
+ rc = parse_vkb_config(&vkb, *argv);
+ if (rc) goto out;
+ }
+
+ if (dryrun_only) {
+ char *json = libxl_device_vkb_to_json(ctx, &vkb);
+ printf("vkb: %s\n", json);
+ free(json);
+ goto out;
+ }
+
+ if (libxl_device_vkb_add(ctx, domid, &vkb, 0)) {
+ fprintf(stderr, "libxl_device_vkb_add failed.\n");
+ rc = ERROR_FAIL; goto out;
+ }
+
+ rc = 0;
+
+out:
+ libxl_device_vkb_dispose(&vkb);
+ return rc;
+}
+
+int main_vkblist(int argc, char **argv)
+{
+ int opt;
+ libxl_device_vkb *vkbs;
+ libxl_vkbinfo vkbinfo;
+ int nb, i;
+
+ SWITCH_FOREACH_OPT(opt, "", NULL, "vkb-list", 1) {
+ /* No options */
+ }
+
+ /* Idx BE Hdl Sta evch ref BE-path */
+ printf("%-3s %-2s %-6s %-5s %-6s %6s %-30s\n",
+ "Idx", "BE", "handle", "state", "evt-ch", "ref", "BE-path");
+ for (argv += optind, argc -= optind; argc > 0; --argc, ++argv) {
+ uint32_t domid = find_domain(*argv);
+ vkbs = libxl_device_vkb_list(ctx, domid, &nb);
+ if (!vkbs) {
+ continue;
+ }
+ for (i = 0; i < nb; ++i) {
+ if (!libxl_device_vkb_getinfo(ctx, domid, &vkbs[i], &vkbinfo)) {
+ /* Idx BE */
+ printf("%-3d %-2d ", vkbinfo.devid, vkbinfo.backend_id);
+ /* Hdl Sta evch ref BE-path */
+ printf("%6d %5d %6d %6d %-30s\n",
+ vkbinfo.devid, vkbinfo.state, vkbinfo.evtch,
+ vkbinfo.rref, vkbinfo.backend);
+ libxl_vkbinfo_dispose(&vkbinfo);
+ }
+ }
+ libxl_device_vkb_list_free(vkbs, nb);
+ }
+ return 0;
+}
+
+int main_vkbdetach(int argc, char **argv)
+{
+ uint32_t domid, devid;
+ int opt, rc;
+ libxl_device_vkb vkb;
+
+ SWITCH_FOREACH_OPT(opt, "", NULL, "vkb-detach", 2) {
+ /* No options */
+ }
+
+ domid = find_domain(argv[optind++]);
+ devid = atoi(argv[optind++]);
+
+ libxl_device_vkb_init(&vkb);
+
+ if (libxl_devid_to_device_vkb(ctx, domid, devid, &vkb)) {
+ fprintf(stderr, "Error: Device %d not connected.\n", devid);
+ rc = ERROR_FAIL;
+ goto out;
+ }
+
+ rc = libxl_device_vkb_remove(ctx, domid, &vkb, 0);
+ if (rc) {
+ fprintf(stderr, "libxl_device_vkb_remove failed.\n");
+ rc = ERROR_FAIL;
+ goto out;
+ }
+
+ rc = 0;
+
+out:
+ libxl_device_vkb_dispose(&vkb);
+ return rc;
+}
+
+
+/*
+ * Local variables:
+ * mode: C
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
--
2.7.4
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel
^ permalink raw reply related
* [PATCH 6/6] docs: add vkb device to xl.cfg and xl
From: Oleksandr Grytsov @ 2017-10-05 9:07 UTC (permalink / raw)
To: xen-devel; +Cc: ian.jackson, wei.liu2, Oleksandr Grytsov
In-Reply-To: <1507194431-17588-1-git-send-email-al1img@gmail.com>
From: Oleksandr Grytsov <oleksandr_grytsov@epam.com>
Signed-off-by: Oleksandr Grytsov <oleksandr_grytsov@epam.com>
---
docs/man/xl.cfg.pod.5.in | 24 ++++++++++++++++++++++++
docs/man/xl.pod.1.in | 22 ++++++++++++++++++++++
2 files changed, 46 insertions(+)
diff --git a/docs/man/xl.cfg.pod.5.in b/docs/man/xl.cfg.pod.5.in
index 4948dd7..a9e10aa 100644
--- a/docs/man/xl.cfg.pod.5.in
+++ b/docs/man/xl.cfg.pod.5.in
@@ -1317,6 +1317,30 @@ I<EXAMPLE:>
=back
+=over 4
+
+=item B<vkb=[ "VKB_SPEC_STRING", "VKB_SPEC_STRING", ...]>
+
+Specifies the virtual keyboard device to be provided to the guest.
+
+Each B<VKB_SPEC_STRING> is a comma-separated list of C<KEY=VALUE>
+settings from the following list:
+
+=over 4
+
+=item B<backend=domain-id>
+
+Specifies the backend domain name or id.
+
+=item B<backend-type=type>
+
+Specifies the backend type: qemu - for QEMU backend or linux - for Linux PV
+domain.
+
+=back
+
+=back
+
=head2 Paravirtualised (PV) Guest Specific Options
The following options apply only to Paravirtual (PV) guests.
diff --git a/docs/man/xl.pod.1.in b/docs/man/xl.pod.1.in
index 0a88fd5..17b1e53 100644
--- a/docs/man/xl.pod.1.in
+++ b/docs/man/xl.pod.1.in
@@ -1506,6 +1506,28 @@ List vsnd devices for a domain.
=back
+=head2 KEYBOARD DEVICES
+
+=over 4
+
+=item B<vkb-attach> I<domain-id> I<vkb-device>
+
+Creates a new keyboard device in the domain specified by I<domain-id>.
+I<vkb-device> describes the device to attach, using the same format as the
+B<VKB_SPEC_STRING> string in the domain config file. See L<xl.cfg(5)>
+for more informations.
+
+=item B<vkb-detach> I<domain-id> I<devid>
+
+Removes the keyboard device from the domain specified by I<domain-id>.
+I<devid> is the virtual interface device number within the domain
+
+=item B<vkb-list> I<domain-id>
+
+List virtual network interfaces for a domain.
+
+=back
+
=head1 PCI PASS-THROUGH
=over 4
--
2.7.4
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel
^ permalink raw reply related
* [PATCH 4/6] libxl: vkb add list and info functions
From: Oleksandr Grytsov @ 2017-10-05 9:07 UTC (permalink / raw)
To: xen-devel; +Cc: ian.jackson, wei.liu2, Oleksandr Grytsov
In-Reply-To: <1507194431-17588-1-git-send-email-al1img@gmail.com>
From: Oleksandr Grytsov <oleksandr_grytsov@epam.com>
Signed-off-by: Oleksandr Grytsov <oleksandr_grytsov@epam.com>
---
tools/libxl/libxl.h | 10 +++++
tools/libxl/libxl_types.idl | 11 +++++
tools/libxl/libxl_utils.h | 3 ++
tools/libxl/libxl_vkb.c | 106 ++++++++++++++++++++++++++++++++++++++++++--
4 files changed, 127 insertions(+), 3 deletions(-)
diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h
index acb73ce..f2f8442 100644
--- a/tools/libxl/libxl.h
+++ b/tools/libxl/libxl.h
@@ -1950,6 +1950,16 @@ int libxl_device_vkb_destroy(libxl_ctx *ctx, uint32_t domid,
const libxl_asyncop_how *ao_how)
LIBXL_EXTERNAL_CALLERS_ONLY;
+libxl_device_vkb *libxl_device_vkb_list(libxl_ctx *ctx,
+ uint32_t domid, int *num)
+ LIBXL_EXTERNAL_CALLERS_ONLY;
+void libxl_device_vkb_list_free(libxl_device_vkb* list, int num)
+ LIBXL_EXTERNAL_CALLERS_ONLY;
+int libxl_device_vkb_getinfo(libxl_ctx *ctx, uint32_t domid,
+ libxl_device_vkb *vkb,
+ libxl_vkbinfo *vkbinfo)
+ LIBXL_EXTERNAL_CALLERS_ONLY;
+
/* Framebuffer */
int libxl_device_vfb_add(libxl_ctx *ctx, uint32_t domid, libxl_device_vfb *vfb,
const libxl_asyncop_how *ao_how)
diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl
index 65cd81a..a647bfc 100644
--- a/tools/libxl/libxl_types.idl
+++ b/tools/libxl/libxl_types.idl
@@ -1014,6 +1014,17 @@ libxl_vsndinfo = Struct("vsndinfo", [
("pcms", Array(libxl_pcminfo, "num_vsnd_pcms"))
])
+libxl_vkbinfo = Struct("vkbinfo", [
+ ("backend", string),
+ ("backend_id", uint32),
+ ("frontend", string),
+ ("frontend_id", uint32),
+ ("devid", libxl_devid),
+ ("state", integer),
+ ("evtch", integer),
+ ("rref", integer)
+ ], dir=DIR_OUT)
+
# NUMA node characteristics: size and free are how much memory it has, and how
# much of it is free, respectively. dists is an array of distances from this
# node to each other node.
diff --git a/tools/libxl/libxl_utils.h b/tools/libxl/libxl_utils.h
index 5455752..44409af 100644
--- a/tools/libxl/libxl_utils.h
+++ b/tools/libxl/libxl_utils.h
@@ -79,6 +79,9 @@ int libxl_devid_to_device_vtpm(libxl_ctx *ctx, uint32_t domid,
int libxl_devid_to_device_usbctrl(libxl_ctx *ctx, uint32_t domid,
int devid, libxl_device_usbctrl *usbctrl);
+int libxl_devid_to_device_vkb(libxl_ctx *ctx, uint32_t domid,
+ int devid, libxl_device_vkb *vkb);
+
int libxl_devid_to_device_vdispl(libxl_ctx *ctx, uint32_t domid,
int devid, libxl_device_vdispl *vdispl);
diff --git a/tools/libxl/libxl_vkb.c b/tools/libxl/libxl_vkb.c
index 07b5428..276cc8a 100644
--- a/tools/libxl/libxl_vkb.c
+++ b/tools/libxl/libxl_vkb.c
@@ -13,6 +13,7 @@
*/
#include "libxl_internal.h"
+#include "xen/io/kbdif.h"
static int libxl__device_vkb_setdefault(libxl__gc *gc, uint32_t domid,
libxl_device_vkb *vkb, bool hotplug)
@@ -41,6 +42,22 @@ static int libxl__device_vkb_dm_needed(libxl_device_vkb *vkb, uint32_t domid)
return 0;
}
+static int libxl__vkb_from_xenstore(libxl__gc *gc, const char *libxl_path,
+ libxl_devid devid,
+ libxl_device_vkb *vkb)
+{
+ const char *be_path;
+ int rc;
+
+ vkb->devid = devid;
+ rc = libxl__xs_read_mandatory(gc, XBT_NULL,
+ GCSPRINTF("%s/backend", libxl_path),
+ &be_path);
+ if (rc) return rc;
+
+ return libxl__backendpath_parse_domid(gc, be_path, &vkb->backend_domid);
+}
+
int libxl_device_vkb_add(libxl_ctx *ctx, uint32_t domid, libxl_device_vkb *vkb,
const libxl_asyncop_how *ao_how)
{
@@ -58,17 +75,100 @@ out:
return AO_INPROGRESS;
}
+int libxl_devid_to_device_vkb(libxl_ctx *ctx, uint32_t domid,
+ int devid, libxl_device_vkb *vkb)
+{
+ GC_INIT(ctx);
+
+ libxl_device_vkb *vkbs = NULL;
+ int n, i;
+ int rc;
+
+ libxl_device_vkb_init(vkb);
+
+ vkbs = libxl__device_list(gc, &libxl__vkb_devtype, domid, &n);
+
+ if (!vkbs) { rc = ERROR_NOTFOUND; goto out; }
+
+ for (i = 0; i < n; ++i) {
+ if (devid == vkbs[i].devid) {
+ libxl_device_vkb_copy(ctx, vkb, &vkbs[i]);
+ rc = 0;
+ goto out;
+ }
+ }
+
+ rc = ERROR_NOTFOUND;
+
+out:
+
+ if (vkbs)
+ libxl__device_list_free(&libxl__vkb_devtype, vkbs, n);
+
+ GC_FREE;
+ return rc;
+}
+
+int libxl_device_vkb_getinfo(libxl_ctx *ctx, uint32_t domid,
+ libxl_device_vkb *vkb,
+ libxl_vkbinfo *info)
+{
+ GC_INIT(ctx);
+ char *libxl_path, *dompath, *devpath;
+ char *val;
+ int rc;
+
+ libxl_vkbinfo_init(info);
+ dompath = libxl__xs_get_dompath(gc, domid);
+ info->devid = vkb->devid;
+
+ devpath = GCSPRINTF("%s/device/vkbd/%d", dompath, info->devid);
+ libxl_path = GCSPRINTF("%s/device/vkbd/%d",
+ libxl__xs_libxl_path(gc, domid),
+ info->devid);
+ info->backend = xs_read(ctx->xsh, XBT_NULL,
+ GCSPRINTF("%s/backend", libxl_path),
+ NULL);
+ if (!info->backend) { rc = ERROR_FAIL; goto out; }
+
+ rc = libxl__backendpath_parse_domid(gc, info->backend, &info->backend_id);
+ if (rc) goto out;
+
+ val = libxl__xs_read(gc, XBT_NULL, GCSPRINTF("%s/state", devpath));
+ info->state = val ? strtoul(val, NULL, 10) : -1;
+
+ info->frontend = xs_read(ctx->xsh, XBT_NULL,
+ GCSPRINTF("%s/frontend", libxl_path),
+ NULL);
+ info->frontend_id = domid;
+
+ val = libxl__xs_read(gc, XBT_NULL,
+ GCSPRINTF("%s/"XENKBD_FIELD_EVT_CHANNEL, devpath));
+ info->evtch = val ? strtoul(val, NULL, 10) : -1;
+
+ val = libxl__xs_read(gc, XBT_NULL,
+ GCSPRINTF("%s/"XENKBD_FIELD_RING_GREF, devpath));
+ info->rref = val ? strtoul(val, NULL, 10) : -1;
+
+ rc = 0;
+
+out:
+ GC_FREE;
+ return rc;
+}
+
static LIBXL_DEFINE_UPDATE_DEVID(vkb, "vkbd")
#define libxl__add_vkbs NULL
-#define libxl_device_vkb_list NULL
#define libxl_device_vkb_compare NULL
+LIBXL_DEFINE_DEVICE_LIST(vkb)
LIBXL_DEFINE_DEVICE_REMOVE(vkb)
-DEFINE_DEVICE_TYPE_STRUCT_X(vkb, vkb, vkbd
+DEFINE_DEVICE_TYPE_STRUCT_X(vkb, vkb, vkbd,
.skip_attach = 1,
- .dm_needed = (device_dm_needed_fn_t)libxl__device_vkb_dm_needed
+ .dm_needed = (device_dm_needed_fn_t)libxl__device_vkb_dm_needed,
+ .from_xenstore = (device_from_xenstore_fn_t)libxl__vkb_from_xenstore
);
/*
--
2.7.4
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel
^ permalink raw reply related
* [PATCH 3/6] libxl: add backend type to vkb
From: Oleksandr Grytsov @ 2017-10-05 9:07 UTC (permalink / raw)
To: xen-devel; +Cc: ian.jackson, wei.liu2, Oleksandr Grytsov
In-Reply-To: <1507194431-17588-1-git-send-email-al1img@gmail.com>
From: Oleksandr Grytsov <oleksandr_grytsov@epam.com>
New field backend_type is added to vkb device
in order to have QEMU and user space backend
simultaneously. Each vkb backend shall read
appropriate XS entry and service only own
frontends.
Signed-off-by: Oleksandr Grytsov <oleksandr_grytsov@epam.com>
---
tools/libxl/libxl_create.c | 4 ++++
tools/libxl/libxl_dm.c | 2 ++
tools/libxl/libxl_types.idl | 7 +++++++
tools/libxl/libxl_vkb.c | 10 +++++++++-
tools/xl/xl_parse.c | 4 ++++
5 files changed, 26 insertions(+), 1 deletion(-)
diff --git a/tools/libxl/libxl_create.c b/tools/libxl/libxl_create.c
index f813114..7268f7f 100644
--- a/tools/libxl/libxl_create.c
+++ b/tools/libxl/libxl_create.c
@@ -1349,6 +1349,7 @@ static void domcreate_launch_dm(libxl__egc *egc, libxl__multidev *multidev,
}
libxl_device_vkb_init(&vkb);
+ vkb.backend_type = LIBXL_VKB_BACKEND_QEMU;
libxl__device_add(gc, domid, &libxl__vkb_devtype, &vkb);
libxl_device_vkb_dispose(&vkb);
@@ -1376,6 +1377,9 @@ static void domcreate_launch_dm(libxl__egc *egc, libxl__multidev *multidev,
for (i = 0; i < d_config->num_vfbs; i++) {
libxl__device_add(gc, domid, &libxl__vfb_devtype,
&d_config->vfbs[i]);
+ }
+
+ for (i = 0; i < d_config->num_vkbs; i++) {
libxl__device_add(gc, domid, &libxl__vkb_devtype,
&d_config->vkbs[i]);
}
diff --git a/tools/libxl/libxl_dm.c b/tools/libxl/libxl_dm.c
index 98f89a9..d8b0ee7 100644
--- a/tools/libxl/libxl_dm.c
+++ b/tools/libxl/libxl_dm.c
@@ -1728,6 +1728,8 @@ static int libxl__vfb_and_vkb_from_hvm_guest_config(libxl__gc *gc,
vkb->backend_domid = 0;
vkb->devid = 0;
+ vkb->backend_type = LIBXL_VKB_BACKEND_QEMU;
+
return 0;
}
diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl
index cd0c06f..65cd81a 100644
--- a/tools/libxl/libxl_types.idl
+++ b/tools/libxl/libxl_types.idl
@@ -240,6 +240,12 @@ libxl_checkpointed_stream = Enumeration("checkpointed_stream", [
(2, "COLO"),
])
+libxl_vkb_backend = Enumeration("vkb_backend", [
+ (0, "UNKNOWN"),
+ (1, "QEMU"),
+ (2, "LINUX")
+ ])
+
#
# Complex libxl types
#
@@ -603,6 +609,7 @@ libxl_device_vkb = Struct("device_vkb", [
("backend_domid", libxl_domid),
("backend_domname", string),
("devid", libxl_devid),
+ ("backend_type", libxl_vkb_backend)
])
libxl_device_disk = Struct("device_disk", [
diff --git a/tools/libxl/libxl_vkb.c b/tools/libxl/libxl_vkb.c
index ea6fca8..07b5428 100644
--- a/tools/libxl/libxl_vkb.c
+++ b/tools/libxl/libxl_vkb.c
@@ -34,6 +34,13 @@ static int libxl__device_from_vkb(libxl__gc *gc, uint32_t domid,
return 0;
}
+static int libxl__device_vkb_dm_needed(libxl_device_vkb *vkb, uint32_t domid)
+{
+ if (vkb->backend_type == LIBXL_VKB_BACKEND_QEMU)
+ return 1;
+ return 0;
+}
+
int libxl_device_vkb_add(libxl_ctx *ctx, uint32_t domid, libxl_device_vkb *vkb,
const libxl_asyncop_how *ao_how)
{
@@ -60,7 +67,8 @@ static LIBXL_DEFINE_UPDATE_DEVID(vkb, "vkbd")
LIBXL_DEFINE_DEVICE_REMOVE(vkb)
DEFINE_DEVICE_TYPE_STRUCT_X(vkb, vkb, vkbd
- .skip_attach = 1
+ .skip_attach = 1,
+ .dm_needed = (device_dm_needed_fn_t)libxl__device_vkb_dm_needed
);
/*
diff --git a/tools/xl/xl_parse.c b/tools/xl/xl_parse.c
index d4c2efb..7cfd7fd 100644
--- a/tools/xl/xl_parse.c
+++ b/tools/xl/xl_parse.c
@@ -1941,6 +1941,8 @@ skip_nic:
vkb = ARRAY_EXTEND_INIT(d_config->vkbs, d_config->num_vkbs,
libxl_device_vkb_init);
+ vkb->backend_type = LIBXL_VKBD_BACKEND_QEMU;
+
p = strtok(buf2, ",");
if (!p)
goto skip_vfb;
@@ -2272,6 +2274,8 @@ skip_usbdev:
vkb = ARRAY_EXTEND_INIT(d_config->vkbs, d_config->num_vkbs,
libxl_device_vkb_init);
+ vkb->backend_type = LIBXL_VKBD_BACKEND_QEMU;
+
parse_top_level_vnc_options(config, &vfb->vnc);
parse_top_level_sdl_options(config, &vfb->sdl);
xlu_cfg_replace_string (config, "keymap", &vfb->keymap, 0);
--
2.7.4
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel
^ permalink raw reply related
* [PATCH 0/6] libxl: create standalone vkb device
From: Oleksandr Grytsov @ 2017-10-05 9:07 UTC (permalink / raw)
To: xen-devel; +Cc: ian.jackson, wei.liu2, Oleksandr Grytsov
From: Oleksandr Grytsov <oleksandr_grytsov@epam.com>
Currently vkb device is the part of FB and console.
In embedded application we use vkb protocol to communicate
with user space backend. For this purpose we need to have
possibility to enable vkb device without QEMU, FB etc.
This particular issue was already discussed int the mail
thread [1]. There were few possible solutions. We've implemented
one suggested by Stefano: add "type" field for vkb.
Each backend (QEMU or user space) shall read this field and
serve frontend only for own type. I will provide the patch
for QEMU backend, once this solution is submitted to libxl.
This patchset consist of following changes:
* vkb related code is moved to libxl_vkb.c - as it now
used not only by console and FB;
* add backend type support in order to support QEMU and
user space backends;
* add getting vkb list and getting device by id in order
to implement CLI commands to attach, detach and list
vkb devices;
* add new vkb entry in xl.cfg to handle separate vkb
configuration;
* add CLI vkb-attach, vkb-detach and vkb-list commands;
* update documentation accordingly.
[1] https://marc.info/?l=qemu-devel&m=149219237030212&w=2
Oleksandr Grytsov (6):
libxl: move vkb device to libxl_vkb.c
libxl: fix vkb XS entry and type
libxl: add backend type to vkb
libxl: vkb add list and info functions
xl: add vkb config parser and CLI
docs: add vkb device to xl.cfg and xl
docs/man/xl.cfg.pod.5.in | 24 ++++++
docs/man/xl.pod.1.in | 22 ++++++
tools/libxl/Makefile | 1 +
tools/libxl/libxl.h | 10 +++
tools/libxl/libxl_console.c | 53 -------------
tools/libxl/libxl_create.c | 4 +
tools/libxl/libxl_dm.c | 2 +
tools/libxl/libxl_types.idl | 18 +++++s
tools/libxl/libxl_utils.h | 3 +
tools/libxl/libxl_vkb.c | 180 ++++++++++++++++++++++++++++++++++++++++++++
tools/xl/Makefile | 2 +-
tools/xl/xl.h | 3 +
tools/xl/xl_cmdtable.c | 15 ++++
tools/xl/xl_parse.c | 77 ++++++++++++++++++-
tools/xl/xl_parse.h | 2 +-
tools/xl/xl_vkb.c | 141 ++++++++++++++++++++++++++++++++++
16 files changed, 501 insertions(+), 56 deletions(-)
create mode 100644 tools/libxl/libxl_vkb.c
create mode 100644 tools/xl/xl_vkb.c
--
2.7.4
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel
^ permalink raw reply
* [PATCH 2/6] libxl: fix vkb XS entry and type
From: Oleksandr Grytsov @ 2017-10-05 9:07 UTC (permalink / raw)
To: xen-devel; +Cc: ian.jackson, wei.liu2, Oleksandr Grytsov
In-Reply-To: <1507194431-17588-1-git-send-email-al1img@gmail.com>
From: Oleksandr Grytsov <oleksandr_grytsov@epam.com>
vkb has vkbd name in XS.
Signed-off-by: Oleksandr Grytsov <oleksandr_grytsov@epam.com>
---
tools/libxl/libxl_vkb.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/tools/libxl/libxl_vkb.c b/tools/libxl/libxl_vkb.c
index 0d01262..ea6fca8 100644
--- a/tools/libxl/libxl_vkb.c
+++ b/tools/libxl/libxl_vkb.c
@@ -51,7 +51,7 @@ out:
return AO_INPROGRESS;
}
-static LIBXL_DEFINE_UPDATE_DEVID(vkb, "vkb")
+static LIBXL_DEFINE_UPDATE_DEVID(vkb, "vkbd")
#define libxl__add_vkbs NULL
#define libxl_device_vkb_list NULL
@@ -59,7 +59,7 @@ static LIBXL_DEFINE_UPDATE_DEVID(vkb, "vkb")
LIBXL_DEFINE_DEVICE_REMOVE(vkb)
-DEFINE_DEVICE_TYPE_STRUCT(vkb,
+DEFINE_DEVICE_TYPE_STRUCT_X(vkb, vkb, vkbd
.skip_attach = 1
);
--
2.7.4
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel
^ permalink raw reply related
* Re: [PATCH] arm64: dts: renesas: salvator-common: add pfc node for USB3.0 channel 0
From: Simon Horman @ 2017-10-05 9:06 UTC (permalink / raw)
To: Geert Uytterhoeven
Cc: Yoshihiro Shimoda, Magnus Damm, Rob Herring, Mark Rutland,
devicetree@vger.kernel.org, Linux-Renesas
In-Reply-To: <CAMuHMdUz78BmySULe_wizFEhFAtiBiQLZ9Ov++S94+yb4YpxDg@mail.gmail.com>
On Wed, Oct 04, 2017 at 03:53:36PM +0200, Geert Uytterhoeven wrote:
> On Tue, Oct 3, 2017 at 10:01 AM, Yoshihiro Shimoda
> <yoshihiro.shimoda.uh@renesas.com> wrote:
> > Since a R-Car Gen3 bootloader enables the PFC of USB3.0 channel 0,
> > the USB3.0 host controller works without this setting on the kernel.
> > But, this setting should have salvator-common.dtsi. So, this patch
> > adds the pfc node for USB3.0 channel 0.
> >
> > Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
>
> Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Thanks, applied.
^ permalink raw reply
* [PATCH V10 13/15] mmc: block: Add CQE and blk-mq support
From: Adrian Hunter @ 2017-10-05 8:59 UTC (permalink / raw)
To: Ulf Hansson
Cc: linux-mmc, linux-block, linux-kernel, Bough Chen, Alex Lemberg,
Mateusz Nowak, Yuliy Izrailov, Jaehoon Chung, Dong Aisheng,
Das Asutosh, Zhangfei Gao, Sahitya Tummala, Harjani Ritesh,
Venu Byravarasu, Linus Walleij, Shawn Lin, Christoph Hellwig
In-Reply-To: <1506083824-4024-14-git-send-email-adrian.hunter@intel.com>
Add CQE support to the block driver, including:
- optionally using DCMD for flush requests
- "manually" issuing discard requests
- issuing read / write requests to the CQE
- supporting block-layer timeouts
- handling recovery
- supporting re-tuning
CQE offers 25% - 50% better random multi-threaded I/O. There is a slight
(e.g. 2%) drop in sequential read speed but no observable change to sequential
write.
CQE automatically sends the commands to complete requests. However it only
supports reads / writes and so-called "direct commands" (DCMD). Furthermore
DCMD is limited to one command at a time, but discards require 3 commands.
That makes issuing discards through CQE very awkward, but some CQE's don't
support DCMD anyway. So for discards, the existing non-CQE approach is
taken, where the mmc core code issues the 3 commands one at a time i.e.
mmc_erase(). Where DCMD is used, is for issuing flushes.
For host controllers without CQE support, blk-mq support is extended to
synchronous reads/writes or, if the host supports CAP_WAIT_WHILE_BUSY,
asynchonous reads/writes. The advantage of asynchronous reads/writes is
that it allows the preparation of the next request while the current
request is in progress.
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
Changes since V9:
- reinstate mq support for REQ_OP_DRV_IN/OUT that was removed because
it was incorrectly assumed to be handled by the rpmb character device
- don't check for rpmb block device anymore
drivers/mmc/core/block.c | 739 ++++++++++++++++++++++++++++++++++++++++++++++-
drivers/mmc/core/block.h | 8 +
drivers/mmc/core/queue.c | 425 +++++++++++++++++++++++++--
drivers/mmc/core/queue.h | 52 ++++
4 files changed, 1194 insertions(+), 30 deletions(-)
diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c
index ea80ff4cd7f9..51a7aea2caea 100644
--- a/drivers/mmc/core/block.c
+++ b/drivers/mmc/core/block.c
@@ -112,6 +112,7 @@ struct mmc_blk_data {
#define MMC_BLK_WRITE BIT(1)
#define MMC_BLK_DISCARD BIT(2)
#define MMC_BLK_SECDISCARD BIT(3)
+#define MMC_BLK_CQE_RECOVERY BIT(4)
/*
* Only set in main mmc_blk_data associated
@@ -1264,7 +1265,10 @@ static void mmc_blk_issue_drv_op(struct mmc_queue *mq, struct request *req)
break;
}
mq_rq->drv_op_result = ret;
- blk_end_request_all(req, ret ? BLK_STS_IOERR : BLK_STS_OK);
+ if (req->mq_ctx)
+ blk_mq_end_request(req, ret ? BLK_STS_IOERR : BLK_STS_OK);
+ else
+ blk_end_request_all(req, ret ? BLK_STS_IOERR : BLK_STS_OK);
}
static void mmc_blk_issue_discard_rq(struct mmc_queue *mq, struct request *req)
@@ -1307,7 +1311,10 @@ static void mmc_blk_issue_discard_rq(struct mmc_queue *mq, struct request *req)
else
mmc_blk_reset_success(md, type);
fail:
- blk_end_request(req, status, blk_rq_bytes(req));
+ if (req->mq_ctx)
+ blk_mq_end_request(req, status);
+ else
+ blk_end_request(req, status, blk_rq_bytes(req));
}
static void mmc_blk_issue_secdiscard_rq(struct mmc_queue *mq,
@@ -1377,7 +1384,10 @@ static void mmc_blk_issue_secdiscard_rq(struct mmc_queue *mq,
if (!err)
mmc_blk_reset_success(md, type);
out:
- blk_end_request(req, status, blk_rq_bytes(req));
+ if (req->mq_ctx)
+ blk_mq_end_request(req, status);
+ else
+ blk_end_request(req, status, blk_rq_bytes(req));
}
static void mmc_blk_issue_flush(struct mmc_queue *mq, struct request *req)
@@ -1387,7 +1397,10 @@ static void mmc_blk_issue_flush(struct mmc_queue *mq, struct request *req)
int ret = 0;
ret = mmc_flush_cache(card);
- blk_end_request_all(req, ret ? BLK_STS_IOERR : BLK_STS_OK);
+ if (req->mq_ctx)
+ blk_mq_end_request(req, ret ? BLK_STS_IOERR : BLK_STS_OK);
+ else
+ blk_end_request_all(req, ret ? BLK_STS_IOERR : BLK_STS_OK);
}
/*
@@ -1413,15 +1426,18 @@ static inline void mmc_apply_rel_rw(struct mmc_blk_request *brq,
}
}
-#define CMD_ERRORS \
- (R1_OUT_OF_RANGE | /* Command argument out of range */ \
- R1_ADDRESS_ERROR | /* Misaligned address */ \
+#define CMD_ERRORS_EXCL_OOR \
+ (R1_ADDRESS_ERROR | /* Misaligned address */ \
R1_BLOCK_LEN_ERROR | /* Transferred block length incorrect */\
R1_WP_VIOLATION | /* Tried to write to protected block */ \
R1_CARD_ECC_FAILED | /* Card ECC failed */ \
R1_CC_ERROR | /* Card controller error */ \
R1_ERROR) /* General/unknown error */
+#define CMD_ERRORS \
+ (CMD_ERRORS_EXCL_OOR | \
+ R1_OUT_OF_RANGE) /* Command argument out of range */ \
+
static void mmc_blk_eval_resp_error(struct mmc_blk_request *brq)
{
u32 val;
@@ -1698,6 +1714,138 @@ static void mmc_blk_data_prep(struct mmc_queue *mq, struct mmc_queue_req *mqrq,
*do_data_tag_p = do_data_tag;
}
+#define MMC_CQE_RETRIES 2
+
+static void mmc_blk_cqe_complete_rq(struct mmc_queue *mq, struct request *req)
+{
+ struct mmc_queue_req *mqrq = req_to_mmc_queue_req(req);
+ struct mmc_request *mrq = &mqrq->brq.mrq;
+ struct request_queue *q = req->q;
+ struct mmc_host *host = mq->card->host;
+ unsigned long flags;
+ bool put_card;
+ int err;
+
+ mmc_cqe_post_req(host, mrq);
+
+ if (mrq->cmd && mrq->cmd->error)
+ err = mrq->cmd->error;
+ else if (mrq->data && mrq->data->error)
+ err = mrq->data->error;
+ else
+ err = 0;
+
+ if (err) {
+ if (mqrq->retries++ < MMC_CQE_RETRIES)
+ blk_mq_requeue_request(req, true);
+ else
+ blk_mq_end_request(req, BLK_STS_IOERR);
+ } else if (mrq->data) {
+ if (blk_update_request(req, BLK_STS_OK, mrq->data->bytes_xfered))
+ blk_mq_requeue_request(req, true);
+ else
+ __blk_mq_end_request(req, BLK_STS_OK);
+ } else {
+ blk_mq_end_request(req, BLK_STS_OK);
+ }
+
+ spin_lock_irqsave(q->queue_lock, flags);
+
+ mq->in_flight[mmc_issue_type(mq, req)] -= 1;
+
+ put_card = mmc_tot_in_flight(mq) == 0;
+
+ mmc_cqe_check_busy(mq);
+
+ spin_unlock_irqrestore(q->queue_lock, flags);
+
+ if (!mq->cqe_busy)
+ blk_mq_run_hw_queues(q, true);
+
+ if (put_card)
+ mmc_put_card(mq->card, &mq->ctx);
+}
+
+void mmc_blk_cqe_recovery(struct mmc_queue *mq)
+{
+ struct mmc_card *card = mq->card;
+ struct mmc_host *host = card->host;
+ int err;
+
+ pr_debug("%s: CQE recovery start\n", mmc_hostname(host));
+
+ err = mmc_cqe_recovery(host);
+ if (err)
+ mmc_blk_reset(mq->blkdata, host, MMC_BLK_CQE_RECOVERY);
+ else
+ mmc_blk_reset_success(mq->blkdata, MMC_BLK_CQE_RECOVERY);
+
+ pr_debug("%s: CQE recovery done\n", mmc_hostname(host));
+}
+
+static void mmc_blk_cqe_req_done(struct mmc_request *mrq)
+{
+ struct mmc_queue_req *mqrq = container_of(mrq, struct mmc_queue_req,
+ brq.mrq);
+ struct request *req = mmc_queue_req_to_req(mqrq);
+ struct request_queue *q = req->q;
+ struct mmc_queue *mq = q->queuedata;
+
+ /*
+ * Block layer timeouts race with completions which means the normal
+ * completion path cannot be used during recovery.
+ */
+ if (mq->in_recovery)
+ mmc_blk_cqe_complete_rq(mq, req);
+ else
+ blk_mq_complete_request(req);
+}
+
+static int mmc_blk_cqe_start_req(struct mmc_host *host, struct mmc_request *mrq)
+{
+ mrq->done = mmc_blk_cqe_req_done;
+ mrq->recovery_notifier = mmc_cqe_recovery_notifier;
+
+ return mmc_cqe_start_req(host, mrq);
+}
+
+static struct mmc_request *mmc_blk_cqe_prep_dcmd(struct mmc_queue_req *mqrq,
+ struct request *req)
+{
+ struct mmc_blk_request *brq = &mqrq->brq;
+
+ memset(brq, 0, sizeof(*brq));
+
+ brq->mrq.cmd = &brq->cmd;
+ brq->mrq.tag = req->tag;
+
+ return &brq->mrq;
+}
+
+static int mmc_blk_cqe_issue_flush(struct mmc_queue *mq, struct request *req)
+{
+ struct mmc_queue_req *mqrq = req_to_mmc_queue_req(req);
+ struct mmc_request *mrq = mmc_blk_cqe_prep_dcmd(mqrq, req);
+
+ mrq->cmd->opcode = MMC_SWITCH;
+ mrq->cmd->arg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) |
+ (EXT_CSD_FLUSH_CACHE << 16) |
+ (1 << 8) |
+ EXT_CSD_CMD_SET_NORMAL;
+ mrq->cmd->flags = MMC_CMD_AC | MMC_RSP_R1B;
+
+ return mmc_blk_cqe_start_req(mq->card->host, mrq);
+}
+
+static int mmc_blk_cqe_issue_rw_rq(struct mmc_queue *mq, struct request *req)
+{
+ struct mmc_queue_req *mqrq = req_to_mmc_queue_req(req);
+
+ mmc_blk_data_prep(mq, mqrq, 0, NULL, NULL);
+
+ return mmc_blk_cqe_start_req(mq->card->host, &mqrq->brq.mrq);
+}
+
static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq,
struct mmc_card *card,
int disable_multi,
@@ -1766,6 +1914,583 @@ static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq,
mqrq->areq.err_check = mmc_blk_err_check;
}
+#define MMC_MAX_RETRIES 5
+#define MMC_DATA_RETRIES 2
+#define MMC_NO_RETRIES (MMC_MAX_RETRIES + 1)
+
+/* Single sector read during recovery */
+static void mmc_blk_ss_read(struct mmc_queue *mq, struct request *req)
+{
+ struct mmc_queue_req *mqrq = req_to_mmc_queue_req(req);
+ blk_status_t status;
+
+ while (1) {
+ mmc_blk_rw_rq_prep(mqrq, mq->card, 1, mq);
+
+ mmc_wait_for_req(mq->card->host, &mqrq->brq.mrq);
+
+ /*
+ * Not expecting command errors, so just give up in that case.
+ * If there are retries remaining, the request will get
+ * requeued.
+ */
+ if (mqrq->brq.cmd.error)
+ return;
+
+ if (blk_rq_bytes(req) <= 512)
+ break;
+
+ status = mqrq->brq.data.error ? BLK_STS_IOERR : BLK_STS_OK;
+
+ blk_update_request(req, status, 512);
+ }
+
+ mqrq->retries = MMC_NO_RETRIES;
+}
+
+static inline bool mmc_blk_oor_valid(struct mmc_blk_request *brq)
+{
+ return !!brq->mrq.sbc;
+}
+
+static inline u32 mmc_blk_stop_err_bits(struct mmc_blk_request *brq)
+{
+ return mmc_blk_oor_valid(brq) ? CMD_ERRORS : CMD_ERRORS_EXCL_OOR;
+}
+
+static inline bool mmc_blk_in_tran_state(u32 status)
+{
+ /*
+ * Some cards mishandle the status bits, so make sure to check both the
+ * busy indication and the card state.
+ */
+ return status & R1_READY_FOR_DATA &&
+ (R1_CURRENT_STATE(status) == R1_STATE_TRAN);
+}
+
+/*
+ * Check for errors the host controller driver might not have seen such as
+ * response mode errors or invalid card state.
+ */
+static bool mmc_blk_status_error(struct request *req, u32 status)
+{
+ struct mmc_queue_req *mqrq = req_to_mmc_queue_req(req);
+ struct mmc_blk_request *brq = &mqrq->brq;
+ u32 stop_err_bits = mmc_blk_stop_err_bits(brq);
+
+ return brq->cmd.resp[0] & CMD_ERRORS ||
+ brq->stop.resp[0] & stop_err_bits ||
+ status & stop_err_bits ||
+ (rq_data_dir(req) == WRITE && !mmc_blk_in_tran_state(status));
+}
+
+static inline bool mmc_blk_cmd_started(struct mmc_blk_request *brq)
+{
+ return !brq->sbc.error && !brq->cmd.error &&
+ !(brq->cmd.resp[0] & CMD_ERRORS);
+}
+
+static unsigned int mmc_blk_clock_khz(struct mmc_host *host)
+{
+ if (host->actual_clock)
+ return host->actual_clock / 1000;
+
+ /* Clock may be subject to a divisor, fudge it by a factor of 2. */
+ if (host->ios.clock)
+ return host->ios.clock / 2000;
+
+ /* How can there be no clock */
+ WARN_ON_ONCE(1);
+ return 100; /* 100 kHz is minimum possible value */
+}
+
+static unsigned long mmc_blk_data_timeout_jiffies(struct mmc_host *host,
+ struct mmc_data *data)
+{
+ unsigned int ms = DIV_ROUND_UP(data->timeout_ns, 1000000);
+ unsigned int khz;
+
+ if (data->timeout_clks) {
+ khz = mmc_blk_clock_khz(host);
+ ms += DIV_ROUND_UP(data->timeout_clks, khz);
+ }
+
+ return msecs_to_jiffies(ms);
+}
+
+static int mmc_blk_card_stuck(struct mmc_card *card, struct request *req,
+ u32 *resp_errs)
+{
+ struct mmc_queue_req *mqrq = req_to_mmc_queue_req(req);
+ struct mmc_data *data = &mqrq->brq.data;
+ unsigned long timeout;
+ u32 status;
+ int err;
+
+ timeout = jiffies + mmc_blk_data_timeout_jiffies(card->host, data);
+
+ while (1) {
+ bool done = time_after(jiffies, timeout);
+
+ err = __mmc_send_status(card, &status, 5);
+ if (err) {
+ pr_err("%s: error %d requesting status\n",
+ req->rq_disk->disk_name, err);
+ break;
+ }
+
+ /* Accumulate any response error bits seen */
+ if (resp_errs)
+ *resp_errs |= status;
+
+ if (mmc_blk_in_tran_state(status))
+ break;
+
+ /* Timeout if the device never becomes ready */
+ if (done) {
+ pr_err("%s: Card stuck in wrong state! %s %s\n",
+ mmc_hostname(card->host),
+ req->rq_disk->disk_name, __func__);
+ err = -ETIMEDOUT;
+ break;
+ }
+ }
+
+ return err;
+}
+
+static int mmc_blk_send_stop(struct mmc_card *card)
+{
+ struct mmc_command cmd = {
+ .opcode = MMC_STOP_TRANSMISSION,
+ .flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC,
+ };
+
+ return mmc_wait_for_cmd(card->host, &cmd, 5);
+}
+
+static int mmc_blk_fix_state(struct mmc_card *card, struct request *req)
+{
+ int err;
+
+ mmc_retune_hold_now(card->host);
+
+ mmc_blk_send_stop(card);
+
+ err = mmc_blk_card_stuck(card, req, NULL);
+
+ mmc_retune_release(card->host);
+
+ return err;
+}
+
+static void mmc_blk_rw_recovery(struct mmc_queue *mq, struct request *req)
+{
+ int type = rq_data_dir(req) == READ ? MMC_BLK_READ : MMC_BLK_WRITE;
+ struct mmc_queue_req *mqrq = req_to_mmc_queue_req(req);
+ struct mmc_blk_request *brq = &mqrq->brq;
+ struct mmc_blk_data *md = mq->blkdata;
+ struct mmc_card *card = mq->card;
+ u32 status;
+ u32 blocks;
+ int err;
+
+ /*
+ * Status error bits might get lost during re-tuning so don't allow
+ * re-tuning yet.
+ */
+ mmc_retune_hold_now(card->host);
+
+ /*
+ * Some errors the host driver might not have seen. Set the number of
+ * bytes transferred to zero in that case.
+ */
+ err = __mmc_send_status(card, &status, 0);
+ if (err || mmc_blk_status_error(req, status))
+ brq->data.bytes_xfered = 0;
+
+ mmc_retune_release(card->host);
+
+ /*
+ * Try again to get the status. This also provides an opportunity for
+ * re-tuning.
+ */
+ if (err)
+ err = __mmc_send_status(card, &status, 0);
+
+ /*
+ * Nothing more to do after the number of bytes transferred has been
+ * updated and there is no card.
+ */
+ if (err && mmc_detect_card_removed(card->host))
+ return;
+
+ /* Try to get back to "tran" state */
+ if (err || !mmc_blk_in_tran_state(status))
+ err = mmc_blk_fix_state(mq->card, req);
+
+ /*
+ * Special case for SD cards where the card might record the number of
+ * blocks written.
+ */
+ if (!err && mmc_blk_cmd_started(brq) && mmc_card_sd(card) &&
+ rq_data_dir(req) == WRITE && !mmc_sd_num_wr_blocks(card, &blocks))
+ brq->data.bytes_xfered = blocks << 9;
+
+ /* Reset if the card is in a bad state */
+ if (err && mmc_blk_reset(md, card->host, type)) {
+ pr_err("%s: recovery failed!\n", req->rq_disk->disk_name);
+ mqrq->retries = MMC_NO_RETRIES;
+ return;
+ }
+
+ /*
+ * If anything was done, just return and if there is anything remaining
+ * on the request it will get requeued.
+ */
+ if (brq->data.bytes_xfered)
+ return;
+
+ /* Reset before last retry */
+ if (mqrq->retries + 1 == MMC_MAX_RETRIES)
+ mmc_blk_reset(md, card->host, type);
+
+ /* Command errors fail fast, so use all MMC_MAX_RETRIES */
+ if (brq->sbc.error || brq->cmd.error)
+ return;
+
+ /* Reduce the remaining retries for data errors */
+ if (mqrq->retries < MMC_MAX_RETRIES - MMC_DATA_RETRIES) {
+ mqrq->retries = MMC_MAX_RETRIES - MMC_DATA_RETRIES;
+ return;
+ }
+
+ /* FIXME: Missing single sector read for large sector size */
+ if (rq_data_dir(req) == READ && !mmc_large_sector(card)) {
+ /* Read one sector at a time */
+ mmc_blk_ss_read(mq, req);
+ return;
+ }
+}
+
+static inline bool mmc_blk_rq_error(struct mmc_blk_request *brq)
+{
+ mmc_blk_eval_resp_error(brq);
+
+ return brq->sbc.error || brq->cmd.error || brq->stop.error ||
+ brq->data.error || brq->cmd.resp[0] & CMD_ERRORS;
+}
+
+static int mmc_blk_card_busy(struct mmc_card *card, struct request *req)
+{
+ struct mmc_queue_req *mqrq = req_to_mmc_queue_req(req);
+ u32 status = 0;
+ int err;
+
+ if (mmc_host_is_spi(card->host) || rq_data_dir(req) == READ)
+ return 0;
+
+ mmc_retune_hold_now(card->host);
+
+ err = mmc_blk_card_stuck(card, req, &status);
+
+ mmc_retune_release(card->host);
+
+ /*
+ * Do not assume data transferred correctly if there are any error bits
+ * set.
+ */
+ if (!err && status & mmc_blk_stop_err_bits(&mqrq->brq)) {
+ mqrq->brq.data.bytes_xfered = 0;
+ err = -EIO;
+ }
+
+ /* Copy the exception bit so it will be seen later on */
+ if (mmc_card_mmc(card) && status & R1_EXCEPTION_EVENT)
+ mqrq->brq.cmd.resp[0] |= R1_EXCEPTION_EVENT;
+
+ return err;
+}
+
+static inline void mmc_blk_rw_reset_success(struct mmc_queue *mq,
+ struct request *req)
+{
+ int type = rq_data_dir(req) == READ ? MMC_BLK_READ : MMC_BLK_WRITE;
+
+ mmc_blk_reset_success(mq->blkdata, type);
+}
+
+static void mmc_blk_mq_complete_rq(struct mmc_queue *mq, struct request *req)
+{
+ struct mmc_queue_req *mqrq = req_to_mmc_queue_req(req);
+ unsigned int nr_bytes = mqrq->brq.data.bytes_xfered;
+
+ if (nr_bytes) {
+ if (blk_update_request(req, BLK_STS_OK, nr_bytes))
+ blk_mq_requeue_request(req, true);
+ else
+ __blk_mq_end_request(req, BLK_STS_OK);
+ } else if (mqrq->retries++ < MMC_MAX_RETRIES) {
+ blk_mq_requeue_request(req, true);
+ } else {
+ if (mmc_card_removed(mq->card))
+ req->rq_flags |= RQF_QUIET;
+ blk_mq_end_request(req, BLK_STS_IOERR);
+ }
+}
+
+static bool mmc_blk_urgent_bkops_needed(struct mmc_queue *mq,
+ struct mmc_queue_req *mqrq)
+{
+ return mmc_card_mmc(mq->card) &&
+ (mqrq->brq.cmd.resp[0] & R1_EXCEPTION_EVENT ||
+ mqrq->brq.stop.resp[0] & R1_EXCEPTION_EVENT);
+}
+
+static void mmc_blk_urgent_bkops(struct mmc_queue *mq,
+ struct mmc_queue_req *mqrq)
+{
+ if (mmc_blk_urgent_bkops_needed(mq, mqrq))
+ mmc_start_bkops(mq->card, true);
+}
+
+static int mmc_blk_card_busy_check(struct mmc_queue *mq, struct request *req)
+{
+ if (mmc_queue_rw_async(mq->card->host))
+ return 0;
+
+ return mmc_blk_card_busy(mq->card, req);
+}
+
+void mmc_blk_mq_complete(struct request *req)
+{
+ struct mmc_queue *mq = req->q->queuedata;
+
+ if (mq->use_cqe)
+ mmc_blk_cqe_complete_rq(mq, req);
+ else
+ mmc_blk_mq_complete_rq(mq, req);
+}
+
+static void mmc_blk_finish_rw_rq_blocking(struct mmc_queue *mq,
+ struct request *req)
+{
+ struct mmc_queue_req *mqrq = req_to_mmc_queue_req(req);
+
+ if (mmc_blk_rq_error(&mqrq->brq) || mmc_blk_card_busy_check(mq, req))
+ mmc_blk_rw_recovery(mq, req);
+ else
+ mmc_blk_rw_reset_success(mq, req);
+
+ mmc_blk_urgent_bkops(mq, mqrq);
+
+ mq->rw_wait = false;
+
+ /*
+ * Block layer timeouts race with completions which means the normal
+ * completion path cannot be used during recovery.
+ */
+ if (mq->in_recovery)
+ mmc_blk_mq_complete_rq(mq, req);
+ else
+ blk_mq_complete_request(req);
+}
+
+void mmc_blk_mq_recovery(struct mmc_queue *mq)
+{
+ struct request *req = mq->recovery_req;
+
+ mq->recovery_req = NULL;
+
+ mmc_blk_finish_rw_rq_blocking(mq, req);
+}
+
+static void mmc_blk_issue_rw_rq_blocking(struct mmc_queue *mq,
+ struct request *req)
+{
+ struct mmc_queue_req *mqrq = req_to_mmc_queue_req(req);
+
+ mmc_blk_rw_rq_prep(mqrq, mq->card, 0, mq);
+
+ mmc_wait_for_req(mq->card->host, &mqrq->brq.mrq);
+
+ mmc_blk_finish_rw_rq_blocking(mq, req);
+}
+
+static void mmc_blk_mq_req_done(struct mmc_request *mrq)
+{
+ struct mmc_queue_req *mqrq = container_of(mrq, struct mmc_queue_req,
+ brq.mrq);
+ struct request *req = mmc_queue_req_to_req(mqrq);
+ struct request_queue *q = req->q;
+ struct mmc_queue *mq = q->queuedata;
+ struct mmc_host *host = mq->card->host;
+ unsigned long flags;
+ bool put_card;
+
+ if (mmc_blk_rq_error(&mqrq->brq) ||
+ mmc_blk_urgent_bkops_needed(mq, mqrq)) {
+ if (host->ops->post_req)
+ host->ops->post_req(host, mrq, 0);
+ mq->recovery_needed = true;
+ mq->recovery_req = req;
+ wake_up(&mq->wait);
+ schedule_work(&mq->recovery_work);
+ return;
+ }
+
+ mmc_blk_rw_reset_success(mq, req);
+
+ mq->rw_wait = false;
+ wake_up(&mq->wait);
+
+ if (host->ops->post_req)
+ host->ops->post_req(host, mrq, 0);
+
+ blk_mq_complete_request(req);
+
+ spin_lock_irqsave(q->queue_lock, flags);
+
+ mq->in_flight[mmc_issue_type(mq, req)] -= 1;
+
+ put_card = mmc_tot_in_flight(mq) == 0;
+
+ spin_unlock_irqrestore(q->queue_lock, flags);
+
+ if (put_card)
+ mmc_put_card(mq->card, &mq->ctx);
+}
+
+static bool mmc_blk_rw_wait_cond(struct mmc_queue *mq, int *err)
+{
+ if (mq->recovery_needed) {
+ *err = -EBUSY;
+ return true;
+ }
+
+ return !mq->rw_wait;
+}
+
+static int mmc_blk_rw_wait(struct mmc_queue *mq)
+{
+ int err = 0;
+
+ wait_event(mq->wait, mmc_blk_rw_wait_cond(mq, &err));
+
+ return err;
+}
+
+static int mmc_blk_mq_issue_rw_rq(struct mmc_queue *mq,
+ struct request *req)
+{
+ struct mmc_queue_req *mqrq = req_to_mmc_queue_req(req);
+ struct mmc_host *host = mq->card->host;
+ int err = 0;
+
+ mmc_blk_rw_rq_prep(mqrq, mq->card, 0, mq);
+
+ mqrq->brq.mrq.done = mmc_blk_mq_req_done;
+
+ if (host->ops->pre_req)
+ host->ops->pre_req(host, &mqrq->brq.mrq);
+
+ err = mmc_blk_rw_wait(mq);
+ if (err)
+ goto out_post_req;
+
+ mq->rw_wait = true;
+
+ err = mmc_start_request(host, &mqrq->brq.mrq);
+
+ if (err)
+ mq->rw_wait = false;
+
+ /* Release re-tuning here where there is no synchronization required */
+ mmc_retune_release(host);
+
+out_post_req:
+ if (err && host->ops->post_req)
+ host->ops->post_req(host, &mqrq->brq.mrq, err);
+
+ return err;
+}
+
+static int mmc_blk_wait_for_idle(struct mmc_queue *mq, struct mmc_host *host)
+{
+ if (mq->use_cqe)
+ return host->cqe_ops->cqe_wait_for_idle(host);
+
+ if (mmc_queue_rw_async(host))
+ return mmc_blk_rw_wait(mq);
+
+ return 0;
+}
+
+enum mmc_issued mmc_blk_mq_issue_rq(struct mmc_queue *mq, struct request *req)
+{
+ struct mmc_blk_data *md = mq->blkdata;
+ struct mmc_card *card = md->queue.card;
+ struct mmc_host *host = card->host;
+ int ret;
+
+ ret = mmc_blk_part_switch(card, md->part_type);
+ if (ret)
+ return MMC_REQ_FAILED_TO_START;
+
+ switch (mmc_issue_type(mq, req)) {
+ case MMC_ISSUE_SYNC:
+ ret = mmc_blk_wait_for_idle(mq, host);
+ if (ret)
+ return MMC_REQ_BUSY;
+ switch (req_op(req)) {
+ case REQ_OP_DRV_IN:
+ case REQ_OP_DRV_OUT:
+ mmc_blk_issue_drv_op(mq, req);
+ break;
+ case REQ_OP_DISCARD:
+ mmc_blk_issue_discard_rq(mq, req);
+ break;
+ case REQ_OP_SECURE_ERASE:
+ mmc_blk_issue_secdiscard_rq(mq, req);
+ break;
+ case REQ_OP_FLUSH:
+ mmc_blk_issue_flush(mq, req);
+ break;
+ case REQ_OP_READ:
+ case REQ_OP_WRITE:
+ mmc_blk_issue_rw_rq_blocking(mq, req);
+ break;
+ default:
+ WARN_ON_ONCE(1);
+ return MMC_REQ_FAILED_TO_START;
+ }
+ return MMC_REQ_FINISHED;
+ case MMC_ISSUE_DCMD:
+ case MMC_ISSUE_ASYNC:
+ switch (req_op(req)) {
+ case REQ_OP_FLUSH:
+ ret = mmc_blk_cqe_issue_flush(mq, req);
+ break;
+ case REQ_OP_READ:
+ case REQ_OP_WRITE:
+ if (mq->use_cqe)
+ ret = mmc_blk_cqe_issue_rw_rq(mq, req);
+ else
+ ret = mmc_blk_mq_issue_rw_rq(mq, req);
+ break;
+ default:
+ WARN_ON_ONCE(1);
+ ret = -EINVAL;
+ }
+ if (!ret)
+ return MMC_REQ_STARTED;
+ return ret == -EBUSY ? MMC_REQ_BUSY : MMC_REQ_FAILED_TO_START;
+ default:
+ WARN_ON_ONCE(1);
+ return MMC_REQ_FAILED_TO_START;
+ }
+}
+
static bool mmc_blk_rw_cmd_err(struct mmc_blk_data *md, struct mmc_card *card,
struct mmc_blk_request *brq, struct request *req,
bool old_req_pending)
diff --git a/drivers/mmc/core/block.h b/drivers/mmc/core/block.h
index 860ca7c8df86..742aa4d27cbf 100644
--- a/drivers/mmc/core/block.h
+++ b/drivers/mmc/core/block.h
@@ -6,4 +6,12 @@
void mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req);
+enum mmc_issued;
+
+void mmc_blk_cqe_recovery(struct mmc_queue *mq);
+
+enum mmc_issued mmc_blk_mq_issue_rq(struct mmc_queue *mq, struct request *req);
+void mmc_blk_mq_complete(struct request *req);
+void mmc_blk_mq_recovery(struct mmc_queue *mq);
+
#endif
diff --git a/drivers/mmc/core/queue.c b/drivers/mmc/core/queue.c
index 4f33d277b125..12f367278da2 100644
--- a/drivers/mmc/core/queue.c
+++ b/drivers/mmc/core/queue.c
@@ -22,6 +22,7 @@
#include "block.h"
#include "core.h"
#include "card.h"
+#include "host.h"
/*
* Prepare a MMC request. This just filters out odd stuff.
@@ -34,10 +35,153 @@ static int mmc_prep_request(struct request_queue *q, struct request *req)
return BLKPREP_KILL;
req->rq_flags |= RQF_DONTPREP;
+ req_to_mmc_queue_req(req)->retries = 0;
return BLKPREP_OK;
}
+static inline bool mmc_cqe_dcmd_busy(struct mmc_queue *mq)
+{
+ /* Allow only 1 DCMD at a time */
+ return mq->in_flight[MMC_ISSUE_DCMD];
+}
+
+void mmc_cqe_check_busy(struct mmc_queue *mq)
+{
+ if ((mq->cqe_busy & MMC_CQE_DCMD_BUSY) && !mmc_cqe_dcmd_busy(mq))
+ mq->cqe_busy &= ~MMC_CQE_DCMD_BUSY;
+
+ mq->cqe_busy &= ~MMC_CQE_QUEUE_FULL;
+}
+
+static inline bool mmc_cqe_can_dcmd(struct mmc_host *host)
+{
+ return host->caps2 & MMC_CAP2_CQE_DCMD;
+}
+
+enum mmc_issue_type mmc_cqe_issue_type(struct mmc_host *host,
+ struct request *req)
+{
+ switch (req_op(req)) {
+ case REQ_OP_DRV_IN:
+ case REQ_OP_DRV_OUT:
+ case REQ_OP_DISCARD:
+ case REQ_OP_SECURE_ERASE:
+ return MMC_ISSUE_SYNC;
+ case REQ_OP_FLUSH:
+ return mmc_cqe_can_dcmd(host) ? MMC_ISSUE_DCMD : MMC_ISSUE_SYNC;
+ default:
+ return MMC_ISSUE_ASYNC;
+ }
+}
+
+enum mmc_issue_type mmc_issue_type(struct mmc_queue *mq, struct request *req)
+{
+ struct mmc_host *host = mq->card->host;
+
+ if (mq->use_cqe)
+ return mmc_cqe_issue_type(host, req);
+
+ if (mmc_queue_rw_async(host) &&
+ (req_op(req) == REQ_OP_READ || req_op(req) == REQ_OP_WRITE))
+ return MMC_ISSUE_ASYNC;
+
+ return MMC_ISSUE_SYNC;
+}
+
+static void __mmc_cqe_recovery_notifier(struct mmc_queue *mq)
+{
+ if (!mq->recovery_needed) {
+ mq->recovery_needed = true;
+ schedule_work(&mq->recovery_work);
+ }
+}
+
+void mmc_cqe_recovery_notifier(struct mmc_request *mrq)
+{
+ struct mmc_queue_req *mqrq = container_of(mrq, struct mmc_queue_req,
+ brq.mrq);
+ struct request *req = mmc_queue_req_to_req(mqrq);
+ struct request_queue *q = req->q;
+ struct mmc_queue *mq = q->queuedata;
+ unsigned long flags;
+
+ spin_lock_irqsave(q->queue_lock, flags);
+ __mmc_cqe_recovery_notifier(mq);
+ spin_unlock_irqrestore(q->queue_lock, flags);
+}
+
+static enum blk_eh_timer_return mmc_cqe_timed_out(struct request *req)
+{
+ struct mmc_queue_req *mqrq = req_to_mmc_queue_req(req);
+ struct mmc_request *mrq = &mqrq->brq.mrq;
+ struct mmc_queue *mq = req->q->queuedata;
+ struct mmc_host *host = mq->card->host;
+ enum mmc_issue_type issue_type = mmc_issue_type(mq, req);
+ bool recovery_needed = false;
+
+ switch (issue_type) {
+ case MMC_ISSUE_ASYNC:
+ case MMC_ISSUE_DCMD:
+ if (host->cqe_ops->cqe_timeout(host, mrq, &recovery_needed)) {
+ if (recovery_needed)
+ __mmc_cqe_recovery_notifier(mq);
+ return BLK_EH_RESET_TIMER;
+ }
+ /* No timeout */
+ return BLK_EH_HANDLED;
+ default:
+ /* Timeout is handled by mmc core */
+ return BLK_EH_RESET_TIMER;
+ }
+}
+
+static enum blk_eh_timer_return mmc_mq_timed_out(struct request *req,
+ bool reserved)
+{
+ struct request_queue *q = req->q;
+ struct mmc_queue *mq = q->queuedata;
+ unsigned long flags;
+ int ret;
+
+ spin_lock_irqsave(q->queue_lock, flags);
+
+ if (mq->recovery_needed || !mq->use_cqe)
+ ret = BLK_EH_RESET_TIMER;
+ else
+ ret = mmc_cqe_timed_out(req);
+
+ spin_unlock_irqrestore(q->queue_lock, flags);
+
+ return ret;
+}
+
+static void mmc_mq_recovery_handler(struct work_struct *work)
+{
+ struct mmc_queue *mq = container_of(work, struct mmc_queue,
+ recovery_work);
+ struct request_queue *q = mq->queue;
+
+ mmc_get_card(mq->card, &mq->ctx);
+
+ mq->in_recovery = true;
+
+ if (mq->use_cqe)
+ mmc_blk_cqe_recovery(mq);
+ else
+ mmc_blk_mq_recovery(mq);
+
+ mq->in_recovery = false;
+
+ spin_lock_irq(q->queue_lock);
+ mq->recovery_needed = false;
+ spin_unlock_irq(q->queue_lock);
+
+ mmc_put_card(mq->card, &mq->ctx);
+
+ blk_mq_run_hw_queues(q, true);
+}
+
static int mmc_queue_thread(void *d)
{
struct mmc_queue *mq = d;
@@ -154,11 +298,10 @@ static void mmc_queue_setup_discard(struct request_queue *q,
* @req: the request
* @gfp: memory allocation policy
*/
-static int mmc_init_request(struct request_queue *q, struct request *req,
- gfp_t gfp)
+static int __mmc_init_request(struct mmc_queue *mq, struct request *req,
+ gfp_t gfp)
{
struct mmc_queue_req *mq_rq = req_to_mmc_queue_req(req);
- struct mmc_queue *mq = q->queuedata;
struct mmc_card *card = mq->card;
struct mmc_host *host = card->host;
@@ -169,6 +312,12 @@ static int mmc_init_request(struct request_queue *q, struct request *req,
return 0;
}
+static int mmc_init_request(struct request_queue *q, struct request *req,
+ gfp_t gfp)
+{
+ return __mmc_init_request(q->queuedata, req, gfp);
+}
+
static void mmc_exit_request(struct request_queue *q, struct request *req)
{
struct mmc_queue_req *mq_rq = req_to_mmc_queue_req(req);
@@ -177,6 +326,124 @@ static void mmc_exit_request(struct request_queue *q, struct request *req)
mq_rq->sg = NULL;
}
+static int mmc_mq_init_request(struct blk_mq_tag_set *set, struct request *req,
+ unsigned int hctx_idx, unsigned int numa_node)
+{
+ return __mmc_init_request(set->driver_data, req, GFP_KERNEL);
+}
+
+static void mmc_mq_exit_request(struct blk_mq_tag_set *set, struct request *req,
+ unsigned int hctx_idx)
+{
+ struct mmc_queue *mq = set->driver_data;
+
+ mmc_exit_request(mq->queue, req);
+}
+
+static blk_status_t mmc_mq_queue_rq(struct blk_mq_hw_ctx *hctx,
+ const struct blk_mq_queue_data *bd)
+{
+ struct request *req = bd->rq;
+ struct request_queue *q = req->q;
+ struct mmc_queue *mq = q->queuedata;
+ struct mmc_card *card = mq->card;
+ struct mmc_host *host = card->host;
+ enum mmc_issue_type issue_type;
+ enum mmc_issued issued;
+ bool get_card, cqe_retune_ok;
+ int ret;
+
+ if (mmc_card_removed(mq->card)) {
+ req->rq_flags |= RQF_QUIET;
+ return BLK_STS_IOERR;
+ }
+
+ issue_type = mmc_issue_type(mq, req);
+
+ spin_lock_irq(q->queue_lock);
+
+ if (mq->recovery_needed) {
+ spin_unlock_irq(q->queue_lock);
+ return BLK_STS_RESOURCE;
+ }
+
+ switch (issue_type) {
+ case MMC_ISSUE_DCMD:
+ if (mmc_cqe_dcmd_busy(mq)) {
+ mq->cqe_busy |= MMC_CQE_DCMD_BUSY;
+ spin_unlock_irq(q->queue_lock);
+ return BLK_STS_RESOURCE;
+ }
+ break;
+ case MMC_ISSUE_ASYNC:
+ break;
+ default:
+ /*
+ * Timeouts are handled by mmc core, so set a large value to
+ * avoid races.
+ */
+ req->timeout = 600 * HZ;
+ break;
+ }
+
+ mq->in_flight[issue_type] += 1;
+ get_card = mmc_tot_in_flight(mq) == 1;
+ cqe_retune_ok = mmc_cqe_qcnt(mq) == 1;
+
+ spin_unlock_irq(q->queue_lock);
+
+ if (!(req->rq_flags & RQF_DONTPREP)) {
+ req_to_mmc_queue_req(req)->retries = 0;
+ req->rq_flags |= RQF_DONTPREP;
+ }
+
+ if (get_card)
+ mmc_get_card(card, &mq->ctx);
+
+ if (mq->use_cqe) {
+ host->retune_now = host->need_retune && cqe_retune_ok &&
+ !host->hold_retune;
+ }
+
+ blk_mq_start_request(req);
+
+ issued = mmc_blk_mq_issue_rq(mq, req);
+
+ switch (issued) {
+ case MMC_REQ_BUSY:
+ ret = BLK_STS_RESOURCE;
+ break;
+ case MMC_REQ_FAILED_TO_START:
+ ret = BLK_STS_IOERR;
+ break;
+ default:
+ ret = BLK_STS_OK;
+ break;
+ }
+
+ if (issued != MMC_REQ_STARTED) {
+ bool put_card = false;
+
+ spin_lock_irq(q->queue_lock);
+ mq->in_flight[issue_type] -= 1;
+ if (mmc_tot_in_flight(mq) == 0)
+ put_card = true;
+ spin_unlock_irq(q->queue_lock);
+ if (put_card)
+ mmc_put_card(card, &mq->ctx);
+ }
+
+ return ret;
+}
+
+static const struct blk_mq_ops mmc_mq_cqe_ops = {
+ .queue_rq = mmc_mq_queue_rq,
+ .init_request = mmc_mq_init_request,
+ .exit_request = mmc_mq_exit_request,
+ .complete = mmc_blk_mq_complete,
+ .timeout = mmc_mq_timed_out,
+};
+
static void mmc_setup_queue(struct mmc_queue *mq, struct mmc_card *card)
{
struct mmc_host *host = card->host;
@@ -198,6 +465,72 @@ static void mmc_setup_queue(struct mmc_queue *mq, struct mmc_card *card)
/* Initialize thread_sem even if it is not used */
sema_init(&mq->thread_sem, 1);
+
+ /* Initialize recovery_work even if it is not used */
+ INIT_WORK(&mq->recovery_work, mmc_mq_recovery_handler);
+
+ init_waitqueue_head(&mq->wait);
+}
+
+static int mmc_mq_init_queue(struct mmc_queue *mq, int q_depth,
+ const struct blk_mq_ops *mq_ops, spinlock_t *lock)
+{
+ int ret;
+
+ memset(&mq->tag_set, 0, sizeof(mq->tag_set));
+ mq->tag_set.ops = mq_ops;
+ mq->tag_set.queue_depth = q_depth;
+ mq->tag_set.numa_node = NUMA_NO_NODE;
+ mq->tag_set.flags = BLK_MQ_F_SHOULD_MERGE | BLK_MQ_F_SG_MERGE |
+ BLK_MQ_F_BLOCKING;
+ mq->tag_set.nr_hw_queues = 1;
+ mq->tag_set.cmd_size = sizeof(struct mmc_queue_req);
+ mq->tag_set.driver_data = mq;
+
+ ret = blk_mq_alloc_tag_set(&mq->tag_set);
+ if (ret)
+ return ret;
+
+ mq->queue = blk_mq_init_queue(&mq->tag_set);
+ if (IS_ERR(mq->queue)) {
+ ret = PTR_ERR(mq->queue);
+ goto free_tag_set;
+ }
+
+ mq->queue->queue_lock = lock;
+ mq->queue->queuedata = mq;
+
+ return 0;
+
+free_tag_set:
+ blk_mq_free_tag_set(&mq->tag_set);
+
+ return ret;
+}
+
+#define MMC_QUEUE_DEPTH 64
+
+static int mmc_mq_init(struct mmc_queue *mq, struct mmc_card *card,
+ spinlock_t *lock)
+{
+ struct mmc_host *host = card->host;
+ int q_depth;
+ int ret;
+
+ if (mq->use_cqe)
+ q_depth = min_t(int, card->ext_csd.cmdq_depth, host->cqe_qdepth);
+ else
+ q_depth = MMC_QUEUE_DEPTH;
+
+ ret = mmc_mq_init_queue(mq, q_depth, &mmc_mq_cqe_ops, lock);
+ if (ret)
+ return ret;
+
+ blk_queue_rq_timeout(mq->queue, 60 * HZ);
+
+ mmc_setup_queue(mq, card);
+
+ return 0;
}
/**
@@ -216,6 +549,12 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card,
int ret = -ENOMEM;
mq->card = card;
+
+ mq->use_cqe = host->cqe_enabled;
+
+ if (mq->use_cqe || mmc_host_use_blk_mq(host))
+ return mmc_mq_init(mq, card, lock);
+
mq->queue = blk_alloc_queue(GFP_KERNEL);
if (!mq->queue)
return -ENOMEM;
@@ -251,11 +590,63 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card,
return ret;
}
+static void mmc_mq_queue_suspend(struct mmc_queue *mq)
+{
+ blk_mq_quiesce_queue(mq->queue);
+
+ /*
+ * The host remains claimed while there are outstanding requests, so
+ * simply claiming and releasing here ensures there are none.
+ */
+ mmc_claim_host(mq->card->host);
+ mmc_release_host(mq->card->host);
+}
+
+static void mmc_mq_queue_resume(struct mmc_queue *mq)
+{
+ blk_mq_unquiesce_queue(mq->queue);
+}
+
+static void __mmc_queue_suspend(struct mmc_queue *mq)
+{
+ struct request_queue *q = mq->queue;
+ unsigned long flags;
+
+ if (!mq->suspended) {
+ mq->suspended |= true;
+
+ spin_lock_irqsave(q->queue_lock, flags);
+ blk_stop_queue(q);
+ spin_unlock_irqrestore(q->queue_lock, flags);
+
+ down(&mq->thread_sem);
+ }
+}
+
+static void __mmc_queue_resume(struct mmc_queue *mq)
+{
+ struct request_queue *q = mq->queue;
+ unsigned long flags;
+
+ if (mq->suspended) {
+ mq->suspended = false;
+
+ up(&mq->thread_sem);
+
+ spin_lock_irqsave(q->queue_lock, flags);
+ blk_start_queue(q);
+ spin_unlock_irqrestore(q->queue_lock, flags);
+ }
+}
+
void mmc_cleanup_queue(struct mmc_queue *mq)
{
struct request_queue *q = mq->queue;
unsigned long flags;
+ if (q->mq_ops)
+ return;
+
/* Make sure the queue isn't suspended, as that will deadlock */
mmc_queue_resume(mq);
@@ -283,17 +674,11 @@ void mmc_cleanup_queue(struct mmc_queue *mq)
void mmc_queue_suspend(struct mmc_queue *mq)
{
struct request_queue *q = mq->queue;
- unsigned long flags;
-
- if (!mq->suspended) {
- mq->suspended |= true;
-
- spin_lock_irqsave(q->queue_lock, flags);
- blk_stop_queue(q);
- spin_unlock_irqrestore(q->queue_lock, flags);
- down(&mq->thread_sem);
- }
+ if (q->mq_ops)
+ mmc_mq_queue_suspend(mq);
+ else
+ __mmc_queue_suspend(mq);
}
/**
@@ -303,17 +688,11 @@ void mmc_queue_suspend(struct mmc_queue *mq)
void mmc_queue_resume(struct mmc_queue *mq)
{
struct request_queue *q = mq->queue;
- unsigned long flags;
-
- if (mq->suspended) {
- mq->suspended = false;
- up(&mq->thread_sem);
-
- spin_lock_irqsave(q->queue_lock, flags);
- blk_start_queue(q);
- spin_unlock_irqrestore(q->queue_lock, flags);
- }
+ if (q->mq_ops)
+ mmc_mq_queue_resume(mq);
+ else
+ __mmc_queue_resume(mq);
}
/*
diff --git a/drivers/mmc/core/queue.h b/drivers/mmc/core/queue.h
index 68f68ecd94ea..dfd2cbb7e96c 100644
--- a/drivers/mmc/core/queue.h
+++ b/drivers/mmc/core/queue.h
@@ -7,6 +7,20 @@
#include <linux/mmc/core.h>
#include <linux/mmc/host.h>
+enum mmc_issued {
+ MMC_REQ_STARTED,
+ MMC_REQ_BUSY,
+ MMC_REQ_FAILED_TO_START,
+ MMC_REQ_FINISHED,
+};
+
+enum mmc_issue_type {
+ MMC_ISSUE_SYNC,
+ MMC_ISSUE_DCMD,
+ MMC_ISSUE_ASYNC,
+ MMC_ISSUE_MAX,
+};
+
static inline struct mmc_queue_req *req_to_mmc_queue_req(struct request *rq)
{
return blk_mq_rq_to_pdu(rq);
@@ -56,12 +70,15 @@ struct mmc_queue_req {
int drv_op_result;
void *drv_op_data;
unsigned int ioc_count;
+ int retries;
};
struct mmc_queue {
struct mmc_card *card;
struct task_struct *thread;
struct semaphore thread_sem;
+ struct mmc_ctx ctx;
+ struct blk_mq_tag_set tag_set;
bool suspended;
bool asleep;
struct mmc_blk_data *blkdata;
@@ -73,6 +90,18 @@ struct mmc_queue {
* associated mmc_queue_req data.
*/
int qcnt;
+
+ int in_flight[MMC_ISSUE_MAX];
+ unsigned int cqe_busy;
+#define MMC_CQE_DCMD_BUSY BIT(0)
+#define MMC_CQE_QUEUE_FULL BIT(1)
+ bool use_cqe;
+ bool recovery_needed;
+ bool in_recovery;
+ bool rw_wait;
+ struct work_struct recovery_work;
+ wait_queue_head_t wait;
+ struct request *recovery_req;
};
extern int mmc_init_queue(struct mmc_queue *, struct mmc_card *, spinlock_t *,
@@ -83,4 +112,27 @@ extern int mmc_init_queue(struct mmc_queue *, struct mmc_card *, spinlock_t *,
extern unsigned int mmc_queue_map_sg(struct mmc_queue *,
struct mmc_queue_req *);
+void mmc_cqe_check_busy(struct mmc_queue *mq);
+void mmc_cqe_recovery_notifier(struct mmc_request *mrq);
+
+enum mmc_issue_type mmc_issue_type(struct mmc_queue *mq, struct request *req);
+
+static inline int mmc_tot_in_flight(struct mmc_queue *mq)
+{
+ return mq->in_flight[MMC_ISSUE_SYNC] +
+ mq->in_flight[MMC_ISSUE_DCMD] +
+ mq->in_flight[MMC_ISSUE_ASYNC];
+}
+
+static inline int mmc_cqe_qcnt(struct mmc_queue *mq)
+{
+ return mq->in_flight[MMC_ISSUE_DCMD] +
+ mq->in_flight[MMC_ISSUE_ASYNC];
+}
+
+static inline bool mmc_queue_rw_async(struct mmc_host *host)
+{
+ return host->caps & MMC_CAP_WAIT_WHILE_BUSY;
+}
+
#endif
--
1.9.1
^ permalink raw reply related
* Re: [PATCH] arm64: dts: renesas: salvator-common: add pfc node for USB3.0 channel 0
From: Simon Horman @ 2017-10-05 9:06 UTC (permalink / raw)
To: Geert Uytterhoeven
Cc: Yoshihiro Shimoda, Magnus Damm, Rob Herring, Mark Rutland,
devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Linux-Renesas
In-Reply-To: <CAMuHMdUz78BmySULe_wizFEhFAtiBiQLZ9Ov++S94+yb4YpxDg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
On Wed, Oct 04, 2017 at 03:53:36PM +0200, Geert Uytterhoeven wrote:
> On Tue, Oct 3, 2017 at 10:01 AM, Yoshihiro Shimoda
> <yoshihiro.shimoda.uh-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org> wrote:
> > Since a R-Car Gen3 bootloader enables the PFC of USB3.0 channel 0,
> > the USB3.0 host controller works without this setting on the kernel.
> > But, this setting should have salvator-common.dtsi. So, this patch
> > adds the pfc node for USB3.0 channel 0.
> >
> > Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh-zM6kxYcvzFBBDgjK7y7TUQ@public.gmane.org>
>
> Reviewed-by: Geert Uytterhoeven <geert+renesas-gXvu3+zWzMSzQB+pC5nmwQ@public.gmane.org>
Thanks, applied.
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH v2 07/13] fuzz/x86_emulate: Add 'afl-cov' target
From: Jan Beulich @ 2017-10-05 9:06 UTC (permalink / raw)
To: George Dunlap; +Cc: Andrew Cooper, Wei Liu, xen-devel, Ian Jackson
In-Reply-To: <dee9dc34-8fe1-c986-f1dd-099a12cb3017@citrix.com>
>>> On 04.10.17 at 18:48, <george.dunlap@citrix.com> wrote:
> On 10/04/2017 09:23 AM, Jan Beulich wrote:
>>>>> On 25.09.17 at 16:26, <george.dunlap@citrix.com> wrote:
>>> x86.h := asm/x86-vendors.h asm/x86-defns.h asm/msr-index.h
>>> x86_emulate.h := x86_emulate_user.h x86_emulate/x86_emulate.h $(x86.h)
>>>
>>> -x86_emulate_user.o: x86_emulate_user.c x86_emulate/x86_emulate.c $(x86_emulate.h)
>>> +X86_EMULATE_INPUTS = x86_emulate_user.c x86_emulate/x86_emulate.c $(x86_emulate.h)
>>> +x86_emulate_user.o: $(X86_EMULATE_INPUTS)
>>> +
>>> +x86_emulate_user-cov.o: $(X86_EMULATE_INPUTS)
>>> + $(CC) -c $(CFLAGS) $(GCOV_FLAGS) -o $@ x86_emulate_user.c
>>>
>>> fuzz-emul.o: $(x86_emulate.h)
>>>
>>> +fuzz-emul-cov.o: fuzz-emul.c $(x86_emulate.h)
>>> + $(CC) -c $(CFLAGS) $(GCOV_FLAGS) -o $@ fuzz-emul.c
>>> +
>>> +afl-harness-cov.o: afl-harness.c
>>> + $(CC) -c $(CFLAGS) $(GCOV_FLAGS) $^ -o $@
>>
>> Rather than effectively repeating this command three time, I think
>> someone else had already suggested to use a pattern rule instead.
>
> What do you mean "three times"? There's only one *-cov.o file which
> can possibly be created by a generic rule, and that's this one. (The
> others all have special formulas already.) Is it really worth making a
> generic rule for a single instance?
All three rules could be changed to use $< afaict, and then they're
all identical.
>>> @@ -46,7 +61,7 @@ distclean: clean
>>>
>>> .PHONY: clean
>>> clean:
>>> - rm -f *.a *.o .*.d afl-harness
>>> + rm -f *.a *.o .*.d afl-harness afl-harness-cov *.gcda *.gcno *.gcov
>>
>> Perhaps simply *.gc* to cover for possible future generated file types?
>
> If I knew that this wouldn't match files like "foo.gcov-notes.txt" I'd
> be fine with it. I'll change it if you insist but I think it's probably
> better the way it is for now.
Okay, same matter of taste as in the earlier patch. I.e. no, I
won't insist.
Jan
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel
^ permalink raw reply
* [U-Boot] [PATCH] disk: part_dos: Use the original allocation scheme for the SPL case
From: Rob Clark @ 2017-10-05 9:05 UTC (permalink / raw)
To: u-boot
In-Reply-To: <20171005043646.GB8685@largo.jsg.id.au>
On Thu, Oct 5, 2017 at 12:36 AM, Jonathan Gray <jsg@jsg.id.au> wrote:
> On Wed, Oct 04, 2017 at 01:12:48PM -0400, Rob Clark wrote:
>> On Wed, Oct 4, 2017 at 12:29 PM, Fabio Estevam <fabio.estevam@nxp.com> wrote:
>> > Since commit ff98cb90514d ("part: extract MBR signature from partitions")
>> > SPL boot on i.MX6 starts to fail:
>> >
>> > U-Boot SPL 2017.09-00221-g0d6ab32 (Oct 02 2017 - 15:13:19)
>> > Trying to boot from MMC1
>> > (keep in loop)
>> >
>> > Use the original allocation scheme for the SPL case, so that MX6 boards
>> > can boot again.
>> >
>> > This is a temporary solution to avoid the boot regression.
>> >
>> > Signed-off-by: Fabio Estevam <fabio.estevam@nxp.com>
>> > ---
>> > Hi Tom,
>> >
>> > I do not have time this week to further investigate and narrow down
>> > this problem.
>> >
>> > Using the old allocation scheme fixes the mx6 SPL boot problem.
>> >
>>
>> Hi Tom, if you are ok with this as a temporary fix, then this is:
>>
>> Acked-by: Rob Clark <robdclark@gmail.com>
>>
>> I'm getting some help from some of the fedora-arm folks so hopefully I
>> can get some idea what is going wrong, but I'd like to unblock folks
>> w/ mx6 boards..
>>
>> BR,
>> -R
>
> This does not seem to be a complete fix, cubox is still broken when
> U-Boot proper loads, unless the efi loader commits are to blame
> for introducing unaligned accesses.
>
> Works with 2017.09.
>
> U-Boot SPL 2017.11-rc1-00026-g14b55fc833 (Oct 05 2017 - 15:17:47)
> Trying to boot from MMC1
>
>
> U-Boot 2017.11-rc1-00026-g14b55fc833 (Oct 05 2017 - 15:17:47 +1100)
>
> CPU: Freescale i.MX6Q rev1.5 996 MHz (running at 792 MHz)
> CPU: Extended Commercial temperature grade (-20C to 105C) at 34C
> Reset cause: WDOG
> Board: MX6 Cubox-i
> DRAM: 2 GiB
> MMC: FSL_SDHC: 0
> *** Warning - bad CRC, using default environment
>
> No panel detected: default to HDMI
> Display: HDMI (1024x768)
> In: serial
> Out: serial
> Err: serial
> Net: FEC
> Hit any key to stop autoboot: 0
> switch to partitions #0, OK
> mmc0 is current device
> Scanning mmc 0:1...
I don't think any efi_loader code is running here, you would see a message like:
## Starting EFI application at XYZ
But to be sure you can disable CONFIG_EFI_LOADER in menuconfig to confirm.
I guess this is some unrelated change. I suspect Tom's change to
malloc the fat_itr's which would make the buffers used for
fs_exists()/etc not cache aligned. I thought there was a patch
floating around to change that to memalign().
BR,
-R
> CACHE: Misaligned operation at range [8f89da30, 8f89e230]
> CACHE: Misaligned operation at range [8f89da30, 8f89e230]
> ERROR: v7_outer_cache_inval_range - start address is not aligned - 0x8f89da30
> ERROR: v7_outer_cache_inval_range - stop address is not aligned - 0x8f89e230
> CACHE: Misaligned operation at range [8f89da30, 8f89e230]
> CACHE: Misaligned operation at range [8f89da30, 8f89e230]
> ERROR: v7_outer_cache_inval_range - start address is not aligned - 0x8f89da30
> ERROR: v7_outer_cache_inval_range - stop address is not aligned - 0x8f89e230
> CACHE: Misaligned operation at range [8f89dca0, 8f89e4a0]
> CACHE: Misaligned operation at range [8f89dca0, 8f89e4a0]
> CACHE: Misaligned operation at range [8f89dca0, 8f89e4a0]
> CACHE: Misaligned operation at range [8f89dca0, 8f89e4a0]
> CACHE: Misaligned operation at range [8f89dc68, 8f89e468]
> CACHE: Misaligned operation at range [8f89dc68, 8f89e468]
> ERROR: v7_outer_cache_inval_range - start address is not aligned - 0x8f89dc68
> ERROR: v7_outer_cache_inval_range - stop address is not aligned - 0x8f89e468
> CACHE: Misaligned operation at range [8f89dc68, 8f89e468]
> CACHE: Misaligned operation at range [8f89dc68, 8f89e468]
> ERROR: v7_outer_cache_inval_range - start address is not aligned - 0x8f89dc68
> ERROR: v7_outer_cache_inval_range - stop address is not aligned - 0x8f89e468
> CACHE: Misaligned operation at range [8f89dab0, 8f89e2b0]
> CACHE: Misaligned operation at range [8f89dab0, 8f89e2b0]
> ERROR: v7_outer_cache_inval_range - start address is not aligned - 0x8f89dab0
> ERROR: v7_outer_cache_inval_range - stop address is not aligned - 0x8f89e2b0
> CACHE: Misaligned operation at range [8f89dab0, 8f89e2b0]
> CACHE: Misaligned operation at range [8f89dab0, 8f89e2b0]
> ERROR: v7_outer_cache_inval_range - start address is not aligned - 0x8f89dab0
> ERROR: v7_outer_cache_inval_range - stop address is not aligned - 0x8f89e2b0
> CACHE: Misaligned operation at range [8f89dca8, 8f89e4a8]
> CACHE: Misaligned operation at range [8f89dca8, 8f89e4a8]
> ERROR: v7_outer_cache_inval_range - start address is not aligned - 0x8f89dca8
> ERROR: v7_outer_cache_inval_range - stop address is not aligned - 0x8f89e4a8
> CACHE: Misaligned operation at range [8f89dca8, 8f89e4a8]
> CACHE: Misaligned operation at range [8f89dca8, 8f89e4a8]
> ERROR: v7_outer_cache_inval_range - start address is not aligned - 0x8f89dca8
> ERROR: v7_outer_cache_inval_range - stop address is not aligned - 0x8f89e4a8
> CACHE: Misaligned operation at range [8f89dc70, 8f89e470]
> CACHE: Misaligned operation at range [8f89dc70, 8f89e470]
> ERROR: v7_outer_cache_inval_range - start address is not aligned - 0x8f89dc70
> ERROR: v7_outer_cache_inval_range - stop address is not aligned - 0x8f89e470
> CACHE: Misaligned operation at range [8f89dc70, 8f89e470]
> CACHE: Misaligned operation at range [8f89dc70, 8f89e470]
> ERROR: v7_outer_cache_inval_range - start address is not aligned - 0x8f89dc70
> ERROR: v7_outer_cache_inval_range - stop address is not aligned - 0x8f89e470
> CACHE: Misaligned operation at range [8f89e488, 8f89ec88]
> CACHE: Misaligned operation at range [8f89e488, 8f89ec88]
> ERROR: v7_outer_cache_inval_range - start address is not aligned - 0x8f89e488
> ERROR: v7_outer_cache_inval_range - stop address is not aligned - 0x8f89ec88
> CACHE: Misaligned operation at range [8f89e488, 8f89ec88]
> CACHE: Misaligned operation at range [8f89e488, 8f89ec88]
> ERROR: v7_outer_cache_inval_range - start address is not aligned - 0x8f89e488
> ERROR: v7_outer_cache_inval_range - stop address is not aligned - 0x8f89ec88
> CACHE: Misaligned operation at range [8f89e470, 8f89ec70]
> CACHE: Misaligned operation at range [8f89e470, 8f89ec70]
> ERROR: v7_outer_cache_inval_range - start address is not aligned - 0x8f89e470
> ERROR: v7_outer_cache_inval_range - stop address is not aligned - 0x8f89ec70
> CACHE: Misaligned operation at range [8f89e470, 8f89ec70]
> CACHE: Misaligned operation at range [8f89e470, 8f89ec70]
> ERROR: v7_outer_cache_inval_range - start address is not aligned - 0x8f89e470
> ERROR: v7_outer_cache_inval_range - stop address is not aligned - 0x8f89ec70
> CACHE: Misaligned operation at range [8f89e488, 8f89ec88]
> CACHE: Misaligned operation at range [8f89e488, 8f89ec88]
> ERROR: v7_outer_cache_inval_range - start address is not aligned - 0x8f89e488
> ERROR: v7_outer_cache_inval_range - stop address is not aligned - 0x8f89ec88
> CACHE: Misaligned operation at range [8f89e488, 8f89ec88]
> CACHE: Misaligned operation at range [8f89e488, 8f89ec88]
> ERROR: v7_outer_cache_inval_range - start address is not aligned - 0x8f89e488
> ERROR: v7_outer_cache_inval_range - stop address is not aligned - 0x8f89ec88
> CACHE: Misaligned operation at range [8f89e438, 8f89ec38]
> CACHE: Misaligned operation at range [8f89e438, 8f89ec38]
> ERROR: v7_outer_cache_inval_range - start address is not aligned - 0x8f89e438
> ERROR: v7_outer_cache_inval_range - stop address is not aligned - 0x8f89ec38
> CACHE: Misaligned operation at range [8f89e438, 8f89ec38]
> CACHE: Misaligned operation at range [8f89e438, 8f89ec38]
> ERROR: v7_outer_cache_inval_range - start address is not aligned - 0x8f89e438
> ERROR: v7_outer_cache_inval_range - stop address is not aligned - 0x8f89ec38
> AHCI 0001.0300 32 slots 1 ports 3 Gbps 0x1 impl SATA mode
> flags: ncq stag pm led clo only pmp pio slum part
> No port device detected!
>
> Device 0: Model: Firm: Ser#:
> Type: Hard Disk
> Capacity: not available
> ... is now current device
> ** Bad device size - sata 0 **
> starting USB...
> USB0: Port not available.
> USB1: USB EHCI 1.00
> scanning bus 1 for devices... 1 USB Device(s) found
> scanning usb for storage devices... 0 Storage Device(s) found
>
> Device 0: device type unknown
> ... is now current device
> ** Bad device usb 0 **
> ** Bad device usb 0 **
^ permalink raw reply
* Re: [PATCH v2 8/8] arm64: dts: renesas: eagle: add EtherAVB support
From: Simon Horman @ 2017-10-05 9:05 UTC (permalink / raw)
To: Geert Uytterhoeven
Cc: Sergei Shtylyov, Rob Herring, Catalin Marinas, Will Deacon,
Linux-Renesas, devicetree@vger.kernel.org, Mark Rutland,
Magnus Damm, linux-arm-kernel@lists.infradead.org,
Vladimir Barinov
In-Reply-To: <CAMuHMdVCTORpfKN+GTka_6pT1VWjOneV2GBhGo7Y8DsZYSxdvw@mail.gmail.com>
On Thu, Sep 21, 2017 at 06:09:34PM +0200, Geert Uytterhoeven wrote:
> Hi Sergei,
>
> On Thu, Sep 21, 2017 at 6:03 PM, Sergei Shtylyov
> <sergei.shtylyov@cogentembedded.com> wrote:
> > On 9/21/2017 4:08 PM, Geert Uytterhoeven wrote:
> >>> Define the Eagle board dependent part of the EtherAVB device node.
> >>> Enable DHCP and NFS root for the kernel booting.
> >>>
> >>> Based on the original (and large) patch by Vladimir Barinov.
> >>>
> >>> Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
> >>> Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
> >>
> >>
> >>> --- renesas.orig/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts
> >>> +++ renesas/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts
> >
> > [...]
> >>>
> >>> @@ -43,3 +44,14 @@
> >>> &scif0 {
> >>> status = "okay";
> >>> };
> >>> +
> >>> +&avb {
> >>> + renesas,no-ether-link;
> >>> + phy-handle = <&phy0>;
> >>> + status = "okay";
> >>> +
> >>> + phy0: ethernet-phy@0 {
> >>> + rxc-skew-ps = <1500>;
> >>> + reg = <0>;
> >>
> >>
> >> Any specific reason why you don't want to wire up the interrupt?
> >>
> >> interrupt-parent = <&gpio2>;
> >
> >
> > I thought it's quite obvious -- we don't have GPIOs yet, and GPIOs seem
> > to require PFC.
>
> Of course. And these can be added later.
>
> Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Thanks, applied.
^ permalink raw reply
* [PATCH v2 8/8] arm64: dts: renesas: eagle: add EtherAVB support
From: Simon Horman @ 2017-10-05 9:05 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAMuHMdVCTORpfKN+GTka_6pT1VWjOneV2GBhGo7Y8DsZYSxdvw@mail.gmail.com>
On Thu, Sep 21, 2017 at 06:09:34PM +0200, Geert Uytterhoeven wrote:
> Hi Sergei,
>
> On Thu, Sep 21, 2017 at 6:03 PM, Sergei Shtylyov
> <sergei.shtylyov@cogentembedded.com> wrote:
> > On 9/21/2017 4:08 PM, Geert Uytterhoeven wrote:
> >>> Define the Eagle board dependent part of the EtherAVB device node.
> >>> Enable DHCP and NFS root for the kernel booting.
> >>>
> >>> Based on the original (and large) patch by Vladimir Barinov.
> >>>
> >>> Signed-off-by: Vladimir Barinov <vladimir.barinov@cogentembedded.com>
> >>> Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
> >>
> >>
> >>> --- renesas.orig/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts
> >>> +++ renesas/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts
> >
> > [...]
> >>>
> >>> @@ -43,3 +44,14 @@
> >>> &scif0 {
> >>> status = "okay";
> >>> };
> >>> +
> >>> +&avb {
> >>> + renesas,no-ether-link;
> >>> + phy-handle = <&phy0>;
> >>> + status = "okay";
> >>> +
> >>> + phy0: ethernet-phy at 0 {
> >>> + rxc-skew-ps = <1500>;
> >>> + reg = <0>;
> >>
> >>
> >> Any specific reason why you don't want to wire up the interrupt?
> >>
> >> interrupt-parent = <&gpio2>;
> >
> >
> > I thought it's quite obvious -- we don't have GPIOs yet, and GPIOs seem
> > to require PFC.
>
> Of course. And these can be added later.
>
> Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Thanks, applied.
^ permalink raw reply
* [Qemu-devel] [PULL 1/4] hw/usb/bus: Remove bad object_unparent() from usb_try_create_simple()
From: Gerd Hoffmann @ 2017-10-05 9:04 UTC (permalink / raw)
To: qemu-devel; +Cc: Thomas Huth, Gerd Hoffmann
In-Reply-To: <20171005090443.26889-1-kraxel@redhat.com>
From: Thomas Huth <thuth@redhat.com>
Valgrind detects an invalid read operation when hot-plugging of an
USB device fails:
$ valgrind x86_64-softmmu/qemu-system-x86_64 -device usb-ehci -nographic -S
==30598== Memcheck, a memory error detector
==30598== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==30598== Using Valgrind-3.12.0 and LibVEX; rerun with -h for copyright info
==30598== Command: x86_64-softmmu/qemu-system-x86_64 -device usb-ehci -nographic -S
==30598==
QEMU 2.10.50 monitor - type 'help' for more information
(qemu) device_add usb-tablet
(qemu) device_add usb-tablet
(qemu) device_add usb-tablet
(qemu) device_add usb-tablet
(qemu) device_add usb-tablet
(qemu) device_add usb-tablet
==30598== Invalid read of size 8
==30598== at 0x60EF50: object_unparent (object.c:445)
==30598== by 0x580F0D: usb_try_create_simple (bus.c:346)
==30598== by 0x581BEB: usb_claim_port (bus.c:451)
==30598== by 0x582310: usb_qdev_realize (bus.c:257)
==30598== by 0x4CB399: device_set_realized (qdev.c:914)
==30598== by 0x60E26D: property_set_bool (object.c:1886)
==30598== by 0x61235E: object_property_set_qobject (qom-qobject.c:27)
==30598== by 0x61000F: object_property_set_bool (object.c:1162)
==30598== by 0x4567C3: qdev_device_add (qdev-monitor.c:630)
==30598== by 0x456D52: qmp_device_add (qdev-monitor.c:807)
==30598== by 0x470A99: hmp_device_add (hmp.c:1933)
==30598== by 0x3679C3: handle_hmp_command (monitor.c:3123)
The object_unparent() here is not necessary anymore since commit
69382d8b3e8600b3 ("qdev: Fix object reference leak in case device.realize()
fails"), so let's remove it now.
Suggested-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
Message-id: 1506526106-30971-1-git-send-email-thuth@redhat.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
hw/usb/bus.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/hw/usb/bus.c b/hw/usb/bus.c
index d910f849e7..e56dc3348a 100644
--- a/hw/usb/bus.c
+++ b/hw/usb/bus.c
@@ -341,9 +341,7 @@ static USBDevice *usb_try_create_simple(USBBus *bus, const char *name,
object_property_set_bool(OBJECT(dev), true, "realized", &err);
if (err) {
error_propagate(errp, err);
- error_prepend(errp, "Failed to initialize USB device '%s': ",
- name);
- object_unparent(OBJECT(dev));
+ error_prepend(errp, "Failed to initialize USB device '%s': ", name);
return NULL;
}
return dev;
--
2.9.3
^ permalink raw reply related
* [Qemu-devel] [PULL 2/4] usb: fix libusb config variable name.
From: Gerd Hoffmann @ 2017-10-05 9:04 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann, Jan Kiszka
In-Reply-To: <20171005090443.26889-1-kraxel@redhat.com>
Cc: Jan Kiszka <jan.kiszka@siemens.com>
Fixes: 4e5ee5b21c84fe3023a64b5cc2e12a52ab0597c1
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Tested-by: Jan Kiszka <jan.kiszka@siemens.com>
Message-id: 20170926063820.30773-1-kraxel@redhat.com
---
hw/usb/Makefile.objs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/hw/usb/Makefile.objs b/hw/usb/Makefile.objs
index 9255234c63..0e6d54b21f 100644
--- a/hw/usb/Makefile.objs
+++ b/hw/usb/Makefile.objs
@@ -42,7 +42,7 @@ redirect.o-cflags = $(USB_REDIR_CFLAGS)
redirect.o-libs = $(USB_REDIR_LIBS)
# usb pass-through
-ifeq ($(CONFIG_LIBUSB)$(CONFIG_USB),yy)
+ifeq ($(CONFIG_USB_LIBUSB)$(CONFIG_USB),yy)
common-obj-y += host-libusb.o host-legacy.o
else
common-obj-y += host-stub.o
--
2.9.3
^ permalink raw reply related
* [Qemu-devel] [PULL 4/4] usb: fix host-stub.c build race
From: Gerd Hoffmann @ 2017-10-05 9:04 UTC (permalink / raw)
To: qemu-devel; +Cc: Gerd Hoffmann
In-Reply-To: <20171005090443.26889-1-kraxel@redhat.com>
Suggested-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Message-id: 20171004125210.7817-1-kraxel@redhat.com
---
hw/usb/Makefile.objs | 1 +
1 file changed, 1 insertion(+)
diff --git a/hw/usb/Makefile.objs b/hw/usb/Makefile.objs
index 0e6d54b21f..bdfead6701 100644
--- a/hw/usb/Makefile.objs
+++ b/hw/usb/Makefile.objs
@@ -47,6 +47,7 @@ common-obj-y += host-libusb.o host-legacy.o
else
common-obj-y += host-stub.o
endif
+common-obj-$(CONFIG_ALL) += host-stub.o
host-libusb.o-cflags := $(LIBUSB_CFLAGS)
host-libusb.o-libs := $(LIBUSB_LIBS)
--
2.9.3
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.