Re: [PATCH 09/10] Input: synaptics-rmi4: Add device tree support to the SPI transport driver
On Wed, Nov 25, 2015 at 04:10:25PM -0800, Andrew Duggan wrote: > Add devicetree binding for SPI devices. > > Signed-off-by: Andrew Duggan> --- > .../devicetree/bindings/input/rmi4/rmi_spi.txt | 57 > ++ > drivers/input/rmi4/rmi_spi.c | 44 - > 2 files changed, 100 insertions(+), 1 deletion(-) > create mode 100644 Documentation/devicetree/bindings/input/rmi4/rmi_spi.txt > > diff --git a/Documentation/devicetree/bindings/input/rmi4/rmi_spi.txt > b/Documentation/devicetree/bindings/input/rmi4/rmi_spi.txt > new file mode 100644 > index 000..f20366b6 > --- /dev/null > +++ b/Documentation/devicetree/bindings/input/rmi4/rmi_spi.txt > @@ -0,0 +1,57 @@ > +Synaptics RMI4 SPI Device Binding > + > +The Synaptics RMI4 core is able to support RMI4 devices using differnet > +transports and differnet functions. This file describes the device tree > +bindings for devices using the SPI tranport driver. Complete documentation > +for other transports and functions cen be found ini > +Documentation/devicetree/bindings/input/rmi4. > + > +Required Properties: > +- compatible: syna,rmi-spi > +- reg: Chip select address for the device > +- #address-cells: Set to 1 to indicate that the function child nodes > + consist of only on uint32 value. > +- #size-cells: Set to 0 to indicate that the function child nodes do not > + have a size property. > + > +Optional Properties: > +- interrupts: interrupt which the rmi device is connected to. > +- interrupt-parent: The interrupt controller. > +See Documentation/devicetree/bindings/interrupt-controller/interrupts.txt > + > +- syna,spi-read-delay: millisecond delay between read byte transfers. > +- syna,spi-write-delay: millisecond delay between write byte transfers. These could possibly be common SPI properties, but they would need to be somewhat better defined as every access on SPI is a read and a write. What if you have a read then write or write then read? Just a time between transfers would probably make more sense. Minimally, they should have -msec suffix. Rob -- To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[3.19.y-ckt stable] Patch "HID: core: Avoid uninitialized buffer access" has been added to staging queue
This is a note to let you know that I have just added a patch titled HID: core: Avoid uninitialized buffer access to the linux-3.19.y-queue branch of the 3.19.y-ckt extended stable tree which can be found at: http://kernel.ubuntu.com/git/ubuntu/linux.git/log/?h=linux-3.19.y-queue This patch is scheduled to be released in version 3.19.8-ckt11. If you, or anyone else, feels it should not be added to this tree, please reply to this email. For more information about the 3.19.y-ckt tree, see https://wiki.ubuntu.com/Kernel/Dev/ExtendedStable Thanks. -Kamal -- >From b6be0e21e58d8c6284e85baeecaa5e206245946e Mon Sep 17 00:00:00 2001 From: Richard PurdieDate: Fri, 18 Sep 2015 16:31:33 -0700 Subject: HID: core: Avoid uninitialized buffer access commit 79b568b9d0c7c5d81932f4486d50b38efdd6da6d upstream. hid_connect adds various strings to the buffer but they're all conditional. You can find circumstances where nothing would be written to it but the kernel will still print the supposedly empty buffer with printk. This leads to corruption on the console/in the logs. Ensure buf is initialized to an empty string. Signed-off-by: Richard Purdie [dvhart: Initialize string to "" rather than assign buf[0] = NULL;] Cc: Jiri Kosina Cc: linux-input@vger.kernel.org Signed-off-by: Darren Hart Signed-off-by: Jiri Kosina Signed-off-by: Kamal Mostafa --- drivers/hid/hid-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 8b63879..d7d965f 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1562,7 +1562,7 @@ int hid_connect(struct hid_device *hdev, unsigned int connect_mask) "Multi-Axis Controller" }; const char *type, *bus; - char buf[64]; + char buf[64] = ""; unsigned int i; int len; int ret; -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] Input: aiptek: fix crash on detecting device without endpoints
On Mon, Nov 30, 2015 at 03:38:20PM -0500, Alan Stern wrote: > On Mon, 30 Nov 2015, Dmitry Torokhov wrote: > > > How about we do something like below? > > It looks okay to me. If you want to propose it on the linux-usb > mailing list, you can add: > > Acked-by: Alan SternI will, thank you Alan. -- Dmitry -- To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] Input: aiptek: fix crash on detecting device without endpoints
On Mon, 30 Nov 2015, Vladis Dronov wrote: > Hello, Alan, all. Hello. > > > Yes for the normal USB device. This case is a weird USB device (with no > > > endpoints) specially designed to be weird. My point here is that even a > > > weird device probing should not crash a kernel by a NULL-deref. > > > > True. However, a weird device that didn't have any endpoint 0 would > > not crash the kernel, because the kernel wouldn't be able to > > communicate with it at all. > > I'm afraid, I do not get you here. A device in question _does_ crash the > kernel > (or driver only) as this call trace shows (see attached for the full call > trace), > and that's why the patch is proposed: > > [ 622.444650] BUG: unable to handle kernel NULL pointer dereference at > 0002 > [ 622.445019] IP: [] aiptek_probe+0x463/0x658 [aiptek] > [ 622.445019] RIP: 0010:[] aiptek_probe+0x463/0x658 > [aiptek] > [ 622.445019] RAX: RBX: 88000bd67800 RCX: > 88000bcd0800 > ^^^ rax is NULL, it is being dereferenced This is the result of a bug in the aiptek driver. See below. > Kernel does not communicates with the device, Yes it does. Otherwise how would the kernel know that the aiptek driver was the one which should be probed for this device? > but the driver tries to access > a kernel structure, which was not allocated (thus, a null-deref): > > endpoint = >altsetting[0].endpoint[0].desc; // the structure endpoint[0] > // was not kzalloc()ed, thus NULL > usb_rcvintpipe(aiptek->usbdev, endpoint->bEndpointAddress) // NULL deref Right. That's the bug; aiptek should not try to access a data structure that was never allocated. > > Drivers do not have to check whether endpoint 0 exists; it always does. > > But they do have to check any other endpoint they use. > > As the above example shows, endpoint 0 does not always exists. A specially > crafted weird USB device can advertise absence of endpoint 0 and the kernel > will accept this: The example above has nothing to do with endpoint 0. The entries in the altsetting[n].endpoint array are not stored in numerical order; entry 0 in this array does not refer to endpoint 0. (See the comment for the endpoint field in the definition of struct usb_host_interface in include/linux/usb.h.) In fact, endpoint 0 is treated specially and isn't part of this array at all. > [drivers/usb/core/config.c] > num_ep = num_ep_orig = alt->desc.bNumEndpoints; // weird device can have 0 > here > alt->desc.bNumEndpoints = 0; > if (num_ep > 0) { > /* Can't allocate 0 bytes */ > len = sizeof(struct usb_host_endpoint) * num_ep; > alt->endpoint = kzalloc(len, GFP_KERNEL); > > As far as I understand, this is a question we discuss here: whose > responsibility > is to handle situations of endpoint 0 absence in an altconfig? num_ep counts the number of endpoints _other_ than endpoint 0. There's no point counting endpoint 0 because it is always present. Not to mention that it doesn't get stored in this array, since endpoint 0 has no descriptor. > - if it is driver's job, a driver much check this, as in the patch I propose > > - if it is a kernel job not to allow devices with no endpoint 0 in one the > configurations, the current USB device detection implementation (in > drivers/usb/core/config.c) should be modified, as currently it allows such. > > I do not have much expertise in the Linux USB stack, so I'm asking you and > the community for an advise on this. My advice is to fix aiptek's probe routine. It should check that intf->altsetting[0].desc.bNumEndpoints > 0 before trying to accessing the endpoint array. > > > btw, indeed, this is not the only driver with this problem, I've met 2 > > > more. > > > > In fact, there's no way to check whether endpoint 0 exists. Where > > would you look to find out? There isn't any endpoint descriptor for it. > > I believe, there is a configuration descriptor for that, probably, I'm wrong: > > if (intf->altsetting[0].desc.bNumEndpoints < 1) { ... That value is the number of endpoints _other_ than endpoint 0. This is documented in the USB-2.0 specification, Table 9-12. Alan Stern -- To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 0/3] introduce new evdev interface type
On Sunday 29 November 2015 17:13:50 Pingbo Wen wrote: > > 在 2015年11月28日,00:58,Arnd Bergmann写道: > > > > On Friday 27 November 2015 18:00:29 WEN Pingbo wrote: > >> To solve the y2038 problem in input_event, I had some attempts before [1], > >> and this is the second one. > >> > >> We can force userspace to use monotonic time in event timestamp, so the > >> 'struct timeval' is enough to keep y2038-safe, as Arnd suggested. But we > >> can not find a way to make kernel compatible with old binaries, which use > >> realtime, and there are still some devices, which depend on realtime. > >> > >> So I get a idea to add a new evdev interface, which is y2038 safe. And > >> userspace can switch between the old and new interface via ioctl. > >> > >> The patch series add three evdev interface type: > >> > >> - EV_IF_LEGACY > >> send event by input_event. This is the default option, keep kernel > >> backward compatible. > > > > The problem I see with this approach is that it still breaks any > > legacy source code that is compiled with a new libc that uses 64-bit > > time_t. If we are requiring source code changes for building users > > of input devices with a new libc, we can easily get them to handle > > the overflow (they normally only care about the microsecond portion > > anyway, so it doesn't matter in most cases), or to use monotonic time. > > I don’t think so. > > Actually, from the view of userspace, EV_IF_LEGACY interface is work > exactly the same as old evdev. We didn’t change anything in input_event > and input_event_compat. And the problem you said will still be there, > even without those patches. I think we're still talking past one another. I thought we had established that 1. the current interface is broken when time_t changes in user space 2. we can fix it by redefining struct input_event in a way that is independent of time_t 3. once both user space and kernel are using the same ABI independent of time_t, we can look improving the timestamps so they don't overflow 4. the monotonic timestamp interface already avoids the overflow, so it would be sufficient as a solution for 3. Where did I lose you here? Did you find any other facts that I was missing? I don't know whether the two new event structures make the interface better in some other way, but it seems mostly unrelated to either of the two problems we already have with time_t (the ABI mismatch, and the use of non-monotonic timestamps). Arnd -- To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] Input: arizona-haptic: Correct disable of haptics device
A small copy and paste error was preventing the haptics device being disabled. This patch corrects the value written on disable. Signed-off-by: Charles Keepax--- drivers/input/misc/arizona-haptics.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/input/misc/arizona-haptics.c b/drivers/input/misc/arizona-haptics.c index 4bf6785..d5994a7 100644 --- a/drivers/input/misc/arizona-haptics.c +++ b/drivers/input/misc/arizona-haptics.c @@ -97,8 +97,7 @@ static void arizona_haptics_work(struct work_struct *work) ret = regmap_update_bits(arizona->regmap, ARIZONA_HAPTICS_CONTROL_1, -ARIZONA_HAP_CTRL_MASK, -1 << ARIZONA_HAP_CTRL_SHIFT); +ARIZONA_HAP_CTRL_MASK, 0); if (ret != 0) { dev_err(arizona->dev, "Failed to stop haptics: %d\n", ret); -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] Input: aiptek: fix crash on detecting device without endpoints
On Mon, Nov 30, 2015 at 11:06:30AM -0500, Alan Stern wrote: > On Mon, 30 Nov 2015, Vladis Dronov wrote: > > > Hello, Alan, all. > > Hello. > > > > > Yes for the normal USB device. This case is a weird USB device (with no > > > > endpoints) specially designed to be weird. My point here is that even a > > > > weird device probing should not crash a kernel by a NULL-deref. > > > > > > True. However, a weird device that didn't have any endpoint 0 would > > > not crash the kernel, because the kernel wouldn't be able to > > > communicate with it at all. > > > > I'm afraid, I do not get you here. A device in question _does_ crash the > > kernel > > (or driver only) as this call trace shows (see attached for the full call > > trace), > > and that's why the patch is proposed: > > > > [ 622.444650] BUG: unable to handle kernel NULL pointer dereference at > > 0002 > > [ 622.445019] IP: [] aiptek_probe+0x463/0x658 [aiptek] > > [ 622.445019] RIP: 0010:[] aiptek_probe+0x463/0x658 > > [aiptek] > > [ 622.445019] RAX: RBX: 88000bd67800 RCX: > > 88000bcd0800 > > ^^^ rax is NULL, it is being dereferenced > > This is the result of a bug in the aiptek driver. See below. > > > Kernel does not communicates with the device, > > Yes it does. Otherwise how would the kernel know that the aiptek > driver was the one which should be probed for this device? > > > but the driver tries to access > > a kernel structure, which was not allocated (thus, a null-deref): > > > > endpoint = >altsetting[0].endpoint[0].desc; // the structure > > endpoint[0] > > // was not kzalloc()ed, thus > > NULL > > usb_rcvintpipe(aiptek->usbdev, endpoint->bEndpointAddress) // NULL deref > > Right. That's the bug; aiptek should not try to access a data > structure that was never allocated. > > > > Drivers do not have to check whether endpoint 0 exists; it always does. > > > But they do have to check any other endpoint they use. > > > > As the above example shows, endpoint 0 does not always exists. A specially > > crafted weird USB device can advertise absence of endpoint 0 and the kernel > > will accept this: > > The example above has nothing to do with endpoint 0. The entries in > the altsetting[n].endpoint array are not stored in numerical order; > entry 0 in this array does not refer to endpoint 0. (See the comment > for the endpoint field in the definition of struct usb_host_interface > in include/linux/usb.h.) In fact, endpoint 0 is treated specially and > isn't part of this array at all. > > > [drivers/usb/core/config.c] > > num_ep = num_ep_orig = alt->desc.bNumEndpoints; // weird device can have 0 > > here > > alt->desc.bNumEndpoints = 0; > > if (num_ep > 0) { > > /* Can't allocate 0 bytes */ > > len = sizeof(struct usb_host_endpoint) * num_ep; > > alt->endpoint = kzalloc(len, GFP_KERNEL); > > > > As far as I understand, this is a question we discuss here: whose > > responsibility > > is to handle situations of endpoint 0 absence in an altconfig? > > num_ep counts the number of endpoints _other_ than endpoint 0. > There's no point counting endpoint 0 because it is always present. > Not to mention that it doesn't get stored in this array, since endpoint > 0 has no descriptor. > > > - if it is driver's job, a driver much check this, as in the patch I propose > > > > - if it is a kernel job not to allow devices with no endpoint 0 in one the > > configurations, the current USB device detection implementation (in > > drivers/usb/core/config.c) should be modified, as currently it allows such. > > > > I do not have much expertise in the Linux USB stack, so I'm asking you and > > the community for an advise on this. > > My advice is to fix aiptek's probe routine. It should check that > intf->altsetting[0].desc.bNumEndpoints > 0 before trying to accessing > the endpoint array. > > > > > btw, indeed, this is not the only driver with this problem, I've met 2 > > > > more. > > > > > > In fact, there's no way to check whether endpoint 0 exists. Where > > > would you look to find out? There isn't any endpoint descriptor for it. > > > > I believe, there is a configuration descriptor for that, probably, I'm > > wrong: > > > > if (intf->altsetting[0].desc.bNumEndpoints < 1) { ... > > That value is the number of endpoints _other_ than endpoint 0. This is > documented in the USB-2.0 specification, Table 9-12. How about we do something like below? Thanks. -- Dmitry usb: interface: allow drivers declare number of endpoints they need From: Dmitry TorokhovUSB interface drivers need to check number of endpoints before trying to access/use them. Quite a few drivers only use the default setting (altsetting 0), so let's allow them to declare number of endpoints in altsetting 0 they require to operate and have USB core check it for us instead of
Re: [PATCH] Input: aiptek: fix crash on detecting device without endpoints
On Mon, 30 Nov 2015, Dmitry Torokhov wrote: > How about we do something like below? It looks okay to me. If you want to propose it on the linux-usb mailing list, you can add: Acked-by: Alan SternAlan Stern -- To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/2] HID: hid-logitech: Add support for G29
On Mon, Nov 30, 2015 at 3:15 PM,wrote: > Hi all, > > my completely off-the-bat guess would be that the combo uses multiple > interfaces as well, the patch seems to ignore everything but iface 0. Can you > comment out the 'if' that does this and give it a go? Just a FYI: https://bugzilla.kernel.org/show_bug.cgi?id=108121 I just been reported that the patch I attached here fixed the issue. I'll send it to the list tomorrow unless Jiri beats me at picking it up before :) Cheers, Benjamin > > Michal > > On Mon Nov 30 14:03:51 2015 GMT+0100, Joshua Clayton wrote: >> Simon et al, >> My logitech cordless mouse is not detected in linux-next >> I have bisected the breakage to this patch, >> commit 29fae1c85166ef525b8b6518e749295e0c9d1e20 in linux-next. >> >> On Monday, November 02, 2015 07:56:52 AM Simon Wood wrote: >> > At present the G29 is mis-identified as a DFGT, this patch ensures >> > that the wheel is correctly detected and allows setting the LEDs and >> > turning range via the '/sys' interface. >> > >> > This wheel can also emulate other types of Logitech wheels. >> > >> > Signed-off-by: Simon Wood >> > --- >> > drivers/hid/hid-core.c | 1 + >> > drivers/hid/hid-lg.c| 9 >> > drivers/hid/hid-lg4ff.c | 57 >> > + >> > 3 files changed, 63 insertions(+), 4 deletions(-) >> > >> > diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c >> > index 70a11ac..949d804 100644 >> > --- a/drivers/hid/hid-core.c >> > +++ b/drivers/hid/hid-core.c >> > @@ -1896,6 +1896,7 @@ static const struct hid_device_id >> > hid_have_special_driver[] = { >> > { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, >> > USB_DEVICE_ID_LOGITECH_RUMBLEPAD_CORD) }, >> > { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, >> > USB_DEVICE_ID_LOGITECH_RUMBLEPAD) }, >> > { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, >> > USB_DEVICE_ID_LOGITECH_RUMBLEPAD2_2) }, >> > + { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, >> > USB_DEVICE_ID_LOGITECH_G29_WHEEL) }, >> > { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, >> > USB_DEVICE_ID_LOGITECH_WINGMAN_F3D) }, >> > { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, >> > USB_DEVICE_ID_LOGITECH_WINGMAN_FFG ) }, >> > { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, >> > USB_DEVICE_ID_LOGITECH_FORCE3D_PRO) }, >> > diff --git a/drivers/hid/hid-lg.c b/drivers/hid/hid-lg.c >> > index 5332fb7..c20ac76 100644 >> > --- a/drivers/hid/hid-lg.c >> > +++ b/drivers/hid/hid-lg.c >> > @@ -620,6 +620,7 @@ static int lg_input_mapped(struct hid_device *hdev, >> > struct hid_input *hi, >> > usage->code == ABS_Y || usage->code == ABS_Z || >> > usage->code == ABS_RZ)) { >> > switch (hdev->product) { >> > + case USB_DEVICE_ID_LOGITECH_G29_WHEEL: >> > case USB_DEVICE_ID_LOGITECH_WHEEL: >> > case USB_DEVICE_ID_LOGITECH_MOMO_WHEEL: >> > case USB_DEVICE_ID_LOGITECH_DFP_WHEEL: >> > @@ -658,10 +659,18 @@ static int lg_event(struct hid_device *hdev, struct >> > hid_field *field, >> > >> > static int lg_probe(struct hid_device *hdev, const struct hid_device_id >> > *id) >> > { >> > + struct usb_interface *iface = to_usb_interface(hdev->dev.parent); >> > + __u8 iface_num = iface->cur_altsetting->desc.bInterfaceNumber; >> > unsigned int connect_mask = HID_CONNECT_DEFAULT; >> > struct lg_drv_data *drv_data; >> > int ret; >> > >> > + /* Only work with the 1st interface (G29 presents multiple) */ >> > + if (iface_num != 0) { >> > + dbg_hid("%s: ignoring ifnum %d\n", __func__, iface_num); >> > + return -ENODEV; >> > + } >> > + >> > drv_data = kzalloc(sizeof(struct lg_drv_data), GFP_KERNEL); >> > if (!drv_data) { >> > hid_err(hdev, "Insufficient memory, cannot allocate driver >> > data\n"); >> > diff --git a/drivers/hid/hid-lg4ff.c b/drivers/hid/hid-lg4ff.c >> > index b363d88..fbddcb3 100644 >> > --- a/drivers/hid/hid-lg4ff.c >> > +++ b/drivers/hid/hid-lg4ff.c >> > @@ -45,7 +45,8 @@ >> > #define LG4FF_MODE_G25_IDX 3 >> > #define LG4FF_MODE_DFGT_IDX 4 >> > #define LG4FF_MODE_G27_IDX 5 >> > -#define LG4FF_MODE_MAX_IDX 6 >> > +#define LG4FF_MODE_G29_IDX 6 >> > +#define LG4FF_MODE_MAX_IDX 7 >> > >> > #define LG4FF_MODE_NATIVE BIT(LG4FF_MODE_NATIVE_IDX) >> > #define LG4FF_MODE_DFEX BIT(LG4FF_MODE_DFEX_IDX) >> > @@ -53,6 +54,7 @@ >> > #define LG4FF_MODE_G25 BIT(LG4FF_MODE_G25_IDX) >> > #define LG4FF_MODE_DFGT BIT(LG4FF_MODE_DFGT_IDX) >> > #define LG4FF_MODE_G27 BIT(LG4FF_MODE_G27_IDX) >> > +#define LG4FF_MODE_G29 BIT(LG4FF_MODE_G29_IDX) >> > >> > #define LG4FF_DFEX_TAG "DF-EX" >> > #define LG4FF_DFEX_NAME "Driving Force / Formula EX" >> > @@ -62,6 +64,8 @@ >> > #define LG4FF_G25_NAME "G25 Racing Wheel" >> > #define LG4FF_G27_TAG "G27" >> > #define LG4FF_G27_NAME "G27 Racing Wheel" >> > +#define LG4FF_G29_TAG "G29" >> > +#define LG4FF_G29_NAME "G29 Racing Wheel" >> >
Some media keys are not working on my Asus X450LCP
Hi guys, this is the right place to ask aboutr media keys? In my laptop some keys like brightness and wireless toggle are not working. If there is some necessary info, please ask me. And if this is an easy task to code on kernel, please give me some code pointers! Thanks a lot! -- Att, Marcos Paulo de Souza Github: https://github.com/marcosps/ -- To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/7] HID: wacom: Move Intuos pad handling code into dedicated function
Begin slimming down the body of 'wacom_intuos_irq' by moving out its largest block of code to a dedicated 'wacom_intuos_pad' function. Signed-off-by: Jason Gerecke--- drivers/hid/wacom_wac.c | 482 +--- 1 file changed, 247 insertions(+), 235 deletions(-) diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index 8b29949..c611ea5 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -446,6 +446,249 @@ static void wacom_intuos_schedule_prox_event(struct wacom_wac *wacom_wac) } } +static int wacom_intuos_pad(struct wacom_wac *wacom) +{ + struct wacom_features *features = >features; + unsigned char *data = wacom->data; + struct input_dev *input = wacom->pad_input; + + /* pad packets. Works as a second tool and is always in prox */ + if (!(data[0] == WACOM_REPORT_INTUOSPAD || data[0] == WACOM_REPORT_INTUOS5PAD || + data[0] == WACOM_REPORT_CINTIQPAD)) + return 0; + + if (features->type >= INTUOS4S && features->type <= INTUOS4L) { + input_report_key(input, BTN_0, (data[2] & 0x01)); + input_report_key(input, BTN_1, (data[3] & 0x01)); + input_report_key(input, BTN_2, (data[3] & 0x02)); + input_report_key(input, BTN_3, (data[3] & 0x04)); + input_report_key(input, BTN_4, (data[3] & 0x08)); + input_report_key(input, BTN_5, (data[3] & 0x10)); + input_report_key(input, BTN_6, (data[3] & 0x20)); + if (data[1] & 0x80) { + input_report_abs(input, ABS_WHEEL, (data[1] & 0x7f)); + } else { + /* Out of proximity, clear wheel value. */ + input_report_abs(input, ABS_WHEEL, 0); + } + if (features->type != INTUOS4S) { + input_report_key(input, BTN_7, (data[3] & 0x40)); + input_report_key(input, BTN_8, (data[3] & 0x80)); + } + if (data[1] | (data[2] & 0x01) | data[3]) { + input_report_abs(input, ABS_MISC, PAD_DEVICE_ID); + } else { + input_report_abs(input, ABS_MISC, 0); + } + } else if (features->type == DTK) { + input_report_key(input, BTN_0, (data[6] & 0x01)); + input_report_key(input, BTN_1, (data[6] & 0x02)); + input_report_key(input, BTN_2, (data[6] & 0x04)); + input_report_key(input, BTN_3, (data[6] & 0x08)); + input_report_key(input, BTN_4, (data[6] & 0x10)); + input_report_key(input, BTN_5, (data[6] & 0x20)); + if (data[6] & 0x3f) { + input_report_abs(input, ABS_MISC, PAD_DEVICE_ID); + } else { + input_report_abs(input, ABS_MISC, 0); + } + } else if (features->type == WACOM_13HD) { + input_report_key(input, BTN_0, (data[3] & 0x01)); + input_report_key(input, BTN_1, (data[4] & 0x01)); + input_report_key(input, BTN_2, (data[4] & 0x02)); + input_report_key(input, BTN_3, (data[4] & 0x04)); + input_report_key(input, BTN_4, (data[4] & 0x08)); + input_report_key(input, BTN_5, (data[4] & 0x10)); + input_report_key(input, BTN_6, (data[4] & 0x20)); + input_report_key(input, BTN_7, (data[4] & 0x40)); + input_report_key(input, BTN_8, (data[4] & 0x80)); + if ((data[3] & 0x01) | data[4]) { + input_report_abs(input, ABS_MISC, PAD_DEVICE_ID); + } else { + input_report_abs(input, ABS_MISC, 0); + } + } else if (features->type == WACOM_24HD) { + input_report_key(input, BTN_0, (data[6] & 0x01)); + input_report_key(input, BTN_1, (data[6] & 0x02)); + input_report_key(input, BTN_2, (data[6] & 0x04)); + input_report_key(input, BTN_3, (data[6] & 0x08)); + input_report_key(input, BTN_4, (data[6] & 0x10)); + input_report_key(input, BTN_5, (data[6] & 0x20)); + input_report_key(input, BTN_6, (data[6] & 0x40)); + input_report_key(input, BTN_7, (data[6] & 0x80)); + input_report_key(input, BTN_8, (data[8] & 0x01)); + input_report_key(input, BTN_9, (data[8] & 0x02)); + input_report_key(input, BTN_A, (data[8] & 0x04)); + input_report_key(input, BTN_B, (data[8] & 0x08)); + input_report_key(input, BTN_C, (data[8] & 0x10)); + input_report_key(input, BTN_X, (data[8] & 0x20)); + input_report_key(input, BTN_Y, (data[8] & 0x40)); + input_report_key(input, BTN_Z, (data[8] & 0x80)); + + /* +*
[PATCH 4/7] HID: wacom: Replace magic masks and comparisons with switch cases
Reasoning through the conditions under which a particular block of code in 'wacom_intuos_general' will be reached is not at all easy due to the sheer number of magic masks and comparisons. Remove these and replace them with a switch statement over the various 'types' of packets that will be encountered. Signed-off-by: Jason Gerecke--- drivers/hid/wacom_wac.c | 79 ++--- 1 file changed, 49 insertions(+), 30 deletions(-) diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index e395688..a426cb2 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -886,6 +886,7 @@ static int wacom_intuos_general(struct wacom_wac *wacom) unsigned char *data = wacom->data; struct input_dev *input = wacom->pen_input; int idx = (features->type == INTUOS) ? (data[1] & 0x01) : 0; + unsigned char type = (data[1] >> 1) & 0x0F; unsigned int t; if (data[0] != WACOM_REPORT_PENABLED && data[0] != WACOM_REPORT_CINTIQ && @@ -902,8 +903,12 @@ static int wacom_intuos_general(struct wacom_wac *wacom) input_report_abs(input, ABS_DISTANCE, ((data[9] >> 3) & 0x1f)); } - /* general pen packet */ - if ((data[1] & 0xb8) == 0xa0) { + switch (type) { + case 0x00: + case 0x01: + case 0x02: + case 0x03: + /* general pen packet */ t = (data[6] << 2) | ((data[7] >> 6) & 3); if (features->pressure_max == 2047) { t = (t << 1) | (data[1] & 1); @@ -917,36 +922,40 @@ static int wacom_intuos_general(struct wacom_wac *wacom) input_report_key(input, BTN_STYLUS, data[1] & 2); input_report_key(input, BTN_STYLUS2, data[1] & 4); input_report_key(input, BTN_TOUCH, t > 10); - } + break; - /* airbrush second packet */ - if ((data[1] & 0xbc) == 0xb4) { + case 0x0a: + case 0x0b: + /* airbrush second packet */ input_report_abs(input, ABS_WHEEL, (data[6] << 2) | ((data[7] >> 6) & 3)); input_report_abs(input, ABS_TILT_X, (((data[7] << 1) & 0x7e) | (data[8] >> 7)) - 64); input_report_abs(input, ABS_TILT_Y, (data[8] & 0x7f) - 64); - } + break; - /* 4D mouse, 2D mouse, marker pen rotation, tilt mouse, or Lens cursor packets */ - if ((data[1] & 0xbc) == 0xa8 || (data[1] & 0xbe) == 0xb0 || (data[1] & 0xbc) == 0xac) { - - if (data[1] & 0x02) { - /* Rotation packet */ - if (features->type >= INTUOS3S) { - /* I3 marker pen rotation */ - t = (data[6] << 3) | ((data[7] >> 5) & 7); - t = (data[7] & 0x20) ? ((t > 900) ? ((t-1) / 2 - 1350) : - ((t-1) / 2 + 450)) : (450 - t / 2) ; - input_report_abs(input, ABS_Z, t); - } else { - /* 4D mouse rotation packet */ - t = (data[6] << 3) | ((data[7] >> 5) & 7); - input_report_abs(input, ABS_RZ, (data[7] & 0x20) ? - ((t - 1) / 2) : -t / 2); - } + case 0x05: + case 0x07: + /* Rotation packet */ + if (features->type >= INTUOS3S) { + /* I3 marker pen rotation */ + t = (data[6] << 3) | ((data[7] >> 5) & 7); + t = (data[7] & 0x20) ? ((t > 900) ? ((t-1) / 2 - 1350) : + ((t-1) / 2 + 450)) : (450 - t / 2) ; + input_report_abs(input, ABS_Z, t); + } else { + /* 4D mouse rotation packet */ + t = (data[6] << 3) | ((data[7] >> 5) & 7); + input_report_abs(input, ABS_RZ, (data[7] & 0x20) ? + ((t - 1) / 2) : -t / 2); + } + break; - } else if (!(data[1] & 0x10) && features->type < INTUOS3S) { + /* 4D mouse, 2D mouse, marker pen rotation, tilt mouse, or Lens cursor packets */ + case 0x04: + case 0x06: + case 0x08: + if (features->type < INTUOS3S && type != 0x08) { /* 4D mouse packet */ input_report_key(input, BTN_LEFT, data[8] & 0x01); input_report_key(input, BTN_MIDDLE, data[8] & 0x02); @@ -956,8 +965,8 @@ static int wacom_intuos_general(struct wacom_wac *wacom) input_report_key(input, BTN_EXTRA, data[8] & 0x10); t = (data[6] << 2) | ((data[7] >> 6) & 3);
[PATCH 7/7] HID: wacom: Rename wacom ID report ID macros
"INTUOSREAD" and "INTUOSWRITE" are poorly named. These are report IDs for pen ID (proximity) packets. It should be noted that the latter is only used on Intuos/Intuos2 for a second stylus when DualTrack is in use. Signed-off-by: Jason Gerecke--- drivers/hid/wacom_wac.c | 6 +++--- drivers/hid/wacom_wac.h | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index 0008650..3953416 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -443,7 +443,7 @@ static void wacom_intuos_schedule_prox_event(struct wacom_wac *wacom_wac) struct hid_report_enum *re; re = &(wacom->hdev->report_enum[HID_FEATURE_REPORT]); - r = re->report_id_hash[WACOM_REPORT_INTUOSREAD]; + r = re->report_id_hash[WACOM_REPORT_INTUOS_ID1]; if (r) { hid_hw_request(wacom->hdev, r, HID_REQ_GET_REPORT); } @@ -1027,8 +1027,8 @@ static int wacom_intuos_irq(struct wacom_wac *wacom) int result; if (data[0] != WACOM_REPORT_PENABLED && - data[0] != WACOM_REPORT_INTUOSREAD && - data[0] != WACOM_REPORT_INTUOSWRITE && + data[0] != WACOM_REPORT_INTUOS_ID1 && + data[0] != WACOM_REPORT_INTUOS_ID2 && data[0] != WACOM_REPORT_INTUOSPAD && data[0] != WACOM_REPORT_INTUOS_PEN && data[0] != WACOM_REPORT_CINTIQ && diff --git a/drivers/hid/wacom_wac.h b/drivers/hid/wacom_wac.h index 877c24a..3f60192 100644 --- a/drivers/hid/wacom_wac.h +++ b/drivers/hid/wacom_wac.h @@ -47,8 +47,8 @@ /* wacom data packet report IDs */ #define WACOM_REPORT_PENABLED 2 #define WACOM_REPORT_PENABLED_BT 3 -#define WACOM_REPORT_INTUOSREAD5 -#define WACOM_REPORT_INTUOSWRITE 6 +#define WACOM_REPORT_INTUOS_ID15 +#define WACOM_REPORT_INTUOS_ID26 #define WACOM_REPORT_INTUOSPAD 12 #define WACOM_REPORT_INTUOS5PAD3 #define WACOM_REPORT_DTUSPAD 21 -- 2.6.2 -- To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/7] HID: wacom: Slim down wacom_intuos_pad processing
Seperate the function into two halves: first gather data from the packet, next report all gathered data. The input subsystem should automatically mute any events that aren't actually declared for the tablet at hand. Signed-off-by: Jason Gerecke--- drivers/hid/wacom_wac.c | 277 +++- 1 file changed, 86 insertions(+), 191 deletions(-) diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index c611ea5..ec1e13e 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -34,6 +34,9 @@ */ #define WACOM_CONTACT_AREA_SCALE 2607 +static void wacom_report_numbered_buttons(struct input_dev *input_dev, + int button_count, int mask); + /* * Percent of battery capacity for Graphire. * 8th value means AC online and show 100% capacity. @@ -451,6 +454,12 @@ static int wacom_intuos_pad(struct wacom_wac *wacom) struct wacom_features *features = >features; unsigned char *data = wacom->data; struct input_dev *input = wacom->pad_input; + int i; + int buttons = 0, nbuttons = features->numbered_buttons; + int keys = 0, nkeys = 0; + int ring1 = 0, ring2 = 0; + int strip1 = 0, strip2 = 0; + bool prox = false; /* pad packets. Works as a second tool and is always in prox */ if (!(data[0] == WACOM_REPORT_INTUOSPAD || data[0] == WACOM_REPORT_INTUOS5PAD || @@ -458,72 +467,16 @@ static int wacom_intuos_pad(struct wacom_wac *wacom) return 0; if (features->type >= INTUOS4S && features->type <= INTUOS4L) { - input_report_key(input, BTN_0, (data[2] & 0x01)); - input_report_key(input, BTN_1, (data[3] & 0x01)); - input_report_key(input, BTN_2, (data[3] & 0x02)); - input_report_key(input, BTN_3, (data[3] & 0x04)); - input_report_key(input, BTN_4, (data[3] & 0x08)); - input_report_key(input, BTN_5, (data[3] & 0x10)); - input_report_key(input, BTN_6, (data[3] & 0x20)); - if (data[1] & 0x80) { - input_report_abs(input, ABS_WHEEL, (data[1] & 0x7f)); - } else { - /* Out of proximity, clear wheel value. */ - input_report_abs(input, ABS_WHEEL, 0); - } - if (features->type != INTUOS4S) { - input_report_key(input, BTN_7, (data[3] & 0x40)); - input_report_key(input, BTN_8, (data[3] & 0x80)); - } - if (data[1] | (data[2] & 0x01) | data[3]) { - input_report_abs(input, ABS_MISC, PAD_DEVICE_ID); - } else { - input_report_abs(input, ABS_MISC, 0); - } + buttons = (data[3] << 1) | (data[2] & 0x01); + ring1 = data[1]; } else if (features->type == DTK) { - input_report_key(input, BTN_0, (data[6] & 0x01)); - input_report_key(input, BTN_1, (data[6] & 0x02)); - input_report_key(input, BTN_2, (data[6] & 0x04)); - input_report_key(input, BTN_3, (data[6] & 0x08)); - input_report_key(input, BTN_4, (data[6] & 0x10)); - input_report_key(input, BTN_5, (data[6] & 0x20)); - if (data[6] & 0x3f) { - input_report_abs(input, ABS_MISC, PAD_DEVICE_ID); - } else { - input_report_abs(input, ABS_MISC, 0); - } + buttons = data[6]; } else if (features->type == WACOM_13HD) { - input_report_key(input, BTN_0, (data[3] & 0x01)); - input_report_key(input, BTN_1, (data[4] & 0x01)); - input_report_key(input, BTN_2, (data[4] & 0x02)); - input_report_key(input, BTN_3, (data[4] & 0x04)); - input_report_key(input, BTN_4, (data[4] & 0x08)); - input_report_key(input, BTN_5, (data[4] & 0x10)); - input_report_key(input, BTN_6, (data[4] & 0x20)); - input_report_key(input, BTN_7, (data[4] & 0x40)); - input_report_key(input, BTN_8, (data[4] & 0x80)); - if ((data[3] & 0x01) | data[4]) { - input_report_abs(input, ABS_MISC, PAD_DEVICE_ID); - } else { - input_report_abs(input, ABS_MISC, 0); - } + buttons = (data[4] << 1) | (data[3] & 0x01); } else if (features->type == WACOM_24HD) { - input_report_key(input, BTN_0, (data[6] & 0x01)); - input_report_key(input, BTN_1, (data[6] & 0x02)); - input_report_key(input, BTN_2, (data[6] & 0x04)); - input_report_key(input, BTN_3, (data[6] & 0x08)); - input_report_key(input, BTN_4, (data[6] & 0x10)); - input_report_key(input, BTN_5, (data[6]
[PATCH 6/7] HID: wacom: Clean up value reading
Make the logic for reading X, Y, distance, and pressure a bit more clear. An additional bit was stuffed into the packet format many models back, and /most/ devices in use will use it. If we happen to be dealing with a particularly old tablet, just shift it off the end to pretend we never read it. Signed-off-by: Jason Gerecke--- drivers/hid/wacom_wac.c | 27 ++- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index ce3afab..0008650 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -887,21 +887,23 @@ static int wacom_intuos_general(struct wacom_wac *wacom) struct input_dev *input = wacom->pen_input; int idx = (features->type == INTUOS) ? (data[1] & 0x01) : 0; unsigned char type = (data[1] >> 1) & 0x0F; - unsigned int t; + unsigned int x, y, distance, t; if (data[0] != WACOM_REPORT_PENABLED && data[0] != WACOM_REPORT_CINTIQ && data[0] != WACOM_REPORT_INTUOS_PEN) return 0; - if (features->type >= INTUOS3S) { - input_report_abs(input, ABS_X, (data[2] << 9) | (data[3] << 1) | ((data[9] >> 1) & 1)); - input_report_abs(input, ABS_Y, (data[4] << 9) | (data[5] << 1) | (data[9] & 1)); - input_report_abs(input, ABS_DISTANCE, ((data[9] >> 2) & 0x3f)); - } else { - input_report_abs(input, ABS_X, be16_to_cpup((__be16 *)[2])); - input_report_abs(input, ABS_Y, be16_to_cpup((__be16 *)[4])); - input_report_abs(input, ABS_DISTANCE, ((data[9] >> 3) & 0x1f)); + x = (be16_to_cpup((__be16 *)[2]) << 1) | ((data[9] >> 1) & 1); + y = (be16_to_cpup((__be16 *)[4]) << 1) | (data[9] & 1); + distance = data[9] >> 2; + if (features->type < INTUOS3S) { + x >>= 1; + y >>= 1; + distance >>= 1; } + input_report_abs(input, ABS_X, x); + input_report_abs(input, ABS_Y, y); + input_report_abs(input, ABS_DISTANCE, distance); switch (type) { case 0x00: @@ -909,10 +911,9 @@ static int wacom_intuos_general(struct wacom_wac *wacom) case 0x02: case 0x03: /* general pen packet */ - t = (data[6] << 2) | ((data[7] >> 6) & 3); - if (features->pressure_max == 2047) { - t = (t << 1) | (data[1] & 1); - } + t = (data[6] << 3) | ((data[7] & 0xC0) >> 5) | (data[1] & 1); + if (features->pressure_max < 2047) + t >>= 1; input_report_abs(input, ABS_PRESSURE, t); if (features->type != INTUOSHT2) { input_report_abs(input, ABS_TILT_X, -- 2.6.2 -- To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 5/7] HID: wacom: Further clean up wacom_intuos_general packet decoder
Continue re-organizing and trimming cases to make it easier to wrap the brain around. A number of changes were made after consulting the protocol spec and so don't necessarily follow from the code itself. Signed-off-by: Jason Gerecke--- drivers/hid/wacom_wac.c | 87 +++-- 1 file changed, 41 insertions(+), 46 deletions(-) diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index a426cb2..ce3afab 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -925,7 +925,6 @@ static int wacom_intuos_general(struct wacom_wac *wacom) break; case 0x0a: - case 0x0b: /* airbrush second packet */ input_report_abs(input, ABS_WHEEL, (data[6] << 2) | ((data[7] >> 6) & 3)); @@ -935,7 +934,6 @@ static int wacom_intuos_general(struct wacom_wac *wacom) break; case 0x05: - case 0x07: /* Rotation packet */ if (features->type >= INTUOS3S) { /* I3 marker pen rotation */ @@ -944,61 +942,56 @@ static int wacom_intuos_general(struct wacom_wac *wacom) ((t-1) / 2 + 450)) : (450 - t / 2) ; input_report_abs(input, ABS_Z, t); } else { - /* 4D mouse rotation packet */ + /* 4D mouse 2nd packet */ t = (data[6] << 3) | ((data[7] >> 5) & 7); input_report_abs(input, ABS_RZ, (data[7] & 0x20) ? ((t - 1) / 2) : -t / 2); } break; - /* 4D mouse, 2D mouse, marker pen rotation, tilt mouse, or Lens cursor packets */ case 0x04: + /* 4D mouse 1st packet */ + input_report_key(input, BTN_LEFT, data[8] & 0x01); + input_report_key(input, BTN_MIDDLE, data[8] & 0x02); + input_report_key(input, BTN_RIGHT, data[8] & 0x04); + + input_report_key(input, BTN_SIDE, data[8] & 0x20); + input_report_key(input, BTN_EXTRA, data[8] & 0x10); + t = (data[6] << 2) | ((data[7] >> 6) & 3); + input_report_abs(input, ABS_THROTTLE, (data[8] & 0x08) ? -t : t); + break; + case 0x06: - case 0x08: - if (features->type < INTUOS3S && type != 0x08) { - /* 4D mouse packet */ - input_report_key(input, BTN_LEFT, data[8] & 0x01); - input_report_key(input, BTN_MIDDLE, data[8] & 0x02); - input_report_key(input, BTN_RIGHT, data[8] & 0x04); + /* I4 mouse */ + input_report_key(input, BTN_LEFT, data[6] & 0x01); + input_report_key(input, BTN_MIDDLE, data[6] & 0x02); + input_report_key(input, BTN_RIGHT, data[6] & 0x04); + input_report_rel(input, REL_WHEEL, ((data[7] & 0x80) >> 7) +- ((data[7] & 0x40) >> 6)); + input_report_key(input, BTN_SIDE, data[6] & 0x08); + input_report_key(input, BTN_EXTRA, data[6] & 0x10); - input_report_key(input, BTN_SIDE, data[8] & 0x20); - input_report_key(input, BTN_EXTRA, data[8] & 0x10); - t = (data[6] << 2) | ((data[7] >> 6) & 3); - input_report_abs(input, ABS_THROTTLE, (data[8] & 0x08) ? -t : t); - } - else if (wacom->tool[idx] == BTN_TOOL_MOUSE) { - /* I4 mouse */ - if (features->type >= INTUOS4S && features->type <= INTUOSPL) { - input_report_key(input, BTN_LEFT, data[6] & 0x01); - input_report_key(input, BTN_MIDDLE, data[6] & 0x02); - input_report_key(input, BTN_RIGHT, data[6] & 0x04); - input_report_rel(input, REL_WHEEL, ((data[7] & 0x80) >> 7) -- ((data[7] & 0x40) >> 6)); - input_report_key(input, BTN_SIDE, data[6] & 0x08); - input_report_key(input, BTN_EXTRA, data[6] & 0x10); - - input_report_abs(input, ABS_TILT_X, - (((data[7] << 1) & 0x7e) | (data[8] >> 7)) - 64); - input_report_abs(input, ABS_TILT_Y, (data[8] & 0x7f) - 64); - } else { - /* 2D mouse packet */ - input_report_key(input, BTN_LEFT, data[8] & 0x04); - input_report_key(input, BTN_MIDDLE, data[8] & 0x08); - input_report_key(input, BTN_RIGHT, data[8] & 0x10); -
[PATCH 3/7] HID: wacom: Centralize Intuos pen packet decoding
Continue to slim down 'wacom_intuos_irq' by moving all decoding and reporting of pen packet data into the 'wacom_intuos_general' function. Signed-off-by: Jason Gerecke--- drivers/hid/wacom_wac.c | 105 +--- 1 file changed, 54 insertions(+), 51 deletions(-) diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index ec1e13e..e395688 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -880,13 +880,28 @@ static int wacom_remote_status_irq(struct wacom_wac *wacom_wac, size_t len) return 0; } -static void wacom_intuos_general(struct wacom_wac *wacom) +static int wacom_intuos_general(struct wacom_wac *wacom) { struct wacom_features *features = >features; unsigned char *data = wacom->data; struct input_dev *input = wacom->pen_input; + int idx = (features->type == INTUOS) ? (data[1] & 0x01) : 0; unsigned int t; + if (data[0] != WACOM_REPORT_PENABLED && data[0] != WACOM_REPORT_CINTIQ && + data[0] != WACOM_REPORT_INTUOS_PEN) + return 0; + + if (features->type >= INTUOS3S) { + input_report_abs(input, ABS_X, (data[2] << 9) | (data[3] << 1) | ((data[9] >> 1) & 1)); + input_report_abs(input, ABS_Y, (data[4] << 9) | (data[5] << 1) | (data[9] & 1)); + input_report_abs(input, ABS_DISTANCE, ((data[9] >> 2) & 0x3f)); + } else { + input_report_abs(input, ABS_X, be16_to_cpup((__be16 *)[2])); + input_report_abs(input, ABS_Y, be16_to_cpup((__be16 *)[4])); + input_report_abs(input, ABS_DISTANCE, ((data[9] >> 3) & 0x1f)); + } + /* general pen packet */ if ((data[1] & 0xb8) == 0xa0) { t = (data[6] << 2) | ((data[7] >> 6) & 3); @@ -912,55 +927,6 @@ static void wacom_intuos_general(struct wacom_wac *wacom) (((data[7] << 1) & 0x7e) | (data[8] >> 7)) - 64); input_report_abs(input, ABS_TILT_Y, (data[8] & 0x7f) - 64); } -} - -static int wacom_intuos_irq(struct wacom_wac *wacom) -{ - struct wacom_features *features = >features; - unsigned char *data = wacom->data; - struct input_dev *input = wacom->pen_input; - unsigned int t; - int idx = 0, result; - - if (data[0] != WACOM_REPORT_PENABLED && - data[0] != WACOM_REPORT_INTUOSREAD && - data[0] != WACOM_REPORT_INTUOSWRITE && - data[0] != WACOM_REPORT_INTUOSPAD && - data[0] != WACOM_REPORT_INTUOS_PEN && - data[0] != WACOM_REPORT_CINTIQ && - data[0] != WACOM_REPORT_CINTIQPAD && - data[0] != WACOM_REPORT_INTUOS5PAD) { - dev_dbg(input->dev.parent, - "%s: received unknown report #%d\n", __func__, data[0]); -return 0; - } - - /* tool number */ - if (features->type == INTUOS) - idx = data[1] & 0x01; - - /* process pad events */ - result = wacom_intuos_pad(wacom); - if (result) - return result; - - /* process in/out prox events */ - result = wacom_intuos_inout(wacom); - if (result) -return result - 1; - - if (features->type >= INTUOS3S) { - input_report_abs(input, ABS_X, (data[2] << 9) | (data[3] << 1) | ((data[9] >> 1) & 1)); - input_report_abs(input, ABS_Y, (data[4] << 9) | (data[5] << 1) | (data[9] & 1)); - input_report_abs(input, ABS_DISTANCE, ((data[9] >> 2) & 0x3f)); - } else { - input_report_abs(input, ABS_X, be16_to_cpup((__be16 *)[2])); - input_report_abs(input, ABS_Y, be16_to_cpup((__be16 *)[4])); - input_report_abs(input, ABS_DISTANCE, ((data[9] >> 3) & 0x1f)); - } - - /* process general packets */ - wacom_intuos_general(wacom); /* 4D mouse, 2D mouse, marker pen rotation, tilt mouse, or Lens cursor packets */ if ((data[1] & 0xbc) == 0xa8 || (data[1] & 0xbe) == 0xb0 || (data[1] & 0xbc) == 0xac) { @@ -1036,7 +1002,44 @@ static int wacom_intuos_irq(struct wacom_wac *wacom) input_report_key(input, wacom->tool[idx], 1); input_event(input, EV_MSC, MSC_SERIAL, wacom->serial[idx]); wacom->reporting_data = true; - return 1; + return 2; +} + +static int wacom_intuos_irq(struct wacom_wac *wacom) +{ + unsigned char *data = wacom->data; + struct input_dev *input = wacom->pen_input; + int result; + + if (data[0] != WACOM_REPORT_PENABLED && + data[0] != WACOM_REPORT_INTUOSREAD && + data[0] != WACOM_REPORT_INTUOSWRITE && + data[0] != WACOM_REPORT_INTUOSPAD && + data[0] != WACOM_REPORT_INTUOS_PEN && + data[0] != WACOM_REPORT_CINTIQ && + data[0] != WACOM_REPORT_CINTIQPAD && + data[0] != WACOM_REPORT_INTUOS5PAD) {
Re: [PATCH 00/10] Input: synaptics-rmi4: Synaptics RMI4 Driver rebased on 4.3
On Thu, Nov 26, 2015 at 1:07 AM, Andrew Dugganwrote: > I tried to include all of the feedback I received from the previous > patches I posted. However, I did not come up with a satisfactory solution > for allowing function drivers to be built as modules. I think it is fine > to allow function drivers to be enabled or disabled in the core at build > time. I am happy with this. If people need something else they can put in the work, I'm just happy to have my hardware working. A large slew of the systems using this will be Androids with tailored kernels anyway, they will all build this in. Yours, Linus Walleij -- To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] Input: aiptek: fix crash on detecting device without endpoints
Hello, Alan, all. > > > > Hmm, I see quite a few drivers assuming that endpoint 0 will be present. > > > > I wonder if that should not be solved at USB level. > > > > > > Every USB device always has endpoint 0. If one didn't, the kernel > > > wouldn't be able to initialize and enumerate it. > > > > Yes for the normal USB device. This case is a weird USB device (with no > > endpoints) specially designed to be weird. My point here is that even a > > weird device probing should not crash a kernel by a NULL-deref. > > True. However, a weird device that didn't have any endpoint 0 would > not crash the kernel, because the kernel wouldn't be able to > communicate with it at all. I'm afraid, I do not get you here. A device in question _does_ crash the kernel (or driver only) as this call trace shows (see attached for the full call trace), and that's why the patch is proposed: [ 622.444650] BUG: unable to handle kernel NULL pointer dereference at 0002 [ 622.445019] IP: [] aiptek_probe+0x463/0x658 [aiptek] [ 622.445019] RIP: 0010:[] aiptek_probe+0x463/0x658 [aiptek] [ 622.445019] RAX: RBX: 88000bd67800 RCX: 88000bcd0800 ^^^ rax is NULL, it is being dereferenced Kernel does not communicates with the device, but the driver tries to access a kernel structure, which was not allocated (thus, a null-deref): endpoint = >altsetting[0].endpoint[0].desc; // the structure endpoint[0] // was not kzalloc()ed, thus NULL usb_rcvintpipe(aiptek->usbdev, endpoint->bEndpointAddress) // NULL deref > > > > Alan, does it make sense to have drivers probe interface if it does not > > > > have any endpoints? > > > > > > Yes; in theory an interface can do everything it needs using only > > > endpoint 0. Driver shouldn't assume anything about the endpoints in > > > the interfaces they problem. > > > > The current kernel code in drivers/usb/core/config.c accepts an interface > > with no endpoints in one of its configurations, and I could not find a > > direct ban for that in USB standard. So, I currently believe, it is a driver > > job to check if the endpoint 0 exist, otherwise we must change the kernel > > USB detection code. > > Drivers do not have to check whether endpoint 0 exists; it always does. > But they do have to check any other endpoint they use. As the above example shows, endpoint 0 does not always exists. A specially crafted weird USB device can advertise absence of endpoint 0 and the kernel will accept this: [drivers/usb/core/config.c] num_ep = num_ep_orig = alt->desc.bNumEndpoints; // weird device can have 0 here alt->desc.bNumEndpoints = 0; if (num_ep > 0) { /* Can't allocate 0 bytes */ len = sizeof(struct usb_host_endpoint) * num_ep; alt->endpoint = kzalloc(len, GFP_KERNEL); As far as I understand, this is a question we discuss here: whose responsibility is to handle situations of endpoint 0 absence in an altconfig? - if it is driver's job, a driver much check this, as in the patch I propose - if it is a kernel job not to allow devices with no endpoint 0 in one the configurations, the current USB device detection implementation (in drivers/usb/core/config.c) should be modified, as currently it allows such. I do not have much expertise in the Linux USB stack, so I'm asking you and the community for an advise on this. > > btw, indeed, this is not the only driver with this problem, I've met 2 more. > > In fact, there's no way to check whether endpoint 0 exists. Where > would you look to find out? There isn't any endpoint descriptor for it. I believe, there is a configuration descriptor for that, probably, I'm wrong: if (intf->altsetting[0].desc.bNumEndpoints < 1) { ... Best regards, Vladis Dronov | Red Hat, Inc. | Product Security Engineer[ 622.149957] usb 1-1: new full-speed USB device number 2 using xhci_hcd [ 622.354485] usb 1-1: config 1 interface 0 altsetting 0 has 3 endpoint descriptors, different from the interface descriptor's value: 0 [ 622.386630] usb 1-1: New USB device found, idVendor=0458, idProduct=5003 [ 622.392414] usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3 [ 622.399416] usb 1-1: Product: Ä [ 622.404640] usb 1-1: Manufacturer: Ä [ 622.410079] usb 1-1: SerialNumber: % [ 622.444650] BUG: unable to handle kernel NULL pointer dereference at 0002 [ 622.445019] IP: [] aiptek_probe+0x463/0x658 [aiptek] [ 622.445019] PGD 0 [ 622.445019] Oops: [#1] SMP [ 622.445019] Modules linked in: aiptek(+) ip6t_rpfilter ip6t_REJECT ipt_REJECT xt_conntrack ebtable_nat ebtable_broute bridge stp llc ebtable_filter ebtables ip6table_nat nf_conntrack_ipv6 nf_defrag_ipv6 nf_nat_ipv6 ip6table_mangle ip6table_security ip6table_raw ip6table_filter ip6_tables iptable_nat nf_conntrack_ipv4 nf_defrag_ipv4 nf_nat_ipv4 nf_nat nf_conntrack iptable_mangle iptable_security iptable_raw iptable_filter ip_tables bochs_drm
[3.16.y-ckt stable] Patch "HID: core: Avoid uninitialized buffer access" has been added to staging queue
This is a note to let you know that I have just added a patch titled HID: core: Avoid uninitialized buffer access to the linux-3.16.y-queue branch of the 3.16.y-ckt extended stable tree which can be found at: http://kernel.ubuntu.com/git/ubuntu/linux.git/log/?h=linux-3.16.y-queue This patch is scheduled to be released in version 3.16.7-ckt21. If you, or anyone else, feels it should not be added to this tree, please reply to this email. For more information about the 3.16.y-ckt tree, see https://wiki.ubuntu.com/Kernel/Dev/ExtendedStable Thanks. -Luis -- >From 2cbc310d70eb6aeb2c8289291f939e612ea5a830 Mon Sep 17 00:00:00 2001 From: Richard PurdieDate: Fri, 18 Sep 2015 16:31:33 -0700 Subject: HID: core: Avoid uninitialized buffer access commit 79b568b9d0c7c5d81932f4486d50b38efdd6da6d upstream. hid_connect adds various strings to the buffer but they're all conditional. You can find circumstances where nothing would be written to it but the kernel will still print the supposedly empty buffer with printk. This leads to corruption on the console/in the logs. Ensure buf is initialized to an empty string. Signed-off-by: Richard Purdie [dvhart: Initialize string to "" rather than assign buf[0] = NULL;] Cc: Jiri Kosina Cc: linux-input@vger.kernel.org Signed-off-by: Darren Hart Signed-off-by: Jiri Kosina Signed-off-by: Luis Henriques --- drivers/hid/hid-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 5ed3a7b91b4c..fb16c812816a 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1561,7 +1561,7 @@ int hid_connect(struct hid_device *hdev, unsigned int connect_mask) "Multi-Axis Controller" }; const char *type, *bus; - char buf[64]; + char buf[64] = ""; unsigned int i; int len; int ret; -- To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/2] HID: hid-logitech: Add support for G29
Simon et al, My logitech cordless mouse is not detected in linux-next I have bisected the breakage to this patch, commit 29fae1c85166ef525b8b6518e749295e0c9d1e20 in linux-next. On Monday, November 02, 2015 07:56:52 AM Simon Wood wrote: > At present the G29 is mis-identified as a DFGT, this patch ensures > that the wheel is correctly detected and allows setting the LEDs and > turning range via the '/sys' interface. > > This wheel can also emulate other types of Logitech wheels. > > Signed-off-by: Simon Wood> --- > drivers/hid/hid-core.c | 1 + > drivers/hid/hid-lg.c| 9 > drivers/hid/hid-lg4ff.c | 57 > + > 3 files changed, 63 insertions(+), 4 deletions(-) > > diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c > index 70a11ac..949d804 100644 > --- a/drivers/hid/hid-core.c > +++ b/drivers/hid/hid-core.c > @@ -1896,6 +1896,7 @@ static const struct hid_device_id > hid_have_special_driver[] = { > { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, > USB_DEVICE_ID_LOGITECH_RUMBLEPAD_CORD) }, > { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, > USB_DEVICE_ID_LOGITECH_RUMBLEPAD) }, > { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, > USB_DEVICE_ID_LOGITECH_RUMBLEPAD2_2) }, > + { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, > USB_DEVICE_ID_LOGITECH_G29_WHEEL) }, > { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, > USB_DEVICE_ID_LOGITECH_WINGMAN_F3D) }, > { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, > USB_DEVICE_ID_LOGITECH_WINGMAN_FFG ) }, > { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, > USB_DEVICE_ID_LOGITECH_FORCE3D_PRO) }, > diff --git a/drivers/hid/hid-lg.c b/drivers/hid/hid-lg.c > index 5332fb7..c20ac76 100644 > --- a/drivers/hid/hid-lg.c > +++ b/drivers/hid/hid-lg.c > @@ -620,6 +620,7 @@ static int lg_input_mapped(struct hid_device *hdev, > struct hid_input *hi, > usage->code == ABS_Y || usage->code == ABS_Z || > usage->code == ABS_RZ)) { > switch (hdev->product) { > + case USB_DEVICE_ID_LOGITECH_G29_WHEEL: > case USB_DEVICE_ID_LOGITECH_WHEEL: > case USB_DEVICE_ID_LOGITECH_MOMO_WHEEL: > case USB_DEVICE_ID_LOGITECH_DFP_WHEEL: > @@ -658,10 +659,18 @@ static int lg_event(struct hid_device *hdev, struct > hid_field *field, > > static int lg_probe(struct hid_device *hdev, const struct hid_device_id *id) > { > + struct usb_interface *iface = to_usb_interface(hdev->dev.parent); > + __u8 iface_num = iface->cur_altsetting->desc.bInterfaceNumber; > unsigned int connect_mask = HID_CONNECT_DEFAULT; > struct lg_drv_data *drv_data; > int ret; > > + /* Only work with the 1st interface (G29 presents multiple) */ > + if (iface_num != 0) { > + dbg_hid("%s: ignoring ifnum %d\n", __func__, iface_num); > + return -ENODEV; > + } > + > drv_data = kzalloc(sizeof(struct lg_drv_data), GFP_KERNEL); > if (!drv_data) { > hid_err(hdev, "Insufficient memory, cannot allocate driver > data\n"); > diff --git a/drivers/hid/hid-lg4ff.c b/drivers/hid/hid-lg4ff.c > index b363d88..fbddcb3 100644 > --- a/drivers/hid/hid-lg4ff.c > +++ b/drivers/hid/hid-lg4ff.c > @@ -45,7 +45,8 @@ > #define LG4FF_MODE_G25_IDX 3 > #define LG4FF_MODE_DFGT_IDX 4 > #define LG4FF_MODE_G27_IDX 5 > -#define LG4FF_MODE_MAX_IDX 6 > +#define LG4FF_MODE_G29_IDX 6 > +#define LG4FF_MODE_MAX_IDX 7 > > #define LG4FF_MODE_NATIVE BIT(LG4FF_MODE_NATIVE_IDX) > #define LG4FF_MODE_DFEX BIT(LG4FF_MODE_DFEX_IDX) > @@ -53,6 +54,7 @@ > #define LG4FF_MODE_G25 BIT(LG4FF_MODE_G25_IDX) > #define LG4FF_MODE_DFGT BIT(LG4FF_MODE_DFGT_IDX) > #define LG4FF_MODE_G27 BIT(LG4FF_MODE_G27_IDX) > +#define LG4FF_MODE_G29 BIT(LG4FF_MODE_G29_IDX) > > #define LG4FF_DFEX_TAG "DF-EX" > #define LG4FF_DFEX_NAME "Driving Force / Formula EX" > @@ -62,6 +64,8 @@ > #define LG4FF_G25_NAME "G25 Racing Wheel" > #define LG4FF_G27_TAG "G27" > #define LG4FF_G27_NAME "G27 Racing Wheel" > +#define LG4FF_G29_TAG "G29" > +#define LG4FF_G29_NAME "G29 Racing Wheel" > #define LG4FF_DFGT_TAG "DFGT" > #define LG4FF_DFGT_NAME "Driving Force GT" > > @@ -140,6 +144,7 @@ static const struct lg4ff_wheel lg4ff_devices[] = { > {USB_DEVICE_ID_LOGITECH_G25_WHEEL, lg4ff_wheel_effects, 40, 900, > lg4ff_set_range_g25}, > {USB_DEVICE_ID_LOGITECH_DFGT_WHEEL, lg4ff_wheel_effects, 40, 900, > lg4ff_set_range_g25}, > {USB_DEVICE_ID_LOGITECH_G27_WHEEL, lg4ff_wheel_effects, 40, 900, > lg4ff_set_range_g25}, > + {USB_DEVICE_ID_LOGITECH_G29_WHEEL, lg4ff_wheel_effects, 40, 900, > lg4ff_set_range_g25}, > {USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2, lg4ff_wheel_effects, 40, 270, > NULL}, > {USB_DEVICE_ID_LOGITECH_WII_WHEEL, lg4ff_wheel_effects, 40, 270, NULL} > }; > @@ -157,6 +162,9 @@ static const struct lg4ff_multimode_wheel > lg4ff_multimode_wheels[] = { >
Re: [PATCH 2/2] HID: hid-logitech: Add support for G29
Hi all, my completely off-the-bat guess would be that the combo uses multiple interfaces as well, the patch seems to ignore everything but iface 0. Can you comment out the 'if' that does this and give it a go? Michal On Mon Nov 30 14:03:51 2015 GMT+0100, Joshua Clayton wrote: > Simon et al, > My logitech cordless mouse is not detected in linux-next > I have bisected the breakage to this patch, > commit 29fae1c85166ef525b8b6518e749295e0c9d1e20 in linux-next. > > On Monday, November 02, 2015 07:56:52 AM Simon Wood wrote: > > At present the G29 is mis-identified as a DFGT, this patch ensures > > that the wheel is correctly detected and allows setting the LEDs and > > turning range via the '/sys' interface. > > > > This wheel can also emulate other types of Logitech wheels. > > > > Signed-off-by: Simon Wood> > --- > > drivers/hid/hid-core.c | 1 + > > drivers/hid/hid-lg.c| 9 > > drivers/hid/hid-lg4ff.c | 57 > > + > > 3 files changed, 63 insertions(+), 4 deletions(-) > > > > diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c > > index 70a11ac..949d804 100644 > > --- a/drivers/hid/hid-core.c > > +++ b/drivers/hid/hid-core.c > > @@ -1896,6 +1896,7 @@ static const struct hid_device_id > > hid_have_special_driver[] = { > > { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, > > USB_DEVICE_ID_LOGITECH_RUMBLEPAD_CORD) }, > > { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, > > USB_DEVICE_ID_LOGITECH_RUMBLEPAD) }, > > { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, > > USB_DEVICE_ID_LOGITECH_RUMBLEPAD2_2) }, > > + { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, > > USB_DEVICE_ID_LOGITECH_G29_WHEEL) }, > > { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, > > USB_DEVICE_ID_LOGITECH_WINGMAN_F3D) }, > > { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, > > USB_DEVICE_ID_LOGITECH_WINGMAN_FFG ) }, > > { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, > > USB_DEVICE_ID_LOGITECH_FORCE3D_PRO) }, > > diff --git a/drivers/hid/hid-lg.c b/drivers/hid/hid-lg.c > > index 5332fb7..c20ac76 100644 > > --- a/drivers/hid/hid-lg.c > > +++ b/drivers/hid/hid-lg.c > > @@ -620,6 +620,7 @@ static int lg_input_mapped(struct hid_device *hdev, > > struct hid_input *hi, > > usage->code == ABS_Y || usage->code == ABS_Z || > > usage->code == ABS_RZ)) { > > switch (hdev->product) { > > + case USB_DEVICE_ID_LOGITECH_G29_WHEEL: > > case USB_DEVICE_ID_LOGITECH_WHEEL: > > case USB_DEVICE_ID_LOGITECH_MOMO_WHEEL: > > case USB_DEVICE_ID_LOGITECH_DFP_WHEEL: > > @@ -658,10 +659,18 @@ static int lg_event(struct hid_device *hdev, struct > > hid_field *field, > > > > static int lg_probe(struct hid_device *hdev, const struct hid_device_id > > *id) > > { > > + struct usb_interface *iface = to_usb_interface(hdev->dev.parent); > > + __u8 iface_num = iface->cur_altsetting->desc.bInterfaceNumber; > > unsigned int connect_mask = HID_CONNECT_DEFAULT; > > struct lg_drv_data *drv_data; > > int ret; > > > > + /* Only work with the 1st interface (G29 presents multiple) */ > > + if (iface_num != 0) { > > + dbg_hid("%s: ignoring ifnum %d\n", __func__, iface_num); > > + return -ENODEV; > > + } > > + > > drv_data = kzalloc(sizeof(struct lg_drv_data), GFP_KERNEL); > > if (!drv_data) { > > hid_err(hdev, "Insufficient memory, cannot allocate driver > > data\n"); > > diff --git a/drivers/hid/hid-lg4ff.c b/drivers/hid/hid-lg4ff.c > > index b363d88..fbddcb3 100644 > > --- a/drivers/hid/hid-lg4ff.c > > +++ b/drivers/hid/hid-lg4ff.c > > @@ -45,7 +45,8 @@ > > #define LG4FF_MODE_G25_IDX 3 > > #define LG4FF_MODE_DFGT_IDX 4 > > #define LG4FF_MODE_G27_IDX 5 > > -#define LG4FF_MODE_MAX_IDX 6 > > +#define LG4FF_MODE_G29_IDX 6 > > +#define LG4FF_MODE_MAX_IDX 7 > > > > #define LG4FF_MODE_NATIVE BIT(LG4FF_MODE_NATIVE_IDX) > > #define LG4FF_MODE_DFEX BIT(LG4FF_MODE_DFEX_IDX) > > @@ -53,6 +54,7 @@ > > #define LG4FF_MODE_G25 BIT(LG4FF_MODE_G25_IDX) > > #define LG4FF_MODE_DFGT BIT(LG4FF_MODE_DFGT_IDX) > > #define LG4FF_MODE_G27 BIT(LG4FF_MODE_G27_IDX) > > +#define LG4FF_MODE_G29 BIT(LG4FF_MODE_G29_IDX) > > > > #define LG4FF_DFEX_TAG "DF-EX" > > #define LG4FF_DFEX_NAME "Driving Force / Formula EX" > > @@ -62,6 +64,8 @@ > > #define LG4FF_G25_NAME "G25 Racing Wheel" > > #define LG4FF_G27_TAG "G27" > > #define LG4FF_G27_NAME "G27 Racing Wheel" > > +#define LG4FF_G29_TAG "G29" > > +#define LG4FF_G29_NAME "G29 Racing Wheel" > > #define LG4FF_DFGT_TAG "DFGT" > > #define LG4FF_DFGT_NAME "Driving Force GT" > > > > @@ -140,6 +144,7 @@ static const struct lg4ff_wheel lg4ff_devices[] = { > > {USB_DEVICE_ID_LOGITECH_G25_WHEEL, lg4ff_wheel_effects, 40, 900, > > lg4ff_set_range_g25}, > > {USB_DEVICE_ID_LOGITECH_DFGT_WHEEL, lg4ff_wheel_effects, 40, 900, > > lg4ff_set_range_g25}, > > {USB_DEVICE_ID_LOGITECH_G27_WHEEL,