Skip to content

Commit d0c22de

Browse files
committed
Merge tag 'input-for-v6.15-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
Pull input fixes from Dmitry Torokhov: - even more Xbox controllers added to xpad driver: Turtle Beach Recon Wired Controller, Turtle Beach Stealth Ultra, and PowerA Wired Controller - a fix to Synaptics RMI driver to not crash if controller reports unsupported version of F34 (firmware flash) function * tag 'input-for-v6.15-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input: Input: synaptics-rmi - fix crash with unsupported versions of F34 Input: xpad - add more controllers
2 parents 95a9580 + ca39500 commit d0c22de

File tree

2 files changed

+79
-59
lines changed

2 files changed

+79
-59
lines changed

drivers/input/joystick/xpad.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,8 @@ static const struct xpad_device {
290290
{ 0x1038, 0x1430, "SteelSeries Stratus Duo", 0, XTYPE_XBOX360 },
291291
{ 0x1038, 0x1431, "SteelSeries Stratus Duo", 0, XTYPE_XBOX360 },
292292
{ 0x10f5, 0x7005, "Turtle Beach Recon Controller", 0, XTYPE_XBOXONE },
293+
{ 0x10f5, 0x7008, "Turtle Beach Recon Controller", MAP_SHARE_BUTTON, XTYPE_XBOXONE },
294+
{ 0x10f5, 0x7073, "Turtle Beach Stealth Ultra Controller", MAP_SHARE_BUTTON, XTYPE_XBOXONE },
293295
{ 0x11c9, 0x55f0, "Nacon GC-100XF", 0, XTYPE_XBOX360 },
294296
{ 0x11ff, 0x0511, "PXN V900", 0, XTYPE_XBOX360 },
295297
{ 0x1209, 0x2882, "Ardwiino Controller", 0, XTYPE_XBOX360 },
@@ -354,6 +356,7 @@ static const struct xpad_device {
354356
{ 0x1ee9, 0x1590, "ZOTAC Gaming Zone", 0, XTYPE_XBOX360 },
355357
{ 0x20d6, 0x2001, "BDA Xbox Series X Wired Controller", 0, XTYPE_XBOXONE },
356358
{ 0x20d6, 0x2009, "PowerA Enhanced Wired Controller for Xbox Series X|S", 0, XTYPE_XBOXONE },
359+
{ 0x20d6, 0x2064, "PowerA Wired Controller for Xbox", MAP_SHARE_BUTTON, XTYPE_XBOXONE },
357360
{ 0x20d6, 0x281f, "PowerA Wired Controller For Xbox 360", 0, XTYPE_XBOX360 },
358361
{ 0x20d6, 0x400b, "PowerA FUSION Pro 4 Wired Controller", MAP_SHARE_BUTTON, XTYPE_XBOXONE },
359362
{ 0x20d6, 0x890b, "PowerA MOGA XP-Ultra Controller", MAP_SHARE_BUTTON, XTYPE_XBOXONE },

drivers/input/rmi4/rmi_f34.c

Lines changed: 76 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
* Copyright (C) 2016 Zodiac Inflight Innovations
55
*/
66

7+
#include "linux/device.h"
78
#include <linux/kernel.h>
89
#include <linux/rmi.h>
910
#include <linux/firmware.h>
@@ -289,39 +290,30 @@ static int rmi_f34_update_firmware(struct f34_data *f34,
289290
return rmi_f34_flash_firmware(f34, syn_fw);
290291
}
291292

292-
static int rmi_f34_status(struct rmi_function *fn)
293-
{
294-
struct f34_data *f34 = dev_get_drvdata(&fn->dev);
295-
296-
/*
297-
* The status is the percentage complete, or once complete,
298-
* zero for success or a negative return code.
299-
*/
300-
return f34->update_status;
301-
}
302-
303293
static ssize_t rmi_driver_bootloader_id_show(struct device *dev,
304294
struct device_attribute *dattr,
305295
char *buf)
306296
{
307297
struct rmi_driver_data *data = dev_get_drvdata(dev);
308-
struct rmi_function *fn = data->f34_container;
298+
struct rmi_function *fn;
309299
struct f34_data *f34;
310300

311-
if (fn) {
312-
f34 = dev_get_drvdata(&fn->dev);
313-
314-
if (f34->bl_version == 5)
315-
return sysfs_emit(buf, "%c%c\n",
316-
f34->bootloader_id[0],
317-
f34->bootloader_id[1]);
318-
else
319-
return sysfs_emit(buf, "V%d.%d\n",
320-
f34->bootloader_id[1],
321-
f34->bootloader_id[0]);
322-
}
301+
fn = data->f34_container;
302+
if (!fn)
303+
return -ENODEV;
323304

324-
return 0;
305+
f34 = dev_get_drvdata(&fn->dev);
306+
if (!f34)
307+
return -ENODEV;
308+
309+
if (f34->bl_version == 5)
310+
return sysfs_emit(buf, "%c%c\n",
311+
f34->bootloader_id[0],
312+
f34->bootloader_id[1]);
313+
else
314+
return sysfs_emit(buf, "V%d.%d\n",
315+
f34->bootloader_id[1],
316+
f34->bootloader_id[0]);
325317
}
326318

327319
static DEVICE_ATTR(bootloader_id, 0444, rmi_driver_bootloader_id_show, NULL);
@@ -334,13 +326,16 @@ static ssize_t rmi_driver_configuration_id_show(struct device *dev,
334326
struct rmi_function *fn = data->f34_container;
335327
struct f34_data *f34;
336328

337-
if (fn) {
338-
f34 = dev_get_drvdata(&fn->dev);
329+
fn = data->f34_container;
330+
if (!fn)
331+
return -ENODEV;
332+
333+
f34 = dev_get_drvdata(&fn->dev);
334+
if (!f34)
335+
return -ENODEV;
339336

340-
return sysfs_emit(buf, "%s\n", f34->configuration_id);
341-
}
342337

343-
return 0;
338+
return sysfs_emit(buf, "%s\n", f34->configuration_id);
344339
}
345340

346341
static DEVICE_ATTR(configuration_id, 0444,
@@ -356,10 +351,14 @@ static int rmi_firmware_update(struct rmi_driver_data *data,
356351

357352
if (!data->f34_container) {
358353
dev_warn(dev, "%s: No F34 present!\n", __func__);
359-
return -EINVAL;
354+
return -ENODEV;
360355
}
361356

362357
f34 = dev_get_drvdata(&data->f34_container->dev);
358+
if (!f34) {
359+
dev_warn(dev, "%s: No valid F34 present!\n", __func__);
360+
return -ENODEV;
361+
}
363362

364363
if (f34->bl_version >= 7) {
365364
if (data->pdt_props & HAS_BSR) {
@@ -485,10 +484,18 @@ static ssize_t rmi_driver_update_fw_status_show(struct device *dev,
485484
char *buf)
486485
{
487486
struct rmi_driver_data *data = dev_get_drvdata(dev);
488-
int update_status = 0;
487+
struct f34_data *f34;
488+
int update_status = -ENODEV;
489489

490-
if (data->f34_container)
491-
update_status = rmi_f34_status(data->f34_container);
490+
/*
491+
* The status is the percentage complete, or once complete,
492+
* zero for success or a negative return code.
493+
*/
494+
if (data->f34_container) {
495+
f34 = dev_get_drvdata(&data->f34_container->dev);
496+
if (f34)
497+
update_status = f34->update_status;
498+
}
492499

493500
return sysfs_emit(buf, "%d\n", update_status);
494501
}
@@ -508,33 +515,21 @@ static const struct attribute_group rmi_firmware_attr_group = {
508515
.attrs = rmi_firmware_attrs,
509516
};
510517

511-
static int rmi_f34_probe(struct rmi_function *fn)
518+
static int rmi_f34v5_probe(struct f34_data *f34)
512519
{
513-
struct f34_data *f34;
514-
unsigned char f34_queries[9];
520+
struct rmi_function *fn = f34->fn;
521+
u8 f34_queries[9];
515522
bool has_config_id;
516-
u8 version = fn->fd.function_version;
517-
int ret;
518-
519-
f34 = devm_kzalloc(&fn->dev, sizeof(struct f34_data), GFP_KERNEL);
520-
if (!f34)
521-
return -ENOMEM;
522-
523-
f34->fn = fn;
524-
dev_set_drvdata(&fn->dev, f34);
525-
526-
/* v5 code only supported version 0, try V7 probe */
527-
if (version > 0)
528-
return rmi_f34v7_probe(f34);
523+
int error;
529524

530525
f34->bl_version = 5;
531526

532-
ret = rmi_read_block(fn->rmi_dev, fn->fd.query_base_addr,
533-
f34_queries, sizeof(f34_queries));
534-
if (ret) {
527+
error = rmi_read_block(fn->rmi_dev, fn->fd.query_base_addr,
528+
f34_queries, sizeof(f34_queries));
529+
if (error) {
535530
dev_err(&fn->dev, "%s: Failed to query properties\n",
536531
__func__);
537-
return ret;
532+
return error;
538533
}
539534

540535
snprintf(f34->bootloader_id, sizeof(f34->bootloader_id),
@@ -560,11 +555,11 @@ static int rmi_f34_probe(struct rmi_function *fn)
560555
f34->v5.config_blocks);
561556

562557
if (has_config_id) {
563-
ret = rmi_read_block(fn->rmi_dev, fn->fd.control_base_addr,
564-
f34_queries, sizeof(f34_queries));
565-
if (ret) {
558+
error = rmi_read_block(fn->rmi_dev, fn->fd.control_base_addr,
559+
f34_queries, sizeof(f34_queries));
560+
if (error) {
566561
dev_err(&fn->dev, "Failed to read F34 config ID\n");
567-
return ret;
562+
return error;
568563
}
569564

570565
snprintf(f34->configuration_id, sizeof(f34->configuration_id),
@@ -573,12 +568,34 @@ static int rmi_f34_probe(struct rmi_function *fn)
573568
f34_queries[2], f34_queries[3]);
574569

575570
rmi_dbg(RMI_DEBUG_FN, &fn->dev, "Configuration ID: %s\n",
576-
f34->configuration_id);
571+
f34->configuration_id);
577572
}
578573

579574
return 0;
580575
}
581576

577+
static int rmi_f34_probe(struct rmi_function *fn)
578+
{
579+
struct f34_data *f34;
580+
u8 version = fn->fd.function_version;
581+
int error;
582+
583+
f34 = devm_kzalloc(&fn->dev, sizeof(struct f34_data), GFP_KERNEL);
584+
if (!f34)
585+
return -ENOMEM;
586+
587+
f34->fn = fn;
588+
589+
/* v5 code only supported version 0 */
590+
error = version == 0 ? rmi_f34v5_probe(f34) : rmi_f34v7_probe(f34);
591+
if (error)
592+
return error;
593+
594+
dev_set_drvdata(&fn->dev, f34);
595+
596+
return 0;
597+
}
598+
582599
int rmi_f34_create_sysfs(struct rmi_device *rmi_dev)
583600
{
584601
return sysfs_create_group(&rmi_dev->dev.kobj, &rmi_firmware_attr_group);

0 commit comments

Comments
 (0)