diff options
| author | Kimplul <kimi.h.kuparinen@gmail.com> | 2022-03-12 20:53:39 +0200 |
|---|---|---|
| committer | Kimplul <kimi.h.kuparinen@gmail.com> | 2022-03-12 20:53:39 +0200 |
| commit | 9b6810ba6e1bd2553e205eb6719844253d5ce051 (patch) | |
| tree | c089f895afd8805336cdd1a04160d3558db9f83b | |
| parent | 60e90e0a96039c58968de551aadca0fab490d35d (diff) | |
| download | hid-tmff2-9b6810ba6e1bd2553e205eb6719844253d5ce051.tar.gz hid-tmff2-9b6810ba6e1bd2553e205eb6719844253d5ce051.zip | |
fix crashes
| -rw-r--r-- | hid-tmff2.c | 24 | ||||
| -rw-r--r-- | hid-tmff2.h | 4 | ||||
| -rw-r--r-- | hid-tmt300rs.c | 78 |
3 files changed, 52 insertions, 54 deletions
diff --git a/hid-tmff2.c b/hid-tmff2.c index f1d1f84..6a112fa 100644 --- a/hid-tmff2.c +++ b/hid-tmff2.c @@ -52,15 +52,15 @@ static struct tmff2_device_entry *tmff2_from_hdev(struct hid_device *hdev) static struct tmff2_device_entry *tmff2_from_input(struct input_dev *input_dev) { - struct tmff2_device_entry *tmff2; + struct hid_device *hdev; spin_lock_irqsave(&lock, lock_flags); - if (!(tmff2 = input_get_drvdata(input_dev))) { + if (!(hdev = input_get_drvdata(input_dev))) { dev_err(&input_dev->dev, "input_dev private data not found\n"); return NULL; } spin_unlock_irqrestore(&lock, lock_flags); - return tmff2; + return tmff2_from_hdev(hdev); } static ssize_t spring_level_store(struct device *dev, @@ -301,7 +301,7 @@ static void tmff2_work_handler(struct work_struct *w) } if (test_bit(FF_EFFECT_QUEUE_START, &state->flags)) { - if (tmff2->play_effect(tmff2, state)) { + if (tmff2->play_effect(tmff2->data, state)) { hid_warn(tmff2->hdev, "failed starting effect\n"); } else { __clear_bit(FF_EFFECT_QUEUE_START, &state->flags); @@ -311,7 +311,7 @@ static void tmff2_work_handler(struct work_struct *w) } if (test_bit(FF_EFFECT_QUEUE_STOP, &state->flags)) { - if (tmff2->stop_effect(tmff2, state)) { + if (tmff2->stop_effect(tmff2->data, state)) { hid_warn(tmff2->hdev, "failed stopping effect\n"); } else { __clear_bit(FF_EFFECT_PLAYING, &state->flags); @@ -420,9 +420,15 @@ static int tmff2_wheel_init(struct tmff2_device_entry *tmff2) { int ret, i; struct ff_device *ff; + spin_lock_init(&lock); spin_lock_init(&tmff2->lock); INIT_DELAYED_WORK(&tmff2->work, tmff2_work_handler); + /* get parameters etc from backend */ + if ((ret = tmff2->wheel_init(tmff2))) + goto err; + + tmff2->states = kzalloc(sizeof(struct tmff2_effect_state) * tmff2->max_effects, GFP_KERNEL); @@ -431,10 +437,6 @@ static int tmff2_wheel_init(struct tmff2_device_entry *tmff2) goto err; } - /* is this required or should it be done in t300rs_populate_api? */ - if ((ret = tmff2->wheel_init(tmff2->data))) - goto err; - /* set supported effects into input_dev->ffbit */ for (i = 0; tmff2->supported_effects[i] >= 0; ++i) __set_bit(tmff2->supported_effects[i], tmff2->input_dev->ffbit); @@ -482,8 +484,6 @@ static int tmff2_probe(struct hid_device *hdev, const struct hid_device_id *id) tmff2->hdev = hdev; hid_set_drvdata(tmff2->hdev, tmff2); - tmff2->input_dev = list_entry(hdev->inputs.next, struct hid_input, list)->input; - input_set_drvdata(tmff2->input_dev, tmff2); switch (tmff2->hdev->product) { /* t300rs */ @@ -508,6 +508,8 @@ static int tmff2_probe(struct hid_device *hdev, const struct hid_device_id *id) goto hid_err; } + tmff2->input_dev = list_entry(hdev->inputs.next, struct hid_input, list)->input; + if ((ret = tmff2_wheel_init(tmff2))) { hid_err(hdev, "init failed\n"); goto init_err; diff --git a/hid-tmff2.h b/hid-tmff2.h index bdde1a7..b2a46c9 100644 --- a/hid-tmff2.h +++ b/hid-tmff2.h @@ -60,7 +60,7 @@ struct tmff2_device_entry { int (*update_effect)(void *data, struct tmff2_effect_state *state); int (*stop_effect)(void *data, struct tmff2_effect_state *state); - int (*wheel_init)(void *data); + int (*wheel_init)(struct tmff2_device_entry *tmff2); int (*wheel_destroy)(void *data); /* optional callbacks */ @@ -71,6 +71,8 @@ struct tmff2_device_entry { int (*switch_mode)(void *data, uint16_t mode); int (*set_autocenter)(void *data, uint16_t autocenter); __u8 *(*wheel_fixup)(struct hid_device *hdev, __u8 *rdesc, unsigned int *rsize); + + /* void pointers are dangerous, I know, but in this case likely the best option... */ }; #endif /* _HID_TMFF2 */ diff --git a/hid-tmt300rs.c b/hid-tmt300rs.c index ee0e817..8171578 100644 --- a/hid-tmt300rs.c +++ b/hid-tmt300rs.c @@ -1329,31 +1329,31 @@ static int t300rs_close(void *data) return ret; } -static int t300rs_create_files(struct hid_device *hdev) +static int t300rs_create_files(struct t300rs_device_entry *t300rs) { int ret; - if ((ret = device_create_file(&hdev->dev, &dev_attr_alt_mode))) { - hid_err(hdev, "unable to create sysfs interface for alt_mode\n"); + if ((ret = device_create_file(&t300rs->hdev->dev, &dev_attr_alt_mode))) { + hid_err(t300rs->hdev, "unable to create sysfs interface for alt_mode\n"); goto alt_err; } - if ((ret = device_create_file(&hdev->dev, &dev_attr_range))) { - hid_warn(hdev, "unable to create sysfs interface for range\n"); + if ((ret = device_create_file(&t300rs->hdev->dev, &dev_attr_range))) { + hid_warn(t300rs->hdev, "unable to create sysfs interface for range\n"); goto range_err; } - if ((ret = device_create_file(&hdev->dev, &dev_attr_spring_level))) { - hid_warn(hdev, "unable to create sysfs interface for spring_level\n"); + if ((ret = device_create_file(&t300rs->hdev->dev, &dev_attr_spring_level))) { + hid_warn(t300rs->hdev, "unable to create sysfs interface for spring_level\n"); goto spring_err; } - if ((ret = device_create_file(&hdev->dev, &dev_attr_damper_level))) { - hid_warn(hdev, "unable to create sysfs interface for damper_level\n"); + if ((ret = device_create_file(&t300rs->hdev->dev, &dev_attr_damper_level))) { + hid_warn(t300rs->hdev, "unable to create sysfs interface for damper_level\n"); goto damper_err; } - if ((ret = device_create_file(&hdev->dev, &dev_attr_friction_level))) { - hid_warn(hdev, "unable to create sysfs interface for friction_level\n"); + if ((ret = device_create_file(&t300rs->hdev->dev, &dev_attr_friction_level))) { + hid_warn(t300rs->hdev, "unable to create sysfs interface for friction_level\n"); goto friction_err; } @@ -1362,13 +1362,13 @@ static int t300rs_create_files(struct hid_device *hdev) /* if the creation of dev_attr_friction fails, we don't need to remove it */ /* device_remove_file(&hdev->dev, &dev_attr_friction_level); */ friction_err: - device_remove_file(&hdev->dev, &dev_attr_damper_level); + device_remove_file(&t300rs->hdev->dev, &dev_attr_damper_level); damper_err: - device_remove_file(&hdev->dev, &dev_attr_spring_level); + device_remove_file(&t300rs->hdev->dev, &dev_attr_spring_level); spring_err: - device_remove_file(&hdev->dev, &dev_attr_range); + device_remove_file(&t300rs->hdev->dev, &dev_attr_range); range_err: - device_remove_file(&hdev->dev, &dev_attr_alt_mode); + device_remove_file(&t300rs->hdev->dev, &dev_attr_alt_mode); alt_err: return ret; } @@ -1397,7 +1397,7 @@ static int t300rs_check_firmware(struct t300rs_device_entry *t300rs) ); if (ret < 0) { - hid_err(t300rs->hdev, "could not fetch firmware version\n"); + hid_err(t300rs->hdev, "could not fetch firmware version: %i\n", ret); goto out; } @@ -1422,12 +1422,21 @@ out: return ret; } -static int t300rs_wheel_init(void *data) +static int t300rs_wheel_init(struct tmff2_device_entry *tmff2) { - struct t300rs_device_entry *t300rs = data; + struct t300rs_device_entry *t300rs = kzalloc(sizeof(struct t300rs_device_entry), GFP_KERNEL); struct list_head *report_list; int ret; + if (!t300rs) { + ret = -ENOMEM; + goto t300rs_err; + } + + t300rs->hdev = tmff2->hdev; + t300rs->input_dev = tmff2->input_dev; + t300rs->usbdev = to_usb_device(tmff2->hdev->dev.parent->parent); + if(t300rs->hdev->product == 0xb66d) t300rs->buffer_length = T300RS_PS4_BUFFER_LENGTH; else @@ -1451,19 +1460,21 @@ static int t300rs_wheel_init(void *data) t300rs->open = t300rs->input_dev->open; t300rs->close = t300rs->input_dev->close; - if ((ret = t300rs_create_files(t300rs->hdev))) { + if ((ret = t300rs_create_files(t300rs))) { /* probably not a massive issue, but could affect programs like * Oversteer, best play it safe */ hid_err(t300rs->hdev, "could not create sysfs files\n"); goto sysfs_err; } - t300rs_set_range(t300rs, range); - t300rs_set_gain(t300rs, 0xffff); - /* TODO: PS4 advanced mode? */ alt_mode = (t300rs->hdev->product == 0xb66f); + /* everythin went OK */ + tmff2->data = t300rs; + tmff2->max_effects = T300RS_MAX_EFFECTS; + memcpy(tmff2->supported_effects, t300rs_effects, sizeof(t300rs_effects)); + hid_info(t300rs->hdev, "force feedback for T300RS\n"); return 0; @@ -1471,8 +1482,10 @@ sysfs_err: firmware_err: kfree(t300rs->send_buffer); +t300rs_err: + kfree(t300rs); send_err: - hid_err(t300rs->hdev, "failed creating force feedback device\n"); + hid_err(tmff2->hdev, "failed creating force feedback device\n"); return ret; } @@ -1523,17 +1536,6 @@ static __u8 *t300rs_wheel_fixup(struct hid_device *hdev, __u8 *rdesc, static int t300rs_populate_api(struct tmff2_device_entry *tmff2) { - struct t300rs_device_entry *t300rs = - kzalloc(sizeof(struct t300rs_device_entry), GFP_KERNEL); - - /* we must populate wheel_destroy at the least, even if t300rs didn't - * get allocated */ - tmff2->data = t300rs; - tmff2->max_effects = T300RS_MAX_EFFECTS; - - /* copy over supported effects */ - memcpy(tmff2->supported_effects, t300rs_effects, ARRAY_SIZE(t300rs_effects)); - /* set callbacks */ tmff2->play_effect = t300rs_play_effect; tmff2->upload_effect = t300rs_upload_effect; @@ -1551,13 +1553,5 @@ static int t300rs_populate_api(struct tmff2_device_entry *tmff2) tmff2->set_autocenter = t300rs_set_autocenter; tmff2->wheel_fixup = t300rs_wheel_fixup; - if (!t300rs) - return -ENOMEM; - - /* copy over stuff we need */ - t300rs->hdev = tmff2->hdev; - t300rs->input_dev = tmff2->input_dev; - t300rs->usbdev = to_usb_device(&tmff2->hdev->dev); - return 0; } |
