All of lore.kernel.org
 help / color / mirror / Atom feed
From: Benjamin Tissoires <benjamin.tissoires@gmail.com>
To: Jiri Kosina <jikos@kernel.org>
Cc: Bastien Nocera <hadess@hadess.net>,
	Peter Hutterer <peter.hutterer@who-t.net>,
	Nestor Lopez Casado <nlopezcasad@logitech.com>,
	Olivier Gay <ogay@logitech.com>, Simon Wood <simon@mungewell.org>,
	linux-input <linux-input@vger.kernel.org>,
	"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH 13/17] HID: logitech-hidpp: make .probe usbhid capable
Date: Wed, 18 Jan 2017 10:26:12 +0100	[thread overview]
Message-ID: <CAN+gG=G30ZROL7R9WRZ7971pmmd46OhLctA-v-zSB+CmFu2SUQ@mail.gmail.com> (raw)
In-Reply-To: <20170117143547.30488-14-benjamin.tissoires@redhat.com>

On Tue, Jan 17, 2017 at 3:35 PM, Benjamin Tissoires
<benjamin.tissoires@redhat.com> wrote:
> The current custom solution for the G920 is not the best because
> hid_hw_start() is not called at the end of the .probe().
> It means that any configuration retrieved after the initial hid_hw_start
> would not be exposed to user space without races.
>
> We can simply force hid_hw_start to just enable the transport layer by
> not using a connect_mask. This way, we can have a common path between
> USB, Unifying and Bluetooth devices.
>
> Tested with a G502 (plain USB), a T650 and many other unifying devices,
> and the T651 over Bluetooth.
>
> Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
> ---
>  drivers/hid/hid-logitech-hidpp.c | 88 ++++++++++++++++++++++------------------
>  1 file changed, 48 insertions(+), 40 deletions(-)
>
> diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c
> index a5d37a4..f5889ff 100644
> --- a/drivers/hid/hid-logitech-hidpp.c
> +++ b/drivers/hid/hid-logitech-hidpp.c
> @@ -2813,6 +2813,17 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id)
>         if (!hidpp_validate_device(hdev))
>                 return hid_hw_start(hdev, HID_CONNECT_DEFAULT);
>
> +       /*
> +        * HID++ needs to read incoming report while in .probe().
> +        * However, this doesn't work for plain USB devices until the hdev
> +        * status is set with HID_STAT_ADDED (device fully registered once
> +        * with HID).
> +        * So we ask for it to be reprobed later.
> +        */
> +       if (id->group != HID_GROUP_LOGITECH_DJ_DEVICE &&
> +           !(hdev->status & HID_STAT_ADDED))

Looks like this test breaks the T651 (bluetooth) after all. I seem to
have better success with:
    if (id->bus == BUS_USB && !(hdev->status & HID_STAT_ADDED))

But that also means that the solution will not work if there is only
one USB interface in the device :/

Cheers,
Benjamin

> +               return -EPROBE_DEFER;
> +
>         hidpp = devm_kzalloc(&hdev->dev, sizeof(struct hidpp_device),
>                         GFP_KERNEL);
>         if (!hidpp)
> @@ -2853,24 +2864,23 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id)
>                 hid_warn(hdev, "Cannot allocate sysfs group for %s\n",
>                          hdev->name);
>
> -       if (hidpp->quirks & HIDPP_QUIRK_NO_HIDINPUT)
> -               connect_mask &= ~HID_CONNECT_HIDINPUT;
> -
> -       if (hidpp->quirks & HIDPP_QUIRK_CLASS_G920) {
> -               ret = hid_hw_start(hdev, connect_mask);
> -               if (ret) {
> -                       hid_err(hdev, "hw start failed\n");
> -                       goto hid_hw_start_fail;
> -               }
> -               ret = hid_hw_open(hdev);
> -               if (ret < 0) {
> -                       dev_err(&hdev->dev, "%s:hid_hw_open returned error:%d\n",
> -                               __func__, ret);
> -                       hid_hw_stop(hdev);
> -                       goto hid_hw_start_fail;
> -               }
> +       /*
> +        * Plain USB connections need to actually call start and open
> +        * on the transport driver to allow incoming data.
> +        */
> +       ret = hid_hw_start(hdev, 0);
> +       if (ret) {
> +               hid_err(hdev, "hw start failed\n");
> +               goto hid_hw_start_fail;
>         }
>
> +       ret = hid_hw_open(hdev);
> +       if (ret < 0) {
> +               dev_err(&hdev->dev, "%s:hid_hw_open returned error:%d\n",
> +                       __func__, ret);
> +               hid_hw_stop(hdev);
> +               goto hid_hw_open_fail;
> +       }
>
>         /* Allow incoming packets */
>         hid_device_io_start(hdev);
> @@ -2880,7 +2890,7 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id)
>                 if (!connected) {
>                         ret = -ENODEV;
>                         hid_err(hdev, "Device not connected");
> -                       goto hid_hw_open_failed;
> +                       goto hid_hw_init_fail;
>                 }
>
>                 hid_info(hdev, "HID++ %u.%u device connected.\n",
> @@ -2893,37 +2903,36 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id)
>         if (connected && (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP)) {
>                 ret = wtp_get_config(hidpp);
>                 if (ret)
> -                       goto hid_hw_open_failed;
> +                       goto hid_hw_init_fail;
>         } else if (connected && (hidpp->quirks & HIDPP_QUIRK_CLASS_G920)) {
>                 ret = g920_get_config(hidpp);
>                 if (ret)
> -                       goto hid_hw_open_failed;
> +                       goto hid_hw_init_fail;
>         }
>
> -       /* Block incoming packets */
> -       hid_device_io_stop(hdev);
> +       hidpp_connect_event(hidpp);
>
> -       if (!(hidpp->quirks & HIDPP_QUIRK_CLASS_G920)) {
> -               ret = hid_hw_start(hdev, connect_mask);
> -               if (ret) {
> -                       hid_err(hdev, "%s:hid_hw_start returned error\n", __func__);
> -                       goto hid_hw_start_fail;
> -               }
> -       }
> +       /* Reset the HID node state */
> +       hid_device_io_stop(hdev);
> +       hid_hw_close(hdev);
> +       hid_hw_stop(hdev);
>
> -       /* Allow incoming packets */
> -       hid_device_io_start(hdev);
> +       if (hidpp->quirks & HIDPP_QUIRK_NO_HIDINPUT)
> +               connect_mask &= ~HID_CONNECT_HIDINPUT;
>
> -       hidpp_connect_event(hidpp);
> +       /* Now export the actual inputs and hidraw nodes to the world */
> +       ret = hid_hw_start(hdev, connect_mask);
> +       if (ret) {
> +               hid_err(hdev, "%s:hid_hw_start returned error\n", __func__);
> +               goto hid_hw_start_fail;
> +       }
>
>         return ret;
>
> -hid_hw_open_failed:
> -       hid_device_io_stop(hdev);
> -       if (hidpp->quirks & HIDPP_QUIRK_CLASS_G920) {
> -               hid_hw_close(hdev);
> -               hid_hw_stop(hdev);
> -       }
> +hid_hw_init_fail:
> +       hid_hw_close(hdev);
> +hid_hw_open_fail:
> +       hid_hw_stop(hdev);
>  hid_hw_start_fail:
>         sysfs_remove_group(&hdev->dev.kobj, &ps_attribute_group);
>         cancel_work_sync(&hidpp->work);
> @@ -2942,10 +2951,9 @@ static void hidpp_remove(struct hid_device *hdev)
>
>         sysfs_remove_group(&hdev->dev.kobj, &ps_attribute_group);
>
> -       if (hidpp->quirks & HIDPP_QUIRK_CLASS_G920) {
> +       if (hidpp->quirks & HIDPP_QUIRK_CLASS_G920)
>                 hidpp_ff_deinit(hdev);
> -               hid_hw_close(hdev);
> -       }
> +
>         hid_hw_stop(hdev);
>         cancel_work_sync(&hidpp->work);
>         mutex_destroy(&hidpp->send_mutex);
> --
> 2.9.3
>

  reply	other threads:[~2017-01-18  9:26 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-01-17 14:35 [PATCH 00/17] Report power supply from hid-logitech-dj and others Benjamin Tissoires
2017-01-17 14:35 ` [PATCH 01/17] HID: logitech-dj: allow devices to request full pairing information Benjamin Tissoires
2017-01-17 14:35 ` [PATCH 02/17] HID: logitech-hidpp: Add scope to battery Benjamin Tissoires
2017-01-18 11:35   ` Bastien Nocera
2017-01-20 13:11   ` Jiri Kosina
2017-01-20 14:25     ` Benjamin Tissoires
2017-01-20 14:26       ` Jiri Kosina
2017-01-17 14:35 ` [PATCH 03/17] HID: logitech-hidpp: make sure we only register one battery per device Benjamin Tissoires
2017-01-17 14:35 ` [PATCH 04/17] HID: logitech-hidpp: battery: remove overloads and provide ONLINE Benjamin Tissoires
2017-01-17 14:35 ` [PATCH 05/17] HID: logitech-hidpp: forward device info in power_supply Benjamin Tissoires
2017-01-17 14:35 ` [PATCH 06/17] HID: logitech-hidpp: create the battery for all types of HID++ devices Benjamin Tissoires
2017-01-17 14:35 ` [PATCH 07/17] HID: logitech-hidpp: return an error if the feature is not present Benjamin Tissoires
2017-01-17 14:35 ` [PATCH 08/17] HID: logitech-hidpp: add support for battery status for the K750 Benjamin Tissoires
2017-01-17 14:35 ` [PATCH 09/17] HID: logitech-hidpp: enable HID++ 1.0 battery reporting Benjamin Tissoires
2017-01-17 14:35 ` [PATCH 10/17] HID: logitech-hidpp: notify battery on connect Benjamin Tissoires
2017-01-17 14:35 ` [PATCH 11/17] HID: logitech-hidpp: add a sysfs file to tell we support power_supply Benjamin Tissoires
2017-01-17 14:35 ` [PATCH 12/17] HID: logitech-hidpp: allow non HID++ devices to be handled by this module Benjamin Tissoires
2017-01-17 14:35 ` [PATCH 13/17] HID: logitech-hidpp: make .probe usbhid capable Benjamin Tissoires
2017-01-18  9:26   ` Benjamin Tissoires [this message]
2017-01-19 10:56     ` Jiri Kosina
2017-01-19 11:11       ` Benjamin Tissoires
2017-01-17 14:35 ` [PATCH 14/17] HID: logitech-hidpp: do not query the name through HID++ for 1.0 devices Benjamin Tissoires
2017-01-17 14:35 ` [PATCH 15/17] HID: logitech-hidpp: rework probe path for unifying devices Benjamin Tissoires
2017-01-17 14:35 ` [PATCH 16/17] HID: logitech-hidpp: report battery for the G700 over wireless Benjamin Tissoires
2017-01-17 14:35 ` [PATCH 17/17] HID: logitech-hidpp: retrieve the name of the gaming mice " Benjamin Tissoires
2017-01-23 14:35 ` [PATCH 00/17] Report power supply from hid-logitech-dj and others Bastien Nocera
2017-01-23 15:22   ` Benjamin Tissoires
2017-01-24 17:11   ` Bastien Nocera

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAN+gG=G30ZROL7R9WRZ7971pmmd46OhLctA-v-zSB+CmFu2SUQ@mail.gmail.com' \
    --to=benjamin.tissoires@gmail.com \
    --cc=hadess@hadess.net \
    --cc=jikos@kernel.org \
    --cc=linux-input@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=nlopezcasad@logitech.com \
    --cc=ogay@logitech.com \
    --cc=peter.hutterer@who-t.net \
    --cc=simon@mungewell.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.