1
0
Fork 0
mirror of synced 2025-03-06 20:59:54 +01:00

hid-for-linus-2025030501

-----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCAAdFiEEL65usyKPHcrRDEicpmLzj2vtYEkFAmfIU/YACgkQpmLzj2vt
 YElabBAApth4hmsxhJSlClPw5py3rK2vFnPBj4wtxbClar8vzV6c/DUqdGIZe1+I
 FvNvS+G3fyA5XvwU8cTwObjtj0nIiYhFxpcpJ6taIZtzoru/UqkLjbNTE9gX2QAL
 yPrHQv6KIM5u99hMVYabZkjI4NoI0pQXcdTJrb1hInwcV6WTjzGIGnZ31NKda3nw
 PwKebdqK4wEUG6Ctp9f4TN2qpiNlJJHAsrbQjusRG4eaNTRHFUxqfg2xek8DCT3w
 ABV/oI/XmR1Fptx8KbGo5RW2Ird9CpnfA1VAPu1SYq7foztpnxGzoOdolh1bqxGl
 30U8+r2y9cQSg1B00EbBcXh4+Ncg8KeoX0skES8mBI+js5uskvhq7n07h06MnTRA
 2skf9BUsF3+zG+OtxhS8dqvN/MupW89hTmpfT7yOi2JSgoDLyNZXHaeBXhjil2Im
 KFgYdYxv9oM95nsuQtqJTHQfHjay3UPFchG3HcCmzwiQLq+wKPb/25Mh0FvNT65z
 yIB3jqpPgckhylCsUitrZHgXhtX9v1roa9360nbkn0NShDJRXnMP2pWnjd6WKUBz
 fFwTdtDMLHIv6EMADmLuefIp/LT11EAgOMIDzOfZqdXPmvgfkWPoq1W8xV/85ug2
 fbdNbs5fGxsW9/PxZkbC4e/iEOswWiDKFl7yHVlEsN3KDd6wWjs=
 =B3rd
 -----END PGP SIGNATURE-----

Merge tag 'hid-for-linus-2025030501' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid

Pull HID fixes from Jiri Kosina:

 - power management fix in intel-thc-hid (Even Xu)

 - nintendo gencon mapping fix (Ryan McClelland)

 - fix for UAF on device diconnect path in hid-steam (Vicki Pfau)

 - two fixes for UAF on device disconnect path in intel-ish-hid (Zhang
   Lixu)

 - fix for potential NULL dereference in hid-appleir (Daniil Dulov)

 - few other small cosmetic fixes (e.g. typos)

* tag 'hid-for-linus-2025030501' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid:
  HID: Intel-thc-hid: Intel-quickspi: Correct device state after S4
  HID: intel-thc-hid: Fix spelling mistake "intput" -> "input"
  HID: hid-steam: Fix use-after-free when detaching device
  HID: debug: Fix spelling mistake "Messanger" -> "Messenger"
  HID: appleir: Fix potential NULL dereference at raw event handle
  HID: apple: disable Fn key handling on the Omoton KB066
  HID: i2c-hid: improve i2c_hid_get_report error message
  HID: intel-ish-hid: Fix use-after-free issue in ishtp_hid_remove()
  HID: intel-ish-hid: Fix use-after-free issue in hid_ishtp_cl_remove()
  HID: google: fix unused variable warning under !CONFIG_ACPI
  HID: nintendo: fix gencon button events map
  HID: corsair-void: Update power supply values with a unified work handler
This commit is contained in:
Linus Torvalds 2025-03-05 07:46:59 -10:00
commit 848e076317
12 changed files with 70 additions and 58 deletions

View file

@ -378,6 +378,12 @@ static bool apple_is_non_apple_keyboard(struct hid_device *hdev)
return false;
}
static bool apple_is_omoton_kb066(struct hid_device *hdev)
{
return hdev->product == USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI &&
strcmp(hdev->name, "Bluetooth Keyboard") == 0;
}
static inline void apple_setup_key_translation(struct input_dev *input,
const struct apple_key_translation *table)
{
@ -546,9 +552,6 @@ static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input,
}
}
if (usage->hid == 0xc0301) /* Omoton KB066 quirk */
code = KEY_F6;
if (usage->code != code) {
input_event_with_scancode(input, usage->type, code, usage->hid, value);
@ -728,7 +731,7 @@ static int apple_input_configured(struct hid_device *hdev,
{
struct apple_sc *asc = hid_get_drvdata(hdev);
if ((asc->quirks & APPLE_HAS_FN) && !asc->fn_found) {
if (((asc->quirks & APPLE_HAS_FN) && !asc->fn_found) || apple_is_omoton_kb066(hdev)) {
hid_info(hdev, "Fn key not found (Apple Wireless Keyboard clone?), disabling Fn key handling\n");
asc->quirks &= ~APPLE_HAS_FN;
}

View file

@ -188,7 +188,7 @@ static int appleir_raw_event(struct hid_device *hid, struct hid_report *report,
static const u8 flatbattery[] = { 0x25, 0x87, 0xe0 };
unsigned long flags;
if (len != 5)
if (len != 5 || !(hid->claimed & HID_CLAIMED_INPUT))
goto out;
if (!memcmp(data, keydown, sizeof(keydown))) {

View file

@ -71,11 +71,9 @@
#include <linux/bitfield.h>
#include <linux/bitops.h>
#include <linux/cleanup.h>
#include <linux/device.h>
#include <linux/hid.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/power_supply.h>
#include <linux/usb.h>
#include <linux/workqueue.h>
@ -120,6 +118,12 @@ enum {
CORSAIR_VOID_BATTERY_CHARGING = 5,
};
enum {
CORSAIR_VOID_ADD_BATTERY = 0,
CORSAIR_VOID_REMOVE_BATTERY = 1,
CORSAIR_VOID_UPDATE_BATTERY = 2,
};
static enum power_supply_property corsair_void_battery_props[] = {
POWER_SUPPLY_PROP_STATUS,
POWER_SUPPLY_PROP_PRESENT,
@ -155,12 +159,12 @@ struct corsair_void_drvdata {
struct power_supply *battery;
struct power_supply_desc battery_desc;
struct mutex battery_mutex;
struct delayed_work delayed_status_work;
struct delayed_work delayed_firmware_work;
struct work_struct battery_remove_work;
struct work_struct battery_add_work;
unsigned long battery_work_flags;
struct work_struct battery_work;
};
/*
@ -260,11 +264,9 @@ success:
/* Inform power supply if battery values changed */
if (memcmp(&orig_battery_data, battery_data, sizeof(*battery_data))) {
scoped_guard(mutex, &drvdata->battery_mutex) {
if (drvdata->battery) {
power_supply_changed(drvdata->battery);
}
}
set_bit(CORSAIR_VOID_UPDATE_BATTERY,
&drvdata->battery_work_flags);
schedule_work(&drvdata->battery_work);
}
}
@ -536,29 +538,11 @@ static void corsair_void_firmware_work_handler(struct work_struct *work)
}
static void corsair_void_battery_remove_work_handler(struct work_struct *work)
static void corsair_void_add_battery(struct corsair_void_drvdata *drvdata)
{
struct corsair_void_drvdata *drvdata;
drvdata = container_of(work, struct corsair_void_drvdata,
battery_remove_work);
scoped_guard(mutex, &drvdata->battery_mutex) {
if (drvdata->battery) {
power_supply_unregister(drvdata->battery);
drvdata->battery = NULL;
}
}
}
static void corsair_void_battery_add_work_handler(struct work_struct *work)
{
struct corsair_void_drvdata *drvdata;
struct power_supply_config psy_cfg = {};
struct power_supply *new_supply;
drvdata = container_of(work, struct corsair_void_drvdata,
battery_add_work);
guard(mutex)(&drvdata->battery_mutex);
if (drvdata->battery)
return;
@ -583,16 +567,42 @@ static void corsair_void_battery_add_work_handler(struct work_struct *work)
drvdata->battery = new_supply;
}
static void corsair_void_battery_work_handler(struct work_struct *work)
{
struct corsair_void_drvdata *drvdata = container_of(work,
struct corsair_void_drvdata, battery_work);
bool add_battery = test_and_clear_bit(CORSAIR_VOID_ADD_BATTERY,
&drvdata->battery_work_flags);
bool remove_battery = test_and_clear_bit(CORSAIR_VOID_REMOVE_BATTERY,
&drvdata->battery_work_flags);
bool update_battery = test_and_clear_bit(CORSAIR_VOID_UPDATE_BATTERY,
&drvdata->battery_work_flags);
if (add_battery && !remove_battery) {
corsair_void_add_battery(drvdata);
} else if (remove_battery && !add_battery && drvdata->battery) {
power_supply_unregister(drvdata->battery);
drvdata->battery = NULL;
}
if (update_battery && drvdata->battery)
power_supply_changed(drvdata->battery);
}
static void corsair_void_headset_connected(struct corsair_void_drvdata *drvdata)
{
schedule_work(&drvdata->battery_add_work);
set_bit(CORSAIR_VOID_ADD_BATTERY, &drvdata->battery_work_flags);
schedule_work(&drvdata->battery_work);
schedule_delayed_work(&drvdata->delayed_firmware_work,
msecs_to_jiffies(100));
}
static void corsair_void_headset_disconnected(struct corsair_void_drvdata *drvdata)
{
schedule_work(&drvdata->battery_remove_work);
set_bit(CORSAIR_VOID_REMOVE_BATTERY, &drvdata->battery_work_flags);
schedule_work(&drvdata->battery_work);
corsair_void_set_unknown_wireless_data(drvdata);
corsair_void_set_unknown_batt(drvdata);
@ -678,13 +688,7 @@ static int corsair_void_probe(struct hid_device *hid_dev,
drvdata->battery_desc.get_property = corsair_void_battery_get_property;
drvdata->battery = NULL;
INIT_WORK(&drvdata->battery_remove_work,
corsair_void_battery_remove_work_handler);
INIT_WORK(&drvdata->battery_add_work,
corsair_void_battery_add_work_handler);
ret = devm_mutex_init(drvdata->dev, &drvdata->battery_mutex);
if (ret)
return ret;
INIT_WORK(&drvdata->battery_work, corsair_void_battery_work_handler);
ret = sysfs_create_group(&hid_dev->dev.kobj, &corsair_void_attr_group);
if (ret)
@ -721,8 +725,7 @@ static void corsair_void_remove(struct hid_device *hid_dev)
struct corsair_void_drvdata *drvdata = hid_get_drvdata(hid_dev);
hid_hw_stop(hid_dev);
cancel_work_sync(&drvdata->battery_remove_work);
cancel_work_sync(&drvdata->battery_add_work);
cancel_work_sync(&drvdata->battery_work);
if (drvdata->battery)
power_supply_unregister(drvdata->battery);

View file

@ -3450,7 +3450,7 @@ static const char *keys[KEY_MAX + 1] = {
[KEY_MACRO_RECORD_START] = "MacroRecordStart",
[KEY_MACRO_RECORD_STOP] = "MacroRecordStop",
[KEY_MARK_WAYPOINT] = "MarkWayPoint", [KEY_MEDIA_REPEAT] = "MediaRepeat",
[KEY_MEDIA_TOP_MENU] = "MediaTopMenu", [KEY_MESSENGER] = "Messanger",
[KEY_MEDIA_TOP_MENU] = "MediaTopMenu", [KEY_MESSENGER] = "Messenger",
[KEY_NAV_CHART] = "NavChar", [KEY_NAV_INFO] = "NavInfo",
[KEY_NEWS] = "News", [KEY_NEXT_ELEMENT] = "NextElement",
[KEY_NEXT_FAVORITE] = "NextFavorite", [KEY_NOTIFICATION_CENTER] = "NotificationCenter",

View file

@ -268,11 +268,13 @@ static void cbas_ec_remove(struct platform_device *pdev)
mutex_unlock(&cbas_ec_reglock);
}
#ifdef CONFIG_ACPI
static const struct acpi_device_id cbas_ec_acpi_ids[] = {
{ "GOOG000B", 0 },
{ }
};
MODULE_DEVICE_TABLE(acpi, cbas_ec_acpi_ids);
#endif
#ifdef CONFIG_OF
static const struct of_device_id cbas_ec_of_match[] = {

View file

@ -457,13 +457,13 @@ static const struct joycon_ctlr_button_mapping snescon_button_mappings[] = {
};
static const struct joycon_ctlr_button_mapping gencon_button_mappings[] = {
{ BTN_A, JC_BTN_A, },
{ BTN_B, JC_BTN_B, },
{ BTN_C, JC_BTN_R, },
{ BTN_X, JC_BTN_X, }, /* MD/GEN 6B Only */
{ BTN_Y, JC_BTN_Y, }, /* MD/GEN 6B Only */
{ BTN_Z, JC_BTN_L, }, /* MD/GEN 6B Only */
{ BTN_SELECT, JC_BTN_ZR, },
{ BTN_WEST, JC_BTN_A, }, /* A */
{ BTN_SOUTH, JC_BTN_B, }, /* B */
{ BTN_EAST, JC_BTN_R, }, /* C */
{ BTN_TL, JC_BTN_X, }, /* X MD/GEN 6B Only */
{ BTN_NORTH, JC_BTN_Y, }, /* Y MD/GEN 6B Only */
{ BTN_TR, JC_BTN_L, }, /* Z MD/GEN 6B Only */
{ BTN_SELECT, JC_BTN_ZR, }, /* Mode */
{ BTN_START, JC_BTN_PLUS, },
{ BTN_MODE, JC_BTN_HOME, },
{ BTN_Z, JC_BTN_CAP, },

View file

@ -1327,11 +1327,11 @@ static void steam_remove(struct hid_device *hdev)
return;
}
hid_destroy_device(steam->client_hdev);
cancel_delayed_work_sync(&steam->mode_switch);
cancel_work_sync(&steam->work_connect);
cancel_work_sync(&steam->rumble_work);
cancel_work_sync(&steam->unregister_work);
hid_destroy_device(steam->client_hdev);
steam->client_hdev = NULL;
steam->client_opened = 0;
if (steam->quirks & STEAM_QUIRK_WIRELESS) {

View file

@ -290,7 +290,7 @@ static int i2c_hid_get_report(struct i2c_hid *ihid,
ihid->rawbuf, recv_len + sizeof(__le16));
if (error) {
dev_err(&ihid->client->dev,
"failed to set a report to device: %d\n", error);
"failed to get a report from device: %d\n", error);
return error;
}

View file

@ -832,9 +832,9 @@ static void hid_ishtp_cl_remove(struct ishtp_cl_device *cl_device)
hid_ishtp_cl);
dev_dbg(ishtp_device(cl_device), "%s\n", __func__);
hid_ishtp_cl_deinit(hid_ishtp_cl);
ishtp_put_device(cl_device);
ishtp_hid_remove(client_data);
hid_ishtp_cl_deinit(hid_ishtp_cl);
hid_ishtp_cl = NULL;

View file

@ -261,12 +261,14 @@ err_hid_data:
*/
void ishtp_hid_remove(struct ishtp_cl_data *client_data)
{
void *data;
int i;
for (i = 0; i < client_data->num_hid_devices; ++i) {
if (client_data->hid_sensor_hubs[i]) {
kfree(client_data->hid_sensor_hubs[i]->driver_data);
data = client_data->hid_sensor_hubs[i]->driver_data;
hid_destroy_device(client_data->hid_sensor_hubs[i]);
kfree(data);
client_data->hid_sensor_hubs[i] = NULL;
}
}

View file

@ -909,6 +909,8 @@ static int quickspi_restore(struct device *device)
thc_change_ltr_mode(qsdev->thc_hw, THC_LTR_MODE_ACTIVE);
qsdev->state = QUICKSPI_ENABLED;
return 0;
}

View file

@ -107,7 +107,7 @@ static int quickspi_get_device_descriptor(struct quickspi_device *qsdev)
return 0;
}
dev_err_once(qsdev->dev, "Unexpected intput report type: %d\n", input_rep_type);
dev_err_once(qsdev->dev, "Unexpected input report type: %d\n", input_rep_type);
return -EINVAL;
}