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

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
Loading
Loading
Loading
Loading
+42 −50
Original line number Original line Diff line number Diff line
@@ -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 {
	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
/* 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
 * 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)
	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)
		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)


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;