hid-for-linus-2024020101
-----BEGIN PGP SIGNATURE----- iQJHBAABCAAxFiEEoEVH9lhNrxiMPSyI7MXwXhnZSjYFAmW7veITHGJlbnRpc3NA a2VybmVsLm9yZwAKCRDsxfBeGdlKNpzjD/97PuMdidU2cmy+N1k5AmFw8io/BO+Y hl/wOOMY4n2vaL98m0dte1y+IV2352yAANCfxYH4dO01h0x0BCz5Rk5J55Jsix8G jHPyUpGYCRKTNpaWuOE8nKbsCSRDF9ui0LvbgV9So/BwGScLdFCJwY7VNPp16W1s d+ccq/3Cy6XiQs2ZygdHogxC1F/youyPXo65IlkwClSI2naozDH+O8inhq+P/Mfl +WpR/oDjS3225nh/eKDYvni/u2+Fjc+7fZKskz8dxkR3dKsTrOHLh98hHFHQ2NQU lKf2FWxiq9CnvIoFI/f17KsC9CxJ3gTrzqt0JCv5niNkafkw0dzrYlAPVC4CuAwY odhwRHZomqY5f+t3qw8TS6haXp3faZVdbwh7Zz2osK2dtBrySa8eCT6H3kEhIQaI HKsTv5Fgq8vZ58ciiBCf13Z2nNFxq4bf9tx0haup7ktY1vNocwJ58cdCqIoyKKZS vrNRSt+lRzr3reHR2+ezPp0Fo4kDgCsQQHnNpu8IJ1+iD1kUa9gENOrs4MEufUoz QMDsI05ENslXjdbTlFci7a4kMth29CA4Y8d7TEkNRhGXVvvGnHB9xV+eX6kLq5UQ H28udI8DVXmR6Ctu4uwwYdB/4ilaD21XpfpktDF3EC0/09ff2vmIVr9DkBLevQ6h VQyResy9xnY+Wg== =yfy5 -----END PGP SIGNATURE----- Merge tag 'hid-for-linus-2024020101' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid Pull HID fixes from Benjamin Tissoires: - cleanups in the error path in hid-steam (Dan Carpenter) - fixes for Wacom tablets selftests that sneaked in while the CI was taking a break during the year end holidays (Benjamin Tissoires) - null pointer check in nvidia-shield (Kunwu Chan) - memory leak fix in hidraw (Su Hui) - another null pointer fix in i2c-hid-of (Johan Hovold) - another memory leak fix in HID-BPF this time, as well as a double fdget() fix reported by Dan Carpenter (Benjamin Tissoires) - fix for Cirque touchpad when they go on suspend (Kai-Heng Feng) - new device ID in hid-logitech-hidpp: "Logitech G Pro X SuperLight 2" (Jiri Kosina) * tag 'hid-for-linus-2024020101' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid: HID: bpf: use __bpf_kfunc instead of noinline HID: bpf: actually free hdev memory after attaching a HID-BPF program HID: bpf: remove double fdget() HID: i2c-hid-of: fix NULL-deref on failed power up HID: hidraw: fix a problem of memory leak in hidraw_release() HID: i2c-hid: Skip SET_POWER SLEEP for Cirque touchpad on system suspend HID: nvidia-shield: Add missing null pointer checks to LED initialization HID: logitech-hidpp: add support for Logitech G Pro X Superlight 2 selftests/hid: wacom: fix confidence tests HID: hid-steam: Fix cleanup in probe() HID: hid-steam: remove pointless error message
This commit is contained in:
commit
5c24e4e9e7
@ -143,6 +143,9 @@ u8 *call_hid_bpf_rdesc_fixup(struct hid_device *hdev, u8 *rdesc, unsigned int *s
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(call_hid_bpf_rdesc_fixup);
|
||||
|
||||
/* Disables missing prototype warnings */
|
||||
__bpf_kfunc_start_defs();
|
||||
|
||||
/**
|
||||
* hid_bpf_get_data - Get the kernel memory pointer associated with the context @ctx
|
||||
*
|
||||
@ -152,7 +155,7 @@ EXPORT_SYMBOL_GPL(call_hid_bpf_rdesc_fixup);
|
||||
*
|
||||
* @returns %NULL on error, an %__u8 memory pointer on success
|
||||
*/
|
||||
noinline __u8 *
|
||||
__bpf_kfunc __u8 *
|
||||
hid_bpf_get_data(struct hid_bpf_ctx *ctx, unsigned int offset, const size_t rdwr_buf_size)
|
||||
{
|
||||
struct hid_bpf_ctx_kern *ctx_kern;
|
||||
@ -167,6 +170,7 @@ hid_bpf_get_data(struct hid_bpf_ctx *ctx, unsigned int offset, const size_t rdwr
|
||||
|
||||
return ctx_kern->data + offset;
|
||||
}
|
||||
__bpf_kfunc_end_defs();
|
||||
|
||||
/*
|
||||
* The following set contains all functions we agree BPF programs
|
||||
@ -241,50 +245,25 @@ int hid_bpf_reconnect(struct hid_device *hdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* hid_bpf_attach_prog - Attach the given @prog_fd to the given HID device
|
||||
*
|
||||
* @hid_id: the system unique identifier of the HID device
|
||||
* @prog_fd: an fd in the user process representing the program to attach
|
||||
* @flags: any logical OR combination of &enum hid_bpf_attach_flags
|
||||
*
|
||||
* @returns an fd of a bpf_link object on success (> %0), an error code otherwise.
|
||||
* Closing this fd will detach the program from the HID device (unless the bpf_link
|
||||
* is pinned to the BPF file system).
|
||||
*/
|
||||
/* called from syscall */
|
||||
noinline int
|
||||
hid_bpf_attach_prog(unsigned int hid_id, int prog_fd, __u32 flags)
|
||||
static int do_hid_bpf_attach_prog(struct hid_device *hdev, int prog_fd, struct bpf_prog *prog,
|
||||
__u32 flags)
|
||||
{
|
||||
struct hid_device *hdev;
|
||||
struct device *dev;
|
||||
int fd, err, prog_type = hid_bpf_get_prog_attach_type(prog_fd);
|
||||
|
||||
if (!hid_bpf_ops)
|
||||
return -EINVAL;
|
||||
int fd, err, prog_type;
|
||||
|
||||
prog_type = hid_bpf_get_prog_attach_type(prog);
|
||||
if (prog_type < 0)
|
||||
return prog_type;
|
||||
|
||||
if (prog_type >= HID_BPF_PROG_TYPE_MAX)
|
||||
return -EINVAL;
|
||||
|
||||
if ((flags & ~HID_BPF_FLAG_MASK))
|
||||
return -EINVAL;
|
||||
|
||||
dev = bus_find_device(hid_bpf_ops->bus_type, NULL, &hid_id, device_match_id);
|
||||
if (!dev)
|
||||
return -EINVAL;
|
||||
|
||||
hdev = to_hid_device(dev);
|
||||
|
||||
if (prog_type == HID_BPF_PROG_TYPE_DEVICE_EVENT) {
|
||||
err = hid_bpf_allocate_event_data(hdev);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
fd = __hid_bpf_attach_prog(hdev, prog_type, prog_fd, flags);
|
||||
fd = __hid_bpf_attach_prog(hdev, prog_type, prog_fd, prog, flags);
|
||||
if (fd < 0)
|
||||
return fd;
|
||||
|
||||
@ -299,6 +278,66 @@ hid_bpf_attach_prog(unsigned int hid_id, int prog_fd, __u32 flags)
|
||||
return fd;
|
||||
}
|
||||
|
||||
/* Disables missing prototype warnings */
|
||||
__bpf_kfunc_start_defs();
|
||||
|
||||
/**
|
||||
* hid_bpf_attach_prog - Attach the given @prog_fd to the given HID device
|
||||
*
|
||||
* @hid_id: the system unique identifier of the HID device
|
||||
* @prog_fd: an fd in the user process representing the program to attach
|
||||
* @flags: any logical OR combination of &enum hid_bpf_attach_flags
|
||||
*
|
||||
* @returns an fd of a bpf_link object on success (> %0), an error code otherwise.
|
||||
* Closing this fd will detach the program from the HID device (unless the bpf_link
|
||||
* is pinned to the BPF file system).
|
||||
*/
|
||||
/* called from syscall */
|
||||
__bpf_kfunc int
|
||||
hid_bpf_attach_prog(unsigned int hid_id, int prog_fd, __u32 flags)
|
||||
{
|
||||
struct hid_device *hdev;
|
||||
struct bpf_prog *prog;
|
||||
struct device *dev;
|
||||
int err, fd;
|
||||
|
||||
if (!hid_bpf_ops)
|
||||
return -EINVAL;
|
||||
|
||||
if ((flags & ~HID_BPF_FLAG_MASK))
|
||||
return -EINVAL;
|
||||
|
||||
dev = bus_find_device(hid_bpf_ops->bus_type, NULL, &hid_id, device_match_id);
|
||||
if (!dev)
|
||||
return -EINVAL;
|
||||
|
||||
hdev = to_hid_device(dev);
|
||||
|
||||
/*
|
||||
* take a ref on the prog itself, it will be released
|
||||
* on errors or when it'll be detached
|
||||
*/
|
||||
prog = bpf_prog_get(prog_fd);
|
||||
if (IS_ERR(prog)) {
|
||||
err = PTR_ERR(prog);
|
||||
goto out_dev_put;
|
||||
}
|
||||
|
||||
fd = do_hid_bpf_attach_prog(hdev, prog_fd, prog, flags);
|
||||
if (fd < 0) {
|
||||
err = fd;
|
||||
goto out_prog_put;
|
||||
}
|
||||
|
||||
return fd;
|
||||
|
||||
out_prog_put:
|
||||
bpf_prog_put(prog);
|
||||
out_dev_put:
|
||||
put_device(dev);
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* hid_bpf_allocate_context - Allocate a context to the given HID device
|
||||
*
|
||||
@ -306,7 +345,7 @@ hid_bpf_attach_prog(unsigned int hid_id, int prog_fd, __u32 flags)
|
||||
*
|
||||
* @returns A pointer to &struct hid_bpf_ctx on success, %NULL on error.
|
||||
*/
|
||||
noinline struct hid_bpf_ctx *
|
||||
__bpf_kfunc struct hid_bpf_ctx *
|
||||
hid_bpf_allocate_context(unsigned int hid_id)
|
||||
{
|
||||
struct hid_device *hdev;
|
||||
@ -323,8 +362,10 @@ hid_bpf_allocate_context(unsigned int hid_id)
|
||||
hdev = to_hid_device(dev);
|
||||
|
||||
ctx_kern = kzalloc(sizeof(*ctx_kern), GFP_KERNEL);
|
||||
if (!ctx_kern)
|
||||
if (!ctx_kern) {
|
||||
put_device(dev);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ctx_kern->ctx.hid = hdev;
|
||||
|
||||
@ -337,14 +378,19 @@ hid_bpf_allocate_context(unsigned int hid_id)
|
||||
* @ctx: the HID-BPF context to release
|
||||
*
|
||||
*/
|
||||
noinline void
|
||||
__bpf_kfunc void
|
||||
hid_bpf_release_context(struct hid_bpf_ctx *ctx)
|
||||
{
|
||||
struct hid_bpf_ctx_kern *ctx_kern;
|
||||
struct hid_device *hid;
|
||||
|
||||
ctx_kern = container_of(ctx, struct hid_bpf_ctx_kern, ctx);
|
||||
hid = (struct hid_device *)ctx_kern->ctx.hid; /* ignore const */
|
||||
|
||||
kfree(ctx_kern);
|
||||
|
||||
/* get_device() is called by bus_find_device() */
|
||||
put_device(&hid->dev);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -358,7 +404,7 @@ hid_bpf_release_context(struct hid_bpf_ctx *ctx)
|
||||
*
|
||||
* @returns %0 on success, a negative error code otherwise.
|
||||
*/
|
||||
noinline int
|
||||
__bpf_kfunc int
|
||||
hid_bpf_hw_request(struct hid_bpf_ctx *ctx, __u8 *buf, size_t buf__sz,
|
||||
enum hid_report_type rtype, enum hid_class_request reqtype)
|
||||
{
|
||||
@ -426,6 +472,7 @@ hid_bpf_hw_request(struct hid_bpf_ctx *ctx, __u8 *buf, size_t buf__sz,
|
||||
kfree(dma_data);
|
||||
return ret;
|
||||
}
|
||||
__bpf_kfunc_end_defs();
|
||||
|
||||
/* our HID-BPF entrypoints */
|
||||
BTF_SET8_START(hid_bpf_fmodret_ids)
|
||||
|
@ -12,9 +12,9 @@ struct hid_bpf_ctx_kern {
|
||||
|
||||
int hid_bpf_preload_skel(void);
|
||||
void hid_bpf_free_links_and_skel(void);
|
||||
int hid_bpf_get_prog_attach_type(int prog_fd);
|
||||
int hid_bpf_get_prog_attach_type(struct bpf_prog *prog);
|
||||
int __hid_bpf_attach_prog(struct hid_device *hdev, enum hid_bpf_prog_type prog_type, int prog_fd,
|
||||
__u32 flags);
|
||||
struct bpf_prog *prog, __u32 flags);
|
||||
void __hid_bpf_destroy_device(struct hid_device *hdev);
|
||||
int hid_bpf_prog_run(struct hid_device *hdev, enum hid_bpf_prog_type type,
|
||||
struct hid_bpf_ctx_kern *ctx_kern);
|
||||
|
@ -196,6 +196,7 @@ static void __hid_bpf_do_release_prog(int map_fd, unsigned int idx)
|
||||
static void hid_bpf_release_progs(struct work_struct *work)
|
||||
{
|
||||
int i, j, n, map_fd = -1;
|
||||
bool hdev_destroyed;
|
||||
|
||||
if (!jmp_table.map)
|
||||
return;
|
||||
@ -220,6 +221,12 @@ static void hid_bpf_release_progs(struct work_struct *work)
|
||||
if (entry->hdev) {
|
||||
hdev = entry->hdev;
|
||||
type = entry->type;
|
||||
/*
|
||||
* hdev is still valid, even if we are called after hid_destroy_device():
|
||||
* when hid_bpf_attach() gets called, it takes a ref on the dev through
|
||||
* bus_find_device()
|
||||
*/
|
||||
hdev_destroyed = hdev->bpf.destroyed;
|
||||
|
||||
hid_bpf_populate_hdev(hdev, type);
|
||||
|
||||
@ -232,12 +239,19 @@ static void hid_bpf_release_progs(struct work_struct *work)
|
||||
if (test_bit(next->idx, jmp_table.enabled))
|
||||
continue;
|
||||
|
||||
if (next->hdev == hdev && next->type == type)
|
||||
if (next->hdev == hdev && next->type == type) {
|
||||
/*
|
||||
* clear the hdev reference and decrement the device ref
|
||||
* that was taken during bus_find_device() while calling
|
||||
* hid_bpf_attach()
|
||||
*/
|
||||
next->hdev = NULL;
|
||||
put_device(&hdev->dev);
|
||||
}
|
||||
}
|
||||
|
||||
/* if type was rdesc fixup, reconnect device */
|
||||
if (type == HID_BPF_PROG_TYPE_RDESC_FIXUP)
|
||||
/* if type was rdesc fixup and the device is not gone, reconnect device */
|
||||
if (type == HID_BPF_PROG_TYPE_RDESC_FIXUP && !hdev_destroyed)
|
||||
hid_bpf_reconnect(hdev);
|
||||
}
|
||||
}
|
||||
@ -333,15 +347,10 @@ static int hid_bpf_insert_prog(int prog_fd, struct bpf_prog *prog)
|
||||
return err;
|
||||
}
|
||||
|
||||
int hid_bpf_get_prog_attach_type(int prog_fd)
|
||||
int hid_bpf_get_prog_attach_type(struct bpf_prog *prog)
|
||||
{
|
||||
struct bpf_prog *prog = NULL;
|
||||
int i;
|
||||
int prog_type = HID_BPF_PROG_TYPE_UNDEF;
|
||||
|
||||
prog = bpf_prog_get(prog_fd);
|
||||
if (IS_ERR(prog))
|
||||
return PTR_ERR(prog);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < HID_BPF_PROG_TYPE_MAX; i++) {
|
||||
if (hid_bpf_btf_ids[i] == prog->aux->attach_btf_id) {
|
||||
@ -350,8 +359,6 @@ int hid_bpf_get_prog_attach_type(int prog_fd)
|
||||
}
|
||||
}
|
||||
|
||||
bpf_prog_put(prog);
|
||||
|
||||
return prog_type;
|
||||
}
|
||||
|
||||
@ -388,19 +395,13 @@ static const struct bpf_link_ops hid_bpf_link_lops = {
|
||||
/* called from syscall */
|
||||
noinline int
|
||||
__hid_bpf_attach_prog(struct hid_device *hdev, enum hid_bpf_prog_type prog_type,
|
||||
int prog_fd, __u32 flags)
|
||||
int prog_fd, struct bpf_prog *prog, __u32 flags)
|
||||
{
|
||||
struct bpf_link_primer link_primer;
|
||||
struct hid_bpf_link *link;
|
||||
struct bpf_prog *prog = NULL;
|
||||
struct hid_bpf_prog_entry *prog_entry;
|
||||
int cnt, err = -EINVAL, prog_table_idx = -1;
|
||||
|
||||
/* take a ref on the prog itself */
|
||||
prog = bpf_prog_get(prog_fd);
|
||||
if (IS_ERR(prog))
|
||||
return PTR_ERR(prog);
|
||||
|
||||
mutex_lock(&hid_bpf_attach_lock);
|
||||
|
||||
link = kzalloc(sizeof(*link), GFP_USER);
|
||||
@ -467,7 +468,6 @@ __hid_bpf_attach_prog(struct hid_device *hdev, enum hid_bpf_prog_type prog_type,
|
||||
err_unlock:
|
||||
mutex_unlock(&hid_bpf_attach_lock);
|
||||
|
||||
bpf_prog_put(prog);
|
||||
kfree(link);
|
||||
|
||||
return err;
|
||||
|
@ -298,6 +298,9 @@
|
||||
|
||||
#define USB_VENDOR_ID_CIDC 0x1677
|
||||
|
||||
#define I2C_VENDOR_ID_CIRQUE 0x0488
|
||||
#define I2C_PRODUCT_ID_CIRQUE_1063 0x1063
|
||||
|
||||
#define USB_VENDOR_ID_CJTOUCH 0x24b8
|
||||
#define USB_DEVICE_ID_CJTOUCH_MULTI_TOUCH_0020 0x0020
|
||||
#define USB_DEVICE_ID_CJTOUCH_MULTI_TOUCH_0040 0x0040
|
||||
|
@ -4610,6 +4610,8 @@ static const struct hid_device_id hidpp_devices[] = {
|
||||
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC088) },
|
||||
{ /* Logitech G Pro X Superlight Gaming Mouse over USB */
|
||||
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC094) },
|
||||
{ /* Logitech G Pro X Superlight 2 Gaming Mouse over USB */
|
||||
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC09b) },
|
||||
|
||||
{ /* G935 Gaming Headset */
|
||||
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0x0a87),
|
||||
|
@ -800,6 +800,8 @@ static inline int thunderstrike_led_create(struct thunderstrike *ts)
|
||||
|
||||
led->name = devm_kasprintf(&ts->base.hdev->dev, GFP_KERNEL,
|
||||
"thunderstrike%d:blue:led", ts->id);
|
||||
if (!led->name)
|
||||
return -ENOMEM;
|
||||
led->max_brightness = 1;
|
||||
led->flags = LED_CORE_SUSPENDRESUME | LED_RETAIN_AT_SHUTDOWN;
|
||||
led->brightness_get = &thunderstrike_led_get_brightness;
|
||||
@ -831,6 +833,8 @@ static inline int thunderstrike_psy_create(struct shield_device *shield_dev)
|
||||
shield_dev->battery_dev.desc.name =
|
||||
devm_kasprintf(&ts->base.hdev->dev, GFP_KERNEL,
|
||||
"thunderstrike_%d", ts->id);
|
||||
if (!shield_dev->battery_dev.desc.name)
|
||||
return -ENOMEM;
|
||||
|
||||
shield_dev->battery_dev.psy = power_supply_register(
|
||||
&hdev->dev, &shield_dev->battery_dev.desc, &psy_cfg);
|
||||
|
@ -1109,10 +1109,9 @@ static int steam_probe(struct hid_device *hdev,
|
||||
return hid_hw_start(hdev, HID_CONNECT_DEFAULT);
|
||||
|
||||
steam = devm_kzalloc(&hdev->dev, sizeof(*steam), GFP_KERNEL);
|
||||
if (!steam) {
|
||||
ret = -ENOMEM;
|
||||
goto steam_alloc_fail;
|
||||
}
|
||||
if (!steam)
|
||||
return -ENOMEM;
|
||||
|
||||
steam->hdev = hdev;
|
||||
hid_set_drvdata(hdev, steam);
|
||||
spin_lock_init(&steam->lock);
|
||||
@ -1129,14 +1128,14 @@ static int steam_probe(struct hid_device *hdev,
|
||||
*/
|
||||
ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_HIDRAW);
|
||||
if (ret)
|
||||
goto hid_hw_start_fail;
|
||||
goto err_cancel_work;
|
||||
|
||||
ret = hid_hw_open(hdev);
|
||||
if (ret) {
|
||||
hid_err(hdev,
|
||||
"%s:hid_hw_open\n",
|
||||
__func__);
|
||||
goto hid_hw_open_fail;
|
||||
goto err_hw_stop;
|
||||
}
|
||||
|
||||
if (steam->quirks & STEAM_QUIRK_WIRELESS) {
|
||||
@ -1152,36 +1151,37 @@ static int steam_probe(struct hid_device *hdev,
|
||||
hid_err(hdev,
|
||||
"%s:steam_register failed with error %d\n",
|
||||
__func__, ret);
|
||||
goto input_register_fail;
|
||||
goto err_hw_close;
|
||||
}
|
||||
}
|
||||
|
||||
steam->client_hdev = steam_create_client_hid(hdev);
|
||||
if (IS_ERR(steam->client_hdev)) {
|
||||
ret = PTR_ERR(steam->client_hdev);
|
||||
goto client_hdev_fail;
|
||||
goto err_stream_unregister;
|
||||
}
|
||||
steam->client_hdev->driver_data = steam;
|
||||
|
||||
ret = hid_add_device(steam->client_hdev);
|
||||
if (ret)
|
||||
goto client_hdev_add_fail;
|
||||
goto err_destroy;
|
||||
|
||||
return 0;
|
||||
|
||||
client_hdev_add_fail:
|
||||
hid_hw_stop(hdev);
|
||||
client_hdev_fail:
|
||||
err_destroy:
|
||||
hid_destroy_device(steam->client_hdev);
|
||||
input_register_fail:
|
||||
hid_hw_open_fail:
|
||||
hid_hw_start_fail:
|
||||
err_stream_unregister:
|
||||
if (steam->connected)
|
||||
steam_unregister(steam);
|
||||
err_hw_close:
|
||||
hid_hw_close(hdev);
|
||||
err_hw_stop:
|
||||
hid_hw_stop(hdev);
|
||||
err_cancel_work:
|
||||
cancel_work_sync(&steam->work_connect);
|
||||
cancel_delayed_work_sync(&steam->mode_switch);
|
||||
cancel_work_sync(&steam->rumble_work);
|
||||
steam_alloc_fail:
|
||||
hid_err(hdev, "%s: failed with error %d\n",
|
||||
__func__, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -357,8 +357,11 @@ static int hidraw_release(struct inode * inode, struct file * file)
|
||||
down_write(&minors_rwsem);
|
||||
|
||||
spin_lock_irqsave(&hidraw_table[minor]->list_lock, flags);
|
||||
for (int i = list->tail; i < list->head; i++)
|
||||
kfree(list->buffer[i].value);
|
||||
while (list->tail != list->head) {
|
||||
kfree(list->buffer[list->tail].value);
|
||||
list->buffer[list->tail].value = NULL;
|
||||
list->tail = (list->tail + 1) & (HIDRAW_BUFFER_SIZE - 1);
|
||||
}
|
||||
list_del(&list->node);
|
||||
spin_unlock_irqrestore(&hidraw_table[minor]->list_lock, flags);
|
||||
kfree(list);
|
||||
|
@ -49,6 +49,7 @@
|
||||
#define I2C_HID_QUIRK_RESET_ON_RESUME BIT(2)
|
||||
#define I2C_HID_QUIRK_BAD_INPUT_SIZE BIT(3)
|
||||
#define I2C_HID_QUIRK_NO_WAKEUP_AFTER_RESET BIT(4)
|
||||
#define I2C_HID_QUIRK_NO_SLEEP_ON_SUSPEND BIT(5)
|
||||
|
||||
/* Command opcodes */
|
||||
#define I2C_HID_OPCODE_RESET 0x01
|
||||
@ -131,6 +132,8 @@ static const struct i2c_hid_quirks {
|
||||
I2C_HID_QUIRK_RESET_ON_RESUME },
|
||||
{ USB_VENDOR_ID_ITE, I2C_DEVICE_ID_ITE_LENOVO_LEGION_Y720,
|
||||
I2C_HID_QUIRK_BAD_INPUT_SIZE },
|
||||
{ I2C_VENDOR_ID_CIRQUE, I2C_PRODUCT_ID_CIRQUE_1063,
|
||||
I2C_HID_QUIRK_NO_SLEEP_ON_SUSPEND },
|
||||
/*
|
||||
* Sending the wakeup after reset actually break ELAN touchscreen controller
|
||||
*/
|
||||
@ -956,7 +959,8 @@ static int i2c_hid_core_suspend(struct i2c_hid *ihid, bool force_poweroff)
|
||||
return ret;
|
||||
|
||||
/* Save some power */
|
||||
i2c_hid_set_power(ihid, I2C_HID_PWR_SLEEP);
|
||||
if (!(ihid->quirks & I2C_HID_QUIRK_NO_SLEEP_ON_SUSPEND))
|
||||
i2c_hid_set_power(ihid, I2C_HID_PWR_SLEEP);
|
||||
|
||||
disable_irq(client->irq);
|
||||
|
||||
|
@ -87,6 +87,7 @@ static int i2c_hid_of_probe(struct i2c_client *client)
|
||||
if (!ihid_of)
|
||||
return -ENOMEM;
|
||||
|
||||
ihid_of->client = client;
|
||||
ihid_of->ops.power_up = i2c_hid_of_power_up;
|
||||
ihid_of->ops.power_down = i2c_hid_of_power_down;
|
||||
|
||||
|
@ -77,17 +77,6 @@ enum hid_bpf_attach_flags {
|
||||
int hid_bpf_device_event(struct hid_bpf_ctx *ctx);
|
||||
int hid_bpf_rdesc_fixup(struct hid_bpf_ctx *ctx);
|
||||
|
||||
/* Following functions are kfunc that we export to BPF programs */
|
||||
/* available everywhere in HID-BPF */
|
||||
__u8 *hid_bpf_get_data(struct hid_bpf_ctx *ctx, unsigned int offset, const size_t __sz);
|
||||
|
||||
/* only available in syscall */
|
||||
int hid_bpf_attach_prog(unsigned int hid_id, int prog_fd, __u32 flags);
|
||||
int hid_bpf_hw_request(struct hid_bpf_ctx *ctx, __u8 *buf, size_t buf__sz,
|
||||
enum hid_report_type rtype, enum hid_class_request reqtype);
|
||||
struct hid_bpf_ctx *hid_bpf_allocate_context(unsigned int hid_id);
|
||||
void hid_bpf_release_context(struct hid_bpf_ctx *ctx);
|
||||
|
||||
/*
|
||||
* Below is HID internal
|
||||
*/
|
||||
|
@ -880,8 +880,8 @@ class TestDTH2452Tablet(test_multitouch.BaseTest.TestMultitouch, TouchTabletTest
|
||||
does not overlap with other contacts. The value of `t` may be
|
||||
incremented over time to move the point along a linear path.
|
||||
"""
|
||||
x = 50 + 10 * contact_id + t
|
||||
y = 100 + 100 * contact_id + t
|
||||
x = 50 + 10 * contact_id + t * 11
|
||||
y = 100 + 100 * contact_id + t * 11
|
||||
return test_multitouch.Touch(contact_id, x, y)
|
||||
|
||||
def make_contacts(self, n, t=0):
|
||||
@ -902,8 +902,8 @@ class TestDTH2452Tablet(test_multitouch.BaseTest.TestMultitouch, TouchTabletTest
|
||||
tracking_id = contact_ids.tracking_id
|
||||
slot_num = contact_ids.slot_num
|
||||
|
||||
x = 50 + 10 * contact_id + t
|
||||
y = 100 + 100 * contact_id + t
|
||||
x = 50 + 10 * contact_id + t * 11
|
||||
y = 100 + 100 * contact_id + t * 11
|
||||
|
||||
# If the data isn't supposed to be stored in any slots, there is
|
||||
# nothing we can check for in the evdev stream.
|
||||
|
Loading…
Reference in New Issue
Block a user