Commit 3b6b17b7 authored by Michal Malý's avatar Michal Malý Committed by Jiri Kosina

HID: lg4ff: Take advantage of private driver data

lg4ff now calls hid_get/set_drvdata() to read or store device configuration.
Signed-off-by: default avatarMichal Malý <madcatxster@gmail.com>
Tested-by: default avatarSimon Wood <simon@mungewell.org>
Signed-off-by: default avatarJiri Kosina <jkosina@suse.cz>
parent 6a2e176b
...@@ -51,10 +51,7 @@ static ssize_t lg4ff_range_store(struct device *dev, struct device_attribute *at ...@@ -51,10 +51,7 @@ static ssize_t lg4ff_range_store(struct device *dev, struct device_attribute *at
static DEVICE_ATTR(range, S_IRWXU | S_IRWXG | S_IRWXO, lg4ff_range_show, lg4ff_range_store); static DEVICE_ATTR(range, S_IRWXU | S_IRWXG | S_IRWXO, lg4ff_range_show, lg4ff_range_store);
static bool list_inited;
struct lg4ff_device_entry { struct lg4ff_device_entry {
char *device_id; /* Use name in respective kobject structure's address as the ID */
__u16 range; __u16 range;
__u16 min_range; __u16 min_range;
__u16 max_range; __u16 max_range;
...@@ -63,8 +60,6 @@ struct lg4ff_device_entry { ...@@ -63,8 +60,6 @@ struct lg4ff_device_entry {
void (*set_range)(struct hid_device *hid, u16 range); void (*set_range)(struct hid_device *hid, u16 range);
}; };
static struct lg4ff_device_entry device_list;
static const signed short lg4ff_wheel_effects[] = { static const signed short lg4ff_wheel_effects[] = {
FF_CONSTANT, FF_CONSTANT,
FF_AUTOCENTER, FF_AUTOCENTER,
...@@ -285,18 +280,20 @@ static void hid_lg4ff_switch_native(struct hid_device *hid, const struct lg4ff_n ...@@ -285,18 +280,20 @@ static void hid_lg4ff_switch_native(struct hid_device *hid, const struct lg4ff_n
/* Read current range and display it in terminal */ /* Read current range and display it in terminal */
static ssize_t lg4ff_range_show(struct device *dev, struct device_attribute *attr, char *buf) static ssize_t lg4ff_range_show(struct device *dev, struct device_attribute *attr, char *buf)
{ {
struct lg4ff_device_entry *uninitialized_var(entry);
struct list_head *h;
struct hid_device *hid = to_hid_device(dev); struct hid_device *hid = to_hid_device(dev);
struct lg4ff_device_entry *entry;
struct lg_drv_data *drv_data;
size_t count; size_t count;
list_for_each(h, &device_list.list) { drv_data = hid_get_drvdata(hid);
entry = list_entry(h, struct lg4ff_device_entry, list); if (!drv_data) {
if (strcmp(entry->device_id, (&hid->dev)->kobj.name) == 0) hid_err(hid, "Private driver data not found!\n");
break; return 0;
} }
if (h == &device_list.list) {
dbg_hid("Device not found!"); entry = drv_data->device_props;
if (!entry) {
hid_err(hid, "Device properties not found!\n");
return 0; return 0;
} }
...@@ -308,19 +305,21 @@ static ssize_t lg4ff_range_show(struct device *dev, struct device_attribute *att ...@@ -308,19 +305,21 @@ static ssize_t lg4ff_range_show(struct device *dev, struct device_attribute *att
* according to the type of the wheel */ * according to the type of the wheel */
static ssize_t lg4ff_range_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) static ssize_t lg4ff_range_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{ {
struct lg4ff_device_entry *uninitialized_var(entry);
struct list_head *h;
struct hid_device *hid = to_hid_device(dev); struct hid_device *hid = to_hid_device(dev);
struct lg4ff_device_entry *entry;
struct lg_drv_data *drv_data;
__u16 range = simple_strtoul(buf, NULL, 10); __u16 range = simple_strtoul(buf, NULL, 10);
list_for_each(h, &device_list.list) { drv_data = hid_get_drvdata(hid);
entry = list_entry(h, struct lg4ff_device_entry, list); if (!drv_data) {
if (strcmp(entry->device_id, (&hid->dev)->kobj.name) == 0) hid_err(hid, "Private driver data not found!\n");
break; return 0;
} }
if (h == &device_list.list) {
dbg_hid("Device not found!"); entry = drv_data->device_props;
return count; if (!entry) {
hid_err(hid, "Device properties not found!\n");
return 0;
} }
if (range == 0) if (range == 0)
...@@ -344,6 +343,7 @@ int lg4ff_init(struct hid_device *hid) ...@@ -344,6 +343,7 @@ int lg4ff_init(struct hid_device *hid)
struct hid_report *report; struct hid_report *report;
struct hid_field *field; struct hid_field *field;
struct lg4ff_device_entry *entry; struct lg4ff_device_entry *entry;
struct lg_drv_data *drv_data;
struct usb_device_descriptor *udesc; struct usb_device_descriptor *udesc;
int error, i, j; int error, i, j;
__u16 bcdDevice, rev_maj, rev_min; __u16 bcdDevice, rev_maj, rev_min;
...@@ -423,28 +423,24 @@ int lg4ff_init(struct hid_device *hid) ...@@ -423,28 +423,24 @@ int lg4ff_init(struct hid_device *hid)
dev->ff->set_autocenter(dev, 0); dev->ff->set_autocenter(dev, 0);
} }
/* Initialize device_list if this is the first device to handle by lg4ff */ /* Get private driver data */
if (!list_inited) { drv_data = hid_get_drvdata(hid);
INIT_LIST_HEAD(&device_list.list); if (!drv_data) {
list_inited = 1; hid_err(hid, "Cannot add device, private driver data not allocated\n");
return -1;
} }
/* Add the device to device_list */ /* Initialize device properties */
entry = kzalloc(sizeof(struct lg4ff_device_entry), GFP_KERNEL); entry = kzalloc(sizeof(struct lg4ff_device_entry), GFP_KERNEL);
if (!entry) { if (!entry) {
hid_err(hid, "Cannot add device, insufficient memory.\n"); hid_err(hid, "Cannot add device, insufficient memory to allocate device properties.\n");
return -ENOMEM;
}
entry->device_id = kstrdup((&hid->dev)->kobj.name, GFP_KERNEL);
if (!entry->device_id) {
hid_err(hid, "Cannot set device_id, insufficient memory.\n");
kfree(entry);
return -ENOMEM; return -ENOMEM;
} }
drv_data->device_props = entry;
entry->min_range = lg4ff_devices[i].min_range; entry->min_range = lg4ff_devices[i].min_range;
entry->max_range = lg4ff_devices[i].max_range; entry->max_range = lg4ff_devices[i].max_range;
entry->set_range = lg4ff_devices[i].set_range; entry->set_range = lg4ff_devices[i].set_range;
list_add(&entry->list, &device_list.list);
/* Create sysfs interface */ /* Create sysfs interface */
error = device_create_file(&hid->dev, &dev_attr_range); error = device_create_file(&hid->dev, &dev_attr_range);
...@@ -463,27 +459,23 @@ int lg4ff_init(struct hid_device *hid) ...@@ -463,27 +459,23 @@ int lg4ff_init(struct hid_device *hid)
int lg4ff_deinit(struct hid_device *hid) int lg4ff_deinit(struct hid_device *hid)
{ {
bool found = 0;
struct lg4ff_device_entry *entry; struct lg4ff_device_entry *entry;
struct list_head *h, *g; struct lg_drv_data *drv_data;
device_remove_file(&hid->dev, &dev_attr_range); device_remove_file(&hid->dev, &dev_attr_range);
list_for_each_safe(h, g, &device_list.list) { drv_data = hid_get_drvdata(hid);
entry = list_entry(h, struct lg4ff_device_entry, list); if (!drv_data) {
if (strcmp(entry->device_id, (&hid->dev)->kobj.name) == 0) { hid_err(hid, "Error while deinitializing device, no private driver data.\n");
list_del(h); return -1;
kfree(entry->device_id);
kfree(entry);
found = 1;
break;
}
} }
entry = drv_data->device_props;
if (!found) { if (!entry) {
hid_err(hid, "Device entry not found!\n"); hid_err(hid, "Error while deinitializing device, no device properties data.\n");
return -1; return -1;
} }
/* Deallocate memory */
kfree(entry);
dbg_hid("Device successfully unregistered\n"); dbg_hid("Device successfully unregistered\n");
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment